Item extra: Molotov cocktail No ZP
#1
Hola, hemos estado intentando usar este plugin pero no hay caso, el servidor de vez en cuando crashea (al inicio de la ronda segun testeo nuestro cuando se compra un molotov por lo general). Al caer el servidor no muestra errores en consola. Se ha testeado en Linux con AMXX 1.8.9, Metamod 1.21p37.

Capaz alguien de aquí nos ve el error que esta causando esto:

Código PHP:
// Uncomment the following line to enable debug logging.
#define MOLOTOV_DEBUG


#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <fakemeta_util>
#include <cstrike>
#include <csx>        // Used only for custom_weapon_* functions

// If you really want to same some memory and know you won't have 32 players, you can change this.
#define MAX_PLAYERS        32
#define ADMIN_ACCESS        ADMIN_KICK

#define ANTI_LAGG        7    // Define los cálculos máximos antes de que se genere una llama sin verificar si está en el suelo
// Esto es para evitar retrasos en entradas realmente estrechas donde podría terminar con 400 cálculos por llama. Sugerido: <= 10

#define MOLOTOV_HARD_LIMIT    10    // Cócteles Molotov máximos que este código es capaz de manejar sin errores (por jugador)

// Task IDs
#define MOLOTOV_TASKID_OFFSET    MOLOTOV_HARD_LIMIT

// These task IDs are dynamically set per-Molotov
#define MOLOTOV_TASKID_BASE1    2000                        // By default, with 32 players, task ids
#define MOLOTOV_TASKID_BASE2    MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET * MAX_PLAYERS) // from 2000 to 2959 can
#define MOLOTOV_TASKID_BASE3    MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET * MAX_PLAYERS) // potentially be used used.

new const g_PLUGIN[]  = "Molotov Cocktail";
new const 
g_AUTHORS[] = "DynamicBits";
new const 
g_VERSION[] = "3.30";

new 
pEnabled;                // Pointer to molotov_enabled
new pMlDamage;                // Pointer to molotov_damage
new pMlRadius;                // Pointer to molotov_radius
new pFireTime;                // Pointer to molotov_firetime
new pFriendlyFire;            // Pointer to mp_friendlyfire
new pFireDmg;                // Pointer to molotov_firedamage
new pMaxMolotovs;            // Pointer to molotov_max


new pBuyZone;                // Pointer to molotov_buyzone
new pPrice;                // Pointer to molotov_price

new g_msgScoreInfo;            // ScoreInfo message ID

new g_msgDeathMsg;            // DeathMsg message ID

new g_NumMolotov[MAX_PLAYERS+1];        // How many Molotovs each player has

new bool:g_bRestarted;            // Reset Molotovs after first round restart

new g_MaxPlayers;            // Max players (calculated at runtime to make loops more efficient)
new g_wpnMolotov;            // Custom weapon ID
new bool:g_bReset;            // Reiniciar y detener las explosiones después de que finalice la ronda 
                    // Evita que reset_tasks () sea llamado una vez por jugador

new g_iFireSpriteg_iSmokeSprite[2];    // Handles to the precached sprites
new g_iMolotovOffset[MAX_PLAYERS+1];    // Offset utilizado para la ID de tarea de un jugador


