MxEMexico

Versión completa: [TTT] Item: Granada de Choque
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Wenas tardes panas. Acabo de terminar este pequeño aporte para el mod [TTT]

Item: [TTT] Item: Granada de Choque

Team: Traidores

Descripción: Es un item basado en la Granada de Choque del juego Fortnite. Es una granada con knockback (empuje), que avienta hacia todas direcciones a los jugadores que estén dentro de su rango de explosión. Osea los saca volando hasta la chingada de lejos. 
Tal y como en el juego original de Fortnite, la granada te lanza, mas al caer no te produce daño por caída, por lo tanto no habría muertes estúpidamente rotas dentro del juego. 
Este item puede funcionar para trolear, así como puede ser de utilidad para los traidores al momento de intentar escapar.

*Se aceptan sugerencias a cambios*

Creditos:
  • Metrikcz: Stock del Blast
  • [ZE] Knockback Nade: Parte del código (sin autor)

Video demostrativo: 


Archivos / Recursos: Link Mega

Código:
[spoiler]
Código PHP:
/* Sublime AMXX Editor v3.0.0-beta */

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <engine>
#include <fun>
#include <ttt>


#define RADIO 400.0
#define pev_nade_type   pev_flTimeStepSound
#define NADE_TYPE_KB    26517
#define make_explode(%1)    entity_set_float(%1, EV_FL_dmgtime, 0.0)

//NADEMODELS
new const g_PlayerModel [ ] = { "models/ttt/kb_nade/p_nade.mdl"};
new const 
g_ViewModel [ ] = { "models/ttt/kb_nade/v_nade.mdl"};
new const 
g_WorldModel [ ] = { "models/ttt/kb_nade/w_nade.mdl" };
new const 
grenade_color[] = { 5151255 };
//NADESOUNDS
new const g_SoundGrenadeBuy [ ] [ ] = { "items/gunpickup2.wav" };
new const 
g_SoundAmmoPurchase [ ] [ ] = { "items/9mmclip1.wav" };
new const 
g_SoundBombExplode [ ] [ ] = { "ttt/kb_nade/nade_explode.wav" };

new 
g_iNade;
new 
g_iExplo;
new 
g_GlowSprg_exploSpr;
new 
g_MaxPlayers;
new 
g_msgScreenFade;
new 
g_isUserHasNade[33];
new 
g_iCurrentWeapon[33];
new 
bool:ignoreFalling[33];
//CVARS
new cvar_speed;
new 
cvar_precio;

public 
plugin_precache()
{
    
precache_model g_PlayerModel );
    
precache_model g_ViewModel );
    
precache_model g_WorldModel );
    
//precache_model("models/rpgrocket.mdl"); 
    
new i;
    for ( 
0sizeof g_SoundGrenadeBuyi++ )
    {
        
precache_sound g_SoundGrenadeBuy ] );
    }
    for ( 
0sizeof g_SoundAmmoPurchasei++ )
    {
        
precache_sound g_SoundAmmoPurchase ] );
    }
    for ( 
0sizeof g_SoundBombExplodei++ )
    {
        
precache_sound g_SoundBombExplode ] );
    }
}

public 
plugin_init()
{
    
register_plugin("[TTT] Item: Granada de Choque""1.0""GabsHp");
    
//register_clcmd("say /buynade", "buy_nade");
    //register_clcmd("say /tercera", "tercerapersona");
    //register_clcmd("say /primera", "primerapersona");
    
register_event("CurWeapon""EV_CurWeapon""be""1=1");
    
register_event("HLTV""EV_NewRound""a""1=0""2=0");
    
register_event("DeathMsg""EV_DeathMsg""a");
    
register_forward(FM_SetModel"fw_SetModel");
    
RegisterHam(Ham_Think"grenade""fw_ThinkGrenade");
    
RegisterHam(Ham_Touch,     "grenade""fw_touch");
    
RegisterHamHam_TakeDamage"player""Player_TakeDamage" );
    
