From a7e8cd67f8a32298c83ccb64aec59369394b6eab Mon Sep 17 00:00:00 2001 From: Jackz Date: Fri, 18 Jun 2021 23:46:57 -0500 Subject: [PATCH] Add l4d2_vocalize_control --- README.md | 9 ++- plugins/l4d2_vocalize_control.smx | Bin 0 -> 4893 bytes scripting/l4d2_vocalize_control.sp | 112 +++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 plugins/l4d2_vocalize_control.smx create mode 100644 scripting/l4d2_vocalize_control.sp diff --git a/README.md b/README.md index 73d744e..a2fedd7 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Useful things: * [l4d2_autorestart](#l4d2_autorestart) * [l4d2_TKStopper](#l4d2_TKStopper) * [l4d2_crescendo_control](#l4d2_crescendo_control) +* [l4d2_vocalize_control](#l4d2_vocalize_control) ### Modified Others * [200IQBots_FlyYouFools](#200IQBots_FlyYouFools) @@ -325,4 +326,10 @@ _This plugin is currently in **development.**_ Current implementation may be lac * **Cvars:** * `l4d2_crescendo_percent` - * `l4d2_crescendo_range` \ No newline at end of file + * `l4d2_crescendo_range` + +### l4d2_vocalize_control +A very small plugin that simply allows a player to mute another player's vocalizations only for them. + +* **Commands:** + * `sm_vgag ` - Vocalize gag or ungags selected player(s) \ No newline at end of file diff --git a/plugins/l4d2_vocalize_control.smx b/plugins/l4d2_vocalize_control.smx new file mode 100644 index 0000000000000000000000000000000000000000..bc159cfde5521e9f3ec8e90acc4fa592b00ffbb7 GIT binary patch literal 4893 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 +#include +//#include + +public Plugin myinfo = +{ + name = "L4D2 Vocalize Control", + author = "jackzmc", + description = "", + version = PLUGIN_VERSION, + url = "" +}; + +ArrayList gaggedPlayers[MAXPLAYERS]; + +public void OnPluginStart() +{ + EngineVersion g_Game = GetEngineVersion(); + if(g_Game != Engine_Left4Dead2) + { + SetFailState("This plugin is for L4D2 only."); + } + + for(int i = 0; i < sizeof(gaggedPlayers); i++) { + gaggedPlayers[i] = new ArrayList(MAXPLAYERS - 1); + } + + HookEvent("player_disconnect", Event_PlayerDisconnect); + + RegConsoleCmd("sm_vgag", Cmd_Gag, "Gags a player\'s vocalizations locally"); + AddNormalSoundHook(view_as(SoundHook)); +} + +public void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroadcast) { + int client = GetClientOfUserId(event.GetInt("userid")); + if(client > 0) { + //Clear the player's list of gagged + gaggedPlayers[client].Clear(); + //Remove this player from any other player's gag list + for(int i = 0; i <= MaxClients; i++) { + int index = gaggedPlayers[i].FindValue(client); + if(index > -1) { + gaggedPlayers[i].Erase(index); + } + } + } +} + +public Action Cmd_Gag(int client, int args) { + if(args < 1) { + ReplyToCommand(client, "Usage: sm_vgag "); + } else { + char arg1[32]; + GetCmdArg(1, arg1, sizeof(arg1)); + char target_name[MAX_TARGET_LENGTH]; + int target_list[MAXPLAYERS], target_count; + bool tn_is_ml; + if ((target_count = ProcessTargetString( + arg1, + client, + target_list, + MAXPLAYERS, + COMMAND_FILTER_ALIVE, /* Only allow alive players */ + target_name, + sizeof(target_name), + tn_is_ml)) <= 0) + { + /* This function replies to the admin with a failure message */ + ReplyToTargetError(client, target_count); + return Plugin_Handled; + } + for (int i = 0; i < target_count; i++) + { + int playerIndex = gaggedPlayers[client].FindValue(target_list[i]); + if(playerIndex > -1) { + gaggedPlayers[client].Erase(playerIndex); + ReplyToCommand(client, "locally vocalize ungagged %s", target_name[i]); + }else{ + gaggedPlayers[client].Push(target_list[i]); + ReplyToCommand(client, "locally vocalize gagged %s", target_name[i]); + } + } + } + return Plugin_Handled; +} + +public Action SoundHook(int[] clients, int& numClients, char sample[PLATFORM_MAX_PATH], int& entity, int& channel, float& volume, int& level, int& pitch, int& flags, char[] soundEntry, int& seed) { + if(numClients > 0 && entity > 0 && entity <= MaxClients) { + if(StrContains(sample, "survivor\\voice") > -1) { + for(int i = 0; i < numClients; i++) { + int client = clients[i]; + if(gaggedPlayers[client].FindValue(entity) > -1) { + int swap = clients[numClients - 1]; + clients[numClients - 1] = client; + clients[i] = swap; + numClients -= 1; + return Plugin_Handled; + //Remove client from clients + } + } + } + + } + return Plugin_Continue; +}