// Initialize the plugin
public plugin_init() {

    
register_plugin(g_PLUGINg_VERSIONg_AUTHORS);
    
    
register_cvar("MolotovCocktail"g_VERSIONFCVAR_SERVER|FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);

    
    
/* =================================   Punteros globales ================================= */
    
    
pEnabled register_cvar("molotov_enabled""1"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
pMlDamage register_cvar("molotov_damage""50.0"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
pMlRadius register_cvar("molotov_radius""150.0"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
pFireTime register_cvar("molotov_firetime""8"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
pFireDmg register_cvar("molotov_firedamage""7"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
pMaxMolotovs register_cvar("molotov_max""1"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
pFriendlyFire get_cvar_pointer("mp_friendlyfire");
    
pBuyZone register_cvar("molotov_buyzone""1"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
pPrice register_cvar("molotov_price""850"FCVAR_EXTDLL|FCVAR_SPONLY|FCVAR_PRINTABLEONLY);
    
    
/* =================================   Comandos say  ================================= */
    
register_clcmd("say /molotov""cmdSayMolotov");
    
register_clcmd("say_team /molotov""cmdSayMolotov");
    

    
/* =================================   Eventos  ================================= */
    
register_event("DeathMsg""logevent_deathmsg""a""2>0");
    
register_event("CurWeapon""logevent_curweapon""be""1=1");
    
register_event("HLTV""logevent_new_round""a""1=0""2=0");
    
register_event("TextMsg""logevent_gamerestart""a""2=#Game_Commencing""2=#Game_will_restart_in");
    
register_logevent("logevent_round_end"2"1=Round_End");
    
register_forward(FM_EmitSound"fw_emitsound");

    
    
g_MaxPlayers get_maxplayers();

    
g_msgScoreInfo get_user_msgid("ScoreInfo");

    
g_msgDeathMsg get_user_msgid("DeathMsg");

    
g_wpnMolotov custom_weapon_add("molotov"0"molotov");    // I can hardly find any documentation or sample code for this. I have no
                                    //   idea if I'm using it correctly or not. I'm not even sure what it affects.
}

public 
plugin_cfg()
{
    if(
is_plugin_loaded("Pause Plugins") > -1)
        
server_cmd("amx_pausecfg add ^"%s^""g_PLUGIN);
}  

// Precache models and sound(s)
public plugin_precache() {

    
g_iFireSprite precache_model("sprites/flame.spr");
    
g_iSmokeSprite[0] = precache_model("sprites/black_smoke3.spr");
    
g_iSmokeSprite[1] = precache_model("sprites/steam1.spr");


    
precache_model("models/molotov/p_molotov.mdl");
    
precache_model("models/molotov/v_molotov.mdl");
    
precache_model("models/molotov/w_molotov.mdl");
    
precache_model("models/molotov/w_broke_molotov.mdl");
    
    
precache_sound("molotov/molotov_fire.wav");

}

// Reset Molotovs so that a new player doesn't have any
public client_disconnected(id) {
    
g_NumMolotov[id] = 0;
}

// Captura el primer impacto del Molotov y comienza el sonido / explosión
//   Un cóctel molotov debería "explotar" en el impacto, no después de un tiempo establecido.
public fw_emitsound(entchannelsample[]) {

    if (
equal(sample[8], "he_bounce"9)) {
        
// una granada HE reboto contra algun objeto

        
new sModel[32];
        
pev(entpev_modelsModelcharsmax(sModel));

        
// Dependiendo de dónde aterrice el Molotov, el avance EmitSound puede llamarse más de 50 veces.
        // Después del primer golpe, el modelo se cambia a w_broke_molotov, por lo que este código se omite en llamadas sucesivas
        
if (equal(sModel[15], "w_molotov.mdl")) {
            
// la granada HE era una molotov
            
            
            // El sonido de ruptura de vidrio tiene un rango bajo (ATTN_STATIC) para no ser abrumador
            
emit_sound(entCHAN_AUTO"debris/glass2.wav"VOL_NORMATTN_STATIC0PITCH_LOW);

            new 
Float:fFrictionFloat:fVelocity[3];
            
pev(entpev_frictionfFriction);
            
            
// Aumenta la fricción para que parezca más realista
            
fFriction *= 1.15;                
            
            
            
set_pev(entpev_frictionfFriction);

            
// Disminuye la velocidad porque la fricción no lo hace todo
            
pev(entpev_velocityfVelocity);
            
fVelocity[0] *= 0.3;                
            
fVelocity[1] *= 0.3;
            
fVelocity[2] *= 0.3;
            
set_pev(entpev_velocityfVelocity);

            
// Reemplazo por explosión normal de granada
            
molotov_explode(ent);                

            return 
FMRES_SUPERCEDE;
        } else if (
equal(sModel[15], "w_broke_molotov.")) {
            
// "mdl" se trunca debido al tamaño de la matriz, que está bien
            
            // No toques ningún sonido para rebotes.
            
return FMRES_SUPERCEDE;            
        }
    }
    
    return 
FMRES_IGNORED;
}

// Cuando el jugador cambie las armas al Molotov, actualice el modelo.
public logevent_curweapon(id) {

    if (!
get_pcvar_num(pEnabled) || !is_user_alive(id)) {
        
// plugin desactivado o jugador muerto
        
return PLUGIN_CONTINUE;
    }

    if (!
g_NumMolotov[id]) {    
        
// el jugador no compro molotov y la anulacion esta desactivada
        
return PLUGIN_CONTINUE;
    }

    new 
iWeaponID get_user_weapon(id__);

    if (
iWeaponID != CSW_HEGRENADE) {
        
// el usuario cambio de arma pero no es una granada HE
        
return PLUGIN_CONTINUE;
    }

    
// seteamos la molotov
    
set_pev(idpev_viewmodel2"models/molotov/v_molotov.mdl");    // View model (First person)    *model2 doesn't require allocating the string
    
set_pev(idpev_weaponmodel2"models/molotov/p_molotov.mdl");    // Player model (Third person)

    
return PLUGIN_CONTINUE;
}


// Reset Molotovs on death
public logevent_deathmsg() {
#if defined MOLOTOV_DEBUG
    
log_amx("[MC] ========== DeathMsg ========== Killer(%d) Victim(%d)"read_data(1), read_data(2));
#endif

    // Si el jugador muere le borramos las molotov
    
new victim read_data(2);
    
    
// cuando el jugador tiene la molotov en la mano y muere se convertia en una granada HE
    
set_task(5.0"reset_molotov"victim);
    
}

public 
reset_molotov(id) {
    
g_NumMolotov[id] = 0;
}


public 
logevent_gamerestart() {
#if defined MOLOTOV_DEBUG
    
log_amx("[MC] ========== Game Restart ==========");
#endif
    
g_bRestarted true;
    
    
    
// Asegúrate de que el jugador no haya comprado rápidamente un Molotov antes de la primera ronda real
    // Game restarting o game commencing
    
    // Reestablece todas las molotov a cero
    
arrayset(g_NumMolotov0sizeof(g_NumMolotov));
    
    
reset_tasks();
    
#if defined MOLOTOV_DEBUG
    
log_amx("[MC] ========== Game Restart finish ==========");
#endif    
    
}


public 
logevent_round_end() {
#if defined MOLOTOV_DEBUG
    
log_amx("[MC] ========== Round End ==========");
#endif

    
if (!g_bReset) {
        
#if defined MOLOTOV_DEBUG
            
log_amx("[MC] Ejecuta reset_tasks()");
        
#endif
        
        
g_bReset true;
        
reset_tasks();
        
        
#if defined MOLOTOV_DEBUG
            
log_amx("[MC] Termina de ejecutar reset_tasks()");
        
#endif
    
}
    
    
#if defined MOLOTOV_DEBUG
    
log_amx("[MC] ========== Round End finish ==========");
#endif        
}

public 
logevent_new_round() {
#if defined MOLOTOV_DEBUG
    
log_amx("[MC] ========== New Round ==========");
#endif    

    
if (!get_pcvar_num(pEnabled)) {
        return 
PLUGIN_CONTINUE;
    }                        
    
#if defined MOLOTOV_DEBUG
    
log_amx("[MC] ========== New Round finish ==========");
#endif    

    // Detiene el bloqueo
    
g_bReset false;
    
g_bRestarted false;

    return 
PLUGIN_CONTINUE;
}

// Handle the /molotov command and molotov menu
public cmdSayMolotov(id) {
    if (!
get_pcvar_num(pEnabled)) {
        return 
PLUGIN_HANDLED;
    }
    
    if (
g_bRestarted || g_bReset) {
        
// La eliminacion de los task todavia esta en marcha
        
client_print(idprint_center"No podes comprar una molotov en este momento.");
        return 
PLUGIN_HANDLED;
    }

    if (!
is_user_alive(id)) {
        
client_print(idprint_center"You can't buy Molotov cocktails because you are dead.");
        return 
PLUGIN_HANDLED;
    }

    if (!
cs_get_user_buyzone(id) && get_pcvar_num(pBuyZone)) {
        
client_print(idprint_center"You are not in a buyzone.");
        return 
PLUGIN_HANDLED;
    }

    new 
iMoney cs_get_user_money(id);

    if (
iMoney get_pcvar_num(pPrice)) {
        
// el jugador no tiene dinero suficiente
        
client_print(idprint_center"You don't have enough $ to buy a Molotov cocktail.");
        return 
PLUGIN_HANDLED;
    }

    if (!
g_NumMolotov[id] && user_has_weapon(idCSW_HEGRENADE)) {
        
// el jugador compro una granada HE
        
client_print(idprint_center"You already have an HE Grenade.");
        return 
PLUGIN_HANDLED;
    }

    
    if (
g_NumMolotov[id] >= get_pcvar_num(pMaxMolotovs)) {
        
        
// solo para dar un mensaje mas lindo
        
if (g_NumMolotov[id] == 1) {
            
client_print(idprint_center"You already have a Molotov cocktail.");
        } else {
            
client_print(idprint_center"You already have %d Molotov cocktails."g_NumMolotov[id]);
        }
        return 
PLUGIN_HANDLED;
    }
    
    
#if defined MOLOTOV_DEBUG
        
log_amx("[MC] ========== El jugador %d quiere comprar su molotov  =========="id);
    
#endif    

    
    // Le agregamos una molotov
    
g_NumMolotov[id]++;
    
    
    
// le cobramos la granada
    
cs_set_user_money(idiMoney get_pcvar_num(pPrice));
    
    
// le damos la granada
    
fm_give_item(id"weapon_hegrenade");
    
    
// establecemos la cantidad de granadas que tiene el jugador
    
cs_set_user_bpammo(idCSW_HEGRENADEg_NumMolotov[id]);


    
client_print(idprint_chat"You got a Molotov cocktail!");
    
    
#if defined MOLOTOV_DEBUG
        
log_amx("[MC] ========== El jugador %d termina de comprar su molotov  =========="id);
    
#endif    

    
return PLUGIN_HANDLED;
}


// Justo antes de lanzar la granada, cambia el modelo
public grenade_throw(identwid) {
    
    if (!
get_pcvar_num(pEnabled) || !is_user_connected(id) || wid != CSW_HEGRENADE) {
        return 
PLUGIN_CONTINUE;
    }

    if (!
g_NumMolotov[id]) {    
        
// El jugador no compro molotov
        
return PLUGIN_CONTINUE;
    }
    
    
#if defined MOLOTOV_DEBUG
        
log_amx("[MC] ========== El jugador %d lanza una molotov  =========="id);
    
#endif    


    
if (g_NumMolotov[id] > 0) {    
        
// Previene valores negativos
        
g_NumMolotov[id]--;
    } else {
        
g_NumMolotov[id] = 0;
    }

    
// reemplazamos el model de la deto por una molotov
    
engfunc(EngFunc_SetModelent"models/molotov/w_molotov.mdl");
    
    
// ???
    
set_pev(entpev_nextthink99999.0);

    
custom_weapon_shot(g_wpnMolotovid);

    
set_pev(entpev_teamget_user_team(id));
    
    
#if defined MOLOTOV_DEBUG
        
log_amx("[MC] ========== El jugador %d termina de lanzar una molotov  =========="id);
    
#endif

    
return PLUGIN_HANDLED;
}

// Configure la explosión, el sonido, el daño, etc.
// Se ejecuta al explotar el molotov
public molotov_explode(ent) {

    new 
param[7], iOrigin[3];
    new 
Float:fOrigin[3];
    new 
iOwner pev(entpev_owner);
    
    
// La botella rota puede continuar viajando, pero el fuego se centrará alrededor del sitio de la explosión, marcado por esta entidad temporal info_target.
    
new ent2 engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocString"info_target"));

    
pev(entpev_originfOrigin);

    
#if defined MOLOTOV_DEBUG
        
log_amx("[MC] molotov_explode ent(%d) owner(%d) ent2(%d) -----"entiOwnerent2);
    
#endif

    
param[0] = ent;
    
param[1] = ent2;
    
param[2] = iOwner;
    
param[3] = pev(entpev_team);
    
param[4] = iOrigin[0] = floatround(fOrigin[0]);
    
param[5] = iOrigin[1] = floatround(fOrigin[1]);
    
param[6] = iOrigin[2] = floatround(fOrigin[2]);

    
// Convertimos la molotov en un vidrio roto
    
engfunc(EngFunc_SetModelent"models/molotov/w_broke_molotov.mdl");

    
// Dibujamos el campo de fuego y el rango de daño
    // Se hace una llamada particular para restar el daño si el jugador se comio la molotov de lleno
    
random_fire(iOriginent2);
    
radius_damage2(iOwnerparam[3], fOriginget_pcvar_float(pMlDamage), get_pcvar_float(pMlRadius), DMG_BLASTtrue);

    
// Si la ronda finaliza debido al daño infligido por la explosión inicial (en la línea de código anterior), omita cualquier otro efecto Molotov.
    // Es posible que g_bReset ya esté configurado, por lo que es seguro verificarlo en este momento.
    
    
    /* 
    esto no creo que sea necesario ya que se tiene el reset_task
    if (g_bReset) {
        // Retire el Molotov y luego cancele la explosión.
        set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME);
        return PLUGIN_HANDLED;
    }
    */
    
    
new Float:FireTime get_pcvar_float(pFireTime);

    if (++
g_iMolotovOffset[iOwner] == MOLOTOV_HARD_LIMIT) {
        
g_iMolotovOffset[iOwner] = 0;
    }

    
// Chequeamos si hay jugadores sobre el rango de daño de la molotov
    
new tiempo_fuego floatround(FireTime 0.2floatround_floor);
    new 
tiempo_sonido floatround(FireTime) - 1;
    
    
// Quita vida quienes pisen el molotov
    
set_task(0.2"fire_damage"MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET iOwner) + g_iMolotovOffset[iOwner], param7"a"tiempo_fuego);
    
set_task(1.0"fire_sound"MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET iOwner) + g_iMolotovOffset[iOwner], param7"a"tiempo_sonido);
    
    
// Esta tarea elimina la entidad rota Molotov y "info_target" una vez que molotov_firetime ha expirado
    
set_task(FireTime"fire_stop"MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET iOwner ) + g_iMolotovOffset[iOwner], param7);

    return 
PLUGIN_CONTINUE;
}

// Hacer sonidos de fuego
public fire_sound(param[]) {
    
emit_sound(param[1], CHAN_AUTO"molotov/molotov_fire.wav"VOL_NORMATTN_NORM0PITCH_NORM);
}

// Eliminar entidades Molotov
public fire_stop(param[]) {
    if (
pev_valid(param[0])) {
        
// Molotov entity
        
set_pev(param[0], pev_flagspev(param[0], pev_flags) | FL_KILLME); 
    }
    
    if (
pev_valid(param[1])) { 
        
// entidad info_target
        
set_pev(param[1], pev_flagspev(param[1], pev_flags) | FL_KILLME); 
    }    
}

// Llama a efectos visuales y funciones de daño
public fire_damage(param[]) {

    new 
iOrigin[3], Float:fOrigin[3];
    
iOrigin[0] = param[4];
    
iOrigin[1] = param[5];
    
iOrigin[2] = param[6];

    
// Efecto visual de fuego
    
random_fire(iOriginparam[1]);

    
IVecFVec(iOriginfOrigin);
    
    
// Daño actual
    
radius_damage2(param[2], param[3], fOriginget_pcvar_float(pFireDmg), get_pcvar_float(pMlRadius), DMG_BURNfalse);
}

// Hay un radius_damage() en el motor, por lo que se cambió el nombre.
stock radius_damage2(iAttackeriAttackerTeamFloat:fOrigin[3], Float:fDamageFloat:fRangeiDmgTypebool:bCalc true) {

    new 
Float:pOrigin[3], Float:fDistFloat:fTmpDmg;
    new 
id 1iFF get_pcvar_num(pFriendlyFire);

    while (
id <= g_MaxPlayers) {
        if (!
is_user_alive(id)) {
            
// el jugador esta muerto
            
id++;
            continue;
        }


        if ((
iFF == 0) && (iAttackerTeam == get_user_team(id))) {
            
// el ff esta desactivado y el atacante es del mismo equipo
            
id++;
            continue;
        }

        
pev(idpev_originpOrigin);
        
fDist get_distance_f(fOriginpOrigin);

        if (
fDist fRange) {
            
// el jugador no esta dentro del rango del molotov
            
id++;
            continue;
        }

        if (
bCalc) {
            
fTmpDmg fDamage - (fDamage fRange) * fDist;
        } else {
            
fTmpDmg fDamage;
        }

        if (
floatround(fTmpDmg) > 0) {    
            
// This eliminated the "[CSX] Invalid damage 0" error
            // La función pasará el daño hecho por esta arma personalizada al módulo de estadísticas y otros complementos
            
custom_weapon_dmg(g_wpnMolotoviAttackeridfloatround(fTmpDmg), 0);
        }

        if (
pev(idpev_health) <= fTmpDmg) {
            
kill(iAttackeridiAttackerTeam);
        } else {
            
fm_fakedamage(id"molotov"fTmpDmgiDmgType);
        }
        
        
// seguimos con el siguiente jugador
        
id++;
    }
    
    
// At this point, i is one higher than the highest possible player ID, so this loop only affects non-player entities
    
    /*
    esto realmente no se para que sirve
    
    while ((id = engfunc(EngFunc_FindEntityInSphere, id, fOrigin, fRange))) {    
    // Extra parentheses fix warning 211: possibly unintended assignment
        if (pev(id, pev_takedamage)) {
            if (bCalc) {
                pev(id, pev_origin, pOrigin);
                fTmpDmg = fDamage - (fDamage / fRange) * get_distance_f(fOrigin, pOrigin);
            } else {
                fTmpDmg = fDamage;
            }
            fm_fakedamage(id, "molotov", fTmpDmg, iDmgType);
        }
    }*/
}

// Este stock solo crea el efecto visual. No maneja ningún daño.
stock random_fire(Origin[3], ent) {

    static 
iRangeiOrigin[3], g_gi;

    
iRange get_pcvar_num(pMlRadius);

    for (
1<= 5i++) {

        
g_g 1;

        
iOrigin[0] = Origin[0] + random_num(-iRangeiRange);
        
iOrigin[1] = Origin[1] + random_num(-iRangeiRange);
        
iOrigin[2] = Origin[2];
        
iOrigin[2] = ground_z(iOriginent);

        while (
get_distance(iOriginOrigin) > iRange) {        
        
// If iOrigin is too far away, recalculate its position

            
iOrigin[0] = Origin[0] + random_num(-iRangeiRange);
            
iOrigin[1] = Origin[1] + random_num(-iRangeiRange);
            
iOrigin[2] = Origin[2];

            if (++
g_g >= ANTI_LAGG) {
                
iOrigin[2] = ground_z(iOriginent1);
            } else {
                
iOrigin[2] = ground_z(iOriginent);
            }
        }

        
// este valor random establece el alto del sprite de fuego
        
new rand random_num(15);

        
message_begin(MSG_BROADCASTSVC_TEMPENTITY);
        
write_byte(TE_SPRITE);
        
write_coord(iOrigin[0]);    // Position
        
write_coord(iOrigin[1]);
        
write_coord(iOrigin[2] + rand 5);  // aca establece un poco la altura
        
write_short(g_iFireSprite);    // Sprite index
        
write_byte(rand);        // Scale
        
write_byte(100);        // Brightness
        
message_end();
    }

    
// Una bocanada de humo por cada llamada a random_fire, independientemente del número de llamas
    
message_begin(MSG_BROADCASTSVC_TEMPENTITY);
    
write_byte(TE_SMOKE);
    
write_coord(iOrigin[0]);            // Position
    
write_coord(iOrigin[1]);
    
write_coord(iOrigin[2] + 60);            // esto establece la altura del humo
    
write_short(g_iSmokeSprite[random_num(01)]);    // Sprite index
    
write_byte(random_num(1030));            // Scale
    
write_byte(random_num(1020));            // Framerate
    
message_end();

}

// Detenga todas las tareas de efectos visuales / daños físicos
stock reset_tasks() {
#if defined MOLOTOV_DEBUG
    
new tmpdbgid;
#endif

    
for (new 1g_MaxPlayersi++) {
        for (new 
oMOLOTOV_TASKID_OFFSETo++) {
            if (
task_exists(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET i) + o)) {
                
remove_task(MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET i) + o);
                
                
#if defined MOLOTOV_DEBUG
                    
tmpdbgid MOLOTOV_TASKID_BASE1 + (MOLOTOV_TASKID_OFFSET i) + o;
                    
log_amx("[MC] %d exists. ----------==========----------"tmpdbgid);
                
#endif
            
}

            if (
task_exists(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET i) + o)) {
                
remove_task(MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET i) + o);
                
                
                
#if defined MOLOTOV_DEBUG
                    
tmpdbgid MOLOTOV_TASKID_BASE2 + (MOLOTOV_TASKID_OFFSET i) + o;
                    
log_amx("[MC] %d exists. ----------==========----------"tmpdbgid);
                
#endif
            
}
            
            
            if (
task_exists(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET i) + o)) {
                
remove_task(MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET i) + o);
                
                
                
