Code: Select all
/* AMX Mod X
* Displacer Cannon (XV11382)
*
* http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community
*
* This file is provided as is (no warranties)
*/
#pragma semicolon 1
#pragma ctrlchar '\'
#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <fakemeta>
#include <fakemeta_util>
#include <hamsandwich>
#include <xs>
#define PLUGIN "Displacer Cannon (XV11382)"
#define VERSION "1.1"
#define AUTHOR "KORD_12.7"// Fixed by Bim Bim Cay
#define BALL_CLASSNAME "displacer_ball"
#define BEAM_CLASSNAME "dispball_beam"
#define IsPlayer(%1) (1 <= %1 <= g_MaxPlayers)
enum
{
ANIM_IDLE1,
ANIM_IDLE2,
ANIM_SPINUP,
ANIM_SPIN,
ANIM_FIRE,
ANIM_DRAW,
ANIM_HOLSTER,
};
enum _:DISPLACER
{
DISPLACER_ATTACK,
Float: DISPLACER_IDLE,
Float: DISPLACER_FIRE,
DISPLACER_END
};
new const
W_MODEL[] = "models/w_displacer.mdl",
V_MODEL[] = "models/v_displacer.mdl",
P_MODEL[] = "models/p_displacer.mdl";
new const
SOUND_ERROR[] = "buttons/button11.wav",
SOUND_SPIN[] = "weapons/displacer_spin.wav",
SOUND_SPIN2[] = "weapons/displacer_spin2.wav",
SOUND_FIRE[] = "weapons/displacer_fire.wav",
SOUND_TELEPORT[] = "weapons/displacer_teleport.wav",
SOUND_TELEPORT_SELF[] = "weapons/displacer_self.wav";
new const
SPRITE_BLOOD[] = "sprites/blood.spr",
SPRITE_BLOOD2[] = "sprites/bloodspray.spr",
SPRITE_PLASMA[] = "sprites/plasma.spr",
SPRITE_RING[] = "sprites/displacer_ring.spr",
SPRITE_PORTAL[] = "sprites/exit1.spr";
new const
m_pPlayer = 41,
m_iDefaultAmmo = 51,
m_flNextPrimaryAttack = 46,
m_flNextSecondaryAttack = 47,
extraoffset_weapon = 4;
new
m_iBlood[2],
m_Plasma,
m_DispRing,
m_ExitPortal;
new
g_MaxPlayers,
g_Displacer[33][DISPLACER_END];
new
pcvar_displacer_ammo1,
pcvar_displacer_ammo2,
pcvar_displacer_firerate,
pcvar_dispball_damage,
pcvar_dispball_damage_radius,
pcvar_dispball_beam_chance,
pcvar_dispball_beam_damage,
pcvar_dispball_beam_radius,
pcvar_dispball_effect_radius;
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR);
register_cvar("displacer_version", VERSION, FCVAR_SPONLY | FCVAR_SERVER | FCVAR_UNLOGGED);
RegisterHam(Ham_Item_Deploy, "weapon_m249", "Displacer_Deploy", 1);
RegisterHam(Ham_Item_PostFrame, "weapon_m249", "Displacer_PostFrame");
RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_m249", "Displacer_PrimaryAttack");
register_think(BALL_CLASSNAME, "DispBall_Think");
register_think(BEAM_CLASSNAME, "DispBeam_Think");
register_touch(BALL_CLASSNAME, "*", "DispBall_Explode_Touch");
register_forward(FM_UpdateClientData, "UpdateClientData_Post", 1);
register_forward(FM_CmdStart, "fw_CmdStart");
pcvar_displacer_ammo1 = register_cvar("xv_displacer_ammo1", "20");
pcvar_displacer_ammo2 = register_cvar("xv_displacer_ammo2", "60");
pcvar_displacer_firerate = register_cvar("xv_displacer_firerate", "2.5");
pcvar_dispball_damage = register_cvar("xv_dispball_damage", "250.0");
pcvar_dispball_damage_radius = register_cvar("xv_dispball_damage_radius", "300.0");
pcvar_dispball_beam_chance = register_cvar("xv_dispball_beam_chance", "0.1");
pcvar_dispball_beam_damage = register_cvar("xv_dispball_beam_damage", "30.0");
pcvar_dispball_beam_radius = register_cvar("xv_dispball_beam_radius", "300.0");
pcvar_dispball_effect_radius = register_cvar("xv_dispball_effect_radius", "1536.0");
g_MaxPlayers = get_maxplayers();
}
public plugin_precache()
{
m_iBlood[0] = precache_model(SPRITE_BLOOD);
m_iBlood[1] = precache_model(SPRITE_BLOOD2);
m_Plasma = precache_model(SPRITE_PLASMA);
m_DispRing = precache_model(SPRITE_RING);
m_ExitPortal = precache_model(SPRITE_PORTAL);
precache_sound(SOUND_ERROR);
precache_sound(SOUND_SPIN);
precache_sound(SOUND_SPIN2);
precache_sound(SOUND_FIRE);
precache_sound(SOUND_TELEPORT);
precache_sound(SOUND_TELEPORT_SELF);
precache_model(W_MODEL);
precache_model(V_MODEL);
precache_model(P_MODEL);
}
public UpdateClientData_Post(id, sendweapons, CD_Handle)
{
if (!is_user_alive(id) || get_user_weapon(id) != CSW_M249)
return FMRES_IGNORED;
set_cd(CD_Handle, CD_ID, 0);
return FMRES_HANDLED;
}
public Displacer_Deploy(ent)
{
new id = get_pdata_cbase(ent, m_pPlayer, extraoffset_weapon);
set_pev(id, pev_viewmodel2, V_MODEL);
set_pev(id, pev_weaponmodel2, P_MODEL);
g_Displacer[id][DISPLACER_ATTACK] = 0;
g_Displacer[id][DISPLACER_IDLE] = _:(halflife_time() + 1.1);
UTIL_PlayWeaponAnimation(id, ANIM_DRAW);
return HAM_IGNORED;
}
public Displacer_PostFrame(ent)
{
static Float: time; time = halflife_time();
static id; id = get_pdata_cbase(ent, m_pPlayer, extraoffset_weapon);
if (g_Displacer[id][DISPLACER_ATTACK] && g_Displacer[id][DISPLACER_FIRE] < time)
{
switch(g_Displacer[id][DISPLACER_ATTACK])
{
case 1:
{
DispBall_Spawn(id);
emit_sound(id, CHAN_WEAPON, SOUND_FIRE, 0.9, ATTN_NORM, 0, PITCH_NORM);
UTIL_PlayWeaponAnimation(id, ANIM_FIRE);
set_pdata_int(ent, m_iDefaultAmmo, get_pdata_int(ent, m_iDefaultAmmo, extraoffset_weapon) - get_pcvar_num(pcvar_displacer_ammo1), extraoffset_weapon);
}
case 2:
{
new resp_ent, Teleport;
if ((resp_ent = CanTeleport()))
{
if ((Teleport = DispBall_Spawn(id)))
{
DispBall_Teleport(id, resp_ent);
set_pev(Teleport, pev_velocity, Float:{0.0, 0.0, 0.0});
set_pdata_int(ent, m_iDefaultAmmo, get_pdata_int(ent, m_iDefaultAmmo, extraoffset_weapon) - get_pcvar_num(pcvar_displacer_ammo2), extraoffset_weapon);
}
}
else
{
emit_sound(id, CHAN_WEAPON, SOUND_ERROR, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
Displacer_SetNextAttack(ent, 1.0);
}
}
}
g_Displacer[id][DISPLACER_ATTACK] = 0;
}
if (g_Displacer[id][DISPLACER_IDLE] < time)
{
g_Displacer[id][DISPLACER_IDLE] = _:(time + 3.0);
UTIL_PlayWeaponAnimation(id, (random_float(0.0, 1.0) <= 0.5) ? ANIM_IDLE1 : ANIM_IDLE2);
}
return HAM_IGNORED;
}
public Displacer_PrimaryAttack(ent)
{
new id = get_pdata_cbase(ent, m_pPlayer, extraoffset_weapon);
if (!Displacer_CanFire(id, ent, get_pcvar_num(pcvar_displacer_ammo1)))
return HAM_SUPERCEDE;
g_Displacer[id][DISPLACER_ATTACK] = 1;
Displacer_SetNextAttack(ent, get_pcvar_float(pcvar_displacer_firerate));
Displacer_SpinUp(id);
return HAM_SUPERCEDE;
}
public fw_CmdStart(id, uc_handle, seed)
{
if(!is_user_alive(id))
return FMRES_IGNORED;
if(get_user_weapon(id) != CSW_M249)
return FMRES_IGNORED;
static CurButton; CurButton = get_uc(uc_handle, UC_Buttons);
static ent; ent = fm_get_user_weapon_entity(id, CSW_M249);
if(!pev_valid(ent)) return FMRES_IGNORED;
if(CurButton & IN_ATTACK2)
{
CurButton &= ~IN_ATTACK2;
set_uc(uc_handle, UC_Buttons, CurButton);
if(get_pdata_float(ent, m_flNextSecondaryAttack, extraoffset_weapon) > 0.0)
return FMRES_IGNORED;
if (!Displacer_CanFire(id, ent, get_pcvar_num(pcvar_displacer_ammo2)) || g_Displacer[id][DISPLACER_ATTACK])
return FMRES_IGNORED;
g_Displacer[id][DISPLACER_ATTACK] = 2;
Displacer_SetNextAttack(ent, get_pcvar_float(pcvar_displacer_firerate));
Displacer_SpinUp(id);
}
return FMRES_IGNORED;
}
bool: Displacer_CanFire(id, ent, ammo)
{
if (get_pdata_int(ent, m_iDefaultAmmo, extraoffset_weapon) < ammo)
{
emit_sound(id, CHAN_WEAPON, SOUND_ERROR, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
Displacer_SetNextAttack(ent, 1.0);
return false;
}
return true;
}
Displacer_SetNextAttack(ent, Float: time)
{
set_pdata_float( ent, m_flNextPrimaryAttack, time, extraoffset_weapon);
set_pdata_float( ent, m_flNextSecondaryAttack, time, extraoffset_weapon);
}
Displacer_SpinUp(id)
{
new Float: NextIdle, Float: time = halflife_time();
switch(g_Displacer[id][DISPLACER_ATTACK])
{
case 1:
{
NextIdle = 2.2;
emit_sound(id, CHAN_WEAPON, SOUND_SPIN, 0.9, ATTN_NORM, 0, PITCH_NORM);
}
case 2:
{
NextIdle = 1.24;
emit_sound(id, CHAN_WEAPON, SOUND_SPIN2, 0.9, ATTN_NORM, 0, PITCH_NORM);
}
}
if (get_pcvar_float(pcvar_displacer_firerate) >= 1.14)
g_Displacer[id][DISPLACER_FIRE] = _:(time + 1.14);
g_Displacer[id][DISPLACER_IDLE] = _:(time + NextIdle);
UTIL_PlayWeaponAnimation(id, ANIM_SPINUP);
}
DispBall_Spawn(id)
{
static AllocStringCached;
if (!AllocStringCached)
{
AllocStringCached = engfunc(EngFunc_AllocString, "info_target");
}
new ent = engfunc(EngFunc_CreateNamedEntity, AllocStringCached);
if(!pev_valid(ent)) return 0;
set_pev(ent, pev_classname, BALL_CLASSNAME);
new Float: origin[3];
new Float: velocity[3];
new Float: v_forward[3];
new Float: v_right[3];
new Float: v_up[3];
GetGunPosition(id, origin);
global_get(glb_v_forward, v_forward);
global_get(glb_v_right, v_right);
global_get(glb_v_up, v_up);
//xs_vec_mul_scalar(v_forward, 29.0, v_forward)
xs_vec_mul_scalar(v_right, 2.0, v_right);
xs_vec_mul_scalar(v_up, -5.0, v_up);
xs_vec_add(origin, v_forward, origin);
xs_vec_add(origin, v_right, origin);
xs_vec_add(origin, v_up, origin);
set_pev(ent, pev_origin, origin);
set_pev(ent, pev_owner, id);
set_pev(ent, pev_dmg, get_pcvar_float(pcvar_dispball_damage));
engfunc(EngFunc_SetModel, ent, SPRITE_PORTAL);
engfunc(EngFunc_SetSize, ent, Float:{0.0, 0.0, 0.0} , Float:{0.0, 0.0, 0.0});
set_pev(ent, pev_effects, pev(ent, pev_effects) | EF_LIGHT);
set_rendering(ent, kRenderFxNone, 0, 0, 0, kRenderTransAdd, 255);
velocity_by_aim(id, 500, velocity);
set_pev(ent, pev_velocity, velocity);
dllfunc(DLLFunc_Spawn, ent);
set_pev(ent, pev_movetype, MOVETYPE_FLY);
set_pev(ent, pev_solid, SOLID_BBOX);
set_pev(ent, pev_scale, 5);
set_pev(ent, pev_nextthink, get_gametime() + 0.1);
return ent;
}
public DispBall_Think(ent)
{
if (!pev_valid(ent))
return;
DispBall_Animate(ent);
if (pev(ent, pev_iuser4))
{
DispBall_Remove(ent);
return;
}
static Float: velocity[3];
pev(ent, pev_velocity, velocity);
if (!vector_length(velocity) || !IsInWorld(ent))
{
DispBall_Explode(ent);
return;
}
static ptr, i, id, owner, beam;
static Float: Dist;
static Float: flFraction;
static Float: origin[3];
static Float: vecDir[3];
static Float: vecEndPos[3];
Dist = 1.00; ptr = create_tr2();
static Float: beam_radius; beam_radius = get_pcvar_float(pcvar_dispball_beam_radius);
static Float: beam_damage_max; beam_damage_max = get_pcvar_float(pcvar_dispball_beam_damage);
pev(ent, pev_origin, origin);
while ((id = engfunc(EngFunc_FindEntityInSphere, id, origin, beam_radius)))
{
if (random_float(0.0, 1.0) <= get_pcvar_float(pcvar_dispball_beam_chance) && pev(id, pev_takedamage) && is_visible(id, ent) && id != (owner = pev(ent, pev_owner)))
{
static Float: target_origin[3]; pev(id, pev_origin, target_origin);
static Float: beam_dist; beam_dist = get_distance_f(target_origin, origin);
static Float: beam_dmg; beam_dmg = beam_damage_max - ( beam_damage_max / beam_radius ) * beam_dist;
if (beam_dmg < 1.0)
continue;
ExecuteHamB(Ham_TakeDamage, id, ent, owner, beam_dmg, DMG_ENERGYBEAM );
if ((beam = BeamCreate(id, SPRITE_PLASMA, m_Plasma, 65.0)))
{
RelinkBeam(beam, origin, target_origin);
BeamSetColor(beam, 255.0, 255.0, 255.0);
BeamSetNoise(beam, 45);
BeamSetBrightness(beam, 255.0);
BeamSetScrollRate(beam, 35.0);
BeamLiveForTime(beam, 0.1);
}
}
}
for (i = 0; i < 10; i++)
{
vecDir[0] = random_float(-1.0, 1.0);
vecDir[1] = random_float(-1.0, 1.0);
vecDir[2] = random_float(-1.0, 1.0);
VecNormilize(vecDir, vecDir);
xs_vec_mul_scalar(vecDir, get_pcvar_float(pcvar_dispball_effect_radius), vecDir);
xs_vec_add(vecDir, origin, vecDir);
engfunc(EngFunc_TraceLine, origin, vecDir, IGNORE_MONSTERS, ent, ptr);
get_tr2(ptr, TR_flFraction, flFraction);
if (Dist > flFraction)
{
get_tr2(ptr, TR_vecEndPos, vecEndPos);
Dist = flFraction;
}
}
if (Dist < 1.0)
{
if ((beam = BeamCreate(ent, SPRITE_PLASMA, m_Plasma, 30.0)))
{
RelinkBeam(beam, vecEndPos, origin);
BeamSetColor(beam, 90.0, 170.0, 16.0);
BeamSetNoise(beam, 65);
BeamSetBrightness(beam, 255.0);
BeamSetScrollRate(beam, 35.0);
BeamLiveForTime(beam, 1.0);
}
}
set_pev(ent, pev_nextthink, get_gametime() + 0.1);
free_tr2(ptr);
}
public DispBeam_Think(ent)
{
if (pev_valid(ent))
{
remove_entity(ent);
}
}
public DispBall_Explode_Touch(ent, other)
{
if (pev_valid(ent))
{
DispBall_Explode(ent, other);
}
}
DispBall_Explode(ent, other = 0)
{
if (!pev(ent, pev_iuser3))
{
new Float: origin[3];
pev(ent, pev_origin, origin);
set_pev(ent, pev_iuser3, 1);
UTIL_MakeBeamCylinder(origin, m_DispRing) ;
}
if (IsPlayer(other))
{
new resp_ent;
if ((resp_ent = CanTeleport()))
DispBall_Teleport(other, resp_ent);
}
set_pev(ent, pev_velocity, Float:{0.0, 0.0, 0.0});
set_pev(ent, pev_iuser4, 1);
set_pev(ent, pev_nextthink, get_gametime() + 0.6);
}
CanTeleport()
{
new ent, alert, i;
do
{
for (i = random_num(1, 10); i > 0; i-- )
ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "info_player_deathmatch");
if (alert ++ > 10) return 0;
}
while (!IsSpawnPointValid(ent));
return ent;
}
DispBall_Teleport(id, resp_ent)
{
new Float: origin[3], Float: angles[3];
pev(resp_ent, pev_origin, origin);
pev(resp_ent, pev_angles, angles);
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_SPRITE);
engfunc(EngFunc_WriteCoord, origin[0]);
engfunc(EngFunc_WriteCoord, origin[1]);
engfunc(EngFunc_WriteCoord, origin[2]);
write_short(m_ExitPortal);
write_byte(10);
write_byte(128);
message_end();
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_DLIGHT);
engfunc(EngFunc_WriteCoord, origin[0]);
engfunc(EngFunc_WriteCoord, origin[1]);
engfunc(EngFunc_WriteCoord, origin[2]);
write_byte(20) ;
write_byte(90); // red
write_byte(170); // green
write_byte(16); // blue
write_byte(255);
write_byte(5);
write_byte(1);
message_end();
emit_sound(resp_ent, CHAN_WEAPON, SOUND_TELEPORT_SELF, 1.0, ATTN_NORM, 0, PITCH_NORM);
set_pev(id, pev_velocity, Float:{0.0, 0.0, 0.0});
set_pev(id, pev_basevelocity, Float:{0.0, 0.0, 0.0});
set_pev(id, pev_origin, origin);
set_pev(id, pev_angles, angles);
set_pev(id, pev_fixangle, true);
}
bool: IsSpawnPointValid(const resp_ent)
{
new ent = FM_NULLENT;
new Float: origin[3];
pev(resp_ent, pev_origin, origin);
while((ent= engfunc(EngFunc_FindEntityInSphere, ent, origin, 10.0)))
{
return IsPlayer(ent) ? false : true;
}
return false;
}
DispBall_Remove(const ent)
{
new Float: origin[3]; pev(ent, pev_origin, origin);
UTIL_RadiusDamage(origin, ent, pev(ent, pev_owner), float(pev(ent, pev_dmg)), get_pcvar_float(pcvar_dispball_damage_radius), 0, DMG_ENERGYBEAM);
emit_sound(ent, CHAN_VOICE, SOUND_TELEPORT, 0.9, ATTN_NORM, 0, PITCH_NORM);
remove_entity(ent);
}
DispBall_Animate(const ent)
{
entity_set_float(ent, EV_FL_frame, entity_get_float(ent, EV_FL_frame) + 10.0);
if (entity_get_float(ent, EV_FL_frame) > 24)
entity_set_float(ent, EV_FL_frame, 0.0);
}
stock GetGunPosition(const player, Float:origin[3] )
{
new Float:viewOfs[3];
pev(player, pev_origin, origin);
pev(player, pev_view_ofs, viewOfs);
xs_vec_add( origin, viewOfs, origin);
}
stock VecNormilize(Float: in[3], Float: out[3])
{
static Float: vlen;
vlen = vector_length(in);
vlen = 1/vlen;
out[0] *= vlen;
out[1] *= vlen;
out[2] *= vlen;
}
stock UTIL_PlayWeaponAnimation(const Player, const Sequence)
{
set_pev(Player, pev_weaponanim, Sequence);
message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player);
write_byte(Sequence);
write_byte(pev(Player, pev_body));
message_end();
}
stock UTIL_MakeBlood(const Float:vTraceEnd[3], const Float:Damage, const hitEnt)
{
new bloodColor = ExecuteHam(Ham_BloodColor, hitEnt);
if (bloodColor == -1) return;
new amount = floatround(Damage); amount *= 2;
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BLOODSPRITE);
engfunc(EngFunc_WriteCoord, vTraceEnd[0]);
engfunc(EngFunc_WriteCoord, vTraceEnd[1]);
engfunc(EngFunc_WriteCoord, vTraceEnd[2]);
write_short(m_iBlood[1]);
write_short(m_iBlood[0]);
write_byte(bloodColor);
write_byte(min(max(3, amount/10), 16));
message_end();
}
stock UTIL_MakeBeamCylinder(const Float:origin[3], const m_Sprite)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMCYLINDER);
engfunc(EngFunc_WriteCoord, origin[0]);
engfunc(EngFunc_WriteCoord, origin[1]);
engfunc(EngFunc_WriteCoord, origin[2]);
engfunc(EngFunc_WriteCoord, origin[0]);
engfunc(EngFunc_WriteCoord, origin[1]);
engfunc(EngFunc_WriteCoord, origin[2] + 800.0) ;
write_short(m_Sprite) ;
write_byte(0);
write_byte(10);
write_byte(3);
write_byte(20);
write_byte(0);
write_byte(255);
write_byte(255);
write_byte(255);
write_byte(255);
write_byte(0);
message_end();
}
stock UTIL_RadiusDamage(Float:vecSrc[3], iInflictor, iAttacker=0, Float:flDamage, Float:flRadius=0.0, iClassIgnore = 0, bitsDamageType)
{
new pEntity = FM_NULLENT;
new tr = create_tr2();
new Float:flAdjustedDamage, Float:falloff;
new Float:vecSpot[3];
if ( flRadius )
{
falloff = flDamage / flRadius;
}
else
{
falloff = 1.0;
}
new bool: bInWater = (engfunc(EngFunc_PointContents, vecSrc) == CONTENTS_WATER);
vecSrc[2] += 1.0; // in case grenade is lying on the ground
if ( !iAttacker )
{
iAttacker = iInflictor;
}
// iterate on all entities in the vicinity.
new Float:flTakeDamage, Float:flFraction, Float:vecEndPos[3], Float:vecViewOfs[3];
while ((pEntity = engfunc(EngFunc_FindEntityInSphere, pEntity, vecSrc, flRadius)) )
{
if (!is_visible(pEntity, iInflictor))
{
continue;
}
pev(pEntity, pev_takedamage, flTakeDamage);
if ( flTakeDamage != DAMAGE_NO )
{
if ( iClassIgnore != 0 && ExecuteHamB(Ham_Classify, pEntity) == iClassIgnore )
{
continue;
}
if( bInWater )
{
if( !pev(pEntity, pev_waterlevel) )
{
continue;
}
}
else if( pev(pEntity, pev_waterlevel) == 3 )
{
continue;
}
pev(pEntity, pev_origin, vecSpot);
if( ExecuteHamB(Ham_IsPlayer, pEntity) )
{
pev(pEntity, pev_view_ofs, vecViewOfs);
xs_vec_add(vecSpot, vecViewOfs, vecSpot);
}
engfunc(EngFunc_TraceLine, vecSrc, vecSpot, false, iInflictor, tr );
get_tr2(tr, TR_flFraction, flFraction);
if (get_tr2(tr, TR_StartSolid))
{
flFraction = 0.0;
flAdjustedDamage = flDamage;
}
else
{
get_tr2(tr, TR_vecEndPos, vecEndPos);
xs_vec_sub(vecSrc, vecEndPos, vecEndPos);
flAdjustedDamage = vector_length(vecEndPos) * falloff;
flAdjustedDamage = flDamage - flAdjustedDamage;
}
if ( flAdjustedDamage < 0.0 )
{
flAdjustedDamage = 0.0;
}
if (flFraction != 1.0)
{
switch( get_tr2(tr, TR_iHitgroup) )
{
case HIT_HEAD:
{
flAdjustedDamage *= 4.0;
}
case HIT_STOMACH:
{
flAdjustedDamage *= 1.25;
}
case HIT_LEFTLEG, HIT_RIGHTLEG:
{
flAdjustedDamage *= 0.75;
}
}
}
UTIL_MakeBlood(vecSpot, flAdjustedDamage, pEntity);
ExecuteHamB(Ham_TakeDamage, pEntity, iInflictor, iAttacker, flAdjustedDamage, bitsDamageType);
}
}
free_tr2(tr);
}
//*************************************
//* Manage Beam *
//*************************************
BeamCreate(const endIndex, const pSpriteName[], const spriteIndex, const Float: width)
{
static AllocStringCached;
if (!AllocStringCached)
{
AllocStringCached = engfunc(EngFunc_AllocString, "beam");
}
static ent;
if (!(ent = engfunc(EngFunc_CreateNamedEntity, AllocStringCached)))
return 0;
set_pev(ent, pev_classname, BEAM_CLASSNAME);
set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_CUSTOMENTITY);
BeamSetFrame(ent, 0);
set_pev(ent, pev_model, pSpriteName);
BeamSetTexture(ent, spriteIndex);
BeamSetWidth(ent, width);
set_pev(ent, pev_skin, endIndex);
set_pev(ent, pev_sequence, 0);
set_pev(ent, pev_rendermode, 1);
DispatchSpawn(ent);
return ent;
}
RelinkBeam(const beam, const Float: startPos[3], const Float: endPos[3])
{
static Float: mins[3], Float: maxs[3];
mins[0] = floatmin(startPos[0], endPos[0]);
mins[1] = floatmin(startPos[1], endPos[1]);
mins[2] = floatmin(startPos[2], endPos[2]);
maxs[0] = floatmax(startPos[0], endPos[0]);
maxs[1] = floatmax(startPos[1], endPos[1]);
maxs[2] = floatmax(startPos[2], endPos[2]);
xs_vec_sub(mins, startPos, mins);
xs_vec_sub(maxs, startPos, maxs);
set_pev(beam, pev_mins, mins);
set_pev(beam, pev_maxs, maxs);
engfunc(EngFunc_SetSize, beam, mins, maxs);
engfunc(EngFunc_SetOrigin, beam, startPos);
}
BeamLiveForTime(const ent, const Float: time)
{
set_pev(ent, pev_nextthink, halflife_time() + time);
}
BeamSetColor(const ent, const Float: red, const Float: green, const Float: blue)
{
static Float: rgb[3];
rgb[0] = red;
rgb[1] = green;
rgb[2] = blue;
set_pev(ent, pev_rendercolor, rgb);
}
BeamSetBrightness(const ent, const Float: brightness)
{
set_pev(ent, pev_renderamt, brightness);
}
BeamSetNoise(const ent, const noise)
{
set_pev(ent, pev_body, noise);
}
BeamSetFrame(const ent, const frame)
{
set_pev(ent, pev_frame, frame);
}
BeamSetScrollRate(const ent, const Float: speed)
{
set_pev(ent, pev_animtime, speed);
}
BeamSetTexture(const ent, const spriteIndex)
{
set_pev(ent, pev_modelindex, spriteIndex);
}
BeamSetWidth(const ent, const Float: width)
{
set_pev(ent, pev_scale, width);
}