Приветствую.
Прошу помощи в правильной реализации этой функции
Задумка простая как камень. Пока игрок имеет конкретный предмет (оружие), то он не может быть заражен, но может быть убит.
Для этого я использую булевую переменную, которой присваивается значение 1, когда игрок получает предмет (покупает из итемов или подбирает с пола).
Далее накладывается условие "
if (g_UserHadItem)
return ZP_PLUGIN_HANDLED
return PLUGIN CONTINUE
Всё бы хорошо, условие отрабатывает, но юзер становится неуязвимым к урону, а если быть точнее, то армор ему снести могут, а вот ХП-нет.
Я попробовал реализовать это с помощью костыля в таком виде:
И в ходе тестов не совсем понял, работает такая конструкция или нет, ибо по началу урон действительно наносился, а потом сервер стал падать.
После рестарта урон не наносился вовсе.
Прилагаю полный код:
Прошу помощи в правильной реализации этой функции
Задумка простая как камень. Пока игрок имеет конкретный предмет (оружие), то он не может быть заражен, но может быть убит.
Для этого я использую булевую переменную, которой присваивается значение 1, когда игрок получает предмет (покупает из итемов или подбирает с пола).
Далее накладывается условие "
if (g_UserHadItem)
return ZP_PLUGIN_HANDLED
return PLUGIN CONTINUE
Всё бы хорошо, условие отрабатывает, но юзер становится неуязвимым к урону, а если быть точнее, то армор ему снести могут, а вот ХП-нет.
Я попробовал реализовать это с помощью костыля в таком виде:
Код:
public zp_user_infect_attempt(iPlayer, infector, nemesis)
{
if(g_Had_PowerSaw[iPlayer]){
new button = pev(infector, pev_button)
if(button == IN_ATTACK){
// ExecuteHamB(Ham_TakeDamage, iPlayer, infector)
ExecuteHamB(Ham_TakeDamage, iPlayer, infector, infector, random_float(10.0,50.0), DMG_SLASH)
return ZP_PLUGIN_HANDLED;
}
else if(button == IN_ATTACK2){
// ExecuteHamB(Ham_TakeDamage, iPlayer, infector)
ExecuteHamB(Ham_TakeDamage, iPlayer, infector, infector, random_float(50.0, 120.0), DMG_SLASH)
return ZP_PLUGIN_HANDLED;
}
else return ZP_PLUGIN_HANDLED;
}
return PLUGIN_CONTINUE;
}
После рестарта урон не наносился вовсе.
Прилагаю полный код:
Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <zombieplague>
#include <fun>
#define CustomItem(%0) (pev(%0, pev_impulse) == WEAPON_SPECIAL_CODE)
enum _: e_AnimList
{
WEAPON_ANIM_IDLE = 0,
WEAPON_ANIM_DRAW,
WEAPON_ANIM_DRAW_EMPTY,
WEAPON_ANIM_ATTACK_START,
WEAPON_ANIM_ATTACK_LOOP,
WEAPON_ANIM_ATTACK_END,
WEAPON_ANIM_RELOAD,
WEAPON_ANIM_SLASH1,
WEAPON_ANIM_SLASH2,
WEAPON_ANIM_SLASH3,
WEAPON_ANIM_SLASH4,
WEAPON_ANIM_IDLE_EMPTY
};
enum _: e_HitResultList
{
SLASH_HIT_NONE = 0,
SLASH_HIT_WORLD,
SLASH_HIT_ENTITY
};
enum _: e_AttackState
{
STATE_NONE = 0,
STATE_IN_LOOP,
STATE_IN_END
};
// From model: Frames/FPS
#define WEAPON_ANIM_IDLE_TIME 151/30.0
#define WEAPON_ANIM_DRAW_TIME 46/30.0
#define WEAPON_ANIM_ATTACK_START_TIME 16/30.0
#define WEAPON_ANIM_ATTACK_LOOP_TIME 16/30.0
#define WEAPON_ANIM_ATTACK_END_TIME 46/30.0
#define WEAPON_ANIM_RELOAD_TIME 94/30.0
#define WEAPON_ANIM_SLASH_TIME 46/30.0
#define WEAPON_SPECIAL_CODE 3000
#define WEAPON_REFERENCE "weapon_m249"
#define WEAPON_NEW_NAME "VanillaZM/weapon_chainsaw"
#define WEAPON_ITEM_NAME "ePowersaw"
#define WEAPON_ITEM_COST 0
#define WEAPON_MODEL_VIEW "models/VanillaZM/weapons/chainsaw/v_chainsaw.mdl"
#define WEAPON_MODEL_PLAYER "models/VanillaZM/weapons/chainsaw/p_chainsaw.mdl"
#define WEAPON_MODEL_WORLD "models/VanillaZM/weapons/chainsaw/w_chainsaw.mdl"
#define WEAPON_BODY 0
#define WEAPON_SOUND_ATTACK_LOOP "weapons/chainsaw_attack1_loop.wav"
#define WEAPON_SOUND_ATTACK_HIT "weapons/chainsaw_hit1.wav"
#define WEAPON_SOUND_SLASH_HIT "weapons/chainsaw_hit2.wav"
#define WEAPON_SOUND_SLASH_HIT_EMPTY "weapons/chainsaw_hit3.wav"
#define WEAPON_MAX_CLIP 100
#define WEAPON_DEFAULT_AMMO 200
#define WEAPON_RATE 0.075
#define WEAPON_ANIM_EXTENSION_A "m249" // Original CSO: chainsaw (aim, reload, shoot)
#define WEAPON_ANIM_EXTENSION_B "knife" // Original CSO: chainsaw (shoot2)
#define WEAPON_ATTACK_DISTANCE 110.0
#define WEAPON_ATTACK_DAMAGE 110.0
#define WEAPON_SLASH_DISTANCE 160.0
#define WEAPON_SLASH_DAMAGE 600.0
#define WEAPON_SLASH_KNOCKBACK 800.0
new Float: flSendAnglesAttack[] = { 0.0 };
new Float: flSendAnglesUpAttack[] = { 0.0 };
new Float: flSendAnglesSlash[] = { 0.0, -10.0, 10.0, -20.0, 20.0 };
new Float: flSendAnglesUpSlash[] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
new const iWeaponList[] =
{
3, 200,-1, -1, 0, 4, 20, 0 // weapon_m249
};
#define DONT_BLEED -1
#define ACT_RANGE_ATTACK1 28
// Linux extra offsets
#define linux_diff_animating 4
#define linux_diff_weapon 4
#define linux_diff_player 5
// CWeaponBox
#define m_rgpPlayerItems_CWeaponBox 34
// CBaseAnimating
#define m_flFrameRate 36
#define m_flGroundSpeed 37
#define m_flLastEventCheck 38
#define m_fSequenceFinished 39
#define m_fSequenceLoops 40
// CBasePlayerItem
#define m_pPlayer 41
#define m_pNext 42
#define m_iId 43
// CBasePlayerWeapon
#define m_flNextPrimaryAttack 46
#define m_flNextSecondaryAttack 47
#define m_flTimeWeaponIdle 48
#define m_iPrimaryAmmoType 49
#define m_iClip 51
#define m_fInReload 54
#define m_iWeaponState 74
// CBaseMonster
#define m_Activity 73
#define m_IdealActivity 74
#define m_LastHitGroup 75
#define m_flNextAttack 83
// CBasePlayer
#define m_flPainShock 108
#define m_iPlayerTeam 114
#define m_flLastAttackTime 220
#define m_rpgPlayerItems 367
#define m_pActiveItem 373
#define m_rgAmmo 376
#define m_szAnimExtention 492
new g_iszAllocString_Entity,
g_iszAllocString_ModelView,
g_iszAllocString_ModelPlayer,
g_iszModelIndexBloodSpray,
g_iszModelIndexBloodDrop,
g_iMsgID_Weaponlist,
g_iItemID;
new g_Had_PowerSaw[33]
public plugin_init()
{
register_plugin("[ZP] Weapon: Ripper (PowerSaw)", "1.0", "xUnicorn (t3rkecorejz) / Batcoh: Code base");
g_iItemID = zp_register_extra_item(WEAPON_ITEM_NAME, WEAPON_ITEM_COST, ZP_TEAM_HUMAN);
register_forward(FM_UpdateClientData, "FM_Hook_UpdateClientData_Post", true);
register_forward(FM_SetModel, "FM_Hook_SetModel_Pre", false);
RegisterHam(Ham_Item_Holster, WEAPON_REFERENCE, "CWeapon__Holster_Post", true);
RegisterHam(Ham_Item_Deploy, WEAPON_REFERENCE, "CWeapon__Deploy_Post", true);
RegisterHam(Ham_Item_PostFrame, WEAPON_REFERENCE, "CWeapon__PostFrame_Pre", false);
RegisterHam(Ham_Item_AddToPlayer, WEAPON_REFERENCE, "CWeapon__AddToPlayer_Post", true);
RegisterHam(Ham_Weapon_Reload, WEAPON_REFERENCE, "CWeapon__Reload_Pre", false);
RegisterHam(Ham_Weapon_WeaponIdle, WEAPON_REFERENCE, "CWeapon__WeaponIdle_Pre", false);
RegisterHam(Ham_Weapon_PrimaryAttack, WEAPON_REFERENCE, "CWeapon__PrimaryAttack_Pre", false);
RegisterHam(Ham_Weapon_SecondaryAttack, WEAPON_REFERENCE, "CWeapon__SecondaryAttack_Pre", false);
//RegisterHam(Ham_TakeDamage, "player", "HamTakeDamage");
g_iMsgID_Weaponlist = get_user_msgid("WeaponList");
}
public plugin_precache()
{
// Hook weapon
register_clcmd(WEAPON_NEW_NAME, "Command_HookWeapon");
// Precache models
engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_VIEW);
engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_PLAYER);
engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_WORLD);
// Precache generic
UTIL_PrecacheSpritesFromTxt(WEAPON_NEW_NAME);
// Precache sounds
engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_ATTACK_LOOP);
engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_ATTACK_HIT);
engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_SLASH_HIT);
engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_SLASH_HIT_EMPTY);
UTIL_PrecacheSoundsFromModel(WEAPON_MODEL_VIEW);
// Other
g_iszAllocString_Entity = engfunc(EngFunc_AllocString, WEAPON_REFERENCE);
g_iszAllocString_ModelView = engfunc(EngFunc_AllocString, WEAPON_MODEL_VIEW);
g_iszAllocString_ModelPlayer = engfunc(EngFunc_AllocString, WEAPON_MODEL_PLAYER);
// Model Index
g_iszModelIndexBloodSpray = engfunc(EngFunc_PrecacheModel, "sprites/bloodspray.spr");
g_iszModelIndexBloodDrop = engfunc(EngFunc_PrecacheModel, "sprites/blood.spr");
}
// [ Amxx ]
public zp_extra_item_selected(iPlayer, iItem)
{
if(iItem == g_iItemID)
Command_GiveWeapon(iPlayer);
}
public client_connect(iPlayer)
{
g_Had_PowerSaw[iPlayer] = 0
}
public client_disconnected(iPlayer)
{
g_Had_PowerSaw[iPlayer] = 0
}
//public HamTakeDamage(victim, weapon, attacker, Float:damage, damagebits )
//{
//if(is_entity_player(iAgressor = weapon) || is_entity_player(iAgressor = attacker))
//if(get_user_weapon(attacker) == CSW_KNIFE)
//{
// set_user_health(victim, get_user_health(victim)-50)
//}
//}
public zp_user_infect_attempt(iPlayer, infector, nemesis)
{
if(g_Had_PowerSaw[iPlayer]){
new button = pev(infector, pev_button)
if(button == IN_ATTACK){
// ExecuteHamB(Ham_TakeDamage, iPlayer, infector)
ExecuteHamB(Ham_TakeDamage, iPlayer, infector, infector, random_float(10.0,50.0), DMG_SLASH)
return ZP_PLUGIN_HANDLED;
}
else if(button == IN_ATTACK2){
// ExecuteHamB(Ham_TakeDamage, iPlayer, infector)
ExecuteHamB(Ham_TakeDamage, iPlayer, infector, infector, random_float(50.0, 120.0), DMG_SLASH)
return ZP_PLUGIN_HANDLED;
}
else return ZP_PLUGIN_HANDLED;
}
return PLUGIN_CONTINUE;
}
public Command_HookWeapon(iPlayer)
{
engclient_cmd(iPlayer, WEAPON_REFERENCE);
return PLUGIN_HANDLED;
}
public Command_GiveWeapon(iPlayer)
{
g_Had_PowerSaw[iPlayer] = 1
static iEntity; iEntity = engfunc(EngFunc_CreateNamedEntity, g_iszAllocString_Entity);
if(iEntity <= 0) return 0;
set_pev(iEntity, pev_impulse, WEAPON_SPECIAL_CODE);
ExecuteHam(Ham_Spawn, iEntity);
UTIL_DropWeapon(iPlayer, 1);
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);
set_pdata_int(iEntity, m_iClip, WEAPON_MAX_CLIP, linux_diff_weapon);
new iAmmoType = m_rgAmmo + get_pdata_int(iEntity, m_iPrimaryAmmoType, linux_diff_weapon);
if(get_pdata_int(iPlayer, m_rgAmmo, linux_diff_player) < WEAPON_DEFAULT_AMMO)
set_pdata_int(iPlayer, iAmmoType, WEAPON_DEFAULT_AMMO, linux_diff_player);
emit_sound(iPlayer, CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
return 1;
}
// [ Fakemeta ]
public FM_Hook_UpdateClientData_Post(iPlayer, SendWeapons, CD_Handle)
{
if(get_cd(CD_Handle, CD_DeadFlag) != DEAD_NO) return;
static iItem; iItem = get_pdata_cbase(iPlayer, m_pActiveItem, 5);
if(iItem <= 0 || !CustomItem(iItem)) return;
set_cd(CD_Handle, CD_flNextAttack, get_gametime() + 0.001);
}
public FM_Hook_SetModel_Pre(iEntity)
{
static i, szClassName[32], iItem;
pev(iEntity, pev_classname, szClassName, charsmax(szClassName));
if(!equal(szClassName, "weaponbox")) return FMRES_IGNORED;
for(i = 0; i < 6; i++)
{
iItem = get_pdata_cbase(iEntity, m_rgpPlayerItems_CWeaponBox + i, linux_diff_weapon);
if(iItem > 0 && CustomItem(iItem))
{
engfunc(EngFunc_SetModel, iEntity, WEAPON_MODEL_WORLD);
set_pev(iEntity, pev_body, WEAPON_BODY);
return FMRES_SUPERCEDE;
}
}
return FMRES_IGNORED;
}
// [ HamSandwich ]
public CWeapon__Holster_Post(iItem)
{
if(!CustomItem(iItem)) return;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
emit_sound(iPlayer, CHAN_ITEM, "common/null.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
set_pdata_int(iItem, m_iWeaponState, STATE_NONE, linux_diff_weapon);
}
public CWeapon__Deploy_Post(iItem)
{
if(!CustomItem(iItem)) return;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
set_pev_string(iPlayer, pev_viewmodel2, g_iszAllocString_ModelView);
set_pev_string(iPlayer, pev_weaponmodel2, g_iszAllocString_ModelPlayer);
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_DRAW);
set_pdata_float(iPlayer, m_flNextAttack, WEAPON_ANIM_DRAW_TIME, linux_diff_player);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_DRAW_TIME, linux_diff_weapon);
set_pdata_string(iPlayer, m_szAnimExtention * 4, WEAPON_ANIM_EXTENSION_A, -1, linux_diff_player * linux_diff_animating);
}
public CWeapon__PostFrame_Pre(iItem)
{
if(!CustomItem(iItem)) return HAM_IGNORED;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
static iButton; iButton = pev(iPlayer, pev_button);
static iWeaponState; iWeaponState = get_pdata_int(iItem, m_iWeaponState, linux_diff_weapon);
switch(iWeaponState)
{
case STATE_NONE:
{
if(get_pdata_int(iItem, m_fInReload, linux_diff_weapon) == 1)
{
static iAmmoType; iAmmoType = m_rgAmmo + get_pdata_int(iItem, m_iPrimaryAmmoType, linux_diff_weapon);
static iAmmo; iAmmo = get_pdata_int(iPlayer, iAmmoType, linux_diff_player);
static j; j = min(WEAPON_MAX_CLIP - iClip, iAmmo);
set_pdata_int(iItem, m_iClip, iClip + j, linux_diff_weapon);
set_pdata_int(iPlayer, iAmmoType, iAmmo - j, linux_diff_player);
set_pdata_int(iItem, m_fInReload, 0, linux_diff_weapon);
}
if(iButton & IN_ATTACK2 && get_pdata_float(iItem, m_flNextSecondaryAttack, linux_diff_weapon) < 0.0)
{
ExecuteHamB(Ham_Weapon_SecondaryAttack, iItem);
iButton &= ~IN_ATTACK2;
set_pev(iPlayer, pev_button, iButton);
}
}
case STATE_IN_LOOP:
{
if((pev(iPlayer, pev_weaponanim) == WEAPON_ANIM_ATTACK_START || pev(iPlayer, pev_weaponanim) == WEAPON_ANIM_ATTACK_LOOP) && !(iButton & IN_ATTACK) || !iClip)
{
set_pdata_int(iItem, m_iWeaponState, STATE_IN_END, linux_diff_weapon);
}
}
case STATE_IN_END:
{
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_ATTACK_END);
set_pdata_int(iItem, m_iWeaponState, STATE_NONE, linux_diff_weapon);
//set_pdata_float(iPlayer, m_flNextAttack, WEAPON_ANIM_ATTACK_END_TIME, linux_diff_player);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_ATTACK_END_TIME, linux_diff_weapon);
}
}
return HAM_IGNORED;
}
public CWeapon__AddToPlayer_Post(iItem, iPlayer)
{
g_Had_PowerSaw[iPlayer] = 1
set_user_health(iPlayer, 2500)
switch(pev(iItem, pev_impulse))
{
case WEAPON_SPECIAL_CODE: UTIL_WeaponList(iPlayer, true);
case 0: UTIL_WeaponList(iPlayer, false);
}
}
public CWeapon__Reload_Pre(iItem)
{
if(!CustomItem(iItem)) return HAM_IGNORED;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
if(iClip >= WEAPON_MAX_CLIP) return HAM_SUPERCEDE;
static iAmmoType; iAmmoType = m_rgAmmo + get_pdata_int(iItem, m_iPrimaryAmmoType, linux_diff_weapon);
if(get_pdata_int(iPlayer, iAmmoType, linux_diff_player) <= 0) return HAM_SUPERCEDE
set_pdata_int(iItem, m_iClip, 0, linux_diff_weapon);
ExecuteHam(Ham_Weapon_Reload, iItem);
set_pdata_int(iItem, m_iClip, iClip, linux_diff_weapon);
set_pdata_int(iItem, m_fInReload, 1, linux_diff_weapon);
if(get_pdata_int(iItem, m_iWeaponState, linux_diff_weapon) == STATE_IN_LOOP)
set_pdata_int(iItem, m_iWeaponState, STATE_IN_END, linux_diff_weapon);
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_RELOAD);
static szAnimation[64];
formatex(szAnimation, charsmax(szAnimation), pev(iPlayer, pev_flags) & FL_DUCKING ? "crouch_reload_%s" : "ref_reload_%s", WEAPON_ANIM_EXTENSION_A);
UTIL_PlayerAnimation(iPlayer, szAnimation);
set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_ANIM_RELOAD_TIME, linux_diff_weapon);
set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_RELOAD_TIME, linux_diff_weapon);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_RELOAD_TIME, linux_diff_weapon);
set_pdata_float(iPlayer, m_flNextAttack, WEAPON_ANIM_RELOAD_TIME, linux_diff_player);
return HAM_SUPERCEDE;
}
public CWeapon__WeaponIdle_Pre(iItem)
{
if(!CustomItem(iItem) || get_pdata_float(iItem, m_flTimeWeaponIdle, linux_diff_weapon) > 0.0) return HAM_IGNORED;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_IDLE);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_IDLE_TIME, linux_diff_weapon);
return HAM_SUPERCEDE;
}
public CWeapon__PrimaryAttack_Pre(iItem)
{
if(!CustomItem(iItem)) return HAM_IGNORED;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
static iWeaponState; iWeaponState = get_pdata_int(iItem, m_iWeaponState, linux_diff_weapon);
static szAnimation[64];
if(iClip == 0)
{
ExecuteHam(Ham_Weapon_PlayEmptySound, iItem);
set_pdata_float(iItem, m_flNextPrimaryAttack, 0.2, linux_diff_weapon);
return HAM_SUPERCEDE;
}
switch(iWeaponState)
{
case STATE_NONE:
{
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_ATTACK_START);
set_pdata_int(iItem, m_iWeaponState, STATE_IN_LOOP, linux_diff_weapon);
set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_ANIM_ATTACK_START_TIME, linux_diff_weapon);
set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_ATTACK_START_TIME, linux_diff_weapon);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_ATTACK_START_TIME, linux_diff_weapon);
}
case STATE_IN_LOOP:
{
if(pev(iPlayer, pev_weaponanim) != WEAPON_ANIM_ATTACK_LOOP)
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_ATTACK_LOOP);
FakeTraceLine(iPlayer, iItem, 0, WEAPON_ATTACK_DISTANCE, WEAPON_ATTACK_DAMAGE, flSendAnglesAttack, flSendAnglesUpAttack, sizeof flSendAnglesAttack);
formatex(szAnimation, charsmax(szAnimation), pev(iPlayer, pev_flags) & FL_DUCKING ? "crouch_shoot_%s" : "ref_shoot_%s", WEAPON_ANIM_EXTENSION_A);
UTIL_PlayerAnimation(iPlayer, szAnimation);
set_pdata_int(iItem, m_iClip, iClip - 1, linux_diff_weapon);
set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_RATE, linux_diff_weapon);
set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_ATTACK_LOOP_TIME, linux_diff_weapon);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_ATTACK_LOOP_TIME, linux_diff_weapon);
}
}
return HAM_SUPERCEDE;
}
public CWeapon__SecondaryAttack_Pre(iItem)
{
if(!CustomItem(iItem)) return HAM_IGNORED;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
static Float: vecPunchangle[3];
static szAnimation[64];
switch(iClip)
{
case 0: UTIL_SendWeaponAnim(iPlayer, random_num(WEAPON_ANIM_SLASH3, WEAPON_ANIM_SLASH4));
default: UTIL_SendWeaponAnim(iPlayer, random_num(WEAPON_ANIM_SLASH1, WEAPON_ANIM_SLASH2));
}
vecPunchangle[0] = -5.0;
vecPunchangle[1] = random_float(-2.5, 2.5);
set_pev(iPlayer, pev_punchangle, vecPunchangle);
FakeTraceLine(iPlayer, iItem, 1, WEAPON_SLASH_DISTANCE, WEAPON_SLASH_DAMAGE, flSendAnglesSlash, flSendAnglesUpSlash, sizeof flSendAnglesSlash);
formatex(szAnimation, charsmax(szAnimation), pev(iPlayer, pev_flags) & FL_DUCKING ? "crouch_shoot_%s" : "ref_shoot_%s", WEAPON_ANIM_EXTENSION_B);
UTIL_PlayerAnimation(iPlayer, szAnimation);
set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_ANIM_SLASH_TIME - 0.3, linux_diff_weapon);
set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_ANIM_SLASH_TIME - 0.3, linux_diff_weapon);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_SLASH_TIME - 0.3, linux_diff_weapon);
return HAM_SUPERCEDE;
}
// [ Stocks ]
public FakeTraceLine(iPlayer, iItem, iSlash, Float: flDistance, Float: flDamage, Float:flSendAngles[], Float:flSendAnglesUp[], iSendAngles)
{
new Float: flOrigin[3], Float: flAngle[3], Float: flEnd[3], Float: flViewOfs[3];
new Float: flForw[3], Float: flUp[3], Float: flRight[3];
pev(iPlayer, pev_origin, flOrigin);
pev(iPlayer, pev_view_ofs, flViewOfs);
flOrigin[0] += flViewOfs[0];
flOrigin[1] += flViewOfs[1];
flOrigin[2] += flViewOfs[2];
pev(iPlayer, pev_v_angle, flAngle);
engfunc(EngFunc_AngleVectors, flAngle, flForw, flRight, flUp);
new iTrace = create_tr2();
new Float: flTan;
new Float: flMul;
static Float: flFraction, pHit;
static pHitEntity; pHitEntity = SLASH_HIT_NONE;
static iHitResult; iHitResult = SLASH_HIT_NONE;
for(new i; i < iSendAngles; i++)
{
flTan = floattan(flSendAngles[i], degrees);
flEnd[0] = (flForw[0] * flDistance) + (flRight[0] * flTan * flDistance) + flUp[0] * flSendAnglesUp[i];
flEnd[1] = (flForw[1] * flDistance) + (flRight[1] * flTan * flDistance) + flUp[1] * flSendAnglesUp[i];
flEnd[2] = (flForw[2] * flDistance) + (flRight[2] * flTan * flDistance) + flUp[2] * flSendAnglesUp[i];
flMul = (flDistance/vector_length(flEnd));
flEnd[0] *= flMul;
flEnd[1] *= flMul;
flEnd[2] *= flMul;
flEnd[0] = flEnd[0] + flOrigin[0];
flEnd[1] = flEnd[1] + flOrigin[1];
flEnd[2] = flEnd[2] + flOrigin[2];
engfunc(EngFunc_TraceLine, flOrigin, flEnd, DONT_IGNORE_MONSTERS, iPlayer, iTrace);
get_tr2(iTrace, TR_flFraction, flFraction);
if(flFraction == 1.0)
{
engfunc(EngFunc_TraceHull, flOrigin, flEnd, HULL_HEAD, iPlayer, iTrace);
get_tr2(iTrace, TR_flFraction, flFraction);
engfunc(EngFunc_TraceLine, flOrigin, flEnd, DONT_IGNORE_MONSTERS, iPlayer, iTrace);
pHit = get_tr2(iTrace, TR_pHit);
}
else
{
pHit = get_tr2(iTrace, TR_pHit);
}
if(flFraction != 1.0)
{
if(!iHitResult) iHitResult = SLASH_HIT_WORLD;
}
if(pHit > 0 && pHitEntity != pHit)
{
if(pev(pHit, pev_solid) == SOLID_BSP && !(pev(pHit, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY))
{
ExecuteHamB(Ham_TakeDamage, pHit, iPlayer, iPlayer, flDamage, DMG_NEVERGIB | DMG_CLUB);
}
else
{
FakeTraceAttack(pHit, iPlayer, flDamage, flForw, iTrace, DMG_NEVERGIB | DMG_CLUB);
if(iSlash) FakeKnockBack(pHit, flForw, WEAPON_SLASH_KNOCKBACK);
}
iHitResult = SLASH_HIT_ENTITY;
pHitEntity = pHit;
}
}
free_tr2(iTrace);
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
switch(iHitResult)
{
case SLASH_HIT_NONE:
{
if(!iSlash) emit_sound(iPlayer, CHAN_ITEM, WEAPON_SOUND_ATTACK_LOOP, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
}
case SLASH_HIT_WORLD, SLASH_HIT_ENTITY:
{
if(iSlash)
{
if(iClip) emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_SLASH_HIT, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
else emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_SLASH_HIT_EMPTY, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
}
else
{
static Float: vecPunchangle[3];
vecPunchangle[0] = random_float(-1.7, 1.7);
vecPunchangle[1] = random_float(-1.7, 1.7);
set_pev(iPlayer, pev_punchangle, vecPunchangle);
emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_ATTACK_HIT, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
}
}
}
}
public FakeTraceAttack(iVictim, iAttacker, Float: flDamage, Float: vecDirection[3], iTrace, ibitsDamageBits)
{
static Float: flTakeDamage; pev(iVictim, pev_takedamage, flTakeDamage);
if(flTakeDamage == DAMAGE_NO) return 0;
if(!(is_user_alive(iVictim))) return 0;
if(is_user_connected(iVictim))
{
if(get_pdata_int(iVictim, m_iPlayerTeam, linux_diff_player) == get_pdata_int(iAttacker, m_iPlayerTeam, linux_diff_player))
return 0;
}
static iHitgroup; iHitgroup = get_tr2(iTrace, TR_iHitgroup);
static Float: vecEndPos[3]; get_tr2(iTrace, TR_vecEndPos, vecEndPos);
static iBloodColor; iBloodColor = ExecuteHamB(Ham_BloodColor, iVictim);
set_pdata_int(iVictim, m_LastHitGroup, iHitgroup, linux_diff_player);
switch(iHitgroup)
{
case HIT_HEAD: flDamage *= 3.0;
case HIT_LEFTARM, HIT_RIGHTARM: flDamage *= 0.75;
case HIT_LEFTLEG, HIT_RIGHTLEG: flDamage *= 0.75;
case HIT_STOMACH: flDamage *= 1.5;
}
ExecuteHamB(Ham_TakeDamage, iVictim, iAttacker, iAttacker, flDamage, ibitsDamageBits);
if(zp_get_user_zombie(iVictim))
{
if(iBloodColor != DONT_BLEED)
{
ExecuteHamB(Ham_TraceBleed, iVictim, flDamage, vecDirection, iTrace, ibitsDamageBits);
UTIL_BloodDrips(vecEndPos, iBloodColor, floatround(flDamage));
}
}
return 1;
}
public FakeKnockBack(iVictim, Float: vecDirection[3], Float: flKnockBack)
{
if(!(is_user_alive(iVictim) && zp_get_user_zombie(iVictim))) return 0;
set_pdata_float(iVictim, m_flPainShock, 1.0, linux_diff_player);
static Float:vecVelocity[3]; pev(iVictim, pev_velocity, vecVelocity);
if(pev(iVictim, pev_flags) & FL_DUCKING)
flKnockBack *= 0.7;
vecVelocity[0] = vecDirection[0] * flKnockBack;
vecVelocity[1] = vecDirection[1] * flKnockBack;
vecVelocity[2] = 200.0;
set_pev(iVictim, pev_velocity, vecVelocity);
return 1;
}
public UTIL_BloodDrips(Float:vecOrigin[3], iColor, iAmount)
{
if(iAmount > 255) iAmount = 255;
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
write_byte(TE_BLOODSPRITE);
engfunc(EngFunc_WriteCoord, vecOrigin[0]);
engfunc(EngFunc_WriteCoord, vecOrigin[1]);
engfunc(EngFunc_WriteCoord, vecOrigin[2]);
write_short(g_iszModelIndexBloodSpray);
write_short(g_iszModelIndexBloodDrop);
write_byte(iColor);
write_byte(min(max(3,iAmount/10),16));
message_end();
}
stock UTIL_SendWeaponAnim(iPlayer, iAnim)
{
set_pev(iPlayer, pev_weaponanim, iAnim);
message_begin(MSG_ONE, SVC_WEAPONANIM, _, iPlayer);
write_byte(iAnim);
write_byte(0);
message_end();
}
stock UTIL_DropWeapon(iPlayer, iSlot)
{
static iEntity, iNext, szWeaponName[32];
iEntity = get_pdata_cbase(iPlayer, m_rpgPlayerItems + iSlot, linux_diff_player);
if(iEntity > 0)
{
do
{
iNext = get_pdata_cbase(iEntity, m_pNext, linux_diff_weapon);
if(get_weaponname(get_pdata_int(iEntity, m_iId, linux_diff_weapon), szWeaponName, charsmax(szWeaponName)))
engclient_cmd(iPlayer, "drop", szWeaponName);
g_Had_PowerSaw[iPlayer] = 0
}
while((iEntity = iNext) > 0);
}
}
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, bool: bEnabled)
{
message_begin(MSG_ONE, g_iMsgID_Weaponlist, _, iPlayer);
write_string(bEnabled ? WEAPON_NEW_NAME : WEAPON_REFERENCE);
write_byte(iWeaponList[0]);
write_byte(bEnabled ? WEAPON_DEFAULT_AMMO : 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();
}
stock UTIL_PlayerAnimation(const iPlayer, const szAnim[])
{
new iAnimDesired, Float: flFrameRate, Float: flGroundSpeed, bool: bLoops;
if((iAnimDesired = lookup_sequence(iPlayer, szAnim, flFrameRate, bLoops, flGroundSpeed)) == -1)
{
iAnimDesired = 0;
}
new Float: flGameTime = get_gametime();
set_pev(iPlayer, pev_frame, 0.0);
set_pev(iPlayer, pev_framerate, 1.0);
set_pev(iPlayer, pev_animtime, flGameTime);
set_pev(iPlayer, pev_sequence, iAnimDesired);
set_pdata_int(iPlayer, m_fSequenceLoops, bLoops, linux_diff_animating);
set_pdata_int(iPlayer, m_fSequenceFinished, 0, linux_diff_animating);
set_pdata_float(iPlayer, m_flFrameRate, flFrameRate, linux_diff_animating);
set_pdata_float(iPlayer, m_flGroundSpeed, flGroundSpeed, linux_diff_animating);
set_pdata_float(iPlayer, m_flLastEventCheck, flGameTime , linux_diff_animating);
set_pdata_int(iPlayer, m_Activity, ACT_RANGE_ATTACK1, linux_diff_player);
set_pdata_int(iPlayer, m_IdealActivity, ACT_RANGE_ATTACK1, linux_diff_player);
set_pdata_float(iPlayer, m_flLastAttackTime, flGameTime , linux_diff_player);
}