#if defined MOLOTOV_DEBUG
                    
tmpdbgid MOLOTOV_TASKID_BASE3 + (MOLOTOV_TASKID_OFFSET i) + o;
                    
log_amx("[MC] %d exists. ----------==========----------"tmpdbgid);
                
#endif
            
}
            
// La tercera tarea para cada Molotov no se detiene, por lo que puede eliminar las entidades Molotov / info_target.
        
}
    }
}

// Esta función maneja el asesinato y la puntuación.
//   iKillerTeam se almacena porque el asesino puede desconectarse antes de que el Molotov mate a alguien, lo que lleva a una puntuación imprecisa
stock kill(iKilleriVictimiKillerTeam) {
    
    
message_begin(MSG_ALLg_msgDeathMsg, {0,0,0}, 0);
    
write_byte(iKiller);        // Killer ID
    
write_byte(iVictim);        // Victim ID
    
write_byte(0);            // Is Headshot?

    
write_string("molotov");    // Truncated Weapon Name
    
    
message_end();

    
    
// This block of code actually kills the user (silently - DeathMsg was already created)
    
new iVictimTeam get_user_team(iVictim);
    new 
iMsgBlock get_msg_block(g_msgDeathMsg);    // Store original block value
    
set_msg_block(g_msgDeathMsgBLOCK_ONCE);    // Start blocking DeathMsg

    
new iKillerFrags get_user_frags(iKiller);
    new 
iVictimFrags get_user_frags(iVictim);

    
    if (
iKiller != iVictim) {
        
// Agregue frag que user_kill () eliminará
        
fm_set_user_frags(iVictimiVictimFrags 1);            
    }

    if (
iKillerTeam != iVictimTeam) {
        
iKillerFrags++;                            // Killer's Score = Score + 1
    
} else {
        
iKillerFrags--;                            // Killer's Score = Score - 1
    
}
    
    
fm_set_user_frags(iKilleriKillerFrags);

    
user_kill(iVictim0);
    
set_msg_block(g_msgDeathMsgiMsgBlock);        // Stop blocking DeathMsg

    // No estoy realmente seguro de si esto hace algo, pero parece coincidir con el wiki de Valve: https://developer.valvesoftware.com/wiki/HL_Log_Standard
    
new sVictim[32], sVictimAuth[35], sVictimTeam[32];
    
get_user_name(iVictimsVictimcharsmax(sVictim));
    
get_user_authid(iVictimsVictimAuthcharsmax(sVictimAuth));
    
get_user_team(iVictimsVictimTeamcharsmax(sVictimTeam));    // TERRORIST, CT, Allies, Axis, #Dustbowl_team1 (Attackers/Blue), #Dustbowl_team2 (Defenders/Red)
    
    // Lo que se va a mostrar en la consola
    
if (iKiller == iVictim) {
        
log_message("^"%s<%d><%s><%s>^" committed suicide with ^"molotov^""sVictimget_user_userid(iVictim), sVictimAuthsVictimTeam);
    } else if (
is_user_connected(iKiller)) {
        new 
sKiller[32], sKillerAuth[35], sKillerTeam[32];
        
get_user_name(iKillersKillercharsmax(sKiller));
        
get_user_authid(iKillersKillerAuthcharsmax(sKillerAuth));
        
get_user_team(iKillersKillerTeamcharsmax(sKillerTeam));
        
log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"molotov^""sKillerget_user_userid(iKiller), sKillerAuthsKillerTeamsVictimget_user_userid(iVictim), sVictimAuthsVictimTeam);
    }
    
// TODO: There currently isn't a log message for a kill by a disconnected player. The wiki doesn't show the expected format.

// Money (CS) & Score Info

    
new iMoney;
    if (
iKillerTeam == iVictimTeam) {
        
// el jugador se suicido
        
iMoney cs_get_user_money(iKiller) - 3300;            // TODO - $1500 hostage kill penalty
        
cs_set_user_money(iKilleriMoney iMoney);
    } else {
        
// le otorgamos dinero por una kill
        
iMoney cs_get_user_money(iKiller) + 300;
        
cs_set_user_money(iKilleriMoney 16000 16000 iMoney);
    }

    
message_begin(MSG_ALLg_msgScoreInfo);        // Killer ScoreInfo
    
write_byte(iKiller);
    
write_short(iKillerFrags);
    
write_short(get_user_deaths(iKiller));
    
write_short(0);
    
write_short(iKillerTeam);
    
message_end();
}

