При поджоге зомби человеку бросившему гранату воспроизводился звук

Сообщения
15
Реакции
2
Как правильно сделать когда человек бросает святую гранату, при условии что зомби попали под ее взрыв, у человека воспроизводился определенный звук, пробовал сам сделать, вот только получается что когда рядом находится два и более зомби у человека воспроизводится сразу несколько звуков... Как сделать даже если рядом несколько целей, попавших под взрыв гранаты у человека воспроизводился всего один звук а не воспроизводился несколько раз в не зависимости от того, сколько зомби попало под взрыв гранаты?
Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <zombieplague>
#include <xs>

#define MAX_CLIENTS 32
#define DMG_GRENADE (1<<24)
#define TASKID_HOLYBOMB_BURN 3900

#define linux_diff_weapon 4
#define linux_diff_player 5
#define m_pPlayer 41
#define m_LastHitGroup 75

new const WEAPON_REFERENCE[] = "weapon_smokegrenade";
new const WEAPON_DEFAULT_WORLD_MODEL[] = "models/w_smokegrenade.mdl";
const WEAPON_DEFAULT_CSW = CSW_SMOKEGRENADE;
new const WEAPON_AMMO_TYPE[] = "SmokeGrenade";
const WEAPON_SPECIAL_CODE = 6666;

new const WEAPON_VIEW_MODEL[] = "models/x/v_holybomb.mdl";
new const WEAPON_PLAYER_MODEL[] = "models/x/p_holybomb.mdl";
new const WEAPON_WORLD_MODEL[] = "models/x/w_holybomb.mdl";
const WEAPON_WORLD_MODEL_BODY = 0;

new const WEAPON_EXPLODE_SOUND[] = "weapons/holywater_explosion.wav";
new const WEAPON_EXPLODE_SPRITE[] = "sprites/x/holybomb_exp.spr";
new const WEAPON_BURN_SPRITE[] = "sprites/x/holybomb_burn.spr"

const Float: WEAPON_GRENADE_RADIUS = 150.0; // Радиус взрыва, в котором заденет всех врагов
const Float: WEAPON_GRENADE_DAMAGE = 700.0; // Урон при взрыве
const WEAPON_GRENADE_DMGTYPE = DMG_GRENADE; // Тип урона при взрыве

const Float: GRENADE_BURN_DELAY = 1.0; // С каким промежутком времени будет проходить урон
const Float: GRENADE_BURN_DAMAGE = 200.0; // Кол-во урона за 1 сек
const GRENADE_BURN_DURATION = 10; // Длительность горения

new const WEAPON_WEAPONLIST_DIR[] = "x/weapon_holybomb";
new const iWeaponList[] =
{
    //11, 2, -1, -1, 3, 2, 25, 24 // weapon_flashbang
    //12, 1,  -1, -1, 3, 1, 4,  24 // weapon_hegrenade
    13, 1,  -1, -1, 3, 3, 9,  24 // weapon_smokegrenade
};

new gl_iItemID,

    gl_iszModelIndex_Burn,
    gl_iszModelIndex_Smoke,
    gl_iszModelIndex_Explode,

    gl_iUserHasHolyBomb[MAX_CLIENTS + 1],
    gl_iUserBurningDuration[MAX_CLIENTS + 1],

    gl_iMsgID_WeaponList,
    gl_iMsgId_DeathMsg;

public plugin_init()
{
    register_plugin("[ZP] Grenade: Holy Bomb", "1.0 | 2019", "xUnicorn (t3rkecorejz)");

    register_forward(FM_SetModel, "FM_Hook_SetModel_Pre", false);

    RegisterHam(Ham_Think, "grenade", "CGrenade__Think_Pre", false);
    RegisterHam(Ham_Touch, "grenade", "CGrenade__Touch_Pre", false);

    RegisterHam(Ham_Item_Deploy, WEAPON_REFERENCE, "CGrenade__Deploy_Post", true);
    RegisterHam(Ham_Item_AddToPlayer, WEAPON_REFERENCE, "CGrenade__AddToPlayer_Post", true);

    gl_iItemID = zp_register_extra_item("Holy Bomb", 10, ZP_TEAM_HUMAN);
    gl_iMsgID_WeaponList = get_user_msgid("WeaponList");
    gl_iMsgId_DeathMsg = get_user_msgid("DeathMsg");
}

public plugin_precache()
{
    register_clcmd(WEAPON_WEAPONLIST_DIR, "Command_HookWeapon");

    // Models
    engfunc(EngFunc_PrecacheModel, WEAPON_VIEW_MODEL);
    engfunc(EngFunc_PrecacheModel, WEAPON_PLAYER_MODEL);
    engfunc(EngFunc_PrecacheModel, WEAPON_WORLD_MODEL);

    // Sounds
    engfunc(EngFunc_PrecacheSound, WEAPON_EXPLODE_SOUND);
    UTIL_PrecacheSoundsFromModel(WEAPON_VIEW_MODEL);

    // Other
    UTIL_PrecacheSpritesFromTxt(WEAPON_WEAPONLIST_DIR);

    // Model Index
    gl_iszModelIndex_Burn = engfunc(EngFunc_PrecacheModel, WEAPON_BURN_SPRITE);
    gl_iszModelIndex_Smoke = engfunc(EngFunc_PrecacheModel, "sprites/black_smoke3.spr");
    gl_iszModelIndex_Explode = engfunc(EngFunc_PrecacheModel, WEAPON_EXPLODE_SPRITE);
}

public Command_HookWeapon(iPlayer)
{
    engclient_cmd(iPlayer, WEAPON_REFERENCE);
    return PLUGIN_HANDLED;
}