g_MaxPlayers get_maxplayers();
    
g_msgScreenFade get_user_msgid"ScreenFade" );
    
cvar_speed register_cvar "ttt_kbnade_knockback""800" );
    
cvar_precio my_register_cvar("ttt_kbnade_precio""2""Precio de la Granada de Choque");
}

public 
ttt_plugin_cfg()
{
    g_iNade ttt_buymenu_add"Granada de Choque"get_pcvar_num(cvar_precio), PC_TRAITOR);
    ttt_add_exceptiong_iNade );
}

public 
ttt_gamemode(gamemode)
{
    
    
if(gamemode == GAME_ENDED || gamemode == GAME_RESTARTING || gamemode == GAME_PREPARING)
    {    
        
for( new 1<= g_MaxPlayersi++ )
        {
            g_isUserHasNade[i] = 0;
            if(ignoreFalling[i]){
                ignoreFalling[i]=false;
            }
        }
    }
}

public 
ttt_item_selected(iditemname[], price)
{
    if(
g_iNade == item)
    {
        if(
g_isUserHasNade[id]>0){
            
client_print_color(idprint_team_default"%s ^1Ya tienes equipada una ^4Granada de Choque"TTT_TAG);
            return 
PLUGIN_HANDLED;
        }
        
g_isUserHasNade[id]++;
        
give_item id"weapon_smokegrenade");
        
client_print_color(idprint_team_default"%s ^1Has comprado una ^4Granada de Choque^1!"TTT_TAG);
    }
    return 
PLUGIN_CONTINUE;
}
/*
public buy_nade(id){
    if(g_isUserHasNade[id]>0){
        client_print(id, print_center, "Ya tienes una granada de choque!");
        return PLUGIN_HANDLED;
    }
    give_item ( id, "weapon_smokegrenade" );
    emit_sound ( id, CHAN_ITEM, g_SoundGrenadeBuy[random_num(0, sizeof g_SoundGrenadeBuy-1)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM );
    client_print(id, print_chat, "Has comprado una granada de choque!");
    g_isUserHasNade[id]++;
    return PLUGIN_HANDLED;
}
*/
public EV_CurWeapon(id)
{
    if (!is_user_alive(id))
        return PLUGIN_CONTINUE;
    
    g_iCurrentWeapon
[id] = read_data (2);
    
    
if (g_isUserHasNade[id]>&& g_iCurrentWeapon[id] == CSW_SMOKEGRENADE )
    {
        set_pev (idpev_viewmodel2g_ViewModel);
        set_pev (idpev_weaponmodel2g_WorldModel);
        set_pev (idpev_weaponmodelengfunc(EngFunc_AllocStringg_PlayerModel));
    }
    
    
return PLUGIN_CONTINUE;
}

public 
EV_NewRound()
{
    arrayset (g_isUserHasNade033);
    arrayset (ignoreFallingfalse33);
}

public 
EV_DeathMsg()
{
    new iVictim read_data (2);
    
    
if ( !is_user_connected (iVictim))
        return;
    
    g_isUserHasNade
[iVictim] = 0;
    ignoreFalling[iVictim] = false;
}

public 
client_connect (id)
{
    g_isUserHasNade[id] = 0;
    ignoreFalling[id]=false;
}

public 
fw_SetModel Entity, const Model [ ] )
{
    if ( 
Entity )
        return 
FMRES_IGNORED;
    if ( 
pev Entitypev_dmgtime ) == 0.0 )
        return 
FMRES_IGNORED;
    
    
new iOwner entity_get_edict EntityEV_ENT_owner );    
    
    
if(g_isUserHasNade[iOwner] >= && equal(Model[7], "w_sm"4))
    {
        
set_pev(Entitypev_nade_type0);
        
set_pev(Entitypev_nade_typeNADE_TYPE_KB);
        
        g_isUserHasNade
[iOwner]--;
        
        entity_set_model 
Entityg_WorldModel );
        return 