// Intenta soltar las coordenadas pasadas al nivel del suelo
stock ground_z(iOrigin[3], entskip 0iRecursion 0) {

    
iOrigin[2] += random_num(580);

    if (!
pev_valid(ent)) {
        return 
iOrigin[2];
    }

    new 
Float:fOrigin[3];
    
IVecFVec(iOriginfOrigin);
    
set_pev(entpev_originfOrigin);
    
engfunc(EngFunc_DropToFloorent);

    if (!
skip && !engfunc(EngFunc_EntIsOnFloorent)) {
        if (
iRecursion >= ANTI_LAGG) {
            
skip 1;
        }

        return 
ground_z(iOriginentskip, ++iRecursion);
    }

    
pev(entpev_originfOrigin);

    return 
floatround(fOrigin[2]);


Debug al caer
Código:
L 02/22/2020 - 22:06:33: [molotov_cocktail.amxx] [MC] ========== El jugador 4 quiere comprar su molotov  ==========
L 02/22/2020 - 22:06:33: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de comprar su molotov  ==========
L 02/22/2020 - 22:06:38: [molotov_cocktail.amxx] [MC] ========== El jugador 4 lanza una molotov  ==========
L 02/22/2020 - 22:06:38: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de lanzar una molotov  ==========
L 02/22/2020 - 22:06:39: [molotov_cocktail.amxx] [MC] molotov_explode ent(128) owner(4) ent2(131) -----
L 02/22/2020 - 22:06:39: [molotov_cocktail.amxx] [MC] ========== El jugador 4 quiere comprar su molotov  ==========
L 02/22/2020 - 22:06:39: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de comprar su molotov  ==========
L 02/22/2020 - 22:06:42: [molotov_cocktail.amxx] [MC] ========== El jugador 4 lanza una molotov  ==========
L 02/22/2020 - 22:06:42: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de lanzar una molotov  ==========
L 02/22/2020 - 22:06:42: [molotov_cocktail.amxx] [MC] ========== El jugador 4 quiere comprar su molotov  ==========
L 02/22/2020 - 22:06:42: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de comprar su molotov  ==========
L 02/22/2020 - 22:06:43: [molotov_cocktail.amxx] [MC] molotov_explode ent(132) owner(4) ent2(119) -----
L 02/22/2020 - 22:06:44: [molotov_cocktail.amxx] [MC] ========== El jugador 4 lanza una molotov  ==========
L 02/22/2020 - 22:06:44: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de lanzar una molotov  ==========
L 02/22/2020 - 22:06:45: [molotov_cocktail.amxx] [MC] molotov_explode ent(135) owner(4) ent2(133) -----
L 02/22/2020 - 22:06:46: [molotov_cocktail.amxx] [MC] ========== El jugador 4 quiere comprar su molotov  ==========
L 02/22/2020 - 22:06:46: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de comprar su molotov  ==========
L 02/22/2020 - 22:06:49: [molotov_cocktail.amxx] [MC] ========== El jugador 4 lanza una molotov  ==========
L 02/22/2020 - 22:06:49: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de lanzar una molotov  ==========
L 02/22/2020 - 22:06:50: [molotov_cocktail.amxx] [MC] molotov_explode ent(128) owner(4) ent2(131) -----
L 02/22/2020 - 22:06:51: [molotov_cocktail.amxx] [MC] ========== El jugador 4 quiere comprar su molotov  ==========
L 02/22/2020 - 22:06:51: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de comprar su molotov  ==========
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] ========== Round End ==========
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] Ejecuta reset_tasks()
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] 2047 exists. ----------==========----------
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] 2367 exists. ----------==========----------
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] 2687 exists. ----------==========----------
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] Termina de ejecutar reset_tasks()
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] ========== Round End finish ==========
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] ========== El jugador 4 lanza una molotov  ==========
L 02/22/2020 - 22:06:56: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de lanzar una molotov  ==========
L 02/22/2020 - 22:06:57: [molotov_cocktail.amxx] [MC] molotov_explode ent(119) owner(4) ent2(132) -----
L 02/22/2020 - 22:07:01: [molotov_cocktail.amxx] [MC] ========== New Round ==========
L 02/22/2020 - 22:07:01: [molotov_cocktail.amxx] [MC] ========== New Round finish ==========
L 02/22/2020 - 22:07:01: [molotov_cocktail.amxx] [MC] ========== El jugador 4 quiere comprar su molotov  ==========
L 02/22/2020 - 22:07:01: [molotov_cocktail.amxx] [MC] ========== El jugador 4 termina de comprar su molotov  ==========
Protocol version 48
Gracias por su ayuda.
Empresa líder en la prestación de servicios de hosting, servidores de juegos, servidores de voz y alojamiento web en Argentina.
www.4evergaming.com.ar
Responder
#2
En versiones anteriores a 1.8.9 no se cae?, rehlds no tenes no?
Responder
#3
(23/02/2020, 01:30 PM)Pan Bimbo (? escribió: En versiones anteriores a 1.8.9 no se cae?, rehlds no tenes no?

Con versiones anteriores de AMXX no he probado ya que no las utilizo.
Con ReHLDS ya he probado y sucede lo mismo.

Para mi que el error viene de algun task..
Empresa líder en la prestación de servicios de hosting, servidores de juegos, servidores de voz y alojamiento web en Argentina.
www.4evergaming.com.ar
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)