public Command_GiveWeapon(iPlayer)
{
    if(user_has_weapon(iPlayer, WEAPON_DEFAULT_CSW))
    {
        gl_iUserHasHolyBomb[iPlayer]++;
        ExecuteHamB(Ham_GiveAmmo, iPlayer, 1, WEAPON_AMMO_TYPE, 5);
        emit_sound(iPlayer, CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
    }
    else
    {
        gl_iUserHasHolyBomb[iPlayer] = 1;
        UTIL_GiveNamedItem(iPlayer, WEAPON_REFERENCE);
        emit_sound(iPlayer, CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

        gl_iUserHasHolyBomb[iPlayer]++;
        ExecuteHamB(Ham_GiveAmmo, iPlayer, 1, WEAPON_AMMO_TYPE, 5);
    }
}

// [ Zombie Plague ]
public zp_extra_item_selected(iPlayer, iItemID)
{
    if(iItemID == gl_iItemID)
        Command_GiveWeapon(iPlayer);
}

public zp_user_infected_post(iPlayer)
{
    if(!is_user_connected(iPlayer)) return;
    if(gl_iUserHasHolyBomb[iPlayer]) gl_iUserHasHolyBomb[iPlayer] = 0;
}

// [ Fakemeta ]
public FM_Hook_SetModel_Pre(iEntity, const szModel[])
{
    if(!pev_valid(iEntity))  return FMRES_IGNORED;

    new Float: flDamageTime; pev(iEntity, pev_dmgtime, flDamageTime);
    if(flDamageTime == 0.0) return FMRES_IGNORED;

    new iOwner = pev(iEntity, pev_owner);
    if(equal(szModel, WEAPON_DEFAULT_WORLD_MODEL))
    {
        if(gl_iUserHasHolyBomb[iOwner])
        {
            message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
            write_byte(TE_KILLBEAM);
            write_short(iEntity);
            message_end();

            set_pev(iEntity, pev_body, WEAPON_WORLD_MODEL_BODY);
            set_pev(iEntity, pev_flTimeStepSound, WEAPON_SPECIAL_CODE);

            set_pev(iEntity, pev_sequence, random_num(1, 2));
            set_pev(iEntity, pev_animtime, get_gametime());
            set_pev(iEntity, pev_framerate, 1.0);

            engfunc(EngFunc_SetModel, iEntity, WEAPON_WORLD_MODEL);

            gl_iUserHasHolyBomb[iOwner] -= 1;

            return FMRES_SUPERCEDE;
        }
    }

    return FMRES_IGNORED;
}

// [ HamSandwich ]
public CGrenade__Think_Pre(iEntity)
{
    if(!pev_valid(iEntity)) return HAM_IGNORED;

    static Float: flDamageTime; pev(iEntity, pev_dmgtime, flDamageTime);
    if(flDamageTime > get_gametime()) return HAM_IGNORED;

    if(pev(iEntity, pev_flTimeStepSound) == WEAPON_SPECIAL_CODE)
    {
        new iOwner = pev(iEntity, pev_owner);
        emit_sound(iEntity, CHAN_WEAPON, WEAPON_EXPLODE_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

        new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
        write_byte(TE_EXPLOSION);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] + 20.0);
        write_short(gl_iszModelIndex_Explode);
        write_byte(20); // Scale
        write_byte(32); // Framerate
        write_byte(TE_EXPLFLAG_NODLIGHTS|TE_EXPLFLAG_NOSOUND|TE_EXPLFLAG_NOPARTICLES);
        message_end();

        new iVictim = FM_NULLENT;
        while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOrigin, WEAPON_GRENADE_RADIUS)) > 0)
        {
            if(!is_user_alive(iVictim)) continue;
            if(!zp_get_user_zombie(iVictim)) continue;
            if(!is_wall_between_points(iOwner, iVictim)) continue;

            if(is_user_alive(iVictim))
                set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);

            ExecuteHamB(Ham_TakeDamage, iVictim, iEntity, iOwner, WEAPON_GRENADE_DAMAGE, WEAPON_GRENADE_DMGTYPE);

            new iParams[2]; iParams[0] = iOwner;
            gl_iUserBurningDuration[iVictim] += GRENADE_BURN_DURATION;
            
            if(!task_exists(iVictim + TASKID_HOLYBOMB_BURN))
                set_task(GRENADE_BURN_DELAY, "CTask__Burn_HolyBomb", iVictim + TASKID_HOLYBOMB_BURN, iParams, sizeof iParams);
        }

        set_pev(iEntity, pev_flags, FL_KILLME);
        return HAM_SUPERCEDE;
    }

    return HAM_IGNORED;
}

public CGrenade__Touch_Pre(iEntity)
{
    if(!pev_valid(iEntity)) return HAM_IGNORED;

    if(pev(iEntity, pev_flTimeStepSound) == WEAPON_SPECIAL_CODE)
    {
        new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
        if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_WATER)
        {
            set_pev(iEntity, pev_flags, FL_KILLME);
            return HAM_IGNORED;
        }

        set_pev(iEntity, pev_dmgtime, get_gametime());
    }

    return HAM_IGNORED;
}

public CGrenade__Deploy_Post(iItem)
{
    static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);

    if(!gl_iUserHasHolyBomb[iPlayer]) return HAM_IGNORED;
    if(zp_get_user_zombie(iPlayer)) return HAM_IGNORED;

    set_pev(iPlayer, pev_viewmodel2, WEAPON_VIEW_MODEL);
    set_pev(iPlayer, pev_weaponmodel2, WEAPON_PLAYER_MODEL);

    return HAM_IGNORED;
}
public CGrenade__AddToPlayer_Post(iItem, iPlayer) UTIL_WeaponList(iPlayer, gl_iUserHasHolyBomb[iPlayer]);

// [ Tasks ]
public CTask__Burn_HolyBomb(szArgs[1], iTask)
{
    new iOwner = szArgs[0];
    new iVictim = iTask - TASKID_HOLYBOMB_BURN;
    new iFlags = pev(iVictim, pev_flags);
    new Float: vecOrigin[3]; pev(iVictim, pev_origin, vecOrigin);

    if(!is_user_alive(iVictim) || !is_user_connected(iOwner) || iOwner == iVictim || zp_get_user_zombie(iOwner) || iFlags & FL_INWATER || gl_iUserBurningDuration[iVictim] < 1)
    {
        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
        write_byte(TE_SMOKE);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] - 50.0);
        write_short(gl_iszModelIndex_Smoke);
        write_byte(random_num(15, 20)); // Scale
        write_byte(random_num(10, 20)); // Framerate
        message_end();
        
        remove_task(iTask);
        return;
    }
    
    new flHealth = pev(iVictim, pev_health);
    if(flHealth - GRENADE_BURN_DAMAGE > 0.0)
    {
        if(is_user_alive(iVictim))
            set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);

        ExecuteHamB(Ham_TakeDamage, iVictim, iOwner, iOwner, GRENADE_BURN_DAMAGE, WEAPON_GRENADE_DMGTYPE);
    }
    else
    {
        set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);
        
        set_msg_block(gl_iMsgId_DeathMsg, BLOCK_SET);
        ExecuteHamB(Ham_Killed, iVictim, iOwner, 0);
        set_msg_block(gl_iMsgId_DeathMsg, BLOCK_NOT);

        message_begin(MSG_ALL, gl_iMsgId_DeathMsg);
        write_byte(iOwner);
        write_byte(iVictim);
        write_byte(0);
        write_string("grenade");
        message_end();

        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
        write_byte(TE_SMOKE);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] - 50.0);
        write_short(gl_iszModelIndex_Smoke);
        write_byte(random_num(15, 20)); // Scale
        write_byte(random_num(10, 20)); // Framerate
        message_end();

        remove_task(iTask);
        return;
    }

    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
    write_byte(TE_SPRITE);
    engfunc(EngFunc_WriteCoord, vecOrigin[0] + random_float(-5.0, 5.0));
    engfunc(EngFunc_WriteCoord, vecOrigin[1] + random_float(-5.0, 5.0));
    engfunc(EngFunc_WriteCoord, vecOrigin[2] + random_float(-10.0, 10.0));
    write_short(gl_iszModelIndex_Burn);
    write_byte(random_num(5, 7)); // Scale
    write_byte(200); // Alpha
    message_end();

    gl_iUserBurningDuration[iVictim]--;
    set_task(GRENADE_BURN_DELAY, "CTask__Burn_HolyBomb", iTask, szArgs, sizeof szArgs);
}

// [ Stocks ]
stock is_wall_between_points(iPlayer, iEntity)
{
    if(!is_user_alive(iEntity))
        return 0;

    new iTrace = create_tr2();
    new Float: flStart[3], Float: flEnd[3], Float: flEndPos[3];

    pev(iPlayer, pev_origin, flStart);
    pev(iEntity, pev_origin, flEnd);

    engfunc(EngFunc_TraceLine, flStart, flEnd, IGNORE_MONSTERS, iPlayer, iTrace);
    get_tr2(iTrace, TR_vecEndPos, flEndPos);

    free_tr2(iTrace);

    return xs_vec_equal(flEnd, flEndPos);
}