FMRES_SUPERCEDE;
    }
    return 
FMRES_IGNORED;
}

public 
fw_ThinkGrenade (Entity)
{
    if(!pev_valid(Entity))
        return HAM_IGNORED;
    
    
static Float:dmg_time;
    pev(Entitypev_dmgtimedmg_time);
    
    
if (dmg_time get_gametime())
        return HAM_IGNORED;
    
    
if(pev(Entitypev_nade_type) == NADE_TYPE_KB)
    {
        jumping_explode(Entity);
        return HAM_SUPERCEDE;
    }
    return HAM_IGNORED;
}

public 
fw_touch(touchertouched)
{
    if(!(
pev(toucherpev_nade_type) == NADE_TYPE_KB)) return HAM_IGNORED;
    if (
is_solid(touched))
            {
                
make_explode(toucher);
                
entity_set_float(toucherEV_FL_nextthinkget_gametime() + 0.3);
                
entity_set_int(toucherEV_INT_flagsentity_get_int(toucherEV_INT_flags) | FL_ONGROUND);
                return 
HAM_HANDLED;
            }
    return 
HAM_IGNORED;
}

public 
jumping_explode (Entity)
{
    if(
Entity 0)
    return;
    
    
static Float:flOrigin[3];
    
pev(Entitypev_originflOrigin);
    
    engfunc
(EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYflOrigin0);
    
write_byte(TE_SPRITE) ;
    
engfunc(EngFunc_WriteCoordflOrigin ]);
    
engfunc(EngFunc_WriteCoordflOrigin ]);
    
engfunc(EngFunc_WriteCoordflOrigin ] + 45.0);
    
write_short (g_iExplo);
    
write_byte (35);
    
write_byte (186);
    
message_end();
    new 
iOwner entity_get_edict EntityEV_ENT_owner );
    
emit_sound EntityCHAN_WEAPONg_SoundBombExplode[random_num(0sizeof g_SoundBombExplode-1)], VOL_NORMATTN_NORM0PITCH_NORM );
    
create_blast(flOrigingrenade_color[0], grenade_color[1], grenade_color[2]);
    for ( new 
1g_MaxPlayersi++ )
    {
        if ( !
is_user_alive  ) )
            continue;
       

        
        
// Debug!
        //client_print ( iOwner, print_chat, "Owner of Smoke Grenade!" )    
        
        
new Float:flVictimOrigin ];
        
pev ipev_originflVictimOrigin );
        
        
new Float:flDistance get_distance_f flOriginflVictimOrigin );
        
        
if ( flDistance <= RADIO )
        {
            
message_begin(MSG_ONE_UNRELIABLE MSG_BROADCASTg_msgScreenFade_i);
            
write_short4096 );
            
write_short4096 );
            
write_short0x0000 );
            
write_byte(random_num(00));
            
write_byte(random_num(0128));
            
write_byte(random_num(0255));
            
write_byte(120);
            
message_end( );
            static 
Float:flSpeed;
            
flSpeed get_pcvar_float cvar_speed );
            
            
static Float:flNewSpeed;
            
flNewSpeed flSpeed * ( 1.0 - ( flDistance RADIO ) );
            
            
static Float:flVelocity ];
            
get_speed_vector flOriginflVictimOriginflNewSpeedflVelocity );
            
set_pevipev_velocity,flVelocity );
            
set_pevipev_gravity0.5);
            
ignoreFalling[i]=true;
            
set_task(Float:1.0"reset_gravity"i);
            
set_task(Float:4.0"reset_Fall"i);
        }
    }
    
    engfunc 
EngFunc_RemoveEntityEntity );
}
        

