День добрый, Собственно требуется помощь с фиксом плагина [ZP] Weapon Stinger
Оружие выпускает стрелу, которая цепляется за ентити и игроков. Как можно сделать, чтобы стрела не встревала в людей, а только в зомби и другие объекты?
Заранее низкий поклон
Оружие выпускает стрелу, которая цепляется за ентити и игроков. Как можно сделать, чтобы стрела не встревала в людей, а только в зомби и другие объекты?
Заранее низкий поклон
Код:
/*
* [1.0] - Первый релиз
*
* [1.0.1] - Bug fix: WeaponList на кастомных оружиях M249 не работал, кроме этого оружия
*
* [1.0.2] - Перенос Touch & Think с fakemeta на hamsandwich модуль
*/
#include <amxmodx>
#include <fakemeta_util>
#include <hamsandwich>
#include <zombieplague>
#define IsCustomItem(%0) (pev(%0, pev_impulse) == WEAPON_SPECIAL_CODE)
#define PDATA_SAFE 2
#define DMG_GRENADE (1<<24)
/* ~ [ Weapon Animations ] ~ */
#define WEAPON_ANIM_IDLE_TIME 61/30.0
#define WEAPON_ANIM_SHOOT_TIME 31/30.0
#define WEAPON_ANIM_RELOAD_TIME 59/30.0
#define WEAPON_ANIM_DRAW_TIME 46/30.0
enum
{
WEAPON_ANIM_IDLE = 0,
WEAPON_ANIM_IDLE2,
WEAPON_ANIM_IDLE3,
WEAPON_ANIM_SHOOT,
WEAPON_ANIM_SHOOT2,
WEAPON_ANIM_SHOOT3,
WEAPON_ANIM_RELOAD,
WEAPON_ANIM_DRAW,
WEAPON_ANIM_DRAW2,
WEAPON_ANIM_DRAW3,
WEAPON_ANIM_DRAW_EMPTY,
WEAPON_ANIM_IDLE_EMPTY,
WEAPON_ANIM_SHOOT_EMPTY
};
/* ~ [ Extra Item ] ~ */
new const WEAPON_ITEM_NAME[] = "Stinger";
const WEAPON_ITEM_COST = 0;
/* ~ [ Weapon Settings ] ~ */
new const WEAPON_REFERENCE[] = "weapon_m249";
new const WEAPON_WEAPONLIST[] = "x/weapon_speargunm";
new const WEAPON_NATIVE[] = "zp_give_user_speargunm";
new const WEAPON_MODEL_VIEW[] = "models/x/v_speargunm.mdl";
new const WEAPON_MODEL_PLAYER[] = "models/x/p_speargunm.mdl";
new const WEAPON_MODEL_WORLD[] = "models/x/w_speargunm.mdl";
new const WEAPON_SOUND_FIRE[] = "weapons/speargunm-1.wav";
new const WEAPON_SOUND_EMPTY[] = "weapons/speargunm_empty.wav";
const WEAPON_SPECIAL_CODE = 2019;
const WEAPON_BODY = 0;
const WEAPON_MAX_CLIP = 3;
const WEAPON_DEFAULT_AMMO = 30;
const Float: WEAPON_RATE = 0.88;
new const iWeaponList[] = { 3, WEAPON_DEFAULT_AMMO,-1, -1, 0, 4, 20, 0 };
/* ~ [ Entity ] ~ */
new const ENTITY_REFERENCE[] = "info_target";
new const ENTITY_CLASSNAME[] = "ent_spearm";
new const ENTITY_MODEL[] = "models/x/spearm.mdl";
new const ENTITY_EXPLODE_MODEL[] = "models/x/spearm2.mdl";
new const ENTITY_EXPLODE_SPRITE[] = "sprites/fexplo.spr";
new const ENTITY_TRAIL_SPRITE[] = "sprites/laserbeam.spr";
const Float: ENTITY_SPEED = 2000.0; // Max value 2000
const Float: ENTITY_KNOCKBACK = 1500.0;
const Float: ENTITY_KNOCK_EXP = 225.0;
const Float: ENTITY_DAMAGE = 250.0;
const Float: ENTITY_RADIUS_EXP = 100.0;
#define ENTITY_DAMAGE_EXP random_float(250.0, 400.0)
/* ~ [ Offsets ] ~ */
// Linux extra offsets
#define linux_diff_weapon 4
#define linux_diff_player 5
// CWeaponBox
#define m_rgpPlayerItems_CWeaponBox 34
// CBaseAnimating
#define m_flLastEventCheck 38
// 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
// CBaseMonster
#define m_LastHitGroup 75
#define m_flNextAttack 83
// CBasePlayer
#define m_rpgPlayerItems 367
#define m_pActiveItem 373
#define m_rgAmmo 376
/* ~ [ Params ] ~ */
new g_iszAllocString_Entity,
g_iszAllocString_ModelView,
g_iszAllocString_ModelPlayer,
g_iszAllocString_InfoTarget,
g_iszAllocString_SpearClass,
g_iszModelIndex_BloodSpray,
g_iszModelIndex_BloodDrop,
g_iszModelIndex_LaserBeam,
g_iszModelIndex_Explosion,
g_iszModelIndex_BreakSpear,
g_iMsgID_Weaponlist,
g_iItemID;
public plugin_init()
{
register_plugin("[ZP] Weapon: Stinger", "1.0.2", "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_Think, ENTITY_REFERENCE, "CEntity__Think_Pre", false);
RegisterHam(Ham_Touch, ENTITY_REFERENCE, "CEntity__Touch_Pre", false);
g_iMsgID_Weaponlist = get_user_msgid("WeaponList");
}
public plugin_precache()
{
// Hook weapon
register_clcmd(WEAPON_WEAPONLIST, "Command_HookWeapon");
// Precache models
engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_VIEW);
engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_PLAYER);
engfunc(EngFunc_PrecacheModel, WEAPON_MODEL_WORLD);
engfunc(EngFunc_PrecacheModel, ENTITY_MODEL);
// Precache generic
UTIL_PrecacheSpritesFromTxt(WEAPON_WEAPONLIST);
// Precache sounds
engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_FIRE);
engfunc(EngFunc_PrecacheSound, WEAPON_SOUND_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);
g_iszAllocString_InfoTarget = engfunc(EngFunc_AllocString, ENTITY_REFERENCE);
g_iszAllocString_SpearClass = engfunc(EngFunc_AllocString, ENTITY_CLASSNAME);
g_iszModelIndex_BloodSpray = engfunc(EngFunc_PrecacheModel, "sprites/bloodspray.spr");
g_iszModelIndex_BloodDrop = engfunc(EngFunc_PrecacheModel, "sprites/blood.spr");
g_iszModelIndex_LaserBeam = engfunc(EngFunc_PrecacheModel, ENTITY_TRAIL_SPRITE);
g_iszModelIndex_Explosion = engfunc(EngFunc_PrecacheModel, ENTITY_EXPLODE_SPRITE);
g_iszModelIndex_BreakSpear = engfunc(EngFunc_PrecacheModel, ENTITY_EXPLODE_MODEL);
}
public plugin_natives() register_native(WEAPON_NATIVE, "Command_GiveWeapon", 1);
// [ Amxx ]
public zp_extra_item_selected(iPlayer, iItem)
{
if(iItem == g_iItemID)
Command_GiveWeapon(iPlayer);
}
public Command_HookWeapon(iPlayer)
{
engclient_cmd(iPlayer, WEAPON_REFERENCE);
return PLUGIN_HANDLED;
}
public Command_GiveWeapon(iPlayer)
{
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);
set_pdata_int(iEntity, m_iClip, WEAPON_MAX_CLIP, linux_diff_weapon);
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);
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(!is_user_alive(iPlayer)) return;
static iItem; iItem = get_pdata_cbase(iPlayer, m_pActiveItem, linux_diff_player);
if(pev_valid(iItem) != PDATA_SAFE || !IsCustomItem(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 && IsCustomItem(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(!IsCustomItem(iItem)) return;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
set_pdata_float(iItem, m_flNextPrimaryAttack, 0.0, linux_diff_weapon);
set_pdata_float(iItem, m_flNextSecondaryAttack, 0.0, linux_diff_weapon);
set_pdata_float(iItem, m_flTimeWeaponIdle, 0.0, linux_diff_weapon);
set_pdata_float(iPlayer, m_flNextAttack, 0.0, linux_diff_player);
}
public CWeapon__Deploy_Post(iItem)
{
if(!IsCustomItem(iItem)) return;
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
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, iClip <= 0 ? WEAPON_ANIM_DRAW_EMPTY : (WEAPON_ANIM_DRAW3 + 1) - iClip);
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);
}
public CWeapon__PostFrame_Pre(iItem)
{
if(!IsCustomItem(iItem)) return HAM_IGNORED;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
if(get_pdata_int(iItem, m_fInReload, linux_diff_weapon) == 1)
{
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
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);
}
static iButton; iButton = pev(iPlayer, pev_button);
if(iButton & IN_ATTACK2 && get_pdata_float(iItem, m_flNextSecondaryAttack, linux_diff_weapon) <= 0.0)
{
new iEntity = FM_NULLENT;
while((iEntity = fm_find_ent_by_owner(iEntity, ENTITY_CLASSNAME, iPlayer)) > 0)
{
Create_ExplodeSpear(iEntity, pev(iEntity, pev_aiment));
}
set_pdata_float(iItem, m_flNextSecondaryAttack, 1.0, linux_diff_weapon);
iButton &= ~IN_ATTACK2;
set_pev(iPlayer, pev_button, iButton);
}
return HAM_IGNORED;
}
public CWeapon__AddToPlayer_Post(iItem, iPlayer)
{
if(pev(iItem, pev_impulse) == WEAPON_SPECIAL_CODE) UTIL_WeaponList(iPlayer, true);
else if(pev(iItem, pev_impulse) == 0) UTIL_WeaponList(iPlayer, false);
}
public CWeapon__Reload_Pre(iItem)
{
if(!IsCustomItem(iItem)) return HAM_IGNORED;
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
if(iClip >= WEAPON_MAX_CLIP) return HAM_SUPERCEDE;
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
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);
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_RELOAD);
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(!IsCustomItem(iItem) || get_pdata_float(iItem, m_flTimeWeaponIdle, linux_diff_weapon) > 0.0) return HAM_IGNORED;
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
UTIL_SendWeaponAnim(iPlayer, iClip <= 0 ? WEAPON_ANIM_IDLE_EMPTY : (WEAPON_ANIM_IDLE3 + 1) - iClip);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_IDLE_TIME, linux_diff_weapon);
return HAM_SUPERCEDE;
}
public CWeapon__PrimaryAttack_Pre(iItem)
{
if(!IsCustomItem(iItem)) return HAM_IGNORED;
static iClip; iClip = get_pdata_int(iItem, m_iClip, linux_diff_weapon);
static iPlayer; iPlayer = get_pdata_cbase(iItem, m_pPlayer, linux_diff_weapon);
if(iClip == 0)
{
UTIL_SendWeaponAnim(iPlayer, WEAPON_ANIM_SHOOT_EMPTY);
emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_EMPTY, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_ANIM_SHOOT_TIME, linux_diff_weapon);
set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_ANIM_SHOOT_TIME, linux_diff_weapon);
return HAM_SUPERCEDE;
}
Create_Spear(iPlayer);
UTIL_SendWeaponAnim(iPlayer, (WEAPON_ANIM_SHOOT3 + 1) - iClip);
emit_sound(iPlayer, CHAN_WEAPON, WEAPON_SOUND_FIRE, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
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_flTimeWeaponIdle, WEAPON_ANIM_SHOOT_TIME, linux_diff_weapon);
return HAM_SUPERCEDE;
}
public CEntity__Think_Pre(iEntity)
{
if(pev_valid(iEntity) != PDATA_SAFE) return HAM_IGNORED;
if(pev(iEntity, pev_classname) == g_iszAllocString_SpearClass)
{
Create_ExplodeSpear(iEntity, pev(iEntity, pev_aiment));
}
return HAM_IGNORED;
}
public CEntity__Touch_Pre(iEntity, iTouch)
{
if(pev_valid(iEntity) != PDATA_SAFE) return HAM_IGNORED;
if(pev(iEntity, pev_classname) == g_iszAllocString_SpearClass)
{
new iOwner = pev(iEntity, pev_owner);
new Float: vecOrigin[3]; pev(iEntity, pev_origin, vecOrigin);
new Float: flGameTime = get_gametime();
if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_SKY)
{
set_pev(iEntity, pev_flags, FL_KILLME);
return HAM_IGNORED;
}
if(iTouch == iOwner) return HAM_SUPERCEDE;
// Aiment + Velocity
if(is_user_connected(iTouch))
{
if(zp_get_user_zombie(iTouch))
{
new Float: vecVVelocity[3]; pev(iEntity, pev_vuser1, vecVVelocity);
set_pev(iTouch, pev_velocity, vecVVelocity);
}
set_pev(iEntity, pev_aiment, iTouch);
set_pev(iEntity, pev_movetype, MOVETYPE_FOLLOW);
}
else
{
set_pev(iEntity, pev_movetype, MOVETYPE_NONE);
}
set_pev(iEntity, pev_solid, SOLID_NOT);
set_pev(iEntity, pev_velocity, Float: {0.0, 0.0, 0.0});
set_pev(iEntity, pev_nextthink, flGameTime + 1.2);
// Damage
if(iTouch)
{
if(pev(iTouch, pev_takedamage) == DAMAGE_NO)
return HAM_IGNORED;
if(is_user_alive(iTouch))
{
if(iTouch == iOwner || zp_get_user_zombie(iOwner) || !zp_get_user_zombie(iTouch))
return HAM_IGNORED;
}
else if(pev(iTouch, pev_solid) == SOLID_BSP)
{
if(pev(iTouch, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY)
return HAM_IGNORED;
}
new Float: flDamage = ENTITY_DAMAGE;
if(is_user_connected(iTouch) && zp_get_user_zombie(iTouch))
{
new Float: vecVelocity[3]; pev(iEntity, pev_velocity, vecVelocity);
vecVelocity[0] += vecOrigin[0];
vecVelocity[1] += vecOrigin[1];
vecVelocity[2] += vecOrigin[2];
new iTrace = create_tr2();
engfunc(EngFunc_TraceLine, vecOrigin, vecVelocity, DONT_IGNORE_MONSTERS, iEntity, iTrace);
new iHitGroup = get_tr2(iTrace, TR_iHitgroup);
set_pdata_int(iTouch, 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;
}
new Float: vecEndPos[3]; get_tr2(iTrace, TR_vecEndPos, vecEndPos);
UTIL_BloodDrips(vecEndPos, ExecuteHamB(Ham_BloodColor, iTouch), floatround(flDamage));
free_tr2(iTrace);
}
ExecuteHamB(Ham_TakeDamage, iTouch, iOwner, iOwner, flDamage, DMG_BULLET|DMG_NEVERGIB);
}
}
return HAM_IGNORED;
}
// [ Other ]
public Create_Spear(iPlayer)
{
new iEntity = engfunc(EngFunc_CreateNamedEntity, g_iszAllocString_InfoTarget);
if(!iEntity) return 0;
new Float: flGameTime = get_gametime();
new Float: vecOrigin[3]; pev(iPlayer, pev_origin, vecOrigin);
new Float: vecAngles[3]; pev(iPlayer, pev_v_angle, vecAngles);
new Float: vecVelocity[3]; angle_vector(vecAngles, ANGLEVECTOR_FORWARD, vecVelocity);
new Float: vecViewOfs[3]; pev(iPlayer, pev_view_ofs, vecViewOfs);
vecOrigin[0] += vecViewOfs[0] + vecVelocity[0] * 20.0;
vecOrigin[1] += vecViewOfs[1] + vecVelocity[1] * 20.0;
vecOrigin[2] += vecViewOfs[2] + vecVelocity[2] * 20.0;
vecVelocity[0] *= ENTITY_SPEED;
vecVelocity[1] *= ENTITY_SPEED;
vecVelocity[2] *= ENTITY_SPEED;
new Float: vecVVelocity[3]; // Victim velocity
velocity_by_aim(iPlayer, floatround(ENTITY_KNOCKBACK), vecVVelocity);
engfunc(EngFunc_SetModel, iEntity, ENTITY_MODEL);
engfunc(EngFunc_SetOrigin, iEntity, vecOrigin);
set_pev_string(iEntity, pev_classname, g_iszAllocString_SpearClass);
set_pev(iEntity, pev_solid, SOLID_TRIGGER);
set_pev(iEntity, pev_movetype, MOVETYPE_FLY);
set_pev(iEntity, pev_owner, iPlayer);
set_pev(iEntity, pev_velocity, vecVelocity);
engfunc(EngFunc_VecToAngles, vecVelocity, vecAngles);
set_pev(iEntity, pev_angles, vecAngles);
set_pev(iEntity, pev_nextthink, flGameTime + 2.0);
set_pev(iEntity, pev_vuser1, vecVVelocity);
// https://github.com/baso88/SC_AngelScript/wiki/TE_BEAMFOLLOW
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMFOLLOW); // TE
write_short(iEntity); // Target
write_short(g_iszModelIndex_LaserBeam); // Model Index
write_byte(2); // Life
write_byte(1); // Width
write_byte(210); // Red
write_byte(210); // Green
write_byte(210); // Blue
write_byte(150); // Alpha
message_end();
return iEntity;
}
public Create_ExplodeSpear(iEntity, iAimEnt)
{
new iOwner = pev(iEntity, pev_owner);
new Float: vecOrigin[3]; pev(iAimEnt ? iAimEnt : iEntity, pev_origin, vecOrigin);
new iVictim = FM_NULLENT;
while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOrigin, ENTITY_RADIUS_EXP)) > 0)
{
if(pev_valid(iVictim) != PDATA_SAFE) continue;
if(pev(iVictim, pev_takedamage) == DAMAGE_NO)
continue;
if(is_user_alive(iVictim))
{
if(!is_wall_between_points(iOwner, iVictim))
continue;
if(iVictim == iOwner || zp_get_user_zombie(iVictim))
{
static Float: vecVVelocity[3]; pev(iVictim, pev_velocity, vecVVelocity);
vecVVelocity[2] += ENTITY_KNOCK_EXP;
set_pev(iVictim, pev_velocity, vecVVelocity);
}
if(iVictim == iOwner || !zp_get_user_zombie(iVictim))
continue;
}
else if(pev(iVictim, pev_solid) == SOLID_BSP)
{
if(pev(iVictim, pev_spawnflags) & SF_BREAK_TRIGGER_ONLY)
continue;
}
if(is_user_connected(iVictim))
set_pdata_int(iVictim, m_LastHitGroup, HIT_GENERIC, linux_diff_player);
ExecuteHamB(Ham_TakeDamage, iVictim, iOwner, iOwner, ENTITY_DAMAGE_EXP, DMG_GRENADE);
}
// https://github.com/baso88/SC_AngelScript/wiki/TE_EXPLOSION
engfunc(EngFunc_MessageBegin, MSG_PAS, SVC_TEMPENTITY, vecOrigin, 0);
write_byte(TE_EXPLOSION); // TE
engfunc(EngFunc_WriteCoord, vecOrigin[0]); // Position X
engfunc(EngFunc_WriteCoord, vecOrigin[1]); // Position Y
engfunc(EngFunc_WriteCoord, vecOrigin[2] + 50.0); // Position Z
write_short(g_iszModelIndex_Explosion); // Model Index
write_byte(14); // Scale
write_byte(45); // Framerate
write_byte(0); // Flags
message_end();
// https://github.com/baso88/SC_AngelScript/wiki/TE_BREAKMODEL
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BREAKMODEL); // TE
engfunc(EngFunc_WriteCoord, vecOrigin[0]); // Position X
engfunc(EngFunc_WriteCoord, vecOrigin[1]); // Position Y
engfunc(EngFunc_WriteCoord, vecOrigin[2] + 20.0); // Position Z
engfunc(EngFunc_WriteCoord, 150); // Size X
engfunc(EngFunc_WriteCoord, 150); // Size Y
engfunc(EngFunc_WriteCoord, 150); // Size Z
engfunc(EngFunc_WriteCoord, random_num(-50, 50)); // Velocity X
engfunc(EngFunc_WriteCoord, random_num(-50, 50)); // Velocity Y
engfunc(EngFunc_WriteCoord, random_num(-50, 50)); // Velocity Z
write_byte(30); // Noise
write_short(g_iszModelIndex_BreakSpear); // Model Index
write_byte(random_num(15, 20)); // Count
write_byte(20); // Life
write_byte(16); // Flags
message_end();
set_pev(iEntity, pev_flags, FL_KILLME);
}
// [ Stocks ]
stock is_wall_between_points(iPlayer, iEntity)
{
// vector
#define Vector_Equal(%0,%1) ((%1[0] == %0[0]) && (%1[1] == %0[1]) && (%1[2] == %0[2]))
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 Vector_Equal(flEnd, flEndPos);
}
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);
}
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);
}
public UTIL_BloodDrips(Float: vecOrigin[3], iColor, iAmount)
{
if(iAmount > 255) iAmount = 255;
// https://github.com/baso88/SC_AngelScript/wiki/TE_BLOODSPRITE
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0);
write_byte(TE_BLOODSPRITE); // TE
engfunc(EngFunc_WriteCoord, vecOrigin[0]); // Position X
engfunc(EngFunc_WriteCoord, vecOrigin[1]); // Position Y
engfunc(EngFunc_WriteCoord, vecOrigin[2]); // Position Z
write_short(g_iszModelIndex_BloodSpray); // Model Index (1)
write_short(g_iszModelIndex_BloodDrop); // Model Index (2)
write_byte(iColor); // Color
write_byte(min(max(3,iAmount/10),16)); // Scale
message_end();
}
stock UTIL_WeaponList(iPlayer, bool: bEnabled)
{
message_begin(MSG_ONE, g_iMsgID_Weaponlist, _, iPlayer);
write_string(bEnabled ? WEAPON_WEAPONLIST : 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();
}