stock UTIL_GiveNamedItem(iPlayer, const szItem[])
{
    new iEntity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, szItem));
    if(!pev_valid(iEntity)) return 0;
    
    ExecuteHam(Ham_Spawn, iEntity);
    if(!ExecuteHamB(Ham_AddPlayerItem, iPlayer, iEntity))
    {
        set_pev(iEntity, pev_flags, pev(iEntity, pev_flags) | FL_KILLME);
        return 0;
    }

    ExecuteHamB(Ham_Item_AttachToPlayer, iEntity, iPlayer);
    
    return iEntity;
}

stock UTIL_PrecacheSoundsFromModel(const szModelPath[])
{
    new iFile;
    
    if((iFile = fopen(szModelPath, "rt")))
    {
        new szSoundPath[64];
        
        new iNumSeq, iSeqIndex;
        new iEvent, iNumEvents, iEventIndex;
        
        fseek(iFile, 164, SEEK_SET);
        fread(iFile, iNumSeq, BLOCK_INT);
        fread(iFile, iSeqIndex, BLOCK_INT);
        
        for(new k, i = 0; i < iNumSeq; i++)
        {
            fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
            fread(iFile, iNumEvents, BLOCK_INT);
            fread(iFile, iEventIndex, BLOCK_INT);
            fseek(iFile, iEventIndex + 176 * i, SEEK_SET);
            
            for(k = 0; k < iNumEvents; k++)
            {
                fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
                fread(iFile, iEvent, BLOCK_INT);
                fseek(iFile, 4, SEEK_CUR);
                
                if(iEvent != 5004)
                    continue;
                
                fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);
                
                if(strlen(szSoundPath))
                {
                    strtolower(szSoundPath);
                    engfunc(EngFunc_PrecacheSound, szSoundPath);
                }
            }
        }
    }
    
    fclose(iFile);
}

stock UTIL_PrecacheSpritesFromTxt(const szWeaponList[])
{
    new szTxtDir[64], szSprDir[64];
    new szFileData[128], szSprName[48], temp[1];

    format(szTxtDir, charsmax(szTxtDir), "sprites/%s.txt", szWeaponList);
    engfunc(EngFunc_PrecacheGeneric, szTxtDir);

    new iFile = fopen(szTxtDir, "rb");
    while(iFile && !feof(iFile))
    {
        fgets(iFile, szFileData, charsmax(szFileData));
        trim(szFileData);

        if(!strlen(szFileData))
            continue;

        new pos = containi(szFileData, "640");   
            
        if(pos == -1)
            continue;
            
        format(szFileData, charsmax(szFileData), "%s", szFileData[pos+3]);       
        trim(szFileData);

        strtok(szFileData, szSprName, charsmax(szSprName), temp, charsmax(temp), ' ', 1);
        trim(szSprName);
        
        format(szSprDir, charsmax(szSprDir), "sprites/%s.spr", szSprName);
        engfunc(EngFunc_PrecacheGeneric, szSprDir);
    }

    if(iFile) fclose(iFile);
}

stock UTIL_WeaponList(iPlayer, iEnabled)
{
    message_begin(MSG_ONE, gl_iMsgID_WeaponList, _, iPlayer);
    write_string(iEnabled ? WEAPON_WEAPONLIST_DIR : WEAPON_REFERENCE);
    write_byte(iWeaponList[0]);
    write_byte(iWeaponList[1]);
    write_byte(iWeaponList[2]);
    write_byte(iWeaponList[3]);
    write_byte(iWeaponList[4]);
    write_byte(iWeaponList[5]);
    write_byte(iWeaponList[6]);
    write_byte(iWeaponList[7]);
    message_end();
}
 

RockTheStreet

Саппорт года
Сообщения
1,743
Реакции
344
Помог
40 раз(а)
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
В теме должны быть опубликованы попытки (diff кода или последовательность действий) самостоятельного поиска решения.
 
