diff --git a/Update_log.md b/Update_log.md
index 8a38e4ea9..83fa30d83 100644
--- a/Update_log.md
+++ b/Update_log.md
@@ -178,3 +178,6 @@ PS:这种处理方式相比原来的换成写实处理有以下几点好处
#### l4d_boss_vote插件
- 修复9特以上无法投票的功能
+#### 其他
+增加大量对抗插件的i18n翻译
+
diff --git a/addons/sourcemod/plugins/optional/AnneHappy/infected_control.smx b/addons/sourcemod/plugins/optional/AnneHappy/infected_control.smx
index f18f33739..b14d53f84 100644
Binary files a/addons/sourcemod/plugins/optional/AnneHappy/infected_control.smx and b/addons/sourcemod/plugins/optional/AnneHappy/infected_control.smx differ
diff --git a/addons/sourcemod/plugins/optional/autopause.smx b/addons/sourcemod/plugins/optional/autopause.smx
index df39788d5..24c434ef9 100644
Binary files a/addons/sourcemod/plugins/optional/autopause.smx and b/addons/sourcemod/plugins/optional/autopause.smx differ
diff --git a/addons/sourcemod/plugins/optional/checkpoint-rage-control.smx b/addons/sourcemod/plugins/optional/checkpoint-rage-control.smx
index 125a49766..18e8b2603 100644
Binary files a/addons/sourcemod/plugins/optional/checkpoint-rage-control.smx and b/addons/sourcemod/plugins/optional/checkpoint-rage-control.smx differ
diff --git a/addons/sourcemod/plugins/optional/coinflip.smx b/addons/sourcemod/plugins/optional/coinflip.smx
index 1140c9a77..faa0ae9c9 100644
Binary files a/addons/sourcemod/plugins/optional/coinflip.smx and b/addons/sourcemod/plugins/optional/coinflip.smx differ
diff --git a/addons/sourcemod/plugins/optional/current.smx b/addons/sourcemod/plugins/optional/current.smx
index 684fededb..0c5055134 100644
Binary files a/addons/sourcemod/plugins/optional/current.smx and b/addons/sourcemod/plugins/optional/current.smx differ
diff --git a/addons/sourcemod/plugins/optional/l4d2_stats.smx b/addons/sourcemod/plugins/optional/l4d2_stats.smx
index 4c9a1d886..91a29d775 100644
Binary files a/addons/sourcemod/plugins/optional/l4d2_stats.smx and b/addons/sourcemod/plugins/optional/l4d2_stats.smx differ
diff --git a/addons/sourcemod/plugins/optional/l4d_tank_control_eq.smx b/addons/sourcemod/plugins/optional/l4d_tank_control_eq.smx
index 519343ee7..b5fd9e6cd 100644
Binary files a/addons/sourcemod/plugins/optional/l4d_tank_control_eq.smx and b/addons/sourcemod/plugins/optional/l4d_tank_control_eq.smx differ
diff --git a/addons/sourcemod/plugins/optional/l4d_tank_damage_announce.smx b/addons/sourcemod/plugins/optional/l4d_tank_damage_announce.smx
index e07077063..ee9e1f27c 100644
Binary files a/addons/sourcemod/plugins/optional/l4d_tank_damage_announce.smx and b/addons/sourcemod/plugins/optional/l4d_tank_damage_announce.smx differ
diff --git a/addons/sourcemod/plugins/optional/nodeathcamskip.smx b/addons/sourcemod/plugins/optional/nodeathcamskip.smx
index eddda5d36..e84ddba19 100644
Binary files a/addons/sourcemod/plugins/optional/nodeathcamskip.smx and b/addons/sourcemod/plugins/optional/nodeathcamskip.smx differ
diff --git a/addons/sourcemod/plugins/optional/pause.smx b/addons/sourcemod/plugins/optional/pause.smx
index a98b836e1..3ee915151 100644
Binary files a/addons/sourcemod/plugins/optional/pause.smx and b/addons/sourcemod/plugins/optional/pause.smx differ
diff --git a/addons/sourcemod/plugins/optional/readyup.smx b/addons/sourcemod/plugins/optional/readyup.smx
index 9246fc40f..d57a8b4ff 100644
Binary files a/addons/sourcemod/plugins/optional/readyup.smx and b/addons/sourcemod/plugins/optional/readyup.smx differ
diff --git a/addons/sourcemod/plugins/optional/survivor_mvp.smx b/addons/sourcemod/plugins/optional/survivor_mvp.smx
index 2cc05e6ec..bde99ffc1 100644
Binary files a/addons/sourcemod/plugins/optional/survivor_mvp.smx and b/addons/sourcemod/plugins/optional/survivor_mvp.smx differ
diff --git a/addons/sourcemod/plugins/optional/teamflip.smx b/addons/sourcemod/plugins/optional/teamflip.smx
index b0f294583..1987acc44 100644
Binary files a/addons/sourcemod/plugins/optional/teamflip.smx and b/addons/sourcemod/plugins/optional/teamflip.smx differ
diff --git a/addons/sourcemod/plugins/optional/weapon_loadout_vote.smx b/addons/sourcemod/plugins/optional/weapon_loadout_vote.smx
index 84a98f617..4a7cb57ae 100644
Binary files a/addons/sourcemod/plugins/optional/weapon_loadout_vote.smx and b/addons/sourcemod/plugins/optional/weapon_loadout_vote.smx differ
diff --git a/addons/sourcemod/scripting/AnneHappy/infected_control.sp b/addons/sourcemod/scripting/AnneHappy/infected_control.sp
index da963d775..1293aad2f 100644
--- a/addons/sourcemod/scripting/AnneHappy/infected_control.sp
+++ b/addons/sourcemod/scripting/AnneHappy/infected_control.sp
@@ -193,7 +193,7 @@ public void OnPluginStart()
g_hSpawnDistanceMin.AddChangeHook(ConVarChanged_Cvars);
g_hTeleportSi.AddChangeHook(ConVarChanged_Cvars);
g_hTeleportCheckTime.AddChangeHook(ConVarChanged_Cvars);
- g_hTeleportDistance.AddChangeHook(ConVarChanged_Cvars);
+ //g_hTeleportDistance.AddChangeHook(ConVarChanged_Cvars);
g_hSiInterval.AddChangeHook(ConVarChanged_Cvars);
g_hIgnoreIncappedSurvivorSight.AddChangeHook(ConVarChanged_Cvars);
g_hEnableSIoption.AddChangeHook(ConVarChanged_Cvars);
diff --git a/addons/sourcemod/scripting/autopause.sp b/addons/sourcemod/scripting/autopause.sp
index 8d0a71b39..18879db20 100644
--- a/addons/sourcemod/scripting/autopause.sp
+++ b/addons/sourcemod/scripting/autopause.sp
@@ -1,173 +1,190 @@
/*
- SourcePawn is Copyright (C) 2006-2015 AlliedModders LLC. All rights reserved.
- SourceMod is Copyright (C) 2006-2015 AlliedModders LLC. All rights reserved.
- Pawn and SMALL are Copyright (C) 1997-2015 ITB CompuPhase.
- Source is Copyright (C) Valve Corporation.
- All trademarks are property of their respective owners.
-
- This program is free software: you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation, either version 3 of the License, or (at your
- option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program. If not, see .
+ SourcePawn is Copyright (C) 2006-2015 AlliedModders LLC. All rights reserved.
+ SourceMod is Copyright (C) 2006-2015 AlliedModders LLC. All rights reserved.
+ Pawn and SMALL are Copyright (C) 1997-2015 ITB CompuPhase.
+ Source is Copyright (C) Valve Corporation.
+ All trademarks are property of their respective owners.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program. If not, see .
*/
-#include
-#include
+#pragma semicolon 1
+#pragma newdecls required
+
#include
+#include
+#include
#undef REQUIRE_PLUGIN
#include "readyup"
-public Plugin:myinfo =
+public Plugin myinfo =
{
- name = "L4D2 Auto-pause",
- author = "Darkid, Griffin",
- description = "When a player disconnects due to crash, automatically pause the game. When they rejoin, give them a correct spawn timer.",
- version = "2.0",
- url = "https://github.com/jbzdarkid/AutoPause"
+ name = "L4D2 Auto-pause",
+ author = "Darkid, Griffin",
+ description = "When a player disconnects due to crash, automatically pause the game. When they rejoin, give them a correct spawn timer.",
+ version = "2.1",
+ url = "https://github.com/jbzdarkid/AutoPause"
}
-new Handle:g_hCvarEnabled;
-new Handle:g_hCvarForce;
-new Handle:g_hCvarApdebug;
-
-new Handle:crashedPlayers;
-new Handle:infectedPlayers;
-new Handle:survivorPlayers;
-new bool:readyUpIsAvailable;
-new bool:RoundEnd;
-
-public OnPluginStart() {
- // Suggestion by Nati: Disable for any 1v1
- g_hCvarEnabled = CreateConVar("autopause_enable", "1", "Whether or not to automatically pause when a player crashes.");
- g_hCvarForce = CreateConVar("autopause_force", "0", "Whether or not to force pause when a player crashes.");
- g_hCvarApdebug = CreateConVar("autopause_apdebug", "0", "Whether or not to debug information.");
-
- crashedPlayers = CreateTrie();
- infectedPlayers = CreateArray(64);
- survivorPlayers = CreateArray(64);
-
- HookEvent("round_start", round_start);
- HookEvent("round_end", round_end);
- HookEvent("player_team", playerTeam);
- HookEvent("player_disconnect", playerDisconnect, EventHookMode_Pre);
+ConVar
+ g_hCvarEnabled,
+ g_hCvarForce,
+ g_hCvarApdebug;
+Handle
+ crashedPlayers,
+ infectedPlayers,
+ survivorPlayers;
+bool
+ readyUpIsAvailable,
+ RoundEnd;
+
+public void OnPluginStart()
+{
+ LoadTranslations("autopause.phrases");
+ // Suggestion by Nati: Disable for any 1v1
+ g_hCvarEnabled = CreateConVar("autopause_enable", "1", "Whether or not to automatically pause when a player crashes.");
+ g_hCvarForce = CreateConVar("autopause_force", "0", "Whether or not to force pause when a player crashes.");
+ g_hCvarApdebug = CreateConVar("autopause_apdebug", "0", "Whether or not to debug information.");
+
+ crashedPlayers = CreateTrie();
+ infectedPlayers = CreateArray(64);
+ survivorPlayers = CreateArray(64);
+
+ HookEvent("round_start", RoundStart_Event);
+ HookEvent("round_end", RoundEnd_Event);
+ HookEvent("player_team", PlayerTeam_Event);
+ HookEvent("player_disconnect", PlayerDisconnect_Event, EventHookMode_Pre);
}
-public OnAllPluginsLoaded()
+public void OnAllPluginsLoaded()
{
- readyUpIsAvailable = LibraryExists("readyup");
+ readyUpIsAvailable = LibraryExists("readyup");
}
-public OnLibraryRemoved(const String:name[])
+public void OnLibraryRemoved(const char[] name)
{
- if (StrEqual(name, "readyup")) readyUpIsAvailable = false;
+ if (StrEqual(name, "readyup")) readyUpIsAvailable = false;
}
-public OnLibraryAdded(const String:name[])
+public void OnLibraryAdded(const char[] name)
{
- if (StrEqual(name, "readyup")) readyUpIsAvailable = true;
+ if (StrEqual(name, "readyup")) readyUpIsAvailable = true;
}
-public round_start(Handle:event, const String:name[], bool:dontBroadcast) {
- ClearTrie(crashedPlayers);
- ClearArray(infectedPlayers);
- ClearArray(survivorPlayers);
- RoundEnd = false;
+public void RoundStart_Event(Handle event, const char[] name, bool dontBroadcast)
+{
+ ClearTrie(crashedPlayers);
+ ClearArray(infectedPlayers);
+ ClearArray(survivorPlayers);
+ RoundEnd = false;
}
-public round_end(Handle:event, const String:name[], bool:dontBroadcast) {
- RoundEnd = true;
+public void RoundEnd_Event(Handle event, const char[] name, bool dontBroadcast)
+{
+ RoundEnd = true;
}
// Handles players leaving and joining the infected team.
-public playerTeam(Handle:event, const String:name[], bool:dontBroadcast) {
- new client = GetClientOfUserId(GetEventInt(event, "userid"));
- if (client <= 0 || client > MaxClients) return;
- decl String:steamId[64];
- GetClientAuthId(client, AuthId_Steam2, steamId, sizeof(steamId));
- if (strcmp(steamId, "BOT") == 0) return;
- new oldTeam = GetEventInt(event, "oldteam");
- new newTeam = GetEventInt(event, "team");
-
- new index = FindStringInArray(infectedPlayers, steamId);
- new survindex = FindStringInArray(infectedPlayers, steamId);
- if (oldTeam == 3) {
- if (index != -1) RemoveFromArray(infectedPlayers, index);
- if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Removed player %s from infected team.", steamId);
- }
- else if (oldTeam == 2) {
- if (survindex != -1) RemoveFromArray(survivorPlayers, survindex);
- if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Removed player %s from survivor team.", steamId);
- }
- if (newTeam == 3) {
- decl Float:spawnTime;
- if (GetTrieValue(crashedPlayers, steamId, spawnTime)) {
- new CountdownTimer:spawnTimer = L4D2Direct_GetSpawnTimer(client);
- CTimer_Start(spawnTimer, spawnTime);
- RemoveFromTrie(crashedPlayers, steamId);
- LogMessage("[AutoPause] Player %s rejoined, set spawn timer to %f.", steamId, spawnTime);
- } else if (index == -1) {
- PushArrayString(infectedPlayers, steamId);
- if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Added player %s to infected team.", steamId);
- }
- }
- else if (newTeam == 2 && survindex == -1) {
- PushArrayString(survivorPlayers, steamId);
- if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Added player %s to survivor team.", steamId);
- }
+public void PlayerTeam_Event(Event event, const char[] name, bool dontBroadcast)
+{
+ int client = GetClientOfUserId(GetEventInt(event, "userid"));
+ if (client <= 0 || client > MaxClients) return;
+ char steamId[64];
+ GetClientAuthId(client, AuthId_Steam2, steamId, sizeof(steamId));
+ if (strcmp(steamId, "BOT") == 0) return;
+ int oldTeam = GetEventInt(event, "oldteam");
+ int newTeam = GetEventInt(event, "team");
+
+ int index = FindStringInArray(infectedPlayers, steamId);
+ int survindex = FindStringInArray(infectedPlayers, steamId);
+ if (oldTeam == 3)
+ {
+ if (index != -1) RemoveFromArray(infectedPlayers, index);
+ if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Removed player %s from infected team.", steamId);
+ }
+ else if (oldTeam == 2) {
+ if (survindex != -1) RemoveFromArray(survivorPlayers, survindex);
+ if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Removed player %s from survivor team.", steamId);
+ }
+ if (newTeam == 3)
+ {
+ float spawnTime;
+ if (GetTrieValue(crashedPlayers, steamId, spawnTime))
+ {
+ CountdownTimer spawnTimer = L4D2Direct_GetSpawnTimer(client);
+ CTimer_Start(spawnTimer, spawnTime);
+ RemoveFromTrie(crashedPlayers, steamId);
+ LogMessage("[AutoPause] Player %s rejoined, set spawn timer to %f.", steamId, spawnTime);
+ }
+ else if (index == -1) {
+ PushArrayString(infectedPlayers, steamId);
+ if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Added player %s to infected team.", steamId);
+ }
+ }
+ else if (newTeam == 2 && survindex == -1) {
+ PushArrayString(survivorPlayers, steamId);
+ if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Added player %s to survivor team.", steamId);
+ }
}
-public playerDisconnect(Handle:event, const String:name[], bool:dontBroadcast) {
- new client = GetClientOfUserId(GetEventInt(event, "userid"));
- if (client <= 0 || client > MaxClients) return;
- decl String:steamId[64];
- GetClientAuthId(client, AuthId_Steam2, steamId, sizeof(steamId));
- if (strcmp(steamId, "BOT") == 0) return;
-
- // Player wasn't actually a gamer, ignore
- if (FindStringInArray(infectedPlayers, steamId) == -1 && FindStringInArray(survivorPlayers, steamId) == -1) return;
-
- decl String:reason[128];
- GetEventString(event, "reason", reason, sizeof(reason));
- decl String:playerName[128];
- GetEventString(event, "name", playerName, sizeof(playerName));
- decl String:timedOut[256];
- Format(timedOut, sizeof(timedOut), "%s timed out", playerName);
-
- if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Player %s (%s) left the game: %s", playerName, steamId, reason);
-
- // If the leaving player crashed, pause.
- if (strcmp(reason, timedOut) == 0 || strcmp(reason, "No Steam logon") == 0)
- {
- if ((!readyUpIsAvailable || !IsInReady()) && !RoundEnd && GetConVarBool(g_hCvarEnabled))
- {
- if (GetConVarBool(g_hCvarForce))
- {
- ServerCommand("sm_forcepause");
- }
- else
- {
- FakeClientCommand(client, "sm_pause");
- }
- CPrintToChatAll("{blue}[{default}AutoPause{blue}] {olive}%s {default}crashed.", playerName);
- }
- }
-
- // If the leaving player was on infected, save their spawn timer.
- if (FindStringInArray(infectedPlayers, steamId) != -1) {
- decl Float:timeLeft;
- new CountdownTimer:spawnTimer = L4D2Direct_GetSpawnTimer(client);
- if (spawnTimer != CTimer_Null) {
- timeLeft = CTimer_GetRemainingTime(spawnTimer);
- LogMessage("[AutoPause] Player %s left the game with %f time until spawn.", steamId, timeLeft);
- SetTrieValue(crashedPlayers, steamId, timeLeft);
- }
- }
+public void PlayerDisconnect_Event(Event hEvent, const char[] name, bool dontBroadcast)
+{
+ int client = GetClientOfUserId(GetEventInt(hEvent, "userid"));
+ if (client <= 0 || client > MaxClients) return;
+ char steamId[64];
+ GetClientAuthId(client, AuthId_Steam2, steamId, sizeof(steamId));
+ if (strcmp(steamId, "BOT") == 0) return;
+
+ // Player wasn't actually a gamer, ignore
+ if (FindStringInArray(infectedPlayers, steamId) == -1 && FindStringInArray(survivorPlayers, steamId) == -1) return;
+
+ char reason[128];
+ GetEventString(hEvent, "reason", reason, sizeof(reason));
+ char playerName[128];
+ GetEventString(hEvent, "name", playerName, sizeof(playerName));
+ char timedOut[256];
+ Format(timedOut, sizeof(timedOut), "%s timed out", playerName);
+
+ if (GetConVarBool(g_hCvarApdebug)) LogMessage("[AutoPause] Player %s (%s) left the game: %s", playerName, steamId, reason);
+
+ // If the leaving player crashed, pause.
+ if (strcmp(reason, timedOut) == 0 || strcmp(reason, "No Steam logon") == 0)
+ {
+ if ((!readyUpIsAvailable || !IsInReady()) && !RoundEnd && GetConVarBool(g_hCvarEnabled))
+ {
+ if (GetConVarBool(g_hCvarForce))
+ {
+ ServerCommand("sm_forcepause");
+ }
+ else
+ {
+ FakeClientCommand(client, "sm_pause");
+ }
+ CPrintToChatAll("%t %t", "Tag", "crashed", playerName);
+ }
+ }
+
+ // If the leaving player was on infected, save their spawn timer.
+ if (FindStringInArray(infectedPlayers, steamId) != -1)
+ {
+ float timeLeft;
+ CountdownTimer spawnTimer = L4D2Direct_GetSpawnTimer(client);
+ if (spawnTimer != CTimer_Null)
+ {
+ timeLeft = CTimer_GetRemainingTime(spawnTimer);
+ LogMessage("[AutoPause] Player %s left the game with %f time until spawn.", steamId, timeLeft);
+ SetTrieValue(crashedPlayers, steamId, timeLeft);
+ }
+ }
}
\ No newline at end of file
diff --git a/addons/sourcemod/scripting/checkpoint-rage-control.sp b/addons/sourcemod/scripting/checkpoint-rage-control.sp
index d5b403882..d0434fad7 100644
--- a/addons/sourcemod/scripting/checkpoint-rage-control.sp
+++ b/addons/sourcemod/scripting/checkpoint-rage-control.sp
@@ -33,6 +33,7 @@ int
ORIGINAL_BYTES[5];
Address g_pPatchTarget;
bool g_bIsPatched;
+ConVar g_hCvarDebug;
Handle
hAllMaps,
@@ -49,8 +50,7 @@ public Plugin myinfo =
}
-public void
- OnPluginStart()
+public void OnPluginStart()
{
LoadTranslations("checkpoint-rage-control.phrases");
Handle hGamedata = LoadGameConfigFile("checkpoint-rage-control");
@@ -59,10 +59,10 @@ public void
g_pPatchTarget = FindPatchTarget(hGamedata);
CloseHandle(hGamedata);
-
hSaferoomFrustrationTickdownMaps = CreateTrie();
- hAllMaps = CreateConVar("crc_global", "0", "Remove saferoom frustration preservation mechanic on all maps by default");
+ hAllMaps = CreateConVar("crc_global", "0", "Remove saferoom frustration preservation mechanic on all maps by default");
+ g_hCvarDebug = CreateConVar("crc_debug", "0", "Whether or not to debug.", FCVAR_NONE, true, 0.0, true, 1.0);
RegServerCmd("saferoom_frustration_tickdown", SetSaferoomFrustrationTickdown);
}
@@ -105,9 +105,13 @@ public void OnMapStart()
public void L4D_OnSpawnTank_Post(int client, const float vecPos[3], const float vecAng[3])
{
HookEvent("player_entered_start_area", Event_EnteredStartArea);
+ HookEvent("round_end", Event_RoundEndEvent);
+ HookEvent("tank_killed", Event_TankKilled);
+ if(g_hCvarDebug.BoolValue) CPrintToChatAll("%t Prepared Hook", "Tag");
+
}
-public void Event_EnteredStartArea(Event hEvent, const char[] eName, bool dontBroadcast)
+public void Event_EnteredStartArea(Event hEvent, const char[] sName, bool dontBroadcast)
{
int client = GetClientOfUserId(GetEventInt(hEvent, "userid"));
if (IsValidSurvivor(client))
@@ -120,8 +124,28 @@ public void Event_EnteredStartArea(Event hEvent, const char[] eName, bool dontBr
{
CPrintToChatAll("%t %t", "Tag", "KeepFrustration");
}
+ if(g_hCvarDebug.BoolValue) CPrintToChatAll("%t Unhook from player_entered_start_area hook", "Tag");
+ UnhookAll();
}
+}
+
+public void Event_RoundEndEvent(Event hEvent, const char[] sName, bool dontBroadcast)
+{
+ if(g_hCvarDebug.BoolValue) CPrintToChatAll("%t Unhook from round_end hook", "Tag");
+ UnhookAll();
+}
+
+public void Event_TankKilled(Event hEvent, const char[] sName, bool dontBroadcast)
+{
+ if(g_hCvarDebug.BoolValue) CPrintToChatAll("%t Unhook from tank_killed hook", "Tag");
+ UnhookAll();
+}
+
+public void UnhookAll()
+{
UnhookEvent("player_entered_start_area", Event_EnteredStartArea);
+ UnhookEvent("round_end", Event_RoundEndEvent);
+ UnhookEvent("tank_killed", Event_TankKilled);
}
bool IsPatched()
diff --git a/addons/sourcemod/scripting/coinflip.sp b/addons/sourcemod/scripting/coinflip.sp
index 7a23140b1..6388a40a4 100644
--- a/addons/sourcemod/scripting/coinflip.sp
+++ b/addons/sourcemod/scripting/coinflip.sp
@@ -1,37 +1,46 @@
-/*
- Coinflip
+/*
+ Coinflip
by purpletreefactory
Credit for the idea goes to Fig
This version was made out of convenience
-
+
1.0.2: added e-z-p-z commands, removed unnecessary colors.inc, removed generation of config file
*/
-
-#include
+#pragma semicolon 1
+#pragma newdecls required
+
+#include
#include
+#include
+
+char
+ client_name[32]; // Used to store the client_name of the player who calls coinflip
+int
+ result_int,
+ previous_timeC = 0, // Used for coinflip
+ current_timeC = 0, // Used for coinflip
+ previous_timeN = 0, // Used for picknumber
+ current_timeN = 0, // Used for picknumber
+ number_max = 20; // Default maximum bound for picknumber
-new result_int;
-new String:client_name[32]; // Used to store the client_name of the player who calls coinflip
-new previous_timeC = 0; // Used for coinflip
-new current_timeC = 0; // Used for coinflip
-new previous_timeN = 0; // Used for picknumber
-new current_timeN = 0; // Used for picknumber
-new Handle:delay_time; // Handle for the coinflip_delay cvar
-new number_max = 20; // Default maximum bound for picknumber
+ConVar
+ delay_time; // Handle for the coinflip_delay cvar
-public Plugin:myinfo =
+public Plugin myinfo =
{
- name = "Coinflip",
- author = "purpletreefactory, epilimic",
+ name = "Coinflip",
+ author = "purpletreefactory, epilimic",
description = "purpletreefactory's version of coinflip",
- version = "1.0.2",
- url = "http://www.sourcemod.net/"
+ version = "1.0.2",
+ url = "http://www.sourcemod.net/"
+
}
-
-public OnPluginStart()
+
+public void OnPluginStart()
{
- delay_time = CreateConVar("coinflip_delay","-1", "Time delay in seconds between allowed coinflips. Set at -1 if no delay at all is desired.");
+ LoadTranslations("coinflip.phrases");
+ delay_time = CreateConVar("coinflip_delay", "-1", "Time delay in seconds between allowed coinflips. Set at -1 if no delay at all is desired.");
RegConsoleCmd("sm_coinflip", Command_Coinflip);
RegConsoleCmd("sm_cf", Command_Coinflip);
@@ -40,60 +49,57 @@ public OnPluginStart()
RegConsoleCmd("sm_picknumber", Command_Picknumber);
}
-public Action:Command_Coinflip(client, args)
+public Action Command_Coinflip(int client, int args)
{
current_timeC = GetTime();
-
- if((current_timeC - previous_timeC) > GetConVarInt(delay_time)) // Only perform a coinflip if enough time has passed since the last one. This prevents spamming.
+
+ if ((current_timeC - previous_timeC) > GetConVarInt(delay_time)) // Only perform a coinflip if enough time has passed since the last one. This prevents spamming.
{
- result_int = GetURandomInt() % 2; // Gets a random integer and checks to see whether it's odd or even
- GetClientName(client, client_name, sizeof(client_name)); // Gets the client_name of the person using the command
-
- if(result_int == 0)
- PrintToChatAll("\x01[\x05Coinflip\x01] \x03%s\x01 flipped a coin!\nIt's \x04Heads\x01!", client_name); // Here \x04 is actually yellow
- else
- PrintToChatAll("\x01[\x05Coinflip\x01] \x03%s\x01 flipped a coin!\nIt's \x04Tails\x01!", client_name);
-
- previous_timeC = current_timeC; // Update the previous time
+ result_int = GetURandomInt() % 2; // Gets a random integer and checks to see whether it's odd or even
+ GetClientName(client, client_name, sizeof(client_name)); // Gets the client_name of the person using the command
+
+ CPrintToChatAll("%t %t", "Tag", result_int == 0 ? "Tails" : "Heads", client_name);
+ previous_timeC = current_timeC; // Update the previous time
}
else
{
PrintToConsole(client, "[Coinflip] Whoa there buddy, slow down. Wait at least %d seconds.", GetConVarInt(delay_time));
}
-
+
return Plugin_Handled;
}
-public Action:Command_Picknumber(client, args)
+public Action Command_Picknumber(int client, int args)
{
current_timeN = GetTime();
-
- if((current_timeN - previous_timeN) > GetConVarInt(delay_time)) // Only perform a numberpick if enough time has passed since the last one.
+
+ if ((current_timeN - previous_timeN) > GetConVarInt(delay_time)) // Only perform a numberpick if enough time has passed since the last one.
{
- GetClientName(client, client_name, sizeof(client_name)); // Gets the client_name of the person using the command
-
- if(GetCmdArgs() == 0)
+ GetClientName(client, client_name, sizeof(client_name)); // Gets the client_name of the person using the command
+
+ if (GetCmdArgs() == 0)
{
- result_int = GetURandomInt() % (number_max); // Generates a random number within the default range
-
- PrintToChatAll("\x01[\x05Coinflip\x01] \x03%s\x01 rolled a \x03%d \x01sided die!\nIt's \x04%d\x01!", client_name, number_max, result_int + 1);
+ result_int = GetURandomInt() % (number_max); // Generates a random number within the default range
+
+ CPrintToChatAll("%t %t", "Tag", "rolled", client_name, number_max, result_int + 1);
}
else
{
- new String:arg[32];
- new max;
-
- GetCmdArg(1, arg, sizeof(arg)); // Get the command argument
+ char arg[32];
+ int max;
+
+ GetCmdArg(1, arg, sizeof(arg)); // Get the command argument
max = StringToInt(arg);
-
- result_int = GetURandomInt() % (max); // Generates a random number within the specified range
- PrintToChatAll("\x01[\x05Coinflip\x01] \x03%s\x01 rolled a \x03%d \x01sided die!\nIt's \x04%d\x01!", client_name, max, result_int + 1);
+
+ result_int = GetURandomInt() % (max); // Generates a random number within the specified range
+ CPrintToChatAll("%t %t", "Tag", "rolled", client_name, max, result_int + 1);
}
-
- previous_timeN = current_timeN; // Update the previous time
+
+ previous_timeN = current_timeN; // Update the previous time
}
else
{
PrintToConsole(client, "[Coinflip] Whoa there buddy, slow down. Wait at least %d seconds.", GetConVarInt(delay_time));
}
+ return Plugin_Handled;
}
\ No newline at end of file
diff --git a/addons/sourcemod/scripting/current.sp b/addons/sourcemod/scripting/current.sp
index 10582c2d2..5f24b4c3e 100644
--- a/addons/sourcemod/scripting/current.sp
+++ b/addons/sourcemod/scripting/current.sp
@@ -1,8 +1,9 @@
#pragma semicolon 1
#pragma newdecls required
-#include
+#include
#include
+#include
#define TEAM_SURVIVORS 2
@@ -10,15 +11,16 @@ ConVar g_hVsBossBuffer;
public Plugin myinfo =
{
- name = "L4D2 Survivor Progress",
- author = "CanadaRox, Visor",
+ name = "L4D2 Survivor Progress",
+ author = "CanadaRox, Visor",
description = "Print survivor progress in flow percents ",
- version = "2.0.2",
- url = "https://github.com/SirPlease/L4D2-Competitive-Rework"
+ version = "2.0.2",
+ url = "https://github.com/SirPlease/L4D2-Competitive-Rework"
};
public void OnPluginStart()
{
+ LoadTranslations("current.phrases");
g_hVsBossBuffer = FindConVar("versus_boss_buffer");
RegConsoleCmd("sm_cur", CurrentCmd);
@@ -28,7 +30,7 @@ public void OnPluginStart()
public Action CurrentCmd(int client, int args)
{
int boss_proximity = RoundToNearest(GetBossProximity() * 100.0);
- PrintToChat(client, "\x01Current: \x04%d%%", boss_proximity);
+ CPrintToChat(client, "%t", "Current", boss_proximity);
return Plugin_Handled;
}
@@ -41,15 +43,18 @@ float GetBossProximity()
float GetMaxSurvivorCompletion()
{
- float flow = 0.0, tmp_flow = 0.0, origin[3];
+ float flow = 0.0, tmp_flow = 0.0, origin[3];
Address pNavArea;
- for (int i = 1; i <= MaxClients; i++) {
- if (IsClientInGame(i) && GetClientTeam(i) == TEAM_SURVIVORS) {
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (IsClientInGame(i) && GetClientTeam(i) == TEAM_SURVIVORS)
+ {
GetClientAbsOrigin(i, origin);
pNavArea = L4D2Direct_GetTerrorNavArea(origin);
- if (pNavArea != Address_Null) {
+ if (pNavArea != Address_Null)
+ {
tmp_flow = L4D2Direct_GetTerrorNavAreaFlow(pNavArea);
- flow = (flow > tmp_flow) ? flow : tmp_flow;
+ flow = (flow > tmp_flow) ? flow : tmp_flow;
}
}
}
diff --git a/addons/sourcemod/scripting/include/survivor_mvp.inc b/addons/sourcemod/scripting/include/survivor_mvp.inc
new file mode 100644
index 000000000..2cda02ab8
--- /dev/null
+++ b/addons/sourcemod/scripting/include/survivor_mvp.inc
@@ -0,0 +1,82 @@
+#if defined _survivor_mvp_included_
+ #endinput
+#endif
+#define _survivor_mvp_included_
+
+/**
+ * Current round MVP.
+ *
+ * @return Client index.
+ */
+native int SURVMVP_GetMVP();
+
+/**
+ * Damage of client.
+ *
+ * @param client Client to check.
+ * @return Damage.
+ */
+native int SURVMVP_GetMVPDmgCount(int client);
+
+/**
+ * SI kills of client.
+ *
+ * @param client Client to check.
+ * @return SI Kills.
+ */
+native int SURVMVP_GetMVPKills(int client);
+
+/**
+ * Damage percent of client.
+ *
+ * @param client Client to check.
+ * @return Damage.
+ */
+native float SURVMVP_GetMVPDmgPercent(int client);
+
+/**
+ * Current round MVP client (Common)
+ *
+ * @return Client index.
+ */
+native int SURVMVP_GetMVPCI();
+
+/**
+ * Common kills for client.
+ *
+ * @param client Client to check.
+ * @return Kills.
+ */
+native int SURVMVP_GetMVPCIKills(int client);
+
+/**
+ * CI percent of client.
+ *
+ * @param client Client to check.
+ * @return CI Percent.
+ */
+native float SURVMVP_GetMVPCIPercent(int client);
+
+public SharedPlugin __pl_l4d2lib =
+{
+ name = "survivor_mvp",
+ file = "survivor_mvp.smx",
+#if defined REQUIRE_PLUGIN
+ required = 1,
+#else
+ required = 0,
+#endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_l4d2lib_SetNTVOptional()
+{
+ MarkNativeAsOptional("SURVMVP_GetMVP");
+ MarkNativeAsOptional("SURVMVP_GetMVPDmgCount");
+ MarkNativeAsOptional("SURVMVP_GetMVPKills");
+ MarkNativeAsOptional("SURVMVP_GetMVPDmgPercent");
+ MarkNativeAsOptional("SURVMVP_GetMVPCI");
+ MarkNativeAsOptional("SURVMVP_GetMVPCIKills");
+ MarkNativeAsOptional("SURVMVP_GetMVPCIPercent");
+}
+#endif
diff --git a/addons/sourcemod/scripting/l4d2_stats.sp b/addons/sourcemod/scripting/l4d2_stats.sp
index 049c53456..a02fd3e77 100644
--- a/addons/sourcemod/scripting/l4d2_stats.sp
+++ b/addons/sourcemod/scripting/l4d2_stats.sp
@@ -101,8 +101,7 @@ public void Event_PlayerSpawn(Event hEvent, const char[] sEventName, bool bDontB
BoomerKillTime = 0.0;
g_hBoomerKillTimer = CreateTimer(0.1, Timer_KillBoomer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
}
- //防止刷特软件把特感踢出后数值没有被重置
- ClearDamage(client);
+
g_iLastHealth[client] = GetClientHealth(client);
}
}
diff --git a/addons/sourcemod/scripting/l4d_tank_control_eq.sp b/addons/sourcemod/scripting/l4d_tank_control_eq.sp
index 81845f948..2d219cb8b 100644
--- a/addons/sourcemod/scripting/l4d_tank_control_eq.sp
+++ b/addons/sourcemod/scripting/l4d_tank_control_eq.sp
@@ -4,21 +4,21 @@
#pragma semicolon 1
#pragma newdecls required
-#include
#include
+#include
#undef REQUIRE_PLUGIN
#include
-#define IS_VALID_CLIENT(%1) (%1 > 0 && %1 <= MaxClients)
-#define IS_INFECTED(%1) (GetClientTeam(%1) == 3)
-#define IS_VALID_INGAME(%1) (IS_VALID_CLIENT(%1) && IsClientInGame(%1))
-#define IS_VALID_INFECTED(%1) (IS_VALID_INGAME(%1) && IS_INFECTED(%1))
-#define IS_VALID_CASTER(%1) (IS_VALID_INGAME(%1) && casterSystemAvailable && IsClientCaster(%1))
+#define IS_VALID_CLIENT(%1) (%1 > 0 && %1 <= MaxClients)
+#define IS_INFECTED(%1) (GetClientTeam(%1) == 3)
+#define IS_VALID_INGAME(%1) (IS_VALID_CLIENT(%1) && IsClientInGame(%1))
+#define IS_VALID_INFECTED(%1) (IS_VALID_INGAME(%1) && IS_INFECTED(%1))
+#define IS_VALID_CASTER(%1) (IS_VALID_INGAME(%1) && casterSystemAvailable && IsClientCaster(%1))
ArrayList h_whosHadTank;
-char queuedTankSteamId[64];
-ConVar hTankPrint, hTankDebug;
-bool casterSystemAvailable;
+char queuedTankSteamId[64];
+ConVar hTankPrint, hTankDebug;
+bool casterSystemAvailable;
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
@@ -27,65 +27,83 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
return APLRes_Success;
}
-public int Native_GetTankSelection(Handle plugin, int numParams) { return getInfectedPlayerBySteamId(queuedTankSteamId); }
-
-public Plugin myinfo =
+public int Native_GetTankSelection(Handle plugin, int numParams)
{
- name = "L4D2 Tank Control",
- author = "arti",
- description = "Distributes the role of the tank evenly throughout the team",
- version = "0.0.18",
- url = "https://github.com/alexberriman/l4d2-plugins/tree/master/l4d_tank_control"
+ return getInfectedPlayerBySteamId(queuedTankSteamId);
}
-enum L4D2Team
+public Plugin myinfo =
{
- L4D2Team_None = 0,
- L4D2Team_Spectator,
- L4D2Team_Survivor,
- L4D2Team_Infected
+ name = "L4D2 Tank Control",
+ author = "arti",
+ description = "Distributes the role of the tank evenly throughout the team",
+ version = "0.0.18",
+ url = "https://github.com/alexberriman/l4d2-plugins/tree/master/l4d_tank_control"
+
}
-enum ZClass
-{
- ZClass_Smoker = 1,
- ZClass_Boomer = 2,
- ZClass_Hunter = 3,
- ZClass_Spitter = 4,
- ZClass_Jockey = 5,
- ZClass_Charger = 6,
- ZClass_Witch = 7,
- ZClass_Tank = 8
+enum L4D2Team {
+ L4D2Team_None = 0,
+ L4D2Team_Spectator,
+ L4D2Team_Survivor,
+ L4D2Team_Infected
+}
+
+enum ZClass {
+ ZClass_Smoker = 1,
+ ZClass_Boomer = 2,
+ ZClass_Hunter = 3,
+ ZClass_Spitter = 4,
+ ZClass_Jockey = 5,
+ ZClass_Charger = 6,
+ ZClass_Witch = 7,
+ ZClass_Tank = 8
}
public void OnPluginStart()
{
- // Load translations (for targeting player)
- LoadTranslations("common.phrases");
-
- // Event hooks
- HookEvent("player_left_start_area", PlayerLeftStartArea_Event, EventHookMode_PostNoCopy);
- HookEvent("round_start", RoundStart_Event, EventHookMode_PostNoCopy);
- HookEvent("round_end", RoundEnd_Event, EventHookMode_PostNoCopy);
- HookEvent("player_team", PlayerTeam_Event, EventHookMode_Post);
- HookEvent("tank_killed", TankKilled_Event, EventHookMode_PostNoCopy);
- HookEvent("player_death", PlayerDeath_Event, EventHookMode_Post);
-
- // Initialise the tank arrays/data values
- h_whosHadTank = new ArrayList(ByteCountToCells(64));
-
- // Admin commands
- RegAdminCmd("sm_tankshuffle", TankShuffle_Cmd, ADMFLAG_SLAY, "Re-picks at random someone to become tank.");
- RegAdminCmd("sm_givetank", GiveTank_Cmd, ADMFLAG_SLAY, "Gives the tank to a selected player");
-
- // Register the boss commands
- RegConsoleCmd("sm_tank", Tank_Cmd, "Shows who is becoming the tank.");
- RegConsoleCmd("sm_boss", Tank_Cmd, "Shows who is becoming the tank.");
- RegConsoleCmd("sm_witch", Tank_Cmd, "Shows who is becoming the tank.");
-
- // Cvars
- hTankPrint = CreateConVar("tankcontrol_print_all", "0", "Who gets to see who will become the tank? (0 = Infected, 1 = Everyone)");
- hTankDebug = CreateConVar("tankcontrol_debug", "0", "Whether or not to debug to console");
+ // Load translations (for targeting player)
+ LoadTranslations("common.phrases");
+ LoadTranslation("l4d_tank_control_eq.phrases");
+
+ // Event hooks
+ HookEvent("player_left_start_area", PlayerLeftStartArea_Event, EventHookMode_PostNoCopy);
+ HookEvent("round_start", RoundStart_Event, EventHookMode_PostNoCopy);
+ HookEvent("round_end", RoundEnd_Event, EventHookMode_PostNoCopy);
+ HookEvent("player_team", PlayerTeam_Event, EventHookMode_Post);
+ HookEvent("tank_killed", TankKilled_Event, EventHookMode_PostNoCopy);
+ HookEvent("player_death", PlayerDeath_Event, EventHookMode_Post);
+
+ // Initialise the tank arrays/data values
+ h_whosHadTank = new ArrayList(ByteCountToCells(64));
+
+ // Admin commands
+ RegAdminCmd("sm_tankshuffle", TankShuffle_Cmd, ADMFLAG_SLAY, "Re-picks at random someone to become tank.");
+ RegAdminCmd("sm_givetank", GiveTank_Cmd, ADMFLAG_SLAY, "Gives the tank to a selected player");
+
+ // Register the boss commands
+ RegConsoleCmd("sm_tank", Tank_Cmd, "Shows who is becoming the tank.");
+ RegConsoleCmd("sm_boss", Tank_Cmd, "Shows who is becoming the tank.");
+ RegConsoleCmd("sm_witch", Tank_Cmd, "Shows who is becoming the tank.");
+
+ // Cvars
+ hTankPrint = CreateConVar("tankcontrol_print_all", "0", "Who gets to see who will become the tank? (0 = Infected, 1 = Everyone)");
+ hTankDebug = CreateConVar("tankcontrol_debug", "0", "Whether or not to debug to console");
+}
+
+void LoadTranslation(char[] sTranslation)
+{
+ char
+ sPath[PLATFORM_MAX_PATH],
+ sName[64];
+
+ Format(sName, sizeof(sName), "translations/%s.txt", sTranslation);
+ BuildPath(Path_SM, sPath, sizeof(sPath), sName);
+ if (!FileExists(sPath))
+ {
+ SetFailState("Missing translation file %s.txt", sTranslation);
+ }
+ LoadTranslations(sTranslation);
}
public void OnAllPluginsLoaded()
@@ -103,10 +121,10 @@ public void OnLibraryRemoved(const char[] name)
if (StrEqual(name, "caster_system")) casterSystemAvailable = false;
}
-/*public void OnClientDisconnect(int client)
+/*public void OnClientDisconnect(int client)
{
char tmpSteamId[64];
-
+
if (client)
{
GetClientAuthId(client, AuthId_Steam2, tmpSteamId, sizeof(tmpSteamId));
@@ -121,10 +139,9 @@ public void OnLibraryRemoved(const char[] name)
/**
* When a new game starts, reset the tank pool.
*/
-
public void RoundStart_Event(Event hEvent, const char[] eName, bool dontBroadcast)
{
- CreateTimer(10.0, newGame);
+ CreateTimer(10.0, newGame);
}
public Action newGame(Handle timer)
@@ -145,31 +162,28 @@ public Action newGame(Handle timer)
/**
* When the round ends, reset the active tank.
*/
-
public void RoundEnd_Event(Event hEvent, const char[] eName, bool dontBroadcast)
{
- queuedTankSteamId = "";
+ queuedTankSteamId = "";
}
/**
* When a player leaves the start area, choose a tank and output to all.
*/
-
public void PlayerLeftStartArea_Event(Event hEvent, const char[] eName, bool dontBroadcast)
{
- chooseTank(0);
- outputTankToAll(0);
+ chooseTank(0);
+ outputTankToAll(0);
}
/**
* When the queued tank switches teams, choose a new one
*/
-
public void PlayerTeam_Event(Event hEvent, const char[] name, bool dontBroadcast)
{
L4D2Team oldTeam = view_as(hEvent.GetInt("oldteam"));
- int client = GetClientOfUserId(hEvent.GetInt("userid"));
- char tmpSteamId[64];
+ int client = GetClientOfUserId(hEvent.GetInt("userid"));
+ char tmpSteamId[64];
if (client && oldTeam == view_as(L4D2Team_Infected))
{
@@ -185,363 +199,354 @@ public void PlayerTeam_Event(Event hEvent, const char[] name, bool dontBroadcast
/**
* When the tank dies, requeue a player to become tank (for finales)
*/
-
public void PlayerDeath_Event(Event hEvent, const char[] eName, bool dontBroadcast)
{
- int zombieClass = 0;
- int victimId = hEvent.GetInt("userid");
- int victim = GetClientOfUserId(victimId);
-
- if (victimId && IsClientInGame(victim))
- {
- zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
- if (view_as(zombieClass) == ZClass_Tank)
- {
- if (GetConVarBool(hTankDebug))
- {
- PrintToConsoleAll("[TC] Tank died(1), choosing a new tank");
- }
- chooseTank(0);
- }
- }
+ int zombieClass = 0;
+ int victimId = hEvent.GetInt("userid");
+ int victim = GetClientOfUserId(victimId);
+
+ if (victimId && IsClientInGame(victim))
+ {
+ zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
+ if (view_as(zombieClass) == ZClass_Tank)
+ {
+ if (GetConVarBool(hTankDebug))
+ {
+ PrintToConsoleAll("[TC] Tank died(1), choosing a new tank");
+ }
+ chooseTank(0);
+ }
+ }
}
public void TankKilled_Event(Event hEvent, const char[] eName, bool dontBroadcast)
{
- if (GetConVarBool(hTankDebug))
- {
- PrintToConsoleAll("[TC] Tank died(2), choosing a new tank");
- }
- chooseTank(0);
+ if (GetConVarBool(hTankDebug))
+ {
+ PrintToConsoleAll("[TC] Tank died(2), choosing a new tank");
+ }
+ chooseTank(0);
}
/**
* When a player wants to find out whos becoming tank,
* output to them.
*/
-
public Action Tank_Cmd(int client, int args)
{
- if (!IsClientInGame(client))
- return Plugin_Handled;
-
- int tankClientId;
- char tankClientName[128];
-
- // Only output if we have a queued tank
- if (! strcmp(queuedTankSteamId, ""))
- {
- return Plugin_Handled;
- }
-
- tankClientId = getInfectedPlayerBySteamId(queuedTankSteamId);
- if (tankClientId != -1)
- {
- GetClientName(tankClientId, tankClientName, sizeof(tankClientName));
-
- // If on infected, print to entire team
- if (view_as(GetClientTeam(client)) == L4D2Team_Infected || (casterSystemAvailable && IsClientCaster(client)))
- {
- if (client == tankClientId) CPrintToChat(client, "{red}<{default}Tank Selection{red}> {green}You {default}will become the {red}Tank{default}!");
- else CPrintToChat(client, "{red}<{default}Tank Selection{red}> {olive}%s {default}will become the {red}Tank!", tankClientName);
- }
- }
-
- return Plugin_Handled;
+ if (!IsClientInGame(client))
+ return Plugin_Handled;
+
+ int tankClientId;
+ char tankClientName[128];
+
+ // Only output if we have a queued tank
+ if (!strcmp(queuedTankSteamId, ""))
+ {
+ return Plugin_Handled;
+ }
+
+ tankClientId = getInfectedPlayerBySteamId(queuedTankSteamId);
+ if (tankClientId != -1)
+ {
+ GetClientName(tankClientId, tankClientName, sizeof(tankClientName));
+
+ // If on infected, print to entire team
+ if (view_as(GetClientTeam(client)) == L4D2Team_Infected || (casterSystemAvailable && IsClientCaster(client)))
+ {
+ if (client == tankClientId) CPrintToChat(client, "%t %t", "Tag_Selecion", "YouBecomeTank");
+ else CPrintToChat(client, "%t %t", "Tag_Selecion", "BecomeTank", tankClientName);
+ }
+ }
+
+ return Plugin_Handled;
}
/**
* Shuffle the tank (randomly give to another player in
* the pool.
*/
-
public Action TankShuffle_Cmd(int client, int args)
{
- chooseTank(0);
- outputTankToAll(0);
-
- return Plugin_Handled;
+ chooseTank(0);
+ outputTankToAll(0);
+
+ return Plugin_Handled;
}
/**
* Give the tank to a specific player.
*/
-
public Action GiveTank_Cmd(int client, int args)
-{
- // Who are we targetting?
- char arg1[32];
- GetCmdArg(1, arg1, sizeof(arg1));
-
- // Try and find a matching player
- int target = FindTarget(client, arg1);
- if (target == -1)
- {
- return Plugin_Handled;
- }
-
- // Get the players name
- char name[MAX_NAME_LENGTH];
- GetClientName(target, name, sizeof(name));
-
- // Set the tank
- if (IsClientInGame(target) && ! IsFakeClient(target))
- {
- // Checking if on our desired team
- if (view_as(GetClientTeam(target)) != L4D2Team_Infected)
- {
- CPrintToChatAll("{olive}[SM] {default}%s not on infected. Unable to give tank", name);
- return Plugin_Handled;
- }
-
- char steamId[64];
- GetClientAuthId(target, AuthId_Steam2, steamId, sizeof(steamId));
+{
+ // Who are we targetting?
+ char arg1[32];
+ GetCmdArg(1, arg1, sizeof(arg1));
- strcopy(queuedTankSteamId, sizeof(queuedTankSteamId), steamId);
- outputTankToAll(0);
- }
-
- return Plugin_Handled;
+ // Try and find a matching player
+ int target = FindTarget(client, arg1);
+ if (target == -1)
+ {
+ return Plugin_Handled;
+ }
+
+ // Get the players name
+ char name[MAX_NAME_LENGTH];
+ GetClientName(target, name, sizeof(name));
+
+ // Set the tank
+ if (IsClientInGame(target) && !IsFakeClient(target))
+ {
+ // Checking if on our desired team
+ if (view_as(GetClientTeam(target)) != L4D2Team_Infected)
+ {
+ CPrintToChatAll("%t", "UnableGiveTank", name);
+ return Plugin_Handled;
+ }
+
+ char steamId[64];
+ GetClientAuthId(target, AuthId_Steam2, steamId, sizeof(steamId));
+
+ strcopy(queuedTankSteamId, sizeof(queuedTankSteamId), steamId);
+ outputTankToAll(0);
+ }
+
+ return Plugin_Handled;
}
/**
* Selects a player on the infected team from random who hasn't been
* tank and gives it to them.
*/
-
public void chooseTank(any data)
{
- // Create our pool of players to choose from
- ArrayList infectedPool = new ArrayList(ByteCountToCells(64));
- addTeamSteamIdsToArray(infectedPool, L4D2Team_Infected);
-
- // If there is nobody on the infected team, return (otherwise we'd be stuck trying to select forever)
- if (GetArraySize(infectedPool) == 0)
- {
- delete infectedPool;
- return;
- }
+ // Create our pool of players to choose from
+ ArrayList infectedPool = new ArrayList(ByteCountToCells(64));
+ addTeamSteamIdsToArray(infectedPool, L4D2Team_Infected);
- // Remove players who've already had tank from the pool.
- removeTanksFromPool(infectedPool, h_whosHadTank);
-
- // If the infected pool is empty, remove infected players from pool
- if (GetArraySize(infectedPool) == 0) // (when nobody on infected ,error)
- {
- ArrayList infectedTeam = new ArrayList(ByteCountToCells(64));
- addTeamSteamIdsToArray(infectedTeam, L4D2Team_Infected);
- if (GetArraySize(infectedTeam) > 1)
- {
- removeTanksFromPool(h_whosHadTank, infectedTeam);
- chooseTank(0);
- }
- else
- {
- queuedTankSteamId = "";
- }
-
- delete infectedTeam;
- delete infectedPool;
- return;
- }
-
- // Select a random person to become tank
- int rndIndex = GetRandomInt(0, GetArraySize(infectedPool) - 1);
- GetArrayString(infectedPool, rndIndex, queuedTankSteamId, sizeof(queuedTankSteamId));
- delete infectedPool;
+ // If there is nobody on the infected team, return (otherwise we'd be stuck trying to select forever)
+ if (GetArraySize(infectedPool) == 0)
+ {
+ delete infectedPool;
+ return;
+ }
+
+ // Remove players who've already had tank from the pool.
+ removeTanksFromPool(infectedPool, h_whosHadTank);
+
+ // If the infected pool is empty, remove infected players from pool
+ if (GetArraySize(infectedPool) == 0) // (when nobody on infected ,error)
+ {
+ ArrayList infectedTeam = new ArrayList(ByteCountToCells(64));
+ addTeamSteamIdsToArray(infectedTeam, L4D2Team_Infected);
+ if (GetArraySize(infectedTeam) > 1)
+ {
+ removeTanksFromPool(h_whosHadTank, infectedTeam);
+ chooseTank(0);
+ }
+ else
+ {
+ queuedTankSteamId = "";
+ }
+
+ delete infectedTeam;
+ delete infectedPool;
+ return;
+ }
+
+ // Select a random person to become tank
+ int rndIndex = GetRandomInt(0, GetArraySize(infectedPool) - 1);
+ GetArrayString(infectedPool, rndIndex, queuedTankSteamId, sizeof(queuedTankSteamId));
+ delete infectedPool;
}
/**
* Make sure we give the tank to our queued player.
*/
-
-public Action L4D_OnTryOfferingTankBot(int tank_index, bool &enterStatis)
-{
- // Reset the tank's frustration if need be
- if (! IsFakeClient(tank_index))
- {
- PrintHintText(tank_index, "Rage Meter Refilled");
- for (int i = 1; i <= MaxClients; i++)
- {
- if (! IsClientInGame(i) || GetClientTeam(i) != 3)
- continue;
+public Action L4D_OnTryOfferingTankBot(int tank_index, bool& enterStatis)
+{
+ // Reset the tank's frustration if need be
+ if (!IsFakeClient(tank_index))
+ {
+ PrintHintText(tank_index, "%t", "Hit_RageMeterRefilled");
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (!IsClientInGame(i) || GetClientTeam(i) != 3)
+ continue;
- if (tank_index == i) CPrintToChat(i, "{red}<{default}Tank Rage{red}> {olive}Rage Meter {red}Refilled");
- else CPrintToChat(i, "{red}<{default}Tank Rage{red}> {default}({green}%N{default}'s) {olive}Rage Meter {red}Refilled", tank_index);
- }
-
- SetTankFrustration(tank_index, 100);
- L4D2Direct_SetTankPassedCount(L4D2Direct_GetTankPassedCount() + 1);
-
- return Plugin_Handled;
- }
-
- // If we don't have a queued tank, choose one
- if (! strcmp(queuedTankSteamId, ""))
- chooseTank(0);
-
- // Mark the player as having had tank
- if (strcmp(queuedTankSteamId, "") != 0)
- {
- setTankTickets(queuedTankSteamId, 20000);
- PushArrayString(h_whosHadTank, queuedTankSteamId);
- }
-
- return Plugin_Continue;
+ if (tank_index == i) CPrintToChat(i, "%t %t", "Tag_Rage", "YouRageMeterRefilled");
+ else CPrintToChat(i, "%t %t", "Tag_Rage", "RageMeterRefilled", tank_index);
+ }
+
+ SetTankFrustration(tank_index, 100);
+ L4D2Direct_SetTankPassedCount(L4D2Direct_GetTankPassedCount() + 1);
+
+ return Plugin_Handled;
+ }
+
+ // If we don't have a queued tank, choose one
+ if (!strcmp(queuedTankSteamId, ""))
+ chooseTank(0);
+
+ // Mark the player as having had tank
+ if (strcmp(queuedTankSteamId, "") != 0)
+ {
+ setTankTickets(queuedTankSteamId, 20000);
+ PushArrayString(h_whosHadTank, queuedTankSteamId);
+ }
+
+ return Plugin_Continue;
}
/**
* Sets the amount of tickets for a particular player, essentially giving them tank.
*/
-
public void setTankTickets(const char[] steamId, int tickets)
{
- int tankClientId = getInfectedPlayerBySteamId(steamId);
-
- for (int i = 1; i <= MaxClients; i++)
- {
- if (IsClientInGame(i) && ! IsFakeClient(i) && GetClientTeam(i) == 3)
- {
- L4D2Direct_SetTankTickets(i, (i == tankClientId) ? tickets : 0);
- }
- }
+ int tankClientId = getInfectedPlayerBySteamId(steamId);
+
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == 3)
+ {
+ L4D2Direct_SetTankTickets(i, (i == tankClientId) ? tickets : 0);
+ }
+ }
}
/**
* Output who will become tank
*/
-
public void outputTankToAll(any data)
{
- char tankClientName[MAX_NAME_LENGTH];
- int tankClientId = getInfectedPlayerBySteamId(queuedTankSteamId);
-
- if (tankClientId != -1)
- {
- GetClientName(tankClientId, tankClientName, sizeof(tankClientName));
- if (GetConVarBool(hTankPrint))
- {
- CPrintToChatAll("{red}<{default}Tank Selection{red}> {olive}%s {default}will become the {red}Tank!", tankClientName);
- }
- else
- {
- for (int i = 1; i <= MaxClients; i++)
- {
- if (!IS_VALID_INFECTED(i) && !IS_VALID_CASTER(i))
- continue;
-
- if (tankClientId == i) CPrintToChat(i, "{red}<{default}Tank Selection{red}> {green}You {default}will become the {red}Tank{default}!");
- else CPrintToChat(i, "{red}<{default}Tank Selection{red}> {olive}%s {default}will become the {red}Tank!", tankClientName);
- }
- }
- }
+ char tankClientName[MAX_NAME_LENGTH];
+ int tankClientId = getInfectedPlayerBySteamId(queuedTankSteamId);
+
+ if (tankClientId != -1)
+ {
+ GetClientName(tankClientId, tankClientName, sizeof(tankClientName));
+ if (GetConVarBool(hTankPrint))
+ {
+ CPrintToChatAll("%t %t", "Tag_Selecion", "BecomeTank", tankClientName);
+ }
+ else
+ {
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (!IS_VALID_INFECTED(i) && !IS_VALID_CASTER(i))
+ continue;
+
+ if (tankClientId == i) CPrintToChat(i, "%t %t", "Tag_Selecion", "YouBecomeTank");
+ else CPrintToChat(i, "%t %t", "Tag_Selecion", "BecomeTank", tankClientName);
+ }
+ }
+ }
}
-stock void PrintToInfected(const char[] Message, any ... )
+stock void PrintToInfected(const char[] Message, any...)
{
- char sPrint[256];
- VFormat(sPrint, sizeof(sPrint), Message, 2);
+ char sPrint[256];
+ VFormat(sPrint, sizeof(sPrint), Message, 2);
- for (int i = 1; i <= MaxClients; i++)
- {
- if (!IS_VALID_INFECTED(i) && !IS_VALID_CASTER(i))
- {
- continue;
- }
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (!IS_VALID_INFECTED(i) && !IS_VALID_CASTER(i))
+ {
+ continue;
+ }
- CPrintToChat(i, "{default}%s", sPrint);
- }
+ CPrintToChat(i, "{default}%s", sPrint);
+ }
}
/**
* Adds steam ids for a particular team to an array.
- *
+ *
* @ param Handle:steamIds
* The array steam ids will be added to.
* @param L4D2Team:team
* The team to get steam ids for.
*/
-
public void addTeamSteamIdsToArray(ArrayList steamIds, L4D2Team team)
{
- char steamId[64];
+ char steamId[64];
- for (int i = 1; i <= MaxClients; i++)
- {
- // Basic check
- if (IsClientInGame(i) && ! IsFakeClient(i))
- {
- // Checking if on our desired team
- if (view_as(GetClientTeam(i)) != team)
- continue;
-
- GetClientAuthId(i, AuthId_Steam2, steamId, sizeof(steamId));
- PushArrayString(steamIds, steamId);
- }
- }
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ // Basic check
+ if (IsClientInGame(i) && !IsFakeClient(i))
+ {
+ // Checking if on our desired team
+ if (view_as(GetClientTeam(i)) != team)
+ continue;
+
+ GetClientAuthId(i, AuthId_Steam2, steamId, sizeof(steamId));
+ PushArrayString(steamIds, steamId);
+ }
+ }
}
/**
* Removes steam ids from the tank pool if they've already had tank.
- *
+ *
* @param Handle:steamIdTankPool
* The pool of potential steam ids to become tank.
* @ param Handle:tanks
* The steam ids of players who've already had tank.
- *
+ *
* @return
* The pool of steam ids who haven't had tank.
*/
-
public void removeTanksFromPool(ArrayList steamIdTankPool, ArrayList tanks)
{
- int index;
- char steamId[64];
-
- int ArraySize = GetArraySize(tanks);
- for (int i = 0; i < ArraySize; i++)
- {
- GetArrayString(tanks, i, steamId, sizeof(steamId));
- index = FindStringInArray(steamIdTankPool, steamId);
-
- if (index != -1)
- {
- RemoveFromArray(steamIdTankPool, index);
- }
- }
+ int index;
+ char steamId[64];
+
+ int ArraySize = GetArraySize(tanks);
+ for (int i = 0; i < ArraySize; i++)
+ {
+ GetArrayString(tanks, i, steamId, sizeof(steamId));
+ index = FindStringInArray(steamIdTankPool, steamId);
+
+ if (index != -1)
+ {
+ RemoveFromArray(steamIdTankPool, index);
+ }
+ }
}
/**
* Retrieves a player's client index by their steam id.
- *
+ *
* @param const String:steamId[]
* The steam id to look for.
- *
+ *
* @return
* The player's client index.
*/
-
-public int getInfectedPlayerBySteamId(const char[] steamId)
+public int getInfectedPlayerBySteamId(const char[] steamId)
{
- char tmpSteamId[64];
-
- for (int i = 1; i <= MaxClients; i++)
- {
- if (!IsClientInGame(i) || GetClientTeam(i) != 3)
- continue;
-
- GetClientAuthId(i, AuthId_Steam2, tmpSteamId, sizeof(tmpSteamId));
-
- if (strcmp(steamId, tmpSteamId) == 0)
- return i;
- }
-
- return -1;
+ char tmpSteamId[64];
+
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (!IsClientInGame(i) || GetClientTeam(i) != 3)
+ continue;
+
+ GetClientAuthId(i, AuthId_Steam2, tmpSteamId, sizeof(tmpSteamId));
+
+ if (strcmp(steamId, tmpSteamId) == 0)
+ return i;
+ }
+
+ return -1;
}
-void SetTankFrustration(int iTankClient, int iFrustration) {
- if (iFrustration < 0 || iFrustration > 100) {
- return;
- }
-
- SetEntProp(iTankClient, Prop_Send, "m_frustration", 100-iFrustration);
+void SetTankFrustration(int iTankClient, int iFrustration)
+{
+ if (iFrustration < 0 || iFrustration > 100)
+ {
+ return;
+ }
+
+ SetEntProp(iTankClient, Prop_Send, "m_frustration", 100 - iFrustration);
}
\ No newline at end of file
diff --git a/addons/sourcemod/scripting/l4d_tank_damage_announce.sp b/addons/sourcemod/scripting/l4d_tank_damage_announce.sp
index 4eee5f62a..7632442a3 100644
--- a/addons/sourcemod/scripting/l4d_tank_damage_announce.sp
+++ b/addons/sourcemod/scripting/l4d_tank_damage_announce.sp
@@ -1,39 +1,45 @@
/* L4D_TANK_DAMAGE_ANNOUNCE
-* L4D_TANK_DAMAGE_ANNOUNCE
-*/
+ * L4D_TANK_DAMAGE_ANNOUNCE
+ */
#pragma semicolon 1
-#include
-#include
#include
+#include
+#include
-new const TEAM_SURVIVOR = 2;
-new const TEAM_INFECTED = 3;
-new const ZOMBIECLASS_TANK = 8; // Zombie class of the tank, used to find tank after he have been passed to another player
-new bool: g_bEnabled = true;
-new bool: g_bAnnounceTankDamage = false; // Whether or not tank damage should be announced
-new bool: g_bIsTankInPlay = false; // Whether or not the tank is active
-new bool: bPrintedHealth = false; // Is Remaining Health showed?
-new g_iWasTank[MAXPLAYERS + 1] = {0, ...}; // Was Player Tank before he died.
-new g_iWasTankAI = 0;
-new g_iOffset_Incapacitated = 0; // Used to check if tank is dying
-new g_iTankClient = 0; // Which client is currently playing as tank
-new g_iLastTankHealth = 0; // Used to award the killing blow the exact right amount of damage
-new g_iSurvivorLimit = 4; // For survivor array in damage print
-new g_iDamage[MAXPLAYERS + 1];
-new Float: g_fMaxTankHealth = 6000.0;
-new Handle: g_hCvarEnabled = INVALID_HANDLE;
-new Handle: g_hCvarTankHealth = INVALID_HANDLE;
-new Handle: g_hCvarDifficulty = INVALID_HANDLE;
-new Handle: g_hCvarSurvivorLimit = INVALID_HANDLE;
-new Handle:fwdOnTankDeath = INVALID_HANDLE;
+#define TEAM_SURVIVOR 2
+#define TEAM_INFECTED 3
+#define ZOMBIECLASS_TANK 8 // Zombie class of the tank, used to find tank after he have been passed to another player
+
+bool
+ g_bEnabled = true,
+ g_bAnnounceTankDamage = false, // Whether or not tank damage should be announced
+ g_bIsTankInPlay = false, // Whether or not the tank is active
+ bPrintedHealth = false; // Is Remaining Health showed?
+int
+ g_iWasTank[MAXPLAYERS + 1] = { 0, ... }, // Was Player Tank before he died.
+ g_iWasTankAI = 0,
+ g_iOffset_Incapacitated = 0, // Used to check if tank is dying
+ g_iTankClient = 0, // Which client is currently playing as tank
+ g_iLastTankHealth = 0, // Used to award the killing blow the exact right amount of damage
+ g_iSurvivorLimit = 4, // For survivor array in damage print
+ g_iDamage[MAXPLAYERS + 1];
+float
+ g_fMaxTankHealth = 6000.0;
+ConVar
+ g_cvarEnabled,
+ g_cvarTankHealth,
+ g_cvarDifficulty,
+ g_cvarSurvivorLimit;
+Handle
+ fwdOnTankDeath = INVALID_HANDLE;
/*
* Version 0.6.6
* - Better looking Output.
* - Added Tank Name display when Tank dies, normally it only showed the Tank's name if the Tank survived
-*
+*
* Version 0.6.6b
* - Fixed Printing Two Tanks when last map Tank survived.
* Added by; Sir
@@ -41,46 +47,61 @@ new Handle:fwdOnTankDeath = INVALID_HANDLE;
* Version 0.6.7
* - Added Campaign Difficulty Support.
* Added by; Sir
-*/
-
-public Plugin:myinfo =
-{
- name = "Tank Damage Announce L4D2",
- author = "Griffin and Blade",
+*/
+public Plugin myinfo = {
+ name = "Tank Damage Announce L4D2",
+ author = "Griffin and Blade",
description = "Announce damage dealt to tanks by survivors",
- version = "0.6.7",
+ version = "0.6.7",
}
-public OnPluginStart()
+public void OnPluginStart()
{
- g_bIsTankInPlay = false;
+ LoadTranslation("l4d_tank_damage_announce.phrases");
+ g_bIsTankInPlay = false;
g_bAnnounceTankDamage = false;
- g_iTankClient = 0;
+ g_iTankClient = 0;
ClearTankDamage();
HookEvent("tank_spawn", Event_TankSpawn);
HookEvent("player_death", Event_PlayerKilled);
HookEvent("round_start", Event_RoundStart);
HookEvent("round_end", Event_RoundEnd);
HookEvent("player_hurt", Event_PlayerHurt);
-
- g_hCvarEnabled = CreateConVar("l4d_tankdamage_enabled", "1", "Announce damage done to tanks when enabled", FCVAR_NONE|FCVAR_SPONLY|FCVAR_NOTIFY, true, 0.0, true, 1.0);
- g_hCvarSurvivorLimit = FindConVar("survivor_limit");
- g_hCvarTankHealth = FindConVar("z_tank_health");
- g_hCvarDifficulty = FindConVar("z_difficulty");
-
- HookConVarChange(g_hCvarEnabled, Cvar_Enabled);
- HookConVarChange(g_hCvarSurvivorLimit, Cvar_SurvivorLimit);
- HookConVarChange(g_hCvarTankHealth, Cvar_TankHealth);
- HookConVarChange(g_hCvarDifficulty, Cvar_TankHealth);
+
+ g_cvarEnabled = CreateConVar("l4d_tankdamage_enabled", "1", "Announce damage done to tanks when enabled", FCVAR_NONE | FCVAR_SPONLY | FCVAR_NOTIFY, true, 0.0, true, 1.0);
+ g_cvarSurvivorLimit = FindConVar("survivor_limit");
+ g_cvarTankHealth = FindConVar("z_tank_health");
+ g_cvarDifficulty = FindConVar("z_difficulty");
+
+ HookConVarChange(g_cvarEnabled, Cvar_Enabled);
+ HookConVarChange(g_cvarSurvivorLimit, Cvar_SurvivorLimit);
+ HookConVarChange(g_cvarTankHealth, Cvar_TankHealth);
+ HookConVarChange(g_cvarDifficulty, Cvar_TankHealth);
HookConVarChange(FindConVar("mp_gamemode"), Cvar_TankHealth);
- g_bEnabled = GetConVarBool(g_hCvarEnabled);
+
+ g_bEnabled = g_cvarEnabled.BoolValue;
CalculateTankHealth();
-
+
g_iOffset_Incapacitated = FindSendPropInfo("Tank", "m_isIncapacitated");
- fwdOnTankDeath = CreateGlobalForward("OnTankDeath", ET_Event);
+ fwdOnTankDeath = CreateGlobalForward("OnTankDeath", ET_Event);
}
-public OnMapStart()
+void LoadTranslation(char[] sTranslation)
+{
+ char
+ sPath[PLATFORM_MAX_PATH],
+ sName[64];
+
+ Format(sName, sizeof(sName), "translations/%s.txt", sTranslation);
+ BuildPath(Path_SM, sPath, sizeof(sPath), sName);
+ if (!FileExists(sPath))
+ {
+ SetFailState("Missing translation file %s.txt", sTranslation);
+ }
+ LoadTranslations(sTranslation);
+}
+
+public void OnMapStart()
{
// In cases where a tank spawns and map is changed manually, bypassing round end
ClearTankDamage();
@@ -88,33 +109,33 @@ public OnMapStart()
PrecacheSound("ui/pickup_secret01.wav");
}
-public OnClientDisconnect_Post(client)
+public void OnClientDisconnect_Post(int client)
{
if (!g_bIsTankInPlay || client != g_iTankClient) return;
- CreateTimer(0.1, Timer_CheckTank, client); // Use a delayed timer due to bugs where the tank passes to another player
+ CreateTimer(0.1, Timer_CheckTank, client); // Use a delayed timer due to bugs where the tank passes to another player
}
-public Cvar_Enabled(Handle:convar, const String:oldValue[], const String:newValue[])
+public void Cvar_Enabled(Handle convar, const char[] oldValue, const char[] newValue)
{
- g_bEnabled = StringToInt(newValue) > 0 ? true:false;
+ g_bEnabled = StringToInt(newValue) > 0 ? true : false;
}
-public Cvar_SurvivorLimit(Handle:convar, const String:oldValue[], const String:newValue[])
+public void Cvar_SurvivorLimit(Handle convar, const char[] oldValue, const char[] newValue)
{
g_iSurvivorLimit = StringToInt(newValue);
}
-public Cvar_TankHealth(Handle:convar, const String:oldValue[], const String:newValue[])
+public void Cvar_TankHealth(Handle convar, const char[] oldValue, const char[] newValue)
{
CalculateTankHealth();
}
-CalculateTankHealth()
+void CalculateTankHealth()
{
- new String:sGameMode[32];
+ char sGameMode[32];
GetConVarString(FindConVar("mp_gamemode"), sGameMode, sizeof(sGameMode));
- g_fMaxTankHealth = GetConVarFloat(g_hCvarTankHealth);
+ g_fMaxTankHealth = g_cvarTankHealth.FloatValue;
if (g_fMaxTankHealth <= 0.0) g_fMaxTankHealth = 1.0;
// Versus or Realism Versus
@@ -122,85 +143,86 @@ CalculateTankHealth()
g_fMaxTankHealth *= 1.5;
// Anything else (should be fine...?)
- else
+ else
{
- g_fMaxTankHealth = GetConVarFloat(g_hCvarTankHealth);
+ g_fMaxTankHealth = g_cvarTankHealth.FloatValue;
char sDifficulty[16];
- GetConVarString(g_hCvarDifficulty, sDifficulty, sizeof(sDifficulty));
+ GetConVarString(g_cvarDifficulty, sDifficulty, sizeof(sDifficulty));
- if (sDifficulty[0] == 'E') g_fMaxTankHealth *= 0.75; // Easy
+ if (sDifficulty[0] == 'E') g_fMaxTankHealth *= 0.75; // Easy
else if (sDifficulty[0] == 'H'
- || sDifficulty[0] == 'I') g_fMaxTankHealth *= 2.0; // Advanced or Expert
+ || sDifficulty[0] == 'I') g_fMaxTankHealth *= 2.0; // Advanced or Expert
}
}
-public Event_PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
+public void Event_PlayerHurt(Handle event, const char[] name, bool dontBroadcast)
{
- if (!g_bIsTankInPlay) return; // No tank in play; no damage to record
-
- new victim = GetClientOfUserId(GetEventInt(event, "userid"));
- if (victim != GetTankClient() || // Victim isn't tank; no damage to record
- IsTankDying() // Something buggy happens when tank is dying with regards to damage
- ) return;
-
- new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
+ if (!g_bIsTankInPlay)
+ return; // No tank in play; no damage to record
+
+ int victim = GetClientOfUserId(GetEventInt(event, "userid"));
+ if (victim != GetTankClient() || IsTankDying())
+ return;
+
+ int attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
// We only care about damage dealt by survivors, though it can be funny to see
// claw/self inflicted hittable damage, so maybe in the future we'll do that
- if (attacker == 0 || // Damage from world?
- !IsClientInGame(attacker) || // Not sure if this happens
- GetClientTeam(attacker) != TEAM_SURVIVOR
- ) return;
-
+ if (attacker == 0 || !IsClientInGame(attacker) || GetClientTeam(attacker) != TEAM_SURVIVOR)
+ return;
+
g_iDamage[attacker] += GetEventInt(event, "dmg_health");
g_iLastTankHealth = GetEventInt(event, "health");
}
-public Event_PlayerKilled(Handle:event, const String:name[], bool:dontBroadcast)
+public void Event_PlayerKilled(Handle event, const char[] name, bool dontBroadcast)
{
- if (!g_bIsTankInPlay) return; // No tank in play; no damage to record
-
- new victim = GetClientOfUserId(GetEventInt(event, "userid"));
- if (victim != g_iTankClient) return;
-
+ if (!g_bIsTankInPlay)
+ return; // No tank in play; no damage to record
+
+ int victim = GetClientOfUserId(GetEventInt(event, "userid"));
+ if (victim != g_iTankClient)
+ return;
+
// Award the killing blow's damage to the attacker; we don't award
// damage from player_hurt after the tank has died/is dying
// If we don't do it this way, we get wonky/inaccurate damage values
- new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
+ int attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
if (attacker && IsClientInGame(attacker)) g_iDamage[attacker] += g_iLastTankHealth;
-
- //Player was Tank
- if(!IsFakeClient(victim)) g_iWasTank[victim] = 1;
+
+ // Player was Tank
+ if (!IsFakeClient(victim)) g_iWasTank[victim] = 1;
else g_iWasTankAI = 1;
// Damage announce could probably happen right here...
- CreateTimer(0.1, Timer_CheckTank, victim); // Use a delayed timer due to bugs where the tank passes to another player
+ CreateTimer(0.1, Timer_CheckTank, victim); // Use a delayed timer due to bugs where the tank passes to another player
}
-public Event_TankSpawn(Handle:event, const String:name[], bool:dontBroadcast)
+public void Event_TankSpawn(Handle event, const char[] name, bool dontBroadcast)
{
- new client = GetClientOfUserId(GetEventInt(event, "userid"));
+ int client = GetClientOfUserId(GetEventInt(event, "userid"));
g_iTankClient = client;
-
- if (g_bIsTankInPlay) return; // Tank passed
-
+
+ if (g_bIsTankInPlay)
+ return; // Tank passed
+
EmitSoundToAll("ui/pickup_secret01.wav", _, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, 0.8);
// New tank, damage has not been announced
g_bAnnounceTankDamage = true;
- g_bIsTankInPlay = true;
+ g_bIsTankInPlay = true;
// Set health for damage print in case it doesn't get set by player_hurt (aka no one shoots the tank)
- g_iLastTankHealth = GetClientHealth(client);
+ g_iLastTankHealth = GetClientHealth(client);
}
-public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
+public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
{
- bPrintedHealth = false;
+ bPrintedHealth = false;
g_bIsTankInPlay = false;
- g_iTankClient = 0;
- ClearTankDamage(); // Probably redundant
+ g_iTankClient = 0;
+ ClearTankDamage(); // Probably redundant
}
// When survivors wipe or juke tank, announce damage
-public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
+public void Event_RoundEnd(Handle event, const char[] name, bool dontBroadcast)
{
// But only if a tank that hasn't been killed exists
if (g_bAnnounceTankDamage)
@@ -211,164 +233,177 @@ public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
ClearTankDamage();
}
-public Action:Timer_CheckTank(Handle:timer, any:oldtankclient)
+public Action Timer_CheckTank(Handle timer, int oldtankclient)
{
- if (g_iTankClient != oldtankclient) return; // Tank passed
-
- new tankclient = FindTankClient();
+ if (g_iTankClient != oldtankclient)
+ return Plugin_Continue; // Tank passed
+
+ int tankclient = FindTankClient();
if (tankclient && tankclient != oldtankclient)
{
g_iTankClient = tankclient;
-
- return; // Found tank, done
+ return Plugin_Continue; // Found tank, done
}
-
- if (g_bAnnounceTankDamage) PrintTankDamage();
+
+ if (g_bAnnounceTankDamage)
+ PrintTankDamage();
ClearTankDamage();
- g_bIsTankInPlay = false; // No tank in play
+ g_bIsTankInPlay = false; // No tank in play
Call_StartForward(fwdOnTankDeath);
Call_Finish();
+ return Plugin_Continue;
}
-bool:IsTankDying()
+bool IsTankDying()
{
- new tankclient = GetTankClient();
- if (!tankclient) return false;
+ int tankclient = GetTankClient();
+ if (!tankclient)
+ return false;
- return bool:GetEntData(tankclient, g_iOffset_Incapacitated);
+ return view_as(GetEntData(tankclient, g_iOffset_Incapacitated));
}
-PrintRemainingHealth()
+void PrintRemainingHealth()
{
bPrintedHealth = true;
- if (!g_bEnabled) return;
- new tankclient = GetTankClient();
- if (!tankclient) return;
-
- decl String:name[MAX_NAME_LENGTH];
- if (IsFakeClient(tankclient)) name = "AI";
- else GetClientName(tankclient, name, sizeof(name));
- CPrintToChatAll("{default}[{green}!{default}] {blue}Tank {default}({olive}%s{default}) had {green}%d {default}health remaining", name, g_iLastTankHealth);
+ if (!g_bEnabled)
+ return;
+ int tankclient = GetTankClient();
+ if (!tankclient)
+ return;
+
+ char
+ sName[MAX_NAME_LENGTH],
+ sIAName[8];
+ Format(sIAName, sizeof(sIAName), "%t", "AI");
+ GetClientName(tankclient, sName, sizeof(sName));
+ CPrintToChatAll("%t %t", "Tag", "HealthRemaining", IsFakeClient(tankclient) ? sIAName : sName, g_iLastTankHealth);
}
-PrintTankDamage()
+void PrintTankDamage()
{
- if (!g_bEnabled) return;
-
+ if (!g_bEnabled)
+ return;
+
if (!bPrintedHealth)
{
- for (new i = 1; i <= MaxClients; i++)
+ for (int i = 1; i <= MaxClients; i++)
{
- if(g_iWasTank[i] > 0)
+ if (g_iWasTank[i] > 0)
{
- decl String:name[MAX_NAME_LENGTH];
- GetClientName(i, name, sizeof(name));
- CPrintToChatAll("{default}[{green}!{default}] {blue}Damage {default}dealt to {blue}Tank {default}({olive}%s{default})", name);
+ char sName[MAX_NAME_LENGTH];
+ GetClientName(i, sName, sizeof(sName));
+ CPrintToChatAll("%t %t", "Tag", "DealtToTank", sName);
g_iWasTank[i] = 0;
}
- else if(g_iWasTankAI > 0)
- CPrintToChatAll("{default}[{green}!{default}] {blue}Damage {default}dealt to {blue}Tank {default}({olive}AI{default})");
+ else if (g_iWasTankAI > 0)
+ {
+ char sIAName[8];
+ Format(sIAName, sizeof(sIAName), "%t", "AI");
+ CPrintToChatAll("%t %t", "Tag", "DealtToTank", sIAName);
+ }
g_iWasTankAI = 0;
}
}
-
- new client;
- new percent_total; // Accumulated total of calculated percents, for fudging out numbers at the end
- new damage_total; // Accumulated total damage dealt by survivors, to see if we need to fudge upwards to 100%
- new survivor_index = -1;
- new survivor_clients[g_iSurvivorLimit]; // Array to store survivor client indexes in, for the display iteration
- decl percent_damage, damage;
+
+ int
+ client,
+ percent_total, // Accumulated total of calculated percents, for fudging out numbers at the end
+ damage_total, // Accumulated total damage dealt by survivors, to see if we need to fudge upwards to 100%
+ survivor_index = -1,
+ percent_damage,
+ damage;
+ int[] survivor_clients = new int[g_iSurvivorLimit]; // Array to store survivor client indexes in, for the display iteration
for (client = 1; client <= MaxClients; client++)
{
if (!IsClientInGame(client) || GetClientTeam(client) != TEAM_SURVIVOR || g_iDamage[client] == 0) continue;
survivor_index++;
survivor_clients[survivor_index] = client;
- damage = g_iDamage[client];
+ damage = g_iDamage[client];
damage_total += damage;
percent_damage = GetDamageAsPercent(damage);
percent_total += percent_damage;
}
SortCustom1D(survivor_clients, g_iSurvivorLimit, SortByDamageDesc);
-
- new percent_adjustment;
+
+ int percent_adjustment;
// Percents add up to less than 100% AND > 99.5% damage was dealt to tank
if ((percent_total < 100 && float(damage_total) > (g_fMaxTankHealth - (g_fMaxTankHealth / 200.0))))
{
percent_adjustment = 100 - percent_total;
}
-
- new last_percent = 100; // Used to store the last percent in iteration to make sure an adjusted percent doesn't exceed the previous percent
- decl adjusted_percent_damage;
- for (new k; k <= survivor_index; k++)
+
+ int
+ last_percent = 100, // Used to store the last percent in iteration to make sure an adjusted percent doesn't exceed the previous percent
+ adjusted_percent_damage;
+ for (int k; k <= survivor_index; k++)
{
- client = survivor_clients[k];
- damage = g_iDamage[client];
+ client = survivor_clients[k];
+ damage = g_iDamage[client];
percent_damage = GetDamageAsPercent(damage);
// Attempt to adjust the top damager's percent, defer adjustment to next player if it's an exact percent
// e.g. 3000 damage on 6k health tank shouldn't be adjusted
- if (percent_adjustment != 0 && // Is there percent to adjust
- damage > 0 && // Is damage dealt > 0%
- !IsExactPercent(damage) // Percent representation is not exact, e.g. 3000 damage on 6k tank = 50%
+ if (percent_adjustment != 0 && // Is there percent to adjust
+ damage > 0 && // Is damage dealt > 0%
+ !IsExactPercent(damage) // Percent representation is not exact, e.g. 3000 damage on 6k tank = 50%
)
{
adjusted_percent_damage = percent_damage + percent_adjustment;
- if (adjusted_percent_damage <= last_percent) // Make sure adjusted percent is not higher than previous percent, order must be maintained
+ if (adjusted_percent_damage <= last_percent) // Make sure adjusted percent is not higher than previous percent, order must be maintained
{
- percent_damage = adjusted_percent_damage;
+ percent_damage = adjusted_percent_damage;
percent_adjustment = 0;
}
}
last_percent = percent_damage;
- for (new i = 1; i <= MaxClients; i++)
+ for (int i = 1; i <= MaxClients; i++)
{
- if (IsClientInGame(i))
- {
- CPrintToChat(i, "{blue}[{default}%d{blue}] ({default}%i%%{blue}) {olive}%N", damage, percent_damage, client);
+ if (IsClientInGame(i))
+ {
+ CPrintToChat(i, "%t", "PercentDamage", damage, percent_damage, client);
}
}
}
}
-ClearTankDamage()
+void ClearTankDamage()
{
g_iLastTankHealth = 0;
- g_iWasTankAI = 0;
- for (new i = 1; i <= MaxClients; i++)
- {
- g_iDamage[i] = 0;
+ g_iWasTankAI = 0;
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ g_iDamage[i] = 0;
g_iWasTank[i] = 0;
}
g_bAnnounceTankDamage = false;
}
-
-GetTankClient()
+int GetTankClient()
{
- if (!g_bIsTankInPlay) return 0;
-
- new tankclient = g_iTankClient;
-
- if (!IsClientInGame(tankclient)) // If tank somehow is no longer in the game (kicked, hence events didn't fire)
+ if (!g_bIsTankInPlay)
+ return 0;
+
+ int tankclient = g_iTankClient;
+
+ if (!IsClientInGame(tankclient)) // If tank somehow is no longer in the game (kicked, hence events didn't fire)
{
- tankclient = FindTankClient(); // find the tank client
- if (!tankclient) return 0;
+ tankclient = FindTankClient(); // find the tank client
+ if (!tankclient)
+ return 0;
g_iTankClient = tankclient;
}
-
+
return tankclient;
}
-FindTankClient()
+int FindTankClient()
{
- for (new client = 1; client <= MaxClients; client++)
+ for (int client = 1; client <= MaxClients; client++)
{
- if (!IsClientInGame(client) ||
- GetClientTeam(client) != TEAM_INFECTED ||
- !IsPlayerAlive(client) ||
- GetEntProp(client, Prop_Send, "m_zombieClass") != ZOMBIECLASS_TANK)
- continue;
-
- return client; // Found tank, return
+ if (!IsClientInGame(client) || GetClientTeam(client) != TEAM_INFECTED || !IsPlayerAlive(client) || GetEntProp(client, Prop_Send, "m_zombieClass") != ZOMBIECLASS_TANK)
+ continue;
+
+ return client; // Found tank, return
}
return 0;
}
@@ -378,15 +413,15 @@ int GetDamageAsPercent(int damage)
return RoundToNearest((damage / g_fMaxTankHealth) * 100.0);
}
-//comparing the type of int with the float, how different is it
+// comparing the type of int with the float, how different is it
bool IsExactPercent(int damage)
{
float fDamageAsPercent = (damage / g_fMaxTankHealth) * 100.0;
- float fDifference = float(GetDamageAsPercent(damage)) - fDamageAsPercent;
+ float fDifference = float(GetDamageAsPercent(damage)) - fDamageAsPercent;
return (FloatAbs(fDifference) < 0.001) ? true : false;
}
-public SortByDamageDesc(elem1, elem2, const array[], Handle:hndl)
+public int SortByDamageDesc(elem1, elem2, const array[], Handle hndl)
{
// By damage, then by client index, descending
if (g_iDamage[elem1] > g_iDamage[elem2]) return -1;
diff --git a/addons/sourcemod/scripting/nodeathcamskip.sp b/addons/sourcemod/scripting/nodeathcamskip.sp
index ba09f183d..96bdd8f45 100644
--- a/addons/sourcemod/scripting/nodeathcamskip.sp
+++ b/addons/sourcemod/scripting/nodeathcamskip.sp
@@ -44,23 +44,23 @@ public Action Listener_Join(int client, const char[] command, int argc) {
if (GetInfectedPlayers() == (FindConVar("z_max_player_zombies")).IntValue) { return Plugin_Handled; }
if (Blocked[client]) {
-
+
// Warn Others.
if (!bSkipPrint[client])
{
- CPrintToChatAll("{red}[{default}Exploit{red}] {olive}%N {default}tried skipping the Death Timer.", client);
+ CPrintToChatAll("%t %t", "Tag", "DeathTimer", client);
bSkipPrint[client] = true;
}
// Tell Offender.
- CPrintToChat(client, "{red}[{default}Exploit{red}] {default}You will be unable to join the Team for {red}%.1f {default}Seconds.", (fSavedTime[client] + 6.0) - GetGameTime());
- CPrintToChat(client, "{red}[{default}Exploit{red}] {default}You will be moved automatically.");
+ CPrintToChat(client, "%t %t", "Tag", "UnableToJoin", (fSavedTime[client] + 6.0) - GetGameTime());
+ CPrintToChat(client, "%t %t", "Tag", "Moved");
return Plugin_Handled;
}
if (GetInfectedPlayers() + GetBlockedPlayers() == (FindConVar("z_max_player_zombies").IntValue)) {
- CPrintToChat(client, "{red}[{default}!{red}] {default}This team currently has slots {olive}reserved{default}.");
+ CPrintToChat(client, "%t %t", "Tag", "SlotsReserved");
return Plugin_Handled;
}
}
diff --git a/addons/sourcemod/scripting/pause.sp b/addons/sourcemod/scripting/pause.sp
index d4f2166ba..101b904a3 100644
--- a/addons/sourcemod/scripting/pause.sp
+++ b/addons/sourcemod/scripting/pause.sp
@@ -240,8 +240,14 @@ public Action Pause_Cmd(int client, int args)
initiatorId = GetClientUserId(client);
pauseTeam = GetClientTeam(client);
GetClientName(client, initiatorName, sizeof(initiatorName));
-
- CPrintToChatAll("%t %t", "Tag", "PauseCommand", client);
+
+ char sPauseCount[64] = ".";
+ if(pauseLimitCvar.IntValue > 0)
+ {
+ Format(sPauseCount, sizeof(sPauseCount), "%t", "PauseCountFormat", PauseCount(client), pauseLimitCvar.IntValue);
+ }
+
+ CPrintToChatAll("%t %t", "Tag", "PauseCommand", client, sPauseCount);
pauseDelay = pauseDelayCvar.IntValue;
if (pauseDelay == 0)
@@ -424,7 +430,7 @@ bool AddPauseCount(int client)
if (pauseLimit > 0 && pauseCount >= pauseLimit)
{
- CPrintToChat(client, "%t %t", "Tag", "PauseLimit");
+ CPrintToChat(client, "%t %t", "Tag", "PauseLimit", pauseLimit);
return false;
}
@@ -434,6 +440,16 @@ bool AddPauseCount(int client)
return true;
}
+int PauseCount(int client)
+{
+ char authId[18];
+ GetClientAuthId(client, AuthId_SteamID64, authId, 18, false);
+ int pauseCount = 0;
+ playerPauseCount.GetValue(authId, pauseCount);
+
+ return pauseCount;
+}
+
void AttemptPause()
{
if (deferredPauseTimer == null)
diff --git a/addons/sourcemod/scripting/readyup.sp b/addons/sourcemod/scripting/readyup.sp
index f1398729b..29a8fcd27 100644
--- a/addons/sourcemod/scripting/readyup.sp
+++ b/addons/sourcemod/scripting/readyup.sp
@@ -9,7 +9,7 @@
#undef REQUIRE_PLUGIN
#include
-#define PLUGIN_VERSION "10.2.3"
+#define PLUGIN_VERSION "10.2.4"
public Plugin myinfo =
{
@@ -80,7 +80,7 @@ ConVar
// sound
l4d_ready_enable_sound, l4d_ready_notify_sound, l4d_ready_countdown_sound, l4d_ready_live_sound, l4d_ready_autostart_sound, l4d_ready_chuckle, l4d_ready_secret,
// action
- l4d_ready_delay, l4d_ready_force_extra, l4d_ready_autostart_delay, l4d_ready_autostart_wait, l4d_ready_autostart_min, l4d_ready_unbalanced_start, l4d_ready_unbalanced_min;
+ l4d_ready_delay, l4d_ready_force_extra, l4d_ready_autostart_delay, l4d_ready_autostart_wait, l4d_ready_autostart_min, l4d_ready_unbalanced_start, l4d_ready_unbalanced_min, l4d_ready_unready_limit;
// Server Name
ConVar
@@ -129,6 +129,9 @@ char g_sDisruptReason[disruptType_SIZE][] =
"Admin aborted"
};
+// Limit Cancel Ready
+StringMap playerunReadyCount;
+
// Sub modules are included here
#include "readyup/action.inc"
#include "readyup/command.inc"
@@ -158,6 +161,7 @@ public void OnPluginStart()
SetupConVars();
SetupCommands();
+ playerunReadyCount = new StringMap();
nativeFooter = new Footer();
readySurvFreeze = l4d_ready_survivor_freeze.BoolValue;
@@ -383,6 +387,13 @@ public Action L4D_OnFirstSurvivorLeftSafeArea(int client)
ReturnPlayerToSaferoom(client, false);
return Plugin_Handled;
}
+ else
+ {
+ if(l4d_ready_unready_limit.IntValue > 0)
+ {
+ playerunReadyCount.Clear();
+ }
+ }
return Plugin_Continue;
}
diff --git a/addons/sourcemod/scripting/readyup/action.inc b/addons/sourcemod/scripting/readyup/action.inc
index c1c3847f7..d446c2307 100644
--- a/addons/sourcemod/scripting/readyup/action.inc
+++ b/addons/sourcemod/scripting/readyup/action.inc
@@ -232,16 +232,43 @@ void CancelFullReady(int client, disruptType type)
if (s_readyCountdownTimer != null)
{
- delete s_readyCountdownTimer;
- InitiateReadyUp(false);
-
- SetTeamFrozen(L4D2Team_Survivor, l4d_ready_survivor_freeze.BoolValue);
- if (type == teamShuffle) // fix spectating
- SetClientFrozen(client, false);
-
- PrintHintTextToAll("%t", "LiveCountdownCancelled");
- CPrintToChatAllEx(client, "%t", g_sDisruptReason[type], client);
+ if(l4d_ready_unready_limit.IntValue > 0 && type == readyStatus)
+ {
+ if (!AddUnReadyCount(client))
+ return;
+
+ delete s_readyCountdownTimer;
+ InitiateReadyUp(false);
+
+ SetTeamFrozen(L4D2Team_Survivor, l4d_ready_survivor_freeze.BoolValue);
+ if (type == teamShuffle) // fix spectating
+ SetClientFrozen(client, false);
+
+ char sbuffer[64] = "";
+ Format(sbuffer, sizeof(sbuffer), "%t", "CountUnReady", GetUnReadyCount(client), l4d_ready_unready_limit.IntValue);
+ PrintHintTextToAll("%t", "LiveCountdownCancelled");
+ CPrintToChatAllEx(client, "%t %t", "Tag", g_sDisruptReason[type], client, sbuffer);
+ }
+ else
+ {
+ delete s_readyCountdownTimer;
+ InitiateReadyUp(false);
+
+ SetTeamFrozen(L4D2Team_Survivor, l4d_ready_survivor_freeze.BoolValue);
+ if (type == teamShuffle) // fix spectating
+ SetClientFrozen(client, false);
+
+ PrintHintTextToAll("%t", "LiveCountdownCancelled");
+ if(type == readyStatus)
+ {
+ CPrintToChatAllEx(client, "%t %t", "Tag", g_sDisruptReason[type], client, "");
+ }
+ else
+ {
+ CPrintToChatAllEx(client, "%t %t", "Tag", g_sDisruptReason[type], client);
+ }
+ }
if (g_hCountdownCancelledForward.FunctionCount)
{
Call_StartForward(g_hCountdownCancelledForward);
@@ -249,5 +276,36 @@ void CancelFullReady(int client, disruptType type)
Call_PushString(g_sDisruptReason[type]);
Call_Finish();
}
+
}
}
+
+bool AddUnReadyCount(int client)
+{
+ char authId[18];
+ GetClientAuthId(client, AuthId_SteamID64, authId, 18, false);
+ int unReadyCount = 0;
+ int unReadyLimit = l4d_ready_unready_limit.IntValue;
+ playerunReadyCount.GetValue(authId, unReadyCount);
+
+ if (unReadyLimit > 0 && unReadyCount >= unReadyLimit)
+ {
+ CPrintToChat(client, "%t %t", "Tag", "UnReadyLimit", unReadyLimit);
+ return false;
+ }
+
+ unReadyCount++;
+ playerunReadyCount.SetValue(authId, unReadyCount);
+
+ return true;
+}
+
+int GetUnReadyCount(int client)
+{
+ char authId[18];
+ GetClientAuthId(client, AuthId_SteamID64, authId, 18, false);
+ int unReadyCount = 0;
+ playerunReadyCount.GetValue(authId, unReadyCount);
+
+ return unReadyCount;
+}
\ No newline at end of file
diff --git a/addons/sourcemod/scripting/readyup/command.inc b/addons/sourcemod/scripting/readyup/command.inc
index 3dababd63..9c980645f 100644
--- a/addons/sourcemod/scripting/readyup/command.inc
+++ b/addons/sourcemod/scripting/readyup/command.inc
@@ -92,7 +92,7 @@ Action ForceStart_Cmd(int client, int args)
{
isForceStart = true;
InitiateLiveCountdown();
- CPrintToChatAll("%t", "ForceStartAdmin", client);
+ CPrintToChatAll("%t %t", "Tag", "ForceStartAdmin", client);
return Plugin_Handled;
}
}
@@ -108,7 +108,7 @@ Action Hide_Cmd(int client, int args)
if (inReadyUp)
{
SetPlayerHiddenPanel(client, true);
- CPrintToChat(client, "%t", "PanelHide");
+ CPrintToChat(client, "%t %t", "Tag", "PanelHide");
return Plugin_Handled;
}
return Plugin_Continue;
@@ -119,7 +119,7 @@ Action Show_Cmd(int client, int args)
if (inReadyUp)
{
SetPlayerHiddenPanel(client, false);
- CPrintToChat(client, "%t", "PanelShow");
+ CPrintToChat(client, "%t %t", "Tag", "PanelShow");
return Plugin_Handled;
}
return Plugin_Continue;
diff --git a/addons/sourcemod/scripting/readyup/panel.inc b/addons/sourcemod/scripting/readyup/panel.inc
index 9f5a8b1c1..8344b7c36 100644
--- a/addons/sourcemod/scripting/readyup/panel.inc
+++ b/addons/sourcemod/scripting/readyup/panel.inc
@@ -85,15 +85,19 @@ void UpdatePanel()
g_cvServerNamer.GetString(ServerName, sizeof(ServerName));
l4d_ready_cfg_name.GetString(cfgName, sizeof(cfgName));
- Format(ServerBuffer, sizeof(ServerBuffer), "▸ Server: %s \n▸ Slots: %d/%d\n▸ Config: %s", ServerName, GetSeriousClientCount(), FindConVar("sv_maxplayers").IntValue, cfgName);
+ Format(ServerBuffer, sizeof(ServerBuffer), "%T", "PanelSlots", LANG_SERVER, ServerName, GetSeriousClientCount(), FindConVar("sv_maxplayers").IntValue, cfgName);
menuPanel.DrawText(ServerBuffer);
- FormatTime(ServerBuffer, sizeof(ServerBuffer), "▸ %m/%d/%Y - %I:%M%p");
+ // Format will be defined by sm_datetime_format
+ FormatTime(ServerBuffer, sizeof(ServerBuffer), NULL_STRING);
+ Format(ServerBuffer, sizeof(ServerBuffer), "▸ %s", ServerBuffer);
+
Format(ServerBuffer, sizeof(ServerBuffer), "%s (%02d:%02d)", ServerBuffer, iPassTime / 60, iPassTime % 60);
menuPanel.DrawText(ServerBuffer);
menuPanel.DrawText(" ");
- menuPanel.DrawText("▸ Commands:");
+ Format(ServerBuffer, sizeof(ServerBuffer), "%T", "PanelCommands", LANG_SERVER);
+ menuPanel.DrawText(ServerBuffer);
menuPanel.DrawText(FooterGet(cmdFooter, curCmd));
menuPanel.DrawText(" ");
@@ -157,7 +161,7 @@ void UpdatePanel()
{
survivorBuffer[bufLen] = '\0';
ReplaceString(survivorBuffer, sizeof(survivorBuffer), "#", "_");
- Format(nameBuf, sizeof(nameBuf), "->%d. Survivors%s", ++textCount, isTeamReadyMode ? teamReadySymbol[survivorReady] : "");
+ Format(nameBuf, sizeof(nameBuf), "%T", "PanelSurvivors", LANG_SERVER, ++textCount, isTeamReadyMode ? teamReadySymbol[survivorReady] : "");
menuPanel.DrawText(nameBuf);
menuPanel.DrawText(survivorBuffer);
}
@@ -167,7 +171,7 @@ void UpdatePanel()
{
infectedBuffer[bufLen] = '\0';
ReplaceString(infectedBuffer, sizeof(infectedBuffer), "#", "_");
- Format(nameBuf, sizeof(nameBuf), "->%d. Infected%s", ++textCount, isTeamReadyMode ? teamReadySymbol[infectedReady] : "");
+ Format(nameBuf, sizeof(nameBuf), "%T", "PanelInfected", LANG_SERVER, ++textCount, isTeamReadyMode ? teamReadySymbol[infectedReady] : "");
menuPanel.DrawText(nameBuf);
menuPanel.DrawText(infectedBuffer);
}
@@ -180,7 +184,7 @@ void UpdatePanel()
if (bufLen != 0)
{
casterBuffer[bufLen] = '\0';
- Format(nameBuf, sizeof(nameBuf), "->%d. Caster%s", ++textCount, casterCount > 1 ? "s" : "");
+ Format(nameBuf, sizeof(nameBuf), "%T", "PanelCaster", LANG_SERVER, ++textCount, casterCount > 1 ? "s" : "");
menuPanel.DrawText(nameBuf);
ReplaceString(casterBuffer, sizeof(casterBuffer), "#", "_", true);
menuPanel.DrawText(casterBuffer);
@@ -191,11 +195,11 @@ void UpdatePanel()
if (bufLen != 0)
{
specBuffer[bufLen] = '\0';
- Format(nameBuf, sizeof(nameBuf), "->%d. Spectator%s", ++textCount, specCount > 1 ? "s" : "");
+ Format(nameBuf, sizeof(nameBuf), "%T", "PanelSpectator", LANG_SERVER, ++textCount, specCount > 1 ? "s" : "");
menuPanel.DrawText(nameBuf);
ReplaceString(specBuffer, sizeof(specBuffer), "#", "_");
if (playerCount > l4d_ready_max_players.IntValue && specCount - casterCount > 1)
- FormatEx(specBuffer, sizeof(specBuffer), "**Many** (%d)", specCount - casterCount);
+ FormatEx(specBuffer, sizeof(specBuffer), "%T", "PanelMany", LANG_SERVER, specCount - casterCount);
menuPanel.DrawText(specBuffer);
}
diff --git a/addons/sourcemod/scripting/readyup/setup.inc b/addons/sourcemod/scripting/readyup/setup.inc
index fe8649c14..0b4ca4f54 100644
--- a/addons/sourcemod/scripting/readyup/setup.inc
+++ b/addons/sourcemod/scripting/readyup/setup.inc
@@ -32,15 +32,15 @@ void SetupNatives()
void SetupForwards()
{
- g_hPreInitiateForward = new GlobalForward("OnReadyUpInitiatePre", ET_Ignore);
- g_hInitiateForward = new GlobalForward("OnReadyUpInitiate", ET_Ignore);
- g_hPreCountdownForward = new GlobalForward("OnRoundLiveCountdownPre", ET_Ignore);
- g_hCountdownForward = new GlobalForward("OnRoundLiveCountdown", ET_Ignore);
- g_hPreLiveForward = new GlobalForward("OnRoundIsLivePre", ET_Ignore);
- g_hLiveForward = new GlobalForward("OnRoundIsLive", ET_Ignore);
- g_hCountdownCancelledForward = new GlobalForward("OnReadyCountdownCancelled", ET_Ignore, Param_Cell, Param_String);
- g_hPlayerReadyForward = new GlobalForward("OnPlayerReady", ET_Ignore, Param_Cell);
- g_hPlayerUnreadyForward = new GlobalForward("OnPlayerUnready", ET_Ignore, Param_Cell);
+ g_hPreInitiateForward = new GlobalForward("OnReadyUpInitiatePre", ET_Ignore);
+ g_hInitiateForward = new GlobalForward("OnReadyUpInitiate", ET_Ignore);
+ g_hPreCountdownForward = new GlobalForward("OnRoundLiveCountdownPre", ET_Ignore);
+ g_hCountdownForward = new GlobalForward("OnRoundLiveCountdown", ET_Ignore);
+ g_hPreLiveForward = new GlobalForward("OnRoundIsLivePre", ET_Ignore);
+ g_hLiveForward = new GlobalForward("OnRoundIsLive", ET_Ignore);
+ g_hCountdownCancelledForward = new GlobalForward("OnReadyCountdownCancelled", ET_Ignore, Param_Cell, Param_String);
+ g_hPlayerReadyForward = new GlobalForward("OnPlayerReady", ET_Ignore, Param_Cell);
+ g_hPlayerUnreadyForward = new GlobalForward("OnPlayerUnready", ET_Ignore, Param_Cell);
}
void SetupConVars()
@@ -72,14 +72,15 @@ void SetupConVars()
l4d_ready_autostart_min = CreateConVar("l4d_ready_autostart_min", "0.25", "Percent of max players (Versus = 8) in game to allow auto-start to proceed.", FCVAR_NOTIFY, true, 0.0, true, 1.0);
l4d_ready_unbalanced_start = CreateConVar("l4d_ready_unbalanced_start", "0", "Allow game to go live when teams are not full.", FCVAR_NOTIFY, true, 0.0, true, 1.0);
l4d_ready_unbalanced_min = CreateConVar("l4d_ready_unbalanced_min", "2", "Minimum of players in each team to allow a unbalanced start.", FCVAR_NOTIFY, true, 0.0);
+ l4d_ready_unready_limit = CreateConVar("l4d_ready_unready_limit", "0", "Limits the amount of unready a player can do in a single game. Set to 0 to disable.", FCVAR_NOTIFY, true, 0.0);
// game convars
- director_no_specials = FindConVar("director_no_specials");
- god = FindConVar("god");
- sb_stop = FindConVar("sb_stop");
- survivor_limit = FindConVar("survivor_limit");
- z_max_player_zombies = FindConVar("z_max_player_zombies");
- sv_infinite_primary_ammo = FindConVar("sv_infinite_primary_ammo");
+ director_no_specials = FindConVar("director_no_specials");
+ god = FindConVar("god");
+ sb_stop = FindConVar("sb_stop");
+ survivor_limit = FindConVar("survivor_limit");
+ z_max_player_zombies = FindConVar("z_max_player_zombies");
+ sv_infinite_primary_ammo = FindConVar("sv_infinite_primary_ammo");
}
void SetupCommands()
diff --git a/addons/sourcemod/scripting/survivor_mvp.sp b/addons/sourcemod/scripting/survivor_mvp.sp
index 85d2d75f5..572e15136 100644
--- a/addons/sourcemod/scripting/survivor_mvp.sp
+++ b/addons/sourcemod/scripting/survivor_mvp.sp
@@ -1,45 +1,45 @@
#pragma semicolon 1
+#pragma newdecls required
-#include
+#include
+#include
#include
#include
-#include
-#include
+#include
-#define TEAM_SPECTATOR 1
-#define TEAM_SURVIVOR 2
-#define TEAM_INFECTED 3
-#define FLAG_SPECTATOR (1 << TEAM_SPECTATOR)
-#define FLAG_SURVIVOR (1 << TEAM_SURVIVOR)
-#define FLAG_INFECTED (1 << TEAM_INFECTED)
-
-#define ZC_SMOKER 1
-#define ZC_BOOMER 2
-#define ZC_HUNTER 3
-#define ZC_SPITTER 4
-#define ZC_JOCKEY 5
-#define ZC_CHARGER 6
-#define ZC_WITCH 7
-#define ZC_TANK 8
-
-#define BREV_SI 1
-#define BREV_CI 2
-#define BREV_FF 4
-#define BREV_RANK 8
+#define TEAM_SPECTATOR 1
+#define TEAM_SURVIVOR 2
+#define TEAM_INFECTED 3
+#define FLAG_SPECTATOR (1 << TEAM_SPECTATOR)
+#define FLAG_SURVIVOR (1 << TEAM_SURVIVOR)
+#define FLAG_INFECTED (1 << TEAM_INFECTED)
+
+#define ZC_SMOKER 1
+#define ZC_BOOMER 2
+#define ZC_HUNTER 3
+#define ZC_SPITTER 4
+#define ZC_JOCKEY 5
+#define ZC_CHARGER 6
+#define ZC_WITCH 7
+#define ZC_TANK 8
+
+#define BREV_SI 1
+#define BREV_CI 2
+#define BREV_FF 4
+#define BREV_RANK 8
//#define BREV_??? 16
-#define BREV_PERCENT 32
-#define BREV_ABSOLUTE 64
+#define BREV_PERCENT 32
+#define BREV_ABSOLUTE 64
-#define CONBUFSIZE 1024
-#define CONBUFSIZELARGE 4096
-
-#define CHARTHRESHOLD 160 // detecting unicode stuff
+#define CONBUFSIZE 1024
+#define CONBUFSIZELARGE 4096
+#define CHARTHRESHOLD 160 // detecting unicode stuff
/**
-* Issues:
-* - Add damage received from common
-*/
+ * Issues:
+ * - Add damage received from common
+ */
/*
Changelog
@@ -79,1244 +79,1265 @@ Brevity flags:
64 leave out absolutes
*/
-
-public Plugin:myinfo =
+public Plugin myinfo =
{
- name = "Survivor MVP notification",
- author = "Tabun, Artifacial",
- description = "Shows MVP for survivor team at end of round",
- version = "0.3",
- url = "https://github.com/alexberriman/l4d2_survivor_mvp"
+ name = "Survivor MVP notification",
+ author = "Tabun, Artifacial",
+ description = "Shows MVP for survivor team at end of round",
+ version = "0.4",
+ url = "https://github.com/alexberriman/l4d2_survivor_mvp"
};
-
-new Handle: hPluginEnabled = INVALID_HANDLE;
-
-new Handle: hCountTankDamage = INVALID_HANDLE; // whether we're tracking tank damage for MVP-selection
-new Handle: hCountWitchDamage = INVALID_HANDLE; // whether we're tracking witch damage for MVP-selection
-new Handle: hTrackFF = INVALID_HANDLE; // whether we're tracking friendly-fire damage (separate stat)
-new Handle: hBrevityFlags = INVALID_HANDLE; // how verbose/brief the output should be:
-new Handle: hRUPActive = INVALID_HANDLE; // whether the ready up mod is active
-
-new bool: bCountTankDamage;
-new bool: bCountWitchDamage;
-new bool: bTrackFF;
-new iBrevityFlags;
-new bool: bRUPActive;
-
-new Handle: hGameMode = INVALID_HANDLE;
-new String: sGameMode[24] = "\0";
-
-new String: sClientName[MAXPLAYERS + 1][64]; // which name is connected to the clientId?
+ConVar
+ hPluginEnabled,
+ hCountTankDamage, // whether we're tracking tank damage for MVP-selection
+ hCountWitchDamage, // whether we're tracking witch damage for MVP-selection
+ hTrackFF, // whether we're tracking friendly-fire damage (separate stat)
+ hBrevityFlags, // how verbose/brief the output should be:
+ hRUPActive; // whether the ready up mod is active
+
+bool
+ bCountTankDamage,
+ bCountWitchDamage,
+ bTrackFF;
+int
+ iBrevityFlags;
+bool
+ bRUPActive;
+
+Handle
+ hGameMode = INVALID_HANDLE;
+char
+ sGameMode[24] = "\0",
+ sClientName[MAXPLAYERS + 1][64]; // which name is connected to the clientId?
// Basic statistics
-new iGotKills[MAXPLAYERS + 1]; // SI kills track for each client
-new iGotCommon[MAXPLAYERS + 1]; // CI kills
-new iDidDamage[MAXPLAYERS + 1]; // SI only these are a bit redundant, but will keep anyway for now
-new iDidDamageAll[MAXPLAYERS + 1]; // SI + tank + witch
-new iDidDamageTank[MAXPLAYERS + 1]; // tank only
-new iDidDamageWitch[MAXPLAYERS + 1]; // witch only
-new iDidFF[MAXPLAYERS + 1]; // friendly fire damage
+int
+ iGotKills[MAXPLAYERS + 1], // SI kills track for each client
+ iGotCommon[MAXPLAYERS + 1], // CI kills
+ iDidDamage[MAXPLAYERS + 1], // SI only these are a bit redundant, but will keep anyway for now
+ iDidDamageAll[MAXPLAYERS + 1], // SI + tank + witch
+ iDidDamageTank[MAXPLAYERS + 1], // tank only
+ iDidDamageWitch[MAXPLAYERS + 1], // witch only
+ iDidFF[MAXPLAYERS + 1]; // friendly fire damage
// Detailed statistics
-new iDidDamageClass[MAXPLAYERS + 1][ZC_TANK + 1]; // si classes
-new timesPinned[MAXPLAYERS + 1][ZC_TANK + 1]; // times pinned
-new totalPinned[MAXPLAYERS + 1]; // total times pinned
-new pillsUsed[MAXPLAYERS + 1]; // total pills eaten
-new boomerPops[MAXPLAYERS + 1]; // total boomer pops
-new damageReceived[MAXPLAYERS + 1]; // Damage received
+int
+ iDidDamageClass[MAXPLAYERS + 1][ZC_TANK + 1], // si classes
+ timesPinned[MAXPLAYERS + 1][ZC_TANK + 1], // times pinned
+ totalPinned[MAXPLAYERS + 1], // total times pinned
+ pillsUsed[MAXPLAYERS + 1], // total pills eaten
+ boomerPops[MAXPLAYERS + 1], // total boomer pops
+ damageReceived[MAXPLAYERS + 1]; // Damage received
// Tank stats
-new tankSpawned = false; // When tank is spawned
-new commonKilledDuringTank[MAXPLAYERS + 1]; // Common killed during the tank
-new ttlCommonKilledDuringTank = 0; // Common killed during the tank
-new siDmgDuringTank[MAXPLAYERS + 1]; // SI killed during the tank
-//new ttlSiDmgDuringTank = 0; // Total SI killed during the tank
-new tankThrow; // Whether or not the tank has thrown a rock
-new rocksEaten[MAXPLAYERS + 1]; // The amount of rocks a player 'ate'.
-new rockIndex; // The index of the rock (to detect how many times we were rocked)
-new ttlPinnedDuringTank[MAXPLAYERS + 1]; // The total times we were pinned when the tank was up
-
-
-new iTotalKills; // prolly more efficient to store than to recalculate
-new iTotalCommon;
-//new iTotalDamage;
-//new iTotalDamageTank;
-//new iTotalDamageWitch;
-new iTotalDamageAll;
-new iTotalFF;
-
-new iRoundNumber;
-new bInRound;
-new bPlayerLeftStartArea; // used for tracking FF when RUP enabled
-
-new String: sTmpString[MAX_NAME_LENGTH]; // just used because I'm not going to break my head over why string assignment parameter passing doesn't work
+bool
+ tankSpawned = false, // When tank is spawned
+ tankThrow; // Whether or not the tank has thrown a rock
+int
+ commonKilledDuringTank[MAXPLAYERS + 1], // Common killed during the tank
+ ttlCommonKilledDuringTank = 0, // Common killed during the tank
+ siDmgDuringTank[MAXPLAYERS + 1], // SI killed during the tank
+ rocksEaten[MAXPLAYERS + 1], // The amount of rocks a player 'ate'.
+ ttlPinnedDuringTank[MAXPLAYERS + 1], // The total times we were pinned when the tank was up
+ rockIndex; // The index of the rock (to detect how many times we were rocked)
+
+int
+ iTotalKills, // prolly more efficient to store than to recalculate
+ iTotalCommon,
+ iTotalDamageAll,
+ iTotalFF;
+
+int
+ iRoundNumber;
+bool
+ bInRound,
+ bPlayerLeftStartArea; // used for tracking FF when RUP enabled
/*
-* Natives
-* =======
-*/
-
-public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
+ * Natives
+ * =======
+ */
+public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
- CreateNative("SURVMVP_GetMVP", Native_GetMVP);
- CreateNative("SURVMVP_GetMVPDmgCount", Native_GetMVPDmgCount);
- CreateNative("SURVMVP_GetMVPKills", Native_GetMVPKills);
- CreateNative("SURVMVP_GetMVPDmgPercent", Native_GetMVPDmgPercent);
- CreateNative("SURVMVP_GetMVPCI", Native_GetMVPCI);
- CreateNative("SURVMVP_GetMVPCIKills", Native_GetMVPCIKills);
- CreateNative("SURVMVP_GetMVPCIPercent", Native_GetMVPCIPercent);
-
- return APLRes_Success;
+ CreateNative("SURVMVP_GetMVP", Native_GetMVP);
+ CreateNative("SURVMVP_GetMVPDmgCount", Native_GetMVPDmgCount);
+ CreateNative("SURVMVP_GetMVPKills", Native_GetMVPKills);
+ CreateNative("SURVMVP_GetMVPDmgPercent", Native_GetMVPDmgPercent);
+ CreateNative("SURVMVP_GetMVPCI", Native_GetMVPCI);
+ CreateNative("SURVMVP_GetMVPCIKills", Native_GetMVPCIKills);
+ CreateNative("SURVMVP_GetMVPCIPercent", Native_GetMVPCIPercent);
+ RegPluginLibrary("survivor_mvp");
+ return APLRes_Success;
}
+// ========================
+// Natives
+// ========================
+
// simply return current round MVP client
-public Native_GetMVP(Handle:plugin, numParams)
+public int Native_GetMVP(Handle plugin, int numParams)
{
- new client = findMVPSI();
- return _:client;
+ int client = findMVPSI();
+ return client;
}
-// return damage percent of client
-public Native_GetMVPDmgPercent(Handle:plugin, numParams)
+// return damage of client
+public int Native_GetMVPDmgCount(Handle plugin, int numParams)
{
- new client = GetNativeCell(1);
- new Float: dmgprc = client && iTotalDamageAll > 0 ? (float(iDidDamageAll[client]) / float(iTotalDamageAll)) * 100 : 0.0;
- return _:dmgprc;
+ int client = GetNativeCell(1);
+ int dmg = client && iTotalDamageAll > 0 ? iDidDamageAll[client] : 0;
+ return dmg;
}
-// return damage of client
-public Native_GetMVPDmgCount(Handle:plugin, numParams)
+// return SI kills of client
+public int Native_GetMVPKills(Handle plugin, int numParams)
{
- new client = GetNativeCell(1);
- new dmg = client && iTotalDamageAll > 0 ? iDidDamageAll[client] : 0;
- return _:dmg;
+ int client = GetNativeCell(1);
+ int dmg = client && iTotalKills > 0 ? iGotKills[client] : 0;
+ return dmg;
}
-// return SI kills of client
-public Native_GetMVPKills(Handle:plugin, numParams)
+// return damage percent of client
+public any Native_GetMVPDmgPercent(Handle plugin, int numParams)
{
- new client = GetNativeCell(1);
- new dmg = client && iTotalKills > 0 ? iGotKills[client] : 0;
- return _:dmg;
+ int client = GetNativeCell(1);
+ float dmgprc = client && iTotalDamageAll > 0 ? (float(iDidDamageAll[client]) / float(iTotalDamageAll)) * 100 : 0.0;
+ return dmgprc;
}
// simply return current round MVP client (Common)
-public Native_GetMVPCI(Handle:plugin, numParams)
+public int Native_GetMVPCI(Handle plugin, int numParams)
{
- new client = findMVPCommon();
- return _:client;
+ int client = findMVPCommon();
+ return client;
}
// return common kills for client
-public Native_GetMVPCIKills(Handle:plugin, numParams)
+public int Native_GetMVPCIKills(Handle plugin, int numParams)
{
- new client = GetNativeCell(1);
- new dmg = client && iTotalCommon > 0 ? iGotCommon[client] : 0;
- return _:dmg;
+ int client = GetNativeCell(1);
+ int dmg = client && iTotalCommon > 0 ? iGotCommon[client] : 0;
+ return dmg;
}
// return CI percent of client
-public Native_GetMVPCIPercent(Handle:plugin, numParams)
+public any Native_GetMVPCIPercent(Handle plugin, int numParams)
{
- new client = GetNativeCell(1);
- new Float: dmgprc = client && iTotalCommon > 0 ? (float(iGotCommon[client]) / float(iTotalCommon)) * 100 : 0.0;
- return _:dmgprc;
+ int client = GetNativeCell(1);
+ float dmgprc = client && iTotalCommon > 0 ? (float(iGotCommon[client]) / float(iTotalCommon)) * 100 : 0.0;
+ return dmgprc;
}
-
/*
-* init
-* ====
-*/
-
-public OnPluginStart()
+ * init
+ * ====
+ */
+public void OnPluginStart()
{
- // Round triggers
- //HookEvent("door_close", DoorClose_Event);
- //HookEvent("finale_vehicle_leaving", FinaleVehicleLeaving_Event, EventHookMode_PostNoCopy);
- HookEvent("round_start", RoundStart_Event, EventHookMode_PostNoCopy);
- HookEvent("round_end", RoundEnd_Event, EventHookMode_PostNoCopy);
- HookEvent("map_transition", RoundEnd_Event, EventHookMode_PostNoCopy);
- HookEvent("scavenge_round_start", ScavRoundStart, EventHookMode_PostNoCopy);
- HookEvent("player_left_start_area", PlayerLeftStartArea, EventHookMode_PostNoCopy);
- HookEvent("pills_used", pillsUsedEvent);
- HookEvent("boomer_exploded", boomerExploded);
- HookEvent("charger_carry_end", chargerCarryEnd);
- HookEvent("jockey_ride", jockeyRide);
- HookEvent("lunge_pounce", hunterLunged);
- HookEvent("choke_start", smokerChoke);
- HookEvent("tank_killed", tankKilled);
- HookEvent("tank_spawn", tankSpawn);
- HookEvent("ability_use", abilityUseEvent);
- //HookEvent("tank_frustrated", tankFrustrated);
-
- // Catching data
- HookEvent("player_hurt", PlayerHurt_Event, EventHookMode_Post);
- HookEvent("player_death", PlayerDeath_Event, EventHookMode_Post);
- HookEvent("infected_hurt" ,InfectedHurt_Event, EventHookMode_Post);
- HookEvent("infected_death", InfectedDeath_Event, EventHookMode_Post);
-
- // check gamemode (for scavenge fix)
- hGameMode = FindConVar("mp_gamemode");
-
- // Cvars
- hPluginEnabled = CreateConVar("sm_survivor_mvp_enabled", "1", "Enable display of MVP at end of round");
- hCountTankDamage = CreateConVar("sm_survivor_mvp_counttank", "0", "Damage on tank counts towards MVP-selection if enabled.");
- hCountWitchDamage = CreateConVar("sm_survivor_mvp_countwitch", "0", "Damage on witch counts towards MVP-selection if enabled.");
- hTrackFF = CreateConVar("sm_survivor_mvp_showff", "1", "Track Friendly-fire stat.");
- hBrevityFlags = CreateConVar("sm_survivor_mvp_brevity", "0", "Flags for setting brevity of MVP report (hide 1:SI, 2:CI, 4:FF, 8:rank, 32:perc, 64:abs).");
-
- bCountTankDamage = GetConVarBool(hCountTankDamage);
- bCountWitchDamage = GetConVarBool(hCountWitchDamage);
- bTrackFF = GetConVarBool(hTrackFF);
- iBrevityFlags = GetConVarInt(hBrevityFlags);
-
- // for now, force FF tracking on:
- bTrackFF = true;
-
- HookConVarChange(hCountTankDamage, ConVarChange_CountTankDamage);
- HookConVarChange(hCountWitchDamage, ConVarChange_CountWitchDamage);
- HookConVarChange(hTrackFF, ConVarChange_TrackFF);
- HookConVarChange(hBrevityFlags, ConVarChange_BrevityFlags);
-
- if (!(iBrevityFlags & BREV_FF)) { bTrackFF = true; } // force tracking on if we're showing FF
-
- // RUP?
- hRUPActive = FindConVar("l4d_ready_enabled");
- if (hRUPActive != INVALID_HANDLE)
- {
- // hook changes for this, and set state appropriately
- bRUPActive = GetConVarBool(hRUPActive);
- HookConVarChange(hRUPActive, ConVarChange_RUPActive);
- } else {
- // not loaded
- bRUPActive = false;
- }
- bPlayerLeftStartArea = false;
-
- // Commands
- RegConsoleCmd("sm_mvp", SurvivorMVP_Cmd, "Prints the current MVP for the survivor team");
- RegConsoleCmd("sm_mvpme", ShowMVPStats_Cmd, "Prints the client's own MVP-related stats");
-
- RegConsoleCmd("say", Say_Cmd);
- RegConsoleCmd("say_team", Say_Cmd);
+ // Translation
+ LoadTranslation("survivor_mvp.phrases");
+
+ // Round triggers
+ HookEvent("round_start", RoundStart_Event, EventHookMode_PostNoCopy);
+ HookEvent("round_end", RoundEnd_Event, EventHookMode_PostNoCopy);
+ HookEvent("map_transition", RoundEnd_Event, EventHookMode_PostNoCopy);
+ HookEvent("scavenge_round_start", ScavRoundStart, EventHookMode_PostNoCopy);
+ HookEvent("player_left_start_area", PlayerLeftStartArea, EventHookMode_PostNoCopy);
+ HookEvent("pills_used", pillsUsedEvent);
+ HookEvent("boomer_exploded", boomerExploded);
+ HookEvent("charger_carry_end", chargerCarryEnd);
+ HookEvent("jockey_ride", jockeyRide);
+ HookEvent("lunge_pounce", hunterLunged);
+ HookEvent("choke_start", smokerChoke);
+ HookEvent("tank_killed", tankKilled);
+ HookEvent("tank_spawn", tankSpawn);
+ HookEvent("ability_use", abilityUseEvent);
+
+ // Catching data
+ HookEvent("player_hurt", PlayerHurt_Event, EventHookMode_Post);
+ HookEvent("player_death", PlayerDeath_Event, EventHookMode_Post);
+ HookEvent("infected_hurt", InfectedHurt_Event, EventHookMode_Post);
+ HookEvent("infected_death", InfectedDeath_Event, EventHookMode_Post);
+
+ // check gamemode (for scavenge fix)
+ hGameMode = FindConVar("mp_gamemode");
+
+ // Cvars
+ hPluginEnabled = CreateConVar("sm_survivor_mvp_enabled", "1", "Enable display of MVP at end of round");
+ hCountTankDamage = CreateConVar("sm_survivor_mvp_counttank", "0", "Damage on tank counts towards MVP-selection if enabled.");
+ hCountWitchDamage = CreateConVar("sm_survivor_mvp_countwitch", "0", "Damage on witch counts towards MVP-selection if enabled.");
+ hTrackFF = CreateConVar("sm_survivor_mvp_showff", "1", "Track Friendly-fire stat.");
+ hBrevityFlags = CreateConVar("sm_survivor_mvp_brevity", "0", "Flags for setting brevity of MVP report (hide 1:SI, 2:CI, 4:FF, 8:rank, 32:perc, 64:abs).");
+
+ bCountTankDamage = hCountTankDamage.BoolValue;
+ bCountWitchDamage = hCountWitchDamage.BoolValue;
+ bTrackFF = hTrackFF.BoolValue;
+ iBrevityFlags = hBrevityFlags.IntValue;
+
+ // for now, force FF tracking on:
+ bTrackFF = true;
+
+ HookConVarChange(hCountTankDamage, ConVarChange_CountTankDamage);
+ HookConVarChange(hCountWitchDamage, ConVarChange_CountWitchDamage);
+ HookConVarChange(hTrackFF, ConVarChange_TrackFF);
+ HookConVarChange(hBrevityFlags, ConVarChange_BrevityFlags);
+
+ if (!(iBrevityFlags & BREV_FF)) { bTrackFF = true; } // force tracking on if we're showing FF
+
+ // RUP?
+ hRUPActive = FindConVar("l4d_ready_enabled");
+ if (hRUPActive != null)
+ {
+ // hook changes for this, and set state appropriately
+ bRUPActive = hRUPActive.BoolValue;
+ HookConVarChange(hRUPActive, ConVarChange_RUPActive);
+ }
+ else {
+ // not loaded
+ bRUPActive = false;
+ }
+ bPlayerLeftStartArea = false;
+
+ // Commands
+ RegConsoleCmd("sm_mvp", SurvivorMVP_Cmd, "Prints the current MVP for the survivor team");
+ RegConsoleCmd("sm_mvpme", ShowMVPStats_Cmd, "Prints the client's own MVP-related stats");
+
+ RegConsoleCmd("say", Say_Cmd);
+ RegConsoleCmd("say_team", Say_Cmd);
}
-/*
-public OnPluginEnd()
+void LoadTranslation(char[] sTranslation)
{
-// nothing
+ char
+ sPath[PLATFORM_MAX_PATH],
+ sName[64];
+
+ Format(sName, sizeof(sName), "translations/%s.txt", sTranslation);
+ BuildPath(Path_SM, sPath, sizeof(sPath), sName);
+ if (!FileExists(sPath))
+ {
+ SetFailState("Missing translation file %s.txt", sTranslation);
+ }
+ LoadTranslations(sTranslation);
}
-*/
-public OnClientPutInServer(client)
+public void OnClientPutInServer(int client)
{
- decl String:tmpBuffer[64];
- GetClientName(client, tmpBuffer, sizeof(tmpBuffer));
-
- // if previously stored name for same client is not the same, delete stats & overwrite name
- if (strcmp(tmpBuffer, sClientName[client], true) != 0)
- {
- iGotKills[client] = 0;
- iGotCommon[client] = 0;
- iDidDamage[client] = 0;
- iDidDamageAll[client] = 0;
- iDidDamageWitch[client] = 0;
- iDidDamageTank[client] = 0;
- iDidFF[client] = 0;
-
-
- //@todo detailed statistics - set to 0
- for (new siClass = ZC_SMOKER; siClass <= ZC_TANK; siClass++) {
- iDidDamageClass[client][siClass] = 0;
- timesPinned[client][siClass] = 0;
- }
- pillsUsed[client] = 0;
- boomerPops[client] = 0;
- damageReceived[client] = 0;
- totalPinned[client] = 0;
- commonKilledDuringTank[client] = 0;
- siDmgDuringTank[client] = 0;
- rocksEaten[client] = 0;
- ttlPinnedDuringTank[client] = 0;
-
- // store name for later reference
- strcopy(sClientName[client], 64, tmpBuffer);
- }
+ char tmpBuffer[128];
+ GetClientName(client, tmpBuffer, sizeof(tmpBuffer));
+
+ // if previously stored name for same client is not the same, delete stats & overwrite name
+ if (strcmp(tmpBuffer, sClientName[client], true) != 0)
+ {
+ iGotKills[client] = 0;
+ iGotCommon[client] = 0;
+ iDidDamage[client] = 0;
+ iDidDamageAll[client] = 0;
+ iDidDamageWitch[client] = 0;
+ iDidDamageTank[client] = 0;
+ iDidFF[client] = 0;
+
+ //@todo detailed statistics - set to 0
+ for (int siClass = ZC_SMOKER; siClass <= ZC_TANK; siClass++)
+ {
+ iDidDamageClass[client][siClass] = 0;
+ timesPinned[client][siClass] = 0;
+ }
+ pillsUsed[client] = 0;
+ boomerPops[client] = 0;
+ damageReceived[client] = 0;
+ totalPinned[client] = 0;
+ commonKilledDuringTank[client] = 0;
+ siDmgDuringTank[client] = 0;
+ rocksEaten[client] = 0;
+ ttlPinnedDuringTank[client] = 0;
+
+ // store name for later reference
+ strcopy(sClientName[client], sizeof(tmpBuffer), tmpBuffer);
+ }
}
/*
-* convar changes
-* ==============
-*/
-
-public ConVarChange_CountTankDamage(Handle:cvar, const String:oldValue[], const String:newValue[]) {
- bCountTankDamage = StringToInt(newValue) != 0;
+ * convar changes
+ * ==============
+ */
+public void ConVarChange_CountTankDamage(Handle cvar, const char[] oldValue, const char[] newValue)
+{
+ bCountTankDamage = StringToInt(newValue) != 0;
}
-public ConVarChange_CountWitchDamage(Handle:cvar, const String:oldValue[], const String:newValue[]) {
- bCountWitchDamage = StringToInt(newValue) != 0;
+
+public void ConVarChange_CountWitchDamage(Handle cvar, const char[] oldValue, const char[] newValue)
+{
+ bCountWitchDamage = StringToInt(newValue) != 0;
}
-public ConVarChange_TrackFF(Handle:cvar, const String:oldValue[], const String:newValue[]) {
- //if (StringToInt(newValue) == 0) { bTrackFF = false; } else { bTrackFF = true; }
- // for now, disable FF tracking toggle (always on)
+
+public void ConVarChange_TrackFF(Handle cvar, const char[] oldValue, const char[] newValue)
+{
+ // if (StringToInt(newValue) == 0) { bTrackFF = false; } else { bTrackFF = true; }
+ // for now, disable FF tracking toggle (always on)
}
-public ConVarChange_BrevityFlags(Handle:cvar, const String:oldValue[], const String:newValue[]) {
- iBrevityFlags = StringToInt(newValue);
- if (!(iBrevityFlags & BREV_FF)) {
- bTrackFF = true;
- } // force tracking on if we're showing FF
+
+public void ConVarChange_BrevityFlags(Handle cvar, const char[] oldValue, const char[] newValue)
+{
+ iBrevityFlags = StringToInt(newValue);
+ if (!(iBrevityFlags & BREV_FF))
+ {
+ bTrackFF = true;
+ } // force tracking on if we're showing FF
}
-public ConVarChange_RUPActive(Handle:cvar, const String:oldValue[], const String:newValue[]) {
- bRUPActive = StringToInt(newValue) != 0;
+public void ConVarChange_RUPActive(Handle cvar, const char[] oldValue, const char[] newValue)
+{
+ bRUPActive = StringToInt(newValue) != 0;
}
/*
-* map load / round start/end
-* ==========================
-*/
-
-public Action:PlayerLeftStartArea(Handle:event, const String:name[], bool:dontBroadcast)
+ * map load / round start/end
+ * ==========================
+ */
+public Action PlayerLeftStartArea(Handle event, const char[] name, bool dontBroadcast)
{
- // if RUP active, now we can start tracking FF
- bPlayerLeftStartArea = true;
+ // if RUP active, now we can start tracking FF
+ bPlayerLeftStartArea = true;
+ return Plugin_Continue;
}
-public OnMapStart()
+public void OnMapStart()
{
- bPlayerLeftStartArea = false;
- // get gamemode string for scavenge fix
- GetConVarString(hGameMode, sGameMode, sizeof(sGameMode));
+ bPlayerLeftStartArea = false;
+ // get gamemode string for scavenge fix
+ GetConVarString(hGameMode, sGameMode, sizeof(sGameMode));
}
-public OnMapEnd()
+public void OnMapEnd()
{
- iRoundNumber = 0;
- bInRound = false;
+ iRoundNumber = 0;
+ bInRound = false;
}
-public void ScavRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
+public void ScavRoundStart(Handle event, const char[] name, bool dontBroadcast)
{
- // clear mvp stats
- new i, maxplayers = MaxClients;
- for (i = 1; i <= maxplayers; i++)
- {
- iGotKills[i] = 0;
- iGotCommon[i] = 0;
- iDidDamage[i] = 0;
- iDidDamageAll[i] = 0;
- iDidDamageWitch[i] = 0;
- iDidDamageTank[i] = 0;
- iDidFF[i] = 0;
-
- //@todo detailed statistics - set to 0
- for (new siClass = ZC_SMOKER; siClass <= ZC_TANK; siClass++) {
- iDidDamageClass[i][siClass] = 0;
- timesPinned[i][siClass] = 0;
- }
- pillsUsed[i] = 0;
- boomerPops[i] = 0;
- damageReceived[i] = 0;
- totalPinned[i] = 0;
- commonKilledDuringTank[i] = 0;
- siDmgDuringTank[i] = 0;
- rocksEaten[i] = 0;
- ttlPinnedDuringTank[i] = 0;
- }
- iTotalKills = 0;
- iTotalCommon = 0;
- //iTotalDamage = 0;
- //iTotalDamageTank = 0;
- //iTotalDamageWitch = 0;
- iTotalDamageAll = 0;
- iTotalFF = 0;
- //ttlSiDmgDuringTank = 0;
- ttlCommonKilledDuringTank = 0;
- tankThrow = false;
-
- bInRound = true;
- tankSpawned = false;
+ // clear mvp stats
+ int
+ i,
+ maxplayers = MaxClients;
+ for (i = 1; i <= maxplayers; i++)
+ {
+ iGotKills[i] = 0;
+ iGotCommon[i] = 0;
+ iDidDamage[i] = 0;
+ iDidDamageAll[i] = 0;
+ iDidDamageWitch[i] = 0;
+ iDidDamageTank[i] = 0;
+ iDidFF[i] = 0;
+
+ //@todo detailed statistics - set to 0
+ for (int siClass = ZC_SMOKER; siClass <= ZC_TANK; siClass++)
+ {
+ iDidDamageClass[i][siClass] = 0;
+ timesPinned[i][siClass] = 0;
+ }
+ pillsUsed[i] = 0;
+ boomerPops[i] = 0;
+ damageReceived[i] = 0;
+ totalPinned[i] = 0;
+ commonKilledDuringTank[i] = 0;
+ siDmgDuringTank[i] = 0;
+ rocksEaten[i] = 0;
+ ttlPinnedDuringTank[i] = 0;
+ }
+ iTotalKills = 0;
+ iTotalCommon = 0;
+ iTotalDamageAll = 0;
+ iTotalFF = 0;
+ ttlCommonKilledDuringTank = 0;
+ tankThrow = false;
+
+ bInRound = true;
+ tankSpawned = false;
}
-public RoundStart_Event(Handle:event, const String:name[], bool:dontBroadcast)
+public void RoundStart_Event(Handle event, const char[] name, bool dontBroadcast)
{
- bPlayerLeftStartArea = false;
-
- if (!bInRound)
- {
- bInRound = true;
- iRoundNumber++;
- }
-
- // clear mvp stats
- new i, maxplayers = MaxClients;
- for (i = 1; i <= maxplayers; i++)
- {
- iGotKills[i] = 0;
- iGotCommon[i] = 0;
- iDidDamage[i] = 0;
- iDidDamageAll[i] = 0;
- iDidDamageWitch[i] = 0;
- iDidDamageTank[i] = 0;
- iDidFF[i] = 0;
-
- //@todo detailed statistics init to 0
- for (new siClass = ZC_SMOKER; siClass <= ZC_TANK; siClass++) {
- iDidDamageClass[i][siClass] = 0;
- timesPinned[i][siClass] = 0;
- }
- pillsUsed[i] = 0;
- boomerPops[i] = 0;
- damageReceived[i] = 0;
- totalPinned[i] = 0;
- commonKilledDuringTank[i] = 0;
- siDmgDuringTank[i] = 0;
- rocksEaten[i] = 0;
- ttlPinnedDuringTank[i] = 0;
- }
- iTotalKills = 0;
- iTotalCommon = 0;
- //iTotalDamage = 0;
- iTotalDamageAll = 0;
- iTotalFF = 0;
- //ttlSiDmgDuringTank = 0;
- ttlCommonKilledDuringTank = 0;
- //iTotalDamageTank = 0;
- tankThrow = false;
-
- tankSpawned = false;
+ bPlayerLeftStartArea = false;
+
+ if (!bInRound)
+ {
+ bInRound = true;
+ iRoundNumber++;
+ }
+
+ // clear mvp stats
+ int i, maxplayers = MaxClients;
+ for (i = 1; i <= maxplayers; i++)
+ {
+ iGotKills[i] = 0;
+ iGotCommon[i] = 0;
+ iDidDamage[i] = 0;
+ iDidDamageAll[i] = 0;
+ iDidDamageWitch[i] = 0;
+ iDidDamageTank[i] = 0;
+ iDidFF[i] = 0;
+
+ //@todo detailed statistics init to 0
+ for (int siClass = ZC_SMOKER; siClass <= ZC_TANK; siClass++)
+ {
+ iDidDamageClass[i][siClass] = 0;
+ timesPinned[i][siClass] = 0;
+ }
+ pillsUsed[i] = 0;
+ boomerPops[i] = 0;
+ damageReceived[i] = 0;
+ totalPinned[i] = 0;
+ commonKilledDuringTank[i] = 0;
+ siDmgDuringTank[i] = 0;
+ rocksEaten[i] = 0;
+ ttlPinnedDuringTank[i] = 0;
+ }
+ iTotalKills = 0;
+ iTotalCommon = 0;
+ iTotalDamageAll = 0;
+ iTotalFF = 0;
+ ttlCommonKilledDuringTank = 0;
+ tankThrow = false;
+
+ tankSpawned = false;
}
-public RoundEnd_Event(Handle:event, const String:name[], bool:dontBroadcast)
+public void RoundEnd_Event(Handle event, const char[] name, bool dontBroadcast)
{
- if (StrEqual(sGameMode, "coop", false))
- {
- if (bInRound)
- {
- if (GetConVarBool(hPluginEnabled))
- CreateTimer(0.01, delayedMVPPrint); // shorter delay for scavenge.
- bInRound = false;
- }
- }
- else
- {
- // versus or other
- if (bInRound && !StrEqual(name, "map_transition", false))
- {
- // only show / log stuff when the round is done "the first time"
- if (GetConVarBool(hPluginEnabled))
- CreateTimer(2.0, delayedMVPPrint);
- bInRound = false;
- }
- }
-
- tankSpawned = false;
+ if (StrEqual(sGameMode, "coop", false))
+ {
+ if (bInRound)
+ {
+ if (hPluginEnabled.BoolValue)
+ CreateTimer(0.01, delayedMVPPrint); // shorter delay for scavenge.
+ bInRound = false;
+ }
+ }
+ else
+ {
+ // versus or other
+ if (bInRound && !StrEqual(name, "map_transition", false))
+ {
+ // only show / log stuff when the round is done "the first time"
+ if (hPluginEnabled.BoolValue)
+ CreateTimer(2.0, delayedMVPPrint);
+ bInRound = false;
+ }
+ }
+
+ tankSpawned = false;
}
-
/*
-* cmds / reports
-* ==============
-*/
-
-public Action:Say_Cmd(client, args)
+ * cmds / reports
+ * ==============
+ */
+public Action Say_Cmd(int client, int args)
{
- if (!client) { return Plugin_Continue; }
-
- decl String:sMessage[MAX_NAME_LENGTH];
- GetCmdArg(1, sMessage, sizeof(sMessage));
-
- if (StrEqual(sMessage, "!mvp") || StrEqual(sMessage, "!mvpme")) { return Plugin_Handled; }
-
- return Plugin_Continue;
+ if (!client)
+ {
+ return Plugin_Continue;
+ }
+
+ char sMessage[MAX_NAME_LENGTH];
+ GetCmdArg(1, sMessage, sizeof(sMessage));
+
+ if (StrEqual(sMessage, "!mvp") || StrEqual(sMessage, "!mvpme"))
+ {
+ return Plugin_Handled;
+ }
+
+ return Plugin_Continue;
}
-public Action:SurvivorMVP_Cmd(client, args)
+public Action SurvivorMVP_Cmd(int client, int args)
{
- decl String:printBuffer[4096];
- new String:strLines[8][192];
-
- GetMVPString(printBuffer, sizeof(printBuffer));
-
- // PrintToChat has a max length. Split it in to individual lines to output separately
- new intPieces = ExplodeString(printBuffer, "\n", strLines, sizeof(strLines), sizeof(strLines[]));
-
- if (client && IsClientConnected(client))
- {
- for (new i = 0; i < intPieces; i++)
- {
- CPrintToChat(client, "%s", strLines[i]);
- }
- }
- PrintLoserz(true, client);
+ char
+ printBuffer[4096],
+ strLines[8][192];
+
+ GetMVPString(printBuffer, sizeof(printBuffer));
+
+ // PrintToChat has a max length. Split it in to individual lines to output separately
+ int intPieces = ExplodeString(printBuffer, "\n", strLines, sizeof(strLines), sizeof(strLines[]));
+
+ if (client && IsClientConnected(client))
+ {
+ for (int i = 0; i < intPieces; i++)
+ {
+ CPrintToChat(client, "%s", strLines[i]);
+ }
+ }
+ PrintLoserz(true, client);
+ return Plugin_Continue;
}
-public Action:ShowMVPStats_Cmd(client, args)
+public Action ShowMVPStats_Cmd(int client, int args)
{
- PrintLoserz(true, client);
+ PrintLoserz(true, client);
+ return Plugin_Continue;
}
-public Action:delayedMVPPrint(Handle:timer)
+public Action delayedMVPPrint(Handle timer)
{
- decl String:printBuffer[4096];
- new String:strLines[8][192];
-
- GetMVPString(printBuffer, sizeof(printBuffer));
-
- // PrintToChatAll has a max length. Split it in to individual lines to output separately
- new intPieces = ExplodeString(printBuffer, "\n", strLines, sizeof(strLines), sizeof(strLines[]));
- for (new i = 0; i < intPieces; i++)
- {
- for (new client = 1; client <= MaxClients; client++)
- {
- if (IsClientInGame(client)) CPrintToChat(client, "{default}%s", strLines[i]);
- }
- }
-
- CreateTimer(0.1, PrintLosers);
+ char
+ printBuffer[4096],
+ strLines[8][192];
+
+ GetMVPString(printBuffer, sizeof(printBuffer));
+
+ // PrintToChatAll has a max length. Split it in to individual lines to output separately
+ int intPieces = ExplodeString(printBuffer, "\n", strLines, sizeof(strLines), sizeof(strLines[]));
+ for (int i = 0; i < intPieces; i++)
+ {
+ for (int client = 1; client <= MaxClients; client++)
+ {
+ if (IsClientInGame(client)) CPrintToChat(client, "{default}%s", strLines[i]);
+ }
+ }
+ CreateTimer(0.1, PrintLosers);
+ return Plugin_Continue;
}
-public Action:PrintLosers(Handle:timer)
+public Action PrintLosers(Handle timer)
{
- PrintLoserz(false, -1);
+ PrintLoserz(false, -1);
+ return Plugin_Continue;
}
-stock PrintLoserz(bool:bSolo, client)
+stock void PrintLoserz(bool bSolo, int client)
{
- decl String:tmpBuffer[512];
- // also find the three non-mvp survivors and tell them they sucked
- // tell them they sucked with SI
- if (iTotalDamageAll > 0)
- {
- new mvp_SI = findMVPSI();
- new mvp_SI_losers[3];
- mvp_SI_losers[0] = findMVPSI(mvp_SI); // second place
- mvp_SI_losers[1] = findMVPSI(mvp_SI, mvp_SI_losers[0]); // third
- mvp_SI_losers[2] = findMVPSI(mvp_SI, mvp_SI_losers[0], mvp_SI_losers[1]); // fourth
-
- for (new i = 0; i <= 2; i++)
- {
- if (IsClientAndInGame(mvp_SI_losers[i]) && !IsFakeClient(mvp_SI_losers[i]))
- {
- if (bSolo)
- {
- if (mvp_SI_losers[i] == client)
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}Your Rank {green}SI: {olive}#%d - {blue}({default}%d {green}dmg {blue}[{default}%.0f%%{blue}]{olive}, {default}%d {green}kills {blue}[{default}%.0f%%{blue}])", (i + 2), iDidDamageAll[mvp_SI_losers[i]], (float(iDidDamageAll[mvp_SI_losers[i]]) / float(iTotalDamageAll)) * 100, iGotKills[mvp_SI_losers[i]], (float(iGotKills[mvp_SI_losers[i]]) / float(iTotalKills)) * 100);
- CPrintToChat(mvp_SI_losers[i], "%s", tmpBuffer);
- }
- }
- else
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}Your Rank {green}SI: {olive}#%d - {blue}({default}%d {green}dmg {blue}[{default}%.0f%%{blue}]{olive}, {default}%d {green}kills {blue}[{default}%.0f%%{blue}])", (i + 2), iDidDamageAll[mvp_SI_losers[i]], (float(iDidDamageAll[mvp_SI_losers[i]]) / float(iTotalDamageAll)) * 100, iGotKills[mvp_SI_losers[i]], (float(iGotKills[mvp_SI_losers[i]]) / float(iTotalKills)) * 100);
- CPrintToChat(mvp_SI_losers[i], "%s", tmpBuffer);
- }
- }
- }
- }
-
- // tell them they sucked with Common
- if (iTotalCommon > 0)
- {
- new mvp_CI = findMVPCommon();
- new mvp_CI_losers[3];
- mvp_CI_losers[0] = findMVPCommon(mvp_CI); // second place
- mvp_CI_losers[1] = findMVPCommon(mvp_CI, mvp_CI_losers[0]); // third
- mvp_CI_losers[2] = findMVPCommon(mvp_CI, mvp_CI_losers[0], mvp_CI_losers[1]); // fourth
-
- for (new i = 0; i <= 2; i++)
- {
- if (IsClientAndInGame(mvp_CI_losers[i]) && !IsFakeClient(mvp_CI_losers[i]))
- {
- if (bSolo)
- {
- if (mvp_CI_losers[i] == client)
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}Your Rank {green}CI{default}: {olive}#%d {blue}({default}%d {green}common {blue}[{default}%.0f%%{blue}])", (i + 2), iGotCommon[mvp_CI_losers[i]], (float(iGotCommon[mvp_CI_losers[i]]) / float(iTotalCommon)) * 100);
- CPrintToChat(mvp_CI_losers[i], "%s", tmpBuffer);
- }
- }
- else
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}Your Rank {green}CI{default}: {olive}#%d {blue}({default}%d {green}common {blue}[{default}%.0f%%{blue}])", (i + 2), iGotCommon[mvp_CI_losers[i]], (float(iGotCommon[mvp_CI_losers[i]]) / float(iTotalCommon)) * 100);
- CPrintToChat(mvp_CI_losers[i], "%s", tmpBuffer);
- }
- }
- }
- }
-
- // tell them they were better with FF (I know, I know, losers = winners)
- if (iTotalFF > 0)
- {
- new mvp_FF = findLVPFF();
- new mvp_FF_losers[3];
- mvp_FF_losers[0] = findLVPFF(mvp_FF); // second place
- mvp_FF_losers[1] = findLVPFF(mvp_FF, mvp_FF_losers[0]); // third
- mvp_FF_losers[2] = findLVPFF(mvp_FF, mvp_FF_losers[0], mvp_FF_losers[1]); // fourth
-
- for (new i = 0; i <= 2; i++)
- {
- if (IsClientAndInGame(mvp_FF_losers[i]) && !IsFakeClient(mvp_FF_losers[i]))
- {
- if (bSolo)
- {
- if (mvp_FF_losers[i] == client)
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}Your Rank {green}FF{default}: {olive}#%d {blue}({default}%d {green}friendly fire {blue}[{default}%.0f%%{blue}])", (i + 2), iDidFF[mvp_FF_losers[i]], (float(iDidFF[mvp_FF_losers[i]]) / float(iTotalFF)) * 100);
- CPrintToChat(mvp_FF_losers[i], "%s", tmpBuffer);
- }
- }
- else
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}Your Rank {green}FF{default}: {olive}#%d {blue}({default}%d {green}friendly fire {blue}[{default}%.0f%%{blue}])", (i + 2), iDidFF[mvp_FF_losers[i]], (float(iDidFF[mvp_FF_losers[i]]) / float(iTotalFF)) * 100);
- CPrintToChat(mvp_FF_losers[i], "%s", tmpBuffer);
- }
- }
- }
- }
+ char tmpBuffer[512];
+ // also find the three non-mvp survivors and tell them they sucked
+ // tell them they sucked with SI
+ if (iTotalDamageAll > 0)
+ {
+ int
+ mvp_SI = findMVPSI(),
+ mvp_SI_losers[3];
+ mvp_SI_losers[0] = findMVPSI(mvp_SI); // second place
+ mvp_SI_losers[1] = findMVPSI(mvp_SI, mvp_SI_losers[0]); // third
+ mvp_SI_losers[2] = findMVPSI(mvp_SI, mvp_SI_losers[0], mvp_SI_losers[1]); // fourth
+
+ for (int i = 0; i <= 2; i++)
+ {
+ if (IsClientAndInGame(mvp_SI_losers[i]) && !IsFakeClient(mvp_SI_losers[i]))
+ {
+ if (bSolo)
+ {
+ if (mvp_SI_losers[i] == client)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t", "YourRankSI", (i + 2), iDidDamageAll[mvp_SI_losers[i]], (float(iDidDamageAll[mvp_SI_losers[i]]) / float(iTotalDamageAll)) * 100, iGotKills[mvp_SI_losers[i]], (float(iGotKills[mvp_SI_losers[i]]) / float(iTotalKills)) * 100);
+ CPrintToChat(mvp_SI_losers[i], "%s", tmpBuffer);
+ }
+ }
+ else
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t", "YourRankSI", (i + 2), iDidDamageAll[mvp_SI_losers[i]], (float(iDidDamageAll[mvp_SI_losers[i]]) / float(iTotalDamageAll)) * 100, iGotKills[mvp_SI_losers[i]], (float(iGotKills[mvp_SI_losers[i]]) / float(iTotalKills)) * 100);
+ CPrintToChat(mvp_SI_losers[i], "%s", tmpBuffer);
+ }
+ }
+ }
+ }
+
+ // tell them they sucked with Common
+ if (iTotalCommon > 0)
+ {
+ int
+ mvp_CI = findMVPCommon(),
+ mvp_CI_losers[3];
+ mvp_CI_losers[0] = findMVPCommon(mvp_CI); // second place
+ mvp_CI_losers[1] = findMVPCommon(mvp_CI, mvp_CI_losers[0]); // third
+ mvp_CI_losers[2] = findMVPCommon(mvp_CI, mvp_CI_losers[0], mvp_CI_losers[1]); // fourth
+
+ for (int i = 0; i <= 2; i++)
+ {
+ if (IsClientAndInGame(mvp_CI_losers[i]) && !IsFakeClient(mvp_CI_losers[i]))
+ {
+ if (bSolo)
+ {
+ if (mvp_CI_losers[i] == client)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t", "YourRankCI", (i + 2), iGotCommon[mvp_CI_losers[i]], (float(iGotCommon[mvp_CI_losers[i]]) / float(iTotalCommon)) * 100);
+ CPrintToChat(mvp_CI_losers[i], "%s", tmpBuffer);
+ }
+ }
+ else
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t", "YourRankCI", (i + 2), iGotCommon[mvp_CI_losers[i]], (float(iGotCommon[mvp_CI_losers[i]]) / float(iTotalCommon)) * 100);
+ CPrintToChat(mvp_CI_losers[i], "%s", tmpBuffer);
+ }
+ }
+ }
+ }
+
+ // tell them they were better with FF (I know, I know, losers = winners)
+ if (iTotalFF > 0)
+ {
+ int
+ mvp_FF = findLVPFF(),
+ mvp_FF_losers[3];
+ mvp_FF_losers[0] = findLVPFF(mvp_FF); // second place
+ mvp_FF_losers[1] = findLVPFF(mvp_FF, mvp_FF_losers[0]); // third
+ mvp_FF_losers[2] = findLVPFF(mvp_FF, mvp_FF_losers[0], mvp_FF_losers[1]); // fourth
+
+ for (int i = 0; i <= 2; i++)
+ {
+ if (IsClientAndInGame(mvp_FF_losers[i]) && !IsFakeClient(mvp_FF_losers[i]))
+ {
+ if (bSolo)
+ {
+ if (mvp_FF_losers[i] == client)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t", "YourRankFF", (i + 2), iDidFF[mvp_FF_losers[i]], (float(iDidFF[mvp_FF_losers[i]]) / float(iTotalFF)) * 100);
+ CPrintToChat(mvp_FF_losers[i], "%s", tmpBuffer);
+ }
+ }
+ else
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t", "YourRankFF", (i + 2), iDidFF[mvp_FF_losers[i]], (float(iDidFF[mvp_FF_losers[i]]) / float(iTotalFF)) * 100);
+ CPrintToChat(mvp_FF_losers[i], "%s", tmpBuffer);
+ }
+ }
+ }
+ }
}
/**
-* When an entity is created (which we use to track rocks)
-* don't actually need this
-*/
-public OnEntityCreated(entity, const String:classname[])
-{
- if(! tankThrow) {
- return;
- }
-
- if(StrEqual(classname, "tank_rock", true)) {
- rockIndex = entity;
- tankThrow = true;
- }
+ * When an entity is created (which we use to track rocks)
+ * don't actually need this
+ */
+public void OnEntityCreated(int entity, const char[] classname)
+{
+ if (!tankThrow)
+ {
+ return;
+ }
+
+ if (StrEqual(classname, "tank_rock", true))
+ {
+ rockIndex = entity;
+ tankThrow = true;
+ }
}
/**
-* When an entity has been destroyed (i.e. when a rock lands on someone)
-*/
-public OnEntityDestroyed(entity)
-{
- // The rock has been destroyed
- if (rockIndex == entity) {
- tankThrow = false;
- }
+ * When an entity has been destroyed (i.e. when a rock lands on someone)
+ */
+public void OnEntityDestroyed(int entity)
+{
+ // The rock has been destroyed
+ if (rockIndex == entity)
+ {
+ tankThrow = false;
+ }
}
/**
-* When an infected uses their ability
-*/
-public Action:abilityUseEvent(Handle:event, const String:name[], bool:dontBroadcast)
+ * When an infected uses their ability
+ */
+public Action abilityUseEvent(Handle event, const char[] name, bool dontBroadcast)
{
- decl String:ability[32];
- GetEventString(event, "ability", ability, 32);
-
- // If tank is throwing a rock
- if(StrEqual(ability, "ability_throw", true)) {
- tankThrow = true;
- }
+ char ability[32];
+ GetEventString(event, "ability", ability, 32);
+
+ // If tank is throwing a rock
+ if (StrEqual(ability, "ability_throw", true))
+ {
+ tankThrow = true;
+ }
+ return Plugin_Continue;
}
/**
-* Track pill usage
-*/
-public pillsUsedEvent(Handle:event, const String:name[], bool:dontBroadcast)
+ * Track pill usage
+ */
+public void pillsUsedEvent(Handle event, const char[] name, bool dontBroadcast)
{
- new client = GetClientOfUserId(GetEventInt(event, "userid"));
- if (client == 0 || ! IsClientInGame(client)) {
- return;
- }
-
- pillsUsed[client]++;
+ int client = GetClientOfUserId(GetEventInt(event, "userid"));
+ if (client == 0 || !IsClientInGame(client))
+ {
+ return;
+ }
+
+ pillsUsed[client]++;
}
/**
-* Track boomer pops
-*/
-public boomerExploded(Handle:event, const String:name[], bool:dontBroadcast)
+ * Track boomer pops
+ */
+public void boomerExploded(Handle event, const char[] name, bool dontBroadcast)
{
- // We only want to track pops where the boomer didn't bile anyone
- new bool:biled = GetEventBool(event, "splashedbile");
- if (! biled) {
- new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
- if (attacker == 0 || ! IsClientInGame(attacker)) {
- return;
- }
- boomerPops[attacker]++;
- }
+ // We only want to track pops where the boomer didn't bile anyone
+ bool biled = GetEventBool(event, "splashedbile");
+ if (!biled)
+ {
+ int attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
+ if (attacker == 0 || !IsClientInGame(attacker))
+ {
+ return;
+ }
+ boomerPops[attacker]++;
+ }
}
-
/**
-* Track when someone gets charged (end of charge for level, or if someone shoots you off etc.)
-*/
-public chargerCarryEnd(Handle:event, const String:name[], bool:dontBroadcast)
+ * Track when someone gets charged (end of charge for level, or if someone shoots you off etc.)
+ */
+public void chargerCarryEnd(Handle event, const char[] name, bool dontBroadcast)
{
- new client = GetClientOfUserId(GetEventInt(event, "victim"));
- if (client == 0 || ! IsClientInGame(client)) {
- return;
- }
-
- timesPinned[client][ZC_CHARGER]++;
- totalPinned[client]++;
-
- if (tankSpawned) {
- ttlPinnedDuringTank[client]++;
- }
+ int client = GetClientOfUserId(GetEventInt(event, "victim"));
+ if (client == 0 || !IsClientInGame(client))
+ {
+ return;
+ }
+
+ timesPinned[client][ZC_CHARGER]++;
+ totalPinned[client]++;
+
+ if (tankSpawned)
+ {
+ ttlPinnedDuringTank[client]++;
+ }
}
/**
-* Track when someone gets jockeyed.
-*/
-public jockeyRide(Handle:event, const String:name[], bool:dontBroadcast)
+ * Track when someone gets jockeyed.
+ */
+public void jockeyRide(Handle event, const char[] name, bool dontBroadcast)
{
- new client = GetClientOfUserId(GetEventInt(event, "victim"));
- if (client == 0 || ! IsClientInGame(client)) {
- return;
- }
-
- timesPinned[client][ZC_JOCKEY]++;
- totalPinned[client]++;
-
- if (tankSpawned) {
- ttlPinnedDuringTank[client]++;
- }
+ int client = GetClientOfUserId(GetEventInt(event, "victim"));
+ if (client == 0 || !IsClientInGame(client))
+ {
+ return;
+ }
+
+ timesPinned[client][ZC_JOCKEY]++;
+ totalPinned[client]++;
+
+ if (tankSpawned)
+ {
+ ttlPinnedDuringTank[client]++;
+ }
}
-/**
-* Track when someone gets huntered.
-*/
-public hunterLunged(Handle:event, const String:name[], bool:dontBroadcast)
+/**
+ * Track when someone gets huntered.
+ */
+public void hunterLunged(Handle event, const char[] name, bool dontBroadcast)
{
- new client = GetClientOfUserId(GetEventInt(event, "victim"));
- if (client == 0 || ! IsClientInGame(client)) {
- return;
- }
-
- timesPinned[client][ZC_HUNTER]++;
- totalPinned[client]++;
-
- if (tankSpawned) {
- ttlPinnedDuringTank[client]++;
- }
+ int client = GetClientOfUserId(GetEventInt(event, "victim"));
+ if (client == 0 || !IsClientInGame(client))
+ {
+ return;
+ }
+
+ timesPinned[client][ZC_HUNTER]++;
+ totalPinned[client]++;
+
+ if (tankSpawned)
+ {
+ ttlPinnedDuringTank[client]++;
+ }
}
/**
-* Track when someone gets smoked (we track when they start getting smoked, because anyone can get smoked)
-*/
-public smokerChoke(Handle:event, const String:name[], bool:dontBroadcast)
+ * Track when someone gets smoked (we track when they start getting smoked, because anyone can get smoked)
+ */
+public void smokerChoke(Handle event, const char[] name, bool dontBroadcast)
{
- new client = GetClientOfUserId(GetEventInt(event, "victim"));
- if (client == 0 || ! IsClientInGame(client)) {
- return;
- }
-
- timesPinned[client][ZC_SMOKER]++;
- totalPinned[client]++;
-
- if (tankSpawned) {
- ttlPinnedDuringTank[client]++;
- }
+ int client = GetClientOfUserId(GetEventInt(event, "victim"));
+ if (client == 0 || !IsClientInGame(client))
+ {
+ return;
+ }
+
+ timesPinned[client][ZC_SMOKER]++;
+ totalPinned[client]++;
+
+ if (tankSpawned)
+ {
+ ttlPinnedDuringTank[client]++;
+ }
}
/**
-* When the tank spawns
-*/
-public tankSpawn(Handle:event, const String:name[], bool:dontBroadcast) {
- tankSpawned = true;
+ * When the tank spawns
+ */
+public void tankSpawn(Handle event, const char[] name, bool dontBroadcast)
+{
+ tankSpawned = true;
}
/**
-* When the tank is killed
-*/
-public tankKilled(Handle:event, const String:name[], bool:dontBroadcast) {
- tankSpawned = false;
+ * When the tank is killed
+ */
+public void tankKilled(Handle event, const char[] name, bool dontBroadcast)
+{
+ tankSpawned = false;
}
/*
-* track damage/kills
-* ==================
-*/
-
-public PlayerHurt_Event(Handle:event, const String:name[], bool:dontBroadcast)
+ * track damage/kills
+ * ==================
+ */
+public void PlayerHurt_Event(Handle event, const char[] name, bool dontBroadcast)
{
- new zombieClass = 0;
-
- // Victim details
- new victimId = GetEventInt(event, "userid");
- new victim = GetClientOfUserId(victimId);
-
- // Attacker details
- new attackerId = GetEventInt(event, "attacker");
- new attacker = GetClientOfUserId(attackerId);
-
- // Misc details
- new damageDone = GetEventInt(event, "dmg_health");
-
- // no world damage or flukes or whatevs, no bot attackers, no infected-to-infected damage
- if (victimId && attackerId && IsClientAndInGame(victim) && IsClientAndInGame(attacker))
- {
- // If a survivor is attacking infected
- if (GetClientTeam(attacker) == TEAM_SURVIVOR && GetClientTeam(victim) == TEAM_INFECTED)
- {
- zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
-
- // Increment the damage for that class to the total
- iDidDamageClass[attacker][zombieClass] += damageDone;
- //PrintToConsole(attacker, "Attacked: %d - Dmg: %d", zombieClass, damageDone);
- //PrintToConsole(attacker, "Total damage for %d: %d", zombieClass, iDidDamageClass[attacker][zombieClass]);
-
- // separately store SI and tank damage
- if (zombieClass >= ZC_SMOKER && zombieClass < ZC_WITCH)
- {
- // If the tank is up, let's store separately
- if (tankSpawned) {
- siDmgDuringTank[attacker] += damageDone;
- //ttlSiDmgDuringTank += damageDone;
- }
-
- iDidDamage[attacker] += damageDone;
- iDidDamageAll[attacker] += damageDone;
- // iTotalDamage += damageDone;
- iTotalDamageAll += damageDone;
- }
- else if (zombieClass == ZC_TANK && damageDone != 5000) // For some reason the last attacker does 5k damage?
- {
- // We want to track tank damage even if we're not factoring it in to our mvp result
- iDidDamageTank[attacker] += damageDone;
- //iTotalDamageTank += damageDone;
-
- // If we're factoring it in, include it in our overall damage
- if (bCountTankDamage)
- {
- iDidDamageAll[attacker] += damageDone;
- iTotalDamageAll += damageDone;
- }
- }
- }
-
- // Otherwise if friendly fire
- else if (GetClientTeam(attacker) == TEAM_SURVIVOR && GetClientTeam(victim) == TEAM_SURVIVOR && bTrackFF) // survivor on survivor action == FF
- {
- if (!bRUPActive || GetEntityMoveType(victim) != MOVETYPE_NONE || bPlayerLeftStartArea) {
- // but don't record while frozen in readyup / before leaving saferoom
- iDidFF[attacker] += damageDone;
- iTotalFF += damageDone;
- }
- }
-
- // Otherwise if infected are inflicting damage on a survivor
- else if (GetClientTeam(attacker) == TEAM_INFECTED && GetClientTeam(victim) == TEAM_SURVIVOR) {
- zombieClass = GetEntProp(attacker, Prop_Send, "m_zombieClass");
-
- // If we got hit by a tank, let's see what type of damage it was
- // If it was from a rock throw
- if (tankThrow && zombieClass == ZC_TANK && damageDone == 24) {
- rocksEaten[victim]++;
- }
- damageReceived[victim] += damageDone;
- }
- }
+ int
+ zombieClass = 0,
+ // Victim details
+ victimId = GetEventInt(event, "userid"),
+ victim = GetClientOfUserId(victimId),
+ // Attacker details
+ attackerId = GetEventInt(event, "attacker"),
+ attacker = GetClientOfUserId(attackerId),
+ // Misc details
+ damageDone = GetEventInt(event, "dmg_health");
+
+ // no world damage or flukes or whatevs, no bot attackers, no infected-to-infected damage
+ if (victimId && attackerId && IsClientAndInGame(victim) && IsClientAndInGame(attacker))
+ {
+ // If a survivor is attacking infected
+ if (GetClientTeam(attacker) == TEAM_SURVIVOR && GetClientTeam(victim) == TEAM_INFECTED)
+ {
+ zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
+
+ // Increment the damage for that class to the total
+ iDidDamageClass[attacker][zombieClass] += damageDone;
+
+ // separately store SI and tank damage
+ if (zombieClass >= ZC_SMOKER && zombieClass < ZC_WITCH)
+ {
+ // If the tank is up, let's store separately
+ if (tankSpawned)
+ {
+ siDmgDuringTank[attacker] += damageDone;
+ }
+
+ iDidDamage[attacker] += damageDone;
+ iDidDamageAll[attacker] += damageDone;
+ iTotalDamageAll += damageDone;
+ }
+ else if (zombieClass == ZC_TANK && damageDone != 5000) // For some reason the last attacker does 5k damage?
+ {
+ // We want to track tank damage even if we're not factoring it in to our mvp result
+ iDidDamageTank[attacker] += damageDone;
+
+ // If we're factoring it in, include it in our overall damage
+ if (bCountTankDamage)
+ {
+ iDidDamageAll[attacker] += damageDone;
+ iTotalDamageAll += damageDone;
+ }
+ }
+ }
+
+ // Otherwise if friendly fire
+ else if (GetClientTeam(attacker) == TEAM_SURVIVOR && GetClientTeam(victim) == TEAM_SURVIVOR && bTrackFF) // survivor on survivor action == FF
+ {
+ if (!bRUPActive || GetEntityMoveType(victim) != MOVETYPE_NONE || bPlayerLeftStartArea)
+ {
+ // but don't record while frozen in readyup / before leaving saferoom
+ iDidFF[attacker] += damageDone;
+ iTotalFF += damageDone;
+ }
+ }
+
+ // Otherwise if infected are inflicting damage on a survivor
+ else if (GetClientTeam(attacker) == TEAM_INFECTED && GetClientTeam(victim) == TEAM_SURVIVOR)
+ {
+ zombieClass = GetEntProp(attacker, Prop_Send, "m_zombieClass");
+
+ // If we got hit by a tank, let's see what type of damage it was
+ // If it was from a rock throw
+ if (tankThrow && zombieClass == ZC_TANK && damageDone == 24)
+ {
+ rocksEaten[victim]++;
+ }
+ damageReceived[victim] += damageDone;
+ }
+ }
}
-/**
-* When the infected are hurt (i.e. when a survivor hurts an SI)
-* We want to use this to track damage done to the witch.
-*/
-public InfectedHurt_Event(Handle:event, const String:name[], bool:dontBroadcast)
+/**
+ * When the infected are hurt (i.e. when a survivor hurts an SI)
+ * We want to use this to track damage done to the witch.
+ */
+public void InfectedHurt_Event(Handle event, const char[] name, bool dontBroadcast)
{
- // catch damage done to witch
- new victimEntId = GetEventInt(event, "entityid");
-
- if (IsWitch(victimEntId))
- {
- new attackerId = GetEventInt(event, "attacker");
- new attacker = GetClientOfUserId(attackerId);
- new damageDone = GetEventInt(event, "amount");
-
- // no world damage or flukes or whatevs, no bot attackers
- if (attackerId && IsClientAndInGame(attacker) && GetClientTeam(attacker) == TEAM_SURVIVOR)
- {
- // We want to track the witch damage regardless of whether we're counting it in our mvp stat
- iDidDamageWitch[attacker] += damageDone;
- //iTotalDamageWitch += damageDone;
-
- // If we're counting witch damage in our mvp stat, lets add the amount of damage done to the witch
- if (bCountWitchDamage)
- {
- iDidDamageAll[attacker] += damageDone;
- iTotalDamageAll += damageDone;
- }
- }
- }
+ // catch damage done to witch
+ int victimEntId = GetEventInt(event, "entityid");
+
+ if (IsWitch(victimEntId))
+ {
+ int
+ attackerId = GetEventInt(event, "attacker"),
+ attacker = GetClientOfUserId(attackerId),
+ damageDone = GetEventInt(event, "amount");
+
+ // no world damage or flukes or whatevs, no bot attackers
+ if (attackerId && IsClientAndInGame(attacker) && GetClientTeam(attacker) == TEAM_SURVIVOR)
+ {
+ // We want to track the witch damage regardless of whether we're counting it in our mvp stat
+ iDidDamageWitch[attacker] += damageDone;
+
+ // If we're counting witch damage in our mvp stat, lets add the amount of damage done to the witch
+ if (bCountWitchDamage)
+ {
+ iDidDamageAll[attacker] += damageDone;
+ iTotalDamageAll += damageDone;
+ }
+ }
+ }
}
-public PlayerDeath_Event(Handle:event, const String:name[], bool:dontBroadcast)
+public void PlayerDeath_Event(Handle event, const char[] name, bool dontBroadcast)
{
- // Get the victim details
- new zombieClass = 0;
- new victimId = GetEventInt(event, "userid");
- new victim = GetClientOfUserId(victimId);
-
- // Get the attacker details
- new attackerId = GetEventInt(event, "attacker");
- new attacker = GetClientOfUserId(attackerId);
-
- // no world kills or flukes or whatevs, no bot attackers
- if (victimId && attackerId && IsClientAndInGame(victim) && IsClientAndInGame(attacker) && GetClientTeam(attacker) == TEAM_SURVIVOR)
- {
- zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
-
- // only SI, not the tank && only player-attackers
- if (zombieClass >= ZC_SMOKER && zombieClass < ZC_WITCH)
- {
- // store kill to count for attacker id
- iGotKills[attacker]++;
- iTotalKills++;
- }
- }
-
- /**
- * Are we tracking the tank?
- * This is a secondary measure. For some reason when I test locally in PM, the
- * tank_killed event is triggered, but when I test in a custom config, it's not.
- * Hopefully this should fix it.
- */
- if (victimId && IsClientAndInGame(victim)) {
- zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
- if (zombieClass == ZC_TANK) {
- tankSpawned = false;
- }
- }
+ // Get the victim details
+ int
+ zombieClass = 0,
+ victimId = GetEventInt(event, "userid"),
+ victim = GetClientOfUserId(victimId),
+ // Get the attacker details
+ attackerId = GetEventInt(event, "attacker"),
+ attacker = GetClientOfUserId(attackerId);
+
+ // no world kills or flukes or whatevs, no bot attackers
+ if (victimId && attackerId && IsClientAndInGame(victim) && IsClientAndInGame(attacker) && GetClientTeam(attacker) == TEAM_SURVIVOR)
+ {
+ zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
+
+ // only SI, not the tank && only player-attackers
+ if (zombieClass >= ZC_SMOKER && zombieClass < ZC_WITCH)
+ {
+ // store kill to count for attacker id
+ iGotKills[attacker]++;
+ iTotalKills++;
+ }
+ }
+
+ /**
+ * Are we tracking the tank?
+ * This is a secondary measure. For some reason when I test locally in PM, the
+ * tank_killed event is triggered, but when I test in a custom config, it's not.
+ * Hopefully this should fix it.
+ */
+ if (victimId && IsClientAndInGame(victim))
+ {
+ zombieClass = GetEntProp(victim, Prop_Send, "m_zombieClass");
+ if (zombieClass == ZC_TANK)
+ {
+ tankSpawned = false;
+ }
+ }
}
// Was the zombie a hunter?
-public bool:isHunter(zombieClass) {
- return zombieClass == ZC_HUNTER;
+public bool isHunter(int zombieClass)
+{
+ return zombieClass == ZC_HUNTER;
}
-public InfectedDeath_Event(Handle:event, const String:name[], bool:dontBroadcast)
+public void InfectedDeath_Event(Handle event, const char[] name, bool dontBroadcast)
{
- new attackerId = GetEventInt(event, "attacker");
- new attacker = GetClientOfUserId(attackerId);
-
- if (attackerId && IsClientAndInGame(attacker) && GetClientTeam(attacker) == TEAM_SURVIVOR)
- {
- // If the tank is up, let's store separately
- if (tankSpawned) {
- commonKilledDuringTank[attacker]++;
- ttlCommonKilledDuringTank++;
- }
-
- iGotCommon[attacker]++;
- iTotalCommon++;
- // if victimType > 2, it's an "uncommon" (of some type or other) -- do nothing with this ftpresent.
- }
+ int
+ attackerId = GetEventInt(event, "attacker"),
+ attacker = GetClientOfUserId(attackerId);
+
+ if (attackerId && IsClientAndInGame(attacker) && GetClientTeam(attacker) == TEAM_SURVIVOR)
+ {
+ // If the tank is up, let's store separately
+ if (tankSpawned)
+ {
+ commonKilledDuringTank[attacker]++;
+ ttlCommonKilledDuringTank++;
+ }
+
+ iGotCommon[attacker]++;
+ iTotalCommon++;
+ // if victimType > 2, it's an "uncommon" (of some type or other) -- do nothing with this ftpresent.
+ }
}
/*
-* MVP string & 'sorting'
-* ======================
-*/
+ * MVP string & 'sorting'
+ * ======================
+ */
void GetMVPString(char[] printBuffer, const int iSize)
{
- decl String:tmpBuffer[1024];
- printBuffer[0] = '\0';
-
- decl String:tmpName[64];
- decl String:mvp_SI_name[64];
- decl String:mvp_Common_name[64];
- decl String:mvp_FF_name[64];
-
- new mvp_SI = 0;
- new mvp_Common = 0;
- new mvp_FF = 0;
-
- // calculate MVP per category:
- // 1. SI damage & SI kills + damage to tank/witch
- // 2. common kills
-
- // SI MVP
- if (!(iBrevityFlags & BREV_SI))
- {
- mvp_SI = findMVPSI();
- if (mvp_SI > 0)
- {
- // get name from client if connected -- if not, use sClientName array
- if (IsClientConnected(mvp_SI))
- {
- GetClientName(mvp_SI, tmpName, sizeof(tmpName));
- if (IsFakeClient(mvp_SI))
- {
- StrCat(tmpName, 64, " \x01[BOT]");
- }
- } else {
- strcopy(tmpName, 64, sClientName[mvp_SI]);
- }
- mvp_SI_name = tmpName;
- } else {
- mvp_SI_name = "(nobody)";
- }
- }
-
- // Common MVP
- if (!(iBrevityFlags & BREV_CI))
- {
- mvp_Common = findMVPCommon();
- if (mvp_Common > 0)
- {
- // get name from client if connected -- if not, use sClientName array
- if (IsClientConnected(mvp_Common))
- {
- GetClientName(mvp_Common, tmpName, sizeof(tmpName));
- if (IsFakeClient(mvp_Common))
- {
- StrCat(tmpName, 64, " \x01[BOT]");
- }
- } else {
- strcopy(tmpName, 64, sClientName[mvp_Common]);
- }
- mvp_Common_name = tmpName;
- } else {
- mvp_Common_name = "(nobody)";
- }
- }
-
- // FF LVP
- if (!(iBrevityFlags & BREV_FF) && bTrackFF)
- {
- mvp_FF = findLVPFF();
- if (mvp_FF > 0)
- {
- // get name from client if connected -- if not, use sClientName array
- if (IsClientConnected(mvp_FF))
- {
- GetClientName(mvp_FF, tmpName, sizeof(tmpName));
- if (IsFakeClient(mvp_FF))
- {
- StrCat(tmpName, 64, " \x01[BOT]");
- }
- } else {
- strcopy(tmpName, 64, sClientName[mvp_FF]);
- }
- mvp_FF_name = tmpName;
- } else {
- mvp_FF_name = "(nobody)";
- }
- }
-
- // report
-
- if (mvp_SI == 0 && mvp_Common == 0 && !(iBrevityFlags & BREV_SI && iBrevityFlags & BREV_CI))
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}[{default}MVP{blue}]{default} {blue}({default}not enough action yet{blue}){default}\n");
- StrCat(printBuffer, iSize, tmpBuffer);
- }
- else
- {
- if (!(iBrevityFlags & BREV_SI))
- {
- if (mvp_SI > 0)
- {
- if (iBrevityFlags & BREV_PERCENT) {
- Format(tmpBuffer, sizeof(tmpBuffer), "[MVP] SI:\x03 %s \x01(\x05%d \x01dmg,\x05 %d \x01kills)\n", mvp_SI_name, iDidDamageAll[mvp_SI], iGotKills[mvp_SI]);
- } else if (iBrevityFlags & BREV_ABSOLUTE) {
- Format(tmpBuffer, sizeof(tmpBuffer), "[MVP] SI:\x03 %s \x01(dmg \x04%2.0f%%\x01, kills \x04%.0f%%\x01)\n", mvp_SI_name, (float(iDidDamageAll[mvp_SI]) / float(iTotalDamageAll)) * 100, (float(iGotKills[mvp_SI]) / float(iTotalKills)) * 100);
- } else {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}[{default}MVP{blue}] SI: {olive}%s {blue}({default}%d {green}dmg {blue}[{default}%.0f%%{blue}]{olive}, {default}%d {green}kills {blue}[{default}%.0f%%{blue}])\n", mvp_SI_name, iDidDamageAll[mvp_SI], (float(iDidDamageAll[mvp_SI]) / float(iTotalDamageAll)) * 100, iGotKills[mvp_SI], (float(iGotKills[mvp_SI]) / float(iTotalKills)) * 100);
- }
- StrCat(printBuffer, iSize, tmpBuffer);
- }
- else
- {
- StrCat(printBuffer, iSize, "{blue}[{default}MVP{blue}] SI: {blue}({default}nobody{blue}){default}\n");
- }
- }
-
- if (!(iBrevityFlags & BREV_CI))
- {
- if (mvp_Common > 0)
- {
- if (iBrevityFlags & BREV_PERCENT) {
- Format(tmpBuffer, sizeof(tmpBuffer), "[MVP] CI:\x03 %s \x01(\x05%d \x01common)\n", mvp_Common_name, iGotCommon[mvp_Common]);
- } else if (iBrevityFlags & BREV_ABSOLUTE) {
- Format(tmpBuffer, sizeof(tmpBuffer), "[MVP] CI:\x03 %s \x01(\x04%.0f%%\x01)\n", mvp_Common_name, (float(iGotCommon[mvp_Common]) / float(iTotalCommon)) * 100);
- } else {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}[{default}MVP{blue}] CI: {olive}%s {blue}({default}%d {green}common {blue}[{default}%.0f%%{blue}])\n", mvp_Common_name, iGotCommon[mvp_Common], (float(iGotCommon[mvp_Common]) / float(iTotalCommon)) * 100);
- }
- StrCat(printBuffer, iSize, tmpBuffer);
- }
- }
- }
-
- // FF
- if (!(iBrevityFlags & BREV_FF) && bTrackFF)
- {
- if (mvp_FF == 0)
- {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}[{default}LVP{blue}] FF{default}: {green}no friendly fire at all!{default}\n");
- StrCat(printBuffer, iSize, tmpBuffer);
- }
- else
- {
- if (iBrevityFlags & BREV_PERCENT) {
- Format(tmpBuffer, sizeof(tmpBuffer), "[LVP] FF:\x03 %s \x01(\x05%d \x01dmg)\n", mvp_FF_name, iDidFF[mvp_FF]);
- } else if (iBrevityFlags & BREV_ABSOLUTE) {
- Format(tmpBuffer, sizeof(tmpBuffer), "[LVP] FF:\x03 %s \x01(\x04%.0f%%\x01)\n", mvp_FF_name, (float(iDidFF[mvp_FF]) / float(iTotalFF)) * 100);
- } else {
- Format(tmpBuffer, sizeof(tmpBuffer), "{blue}[{default}LVP{blue}] FF{default}: {olive}%s {blue}({default}%d {green}friendly fire {blue}[{default}%.0f%%{blue}]){default}\n", mvp_FF_name, iDidFF[mvp_FF], (float(iDidFF[mvp_FF]) / float(iTotalFF)) * 100);
- }
- StrCat(printBuffer, iSize, tmpBuffer);
- }
- }
+ printBuffer[0] = '\0';
+ char
+ tmpBuffer[1024],
+ tmpName[128],
+ botName[16],
+ nobodyName[16],
+ mvp_SI_name[128],
+ mvp_Common_name[128],
+ mvp_FF_name[128];
+
+ int
+ mvp_SI = 0,
+ mvp_Common = 0,
+ mvp_FF = 0;
+
+ Format(botName, sizeof(botName), "%t", "BotName");
+ Format(nobodyName, sizeof(nobodyName), "%t", "NobodyName");
+ // calculate MVP per category:
+ // 1. SI damage & SI kills + damage to tank/witch
+ // 2. common kills
+
+ // SI MVP
+ if (!(iBrevityFlags & BREV_SI))
+ {
+ mvp_SI = findMVPSI();
+ if (mvp_SI > 0)
+ {
+ // get name from client if connected -- if not, use sClientName array
+ if (IsClientConnected(mvp_SI))
+ {
+ GetClientName(mvp_SI, tmpName, sizeof(tmpName));
+ if (IsFakeClient(mvp_SI))
+ {
+ StrCat(tmpName, sizeof(tmpName), botName);
+ }
+ }
+ else
+ {
+ strcopy(tmpName, sizeof(tmpName), sClientName[mvp_SI]);
+ }
+ mvp_SI_name = tmpName;
+ }
+ else
+ {
+ mvp_SI_name = nobodyName;
+ }
+ }
+
+ // Common MVP
+ if (!(iBrevityFlags & BREV_CI))
+ {
+ mvp_Common = findMVPCommon();
+ if (mvp_Common > 0)
+ {
+ // get name from client if connected -- if not, use sClientName array
+ if (IsClientConnected(mvp_Common))
+ {
+ GetClientName(mvp_Common, tmpName, sizeof(tmpName));
+ if (IsFakeClient(mvp_Common))
+ {
+ StrCat(tmpName, sizeof(tmpName), botName);
+ }
+ }
+ else
+ {
+ strcopy(tmpName, sizeof(tmpName), sClientName[mvp_Common]);
+ }
+ mvp_Common_name = tmpName;
+ }
+ else
+ {
+ mvp_Common_name = nobodyName;
+ }
+ }
+
+ // FF LVP
+ if (!(iBrevityFlags & BREV_FF) && bTrackFF)
+ {
+ mvp_FF = findLVPFF();
+ if (mvp_FF > 0)
+ {
+ // get name from client if connected -- if not, use sClientName array
+ if (IsClientConnected(mvp_FF))
+ {
+ GetClientName(mvp_FF, tmpName, sizeof(tmpName));
+ if (IsFakeClient(mvp_FF))
+ {
+ StrCat(tmpName, sizeof(tmpName), botName);
+ }
+ }
+ else {
+ strcopy(tmpName, sizeof(tmpName), sClientName[mvp_FF]);
+ }
+ mvp_FF_name = tmpName;
+ }
+ else
+ {
+ mvp_FF_name = nobodyName;
+ }
+ }
+
+ // report
+
+ if (mvp_SI == 0 && mvp_Common == 0 && !(iBrevityFlags & BREV_SI && iBrevityFlags & BREV_CI))
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "NotEnoughAction");
+ StrCat(printBuffer, iSize, tmpBuffer);
+ }
+ else
+ {
+ if (!(iBrevityFlags & BREV_SI))
+ {
+ if (mvp_SI > 0)
+ {
+ if (iBrevityFlags & BREV_PERCENT)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportSI_Absolute", mvp_SI_name, iDidDamageAll[mvp_SI], iGotKills[mvp_SI]);
+ }
+ else if (iBrevityFlags & BREV_ABSOLUTE)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportSI_Percent", mvp_SI_name, (float(iDidDamageAll[mvp_SI]) / float(iTotalDamageAll)) * 100, (float(iGotKills[mvp_SI]) / float(iTotalKills)) * 100);
+ }
+ else
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportSI_Full", mvp_SI_name, iDidDamageAll[mvp_SI], (float(iDidDamageAll[mvp_SI]) / float(iTotalDamageAll)) * 100, iGotKills[mvp_SI], (float(iGotKills[mvp_SI]) / float(iTotalKills)) * 100);
+ }
+ StrCat(printBuffer, iSize, tmpBuffer);
+ }
+ else
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportSI_Nobody");
+ StrCat(printBuffer, iSize, tmpBuffer);
+ }
+ }
+
+ if (!(iBrevityFlags & BREV_CI))
+ {
+ if (mvp_Common > 0)
+ {
+ if (iBrevityFlags & BREV_PERCENT)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportCI_Absolute", mvp_Common_name, iGotCommon[mvp_Common]);
+ }
+ else if (iBrevityFlags & BREV_ABSOLUTE)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportCI_Percent", mvp_Common_name, (float(iGotCommon[mvp_Common]) / float(iTotalCommon)) * 100);
+ }
+ else
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportCI_Full", mvp_Common_name, iGotCommon[mvp_Common], (float(iGotCommon[mvp_Common]) / float(iTotalCommon)) * 100);
+ }
+ StrCat(printBuffer, iSize, tmpBuffer);
+ }
+ }
+ }
+
+ // FF
+ if (!(iBrevityFlags & BREV_FF) && bTrackFF)
+ {
+ if (mvp_FF == 0)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "NoFF");
+ StrCat(printBuffer, iSize, tmpBuffer);
+ }
+ else
+ {
+ if (iBrevityFlags & BREV_PERCENT)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportFF_Absolute", mvp_FF_name, iDidFF[mvp_FF]);
+ }
+ else if (iBrevityFlags & BREV_ABSOLUTE)
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportFF_Percent", mvp_FF_name, (float(iDidFF[mvp_FF]) / float(iTotalFF)) * 100);
+ }
+ else
+ {
+ Format(tmpBuffer, sizeof(tmpBuffer), "%t %t\n", "Tag", "ReportFF_Full", mvp_FF_name, iDidFF[mvp_FF], (float(iDidFF[mvp_FF]) / float(iTotalFF)) * 100);
+ }
+ StrCat(printBuffer, iSize, tmpBuffer);
+ }
+ }
}
-
-findMVPSI(excludeMeA = 0, excludeMeB = 0, excludeMeC = 0)
+int findMVPSI(int excludeMeA = 0, int excludeMeB = 0, int excludeMeC = 0)
{
- new i, maxIndex = 0;
- for(i = 1; i < sizeof(iDidDamageAll); i++)
- {
- if(iDidDamageAll[i] > iDidDamageAll[maxIndex] && i != excludeMeA && i != excludeMeB && i != excludeMeC)
- maxIndex = i;
- }
- return maxIndex;
+ int
+ i,
+ maxIndex = 0;
+ for (i = 1; i < sizeof(iDidDamageAll); i++)
+ {
+ if (iDidDamageAll[i] > iDidDamageAll[maxIndex] && i != excludeMeA && i != excludeMeB && i != excludeMeC)
+ maxIndex = i;
+ }
+ return maxIndex;
}
-findMVPCommon(excludeMeA = 0, excludeMeB = 0, excludeMeC = 0)
+int findMVPCommon(int excludeMeA = 0, int excludeMeB = 0, int excludeMeC = 0)
{
- new i, maxIndex = 0;
- for(i = 1; i < sizeof(iGotCommon); i++)
- {
- if(iGotCommon[i] > iGotCommon[maxIndex] && i != excludeMeA && i != excludeMeB && i != excludeMeC)
- maxIndex = i;
- }
- return maxIndex;
+ int
+ i,
+ maxIndex = 0;
+ for (i = 1; i < sizeof(iGotCommon); i++)
+ {
+ if (iGotCommon[i] > iGotCommon[maxIndex] && i != excludeMeA && i != excludeMeB && i != excludeMeC)
+ maxIndex = i;
+ }
+ return maxIndex;
}
-findLVPFF(excludeMeA = 0, excludeMeB = 0, excludeMeC = 0)
+int findLVPFF(int excludeMeA = 0, int excludeMeB = 0, int excludeMeC = 0)
{
- new i, maxIndex = 0;
- for(i = 1; i < sizeof(iDidFF); i++)
- {
- if(iDidFF[i] > iDidFF[maxIndex] && i != excludeMeA && i != excludeMeB && i != excludeMeC)
- maxIndex = i;
- }
- return maxIndex;
+ int i, maxIndex = 0;
+ for (i = 1; i < sizeof(iDidFF); i++)
+ {
+ if (iDidFF[i] > iDidFF[maxIndex] && i != excludeMeA && i != excludeMeB && i != excludeMeC)
+ maxIndex = i;
+ }
+ return maxIndex;
}
-
/*
-* general functions
-* =================
-*/
+ * general functions
+ * =================
+ */
-
-stock bool:IsClientAndInGame(index)
-{
- return (index > 0 && index <= MaxClients && IsClientInGame(index));
-}
-
-stock bool:IsSurvivor(client)
-{
- return IsClientAndInGame(client) && GetClientTeam(client) == TEAM_SURVIVOR;
-}
-
-stock bool:IsInfected(client)
+stock bool IsClientAndInGame(int index)
{
- return IsClientAndInGame(client) && GetClientTeam(client) == TEAM_INFECTED;
+ return (index > 0 && index <= MaxClients && IsClientInGame(index));
}
-stock bool:IsWitch(iEntity)
+stock bool IsSurvivor(int client)
{
- if(iEntity > 0 && IsValidEntity(iEntity) && IsValidEdict(iEntity))
- {
- decl String:strClassName[64];
- GetEdictClassname(iEntity, strClassName, sizeof(strClassName));
- return StrEqual(strClassName, "witch");
- }
- return false;
+ return IsClientAndInGame(client) && GetClientTeam(client) == TEAM_SURVIVOR;
}
-stock getSurvivor(exclude[4])
+stock bool IsInfected(int client)
{
- for(new i=1; i <= MaxClients; i++) {
- if (IsSurvivor(i)) {
- new tagged = false;
- // exclude already tagged survs
- for (new j=0; j < 4; j++) {
- if (exclude[j] == i) { tagged = true; }
- }
- if (!tagged) {
- return i;
- }
- }
- }
- return 0;
+ return IsClientAndInGame(client) && GetClientTeam(client) == TEAM_INFECTED;
}
-public stripUnicode(String:testString[MAX_NAME_LENGTH])
+stock bool IsWitch(int iEntity)
{
- new const maxlength = MAX_NAME_LENGTH;
- //strcopy(testString, maxlength, sTmpString);
- sTmpString = testString;
-
- new uni=0;
- new currentChar;
- new tmpCharLength = 0;
- //new iReplace[MAX_NAME_LENGTH]; // replace these chars
-
- for (new i=0; i < maxlength - 3 && sTmpString[i] != 0; i++)
- {
- // estimate current character value
- if ((sTmpString[i]&0x80) == 0) // single byte character?
- {
- currentChar=sTmpString[i]; tmpCharLength = 0;
- } else if (((sTmpString[i]&0xE0) == 0xC0) && ((sTmpString[i+1]&0xC0) == 0x80)) // two byte character?
- {
- currentChar=(sTmpString[i++] & 0x1f); currentChar=currentChar<<6;
- currentChar+=(sTmpString[i] & 0x3f);
- tmpCharLength = 1;
- } else if (((sTmpString[i]&0xF0) == 0xE0) && ((sTmpString[i+1]&0xC0) == 0x80) && ((sTmpString[i+2]&0xC0) == 0x80)) // three byte character?
- {
- currentChar=(sTmpString[i++] & 0x0f); currentChar=currentChar<<6;
- currentChar+=(sTmpString[i++] & 0x3f); currentChar=currentChar<<6;
- currentChar+=(sTmpString[i] & 0x3f);
- tmpCharLength = 2;
- } else if (((sTmpString[i]&0xF8) == 0xF0) && ((sTmpString[i+1]&0xC0) == 0x80) && ((sTmpString[i+2]&0xC0) == 0x80) && ((sTmpString[i+3]&0xC0) == 0x80)) // four byte character?
- {
- currentChar=(sTmpString[i++] & 0x07); currentChar=currentChar<<6;
- currentChar+=(sTmpString[i++] & 0x3f); currentChar=currentChar<<6;
- currentChar+=(sTmpString[i++] & 0x3f); currentChar=currentChar<<6;
- currentChar+=(sTmpString[i] & 0x3f);
- tmpCharLength = 3;
- } else
- {
- currentChar=CHARTHRESHOLD + 1; // reaching this may be caused by bug in sourcemod or some kind of bug using by the user - for unicode users I do assume last ...
- tmpCharLength = 0;
- }
-
- // decide if character is allowed
- if (currentChar > CHARTHRESHOLD)
- {
- uni++;
- // replace this character // 95 = _, 32 = space
- for (new j=tmpCharLength; j >= 0; j--) {
- sTmpString[i - j] = 95;
- }
- }
- }
+ if (iEntity > 0 && IsValidEntity(iEntity) && IsValidEdict(iEntity))
+ {
+ char strClassName[64];
+ GetEdictClassname(iEntity, strClassName, sizeof(strClassName));
+ return StrEqual(strClassName, "witch");
+ }
+ return false;
}
-/*
-stock bool:IsCommonInfected(iEntity)
+stock int getSurvivor(int exclude[4])
{
-if(iEntity > 0 && IsValidEntity(iEntity) && IsValidEdict(iEntity))
-{
-decl String:strClassName[64];
-GetEdictClassname(iEntity, strClassName, sizeof(strClassName));
-return StrEqual(strClassName, "infected");
-}
-return false;
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (IsSurvivor(i))
+ {
+ bool tagged = false;
+ // exclude already tagged survs
+ for (int j = 0; j < 4; j++)
+ {
+ if (exclude[j] == i)
+ {
+ tagged = true;
+ }
+ }
+ if (!tagged)
+ {
+ return i;
+ }
+ }
+ }
+ return 0;
}
-*/
\ No newline at end of file
diff --git a/addons/sourcemod/scripting/survivor_mvp_test.sp b/addons/sourcemod/scripting/survivor_mvp_test.sp
new file mode 100644
index 000000000..3864656ec
--- /dev/null
+++ b/addons/sourcemod/scripting/survivor_mvp_test.sp
@@ -0,0 +1,73 @@
+/**
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ */
+
+#pragma semicolon 1
+#pragma newdecls required
+
+#include
+#include
+#include
+
+public Plugin myinfo =
+{
+ name = "Survivor MVP Test",
+ author = "Lechuga",
+ description = "Test MVP functions",
+ version = "1.0",
+ url = ""
+};
+
+public void OnPluginStart()
+{
+ RegConsoleCmd("sm_mvptest", Cmd_MVP, "Shows all available stats for Survivor MVP");
+}
+
+public Action Cmd_MVP(int client, int args)
+{
+ if( args < 0 )
+ {
+ return Plugin_Handled;
+ }
+
+ int
+ GetMVP = SURVMVP_GetMVP(),
+ GetMVPDmgCount = SURVMVP_GetMVPDmgCount(client),
+ GetMVPKills = SURVMVP_GetMVPKills(client),
+ GetMVPCI = SURVMVP_GetMVPCI(),
+ GetMVPCIKills = SURVMVP_GetMVPCIKills(client);
+
+ float
+ GetMVPDmgPercent = SURVMVP_GetMVPDmgPercent(client),
+ GetMVPCIPercent = SURVMVP_GetMVPCIPercent(client);
+
+ CPrintToChat(client, "Current round MVP: {olive}%N{default}", GetMVP);
+ CPrintToChat(client, "Damage of client: {olive}%d{default}", GetMVPDmgCount);
+ CPrintToChat(client, "SI kills of client: {olive}%d{default}", GetMVPKills);
+ CPrintToChat(client, "Damage percent of client: {olive}%f{default}", GetMVPDmgPercent);
+ CPrintToChat(client, "Current round MVP client (Common): {olive}%N{default}", GetMVPCI);
+ CPrintToChat(client, "Common kills for client: {olive}%d{default}", GetMVPCIKills);
+ CPrintToChat(client, "CI percent of client: {olive}%f{default}", GetMVPCIPercent);
+ return Plugin_Handled;
+}
\ No newline at end of file
diff --git a/addons/sourcemod/scripting/teamflip.sp b/addons/sourcemod/scripting/teamflip.sp
index 8cdc09155..8efe4a076 100644
--- a/addons/sourcemod/scripting/teamflip.sp
+++ b/addons/sourcemod/scripting/teamflip.sp
@@ -6,53 +6,108 @@
This version was made out of convenience
*/
-
+#pragma semicolon 1
+#pragma newdecls required
+
#include
#include
+#include
+
+enum L4D2Team
+{
+ L4D2Team_None = 0,
+ L4D2Team_Spectator,
+ L4D2Team_Survivor,
+ L4D2Team_Infected,
+
+ L4D2Team_Size //4 size
+}
-new result_int;
-new String:client_name[32]; // Used to store the client_name of the player who calls teamflip
-new previous_timeC = 0; // Used for teamflip
-new current_timeC = 0; // Used for teamflip
-new Handle:delay_time; // Handle for the teamflip_delay cvar
+int
+ result_int,
+ previous_timeC = 0, // Used for teamflip
+ current_timeC = 0; // Used for teamflip
+char
+ client_name[32]; // Used to store the client_name of the player who calls teamflip
+ConVar
+ delay_time; // Handle for the teamflip_delay cvar
+bool
+ swaptoIsAvailable;
-public Plugin:myinfo =
+public Plugin myinfo =
{
name = "Teamflip",
author = "purpletreefactory, epilimic",
description = "coinflip, but for teams!",
- version = "1.0.1.0.1.0",
+ version = "1.0.1.0.1.0.1.0",
url = "http://www.sourcemod.net/"
}
-public OnPluginStart()
+public void OnPluginStart()
{
- delay_time = CreateConVar("teamflip_delay","-1", "Time delay in seconds between allowed teamflips. Set at -1 if no delay at all is desired.");
+ LoadTranslation("teamflip.phrases");
+ delay_time = CreateConVar("teamflip_delay","-1", "Time delay in seconds between allowed teamflips. Set at -1 if no delay at all is desired.", FCVAR_NONE, true, -1.0);
RegConsoleCmd("sm_teamflip", Command_teamflip);
RegConsoleCmd("sm_tf", Command_teamflip);
}
-public Action:Command_teamflip(client, args)
+public void OnAllPluginsLoaded()
+{
+ swaptoIsAvailable = CommandExists("sm_swapto");
+}
+
+void LoadTranslation(char[] sTranslation)
+{
+ char
+ sPath[PLATFORM_MAX_PATH],
+ sName[64];
+
+ Format(sName, sizeof(sName), "translations/%s.txt", sTranslation);
+ BuildPath(Path_SM, sPath, sizeof(sPath), sName);
+ if (!FileExists(sPath))
+ {
+ SetFailState("Missing translation file %s.txt", sTranslation);
+ }
+ LoadTranslations(sTranslation);
+}
+
+public Action Command_teamflip(int client, int args)
{
current_timeC = GetTime();
- if((current_timeC - previous_timeC) > GetConVarInt(delay_time)) // Only perform a teamflip if enough time has passed since the last one. This prevents spamming.
+ if((current_timeC - previous_timeC) > delay_time.IntValue) // Only perform a teamflip if enough time has passed since the last one. This prevents spamming.
{
result_int = GetURandomInt() % 2; // Gets a random integer and checks to see whether it's odd or even
GetClientName(client, client_name, sizeof(client_name)); // Gets the client_name of the person using the command
if(result_int == 0)
- PrintToChatAll("\x01[\x05Teamflip\x01] \x03%s\x01 flipped a team and is on the \x03Survivor \x01team!", client_name); // Here {green} is actually yellow
+ {
+ CPrintToChatAll("%t %t", "Tag", "FlippedSurvivor", client_name); // Here {green} is actually yellow
+ if(swaptoIsAvailable && GetClientTeamEx(client) != L4D2Team_Survivor)
+ {
+ ServerCommand("sm_swapto 2 #%i", GetClientUserId(client));
+ }
+ }
else
- PrintToChatAll("\x01[\x05Teamflip\x01] \x03%s\x01 flipped a team and is on the \x03Infected \x01team!", client_name);
-
+ {
+ CPrintToChatAll("%t %t", "Tag", "FlippedInfected", client_name);
+ if(swaptoIsAvailable && GetClientTeamEx(client) != L4D2Team_Infected)
+ {
+ ServerCommand("sm_swapto 3 #%i", GetClientUserId(client));
+ }
+ }
previous_timeC = current_timeC; // Update the previous time
}
else
{
- PrintToConsole(client, "[Teamflip] Whoa there buddy, slow down. Wait at least %d seconds.", GetConVarInt(delay_time));
+ PrintToConsole(client, "%t", "Wait", delay_time.IntValue);
}
return Plugin_Handled;
+}
+
+stock L4D2Team GetClientTeamEx(int client)
+{
+ return view_as(GetClientTeam(client));
}
\ No newline at end of file
diff --git a/addons/sourcemod/scripting/weapon_loadout_vote.sp b/addons/sourcemod/scripting/weapon_loadout_vote.sp
index 5af36b6c7..841561b6e 100644
--- a/addons/sourcemod/scripting/weapon_loadout_vote.sp
+++ b/addons/sourcemod/scripting/weapon_loadout_vote.sp
@@ -71,12 +71,13 @@ public Plugin myinfo =
name = "Weapon Loadout",
author = "Sir, A1m`",
description = "Allows the Players to choose which weapons to play the mode in.",
- version = "2.3",
+ version = "2.4",
url = "https://github.com/SirPlease/L4D2-Competitive-Rework"
};
public void OnPluginStart()
{
+ LoadTranslation("weapon_loadout.phrases");
HookEvent("round_start", Event_RoundStart);
HookEvent("player_team", Event_PlayerTeam);
@@ -87,6 +88,21 @@ public void OnPluginStart()
InitMenu();
}
+void LoadTranslation(char[] sTranslation)
+{
+ char
+ sPath[PLATFORM_MAX_PATH],
+ sName[64];
+
+ Format(sName, sizeof(sName), "translations/%s.txt", sTranslation);
+ BuildPath(Path_SM, sPath, sizeof(sPath), sName);
+ if (!FileExists(sPath))
+ {
+ SetFailState("Missing translation file %s.txt", sTranslation);
+ }
+ LoadTranslations(sTranslation);
+}
+
void InitMenu()
{
g_hMenu = new Menu(Menu_VoteMenuHandler);
@@ -158,7 +174,7 @@ public Action Cmd_VoteMode(int iClient, int iArgs)
// We've already decided on a mode.
if (!IsInReady() || InSecondHalfOfRound()) {
- CPrintToChat(iClient, "{blue}[{green}Zone{blue}]{default}: You can only call for the vote during the first ready-up of a round");
+ CPrintToChat(iClient, "%t %t", "Tag", "OnlyFirstReadyup");
return Plugin_Handled;
}
@@ -167,13 +183,13 @@ public Action Cmd_VoteMode(int iClient, int iArgs)
// Is a new vote allowed?
if (!IsNewBuiltinVoteAllowed()) {
- CPrintToChat(iClient, "A vote cannot be called at this moment, try again in a second or five.");
+ CPrintToChat(iClient, "%t", "CannotCalled");
return Plugin_Handled;
}
// Check if all players are present, if not.. tell them about it.
if (ReadyPlayers() != GetMaxPlayers()) {
- CPrintToChat(iClient, "{blue}[{green}Zone{blue}]{default}: Both teams need to be full.");
+ CPrintToChat(iClient, "%t %t", "Tag", "NeedFull");
return Plugin_Handled;
}
@@ -193,7 +209,7 @@ public Action Cmd_ForceVoteMode(int iClient, int iArgs)
// Is a new vote allowed?
if (!IsNewBuiltinVoteAllowed()) {
- CPrintToChat(iClient, "A vote cannot be called at this moment, try again in a second or five.");
+ CPrintToChat(iClient, "%t", "CannotCalled");
return Plugin_Handled;
}
@@ -204,10 +220,6 @@ public Action Cmd_ForceVoteMode(int iClient, int iArgs)
void ShowMenu(int iClient)
{
- if (IsInReady()) {
- FakeClientCommand(iClient, "sm_hide");
- }
-
g_hMenu.Display(iClient, MENU_TIME_FOREVER);
}
@@ -217,13 +229,13 @@ public int Menu_VoteMenuHandler(Menu hMenu, MenuAction iAction, int iClient, int
case MenuAction_Select: {
// Is a new vote allowed?
if (!IsNewBuiltinVoteAllowed()) {
- CPrintToChat(iClient, "A vote cannot be called at this moment, try again in a second or five.");
+ CPrintToChat(iClient, "%t", "CannotCalled");
return 0;
}
char sInfo[32], sVoteTitle[64];
if (hMenu.GetItem(iIndex, sInfo, sizeof(sInfo))) {
- Format(sVoteTitle, sizeof(sVoteTitle), "Survivors get %s?", sInfo);
+ Format(sVoteTitle, sizeof(sVoteTitle), "%t", "SurvivorsGet", sInfo);
g_iVotingMode = iIndex + 1;
// Get all non-spectating players
@@ -251,9 +263,6 @@ public int Menu_VoteMenuHandler(Menu hMenu, MenuAction iAction, int iClient, int
FakeClientCommand(iClient, "Vote Yes");
}
}
- case MenuAction_Cancel: {
- FakeClientCommand(iClient, "sm_show");
- }
}
return 0;
@@ -274,7 +283,6 @@ public void BV_VoteActionHandler(Handle hVote, BuiltinVoteAction iAction, int iP
public void BV_VoteResultHandler(Handle vote, int num_votes, int num_clients, const int[][] client_info, int num_items, const int[][] item_info)
{
- ReturnReadyUpPanel();
for (int i = 0; i < num_items; i++) {
if (item_info[i][BUILTINVOTEINFO_ITEM_INDEX] == BUILTINVOTES_VOTE_YES) {
@@ -283,12 +291,14 @@ public void BV_VoteResultHandler(Handle vote, int num_votes, int num_clients, co
// Allow Admins though
if (!IsInReady() && g_iCurrentMode != eUndecided && !g_bIsAdminVote) {
DisplayBuiltinVoteFail(vote, BuiltinVoteFail_Loses);
- CPrintToChatAll("{blue}[{green}Zone{blue}]{default}: Vote didn't pass before you left ready-up.");
+ CPrintToChatAll("%t %t", "Tag", "BeforeReadyup");
return;
}
g_bIsAdminVote = false;
- DisplayBuiltinVotePass(vote, "Survivor Weapons Set!");
+ char sBuffer[64];
+ Format(sBuffer, sizeof(sBuffer), "%t", "WeaponsSet");
+ DisplayBuiltinVotePass(vote, sBuffer);
g_iCurrentMode = g_iVotingMode;
GiveSurvivorsWeapons();
return;
@@ -426,8 +436,8 @@ public Action Timer_InformPlayers(Handle hTimer)
for (int i = 1; i <= MaxClients; i++) {
if (IsClientInGame(i) && GetClientTeam(i) != L4D2Team_Spectator && !g_bVoteUnderstood[i]) {
- CPrintToChat(i, "{blue}[{green}Zone{blue}]{default}: Welcome to {blue}Zone{green}Hunters{default}.");
- CPrintToChat(i, "{blue}[{green}Zone{blue}]{default}: Type {olive}!mode {default}in chat to vote on weapons used.");
+ CPrintToChat(i, "%t %t", "Tag", "Welcome");
+ CPrintToChat(i, "%t %t", "Tag", "Type");
}
}
@@ -435,15 +445,6 @@ public Action Timer_InformPlayers(Handle hTimer)
return Plugin_Continue;
}
-void ReturnReadyUpPanel()
-{
- for (int i = 1; i <= MaxClients; i++) {
- if (IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) > L4D2Team_Spectator) {
- FakeClientCommand(i, "sm_show");
- }
- }
-}
-
int GetMaxPlayers()
{
return FindConVar("survivor_limit").IntValue + FindConVar("z_max_player_zombies").IntValue;
diff --git a/addons/sourcemod/translations/autopause.phrases.txt b/addons/sourcemod/translations/autopause.phrases.txt
new file mode 100644
index 000000000..f74285705
--- /dev/null
+++ b/addons/sourcemod/translations/autopause.phrases.txt
@@ -0,0 +1,13 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "en" "{blue}[{default}AutoPause{blue}]{default}"
+ }
+ "crashed"
+ {
+ "en" "{olive}%s{default} crashed."
+ "es" "{olive}%s{default} no responde."
+ "chi" "{olive}%s{default} 客户端崩溃."
+ }
+}
diff --git a/addons/sourcemod/translations/chi/caster_system.phrases.txt b/addons/sourcemod/translations/chi/caster_system.phrases.txt
index 05edd496d..d52e2fba2 100644
--- a/addons/sourcemod/translations/chi/caster_system.phrases.txt
+++ b/addons/sourcemod/translations/chi/caster_system.phrases.txt
@@ -13,7 +13,7 @@
"SelfCast2"
{
- "chi" "{blue}[{default}Cast{blue}] 重连服务器以加载 MOD"
+ "chi" "{blue}[{default}Cast{blue}] 重连服务器来加载 MOD"
}
"RegCasterTarget"
diff --git a/addons/sourcemod/translations/chi/coinflip.phrases.txt b/addons/sourcemod/translations/chi/coinflip.phrases.txt
new file mode 100644
index 000000000..a19e75a0e
--- /dev/null
+++ b/addons/sourcemod/translations/chi/coinflip.phrases.txt
@@ -0,0 +1,19 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "chi" "[{olive}抛硬币{default}]"
+ }
+ "Heads"
+ {
+ "chi" "{lightgreen}%s{default} 抛了个硬币!\nIt's {green}正面{default}!"
+ }
+ "Tails"
+ {
+ "chi" "{lightgreen}%s{default} 抛了个硬币!\nIt's {green}反面{default}!"
+ }
+ "rolled"
+ {
+ "chi" "{lightgreen}%s{default} 挑选随机数字,最大为 {teamcolor}%d{default}!\n数字为 {green}%d{default}!"
+ }
+}
diff --git a/addons/sourcemod/translations/chi/l4d_tank_control_eq.phrases.txt b/addons/sourcemod/translations/chi/l4d_tank_control_eq.phrases.txt
new file mode 100644
index 000000000..a13b3c58c
--- /dev/null
+++ b/addons/sourcemod/translations/chi/l4d_tank_control_eq.phrases.txt
@@ -0,0 +1,35 @@
+"Phrases"
+{
+ "Tag_Selecion"
+ {
+ "chi" "{red}<{default}Tank 选择系统{red}>{default}"
+ }
+ "Tag_Rage"
+ {
+ "chi" "{red}<{default}Tank 控制权{red}>{default}"
+ }
+ "YouBecomeTank"
+ {
+ "chi" "{green}You{default} 将会成为 {red}Tank{default}!"
+ }
+ "BecomeTank"
+ {
+ "chi" "{olive}%s{default} 将会成为 {red}Tank{default}!"
+ }
+ "UnableGiveTank"
+ {
+ "chi" "[{olive}SM{default}] %s 不是感染者. 无法给予Tank"
+ }
+ "Hit_RageMeterRefilled"
+ {
+ "chi" "第一次控制权结束,第二次控制权开始"
+ }
+ "YouRageMeterRefilled"
+ {
+ "chi" "{olive}第一次控制权结束, {red}第二次控制权开始{default}"
+ }
+ "RageMeterRefilled"
+ {
+ "chi" "({green}%N{default}) {olive}第一次控制权结束, {red}第二次控制权开始"
+ }
+}
diff --git a/addons/sourcemod/translations/chi/l4d_tank_damage_announce.phrases.txt b/addons/sourcemod/translations/chi/l4d_tank_damage_announce.phrases.txt
new file mode 100644
index 000000000..c618bdf18
--- /dev/null
+++ b/addons/sourcemod/translations/chi/l4d_tank_damage_announce.phrases.txt
@@ -0,0 +1,23 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "chi" "[{green}!{default}]"
+ }
+ "AI"
+ {
+ "chi" "AI"
+ }
+ "HealthRemaining"
+ {
+ "chi" "{blue}Tank{default} ({olive}%s{default}) 剩余 {green}%d{default} 点血量"
+ }
+ "DealtToTank"
+ {
+ "chi" "对{blue}Tank{default} ({olive}%s{default}) 造成的{blue}伤害"
+ }
+ "PercentDamage"
+ {
+ "chi" "{blue}[{default}%d{blue}] ({default}%i%%{blue}) {olive}%N"
+ }
+}
diff --git a/addons/sourcemod/translations/chi/nodeathcamskip.phrases.txt b/addons/sourcemod/translations/chi/nodeathcamskip.phrases.txt
new file mode 100644
index 000000000..835963535
--- /dev/null
+++ b/addons/sourcemod/translations/chi/nodeathcamskip.phrases.txt
@@ -0,0 +1,23 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "chi" "{red}[{default}Exploit{red}]{default}"
+ }
+ "DeathTimer"
+ {
+ "chi" "{olive}%N{default} 尝试了跳过死亡时间."
+ }
+ "UnableToJoin"
+ {
+ "chi" "你在 {red}%.1f{default} 秒内将无法加入感染者团队."
+ }
+ "Moved"
+ {
+ "chi" "时间到了之后,将会自动将你移动到感染者团队."
+ }
+ "SlotsReserved"
+ {
+ "chi" "这个队伍目前有 {olive}保留名额{default}."
+ }
+}
diff --git a/addons/sourcemod/translations/chi/pause.phrases.txt b/addons/sourcemod/translations/chi/pause.phrases.txt
index 2e10936df..cf93604a5 100644
--- a/addons/sourcemod/translations/chi/pause.phrases.txt
+++ b/addons/sourcemod/translations/chi/pause.phrases.txt
@@ -2,20 +2,26 @@
{
"Tag"
{
- "chi" "{default}[{green}!{default}]"
+ "chi" "[{green}!{default}]"
}
"ClientFullyLoaded"
{
"chi" "{olive}%N {default}已经完全载入"
}
+ "PauseCountFormat"
+ {
+ "#format" "{1:d},{2:d}" // 1:PauseCount(client), 2:pauseLimitCvar.IntValue
+ "chi" " [{green}{1}{default}/{green}{2}{default}]."
+ }
"PauseCommand"
{
- "chi" "{olive}%N {blue}暂停游戏{default}."
+ "#format" "{1:N},{2:s}" // 1:client, 2:sPauseCount
+ "chi" "{olive}{1}{default} {blue}暂停游戏{default}{2}"
}
// PauseDelay_Timer
"PauseAction"
{
- "chi" "{red}暂停游戏"
+ "chi" "{red}暂停游戏{default}"
}
"PauseDelay"
{
@@ -33,11 +39,13 @@
// Unpause_Cmd
"UnpauseSurvivors"
{
- "chi" "{olive}%N %s{default}表示 {blue}%s {default}准备完毕."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, :2(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "chi" "{olive}{1} {2}{default} 表示 {blue}{3}{default} 准备完毕."
}
"UnpauseInfected"
{
- "chi" "{olive}%N %s{default}表示 {red}%s {default}准备完毕."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, :2(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "chi" "{olive}{1} {2}{default} 表示 {red}{3}{default} 准备完毕."
}
"UnpauseInitiator"
{
@@ -50,11 +58,13 @@
// Unready_Cmd
"UnreadySurvivors"
{
- "chi" "{olive}%N %s{default}表示 {blue}%s {default}还未准备完毕."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, 2:(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "chi" "{olive}{1} {2}{default} 表示 {blue}{3}{default} 还未准备完毕."
}
"UnreadyInfected"
{
- "chi" "{olive}%N %s{default}表示 {red}%s {default}还未准备完毕."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, 2:(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "chi" "{olive}{1} {2}{default} 表示 {red}{3}{default} 还未准备完毕."
}
"UnreadyInitiator"
{
@@ -73,7 +83,7 @@
// AddPauseCount
"PauseLimit"
{
- "chi" "你已经达到你能发起的暂停上限."
+ "chi" "你已经达到你的 {red}暂停上限{default} [{green}%d{default}]."
}
// AttemptPause
"PauseDeferred"
@@ -83,25 +93,22 @@
// Pause
"PausePreventSpawn"
{
- "chi" "{default}你因为暂停 {red}被阻止生成"
+ "chi" "{default}你因为暂停被阻止{red}生成"
}
// Show_Cmd
"PanelShow"
{
- "chi" "准备面板: [{blue}on{default}]."
+ "chi" "准备面板: [{blue}开启{default}]."
}
"PanelHide"
{
- "chi" "准备面板: [{red}off{default}]."
+ "chi" "准备面板: [{red}关闭{default}]."
}
// UpdatePanel
"PanelSlots"
{
- "chi" "▸ 服务器: %s\n▸ 位置: %d/%d"
- }
- "PanelDate"
- {
- "chi" "▸ %m/%d/%Y - %I:%M%p"
+ "#format" "{1:s},{2:d},{3:d}" // 1:info, 2:GetSeriousClientCount(), 3:FindConVar("sv_maxplayers").IntValue
+ "chi" "▸ 服务器: {1}\n▸ 位置: {2}/{3}"
}
"PanelTitle"
{
diff --git a/addons/sourcemod/translations/chi/readyup.phrases.txt b/addons/sourcemod/translations/chi/readyup.phrases.txt
index 1a7c27823..de49cccab 100644
--- a/addons/sourcemod/translations/chi/readyup.phrases.txt
+++ b/addons/sourcemod/translations/chi/readyup.phrases.txt
@@ -1,108 +1,128 @@
"Phrases"
{
-// The following uses bracket style color tags (see colors.inc)
- "PanelHide"
+ "Tag"
{
- "chi" "[{olive}Readyup{default}] 准备面板已 {red}关闭{default}"
+ "chi" "[{green}!{default}]"
}
-
- "PanelShow"
+ // readyup/action.inc
+ "LiveCountdownBegin"
{
- "chi" "[{olive}Readyup{default}] 准备面板已 {blue}开启{default}"
+ "chi" "比赛即将开始!\n输入 !unready / 按 F2 中断倒数"
}
-
- "ForceStartAdmin"
+ "RoundIsLive"
{
- "#format" "{1:N}"
- "chi" "[{green}!{default}] {blue}管理员 {default}({olive}{1}{default}) {green}强制{default}了{blue}游戏开始"
+ "chi" "比赛开始!"
+ }
+ "LiveCountdown"
+ {
+ "#format" "{1:d}"
+ "chi" "开始倒计时: {1}\n输入 !unready / 按 F2 中断倒数"
}
-
- "VoteInProgress"
+ "AutoStartWaiting"
{
- "chi" "[{olive}Readyup{default}] 现在有{olive}投票{green}正在进行{default}"
+ "chi" "等待玩家加入..."
}
-
- "VoteDelay"
+ "AutoStartWaiting"
+ {
+ "chi" "玩家数量不足..."
+ }
+ "InitiateAutoStart"
+ {
+ "chi" "游戏将会自动开始!"
+ }
+ "AutoStartCountdown"
{
"#format" "{1:d}"
- "chi" "[{olive}Readyup{default}] 请等待 {blue}{1}秒 {default}以发起下一轮投票"
+ "chi" "游戏开始于:{1}"
}
-
- "Player marked unready"
+ "LiveCountdownCancelled"
{
- "#format" "{1:N}"
- "chi" "{default}[{green}!{default}] {green}倒数中止! {default}({teamcolor}{1} {green}取消了准备{default})"
+ "chi" "倒数中止!"
}
-
- "Player switched team"
+ "CountUnReady"
{
- "#format" "{1:N}"
- "chi" "{default}[{green}!{default}] {green}倒数中止! {default}({teamcolor}{1} {olive}切换了阵营{default})"
+ "#format" "{1:d}{2:d}" // 1:GetUnReadyCount(client), 2:l4d_ready_unready_limit.IntValue
+ "en" " [{green}{1}{default}/{green}{2}{default}]"
}
-
- "Player disconnected"
+ "UnReadyLimit"
{
- "#format" "{1:N}"
- "chi" "{default}[{green}!{default}] {green}倒数中止! {default}({teamcolor}{1} {green}离开了游戏{default})"
+ "chi" "你已经到达你的 {red}取消准备上限{default} [{green}%d{default}]"
}
-
- "Admin aborted"
+ // readyup/command.inc
+ "ForceStartAdmin"
{
"#format" "{1:N}"
- "chi" "{default}[{green}!{default}] {green}叫停强制开始! {default}({green}由 {olive}{1} {green}发起{default})"
+ "chi" "[{green}!{default}] {blue}管理员 {default}({olive}{1}{default}) {green}强制{default}了{blue}游戏开始"
+ }
+ "PanelHide"
+ {
+ "chi" "[{olive}Readyup{default}] 准备面板已 {red}关闭{default}"
}
-
-
-// The following are not allowed to use any color tag
+ "PanelShow"
+ {
+ "chi" "[{olive}Readyup{default}] 准备面板已 {blue}开启{default}"
+ }
+ // readyup/panel.inc
"HintReady"
{
"chi" "你已经准备了\n输入 !unready / 按 F2 取消准备"
}
-
"HintUnready"
{
"chi" "你还没有准备\n输入 !ready / 按 F1 确认准备"
}
-
- "LiveCountdownBegin"
+ "PanelSlots"
{
- "chi" "比赛即将开始!\n输入 !unready / 按 F2 中断倒数"
+ "#format" "{1:s},{2:d},{3:d},{4:s}" // 1:ServerName, 2:GetSeriousClientCount(), 3:FindConVar("sv_maxplayers").IntValue, 4:cfgName
+ "chi" "▸ 服务器名字: {1} \n▸ 位置: {2}/{3}\n▸ 比赛配置: {4}"
}
-
- "LiveCountdown"
+ "PanelCommands"
{
- "#format" "{1:d}"
- "chi" "请各就各位:{1} \n输入 !unready / 按 F2 中断倒数"
+ "chi" "▸ 命令:"
}
-
- "LiveCountdownCancelled"
+ "PanelSurvivors"
{
- "chi" "倒数中止!"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:isTeamReadyMode ? teamReadySymbol[survivorReady] : ""
+ "chi" "->{1}. 生还者{2}"
}
-
- "RoundIsLive"
+ "PanelInfected"
{
- "chi" "比赛开始!"
- }
-
- "InitiateAutoStart"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:isTeamReadyMode ? teamReadySymbol[survivorReady] : ""
+ "chi" "->{1}. 感染者{2}"
+ }
+ "PanelCaster"
{
- "chi" "游戏将会自动开始!"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:casterCount > 1 ? "s" : ""
+ "chi" "->{1}. 裁判{2}"
}
-
- "AutoStartCountdown"
+ "PanelSpectator"
{
- "#format" "{1:d}"
- "chi" "游戏开始于:{1}"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:specCount > 1 ? "s" : ""
+ "chi" "->{1}. 旁观者{2}"
}
-
- "AutoStartWaiting"
+ "PanelMany"
{
- "chi" "等待玩家加入..."
+ "chi" "**很多** (%d)"
}
-
- "AutoStartNotEnoughPlayers"
+ // g_sDisruptReason[]
+ "Player marked unready"
{
- "chi" "玩家数量不足..."
+ "#format" "{1:N}"
+ "chi" "{default}[{green}!{default}] {green}倒数中止! {default}({teamcolor}{1} {green}取消了准备{default})"
+ }
+ "Player switched team"
+ {
+ "#format" "{1:N}"
+ "chi" "{default}[{green}!{default}] {green}倒数中止! {default}({teamcolor}{1} {olive}切换了阵营{default})"
+ }
+ "Player disconnected"
+ {
+ "#format" "{1:N}"
+ "chi" "{default}[{green}!{default}] {green}倒数中止! {default}({teamcolor}{1} {green}离开了游戏{default})"
+ }
+ "Admin aborted"
+ {
+ "#format" "{1:N}"
+ "chi" "{default}[{green}!{default}] {green}叫停强制开始! {default}({green}由 {olive}{1} {green}发起{default})"
}
}
\ No newline at end of file
diff --git a/addons/sourcemod/translations/chi/survivor_mvp.phrases.txt b/addons/sourcemod/translations/chi/survivor_mvp.phrases.txt
new file mode 100644
index 000000000..59d72bf05
--- /dev/null
+++ b/addons/sourcemod/translations/chi/survivor_mvp.phrases.txt
@@ -0,0 +1,75 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "chi" "{blue}[{default}MVP{blue}]{default}"
+ }
+ "YourRankSI"
+ {
+ "chi" "{green}特感 {blue}排名: {olive}#%d {blue}({default}%d {green}伤害 {blue}[{default}%.0f%%{blue}]{default}, %d {green}kills {blue}[{default}%.0f%%{blue}])"
+ }
+ "YourRankCI"
+ {
+ "chi" "{green}丧尸 {blue}Rank: {olive}#%d {blue}({default}%d {green}丧尸 {blue}[{default}%.0f%%{blue}])"
+ }
+ "YourRankFF"
+ {
+ "chi" "{green}黑枪 {blue}Rank: {olive}#%d {blue}({default}%d {green}友伤 {blue}[{default}%.0f%%{blue}])"
+ }
+ "BotName"
+ {
+ "chi" "[BOT]"
+ }
+ "NobodyName"
+ {
+ "chi" "{blue}({default}没有人{blue})"
+ }
+ "NotEnoughAction"
+ {
+ "chi" "{blue}({default}还没有足够多的操作{blue})"
+ }
+ "ReportSI_Absolute"
+ {
+ "chi" "{green}特感: {olive}%s {blue}({default}%d {green}伤害{default}, %d {green}击杀{blue})"
+ }
+ "ReportSI_Percent"
+ {
+ "chi" "{green}特感: {olive}%s {blue}({green}伤害 {blue}[{default}%.0f%%{blue}]{default}, {green}击杀 {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportSI_Full"
+ {
+ "chi" "{green}特感: {olive}%s {blue}({default}%d {green}伤害 {blue}[{default}%.0f%%{blue}]{default}, %d {green}击杀 {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportSI_Nobody"
+ {
+ "chi" "{green}特感: {blue}({default}无{blue})"
+ }
+ "ReportCI_Absolute"
+ {
+ "chi" "{green}丧尸: {olive}%s {blue}({default}%d {green}丧尸{blue})"
+ }
+ "ReportCI_Percent"
+ {
+ "chi" "{green}丧尸: {olive}%s {blue}({green}丧尸 {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportCI_Full"
+ {
+ "chi" "{green}丧尸: {olive}%s {blue}({default}%d {green}丧尸 {blue}[{default}%.0f%%{blue}])"
+ }
+ "NoFF"
+ {
+ "chi" "{blue}({default}完全没有黑枪!{blue})"
+ }
+ "ReportFF_Absolute"
+ {
+ "chi" "{green}友伤: {olive}%s {blue}({default}%d {green}友伤{blue})"
+ }
+ "ReportFF_Percent"
+ {
+ "chi" "{green}友伤: {olive}%s {blue}({green}友伤 {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportFF_Full"
+ {
+ "chi" "{green}友伤: {olive}%s {blue}({default}%d {green}友伤 {blue}[{default}%.0f%%{blue}])"
+ }
+}
diff --git a/addons/sourcemod/translations/chi/teamflip.phrases.txt b/addons/sourcemod/translations/chi/teamflip.phrases.txt
new file mode 100644
index 000000000..9727074d6
--- /dev/null
+++ b/addons/sourcemod/translations/chi/teamflip.phrases.txt
@@ -0,0 +1,19 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "chi" "[{olive}Teamflip{default}]"
+ }
+ "FlippedSurvivor"
+ {
+ "chi" "{green}%s{default} 随机挑选了一个队伍,是 {blue}幸存者{default} 队伍!"
+ }
+ "FlippedInfected"
+ {
+ "chi" "{green}%s{default} 随机挑选了一个队伍,是 {red}感染者{default} 队伍!"
+ }
+ "Wait"
+ {
+ "chi" "[Teamflip] 哇,伙计,慢点。至少要等 %d 秒。"
+ }
+}
diff --git a/addons/sourcemod/translations/chi/weapon_loadout.phrases.txt b/addons/sourcemod/translations/chi/weapon_loadout.phrases.txt
new file mode 100644
index 000000000..74f3ae139
--- /dev/null
+++ b/addons/sourcemod/translations/chi/weapon_loadout.phrases.txt
@@ -0,0 +1,39 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "chi" "{blue}[{green}Zone{blue}]{default}:"
+ }
+ "OnlyFirstReadyup"
+ {
+ "chi" "你只能在第一回合Readyup前使用这个命令."
+ }
+ "CannotCalled"
+ {
+ "chi" "暂时无法发起一个投票,请稍等几秒钟..."
+ }
+ "NeedFull"
+ {
+ "chi" "所有队伍需要满人."
+ }
+ "SurvivorsGet"
+ {
+ "chi" "生还者获得 %s?"
+ }
+ "BeforeReadyup"
+ {
+ "chi" "准备完毕后无法使用."
+ }
+ "WeaponsSet"
+ {
+ "chi" "生还者武器设置完成!"
+ }
+ "Welcome"
+ {
+ "chi" "欢迎来到 {blue}Zone{green}Hunters模式{default}."
+ }
+ "Type"
+ {
+ "chi" "在聊天栏输入 {olive}!mode{default} 来投票选取武器的使用."
+ }
+}
diff --git a/addons/sourcemod/translations/coinflip.phrases.txt b/addons/sourcemod/translations/coinflip.phrases.txt
new file mode 100644
index 000000000..986e26b49
--- /dev/null
+++ b/addons/sourcemod/translations/coinflip.phrases.txt
@@ -0,0 +1,19 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "en" "[{olive}Coinflip{default}]"
+ }
+ "Heads"
+ {
+ "en" "{lightgreen}%s{default} flipped a coin!\nIt's {green}Heads{default}!"
+ }
+ "Tails"
+ {
+ "en" "{lightgreen}%s{default} flipped a coin!\nIt's {green}Tails{default}!"
+ }
+ "rolled"
+ {
+ "en" "{lightgreen}%s{default} rolled a {teamcolor}%d{default} sided die!\nIt's {green}%d{default}!"
+ }
+}
diff --git a/addons/sourcemod/translations/current.phrases.txt b/addons/sourcemod/translations/current.phrases.txt
new file mode 100644
index 000000000..3a74b8e41
--- /dev/null
+++ b/addons/sourcemod/translations/current.phrases.txt
@@ -0,0 +1,9 @@
+"Phrases"
+{
+ "Current"
+ {
+ "en" "Current: {green}%d%%{default}"
+ "es" "Progreso: {green}%d%%{default}"
+ "chi" "当前进度: {green}%d%%{default}"
+ }
+}
diff --git a/addons/sourcemod/translations/es/coinflip.phrases.txt b/addons/sourcemod/translations/es/coinflip.phrases.txt
new file mode 100644
index 000000000..012030b04
--- /dev/null
+++ b/addons/sourcemod/translations/es/coinflip.phrases.txt
@@ -0,0 +1,15 @@
+"Phrases"
+{
+ "Heads"
+ {
+ "es" "¡{lightgreen}%s{default} tiró una moneda!\n¡Es {green}Cara{default}!"
+ }
+ "Tails"
+ {
+ "es" "¡{lightgreen}%s{default} tiró una moneda!\n¡Es {green}Cruz{default}!"
+ }
+ "rolled"
+ {
+ "es" "!{lightgreen}%s{default} eligió un número del 1 al {teamcolor}%d{default}!\n¡Es {green}%d{default}!"
+ }
+}
diff --git a/addons/sourcemod/translations/es/l4d2_stats.phrases.txt b/addons/sourcemod/translations/es/l4d2_stats.phrases.txt
index 4b8014c14..5f97db692 100644
--- a/addons/sourcemod/translations/es/l4d2_stats.phrases.txt
+++ b/addons/sourcemod/translations/es/l4d2_stats.phrases.txt
@@ -10,6 +10,19 @@
"#format" "{1:N},{2:N}" // 1:victim 2:attacker
"es" "{olive}{2}{default} realizó un {blue}headshot{default} a {olive}{1}{default}"
}
+ "assister"
+ {
+ "#format" "{1:N},{2:d},{3:d},{4:s}" // 1:assisters[0][0], 2:assisters[0][1], 3:g_iShotsDealt[victim][assisters[0][0]], 4:assist_shots == 1 ? AssistShotsSingular:AssistShotsPlural
+ "es" "{1} ({2}/{3} disparo{4})"
+ }
+ "AssistShotsSingular"
+ {
+ "es" ""
+ }
+ "AssistShotsPlural"
+ {
+ "es" "s"
+ }
"TeamSkeeted"
{
"#format" "{1:N},{2:N},{3:d},{4:d},{5:s},{6:s}" // 1:attacker 2:victim 3:damage 4:shots 5:shots == 1 ? "" : "s" 6:assister_string
diff --git a/addons/sourcemod/translations/es/l4d_tank_control_eq.phrases.txt b/addons/sourcemod/translations/es/l4d_tank_control_eq.phrases.txt
new file mode 100644
index 000000000..aaa575f04
--- /dev/null
+++ b/addons/sourcemod/translations/es/l4d_tank_control_eq.phrases.txt
@@ -0,0 +1,35 @@
+"Phrases"
+{
+ "Tag_Selecion"
+ {
+ "es" "{red}<{default}Selección de Tank{red}>{default}"
+ }
+ "Tag_Rage"
+ {
+ "es" "{red}<{default}Ira del Tank{red}>{default}"
+ }
+ "YouBecomeTank"
+ {
+ "es" "¡{green}Tu{default} te convertirás en el {red}Tank{default}!"
+ }
+ "BecomeTank"
+ {
+ "es" "{olive}%s{default} se convertirá en el {red}Tank{default}!"
+ }
+ "UnableGiveTank"
+ {
+ "es" "[{olive}SM{default}] %s no es infectado. No se puede dar el Tank"
+ }
+ "Hit_RageMeterRefilled"
+ {
+ "es" "Medidor de ira Recargado"
+ }
+ "YouRageMeterRefilled"
+ {
+ "es" "{olive}Medidor de ira {red}Recargado{default}"
+ }
+ "RageMeterRefilled"
+ {
+ "es" "({green}%N{default}'s) {olive}Medidor de ira {red}Recargado"
+ }
+}
diff --git a/addons/sourcemod/translations/es/l4d_tank_damage_announce.phrases.txt b/addons/sourcemod/translations/es/l4d_tank_damage_announce.phrases.txt
new file mode 100644
index 000000000..577c7204d
--- /dev/null
+++ b/addons/sourcemod/translations/es/l4d_tank_damage_announce.phrases.txt
@@ -0,0 +1,19 @@
+"Phrases"
+{
+ "AI"
+ {
+ "es" "IA"
+ }
+ "HealthRemaining"
+ {
+ "es" "{blue}Tank{default} ({olive}%s{default}) tiene {green}%d{default} salud restante"
+ }
+ "DealtToTank"
+ {
+ "es" "{blue}Daño{default} infligido al {blue}Tank{default} ({olive}%s{default})"
+ }
+ "PercentDamage"
+ {
+ "es" "{blue}[{default}%d{blue}] ({default}%i%%{blue}) {olive}%N"
+ }
+}
diff --git a/addons/sourcemod/translations/es/nodeathcamskip.phrases.txt b/addons/sourcemod/translations/es/nodeathcamskip.phrases.txt
new file mode 100644
index 000000000..a4da2e80a
--- /dev/null
+++ b/addons/sourcemod/translations/es/nodeathcamskip.phrases.txt
@@ -0,0 +1,19 @@
+"Phrases"
+{
+ "DeathTimer"
+ {
+ "es" "{olive}%N{default} intentó evadir el cronómetro de muerte."
+ }
+ "UnableToJoin"
+ {
+ "es" "No podrás unirte al equipo por {red}%.1f{default} segundos."
+ }
+ "Moved"
+ {
+ "es" "Serás movido automáticamente."
+ }
+ "SlotsReserved"
+ {
+ "es" "Este equipo actualmente tiene espacios {olive}reservados{default}."
+ }
+}
diff --git a/addons/sourcemod/translations/es/pause.phrases.txt b/addons/sourcemod/translations/es/pause.phrases.txt
index 4305b49c7..9957e97f5 100644
--- a/addons/sourcemod/translations/es/pause.phrases.txt
+++ b/addons/sourcemod/translations/es/pause.phrases.txt
@@ -2,151 +2,162 @@
{
"ClientFullyLoaded"
{
- "es" "{olive}%N {default}ha cargado totalmente"
+ "es" "{olive}%N{default} ha cargado totalmente."
+ }
+ "PauseCountFormat"
+ {
+ "#format" "{1:d},{2:d}" // 1:PauseCount(client), 2:pauseLimitCvar.IntValue
+ "en" " [{green}{1}{default}/{green}{2}{default}]."
}
"PauseCommand"
{
- "es" "{olive}%N {default}a {blue} Pausado{default}."
+ "#format" "{1:N},{2:s}" // 1:client, 2:sPauseCount
+ "es" "{olive}{1}{default} a {blue}Pausado{default}{2}"
}
// PauseDelay_Timer
"PauseAction"
{
- "es" "{red}PAUSA"
+ "es" "{red}PAUSA{default}"
}
"PauseDelay"
{
- "es" "{blue}Pausa en{default}: {olive}%d"
+ "es" "{blue}Pausa en{default}: {olive}%d{default}."
}
// ForcePause_Cmd
"Crashed"
{
- "es" "{olive}El juego {default}se ha {green}puesto en pausa {default}porque un jugador se le ha {blue}cerrado{default}."
+ "es" "{olive}El juego{default} se ha {green}Pausado{default}, un jugador {blue}no responde{default}."
}
"ForcePause"
{
- "es" "Una pausa forzada {green}es emitida por {blue}Admin {default}({olive}%N{default})"
+ "es" "{green}Pausa forzada{default} por el {blue}Admin{default} ({olive}%N{default})"
}
// Unpause_Cmd
"UnpauseSurvivors"
{
- "es" "{olive}%N %s{default}a marcado como {blue}%s {default}listo."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, :2(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "es" "{olive}{1} {2}{default} marco que los {blue}{3}{default} estan preparados."
}
"UnpauseInfected"
{
- "es" "{olive}%N %s{default}a marcado como {red}%s {default}listo."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, :2(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "es" "{olive}{1} {2}{default} marco que los {red}{3}{default} estan preparados."
}
"UnpauseInitiator"
{
- "es" "{olive}%N {default}a marcado como {green}Initiator {default}listo."
+ "es" "El jugador que {green}pauso{default} ({olive}%N{default}) marco que está preparado."
}
"UnpauseAdminConfirm"
{
- "es" "{olive}Los equipos {default}están listos. Espere a que {blue}Administrador {default} {green}confirme{default}."
+ "es" "{olive}Los equipos{default} están listos. Espere a que el {blue}Administrador{default} {green}confirme{default}."
}
// Unready_Cmd
"UnreadySurvivors"
{
- "es" "{olive}%N %s{default}marcado {blue}%s {default}no listo."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, 2:(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "es" "{olive}{1} {2}{default} marco que los {blue}{3}{default} no estan preparados."
}
"UnreadyInfected"
{
- "es" "{olive}%N %s{default}marcado {red}%s {default}no listo."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, 2:(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "es" "{olive}{1} {2}{default} marco que los {red}{3}{default} no preparados."
}
"UnreadyInitiator"
{
- "es" "{olive}%N {default}marcó {green}Iniciador {default}no listo."
+ "es" "El jugador que {green}pauso{default} ({olive}%N{default}) marco que no está preparado."
}
// void AsInitiator()
"AsInitiator"
{
- "es" "{default}como {green}Iniciador "
+ "es" "como {green}Iniciador{default}"
}
// ForceUnpause_Cmd
"ForceUnpause"
{
- "es" "Un {green}forzar reanudación {default} es emitido por {blue}Administrador {default}({olive}%N{default})"
+ "es" "El {blue}Administrador{default} ({olive}%N{default}) {green}forzo la reanudación{default}."
}
// AddPauseCount
"PauseLimit"
{
- "es" "Has alcanzado tu límite de pausa."
+ "es" "Has alcanzado tu {red}límite de pausas{default} [{green}%d{default}]."
}
// AttemptPause
"PauseDeferred"
{
- "es" "{red}La pausa se ha retrasado debido a que un sobreviviente se está levantando."
+ "es" "{red}La pausa se ha retrasado debido a que un sobreviviente se está levantando{default}."
}
// Pause
"PausePreventSpawn"
{
- "es" "{default}Tu {red}reaparición {default}ha sido impedido debido a la Pausa"
+ "es" "Tu{red} reaparición {default} fue impedida debido a la Pausa{default}."
}
// Show_Cmd
"PanelShow"
{
- "es" "El panel ahora está {azul} activado {default}."
+ "es" "El panel ahora está {azul}activado{default}."
}
"PanelHide"
{
- "es" "El panel ahora está {rojo}desactivado{predeterminado}."
+ "es" "El panel ahora está {red}desactivado{predeterminado}."
}
// UpdatePanel
"PanelSlots"
{
- "es" "▸ Servidor: %s\n▸ Espacios: %d/%d"
+ "#format" "{1:s},{2:d},{3:d}" // 1:info, 2:GetSeriousClientCount(), 3:FindConVar("sv_maxplayers").IntValue
+ "es" "▸ Servidor: {1}\n▸ Espacios: {2}/{3}"
}
"PanelTitle"
{
- "es" "▸ Estado"
+ "es" "▸ Estado"
}
"RequireAdmin"
{
- "es" "->0. Requerir que el administrador reanude la pausa"
+ "es" "->0. Requerir que el administrador reanude la pausa"
}
"SurvivorUnPaused"
{
- "es" "->1. Sobrevivientes: [√]"
+ "es" "->1. Sobrevivientes: [√]"
}
"SurvivorPaused"
{
- "es" "->1. Sobrevivientes: [X]"
+ "es" "->1. Sobrevivientes: [X]"
}
"InfectedUnPaused"
{
- "es" "->2. Infectado: [√]"
+ "es" "->2. Infectado: [√]"
}
"InfectedPaused"
{
- "es" "->2. Infectado: [X]"
+ "es" "->2. Infectado: [X]"
}
"InitiatorUnPaused"
{
- "es" "->0. Infectado: [√]"
+ "es" "->0. Infectado: [√]"
}
"InitiatorPaused"
{
- "es" "->0. Iniciador: [X]"
+ "es" "->0. Iniciador: [X]"
}
"AutoPauseCrash"
{
- "es" "▸ Pausa automática forzada -> Crash"
+ "es" "▸ Pausa automática forzada -> Crash"
}
"ForcePauseAdmin"
{
- "es" "▸ Forzar la pausa -> %s (Admin)"
+ "es" "▸ Forzar la pausa -> %s (Admin)"
}
"InitiatorPause"
{
- "es" "▸ Iniciador -> %s (%s)"
+ "es" "▸ Iniciador -> %s (%s)"
}
"DurationPause"
{
- "es" "▸ Duración: %02d:%02d"
+ "es" "▸ Duración: %02d:%02d"
}
// InitiateLiveCountdown
"CountdownCancelNotify"
{
- "es" "Escriba {olive}!unready {default}para cancelar"
+ "es" "Escriba {olive}!unready{default} para cancelar"
}
"GameisLive"
{
@@ -159,7 +170,7 @@
// CancelFullReady
"CountdownCancelled"
{
- "es" "{olive}%N {default}canceló la cuenta regresiva!"
+ "es" "{olive}%N{default} canceló la cuenta regresiva!"
}
// Callvote_Callback
"CallvoteNoSpec"
diff --git a/addons/sourcemod/translations/es/readyup.phrases.txt b/addons/sourcemod/translations/es/readyup.phrases.txt
new file mode 100644
index 000000000..f1eef5fd0
--- /dev/null
+++ b/addons/sourcemod/translations/es/readyup.phrases.txt
@@ -0,0 +1,124 @@
+"Phrases"
+{
+ // readyup/action.inc
+ "LiveCountdownBegin"
+ {
+ "es" "¡Iniciando!\n ────────── \nPresiona F2|!nr para cancelar"
+ }
+ "RoundIsLive"
+ {
+ "es" "¡La ronda a comenzado!"
+ }
+ "LiveCountdown"
+ {
+ "#format" "{1:d}"
+ "es" "Iniciando en: {1}\nPresiona F2|!nr para cancelar"
+ }
+ "AutoStartNotEnoughPlayers"
+ {
+ "es" "Se requieren más jugadores..."
+ }
+ "AutoStartWaiting"
+ {
+ "es" "Esperando a los jugadores..."
+ }
+ "InitiateAutoStart"
+ {
+ "es" "¡El juego comenzara automaticamente!"
+ }
+ "AutoStartCountdown"
+ {
+ "#format" "{1:d}"
+ "es" "El juego comienza en: {1}"
+ }
+ "LiveCountdownCancelled"
+ {
+ "es" "¡Cuenta regresiva cancelada!"
+ }
+ "CountUnReady"
+ {
+ "#format" "{1:d}{2:d}" // 1:GetUnReadyCount(client), 2:l4d_ready_unready_limit.IntValue
+ "en" " [{green}{1}{default}/{green}{2}{default}]"
+ }
+ "UnReadyLimit"
+ {
+ "en" "Has alcanzado tu {red}límite de cancelaciones{default} [{green}%d{default}]"
+ }
+ // readyup/command.inc
+ "ForceStartAdmin"
+ {
+ "#format" "{1:N}"
+ "es" "El {blue}inicio del juego{default} es {green}forzado{default} por el {blue}Admin{default} ({olive}{1}{default})"
+ }
+ "PanelHide"
+ {
+ "es" "El panel ahora esta {red}desactivado{default}"
+ }
+ "PanelShow"
+ {
+ "es" "El panel ahora esta {blue}activado{default}"
+ }
+ // readyup/panel.inc
+ "HintReady"
+ {
+ "es" "Estás preparado\n ────────── \nPresiona F2|!nr para cancelar"
+ }
+ "HintUnready"
+ {
+ "es" "No estás preparado\n ────────── \nPresiona F1|!r para confirmar"
+ }
+ "PanelSlots"
+ {
+ "#format" "{1:s},{2:d},{3:d},{4:s}" // 1:ServerName, 2:GetSeriousClientCount(), 3:FindConVar("sv_maxplayers").IntValue, 4:cfgName
+ "es" "▸ Servidor: {1} \n▸ Espacios: {2}/{3}\n▸ Config: {4}"
+ }
+ "PanelCommands"
+ {
+ "es" "▸ Comandos:"
+ }
+ "PanelSurvivors"
+ {
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:isTeamReadyMode ? teamReadySymbol[survivorReady] : ""
+ "es" "->{1}. Superviviente{2}"
+ }
+ "PanelInfected"
+ {
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:isTeamReadyMode ? teamReadySymbol[survivorReady] : ""
+ "es" "->{1}. Infectado{2}"
+ }
+ "PanelCaster"
+ {
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:casterCount > 1 ? "s" : ""
+ "es" "->{1}. Comentador{2}"
+ }
+ "PanelSpectator"
+ {
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:specCount > 1 ? "s" : ""
+ "es" "->{1}. Espectador{2}"
+ }
+ "PanelMany"
+ {
+ "es" "**Muchos** (%d)"
+ }
+ // g_sDisruptReason[]
+ "Player marked unready"
+ {
+ "#format" "{1:N}{2:s}"
+ "es" "{green}¡Cuenta regresiva cancelada!{default} ({teamcolor}{1}{default}){2}"
+ }
+ "Player switched team"
+ {
+ "#format" "{1:N}"
+ "es" "{green}¡Cuenta regresiva cancelada!{default} ({teamcolor}{1} {olive}se cambio de equipo{default})"
+ }
+ "Player disconnected"
+ {
+ "#format" "{1:N}"
+ "es" "{green}¡Cuenta regresiva cancelada!{default} ({teamcolor}{1} {green}se a desconectado{default})"
+ }
+ "Admin aborted"
+ {
+ "#format" "{1:N}"
+ "es" "{green}¡El inicio forzado fue cancelado!{default} ({olive}{1}{default})"
+ }
+}
\ No newline at end of file
diff --git a/addons/sourcemod/translations/es/survivor_mvp.phrases.txt b/addons/sourcemod/translations/es/survivor_mvp.phrases.txt
new file mode 100644
index 000000000..cffe93119
--- /dev/null
+++ b/addons/sourcemod/translations/es/survivor_mvp.phrases.txt
@@ -0,0 +1,71 @@
+"Phrases"
+{
+ "YourRankSI"
+ {
+ "es" "{blue}Rango {green}Especial: {olive}#%d {blue}({default}%d {green}daño {blue}[{default}%.0f%%{blue}]{default}, %d {green}muertes {blue}[{default}%.0f%%{blue}])"
+ }
+ "YourRankCI"
+ {
+ "es" "{blue}Rango {green}Común: {olive}#%d {blue}({default}%d {green}comúnes {blue}[{default}%.0f%%{blue}])"
+ }
+ "YourRankFF"
+ {
+ "es" "{blue}Rango {green}Fuego Amigo: {olive}#%d {blue}({default}%d {green}fuego amigo {blue}[{default}%.0f%%{blue}])"
+ }
+ "BotName"
+ {
+ "es" "[BOT]"
+ }
+ "NobodyName"
+ {
+ "es" "{blue}({default}nadie{blue})"
+ }
+ "NotEnoughAction"
+ {
+ "es" "{blue}({default}no hay suficiente acción todavía{blue})"
+ }
+ "ReportSI_Absolute"
+ {
+ "es" "{green}SI: {olive}%s {blue}({default}%d {green}daño{default}, %d {green}muertes{blue})"
+ }
+ "ReportSI_Percent"
+ {
+ "es" "{green}SI: {olive}%s {blue}({green}daño {blue}[{default}%.0f%%{blue}]{default}, {green}muertes {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportSI_Full"
+ {
+ "es" "{green}Especial: {olive}%s {blue}({default}%d {green}daño {blue}[{default}%.0f%%{blue}]{default}, %d {green}muertes {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportSI_Nobody"
+ {
+ "es" "{green}SI: {blue}({default}Nadie{blue})"
+ }
+ "ReportCI_Absolute"
+ {
+ "es" "{green}CI: {olive}%s {blue}({default}%d {green}comúnes{blue})"
+ }
+ "ReportCI_Percent"
+ {
+ "es" "{green}CI: {olive}%s {blue}({green}comúnes {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportCI_Full"
+ {
+ "es" "{green}Comun: {olive}%s {blue}({default}%d {green}muertes {blue}[{default}%.0f%%{blue}])"
+ }
+ "NoFF"
+ {
+ "es" "{blue}({default}No hay fuego amigo en absoluto!{blue})"
+ }
+ "ReportFF_Absolute"
+ {
+ "es" "{green}FF: {olive}%s {blue}({default}%d {green}fuego amigo{blue})"
+ }
+ "ReportFF_Percent"
+ {
+ "es" "{green}FF: {olive}%s {blue}({green}fuego amigo {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportFF_Full"
+ {
+ "es" "{green}Fuego Amigo: {olive}%s {blue}({default}%d {green}daño {blue}[{default}%.0f%%{blue}])"
+ }
+}
diff --git a/addons/sourcemod/translations/es/teamflip.phrases.txt b/addons/sourcemod/translations/es/teamflip.phrases.txt
new file mode 100644
index 000000000..8107cb983
--- /dev/null
+++ b/addons/sourcemod/translations/es/teamflip.phrases.txt
@@ -0,0 +1,15 @@
+"Phrases"
+{
+ "FlippedSurvivor"
+ {
+ "es" "¡{green}%s{default} lanzo una moneda para elegir equipo y le salió {blue}Superviviente{default}!"
+ }
+ "FlippedInfected"
+ {
+ "es" "¡{green}%s{default} lanzo una moneda para elegir equipo y le salió {blue}Infectado{default}!"
+ }
+ "Wait"
+ {
+ "es" "[Teamflip] Vaya, reduce la velocidad. Espere al menos %d segundos."
+ }
+}
diff --git a/addons/sourcemod/translations/es/weapon_loadout.phrases.txt b/addons/sourcemod/translations/es/weapon_loadout.phrases.txt
new file mode 100644
index 000000000..d16b3925e
--- /dev/null
+++ b/addons/sourcemod/translations/es/weapon_loadout.phrases.txt
@@ -0,0 +1,35 @@
+"Phrases"
+{
+ "OnlyFirstReadyup"
+ {
+ "es" "Solo puede llamar a votación durante la primer ready-up de una ronda."
+ }
+ "CannotCalled"
+ {
+ "es" "No se puede convocar una votación en este momento, inténtelo de nuevo en un segundo o cinco."
+ }
+ "NeedFull"
+ {
+ "es" "Ambos equipos necesitan estar completos."
+ }
+ "SurvivorsGet"
+ {
+ "es" "Los supervivientes obtienen %s?"
+ }
+ "BeforeReadyup"
+ {
+ "es" "La votación no pasó antes del ready-up."
+ }
+ "WeaponsSet"
+ {
+ "es" "¡Los supervivientes obtuvieron sus armas!"
+ }
+ "Welcome"
+ {
+ "es" "Bienvenido a {blue}Zone{green}Hunters{default}."
+ }
+ "Type"
+ {
+ "es" "Escribe {olive}!mode{default} en el chat para votar que armas se usaran."
+ }
+}
diff --git a/addons/sourcemod/translations/l4d_tank_control_eq.phrases.txt b/addons/sourcemod/translations/l4d_tank_control_eq.phrases.txt
new file mode 100644
index 000000000..fa2dfe6d6
--- /dev/null
+++ b/addons/sourcemod/translations/l4d_tank_control_eq.phrases.txt
@@ -0,0 +1,35 @@
+"Phrases"
+{
+ "Tag_Selecion"
+ {
+ "en" "{red}<{default}Tank Selection{red}>{default}"
+ }
+ "Tag_Rage"
+ {
+ "en" "{red}<{default}Tank Rage{red}>{default}"
+ }
+ "YouBecomeTank"
+ {
+ "en" "{green}You{default} will become the {red}Tank{default}!"
+ }
+ "BecomeTank"
+ {
+ "en" "{olive}%s{default} will become the {red}Tank{default}!"
+ }
+ "UnableGiveTank"
+ {
+ "en" "[{olive}SM{default}] %s not on infected. Unable to give tank"
+ }
+ "Hit_RageMeterRefilled"
+ {
+ "en" "Rage Meter Refilled"
+ }
+ "YouRageMeterRefilled"
+ {
+ "en" "{olive}Rage Meter {red}Refilled{default}"
+ }
+ "RageMeterRefilled"
+ {
+ "en" "({green}%N{default}'s) {olive}Rage Meter {red}Refilled"
+ }
+}
diff --git a/addons/sourcemod/translations/l4d_tank_damage_announce.phrases.txt b/addons/sourcemod/translations/l4d_tank_damage_announce.phrases.txt
new file mode 100644
index 000000000..477746741
--- /dev/null
+++ b/addons/sourcemod/translations/l4d_tank_damage_announce.phrases.txt
@@ -0,0 +1,23 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "en" "[{green}!{default}]"
+ }
+ "AI"
+ {
+ "en" "AI"
+ }
+ "HealthRemaining"
+ {
+ "en" "{blue}Tank{default} ({olive}%s{default}) had {green}%d{default} health remaining"
+ }
+ "DealtToTank"
+ {
+ "en" "{blue}Damage{default} dealt to {blue}Tank{default} ({olive}%s{default})"
+ }
+ "PercentDamage"
+ {
+ "en" "{blue}[{default}%d{blue}] ({default}%i%%{blue}) {olive}%N"
+ }
+}
diff --git a/addons/sourcemod/translations/nodeathcamskip.phrases.txt b/addons/sourcemod/translations/nodeathcamskip.phrases.txt
new file mode 100644
index 000000000..6e84fed6b
--- /dev/null
+++ b/addons/sourcemod/translations/nodeathcamskip.phrases.txt
@@ -0,0 +1,23 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "en" "{red}[{default}Exploit{red}]{default}"
+ }
+ "DeathTimer"
+ {
+ "en" "{olive}%N{default} tried skipping the Death Timer."
+ }
+ "UnableToJoin"
+ {
+ "en" "You will be unable to join the Team for {red}%.1f{default} Seconds."
+ }
+ "Moved"
+ {
+ "en" "You will be moved automatically."
+ }
+ "SlotsReserved"
+ {
+ "en" "This team currently has slots {olive}reserved{default}."
+ }
+}
diff --git a/addons/sourcemod/translations/pause.phrases.txt b/addons/sourcemod/translations/pause.phrases.txt
index 914d44009..e5985b2cf 100644
--- a/addons/sourcemod/translations/pause.phrases.txt
+++ b/addons/sourcemod/translations/pause.phrases.txt
@@ -2,159 +2,166 @@
{
"Tag"
{
- "en" "{default}[{green}!{default}]"
+ "en" "[{green}!{default}]"
}
"ClientFullyLoaded"
{
- "en" "{olive}%N {default}has fully loaded"
+ "en" "{olive}%N{default} has fully loaded."
+ }
+ "PauseCountFormat"
+ {
+ "#format" "{1:d},{2:d}" // 1:PauseCount(client), 2:pauseLimitCvar.IntValue
+ "en" " [{green}{1}{default}/{green}{2}{default}]."
}
"PauseCommand"
{
- "en" "{olive}%N {blue}Paused{default}."
+ "#format" "{1:N},{2:s}" // 1:client, 2:sPauseCount
+ "en" "{olive}{1}{default} {blue}Paused{default}{2}"
}
// PauseDelay_Timer
"PauseAction"
{
- "en" "{red}PAUSED"
+ "en" "{red}PAUSED{default}"
}
"PauseDelay"
{
- "en" "{blue}Pausing in{default}: {olive}%d"
+ "en" "{blue}Pausing in{default}: {olive}%d{default}."
}
// ForcePause_Cmd
"Crashed"
{
- "en" "{olive}Game {default}was {green}force paused {default}because a player has {blue}crashed{default}."
+ "en" "{olive}Game{default} was {green}force paused{default} because a player has {blue}crashed{default}."
}
"ForcePause"
{
- "en" "A {green}force pause {default}is issued by {blue}Admin {default}({olive}%N{default})"
+ "en" "A {green}force pause{default} is issued by {blue}Admin{default} ({olive}%N{default})"
}
// Unpause_Cmd
"UnpauseSurvivors"
{
- "en" "{olive}%N %s{default}marked {blue}%s {default}ready."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, :2(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "en" "{olive}{1} {2}{default} marked {blue}{3}{default} ready."
}
"UnpauseInfected"
{
- "en" "{olive}%N %s{default}marked {red}%s {default}ready."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, :2(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "en" "{olive}{1} {2}{default} marked {red}{3}{default} ready."
}
"UnpauseInitiator"
{
- "en" "{olive}%N {default}marked {green}Initiator {default}ready."
+ "en" "{olive}%N{default} marked {green}Initiator{default} ready."
}
"UnpauseAdminConfirm"
{
- "en" "{olive}Teams {default}are ready. Wait for {blue}Admin {default}to {green}confirm{default}."
+ "en" "{olive}Teams{default} are ready. Wait for {blue}Admin{default} to {green}confirm{default}."
}
// Unready_Cmd
"UnreadySurvivors"
{
- "en" "{olive}%N %s{default}marked {blue}%s {default}not ready."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, 2:(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "en" "{olive}{1} {2}{default} marked {blue}{3}{default} not ready."
}
"UnreadyInfected"
{
- "en" "{olive}%N %s{default}marked {red}%s {default}not ready."
+ "#format" "{1:N},{2:s},{3:s}" // 1:client, 2:(initiatorReady && client == initiator) ? AsInitiator() : "", 3:L4D2_TeamName[clientTeam]
+ "en" "{olive}{1} {2}{default} marked {red}{3}{default} not ready."
}
"UnreadyInitiator"
{
- "en" "{olive}%N {default}marked {green}Initiator {default}not ready."
+ "en" "{olive}%N{default} marked {green}Initiator{default} not ready."
}
// void AsInitiator()
"AsInitiator"
{
- "en" "{default}as {green}Initiator "
+ "en" "as {green}Initiator{default} "
}
// ForceUnpause_Cmd
"ForceUnpause"
{
- "en" "A {green}force unpause {default}is issued by {blue}Admin {default}({olive}%N{default})"
+ "en" "A {green}force unpause{default} is issued by {blue}Admin{default} ({olive}%N{default})"
}
// AddPauseCount
"PauseLimit"
{
- "en" "You have reached your pause limit."
+ "en" "You have reached your {red}pause limit{default} [{green}%d{default}]."
}
// AttemptPause
"PauseDeferred"
{
- "en" "{red}Pause has been delayed due to a pick-up in progress!"
+ "en" "{red}Pause has been delayed due to a pick-up in progress!"
}
// Pause
"PausePreventSpawn"
{
- "en" "{default}Your {red}Spawn {default}has been prevented because of the Pause"
+ "en" "Your {red}Spawn{default} has been prevented because of the Pause."
}
// Show_Cmd
"PanelShow"
{
- "en" "Panel is now {blue}on{default}."
+ "en" "Panel is now {blue}on{default}."
}
"PanelHide"
{
- "en" "Panel is now {red}off{default}."
+ "en" "Panel is now {red}off{default}."
}
// UpdatePanel
"PanelSlots"
{
- "en" "▸ Server: %s\n▸ Slots: %d/%d"
- }
- "PanelDate"
- {
- "en" "▸ %m/%d/%Y - %I:%M%p"
+ "#format" "{1:s},{2:d},{3:d}" // 1:info, 2:GetSeriousClientCount(), 3:FindConVar("sv_maxplayers").IntValue
+ "en" "▸ Server: {1}\n▸ Slots: {2}/{3}"
}
"PanelTitle"
{
- "en" "▸ Ready Status"
+ "en" "▸ Ready Status"
}
"RequireAdmin"
{
- "en" "->0. Require Admin to Unpause"
+ "en" "->0. Require Admin to Unpause"
}
"SurvivorUnPaused"
{
- "en" "->1. Survivors: [√]"
+ "en" "->1. Survivors: [√]"
}
"SurvivorPaused"
{
- "en" "->1. Survivors: [X]"
+ "en" "->1. Survivors: [X]"
}
"InfectedUnPaused"
{
- "en" "->2. Infected: [√]"
+ "en" "->2. Infected: [√]"
}
"InfectedPaused"
{
- "en" "->2. Infected: [X]"
+ "en" "->2. Infected: [X]"
}
"InitiatorUnPaused"
{
- "en" "->0. Initiator: [√]"
+ "en" "->0. Initiator: [√]"
}
"InitiatorPaused"
{
- "en" "->0. Initiator: [X]"
+ "en" "->0. Initiator: [X]"
}
"AutoPauseCrash"
{
- "en" "▸ Forced AutoPause -> Crash"
+ "en" "▸ Forced AutoPause -> Crash"
}
"ForcePauseAdmin"
{
- "en" "▸ Force Pause -> %s (Admin)"
+ "en" "▸ Force Pause -> %s (Admin)"
}
"InitiatorPause"
{
- "en" "▸ Initiator -> %s (%s)"
+ "en" "▸ Initiator -> %s (%s)"
}
"DurationPause"
{
- "en" "▸ Duration: %02d:%02d"
+ "en" "▸ Duration: %02d:%02d"
}
// InitiateLiveCountdown
"CountdownCancelNotify"
{
- "en" "Say {olive}!unready {default}to cancel"
+ "en" "Say {olive}!unready{default} to cancel"
}
"GameisLive"
{
@@ -167,7 +174,7 @@
// CancelFullReady
"CountdownCancelled"
{
- "en" "{olive}%N {default}cancelled the countdown!"
+ "en" "{olive}%N{default} cancelled the countdown!"
}
// Callvote_Callback
"CallvoteNoSpec"
diff --git a/addons/sourcemod/translations/readyup.phrases.txt b/addons/sourcemod/translations/readyup.phrases.txt
index 62efbbeb4..c59505ec8 100644
--- a/addons/sourcemod/translations/readyup.phrases.txt
+++ b/addons/sourcemod/translations/readyup.phrases.txt
@@ -1,108 +1,128 @@
"Phrases"
{
-// The following uses bracket style color tags (see colors.inc)
- "PanelHide"
+ "Tag"
{
- "en" "[{olive}Readyup{default}] Panel is now {red}off{default}"
+ "en" "[{green}!{default}]"
}
-
- "PanelShow"
+ // readyup/action.inc
+ "LiveCountdownBegin"
{
- "en" "[{olive}Readyup{default}] Panel is now {blue}on{default}"
+ "en" "Going live!\nSay !unready / Press F2 to cancel"
}
-
- "ForceStartAdmin"
+ "RoundIsLive"
{
- "#format" "{1:N}"
- "en" "[{green}!{default}] {blue}Game {default}start is {green}forced {default}by {blue}Admin {default}({olive}{1}{default})"
+ "en" "Round is live!"
+ }
+ "LiveCountdown"
+ {
+ "#format" "{1:d}"
+ "en" "Live in: {1}\nSay !unready / Press F2 to cancel"
+ }
+ "AutoStartNotEnoughPlayers"
+ {
+ "en" "More players are required..."
+ }
+ "AutoStartWaiting"
+ {
+ "en" "Waiting for loading players..."
}
-
- "VoteInProgress"
+ "InitiateAutoStart"
{
- "en" "[{olive}Readyup{default}] There's {olive}a vote {green}in progress{default}."
+ "en" "Game will automatically start!"
}
-
- "VoteDelay"
+ "AutoStartCountdown"
{
"#format" "{1:d}"
- "en" "[{olive}Readyup{default}] Wait for another {blue}{1}s {default}to call a vote."
+ "en" "Game starts in: {1}"
}
-
- "Player marked unready"
+ "LiveCountdownCancelled"
{
- "#format" "{1:N}"
- "en" "{default}[{green}!{default}] {green}Countdown Cancelled! {default}({teamcolor}{1} {green}marked unready{default})"
+ "en" "Countdown Cancelled!"
}
-
- "Player switched team"
+ "CountUnReady"
{
- "#format" "{1:N}"
- "en" "{default}[{green}!{default}] {green}Countdown Cancelled! {default}({teamcolor}{1} {olive}switched team{default})"
+ "#format" "{1:d}{2:d}" // 1:GetUnReadyCount(client), 2:l4d_ready_unready_limit.IntValue
+ "en" " [{green}{1}{default}/{green}{2}{default}]"
}
-
- "Player disconnected"
+ "UnReadyLimit"
{
- "#format" "{1:N}"
- "en" "{default}[{green}!{default}] {green}Countdown Cancelled! {default}({teamcolor}{1} {green}disconnected{default})"
+ "en" "You have reached your {red}unready limit{default} [{green}%d{default}]"
}
-
- "Admin aborted"
+ // readyup/command.inc
+ "ForceStartAdmin"
{
"#format" "{1:N}"
- "en" "{default}[{green}!{default}] {green}Force Start Aborted! {default}({olive}{1} {green}issued{default})"
+ "en" "{blue}Game{default} start is {green}forced{default} by {blue}Admin{default} ({olive}{1}{default})"
+ }
+ "PanelHide"
+ {
+ "en" "Panel is now {red}off{default}"
+ }
+ "PanelShow"
+ {
+ "en" "Panel is now {blue}on{default}"
}
-
-
-// The following are not allowed to use any color tag
+ // readyup/panel.inc
"HintReady"
{
"en" "You are ready.\nSay !unready / Press F2 to unready."
}
-
"HintUnready"
{
"en" "You are not ready.\nSay !ready / Press F1 to ready up."
}
-
- "LiveCountdownBegin"
+ "PanelSlots"
{
- "en" "Going live!\nSay !unready / Press F2 to cancel"
+ "#format" "{1:s},{2:d},{3:d},{4:s}" // 1:ServerName, 2:GetSeriousClientCount(), 3:FindConVar("sv_maxplayers").IntValue, 4:cfgName
+ "en" "▸ Server: {1} \n▸ Slots: {2}/{3}\n▸ Config: {4}"
}
-
- "LiveCountdown"
+ "PanelCommands"
{
- "#format" "{1:d}"
- "en" "Live in: {1}\nSay !unready / Press F2 to cancel"
+ "en" "▸ Commands:"
}
-
- "LiveCountdownCancelled"
+ "PanelSurvivors"
{
- "en" "Countdown Cancelled!"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:isTeamReadyMode ? teamReadySymbol[survivorReady] : ""
+ "en" "->{1}. Survivors{2}"
}
-
- "RoundIsLive"
+ "PanelInfected"
{
- "en" "Round is live!"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:isTeamReadyMode ? teamReadySymbol[survivorReady] : ""
+ "en" "->{1}. Infected{2}"
}
-
- "InitiateAutoStart"
+ "PanelCaster"
{
- "en" "Game will automatically start!"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:casterCount > 1 ? "s" : ""
+ "en" "->{1}. Caster{2}"
}
-
- "AutoStartCountdown"
+ "PanelSpectator"
{
- "#format" "{1:d}"
- "en" "Game starts in: {1}"
+ "#format" "{1:d},{2:s}" // 1:++textCount, 2:specCount > 1 ? "s" : ""
+ "en" "->{1}. Spectator{2}"
}
-
- "AutoStartWaiting"
+ "PanelMany"
{
- "en" "Waiting for loading players..."
+ "en" "**Many** (%d)"
}
-
- "AutoStartNotEnoughPlayers"
+ // g_sDisruptReason[]
+ "Player marked unready"
{
- "en" "More players are required..."
+ "#format" "{1:N}{2:s}"
+ "en" "{green}Countdown Cancelled!{default} ({teamcolor}{1}{green} marked unready{default}){2}"
+ }
+ "Player switched team"
+ {
+ "#format" "{1:N}"
+ "en" "{green}Countdown Cancelled!{default} ({teamcolor}{1}{olive} switched team{default})"
+ }
+ "Player disconnected"
+ {
+ "#format" "{1:N}"
+ "en" "{green}Countdown Cancelled!{default} ({teamcolor}{1}{green} disconnected{default})"
+ }
+ "Admin aborted"
+ {
+ "#format" "{1:N}"
+ "en" "{green}Force Start Aborted!{default} ({olive}{1}{green} issued{default})"
}
}
\ No newline at end of file
diff --git a/addons/sourcemod/translations/survivor_mvp.phrases.txt b/addons/sourcemod/translations/survivor_mvp.phrases.txt
new file mode 100644
index 000000000..133e2a218
--- /dev/null
+++ b/addons/sourcemod/translations/survivor_mvp.phrases.txt
@@ -0,0 +1,75 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "en" "{blue}[{default}MVP{blue}]{default}"
+ }
+ "YourRankSI"
+ {
+ "en" "{blue}Rank {green}SI: {olive}#%d {blue}({default}%d {green}dmg {blue}[{default}%.0f%%{blue}]{default}, %d {green}kills {blue}[{default}%.0f%%{blue}])"
+ }
+ "YourRankCI"
+ {
+ "en" "{blue}Rank {green}CI: {olive}#%d {blue}({default}%d {green}common {blue}[{default}%.0f%%{blue}])"
+ }
+ "YourRankFF"
+ {
+ "en" "{blue}Rank {green}FF: {olive}#%d {blue}({default}%d {green}friendly fire {blue}[{default}%.0f%%{blue}])"
+ }
+ "BotName"
+ {
+ "en" "[BOT]"
+ }
+ "NobodyName"
+ {
+ "en" "{blue}({default}nobody{blue})"
+ }
+ "NotEnoughAction"
+ {
+ "en" "{blue}({default}not enough action yet{blue})"
+ }
+ "ReportSI_Absolute"
+ {
+ "en" "{green}SI: {olive}%s {blue}({default}%d {green}dmg{default}, %d {green}kills{blue})"
+ }
+ "ReportSI_Percent"
+ {
+ "en" "{green}SI: {olive}%s {blue}({green}dmg {blue}[{default}%.0f%%{blue}]{default}, {green}kills {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportSI_Full"
+ {
+ "en" "{green}SI: {olive}%s {blue}({default}%d {green}dmg {blue}[{default}%.0f%%{blue}]{default}, %d {green}kills {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportSI_Nobody"
+ {
+ "en" "{green}SI: {blue}({default}Nobody{blue})"
+ }
+ "ReportCI_Absolute"
+ {
+ "en" "{green}CI: {olive}%s {blue}({default}%d {green}common{blue})"
+ }
+ "ReportCI_Percent"
+ {
+ "en" "{green}CI: {olive}%s {blue}({green}common {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportCI_Full"
+ {
+ "en" "{green}CI: {olive}%s {blue}({default}%d {green}common {blue}[{default}%.0f%%{blue}])"
+ }
+ "NoFF"
+ {
+ "en" "{blue}({default}No friendly fire at all!{blue})"
+ }
+ "ReportFF_Absolute"
+ {
+ "en" "{green}FF: {olive}%s {blue}({default}%d {green}friendly fire{blue})"
+ }
+ "ReportFF_Percent"
+ {
+ "en" "{green}FF: {olive}%s {blue}({green}friendly fire {blue}[{default}%.0f%%{blue}])"
+ }
+ "ReportFF_Full"
+ {
+ "en" "{green}FF: {olive}%s {blue}({default}%d {green}friendly fire {blue}[{default}%.0f%%{blue}])"
+ }
+}
diff --git a/addons/sourcemod/translations/teamflip.phrases.txt b/addons/sourcemod/translations/teamflip.phrases.txt
new file mode 100644
index 000000000..8dce379d5
--- /dev/null
+++ b/addons/sourcemod/translations/teamflip.phrases.txt
@@ -0,0 +1,19 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "en" "[{olive}Teamflip{default}]"
+ }
+ "FlippedSurvivor"
+ {
+ "en" "{green}%s{default} flipped a team and is on the {blue}Survivor{default} team!"
+ }
+ "FlippedInfected"
+ {
+ "en" "{green}%s{default} flipped a team and is on the {red}Infected{default} team!"
+ }
+ "Wait"
+ {
+ "en" "[Teamflip] Whoa there buddy, slow down. Wait at least %d seconds."
+ }
+}
diff --git a/addons/sourcemod/translations/weapon_loadout.phrases.txt b/addons/sourcemod/translations/weapon_loadout.phrases.txt
new file mode 100644
index 000000000..5ddc01443
--- /dev/null
+++ b/addons/sourcemod/translations/weapon_loadout.phrases.txt
@@ -0,0 +1,39 @@
+"Phrases"
+{
+ "Tag"
+ {
+ "en" "{blue}[{green}Zone{blue}]{default}:"
+ }
+ "OnlyFirstReadyup"
+ {
+ "en" "You can only call for the vote during the first ready-up of a round."
+ }
+ "CannotCalled"
+ {
+ "en" "A vote cannot be called at this moment, try again in a second or five."
+ }
+ "NeedFull"
+ {
+ "en" "Both teams need to be full."
+ }
+ "SurvivorsGet"
+ {
+ "en" "Survivors get %s?"
+ }
+ "BeforeReadyup"
+ {
+ "en" "Vote didn't pass before you left ready-up."
+ }
+ "WeaponsSet"
+ {
+ "en" "Survivor Weapons Set!"
+ }
+ "Welcome"
+ {
+ "en" "Welcome to {blue}Zone{green}Hunters{default}."
+ }
+ "Type"
+ {
+ "en" "Type {olive}!mode{default} in chat to vote on weapons used."
+ }
+}