public reset_gravity(id)
{
    
set_pev(idpev_gravity1.0);
}
public 
reset_Fall(id)
{
    
ignoreFalling[id]=false;
}
public 
Player_TakeDamagevictiminflictorattackerFloat:damagedamagebits )
{
    if(
damagebits==DMG_FALL && ignoreFalling[victim])
    {
        
SetHamParamFloat(4Float:0.0);
        
reset_Fall(victim);
        return 
HAM_HANDLED;
    }
    return 
HAM_IGNORED;
}

stock get_speed_vector(const Float:origin1[3],const Float:origin2[3],Float:speedFloat:new_velocity[3])
{
    
new_velocity[0] = origin2[0] - origin1[0];
    
new_velocity[1] = origin2[1] - origin1[1];
    
new_velocity[2] = origin2[2] - origin1[2];
    new 
Float:num floatsqroot(speed*speed / (new_velocity[0]*new_velocity[0] + new_velocity[1]*new_velocity[1] + new_velocity[2]*new_velocity[2]));
    
new_velocity[0] *= num;
    
new_velocity[1] *= num;
    
new_velocity[2] *= num;
    return 
1;
}


stock create_blast(const Float:originF[3], red=255green=255blue=255)
{    
    
// Les start!
    
engfunc(EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYoriginF0);
    
write_byte(TE_SPRITETRAIL);
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y
    
engfunc(EngFunc_WriteCoordoriginF[2]); // z
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x velocity
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y velocity
    
engfunc(EngFunc_WriteCoordoriginF[2]); // z velocity
    
write_short(g_GlowSpr); // sprite index
    
write_byte(35); // sprite count
    
write_byte(5); // life
    
write_byte(1); // size
    
write_byte(60); // velocity
    
write_byte(60); // velocity
    
message_end(); 
    
    
// Light!
    
engfunc(EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYoriginF0);
    
write_byte(TE_DLIGHT); // TE id
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y
    
engfunc(EngFunc_WriteCoordoriginF[2]); // z
    
write_byte(30); // radius
    
write_byte(red); // red
    
write_byte(green); // green
    
write_byte(blue); // blue
    
write_byte(20); // life
    
write_byte(20); // decay rate
    
message_end();        
    
    
// Smallest ring
    
engfunc(EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYoriginF0);
    
write_byte(TE_BEAMCYLINDER); // TE id
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y
    
engfunc(EngFunc_WriteCoordoriginF[2]); // z
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x axis
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y axis
    
engfunc(EngFunc_WriteCoordoriginF[2]+385.0); // z axis
    
write_short(g_exploSpr); // sprite
    
write_byte(0); // startframe
    
write_byte(0); // framerate
    
write_byte(4); // life
    
write_byte(60); // width
    
write_byte(0); // noise
    
write_byte(red); // red
    
write_byte(green); // green
    
write_byte(blue); // blue
    
write_byte(200); // brightness
    
write_byte(0); // speed
    
message_end();
    
    
// Medium ring
    
engfunc(EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYoriginF0);
    
write_byte(TE_BEAMCYLINDER); // TE id
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y
    
engfunc(EngFunc_WriteCoordoriginF[2]); // z
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x axis
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y axis
    
engfunc(EngFunc_WriteCoordoriginF[2]+470.0); // z axis
    
write_short(g_exploSpr); // sprite
    
write_byte(0); // startframe
    
write_byte(0); // framerate
    
write_byte(4); // life
    
write_byte(60); // width
    
write_byte(0); // noise
    
write_byte(red); // red
    
write_byte(green); // green
    
write_byte(blue); // blue
    
write_byte(200); // brightness
    
write_byte(0); // speed
    
message_end();
    
    
// Largest ring
    
engfunc(EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYoriginF0);
    
write_byte(TE_BEAMCYLINDER); // TE id
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x
    
engfunc(EngFunc_WriteCoordoriginF[1]);// y
    
engfunc(EngFunc_WriteCoordoriginF[2]); // z
    
engfunc(EngFunc_WriteCoordoriginF[0]); // x axis
    
engfunc(EngFunc_WriteCoordoriginF[1]); // y axis
    
engfunc(EngFunc_WriteCoordoriginF[2]+555.0); // z axis
    
write_short(g_exploSpr); // sprite
    
write_byte(0); // startframe
    
write_byte(0); // framerate
    
write_byte(4); // life
    
write_byte(60); // width
    
write_byte(0); // noise
    
write_byte(red); // red
    
write_byte(green); // green
    
write_byte(blue); // blue
    
write_byte(200); // brightness
    
write_byte(0); // speed
    
message_end();
}