Сообщения
15
Реакции
2
Извиняюсь,
пытался делать так, но когда в радиус взрыва попадают два и более зомби у человека воспроизводится несколько звуков
emit_sound(iVictim, CHAN_WEAPON, grenade_sound[random_num(0, sizeof (grenade_sound) - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM);
Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <zombieplague>
#include <xs>

#define MAX_CLIENTS 32
#define DMG_GRENADE (1<<24)
#define TASKID_HOLYBOMB_BURN 3900

#define linux_diff_weapon 4
#define linux_diff_player 5
#define m_pPlayer 41
#define m_LastHitGroup 75

new const grenade_sound[][] =
{
    "zombie_plague/human_sound_1.wav",
    "zombie_plague/human_sound_2.wav"
}

new const WEAPON_REFERENCE[] = "weapon_smokegrenade";
new const WEAPON_DEFAULT_WORLD_MODEL[] = "models/w_smokegrenade.mdl";
const WEAPON_DEFAULT_CSW = CSW_SMOKEGRENADE;
new const WEAPON_AMMO_TYPE[] = "SmokeGrenade";
const WEAPON_SPECIAL_CODE = 6666;

new const WEAPON_VIEW_MODEL[] = "models/x/v_holybomb.mdl";
new const WEAPON_PLAYER_MODEL[] = "models/x/p_holybomb.mdl";
new const WEAPON_WORLD_MODEL[] = "models/x/w_holybomb.mdl";
const WEAPON_WORLD_MODEL_BODY = 0;

new const WEAPON_EXPLODE_SOUND[] = "weapons/holywater_explosion.wav";
new const WEAPON_EXPLODE_SPRITE[] = "sprites/x/holybomb_exp.spr";
new const WEAPON_BURN_SPRITE[] = "sprites/x/holybomb_burn.spr"

const Float: WEAPON_GRENADE_RADIUS = 150.0; // Радиус взрыва, в котором заденет всех врагов
const Float: WEAPON_GRENADE_DAMAGE = 700.0; // Урон при взрыве
const WEAPON_GRENADE_DMGTYPE = DMG_GRENADE; // Тип урона при взрыве

const Float: GRENADE_BURN_DELAY = 1.0; // С каким промежутком времени будет проходить урон
const Float: GRENADE_BURN_DAMAGE = 200.0; // Кол-во урона за 1 сек
const GRENADE_BURN_DURATION = 10; // Длительность горения

new const WEAPON_WEAPONLIST_DIR[] = "x/weapon_holybomb";
new const iWeaponList[] =
{
    //11, 2, -1, -1, 3, 2, 25, 24 // weapon_flashbang
    //12, 1,  -1, -1, 3, 1, 4,  24 // weapon_hegrenade
    13, 1,  -1, -1, 3, 3, 9,  24 // weapon_smokegrenade
};

new gl_iItemID,

    gl_iszModelIndex_Burn,
    gl_iszModelIndex_Smoke,
    gl_iszModelIndex_Explode,

    gl_iUserHasHolyBomb[MAX_CLIENTS + 1],
    gl_iUserBurningDuration[MAX_CLIENTS + 1],

    gl_iMsgID_WeaponList,
    gl_iMsgId_DeathMsg;

public plugin_init()
{
    register_plugin("[ZP] Grenade: Holy Bomb", "1.0 | 2019", "xUnicorn (t3rkecorejz)");

    register_forward(FM_SetModel, "FM_Hook_SetModel_Pre", false);

    RegisterHam(Ham_Think, "grenade", "CGrenade__Think_Pre", false);
    RegisterHam(Ham_Touch, "grenade", "CGrenade__Touch_Pre", false);

    RegisterHam(Ham_Item_Deploy, WEAPON_REFERENCE, "CGrenade__Deploy_Post", true);
    RegisterHam(Ham_Item_AddToPlayer, WEAPON_REFERENCE, "CGrenade__AddToPlayer_Post", true);

    gl_iItemID = zp_register_extra_item("Holy Bomb", 10, ZP_TEAM_HUMAN);
    gl_iMsgID_WeaponList = get_user_msgid("WeaponList");
    gl_iMsgId_DeathMsg = get_user_msgid("DeathMsg");
}

public plugin_precache()
{
    register_clcmd(WEAPON_WEAPONLIST_DIR, "Command_HookWeapon");

    // Models
    engfunc(EngFunc_PrecacheModel, WEAPON_VIEW_MODEL);
    engfunc(EngFunc_PrecacheModel, WEAPON_PLAYER_MODEL);
    engfunc(EngFunc_PrecacheModel, WEAPON_WORLD_MODEL);

    // Sounds
    engfunc(EngFunc_PrecacheSound, WEAPON_EXPLODE_SOUND);
    UTIL_PrecacheSoundsFromModel(WEAPON_VIEW_MODEL);

    // Other
    UTIL_PrecacheSpritesFromTxt(WEAPON_WEAPONLIST_DIR);

    // Model Index
    gl_iszModelIndex_Burn = engfunc(EngFunc_PrecacheModel, WEAPON_BURN_SPRITE);
    gl_iszModelIndex_Smoke = engfunc(EngFunc_PrecacheModel, "sprites/black_smoke3.spr");
    gl_iszModelIndex_Explode = engfunc(EngFunc_PrecacheModel, WEAPON_EXPLODE_SPRITE);
  
    for (new i = 0; i < sizeof grenade_sound; i++)
        engfunc(EngFunc_PrecacheSound, grenade_sound[i]); 
}

public Command_HookWeapon(iPlayer)
{
    engclient_cmd(iPlayer, WEAPON_REFERENCE);
    return PLUGIN_HANDLED;
}

public Command_GiveWeapon(iPlayer)
{
    if(user_has_weapon(iPlayer, WEAPON_DEFAULT_CSW))
    {
        gl_iUserHasHolyBomb[iPlayer]++;
        ExecuteHamB(Ham_GiveAmmo, iPlayer, 1, WEAPON_AMMO_TYPE, 5);
        emit_sound(iPlayer, CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
    }
    else
    {
        gl_iUserHasHolyBomb[iPlayer] = 1;
        UTIL_GiveNamedItem(iPlayer, WEAPON_REFERENCE);
        emit_sound(iPlayer, CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

        gl_iUserHasHolyBomb[iPlayer]++;
        ExecuteHamB(Ham_GiveAmmo, iPlayer, 1, WEAPON_AMMO_TYPE, 5);
    }
}

// [ Zombie Plague ]
public zp_extra_item_selected(iPlayer, iItemID)
{
    if(iItemID == gl_iItemID)
        Command_GiveWeapon(iPlayer);
}

public zp_user_infected_post(iPlayer)
{
    if(!is_user_connected(iPlayer)) return;
    if(gl_iUserHasHolyBomb[iPlayer]) gl_iUserHasHolyBomb[iPlayer] = 0;
}

// [ Fakemeta ]
public FM_Hook_SetModel_Pre(iEntity, const szModel[])
{
    if(!pev_valid(iEntity))  return FMRES_IGNORED;

    new Float: flDamageTime; pev(iEntity, pev_dmgtime, flDamageTime);
    if(flDamageTime == 0.0) return FMRES_IGNORED;

    new iOwner = pev(iEntity, pev_owner);
    if(equal(szModel, WEAPON_DEFAULT_WORLD_MODEL))
    {
        if(gl_iUserHasHolyBomb[iOwner])
        {
            message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
            write_byte(TE_KILLBEAM);
            write_short(iEntity);
            message_end();

            set_pev(iEntity, pev_body, WEAPON_WORLD_MODEL_BODY);
            set_pev(iEntity, pev_flTimeStepSound, WEAPON_SPECIAL_CODE);

            set_pev(iEntity, pev_sequence, random_num(1, 2));
            set_pev(iEntity, pev_animtime, get_gametime());
            set_pev(iEntity, pev_framerate, 1.0);

            engfunc(EngFunc_SetModel, iEntity, WEAPON_WORLD_MODEL);

            gl_iUserHasHolyBomb[iOwner] -= 1;

            return FMRES_SUPERCEDE;
        }
    }

    return FMRES_IGNORED;
}

// [ HamSandwich ]
public CGrenade__Think_Pre(iEntity)
{
    if(!pev_valid(iEntity)) return HAM_IGNORED;

    static Float: flDamageTime; pev(iEntity, pev_dmgtime, flDamageTime);
    if(flDamageTime > get_gametime()) return HAM_IGNORED;

    if(pev(iEntity, pev_flTimeStepSound) == WEAPON_SPECIAL_CODE)
    {
        new iOwner = pev(iEntity, pev_owner);
        emit_sound(iEntity, CHAN_WEAPON, WEAPON_EXPLODE_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

        new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
        write_byte(TE_EXPLOSION);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] + 20.0);
        write_short(gl_iszModelIndex_Explode);
        write_byte(20); // Scale
        write_byte(32); // Framerate
        write_byte(TE_EXPLFLAG_NODLIGHTS|TE_EXPLFLAG_NOSOUND|TE_EXPLFLAG_NOPARTICLES);
        message_end();

        new iVictim = FM_NULLENT;
        while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOrigin, WEAPON_GRENADE_RADIUS)) > 0)
        {
            if(!is_user_alive(iVictim)) continue;
            if(!zp_get_user_zombie(iVictim)) continue;
            if(!is_wall_between_points(iOwner, iVictim)) continue;

            emit_sound(iVictim, CHAN_WEAPON, grenade_sound[random_num(0, sizeof (grenade_sound) - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM);
          
            if(is_user_alive(iVictim))
                set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);

            ExecuteHamB(Ham_TakeDamage, iVictim, iEntity, iOwner, WEAPON_GRENADE_DAMAGE, WEAPON_GRENADE_DMGTYPE);

            new iParams[2]; iParams[0] = iOwner;
            gl_iUserBurningDuration[iVictim] += GRENADE_BURN_DURATION;
          
            if(!task_exists(iVictim + TASKID_HOLYBOMB_BURN))
                set_task(GRENADE_BURN_DELAY, "CTask__Burn_HolyBomb", iVictim + TASKID_HOLYBOMB_BURN, iParams, sizeof iParams);
        }

        set_pev(iEntity, pev_flags, FL_KILLME);
        return HAM_SUPERCEDE;
    }

    return HAM_IGNORED;
}

public CGrenade__Touch_Pre(iEntity)
{
    if(!pev_valid(iEntity)) return HAM_IGNORED;

    if(pev(iEntity, pev_flTimeStepSound) == WEAPON_SPECIAL_CODE)
    {
        new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
        if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_WATER)
        {
            set_pev(iEntity, pev_flags, FL_KILLME);
            return HAM_IGNORED;
        }

        set_pev(iEntity, pev_dmgtime, get_gametime());
    }

    return HAM_IGNORED;
}

