Added neato features to SprayManager because why not
Fix ooooooooooold bug in SprayManager
Fix horrific mistake in ExtraCommands
This commit is contained in:
Obuss 2016-12-02 05:55:09 -06:00
parent 4037006f98
commit 638f816605
2 changed files with 234 additions and 68 deletions

View File

@ -28,7 +28,7 @@ public Plugin myinfo =
name = "Advanced Commands", name = "Advanced Commands",
author = "BotoX + Obus", author = "BotoX + Obus",
description = "Adds extra commands for admins.", description = "Adds extra commands for admins.",
version = "1.9", version = "2.0.0",
url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/ExtraCommands/" url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/ExtraCommands/"
}; };
@ -68,7 +68,11 @@ public void OnPluginStart()
AutoExecConfig(true, "plugin.extracommands"); AutoExecConfig(true, "plugin.extracommands");
if(g_CVar_sv_pausable) if(g_CVar_sv_pausable)
{
AddCommandListener(Listener_Pause, "pause"); AddCommandListener(Listener_Pause, "pause");
AddCommandListener(Listener_Pause, "setpause"); //doesn't work on win32 srcds?
AddCommandListener(Listener_Pause, "unpause"); //doesn't work on win32 srcds?
}
} }
public void OnMapStart() public void OnMapStart()
@ -101,7 +105,7 @@ public Action Listener_Pause(int client, const char[] command, int argc)
if(!g_CVar_sv_pausable.BoolValue) if(!g_CVar_sv_pausable.BoolValue)
{ {
ReplyToCommand(client, "sv_pausable is set to 0!"); ReplyToCommand(client, "[SM] \"sv_pausable\" is set to 0!");
return Plugin_Handled; return Plugin_Handled;
} }
@ -113,13 +117,19 @@ public Action Listener_Pause(int client, const char[] command, int argc)
if(!IsClientAuthorized(client) || !GetAdminFlag(GetUserAdmin(client), Admin_Generic)) if(!IsClientAuthorized(client) || !GetAdminFlag(GetUserAdmin(client), Admin_Generic))
{ {
ReplyToCommand(client, "You do not have permission to pause the game."); ReplyToCommand(client, "[SM] You do not have permission to pause/unpause the game.");
return Plugin_Handled; return Plugin_Handled;
} }
ShowActivity2(client, "\x01[SM] \x04", "%s\x01 the game.", bPaused ? "Unpaused" : "Paused"); if(strcmp(command, "setpause") == 0)
LogAction(client, -1, "\"%L\" %s the game.", client, bPaused ? "unpaused" : "paused"); bPaused = true;
bPaused = !bPaused; else if(strcmp(command, "unpause") == 0)
bPaused = false;
else
bPaused = !bPaused;
ShowActivity2(client, "\x01[SM] \x04", "%s\x01 the game.", bPaused ? "Paused" : "Unpaused");
LogAction(client, -1, "\"%L\" %s the game.", client, bPaused ? "Paused" : "Unpaused");
return Plugin_Continue; return Plugin_Continue;
} }
@ -460,8 +470,11 @@ public Action Command_Strip(int client, int argc)
while ((w = GetPlayerWeaponSlot(target_list[i], j)) != -1) while ((w = GetPlayerWeaponSlot(target_list[i], j)) != -1)
{ {
if(IsValidEntity(w)) if(IsValidEntity(w) && IsValidEdict(w))
{
RemovePlayerItem(target_list[i], w); RemovePlayerItem(target_list[i], w);
AcceptEntityInput(w, "Kill");
}
} }
} }
} }

View File

