Code:
#include <amxmodx>
#include <cstrike>
#include <hamsandwich>
#include <engine>
#include <fakemeta>
#include <xs>
#define PLUGIN "Impulse Grenade"
#define VERSION "1.3"
#define AUTHOR "EFFx"
#define explodeGrenade(%1) set_pev(%1, pev_dmgtime, 0.0)
#define message_begin_fl(%1,%2,%3,%4) engfunc(EngFunc_MessageBegin, %1, %2, %3, %4)
#define write_coord_fl(%1) engfunc(EngFunc_WriteCoord, %1)
#define MAX_MONEY 16000
#define MAX_PLAYERS 32
#define LOG_FILE "ig_logfile.log"
const g_offEvent = 114
const m_pPlayer = 41
const OFFSET_LINUX_WEAPONS = 4
new g_iSmokeEventID
new bool:g_bIsPluginEnabled, bool:g_bIsImpactModeOn
new g_pCvarEnabled, g_pCvarSelfImpulse, g_pCvarImpulseMultiplier, g_pCvarRadius, g_pCvarFFA,
g_pCvarKillMoney, g_pCvarKillInfo, g_pCvarPlayerTrailColor, g_pCvarExplosionColor,
g_pCvarImpactMode
new g_iPlayerTrailSprite, g_iExplosionSprite
new g_mMessageDeathMsg, g_mMessageSayText
new const g_szViewModel[] = "models/v_impulsegrenade.mdl"
new const g_szPlayerModel[] = "models/p_impulsegrenade.mdl"
new const g_szWorldModel[] = "models/w_impulsegrenade.mdl"
new const g_szExplodeSound[] = "weapons/sbarrel1.wav"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pCvarEnabled = register_cvar("impulsegrenade_on", "1")
g_pCvarSelfImpulse = register_cvar("impulsegrenade_self_impulse", "1")
g_pCvarImpulseMultiplier = register_cvar("impulsegrenade_multiplier", "3.8")
g_pCvarRadius = register_cvar("impulsegrenade_radius", "300.0")
g_pCvarFFA = register_cvar("impulsegrenade_ffa", "1")
g_pCvarKillMoney = register_cvar("impulsegrenade_killmoney", "500")
g_pCvarKillInfo = register_cvar("impulsegrenade_killinfo", "1")
g_pCvarPlayerTrailColor = register_cvar("impulsegrenade_trailcolor", "255255255")
g_pCvarExplosionColor = register_cvar("impulsegrenade_blastcolor", "255255255")
g_pCvarImpactMode = register_cvar("impulsegrenade_impactmode", "1")
g_mMessageDeathMsg = get_user_msgid("DeathMsg")
g_mMessageSayText = get_user_msgid("SayText")
g_iSmokeEventID = engfunc(EngFunc_PrecacheEvent, 1, "events/createsmoke.sc")
register_logevent("logevent_roundStart", 2, "1=Round_Start")
register_forward(FM_SetModel, "forward_SetModel")
register_forward(FM_EmitSound, "forward_EmitSound")
register_forward(FM_PlaybackEvent, "pfnPlaybackEvent", false)
RegisterHam(Ham_Item_Deploy, "weapon_smokegrenade", "ham_SmokeDeploy_Post", 1)
RegisterHam(Ham_Touch, "grenade", "ham_Touch_Post", 1)
}
public plugin_precache()
{
g_iPlayerTrailSprite = precache_model("sprites/laserbeam.spr")
g_iExplosionSprite = precache_model("sprites/shockwave.spr")
precache_model(g_szViewModel)
precache_model(g_szPlayerModel)
precache_model(g_szWorldModel)
precache_sound(g_szExplodeSound)
}
public logevent_roundStart()
{
g_bIsPluginEnabled = bool:get_pcvar_num(g_pCvarEnabled)
g_bIsImpactModeOn = bool:get_pcvar_num(g_pCvarImpactMode)
}
public pfnPlaybackEvent(Flags, id, m_usFireEvent, Float:Delay, Float:Origin[3], Float:Angles[3], Float:DirectionX, Float:DirectionY, PunchAngleX, PunchAngleY, bool:Dummy1, bool:Dummy2)
{
if(g_iSmokeEventID == m_usFireEvent)
{
return FMRES_SUPERCEDE
}
return FMRES_IGNORED
}
public ham_Touch_Post(iGrenade, iTouched)
{
if(g_bIsPluginEnabled && isSolid(iTouched) && isAvaliableGrenade(iGrenade) && g_bIsImpactModeOn)
{
explodeGrenade(iGrenade)
entity_set_float(iGrenade, EV_FL_nextthink, get_gametime() + 0.001)
entity_set_int(iGrenade, EV_INT_flags, entity_get_int(iGrenade, EV_INT_flags) | FL_ONGROUND)
}
}
public ham_SmokeDeploy_Post(iWeapon)
{
if(!g_bIsPluginEnabled)
return
static id; id = get_pdata_cbase(iWeapon, m_pPlayer, OFFSET_LINUX_WEAPONS)
if(!is_user_connected(id))
return
set_pev(id, pev_viewmodel2, g_szViewModel)
set_pev(id, pev_weaponmodel2, g_szPlayerModel)
}
public forward_SetModel(iEnt, const szModel[])
{
if(!pev_valid(iEnt) || !g_bIsPluginEnabled)
return FMRES_IGNORED
if(equal(szModel, "models/w_smokegrenade.mdl"))
{
engfunc(EngFunc_SetModel, iEnt, g_szWorldModel)
return FMRES_SUPERCEDE
}
return FMRES_IGNORED
}
public forward_EmitSound(iEnt, channel, const szSample[])
{
if(!g_bIsPluginEnabled)
return FMRES_IGNORED
if(!equal(szSample, "weapons/sg_explode.wav") || !pev_valid(iEnt))
{
return FMRES_IGNORED
}
new Float:fEntOrigin[3], Float:fPlayerOrigin[3], Float:fRadius = get_pcvar_float(g_pCvarRadius)
pev(iEnt, pev_origin, fEntOrigin)
createBlast(fEntOrigin)
emit_sound(iEnt, CHAN_ITEM, g_szExplodeSound, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
new iVictim = -1, iOwner = pev(iEnt, pev_owner)
while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, fEntOrigin, fRadius)) != 0)
{
if(!is_user_alive(iVictim)
|| (pev(iVictim, pev_takedamage) == DAMAGE_NO)
|| (pev(iVictim, pev_flags) & FL_GODMODE)
|| (!get_pcvar_num(g_pCvarSelfImpulse) && (iVictim == iOwner))
|| (!get_pcvar_num(g_pCvarFFA) && get_user_team(iOwner) == get_user_team(iVictim)))
continue
pev(iVictim, pev_origin, fPlayerOrigin)
impulsePlayer(iVictim, iEnt, iOwner, (fRadius - (get_distance_f(fEntOrigin, fPlayerOrigin) * 0.0254)))
}
set_pev(iEnt, pev_flags, pev(iEnt, pev_flags) | FL_KILLME)
return FMRES_SUPERCEDE
}
createBlast(Float:fStartOrigin[3])
{
new iColor[3]
getRgbColor(iColor, get_pcvar_num(g_pCvarExplosionColor))
message_begin_fl(MSG_PVS,SVC_TEMPENTITY, fStartOrigin, 0)
write_byte(TE_BEAMCYLINDER)
write_coord_fl(fStartOrigin[0])
write_coord_fl(fStartOrigin[1])
write_coord_fl(fStartOrigin[2])
write_coord_fl(fStartOrigin[0])
write_coord_fl(fStartOrigin[1])
write_coord_fl(fStartOrigin[2] + get_pcvar_float(g_pCvarRadius))
write_short(g_iExplosionSprite)
write_byte(0)
write_byte(0)
write_byte(4)
write_byte(50)
write_byte(0)
write_byte(iColor[0])
write_byte(iColor[1])
write_byte(iColor[2])
write_byte(100)
write_byte(0)
message_end()
}
// Code took from Weapon Physics edited by me.
impulsePlayer(iVictim, iInflictor, iAttacker, Float:fDamage)
{
static Float:fPlayerVelocity[3], Float:fPlayerOrigin[3], Float:fGrenadeOrigin[3], Float:fTemp[3]
pev(iVictim, pev_velocity, fPlayerVelocity)
pev(iVictim, pev_origin, fPlayerOrigin)
pev(iInflictor, pev_origin, fGrenadeOrigin)
xs_vec_sub(fPlayerOrigin, fGrenadeOrigin, fTemp)
xs_vec_normalize(fTemp, fTemp)
xs_vec_mul_scalar(fTemp, fDamage, fTemp)
xs_vec_mul_scalar(fTemp, get_pcvar_float(g_pCvarImpulseMultiplier), fTemp)
xs_vec_add(fPlayerVelocity, fTemp, fPlayerVelocity)
set_pev(iVictim, pev_velocity, fPlayerVelocity)
static Float:fPlayerAVelocity[3]
fPlayerAVelocity[1] = random_float(-1000.0, 1000.0)
set_pev(iVictim, pev_avelocity, fPlayerAVelocity)
new iColor[3]
getRgbColor(iColor, get_pcvar_num(g_pCvarPlayerTrailColor))
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BEAMFOLLOW)
write_short(iVictim)
write_short(g_iPlayerTrailSprite)
write_byte(4)
write_byte(3)
write_byte(iColor[0])
write_byte(iColor[1])
write_byte(iColor[2])
write_byte(100)
message_end()
new Float:fDamageTaken = (fDamage / 22.5)
if(floatround(fDamageTaken) >= get_user_health(iVictim))
{
set_msg_block(g_mMessageDeathMsg, BLOCK_ONCE)
make_deathmsg(iAttacker, iVictim, 0, "")
new bool:bIsTeamKilled = bool:(get_user_team(iAttacker) == get_user_team(iVictim))
new iCvarKillBonus = get_pcvar_num(g_pCvarKillMoney), iUserMoney = cs_get_user_money(iAttacker)
new iMoney = bIsTeamKilled ? (iUserMoney - iCvarKillBonus) : (iUserMoney + iCvarKillBonus)
cs_set_user_money(iAttacker, clamp(iMoney, 0, MAX_MONEY), 1)
if(get_pcvar_num(g_pCvarKillInfo) && (iAttacker != iVictim))
{
new szKillerName[MAX_PLAYERS], szVictimName[MAX_PLAYERS]
get_user_name(iAttacker, szKillerName, charsmax(szKillerName))
get_user_name(iVictim, szVictimName, charsmax(szVictimName))
log_to_file(LOG_FILE, "Player '%s' killed %s'%s' with the Impulse Grenade.", szKillerName, bIsTeamKilled ? "his teammate " : "", szVictimName)
ChatColor(iAttacker, "^x04[Impulse Grenade]^x01: You %s^x04 %d$^x01 by killing^x04 %s^x01 with the^x04 Impulse Grenade.", bIsTeamKilled ? "lost" : "got", iCvarKillBonus, szVictimName)
ChatColor(iVictim, "^x04[Impulse Grenade]^x01:%s^x03 %s^x01 killed you with the^x04 Impulse Grenade.", bIsTeamKilled ? " Your teammates" : "", szKillerName)
ChatColor(0, "^x04[Impulse Grenade]^x01: Player^x04 %s^x01 killed^x04 %s^x01 with the^x04 Impulse Grenade.", szKillerName, szVictimName)
}
}
ExecuteHam(Ham_TakeDamage, iVictim, iInflictor, iAttacker, fDamageTaken, DMG_BLAST)
}
getRgbColor(iColor[3], iCvar)
{
iColor[0] = (iCvar / 1000000)
iCvar %= 1000000
iColor[1] = (iCvar / 1000)
iColor[2] = (iCvar % 1000)
}
ChatColor(id, szMessage[], any:...)
{
new iPlayers[MAX_PLAYERS], iNum = 1
static szMsg[191]
vformat(szMsg, charsmax(szMsg), szMessage, 3)
replace_all(szMsg, charsmax(szMsg), "!g", "^4")
replace_all(szMsg, charsmax(szMsg), "!y", "^1")
replace_all(szMsg, charsmax(szMsg), "!t", "^3")
if(id) iPlayers[0] = id; else get_players(iPlayers, iNum, "ch")
for(new i, iPlayer; i < iNum; i++)
{
message_begin(MSG_ONE_UNRELIABLE, g_mMessageSayText, .player = (iPlayer = iPlayers[i]))
write_byte(iPlayer)
write_string(szMsg)
message_end()
}
}
bool:isSolid(iEnt)
{
return (iEnt ? ((pev(iEnt, pev_solid) > SOLID_TRIGGER) ? true : false ) : true )
}
isAvaliableGrenade(iEnt)
{
return (get_pdata_int(iEnt, g_offEvent) == g_iSmokeEventID)
}