public CGrenade__Deploy_Post(iItem)
{
    static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);

    if(!gl_iUserHasHolyBomb[iPlayer]) return HAM_IGNORED;
    if(zp_get_user_zombie(iPlayer)) return HAM_IGNORED;

    set_pev(iPlayer, pev_viewmodel2, WEAPON_VIEW_MODEL);
    set_pev(iPlayer, pev_weaponmodel2, WEAPON_PLAYER_MODEL);

    return HAM_IGNORED;
}
public CGrenade__AddToPlayer_Post(iItem, iPlayer) UTIL_WeaponList(iPlayer, gl_iUserHasHolyBomb[iPlayer]);

// [ Tasks ]
public CTask__Burn_HolyBomb(szArgs[1], iTask)
{
    new iOwner = szArgs[0];
    new iVictim = iTask - TASKID_HOLYBOMB_BURN;
    new iFlags = pev(iVictim, pev_flags);
    new Float: vecOrigin[3]; pev(iVictim, pev_origin, vecOrigin);

    if(!is_user_alive(iVictim) || !is_user_connected(iOwner) || iOwner == iVictim || zp_get_user_zombie(iOwner) || iFlags & FL_INWATER || gl_iUserBurningDuration[iVictim] < 1)
    {
        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
        write_byte(TE_SMOKE);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] - 50.0);
        write_short(gl_iszModelIndex_Smoke);
        write_byte(random_num(15, 20)); // Scale
        write_byte(random_num(10, 20)); // Framerate
        message_end();
      
        remove_task(iTask);
        return;
    }
  
    new flHealth = pev(iVictim, pev_health);
    if(flHealth - GRENADE_BURN_DAMAGE > 0.0)
    {
        if(is_user_alive(iVictim))
            set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);

        ExecuteHamB(Ham_TakeDamage, iVictim, iOwner, iOwner, GRENADE_BURN_DAMAGE, WEAPON_GRENADE_DMGTYPE);
    }
    else
    {
        set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);
      
        set_msg_block(gl_iMsgId_DeathMsg, BLOCK_SET);
        ExecuteHamB(Ham_Killed, iVictim, iOwner, 0);
        set_msg_block(gl_iMsgId_DeathMsg, BLOCK_NOT);

        message_begin(MSG_ALL, gl_iMsgId_DeathMsg);
        write_byte(iOwner);
        write_byte(iVictim);
        write_byte(0);
        write_string("grenade");
        message_end();

        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
        write_byte(TE_SMOKE);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] - 50.0);
        write_short(gl_iszModelIndex_Smoke);
        write_byte(random_num(15, 20)); // Scale
        write_byte(random_num(10, 20)); // Framerate
        message_end();

        remove_task(iTask);
        return;
    }

    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
    write_byte(TE_SPRITE);
    engfunc(EngFunc_WriteCoord, vecOrigin[0] + random_float(-5.0, 5.0));
    engfunc(EngFunc_WriteCoord, vecOrigin[1] + random_float(-5.0, 5.0));
    engfunc(EngFunc_WriteCoord, vecOrigin[2] + random_float(-10.0, 10.0));
    write_short(gl_iszModelIndex_Burn);
    write_byte(random_num(5, 7)); // Scale
    write_byte(200); // Alpha
    message_end();

    gl_iUserBurningDuration[iVictim]--;
    set_task(GRENADE_BURN_DELAY, "CTask__Burn_HolyBomb", iTask, szArgs, sizeof szArgs);
}

// [ Stocks ]
stock is_wall_between_points(iPlayer, iEntity)
{
    if(!is_user_alive(iEntity))
        return 0;

    new iTrace = create_tr2();
    new Float: flStart[3], Float: flEnd[3], Float: flEndPos[3];

    pev(iPlayer, pev_origin, flStart);
    pev(iEntity, pev_origin, flEnd);

    engfunc(EngFunc_TraceLine, flStart, flEnd, IGNORE_MONSTERS, iPlayer, iTrace);
    get_tr2(iTrace, TR_vecEndPos, flEndPos);

    free_tr2(iTrace);

    return xs_vec_equal(flEnd, flEndPos);
}

stock UTIL_GiveNamedItem(iPlayer, const szItem[])
{
    new iEntity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, szItem));
    if(!pev_valid(iEntity)) return 0;
  
    ExecuteHam(Ham_Spawn, iEntity);
    if(!ExecuteHamB(Ham_AddPlayerItem, iPlayer, iEntity))
    {
        set_pev(iEntity, pev_flags, pev(iEntity, pev_flags) | FL_KILLME);
        return 0;
    }

    ExecuteHamB(Ham_Item_AttachToPlayer, iEntity, iPlayer);
  
    return iEntity;
}

stock UTIL_PrecacheSoundsFromModel(const szModelPath[])
{
    new iFile;
  
    if((iFile = fopen(szModelPath, "rt")))
    {
        new szSoundPath[64];
      
        new iNumSeq, iSeqIndex;
        new iEvent, iNumEvents, iEventIndex;
      
        fseek(iFile, 164, SEEK_SET);
        fread(iFile, iNumSeq, BLOCK_INT);
        fread(iFile, iSeqIndex, BLOCK_INT);
      
        for(new k, i = 0; i < iNumSeq; i++)
        {
            fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
            fread(iFile, iNumEvents, BLOCK_INT);
            fread(iFile, iEventIndex, BLOCK_INT);
            fseek(iFile, iEventIndex + 176 * i, SEEK_SET);
          
            for(k = 0; k < iNumEvents; k++)
            {
                fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
                fread(iFile, iEvent, BLOCK_INT);
                fseek(iFile, 4, SEEK_CUR);
              
                if(iEvent != 5004)
                    continue;
              
                fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);
              
                if(strlen(szSoundPath))
                {
                    strtolower(szSoundPath);
                    engfunc(EngFunc_PrecacheSound, szSoundPath);
                }
            }
        }
    }
  
    fclose(iFile);
}

stock UTIL_PrecacheSpritesFromTxt(const szWeaponList[])
{
    new szTxtDir[64], szSprDir[64];
    new szFileData[128], szSprName[48], temp[1];

    format(szTxtDir, charsmax(szTxtDir), "sprites/%s.txt", szWeaponList);
    engfunc(EngFunc_PrecacheGeneric, szTxtDir);

    new iFile = fopen(szTxtDir, "rb");
    while(iFile && !feof(iFile))
    {
        fgets(iFile, szFileData, charsmax(szFileData));
        trim(szFileData);

        if(!strlen(szFileData))
            continue;

        new pos = containi(szFileData, "640"); 
          
        if(pos == -1)
            continue;
          
        format(szFileData, charsmax(szFileData), "%s", szFileData[pos+3]);     
        trim(szFileData);

        strtok(szFileData, szSprName, charsmax(szSprName), temp, charsmax(temp), ' ', 1);
        trim(szSprName);
      
        format(szSprDir, charsmax(szSprDir), "sprites/%s.spr", szSprName);
        engfunc(EngFunc_PrecacheGeneric, szSprDir);
    }

    if(iFile) fclose(iFile);
}