@ -23,11 +23,16 @@ enum
Handle g_hDatabase = null; Handle g_hDatabase = null;
Handle g_hTraceTimer = null; Handle g_hTraceTimer = null;
Handle g_hRoundEndTimer = null;
Handle g_hTopMenu = null; Handle g_hTopMenu = null;
ConVar g_cvarHookedDecalFrequency = null; ConVar g_cvarHookedDecalFrequency = null;
ConVar g_cvarDecalFrequency = null; ConVar g_cvarDecalFrequency = null;
ConVar g_cvarUseProximityCheck = null; ConVar g_cvarUseProximityCheck = null;
ConVar g_cvarSendSpraysToConnectingClients = null;
ConVar g_cvarUsePersistentSprays = null;
ConVar g_cvarMaxSprayLifetime = null;
int g_iOldDecalFreqVal;
int g_iAllowSpray; int g_iAllowSpray;
bool g_bLoadedLate; bool g_bLoadedLate;
@ -35,6 +40,7 @@ bool g_bSQLite;
bool g_bGotBans; bool g_bGotBans;
bool g_bGotBlacklist; bool g_bGotBlacklist;
bool g_bFullyConnected; bool g_bFullyConnected;
bool g_bSkipDecalHook;
char g_sBanIssuer[MAXPLAYERS + 1][64]; char g_sBanIssuer[MAXPLAYERS + 1][64];
char g_sBanIssuerSID[MAXPLAYERS + 1][32]; char g_sBanIssuerSID[MAXPLAYERS + 1][32];
@ -46,6 +52,8 @@ bool g_bSprayHashBanned[MAXPLAYERS + 1];
bool g_bInvokedThroughTopMenu[MAXPLAYERS + 1]; bool g_bInvokedThroughTopMenu[MAXPLAYERS + 1];
bool g_bInvokedThroughListMenu[MAXPLAYERS + 1]; bool g_bInvokedThroughListMenu[MAXPLAYERS + 1];
int g_iClientToClientSprayLifetime[MAXPLAYERS + 1][MAXPLAYERS + 1];
int g_iClientSprayLifetime[MAXPLAYERS + 1] = { 2, ... };
int g_iSprayLifetime[MAXPLAYERS + 1]; int g_iSprayLifetime[MAXPLAYERS + 1];
int g_iSprayBanTimestamp[MAXPLAYERS + 1]; int g_iSprayBanTimestamp[MAXPLAYERS + 1];
int g_iSprayUnbanTimestamp[MAXPLAYERS + 1] = { -1, ... }; int g_iSprayUnbanTimestamp[MAXPLAYERS + 1] = { -1, ... };
@ -65,7 +73,7 @@ public Plugin myinfo =
name = "Spray Manager", name = "Spray Manager",
description = "A plugin to help manage player sprays.", description = "A plugin to help manage player sprays.",
author = "Obus", author = "Obus",
version = "1.2.7", version = "2.0.0",
url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/SprayManager" url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/SprayManager"
} }
@ -100,32 +108,38 @@ public void OnPluginStart()
if (LibraryExists("adminmenu") && ((hTopMenu = GetAdminTopMenu()) != null)) if (LibraryExists("adminmenu") && ((hTopMenu = GetAdminTopMenu()) != null))
OnAdminMenuReady(hTopMenu); OnAdminMenuReady(hTopMenu);
if (g_cvarHookedDecalFrequency != null)
delete g_cvarHookedDecalFrequency;
if (g_cvarDecalFrequency != null)
delete g_cvarDecalFrequency;
if (g_cvarUseProximityCheck != null)
delete g_cvarUseProximityCheck;
g_cvarHookedDecalFrequency = FindConVar("decalfrequency"); g_cvarHookedDecalFrequency = FindConVar("decalfrequency");
g_iOldDecalFreqVal = g_cvarHookedDecalFrequency.IntValue;
g_cvarHookedDecalFrequency.IntValue = 0; g_cvarHookedDecalFrequency.IntValue = 0;
g_cvarDecalFrequency = CreateConVar("sm_decalfrequency", "10", "Controls how often clients can spray", FCVAR_NOTIFY); g_cvarDecalFrequency = CreateConVar("sm_decalfrequency", "10.0", "Controls how often clients can spray", FCVAR_NOTIFY);
HookConVarChange(g_cvarHookedDecalFrequency, CVarHook_DecalFrequency); HookConVarChange(g_cvarHookedDecalFrequency, ConVarChanged_DecalFrequency);
g_cvarUseProximityCheck = CreateConVar("sm_spraymanager_blockoverspraying", "1", "Allows or disallows people to overspray other people.", FCVAR_NOTIFY); g_cvarUseProximityCheck = CreateConVar("sm_spraymanager_blockoverspraying", "1", "Blocks people from overspraying each other", FCVAR_NOTIFY);
g_cvarSendSpraysToConnectingClients = CreateConVar("sm_spraymanager_sendspraystoconnectingclients", "1", "Try to send active sprays to connecting clients");
g_cvarUsePersistentSprays = CreateConVar("sm_spraymanager_persistentsprays", "1", "Re-spray sprays when their client-sided lifetime (in rounds) expires");
g_cvarMaxSprayLifetime = CreateConVar("sm_spraymanager_maxspraylifetime", "2", "If not using persistent sprays, remove sprays after their global lifetime (in rounds) exceeds this number");
AutoExecConfig(true, "plugin.spraymanager"); AutoExecConfig(true, "plugin.spraymanager");
if (g_hDatabase != null) g_hTraceTimer = CreateTimer(0.25, Timer_PerformPlayerTraces, _, TIMER_REPEAT);
delete g_hDatabase;
g_hTraceTimer = CreateTimer(0.25, PerformPlayerTraces, _, TIMER_REPEAT);
InitializeSQL(); InitializeSQL();
if (g_bLoadedLate)
{
for (int i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i))
continue;
OnClientPutInServer(i);
}
}
} }
public void OnPluginEnd() public void OnPluginEnd()
@ -135,11 +149,11 @@ public void OnPluginEnd()
if (!IsValidClient(i) || IsFakeClient(i)) if (!IsValidClient(i) || IsFakeClient(i))
continue; continue;
if (g_vecSprayOrigin[i][0] == 0.0) if (IsVectorZero(g_vecSprayOrigin[i]))
continue; continue;
g_iAllowSpray = i; g_iAllowSpray = i;
SprayClientDecal(i, 0, ACTUAL_NULL_VECTOR); SprayClientDecalToAll(i, 0, ACTUAL_NULL_VECTOR);
} }
RemoveTempEntHook("Player Decal", HookDecal); RemoveTempEntHook("Player Decal", HookDecal);
@ -152,7 +166,56 @@ public void OnPluginEnd()
} }
if (g_hTraceTimer != null) if (g_hTraceTimer != null)
KillTimer(g_hTraceTimer); delete g_hTraceTimer;
if (g_hRoundEndTimer != null)
delete g_hRoundEndTimer;
g_cvarHookedDecalFrequency.IntValue = g_iOldDecalFreqVal;
}
public void OnMapEnd()
{
if (g_hRoundEndTimer != null)
delete g_hRoundEndTimer;
}
public void OnClientPutInServer(int client)
{
if (QueryClientConVar(client, "r_spray_lifetime", CvarQueryFinished_SprayLifeTime) == QUERYCOOKIE_FAILED)
g_iClientSprayLifetime[client] = 2;
if (g_cvarSendSpraysToConnectingClients.BoolValue)
{
for (int i = 1; i <= MaxClients; i++)
{
if (!IsValidClient(i) || IsFakeClient(i))
continue;
if (IsVectorZero(g_vecSprayOrigin[i]))
continue;
g_bSkipDecalHook = true;
SprayClientDecalToOne(i, client, g_iDecalEntity[i], g_vecSprayOrigin[i]);
g_iClientToClientSprayLifetime[client][i] = 0;
g_bSkipDecalHook = false;
}
}
}
public void CvarQueryFinished_SprayLifeTime(QueryCookie cookie, int client, ConVarQueryResult res, const char[] sCvarName, const char[] sCvarVal)
{
if (res != ConVarQuery_Okay)
{
g_iClientSprayLifetime[client] = 2;
return;
}
int iVal = StringToInt(sCvarVal);
iVal = iVal <= 0 ? 1 : iVal > 1000 ? 1000 : iVal;
g_iClientSprayLifetime[client] = iVal;
} }
public void OnClientPostAdminCheck(int client) public void OnClientPostAdminCheck(int client)
@ -167,28 +230,27 @@ public void OnClientPostAdminCheck(int client)
public void OnClientDisconnect(int client) public void OnClientDisconnect(int client)
{ {
g_iAllowSpray = client; if (IsValidClient(client))
SprayClientDecal(client, 0, ACTUAL_NULL_VECTOR); {
g_iAllowSpray = client;
SprayClientDecalToAll(client, 0, ACTUAL_NULL_VECTOR);
}
ClearPlayerInfo(client); ClearPlayerInfo(client);
} }
public Action CS_OnTerminateRound(float &fDelay, CSRoundEndReason &reason) public Action CS_OnTerminateRound(float &fDelay, CSRoundEndReason &reason)
{ {
for (int i = 1; i <= MaxClients; i++) if (g_cvarUsePersistentSprays.BoolValue)
{ {
if (!IsValidClient(i) || IsFakeClient(i)) g_hRoundEndTimer = CreateTimer(fDelay, Timer_ProcessPersistentSprays);
continue;
if (!IsVectorZero(g_vecSprayOrigin[i])) return Plugin_Continue;
g_iSprayLifetime[i]++;
if (g_iSprayLifetime[i] >= 2)
{
g_iAllowSpray = i;
SprayClientDecal(i, 0, ACTUAL_NULL_VECTOR);
g_iSprayLifetime[i] = 0;
}
} }
g_hRoundEndTimer = CreateTimer(fDelay, Timer_ResetOldSprays);
return Plugin_Continue;
} }
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse) public Action OnPlayerRunCmd(int client, int &buttons, int &impulse)
@ -209,7 +271,9 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse)
} }
} }
return Plugin_Continue; impulse = 0; //wow
return Plugin_Changed;
} }
public void OnAdminMenuReady(Handle hAdminMenu) public void OnAdminMenuReady(Handle hAdminMenu)
@ -234,7 +298,7 @@ public void OnAdminMenuReady(Handle hAdminMenu)
public void OnLibraryRemoved(const char[] sLibraryName) public void OnLibraryRemoved(const char[] sLibraryName)
{ {
if (StrEqual(sLibraryName, "adminmenu")) if (strcmp(sLibraryName, "adminmenu") == 0)
delete g_hTopMenu; delete g_hTopMenu;
} }
@ -1511,7 +1575,7 @@ public Action Command_RemoveSpray(int client, int argc)
for (int i = 0; i < iTargetCount; i++) for (int i = 0; i < iTargetCount; i++)
{ {
g_iAllowSpray = iTargets[i]; g_iAllowSpray = iTargets[i];
SprayClientDecal(iTargets[i], 0, ACTUAL_NULL_VECTOR); SprayClientDecalToAll(iTargets[i], 0, ACTUAL_NULL_VECTOR);
} }
PrintToChat(client, "\x01\x04[SprayManager]\x01 Removed \x04%s\x01's spray(s).", sTargetName); PrintToChat(client, "\x01\x04[SprayManager]\x01 Removed \x04%s\x01's spray(s).", sTargetName);
@ -1529,7 +1593,7 @@ public Action Command_RemoveSpray(int client, int argc)
continue; continue;
g_iAllowSpray = i; g_iAllowSpray = i;
SprayClientDecal(i, 0, ACTUAL_NULL_VECTOR); SprayClientDecalToAll(i, 0, ACTUAL_NULL_VECTOR);
PrintToChat(client, "\x01\x04[SprayManager]\x01 Removed \x04%N\x01's spray.", i); PrintToChat(client, "\x01\x04[SprayManager]\x01 Removed \x04%N\x01's spray.", i);
@ -1549,6 +1613,7 @@ public Action Command_SprayManager_UpdateInfo(int client, int argc)
if (!IsValidClient(i) || IsFakeClient(i)) if (!IsValidClient(i) || IsFakeClient(i))
continue; continue;
ClearPlayerInfo(i);
UpdatePlayerInfo(i); UpdatePlayerInfo(i);
UpdateSprayHashInfo(i); UpdateSprayHashInfo(i);
} }
@ -1558,6 +1623,9 @@ public Action Command_SprayManager_UpdateInfo(int client, int argc)
public Action HookDecal(const char[] sTEName, const int[] iClients, int iNumClients, float fSendDelay) public Action HookDecal(const char[] sTEName, const int[] iClients, int iNumClients, float fSendDelay)
{ {
if (g_bSkipDecalHook)
return Plugin_Continue;
int client = TE_ReadNum("m_nPlayer"); int client = TE_ReadNum("m_nPlayer");
if (!IsValidClient(client)) if (!IsValidClient(client))
@ -1613,7 +1681,7 @@ public Action HookDecal(const char[] sTEName, const int[] iClients, int iNumClie
if (!CheckCommandAccess(client, "sm_sprayban", ADMFLAG_GENERIC)) if (!CheckCommandAccess(client, "sm_sprayban", ADMFLAG_GENERIC))
{ {
if (g_cvarUseProximityCheck.IntValue >= 1) if (g_cvarUseProximityCheck.BoolValue)
{ {
for (int i = 1; i <= MaxClients; i++) for (int i = 1; i <= MaxClients; i++)
{ {
@ -1646,6 +1714,8 @@ public Action HookDecal(const char[] sTEName, const int[] iClients, int iNumClie
g_iSprayLifetime[client] = 0; g_iSprayLifetime[client] = 0;
UpdateClientToClientSprayLifeTime(client, 0);
g_vecSprayOrigin[client] = vecOrigin; g_vecSprayOrigin[client] = vecOrigin;
g_SprayAABB[client] = AABBTemp; g_SprayAABB[client] = AABBTemp;
@ -1671,13 +1741,13 @@ public void FrameAfterSpray(ArrayList Data)
public Action HookSprayer(int iClients[MAXPLAYERS], int &iNumClients, char sSoundName[PLATFORM_MAX_PATH], int &iEntity, int &iChannel, float &flVolume, int &iLevel, int &iPitch, int &iFlags, char sSoundEntry[PLATFORM_MAX_PATH], int &seed) public Action HookSprayer(int iClients[MAXPLAYERS], int &iNumClients, char sSoundName[PLATFORM_MAX_PATH], int &iEntity, int &iChannel, float &flVolume, int &iLevel, int &iPitch, int &iFlags, char sSoundEntry[PLATFORM_MAX_PATH], int &seed)
{ {
if (StrEqual(sSoundName, "player/sprayer.wav") && iEntity > 0) if (strcmp(sSoundName, "player/sprayer.wav") == 0 && iEntity > 0)
return Plugin_Handled; return Plugin_Handled;
return Plugin_Continue; return Plugin_Continue;
} }
public Action PerformPlayerTraces(Handle hTimer) public Action Timer_PerformPlayerTraces(Handle hTimer)
{ {
static bool bLookingatSpray[MAXPLAYERS + 1]; static bool bLookingatSpray[MAXPLAYERS + 1];
static bool bOnce[MAXPLAYERS + 1]; static bool bOnce[MAXPLAYERS + 1];
@ -1691,17 +1761,17 @@ public Action PerformPlayerTraces(Handle hTimer)
if (!TracePlayerAngles(i, vecPos)) if (!TracePlayerAngles(i, vecPos))
continue; continue;
for (int a = 1; a <= MaxClients; a++) for (int x = 1; x <= MaxClients; x++)
{ {
if (!IsValidClient(a)) if (!IsValidClient(x))
continue; continue;
if (IsPointInsideAABB(vecPos, g_SprayAABB[a])) if (IsPointInsideAABB(vecPos, g_SprayAABB[x]))
{ {
char sSteamID[32]; char sSteamID[32];
GetClientAuthId(a, AuthId_Steam2, sSteamID, sizeof(sSteamID)); GetClientAuthId(x, AuthId_Steam2, sSteamID, sizeof(sSteamID));
PrintHintText(i, "Sprayed by: %N (%s)", a, sSteamID); PrintHintText(i, "Sprayed by: %N (%s)", x, sSteamID);
StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); StopSound(i, SNDCHAN_STATIC, "UI/hint.wav");
bLookingatSpray[i] = true; bLookingatSpray[i] = true;
@ -1714,21 +1784,70 @@ public Action PerformPlayerTraces(Handle hTimer)
} }
} }
for (int x = 1; x <= MaxClients; x++) for (int i = 1; i <= MaxClients; i++)
{ {
if (!IsValidClient(x) || IsFakeClient(x)) if (!IsValidClient(i) || IsFakeClient(i))
continue; continue;
if (!bLookingatSpray[x] && !bOnce[x]) if (!bLookingatSpray[i] && !bOnce[i])
{ {
PrintHintText(x, ""); PrintHintText(i, "");
StopSound(x, SNDCHAN_STATIC, "UI/hint.wav"); StopSound(i, SNDCHAN_STATIC, "UI/hint.wav");
bOnce[x] = true; bOnce[i] = true;
} }
} }
} }
public Action Timer_ProcessPersistentSprays(Handle hThis)
{
for (int i = 1; i <= MaxClients; i++)
{
if (!IsValidClient(i) || IsFakeClient(i))
continue;
for (int x = 1; x <= MaxClients; x++)
{
if (!IsValidClient(x) || IsFakeClient(x))
continue;
if (!IsVectorZero(g_vecSprayOrigin[i]))
g_iClientToClientSprayLifetime[x][i]++;
if (g_iClientToClientSprayLifetime[x][i] >= g_iClientSprayLifetime[x])
{
g_bSkipDecalHook = true;
SprayClientDecalToOne(i, x, g_iDecalEntity[i], g_vecSprayOrigin[i]);
g_iClientToClientSprayLifetime[x][i] = 0;
g_bSkipDecalHook = false;
}
}
}
g_hRoundEndTimer = null;
}
public Action Timer_ResetOldSprays(Handle hThis)
{
for (int i = 1; i <= MaxClients; i++)
{
if (!IsValidClient(i) || IsFakeClient(i))
continue;
if (!IsVectorZero(g_vecSprayOrigin[i]))
g_iSprayLifetime[i]++;
if (g_iSprayLifetime[i] >= g_cvarMaxSprayLifetime.IntValue)
{
g_iAllowSpray = i;
SprayClientDecalToAll(i, 0, ACTUAL_NULL_VECTOR);
g_iSprayLifetime[i] = 0;
}
}
g_hRoundEndTimer = null;
}
void InitializeSQL() void InitializeSQL()
{ {
if (g_hDatabase != null) if (g_hDatabase != null)
@ -1901,7 +2020,7 @@ public Action RetryUpdatingPlayerInfo(Handle hTimer)
} }
} }
public void CVarHook_DecalFrequency(ConVar cvar, const char[] sOldValue, const char[] sNewValue) public void ConVarChanged_DecalFrequency(ConVar cvar, const char[] sOldValue, const char[] sNewValue)
{ {
if (cvar == g_cvarHookedDecalFrequency) if (cvar == g_cvarHookedDecalFrequency)
{ {
@ -1970,7 +2089,7 @@ bool SprayBanClient(int client, int target, int iBanLength, const char[] sReason
g_fNextSprayTime[target] = 0.0; g_fNextSprayTime[target] = 0.0;
g_iAllowSpray = target; g_iAllowSpray = target;
SprayClientDecal(target, 0, ACTUAL_NULL_VECTOR); SprayClientDecalToAll(target, 0, ACTUAL_NULL_VECTOR);
return true; return true;
} }
@ -2014,6 +2133,7 @@ bool SprayUnbanClient(int target, int client=-1)
strcopy(g_sBanReason[target], sizeof(g_sBanReason[]), ""); strcopy(g_sBanReason[target], sizeof(g_sBanReason[]), "");
g_bSprayBanned[target] = false; g_bSprayBanned[target] = false;
g_iSprayLifetime[target] = 0; g_iSprayLifetime[target] = 0;
UpdateClientToClientSprayLifeTime(target, 0);
g_iSprayBanTimestamp[target] = 0; g_iSprayBanTimestamp[target] = 0;
g_iSprayUnbanTimestamp[target] = -1; g_iSprayUnbanTimestamp[target] = -1;
g_fNextSprayTime[target] = 0.0; g_fNextSprayTime[target] = 0.0;
@ -2059,7 +2179,7 @@ bool BanClientSpray(int client, int target)
g_bSprayHashBanned[target] = true; g_bSprayHashBanned[target] = true;
g_iAllowSpray = target; g_iAllowSpray = target;
SprayClientDecal(target, 0, ACTUAL_NULL_VECTOR); SprayClientDecalToAll(target, 0, ACTUAL_NULL_VECTOR);
return true; return true;
} }
@ -2204,7 +2324,7 @@ bool ForceSpray(int client, int target, bool bPlaySound=true)
if (TracePlayerAngles(client, vecEndPos)) if (TracePlayerAngles(client, vecEndPos))
{ {
SprayClientDecal(target, g_iDecalEntity[client], vecEndPos); SprayClientDecalToAll(target, g_iDecalEntity[client], vecEndPos);
if (bPlaySound) if (bPlaySound)
EmitSoundToAll("player/sprayer.wav", SOUND_FROM_WORLD, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, _, _, _, vecEndPos); EmitSoundToAll("player/sprayer.wav", SOUND_FROM_WORLD, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, _, _, _, vecEndPos);
@ -2217,7 +2337,7 @@ bool ForceSpray(int client, int target, bool bPlaySound=true)
return false; return false;
} }
bool SprayClientDecal(int client, int iEntity, float vecOrigin[3]) bool SprayClientDecalToAll(int client, int iEntity, float vecOrigin[3])
{ {
if (!IsValidClient(client)) if (!IsValidClient(client))
return false; return false;
@ -2231,6 +2351,20 @@ bool SprayClientDecal(int client, int iEntity, float vecOrigin[3])
return true; return true;
} }
bool SprayClientDecalToOne(int client, int target, int iEntity, float vecOrigin[3])
{
if (!IsValidClient(client))
return false;
TE_Start("Player Decal");
TE_WriteVector("m_vecOrigin", vecOrigin);
TE_WriteNum("m_nEntity", iEntity);
TE_WriteNum("m_nPlayer", client);
TE_SendToClient(target);
return true;
}
bool TracePlayerAngles(int client, float vecResult[3]) bool TracePlayerAngles(int client, float vecResult[3])
{ {
if (!IsValidClient(client)) if (!IsValidClient(client))
@ -2307,13 +2441,32 @@ void ClearPlayerInfo(int client)
strcopy(g_sSprayHash[client], sizeof(g_sSprayHash[]), ""); strcopy(g_sSprayHash[client], sizeof(g_sSprayHash[]), "");
g_bSprayBanned[client] = false; g_bSprayBanned[client] = false;
g_bSprayHashBanned[client] = false; g_bSprayHashBanned[client] = false;
g_iClientSprayLifetime[client] = 2;
g_iSprayLifetime[client] = 0; g_iSprayLifetime[client] = 0;
ResetClientToClientSprayLifeTime(client);
g_iSprayBanTimestamp[client] = 0; g_iSprayBanTimestamp[client] = 0;
g_iSprayUnbanTimestamp[client] = -1; g_iSprayUnbanTimestamp[client] = -1;
g_fNextSprayTime[client] = 0.0; g_fNextSprayTime[client] = 0.0;
g_vecSprayOrigin[client] = ACTUAL_NULL_VECTOR; g_vecSprayOrigin[client] = ACTUAL_NULL_VECTOR;
} }
void UpdateClientToClientSprayLifeTime(int client, int iLifeTime)
{
for (int i = 1; i <= MaxClients; i++)
{
g_iClientToClientSprayLifetime[i][client] = iLifeTime;
}
}
void ResetClientToClientSprayLifeTime(int client)
{
for (int i = 1; i <= MaxClients; i++)
{
g_iClientToClientSprayLifetime[i][client] = 0;
g_iClientToClientSprayLifetime[client][i] = 0;
}
}
void FormatRemainingTime(int iTimestamp, char[] sBuffer, int iBuffSize) void FormatRemainingTime(int iTimestamp, char[] sBuffer, int iBuffSize)
{ {
if (!iTimestamp) if (!iTimestamp)
@ -2373,12 +2526,12 @@ bool CheckForAABBCollision(float AABB1[6], float AABB2[6])
return true; return true;
} }
stock bool IsVectorZero(float vecPos[3]) bool IsVectorZero(float vecPos[3])
{ {
return ((vecPos[0] == 0.0) && (vecPos[1] == 0.0) && (vecPos[2] == 0.0)); return ((vecPos[0] == 0.0) && (vecPos[1] == 0.0) && (vecPos[2] == 0.0));
} }
stock bool SingularOrMultiple(int num) bool SingularOrMultiple(int num)
{ {
if (!num || num > 1) if (!num || num > 1)
return true; return true;
@ -2386,12 +2539,12 @@ stock bool SingularOrMultiple(int num)
return false; return false;
} }
stock bool TraceEntityFilter_FilterPlayers(int entity, int contentsMask) bool TraceEntityFilter_FilterPlayers(int entity, int contentsMask)
{ {
return entity > MaxClients; return entity > MaxClients;
} }
stock bool IsValidClient(int client) bool IsValidClient(int client)
{ {
if (client <= 0 || client > MaxClients || !IsClientInGame(client)) if (client <= 0 || client > MaxClients || !IsClientInGame(client))
return false; return false;