new Float:g_nextFootstepsTime[MAX_PLAYERS + 1];
const DONT_CHECK_WEAPONS_BITSUM = (1<<CSW_KNIFE)
register_plugin(PLUGIN, VERSION, AUTHOR);
RegisterHam(Ham_Think, "grenade", "Grenade_Water");
RegisterHam(Ham_Player_PostThink, "player", "Player_Water", .Post = false, .specialbot = true);
RegisterHam(Ham_TraceAttack, "worldspawn", "TraceAttack_Water", .Post = false, .specialbot = true);
g_water_splashing = precache_model(WATER_SPLESHING);
public TraceAttack_Water(iEnt, iAttacker, Float:flDamage, Float:fDir[3], ptr, iDamageType)
if(!is_user_alive(iAttacker) || DONT_CHECK_WEAPONS_BITSUM & (1<<get_user_weapon(iAttacker)))
if(pev(iAttacker, pev_flags) & FL_INWATER)
if(~pev(iAttacker, pev_flags) & FL_ONGROUND)
if(pev(iAttacker, pev_waterlevel) > 1)
new Float:vecOrigin[3], Float:vecEnd[3]
pev(iAttacker, pev_origin, vecOrigin)
vecOrigin[2] += ((pev(iAttacker, pev_flags) & FL_DUCKING) ? 12.0 : 18.0)
get_tr2(ptr, TR_vecEndPos, vecEnd)
xs_vec_sub(vecEnd, vecOrigin, fVector)
new Float:length = vector_length(fVector)
fVector[0] = fVector[0] / length * 10
fVector[1] = fVector[1] / length * 10
fVector[2] = fVector[2] / length * 10
xs_vec_add(vecOrigin, fVector, fEndOrigin)
while(!fm_trace_line(iAttacker, vecOrigin, fEndOrigin, vecOrigin) && i < 2000)
if(waterInVicinity(vecOrigin))
TE_SPRITE_MESSAGE(vecOrigin, 15.0, 1, 255);
xs_vec_add(vecOrigin, fVector, fEndOrigin);
public Grenade_Water(iEntity)
pev(iEntity, pev_model, szBombModel, charsmax(szBombModel));
if(containi(szBombModel, "w_hegrenade") == -1)
static Float:dmgtime, Float:current_time;
pev(iEntity, pev_dmgtime, dmgtime)
current_time = get_gametime()
if(dmgtime > current_time)
pev(iEntity, pev_origin, vecOrigin)
if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_WATER)
TE_SPRITE_MESSAGE(vecOrigin, 120.0, 10, 255);
pev(id, pev_origin, start)
if(pev(id, pev_flags) & FL_INWATER)
if(g_nextFootstepsTime[id] > time)
pev(id, pev_maxspeed, maxSpeed)
pev(id, pev_velocity, velocity)
if(vector_length(velocity) < maxSpeed - 2.0)
g_nextFootstepsTime[id] = time + FOOTSTEPS_WATER_DELAY
engfunc(EngFunc_TraceLine, start, end, IGNORE_MONSTERS, id, 0)
get_tr2(0, TR_flFraction, fraction)
TE_SPRITE_MESSAGE(start, -15.0, 2, 255);
if(pev(id, pev_watertype) == CONTENTS_WATER && (pev(id, pev_flags) & FL_ONGROUND))
TE_SPRITE_MESSAGE(start, -15.0, 2, 255);
stock waterInVicinity(Float:origin[3])
new Float:traceEnds[8][3]
traceEnds[0][0] = origin[0] - 2.0
traceEnds[0][1] = origin[1] - 2.0
traceEnds[0][2] = origin[2] - 2.0
traceEnds[1][0] = origin[0] - 2.0
traceEnds[1][1] = origin[1] - 2.0
traceEnds[1][2] = origin[2] + 2.0
traceEnds[2][0] = origin[0] + 2.0
traceEnds[2][1] = origin[1] - 2.0
traceEnds[2][2] = origin[2] + 2.0
traceEnds[3][0] = origin[0] + 2.0
traceEnds[3][1] = origin[1] - 2.0
traceEnds[3][2] = origin[2] - 2.0
traceEnds[4][0] = origin[0] - 2.0
traceEnds[4][1] = origin[1] + 2.0
traceEnds[4][2] = origin[2] - 2.0
traceEnds[5][0] = origin[0] - 2.0
traceEnds[5][1] = origin[1] + 2.0
traceEnds[5][2] = origin[2] + 2.0
traceEnds[6][0] = origin[0] + 2.0
traceEnds[6][1] = origin[1] + 2.0
traceEnds[6][2] = origin[2] + 2.0
traceEnds[7][0] = origin[0] + 2.0
traceEnds[7][1] = origin[1] + 2.0
traceEnds[7][2] = origin[2] - 2.0
for (new i = 0; i < 8; i++)
if(engfunc(EngFunc_PointContents, traceEnds[i]) == CONTENTS_WATER)
TE_SPRITE_MESSAGE(Float:fCoord[3], Float:fZ = 0.0, scale = 2, brightness = 255)
message_begin(MSG_BROADCAST,SVC_TEMPENTITY);
write_coord_f(fCoord[0]);
write_coord_f(fCoord[1]);
write_coord_f(fCoord[2] += fZ);
write_short(g_water_splashing);