stock UTIL_WeaponList(iPlayer, iEnabled)
{
    message_begin(MSG_ONE, gl_iMsgID_WeaponList, _, iPlayer);
    write_string(iEnabled ? WEAPON_WEAPONLIST_DIR : WEAPON_REFERENCE);
    write_byte(iWeaponList[0]);
    write_byte(iWeaponList[1]);
    write_byte(iWeaponList[2]);
    write_byte(iWeaponList[3]);
    write_byte(iWeaponList[4]);
    write_byte(iWeaponList[5]);
    write_byte(iWeaponList[6]);
    write_byte(iWeaponList[7]);
    message_end();
}
 
Сообщения
72
Реакции
10
Извиняюсь,
пытался делать так, но когда в радиус взрыва попадают два и более зомби у человека воспроизводится несколько звуков
emit_sound(iVictim, CHAN_WEAPON, grenade_sound[random_num(0, sizeof (grenade_sound) - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM);
Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <zombieplague>
#include <xs>

#define MAX_CLIENTS 32
#define DMG_GRENADE (1<<24)
#define TASKID_HOLYBOMB_BURN 3900

#define linux_diff_weapon 4
#define linux_diff_player 5
#define m_pPlayer 41
#define m_LastHitGroup 75

new const grenade_sound[][] =
{
    "zombie_plague/human_sound_1.wav",
    "zombie_plague/human_sound_2.wav"
}

new const WEAPON_REFERENCE[] = "weapon_smokegrenade";
new const WEAPON_DEFAULT_WORLD_MODEL[] = "models/w_smokegrenade.mdl";
const WEAPON_DEFAULT_CSW = CSW_SMOKEGRENADE;
new const WEAPON_AMMO_TYPE[] = "SmokeGrenade";
const WEAPON_SPECIAL_CODE = 6666;

new const WEAPON_VIEW_MODEL[] = "models/x/v_holybomb.mdl";
new const WEAPON_PLAYER_MODEL[] = "models/x/p_holybomb.mdl";
new const WEAPON_WORLD_MODEL[] = "models/x/w_holybomb.mdl";
const WEAPON_WORLD_MODEL_BODY = 0;

new const WEAPON_EXPLODE_SOUND[] = "weapons/holywater_explosion.wav";
new const WEAPON_EXPLODE_SPRITE[] = "sprites/x/holybomb_exp.spr";
new const WEAPON_BURN_SPRITE[] = "sprites/x/holybomb_burn.spr"

const Float: WEAPON_GRENADE_RADIUS = 150.0; // Радиус взрыва, в котором заденет всех врагов
const Float: WEAPON_GRENADE_DAMAGE = 700.0; // Урон при взрыве
const WEAPON_GRENADE_DMGTYPE = DMG_GRENADE; // Тип урона при взрыве

const Float: GRENADE_BURN_DELAY = 1.0; // С каким промежутком времени будет проходить урон
const Float: GRENADE_BURN_DAMAGE = 200.0; // Кол-во урона за 1 сек
const GRENADE_BURN_DURATION = 10; // Длительность горения

new const WEAPON_WEAPONLIST_DIR[] = "x/weapon_holybomb";
new const iWeaponList[] =
{
    //11, 2, -1, -1, 3, 2, 25, 24 // weapon_flashbang
    //12, 1,  -1, -1, 3, 1, 4,  24 // weapon_hegrenade
    13, 1,  -1, -1, 3, 3, 9,  24 // weapon_smokegrenade
};

new gl_iItemID,

    gl_iszModelIndex_Burn,
    gl_iszModelIndex_Smoke,
    gl_iszModelIndex_Explode,

    gl_iUserHasHolyBomb[MAX_CLIENTS + 1],
    gl_iUserBurningDuration[MAX_CLIENTS + 1],

    gl_iMsgID_WeaponList,
    gl_iMsgId_DeathMsg;

public plugin_init()
{
    register_plugin("[ZP] Grenade: Holy Bomb", "1.0 | 2019", "xUnicorn (t3rkecorejz)");

    register_forward(FM_SetModel, "FM_Hook_SetModel_Pre", false);

    RegisterHam(Ham_Think, "grenade", "CGrenade__Think_Pre", false);
    RegisterHam(Ham_Touch, "grenade", "CGrenade__Touch_Pre", false);

    RegisterHam(Ham_Item_Deploy, WEAPON_REFERENCE, "CGrenade__Deploy_Post", true);
    RegisterHam(Ham_Item_AddToPlayer, WEAPON_REFERENCE, "CGrenade__AddToPlayer_Post", true);

    gl_iItemID = zp_register_extra_item("Holy Bomb", 10, ZP_TEAM_HUMAN);
    gl_iMsgID_WeaponList = get_user_msgid("WeaponList");
    gl_iMsgId_DeathMsg = get_user_msgid("DeathMsg");
}

public plugin_precache()
{
    register_clcmd(WEAPON_WEAPONLIST_DIR, "Command_HookWeapon");

    // Models
    engfunc(EngFunc_PrecacheModel, WEAPON_VIEW_MODEL);
    engfunc(EngFunc_PrecacheModel, WEAPON_PLAYER_MODEL);
    engfunc(EngFunc_PrecacheModel, WEAPON_WORLD_MODEL);

    // Sounds
    engfunc(EngFunc_PrecacheSound, WEAPON_EXPLODE_SOUND);
    UTIL_PrecacheSoundsFromModel(WEAPON_VIEW_MODEL);

    // Other
    UTIL_PrecacheSpritesFromTxt(WEAPON_WEAPONLIST_DIR);

    // Model Index
    gl_iszModelIndex_Burn = engfunc(EngFunc_PrecacheModel, WEAPON_BURN_SPRITE);
    gl_iszModelIndex_Smoke = engfunc(EngFunc_PrecacheModel, "sprites/black_smoke3.spr");
    gl_iszModelIndex_Explode = engfunc(EngFunc_PrecacheModel, WEAPON_EXPLODE_SPRITE);
 
    for (new i = 0; i < sizeof grenade_sound; i++)
        engfunc(EngFunc_PrecacheSound, grenade_sound[i]);
}

public Command_HookWeapon(iPlayer)
{
    engclient_cmd(iPlayer, WEAPON_REFERENCE);
    return PLUGIN_HANDLED;
}

public Command_GiveWeapon(iPlayer)
{
    if(user_has_weapon(iPlayer, WEAPON_DEFAULT_CSW))
    {
        gl_iUserHasHolyBomb[iPlayer]++;
        ExecuteHamB(Ham_GiveAmmo, iPlayer, 1, WEAPON_AMMO_TYPE, 5);
        emit_sound(iPlayer, CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
    }
    else
    {
        gl_iUserHasHolyBomb[iPlayer] = 1;
        UTIL_GiveNamedItem(iPlayer, WEAPON_REFERENCE);
        emit_sound(iPlayer, CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

        gl_iUserHasHolyBomb[iPlayer]++;
        ExecuteHamB(Ham_GiveAmmo, iPlayer, 1, WEAPON_AMMO_TYPE, 5);
    }
}

// [ Zombie Plague ]
public zp_extra_item_selected(iPlayer, iItemID)
{
    if(iItemID == gl_iItemID)
        Command_GiveWeapon(iPlayer);
}

public zp_user_infected_post(iPlayer)
{
    if(!is_user_connected(iPlayer)) return;
    if(gl_iUserHasHolyBomb[iPlayer]) gl_iUserHasHolyBomb[iPlayer] = 0;
}

// [ Fakemeta ]
public FM_Hook_SetModel_Pre(iEntity, const szModel[])
{
    if(!pev_valid(iEntity))  return FMRES_IGNORED;

    new Float: flDamageTime; pev(iEntity, pev_dmgtime, flDamageTime);
    if(flDamageTime == 0.0) return FMRES_IGNORED;

    new iOwner = pev(iEntity, pev_owner);
    if(equal(szModel, WEAPON_DEFAULT_WORLD_MODEL))
    {
        if(gl_iUserHasHolyBomb[iOwner])
        {
            message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
            write_byte(TE_KILLBEAM);
            write_short(iEntity);
            message_end();

            set_pev(iEntity, pev_body, WEAPON_WORLD_MODEL_BODY);
            set_pev(iEntity, pev_flTimeStepSound, WEAPON_SPECIAL_CODE);

            set_pev(iEntity, pev_sequence, random_num(1, 2));
            set_pev(iEntity, pev_animtime, get_gametime());
            set_pev(iEntity, pev_framerate, 1.0);

            engfunc(EngFunc_SetModel, iEntity, WEAPON_WORLD_MODEL);

            gl_iUserHasHolyBomb[iOwner] -= 1;

            return FMRES_SUPERCEDE;
        }
    }

    return FMRES_IGNORED;
}

// [ HamSandwich ]
public CGrenade__Think_Pre(iEntity)
{
    if(!pev_valid(iEntity)) return HAM_IGNORED;

    static Float: flDamageTime; pev(iEntity, pev_dmgtime, flDamageTime);
    if(flDamageTime > get_gametime()) return HAM_IGNORED;

    if(pev(iEntity, pev_flTimeStepSound) == WEAPON_SPECIAL_CODE)
    {
        new iOwner = pev(iEntity, pev_owner);
        emit_sound(iEntity, CHAN_WEAPON, WEAPON_EXPLODE_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

        new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
        write_byte(TE_EXPLOSION);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] + 20.0);
        write_short(gl_iszModelIndex_Explode);
        write_byte(20); // Scale
        write_byte(32); // Framerate
        write_byte(TE_EXPLFLAG_NODLIGHTS|TE_EXPLFLAG_NOSOUND|TE_EXPLFLAG_NOPARTICLES);
        message_end();

        new iVictim = FM_NULLENT;
        while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOrigin, WEAPON_GRENADE_RADIUS)) > 0)
        {
            if(!is_user_alive(iVictim)) continue;
            if(!zp_get_user_zombie(iVictim)) continue;
            if(!is_wall_between_points(iOwner, iVictim)) continue;

            emit_sound(iVictim, CHAN_WEAPON, grenade_sound[random_num(0, sizeof (grenade_sound) - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM);
         
            if(is_user_alive(iVictim))
                set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);

            ExecuteHamB(Ham_TakeDamage, iVictim, iEntity, iOwner, WEAPON_GRENADE_DAMAGE, WEAPON_GRENADE_DMGTYPE);

            new iParams[2]; iParams[0] = iOwner;
            gl_iUserBurningDuration[iVictim] += GRENADE_BURN_DURATION;
         
            if(!task_exists(iVictim + TASKID_HOLYBOMB_BURN))
                set_task(GRENADE_BURN_DELAY, "CTask__Burn_HolyBomb", iVictim + TASKID_HOLYBOMB_BURN, iParams, sizeof iParams);
        }

        set_pev(iEntity, pev_flags, FL_KILLME);
        return HAM_SUPERCEDE;
    }

    return HAM_IGNORED;
}

public CGrenade__Touch_Pre(iEntity)
{
    if(!pev_valid(iEntity)) return HAM_IGNORED;

    if(pev(iEntity, pev_flTimeStepSound) == WEAPON_SPECIAL_CODE)
    {
        new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
        if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_WATER)
        {
            set_pev(iEntity, pev_flags, FL_KILLME);
            return HAM_IGNORED;
        }

        set_pev(iEntity, pev_dmgtime, get_gametime());
    }

    return HAM_IGNORED;
}

