Imported feature from dev: 688:03dd044dcdd3 - Made scream and moan commands for zombies, with spam protection.
This commit is contained in:
		| @@ -523,6 +523,14 @@ zr_seffects_groan "5" | ||||
| // Default: "1" | ||||
| zr_seffects_death "1" | ||||
|  | ||||
| // Number of sound commands allowed within the time span, or total limit if time span is disabled. ['0' = Disable sound command limit] | ||||
| // Default: "4" | ||||
| zr_seffects_command_limit "4" | ||||
|  | ||||
| // Time span for sound command limiter (in seconds). ['0' = Disable time span check | positive number = Time span] | ||||
| // Default: "10" | ||||
| zr_seffects_command_timespan "10" | ||||
|  | ||||
| // Ambient Sounds | ||||
|  | ||||
| // Play an ambient sound to all players during gameplay. | ||||
|   | ||||
| @@ -45,6 +45,7 @@ CommandsInit() | ||||
|     ZTeleOnCommandsCreate(); | ||||
|     ZHPOnCommandsCreate(); | ||||
|     VolOnCommandsCreate(); | ||||
|     ZombieSoundsOnCommandsCreate(); | ||||
|      | ||||
|     #if defined ADD_VERSION_INFO | ||||
|         VersionOnCommandsCreate(); | ||||
|   | ||||
| @@ -132,6 +132,8 @@ enum CvarsList | ||||
|     Handle:CVAR_SEFFECTS_MOAN, | ||||
|     Handle:CVAR_SEFFECTS_GROAN, | ||||
|     Handle:CVAR_SEFFECTS_DEATH, | ||||
|     Handle:CVAR_SEFFECTS_COMMAND_LIMIT, | ||||
|     Handle:CVAR_SEFFECTS_COMMAND_TIMESPAN, | ||||
|     Handle:CVAR_AMBIENTSOUNDS, | ||||
|     Handle:CVAR_AMBIENTSOUNDS_FILE, | ||||
|     Handle:CVAR_AMBIENTSOUNDS_LENGTH, | ||||
| @@ -413,6 +415,8 @@ CvarsCreate() | ||||
|     g_hCvarsList[CVAR_SEFFECTS_MOAN]                    =    CreateConVar("zr_seffects_moan",               "30.0",                     "Time between emission of a moan sound from a zombie."); | ||||
|     g_hCvarsList[CVAR_SEFFECTS_GROAN]                   =    CreateConVar("zr_seffects_groan",              "5",                        "The probability that a groan sound will be emitted from a zombie when shot. ['100' = 1% chance | '50' = 2% chance | '1' = 100% chance]"); | ||||
|     g_hCvarsList[CVAR_SEFFECTS_DEATH]                   =    CreateConVar("zr_seffects_death",              "1",                        "Emit a death sound when a zombie dies."); | ||||
|     g_hCvarsList[CVAR_SEFFECTS_COMMAND_LIMIT]           =    CreateConVar("zr_seffects_command_limit",      "4",                        "Number of sound commands allowed within the time span, or total limit if time span is disabled. ['0' = Disable sound command limit]"); | ||||
|     g_hCvarsList[CVAR_SEFFECTS_COMMAND_TIMESPAN]        =    CreateConVar("zr_seffects_command_timespan",   "10",                       "Time span for sound command limiter (in seconds). ['0' = Disable time span check | positive number = Time span]"); | ||||
|      | ||||
|     // Ambient Sounds | ||||
|     g_hCvarsList[CVAR_AMBIENTSOUNDS]                    =    CreateConVar("zr_ambientsounds",           "1",                            "Play an ambient sound to all players during gameplay."); | ||||
|   | ||||
| @@ -749,14 +749,8 @@ InfectFireEffects(client) | ||||
|         VEffectsCreateExplosion(clientloc, flags); | ||||
|     } | ||||
|      | ||||
|     // If cvar contains path, then continue. | ||||
|     decl String:sound[PLATFORM_MAX_PATH]; | ||||
|     GetConVarString(g_hCvarsList[CVAR_INFECT_SOUND], sound, sizeof(sound)); | ||||
|     if (sound[0]) | ||||
|     { | ||||
|         // Emit infect sound from infected client. | ||||
|         SEffectsEmitSoundFromClient(client, sound, SNDLEVEL_SCREAMING); | ||||
|     } | ||||
|     // Emit scream sound if enabled. | ||||
|     ZombieSoundsScream(client); | ||||
|      | ||||
|     // If energy splash effect is enabled, then continue. | ||||
|     new bool:esplash = GetConVarBool(g_hCvarsList[CVAR_INFECT_ESPLASH]); | ||||
|   | ||||
| @@ -87,6 +87,7 @@ SEffectsOnRoundEnd() | ||||
|     // Forward event to sub-modules. | ||||
|     VoiceOnRoundEnd(); | ||||
|     AmbientSoundsOnRoundEnd(); | ||||
|     ZombieSoundsOnRoundEnd(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -70,6 +70,16 @@ enum ZombieSounds | ||||
|  */ | ||||
| new Handle:tSEffectsMoan[MAXPLAYERS + 1]; | ||||
|  | ||||
| /** | ||||
|  * Number of sound commands executed by the player. | ||||
|  */ | ||||
| new g_SEffectsCommandCount[MAXPLAYERS + 1]; | ||||
|  | ||||
| /** | ||||
|  * Timers for resetting sound command counters. | ||||
|  */ | ||||
| new Handle:g_hSEffectsCommandTimer[MAXPLAYERS + 1]; | ||||
|  | ||||
| /** | ||||
|  * Client is joining the server. | ||||
|  *  | ||||
| @@ -79,6 +89,10 @@ ZombieSoundsClientInit(client) | ||||
| { | ||||
|     // Reset timer handle. | ||||
|     tSEffectsMoan[client] = INVALID_HANDLE; | ||||
|      | ||||
|     // Reset command counter and make sure there's no timer running. | ||||
|     g_SEffectsCommandCount[client] = 0; | ||||
|     ZREndTimer(g_hSEffectsCommandTimer[client]); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -96,6 +110,10 @@ ZombieSoundsOnClientSpawn(client) | ||||
|      | ||||
|     // Reset timer handle. | ||||
|     tSEffectsMoan[client] = INVALID_HANDLE; | ||||
|      | ||||
|     // Reset command counter and kill timer. | ||||
|     g_SEffectsCommandCount[client] = 0; | ||||
|     ZREndTimer(g_hSEffectsCommandTimer[client]); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -114,6 +132,10 @@ ZombieSoundsOnClientDeath(client) | ||||
|     // Reset timer handle. | ||||
|     tSEffectsMoan[client] = INVALID_HANDLE; | ||||
|      | ||||
|     // Reset command counter and kill timer. | ||||
|     g_SEffectsCommandCount[client] = 0; | ||||
|     ZREndTimer(g_hSEffectsCommandTimer[client]); | ||||
|      | ||||
|     // If player isn't a zombie, then stop. | ||||
|     if (!InfectIsClientInfected(client)) | ||||
|     { | ||||
| @@ -189,6 +211,21 @@ ZombieSoundsOnClientInfected(client) | ||||
|     tSEffectsMoan[client] = CreateTimer(interval, ZombieSoundsMoanTimer, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Round ended. | ||||
|  */ | ||||
| ZombieSoundsOnRoundEnd() | ||||
| { | ||||
|     ZombieSoundsResetCmdCounters(); | ||||
|     ZombieSoundsResetCmdTimers(); | ||||
| } | ||||
|  | ||||
| ZombieSoundsOnCommandsCreate() | ||||
| { | ||||
|     RegConsoleCmd("scream", ZombieSoundsScreamCommand, "Emits a scream sound, if the player is a zombie."); | ||||
|     RegConsoleCmd("moan", ZombieSoundsMoanCommand, "Emits a moan sound, if the player is a zombie."); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Gets a random zombie sound from hl2 folder. | ||||
|  * | ||||
| @@ -270,13 +307,147 @@ public Action:ZombieSoundsMoanTimer(Handle:timer, any:client) | ||||
|         return Plugin_Stop; | ||||
|     } | ||||
|      | ||||
|     // Emit moan sound. | ||||
|     ZombieSoundsMoan(client); | ||||
|      | ||||
|     // Allow timer to continue. | ||||
|     return Plugin_Continue; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Emits a moan sound from the specified client. | ||||
|  * | ||||
|  * @param client    Client index. | ||||
|  */ | ||||
| ZombieSoundsMoan(client) | ||||
| { | ||||
|     // Get random moan sound. | ||||
|     decl String:sound[SOUND_MAX_PATH]; | ||||
|     ZombieSoundsGetRandomSound(sound, Moan); | ||||
|      | ||||
|     // Emit sound from client. | ||||
|     SEffectsEmitSoundFromClient(client, sound, SNDLEVEL_SCREAMING); | ||||
|      | ||||
|     // Allow timer to continue. | ||||
|     return Plugin_Continue; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Emits the scream sound (on infection) from the specified client. | ||||
|  * | ||||
|  * @param client    Client index. | ||||
|  */ | ||||
| ZombieSoundsScream(client) | ||||
| { | ||||
|     decl String:sound[PLATFORM_MAX_PATH]; | ||||
|     GetConVarString(g_hCvarsList[CVAR_INFECT_SOUND], sound, sizeof(sound)); | ||||
|      | ||||
|     // If cvar contains path, then continue. | ||||
|     if (sound[0]) | ||||
|     { | ||||
|         // Emit infect sound from infected client. | ||||
|         SEffectsEmitSoundFromClient(client, sound, SNDLEVEL_SCREAMING); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Starts a reset timer for the client's command counter if not already started. | ||||
|  * | ||||
|  * @param client    Client index. | ||||
|  */ | ||||
| ZombieSoundsCmdTimerCheck(client) | ||||
| { | ||||
|     // Only create timer if it doesn't exist. | ||||
|     if (g_hSEffectsCommandTimer[client] == INVALID_HANDLE) | ||||
|     { | ||||
|         new Float:timespan = GetConVarFloat(g_hCvarsList[CVAR_SEFFECTS_COMMAND_TIMESPAN]); | ||||
|          | ||||
|         // Only create timer if time span is enabled. | ||||
|         if (timespan > 0.0) | ||||
|         { | ||||
|             g_hSEffectsCommandTimer[client] = CreateTimer(timespan, ZombieSoundsCmdTimer, client, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Resets all command counters. | ||||
|  */ | ||||
| ZombieSoundsResetCmdCounters() | ||||
| { | ||||
|     for (new client = 0; client <= MAXPLAYERS; client++) | ||||
|     { | ||||
|         g_SEffectsCommandCount[client] = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Stops all command counter timers. | ||||
|  */ | ||||
| ZombieSoundsResetCmdTimers() | ||||
| { | ||||
|     for (new client = 0; client <= MAXPLAYERS; client++) | ||||
|     { | ||||
|         ZREndTimer(g_hSEffectsCommandTimer[client]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns whether a player is allowed to play a zombie sound or not. | ||||
|  * | ||||
|  * @param client    Client index. | ||||
|  * @return          True if allowed, false otherwise. | ||||
|  */ | ||||
| bool:ZombieSoundsCommandAllowed(client) | ||||
| { | ||||
|     new limit = GetConVarInt(g_hCvarsList[CVAR_SEFFECTS_COMMAND_LIMIT]); | ||||
|      | ||||
|     if (limit <= 0 || | ||||
|         g_SEffectsCommandCount[client] < limit) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
|      | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Scream command handler. | ||||
|  */ | ||||
| public Action:ZombieSoundsScreamCommand(client, argc) | ||||
| { | ||||
|     if (IsClientInGame(client) && | ||||
|         IsPlayerAlive(client) && | ||||
|         InfectIsClientInfected(client) && | ||||
|         ZombieSoundsCommandAllowed(client)) | ||||
|     { | ||||
|         ZombieSoundsScream(client); | ||||
|         g_SEffectsCommandCount[client]++; | ||||
|         ZombieSoundsCmdTimerCheck(client); | ||||
|     } | ||||
|      | ||||
|     return Plugin_Handled; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Moan command handler. | ||||
|  */ | ||||
| public Action:ZombieSoundsMoanCommand(client, argc) | ||||
| { | ||||
|     if (IsClientInGame(client) && | ||||
|         IsPlayerAlive(client) && | ||||
|         InfectIsClientInfected(client) && | ||||
|         ZombieSoundsCommandAllowed(client)) | ||||
|     { | ||||
|         ZombieSoundsMoan(client); | ||||
|         g_SEffectsCommandCount[client]++; | ||||
|         ZombieSoundsCmdTimerCheck(client); | ||||
|     } | ||||
|      | ||||
|     return Plugin_Handled; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Command counter reset timer. | ||||
|  */ | ||||
| public Action:ZombieSoundsCmdTimer(Handle:timer, any:client) | ||||
| { | ||||
|     g_SEffectsCommandCount[client] = 0; | ||||
| } | ||||
|   | ||||
| @@ -106,6 +106,50 @@ stock ZRCreateEligibleClientList(&Handle:arrayEligibleClients, bool:team = false | ||||
|     return GetArraySize(arrayEligibleClients); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks if a timer is currently running. | ||||
|  *  | ||||
|  * @param timer     The timer handle. | ||||
|  */ | ||||
| stock bool:ZRIsTimerRunning(Handle:timer) | ||||
| { | ||||
|     // Return true if the handle isn't empty. | ||||
|     return (timer != INVALID_HANDLE); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Wrapper functions for KilLTimer. | ||||
|  * Ends a timer if running, and resets its timer handle variable. | ||||
|  *  | ||||
|  * @param timer     The timer handle. | ||||
|  * @param kill      True to kill the timer and reset the variable, false to only reset the variable. | ||||
|  *                  Using false is useful when calling from the timer callback, because the timer is already killed. | ||||
|  *  | ||||
|  * @return          True if the handle wasn't INVALID_HANDLE, false if the handle wasn't valid. | ||||
|  */ | ||||
| stock bool:ZREndTimer(&Handle:timer, bool:kill = true) | ||||
| { | ||||
|     // If the timer is running, then kill it. | ||||
|     if (ZRIsTimerRunning(timer)) | ||||
|     { | ||||
|         // Kill if caller says to. | ||||
|         if (kill) | ||||
|         { | ||||
|             KillTimer(timer); | ||||
|         } | ||||
|          | ||||
|         // Reset variable. | ||||
|         timer = INVALID_HANDLE; | ||||
|          | ||||
|         return true; | ||||
|     } | ||||
|      | ||||
|     // Reset variable. | ||||
|     timer = INVALID_HANDLE; | ||||
|      | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Check if a client index is a valid player. | ||||
|  *  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user