public 
bool:is_solid(ent)
{
    
// Here we account for ent = 0, where 0 means it's part of the map (and therefore is solid)
    
return ( ent ? ( (entity_get_int(entEV_INT_solid) > SOLID_TRIGGER) ? true false ) : true );
}
/*
public tercerapersona(id)
{
    set_view(id, CAMERA_3RDPERSON);
    return PLUGIN_HANDLED;
}
public primerapersona(id)
{
    set_view(id, CAMERA_NONE);
    return PLUGIN_HANDLED;
}
*/ 
[/spoiler]

 @"mxemexico" @"totopizza"
Algo que se le puede implementar a este item es el "Empuje critico"

¿Qué significa esto?

Esta granada se le puede implementar un %X a su explosión con la finalidad de que si un jugador es afectado por el empuje y choca contra una pared este muera por el impacto, OJO esto quiere decir si hay 10 jugadores juntos, solo 1 o 2 máximo podrian salir con este "empuje critico"

¿Posibles bugs?

Que el empuje haga que un jugador choque contra otro y este muera haciendo parecer que esta entidad "jugador" sea dicho muro.
Me parece un buen aporte, le da un nuevo aire al papel de traidor, mis sugerencias son estas:
1.- Agregar slow de 3-5 segundos al recibir el impacto de la granada, viéndolo del modo tryhard da más posibilidades de poder reubicarse el traidor.
2.- Te apoyo con lo de no agregar daño y mucho menos un daño que cause la muerte inmediata, ya que por posibles bugs y además lo roto que suena hecharía bastante a perder la experiencia de juego de los jugadores y haría muy chetado el modo traidor.
Buen item pero que al momento de matar a tu team te vayas ban porque lo hacen a drede con la Target
(07-29-2020, 04:53 PM)T H E B O S S¹ escribió: [ -> ]Buen item pero que al momento de matar a tu team te vayas ban porque lo hacen a drede con la Target

No se pueden morir con la granada. Si te caes no te quita vida, osea, no hay daño por caída
(07-29-2020, 12:34 PM)Legend escribió: [ -> ]Algo que se le puede implementar a este item es el "Empuje critico"

¿Qué significa esto?

Esta granada se le puede implementar un %X a su explosión con la finalidad de que si un jugador es afectado por el empuje y choca contra una pared este muera por el impacto, OJO esto quiere decir si hay 10 jugadores juntos, solo 1 o 2 máximo podrian salir con este "empuje critico"

¿Posibles bugs?

Que el empuje haga que un jugador choque contra otro y este muera haciendo parecer que esta entidad "jugador" sea dicho muro.

Mi idea no es agregar daño a la granada, pues estaría demasiado desnivelado. De hecho por el mismo motivo eliminé el daño por caída cuando la granada te empuja.
xD es una buena idea, abre a nuevas posibilidades de divertirse dentro del server xD (Sin implicación de daño)
Esta muy cool la idea, no estaria mal que se implementara en el servidor, puede que haya posibles bugs pero eso es lo de menos, como en todo. 
Buen aporte mugrogabs?
Es sin duda un item bastante útil, pero si se agrega daño dejaría atrás el balance actual, es perfecto para su propósito; el facilitar que los traidores escapen cuando se encuentran en aprietos, aunque lo usarán para trollear más que todo, jajaja.

También sería genial si agregan tu otro item: https://www.mxemexico.com/tema-ttt-item-...-detective