public CGrenade__Deploy_Post(iItem)
{
    static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);

    if(!gl_iUserHasHolyBomb[iPlayer]) return HAM_IGNORED;
    if(zp_get_user_zombie(iPlayer)) return HAM_IGNORED;

    set_pev(iPlayer, pev_viewmodel2, WEAPON_VIEW_MODEL);
    set_pev(iPlayer, pev_weaponmodel2, WEAPON_PLAYER_MODEL);

    return HAM_IGNORED;
}
public CGrenade__AddToPlayer_Post(iItem, iPlayer) UTIL_WeaponList(iPlayer, gl_iUserHasHolyBomb[iPlayer]);

// [ Tasks ]
public CTask__Burn_HolyBomb(szArgs[1], iTask)
{
    new iOwner = szArgs[0];
    new iVictim = iTask - TASKID_HOLYBOMB_BURN;
    new iFlags = pev(iVictim, pev_flags);
    new Float: vecOrigin[3]; pev(iVictim, pev_origin, vecOrigin);

    if(!is_user_alive(iVictim) || !is_user_connected(iOwner) || iOwner == iVictim || zp_get_user_zombie(iOwner) || iFlags & FL_INWATER || gl_iUserBurningDuration[iVictim] < 1)
    {
        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
        write_byte(TE_SMOKE);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] - 50.0);
        write_short(gl_iszModelIndex_Smoke);
        write_byte(random_num(15, 20)); // Scale
        write_byte(random_num(10, 20)); // Framerate
        message_end();
     
        remove_task(iTask);
        return;
    }
 
    new flHealth = pev(iVictim, pev_health);
    if(flHealth - GRENADE_BURN_DAMAGE > 0.0)
    {
        if(is_user_alive(iVictim))
            set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);

        ExecuteHamB(Ham_TakeDamage, iVictim, iOwner, iOwner, GRENADE_BURN_DAMAGE, WEAPON_GRENADE_DMGTYPE);
    }
    else
    {
        set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);
     
        set_msg_block(gl_iMsgId_DeathMsg, BLOCK_SET);
        ExecuteHamB(Ham_Killed, iVictim, iOwner, 0);
        set_msg_block(gl_iMsgId_DeathMsg, BLOCK_NOT);

        message_begin(MSG_ALL, gl_iMsgId_DeathMsg);
        write_byte(iOwner);
        write_byte(iVictim);
        write_byte(0);
        write_string("grenade");
        message_end();

        engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
        write_byte(TE_SMOKE);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] - 50.0);
        write_short(gl_iszModelIndex_Smoke);
        write_byte(random_num(15, 20)); // Scale
        write_byte(random_num(10, 20)); // Framerate
        message_end();

        remove_task(iTask);
        return;
    }

    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
    write_byte(TE_SPRITE);
    engfunc(EngFunc_WriteCoord, vecOrigin[0] + random_float(-5.0, 5.0));
    engfunc(EngFunc_WriteCoord, vecOrigin[1] + random_float(-5.0, 5.0));
    engfunc(EngFunc_WriteCoord, vecOrigin[2] + random_float(-10.0, 10.0));
    write_short(gl_iszModelIndex_Burn);
    write_byte(random_num(5, 7)); // Scale
    write_byte(200); // Alpha
    message_end();

    gl_iUserBurningDuration[iVictim]--;
    set_task(GRENADE_BURN_DELAY, "CTask__Burn_HolyBomb", iTask, szArgs, sizeof szArgs);
}

// [ Stocks ]
stock is_wall_between_points(iPlayer, iEntity)
{
    if(!is_user_alive(iEntity))
        return 0;

    new iTrace = create_tr2();
    new Float: flStart[3], Float: flEnd[3], Float: flEndPos[3];

    pev(iPlayer, pev_origin, flStart);
    pev(iEntity, pev_origin, flEnd);

    engfunc(EngFunc_TraceLine, flStart, flEnd, IGNORE_MONSTERS, iPlayer, iTrace);
    get_tr2(iTrace, TR_vecEndPos, flEndPos);

    free_tr2(iTrace);

    return xs_vec_equal(flEnd, flEndPos);
}

stock UTIL_GiveNamedItem(iPlayer, const szItem[])
{
    new iEntity = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, szItem));
    if(!pev_valid(iEntity)) return 0;
 
    ExecuteHam(Ham_Spawn, iEntity);
    if(!ExecuteHamB(Ham_AddPlayerItem, iPlayer, iEntity))
    {
        set_pev(iEntity, pev_flags, pev(iEntity, pev_flags) | FL_KILLME);
        return 0;
    }

    ExecuteHamB(Ham_Item_AttachToPlayer, iEntity, iPlayer);
 
    return iEntity;
}

stock UTIL_PrecacheSoundsFromModel(const szModelPath[])
{
    new iFile;
 
    if((iFile = fopen(szModelPath, "rt")))
    {
        new szSoundPath[64];
     
        new iNumSeq, iSeqIndex;
        new iEvent, iNumEvents, iEventIndex;
     
        fseek(iFile, 164, SEEK_SET);
        fread(iFile, iNumSeq, BLOCK_INT);
        fread(iFile, iSeqIndex, BLOCK_INT);
     
        for(new k, i = 0; i < iNumSeq; i++)
        {
            fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
            fread(iFile, iNumEvents, BLOCK_INT);
            fread(iFile, iEventIndex, BLOCK_INT);
            fseek(iFile, iEventIndex + 176 * i, SEEK_SET);
         
            for(k = 0; k < iNumEvents; k++)
            {
                fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
                fread(iFile, iEvent, BLOCK_INT);
                fseek(iFile, 4, SEEK_CUR);
             
                if(iEvent != 5004)
                    continue;
             
                fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);
             
                if(strlen(szSoundPath))
                {
                    strtolower(szSoundPath);
                    engfunc(EngFunc_PrecacheSound, szSoundPath);
                }
            }
        }
    }
 
    fclose(iFile);
}

stock UTIL_PrecacheSpritesFromTxt(const szWeaponList[])
{
    new szTxtDir[64], szSprDir[64];
    new szFileData[128], szSprName[48], temp[1];

    format(szTxtDir, charsmax(szTxtDir), "sprites/%s.txt", szWeaponList);
    engfunc(EngFunc_PrecacheGeneric, szTxtDir);

    new iFile = fopen(szTxtDir, "rb");
    while(iFile && !feof(iFile))
    {
        fgets(iFile, szFileData, charsmax(szFileData));
        trim(szFileData);

        if(!strlen(szFileData))
            continue;

        new pos = containi(szFileData, "640");
         
        if(pos == -1)
            continue;
         
        format(szFileData, charsmax(szFileData), "%s", szFileData[pos+3]);    
        trim(szFileData);

        strtok(szFileData, szSprName, charsmax(szSprName), temp, charsmax(temp), ' ', 1);
        trim(szSprName);
     
        format(szSprDir, charsmax(szSprDir), "sprites/%s.spr", szSprName);
        engfunc(EngFunc_PrecacheGeneric, szSprDir);
    }

    if(iFile) fclose(iFile);
}

stock UTIL_WeaponList(iPlayer, iEnabled)
{
    message_begin(MSG_ONE, gl_iMsgID_WeaponList, _, iPlayer);
    write_string(iEnabled ? WEAPON_WEAPONLIST_DIR : WEAPON_REFERENCE);
    write_byte(iWeaponList[0]);
    write_byte(iWeaponList[1]);
    write_byte(iWeaponList[2]);
    write_byte(iWeaponList[3]);
    write_byte(iWeaponList[4]);
    write_byte(iWeaponList[5]);
    write_byte(iWeaponList[6]);
    write_byte(iWeaponList[7]);
    message_end();
}
Попробуйте так:
Код:
public CGrenade__Think_Pre(iEntity)
{
    if(!pev_valid(iEntity)) return HAM_IGNORED;

    static Float: flDamageTime; pev(iEntity, pev_dmgtime, flDamageTime);
    if(flDamageTime > get_gametime()) return HAM_IGNORED;

    if(pev(iEntity, pev_flTimeStepSound) == WEAPON_SPECIAL_CODE)
    {
        new iOwner = pev(iEntity, pev_owner);
        emit_sound(iEntity, CHAN_WEAPON, WEAPON_EXPLODE_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

        new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
        message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
        write_byte(TE_EXPLOSION);
        engfunc(EngFunc_WriteCoord, vecOrigin[0]);
        engfunc(EngFunc_WriteCoord, vecOrigin[1]);
        engfunc(EngFunc_WriteCoord, vecOrigin[2] + 20.0);
        write_short(gl_iszModelIndex_Explode);
        write_byte(20); // Scale
        write_byte(32); // Framerate
        write_byte(TE_EXPLFLAG_NODLIGHTS|TE_EXPLFLAG_NOSOUND|TE_EXPLFLAG_NOPARTICLES);
        message_end();

        emit_sound(iOwner, CHAN_WEAPON, grenade_sound[random_num(0, sizeof (grenade_sound) - 1)], 1.0, ATTN_NORM, 0, PITCH_NORM);
        
        new iVictim = FM_NULLENT;
        while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOrigin, WEAPON_GRENADE_RADIUS)) > 0)
        {
            if(!is_user_alive(iVictim)) continue;
            if(!zp_get_user_zombie(iVictim)) continue;
            if(!is_wall_between_points(iOwner, iVictim)) continue;
          
            if(is_user_alive(iVictim))
                set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);

            ExecuteHamB(Ham_TakeDamage, iVictim, iEntity, iOwner, WEAPON_GRENADE_DAMAGE, WEAPON_GRENADE_DMGTYPE);

            new iParams[2]; iParams[0] = iOwner;
            gl_iUserBurningDuration[iVictim] += GRENADE_BURN_DURATION;
          
            if(!task_exists(iVictim + TASKID_HOLYBOMB_BURN))
                set_task(GRENADE_BURN_DELAY, "CTask__Burn_HolyBomb", iVictim + TASKID_HOLYBOMB_BURN, iParams, sizeof iParams);
        }

        set_pev(iEntity, pev_flags, FL_KILLME);
        return HAM_SUPERCEDE;
    }

    return HAM_IGNORED;
}
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу