now adding cvar to exclude fakeclients, afks and autism bots from being mother zombie, also cvar for how long people must be afk before they cant be mother zombie. also critically a cvar that says fakeclients, autismbots and afks can actually be mother zombie if less than this cvar amount of players are connected. with 3 real players its not good if they constantly are mother zombie, hence at a low player count we still allow afks, fakes and autismbots to be. this update was done by claude AI
This commit is contained in:
@@ -325,6 +325,34 @@ zr_infect_mzombie_countdown "0"
|
|||||||
// Default: "0"
|
// Default: "0"
|
||||||
zr_infect_mzombie_respawn "0"
|
zr_infect_mzombie_respawn "0"
|
||||||
|
|
||||||
|
// Exclude fake clients (bots, SourceTV) from being picked as mother zombie. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]
|
||||||
|
// Default: "1"
|
||||||
|
zr_infect_mzombie_exclude_fakeclients "1"
|
||||||
|
|
||||||
|
// Exclude AFK players (AFKManager idle time of at least zr_infect_mzombie_exclude_afk_time) from being picked as mother zombie. Requires the AFKManager plugin. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]
|
||||||
|
// Default: "1"
|
||||||
|
zr_infect_mzombie_exclude_afk "1"
|
||||||
|
|
||||||
|
// Seconds a player has to be idle (according to AFKManager) to count as AFK for mother zombie selection.
|
||||||
|
// Default: "180"
|
||||||
|
zr_infect_mzombie_exclude_afk_time "180"
|
||||||
|
|
||||||
|
// Exclude autism bots (IsClientAutismBot from the BotTargeting plugin) from being picked as mother zombie. Requires the BotTargeting plugin. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]
|
||||||
|
// Default: "1"
|
||||||
|
zr_infect_mzombie_exclude_autismbots "1"
|
||||||
|
|
||||||
|
// The zr_infect_mzombie_exclude_* cvars only apply while at least this many REAL players are present.
|
||||||
|
// A REAL player is a player who is:
|
||||||
|
// - NOT a fake client
|
||||||
|
// - NOT AFK (AFKManager idle time >= zr_infect_mzombie_exclude_afk_time)
|
||||||
|
// - NOT an autism bot (BotTargeting)
|
||||||
|
// - NOT in spectate/unassigned
|
||||||
|
// - NOT dead
|
||||||
|
// Example: 5 = while there are fewer than 5 real players, fake clients, AFKs and autism bots can be mother zombie too.
|
||||||
|
// [0 = Always apply the exclusions]
|
||||||
|
// Default: "0"
|
||||||
|
zr_infect_mzombie_exclude_min_real "0"
|
||||||
|
|
||||||
// Maximum time from the start of the round until picking the mother zombie(s).
|
// Maximum time from the start of the round until picking the mother zombie(s).
|
||||||
// Default: "50.0"
|
// Default: "50.0"
|
||||||
zr_infect_spawntime_max "50.0"
|
zr_infect_spawntime_max "50.0"
|
||||||
|
|||||||
@@ -325,6 +325,34 @@ zr_infect_mzombie_countdown "0"
|
|||||||
// Default: "0"
|
// Default: "0"
|
||||||
zr_infect_mzombie_respawn "0"
|
zr_infect_mzombie_respawn "0"
|
||||||
|
|
||||||
|
// Exclude fake clients (bots, SourceTV) from being picked as mother zombie. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]
|
||||||
|
// Default: "1"
|
||||||
|
zr_infect_mzombie_exclude_fakeclients "1"
|
||||||
|
|
||||||
|
// Exclude AFK players (AFKManager idle time of at least zr_infect_mzombie_exclude_afk_time) from being picked as mother zombie. Requires the AFKManager plugin. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]
|
||||||
|
// Default: "1"
|
||||||
|
zr_infect_mzombie_exclude_afk "1"
|
||||||
|
|
||||||
|
// Seconds a player has to be idle (according to AFKManager) to count as AFK for mother zombie selection.
|
||||||
|
// Default: "180"
|
||||||
|
zr_infect_mzombie_exclude_afk_time "180"
|
||||||
|
|
||||||
|
// Exclude autism bots (IsClientAutismBot from the BotTargeting plugin) from being picked as mother zombie. Requires the BotTargeting plugin. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]
|
||||||
|
// Default: "1"
|
||||||
|
zr_infect_mzombie_exclude_autismbots "1"
|
||||||
|
|
||||||
|
// The zr_infect_mzombie_exclude_* cvars only apply while at least this many REAL players are present.
|
||||||
|
// A REAL player is a player who is:
|
||||||
|
// - NOT a fake client
|
||||||
|
// - NOT AFK (AFKManager idle time >= zr_infect_mzombie_exclude_afk_time)
|
||||||
|
// - NOT an autism bot (BotTargeting)
|
||||||
|
// - NOT in spectate/unassigned
|
||||||
|
// - NOT dead
|
||||||
|
// Example: 5 = while there are fewer than 5 real players, fake clients, AFKs and autism bots can be mother zombie too.
|
||||||
|
// [0 = Always apply the exclusions]
|
||||||
|
// Default: "0"
|
||||||
|
zr_infect_mzombie_exclude_min_real "0"
|
||||||
|
|
||||||
// Maximum time from the start of the round until picking the mother zombie(s).
|
// Maximum time from the start of the round until picking the mother zombie(s).
|
||||||
// Default: "50.0"
|
// Default: "50.0"
|
||||||
zr_infect_spawntime_max "50.0"
|
zr_infect_spawntime_max "50.0"
|
||||||
|
|||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#if defined _BotTargeting_Included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _BotTargeting_Included
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the client is one of the BotTargeting "autism bot" SteamIDs.
|
||||||
|
*
|
||||||
|
* @param client Client index. Must be in-game and authorized, otherwise a native error is thrown.
|
||||||
|
* @return True if the client is an autism bot, false otherwise.
|
||||||
|
*/
|
||||||
|
native bool IsClientAutismBot(int client);
|
||||||
|
|
||||||
|
public SharedPlugin __pl_BotTargeting =
|
||||||
|
{
|
||||||
|
name = "BotTargeting",
|
||||||
|
file = "BotTargeting.smx",
|
||||||
|
#if defined REQUIRE_PLUGIN
|
||||||
|
required = 1,
|
||||||
|
#else
|
||||||
|
required = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined REQUIRE_PLUGIN
|
||||||
|
public __pl_BotTargeting_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("IsClientAutismBot");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -116,6 +116,11 @@ enum CvarsList
|
|||||||
Handle:CVAR_INFECT_MZOMBIE_MAX,
|
Handle:CVAR_INFECT_MZOMBIE_MAX,
|
||||||
Handle:CVAR_INFECT_MZOMBIE_COUNTDOWN,
|
Handle:CVAR_INFECT_MZOMBIE_COUNTDOWN,
|
||||||
Handle:CVAR_INFECT_MZOMBIE_RESPAWN,
|
Handle:CVAR_INFECT_MZOMBIE_RESPAWN,
|
||||||
|
Handle:CVAR_INFECT_MZOMBIE_EXCLUDE_FAKECLIENTS,
|
||||||
|
Handle:CVAR_INFECT_MZOMBIE_EXCLUDE_AFK,
|
||||||
|
Handle:CVAR_INFECT_MZOMBIE_EXCLUDE_AFK_TIME,
|
||||||
|
Handle:CVAR_INFECT_MZOMBIE_EXCLUDE_AUTISMBOTS,
|
||||||
|
Handle:CVAR_INFECT_MZOMBIE_EXCLUDE_MIN_REAL,
|
||||||
Handle:CVAR_INFECT_EXPLOSION,
|
Handle:CVAR_INFECT_EXPLOSION,
|
||||||
Handle:CVAR_INFECT_FIREBALL,
|
Handle:CVAR_INFECT_FIREBALL,
|
||||||
Handle:CVAR_INFECT_SMOKE,
|
Handle:CVAR_INFECT_SMOKE,
|
||||||
@@ -338,6 +343,11 @@ CvarsCreate()
|
|||||||
g_hCvarsList[CVAR_INFECT_MZOMBIE_MAX] = CreateConVar("zr_infect_mzombie_max", "3", "Maximum number of mother zombies. Range mode only, cannot be zero.");
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_MAX] = CreateConVar("zr_infect_mzombie_max", "3", "Maximum number of mother zombies. Range mode only, cannot be zero.");
|
||||||
g_hCvarsList[CVAR_INFECT_MZOMBIE_COUNTDOWN] = CreateConVar("zr_infect_mzombie_countdown", "0", "Counts down to the first infection of the round. Countdown is printed in the middle of the client's screen.");
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_COUNTDOWN] = CreateConVar("zr_infect_mzombie_countdown", "0", "Counts down to the first infection of the round. Countdown is printed in the middle of the client's screen.");
|
||||||
g_hCvarsList[CVAR_INFECT_MZOMBIE_RESPAWN] = CreateConVar("zr_infect_mzombie_respawn", "0", "Teleport mother zombies back to spawn on infect.");
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_RESPAWN] = CreateConVar("zr_infect_mzombie_respawn", "0", "Teleport mother zombies back to spawn on infect.");
|
||||||
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_FAKECLIENTS] = CreateConVar("zr_infect_mzombie_exclude_fakeclients", "1", "Exclude fake clients (bots, SourceTV) from being picked as mother zombie. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]");
|
||||||
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_AFK] = CreateConVar("zr_infect_mzombie_exclude_afk", "1", "Exclude AFK players (AFKManager idle time of at least zr_infect_mzombie_exclude_afk_time) from being picked as mother zombie. Requires the AFKManager plugin. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]");
|
||||||
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_AFK_TIME] = CreateConVar("zr_infect_mzombie_exclude_afk_time", "180", "Seconds a player has to be idle (according to AFKManager) to count as AFK for mother zombie selection.", _, true, 1.0);
|
||||||
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_AUTISMBOTS] = CreateConVar("zr_infect_mzombie_exclude_autismbots", "1", "Exclude autism bots (IsClientAutismBot from the BotTargeting plugin) from being picked as mother zombie. Requires the BotTargeting plugin. Excluded players are still used as a last resort when no one else can be picked. [0 = Include | 1 = Exclude]");
|
||||||
|
g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_MIN_REAL] = CreateConVar("zr_infect_mzombie_exclude_min_real", "0", "The zr_infect_mzombie_exclude_* cvars only apply while at least this many REAL players are present. A REAL player is a player who is NOT a fake client, NOT AFK (AFKManager idle time >= zr_infect_mzombie_exclude_afk_time), NOT an autism bot (BotTargeting), NOT in spectate/unassigned and NOT dead. Example: 5 = while there are fewer than 5 real players, fake clients, AFKs and autism bots can be mother zombie too. [0 = Always apply the exclusions]", _, true, 0.0);
|
||||||
g_hCvarsList[CVAR_INFECT_SPAWNTIME_MIN] = CreateConVar("zr_infect_spawntime_min", "30.0", "Minimum time from the start of the round until picking the mother zombie(s).");
|
g_hCvarsList[CVAR_INFECT_SPAWNTIME_MIN] = CreateConVar("zr_infect_spawntime_min", "30.0", "Minimum time from the start of the round until picking the mother zombie(s).");
|
||||||
g_hCvarsList[CVAR_INFECT_SPAWNTIME_MAX] = CreateConVar("zr_infect_spawntime_max", "50.0", "Maximum time from the start of the round until picking the mother zombie(s).");
|
g_hCvarsList[CVAR_INFECT_SPAWNTIME_MAX] = CreateConVar("zr_infect_spawntime_max", "50.0", "Maximum time from the start of the round until picking the mother zombie(s).");
|
||||||
g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK] = CreateConVar("zr_infect_consecutive_block", "1", "Prevent a player from being chosen as mother zombie two rounds in a row.");
|
g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK] = CreateConVar("zr_infect_consecutive_block", "1", "Prevent a player from being chosen as mother zombie two rounds in a row.");
|
||||||
|
|||||||
+278
-33
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#tryinclude "AFKManager.inc"
|
#tryinclude "AFKManager.inc"
|
||||||
#tryinclude "TeamManager.inc"
|
#tryinclude "TeamManager.inc"
|
||||||
|
#include <BotTargeting>
|
||||||
|
|
||||||
/* Restore old REQUIRE_PLUGIN value if necessary */
|
/* Restore old REQUIRE_PLUGIN value if necessary */
|
||||||
#if defined TEMP_REQUIRE_PLUGIN
|
#if defined TEMP_REQUIRE_PLUGIN
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
|
|
||||||
new bool:g_AFKManagerLoaded = false;
|
new bool:g_AFKManagerLoaded = false;
|
||||||
new bool:g_TeamManagerLoaded = false;
|
new bool:g_TeamManagerLoaded = false;
|
||||||
|
new bool:g_BotTargetingLoaded = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @section Explosion flags.
|
* @section Explosion flags.
|
||||||
@@ -122,6 +124,9 @@ InfectOnAllPluginsLoaded()
|
|||||||
g_TeamManagerLoaded = LibraryExists("TeamManager");
|
g_TeamManagerLoaded = LibraryExists("TeamManager");
|
||||||
LogMessage("TeamManager: %s", (g_TeamManagerLoaded ? "loaded" : "not loaded"));
|
LogMessage("TeamManager: %s", (g_TeamManagerLoaded ? "loaded" : "not loaded"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
g_BotTargetingLoaded = LibraryExists("BotTargeting");
|
||||||
|
LogMessage("BotTargeting: %s", (g_BotTargetingLoaded ? "loaded" : "not loaded"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,6 +144,11 @@ InfectOnLibraryAdded(const String:name[])
|
|||||||
// TeamManager loaded.
|
// TeamManager loaded.
|
||||||
g_TeamManagerLoaded = true;
|
g_TeamManagerLoaded = true;
|
||||||
}
|
}
|
||||||
|
else if (StrEqual(name, "BotTargeting"))
|
||||||
|
{
|
||||||
|
// BotTargeting loaded.
|
||||||
|
g_BotTargetingLoaded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,6 +166,200 @@ InfectOnLibraryRemoved(const String:name[])
|
|||||||
// TeamManager unloaded.
|
// TeamManager unloaded.
|
||||||
g_TeamManagerLoaded = false;
|
g_TeamManagerLoaded = false;
|
||||||
}
|
}
|
||||||
|
else if (StrEqual(name, "BotTargeting"))
|
||||||
|
{
|
||||||
|
// BotTargeting unloaded.
|
||||||
|
g_BotTargetingLoaded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a (non-fake) client is AFK according to AFKManager.
|
||||||
|
*
|
||||||
|
* @param client The client index. Must be in-game and not a fake client.
|
||||||
|
* @return True if AFKManager is loaded and the client has been idle for
|
||||||
|
* at least zr_infect_mzombie_exclude_afk_time seconds.
|
||||||
|
*/
|
||||||
|
bool:InfectIsClientAFK(client)
|
||||||
|
{
|
||||||
|
#if defined _AFKManager_Included
|
||||||
|
if (g_AFKManagerLoaded && GetClientIdleTime(client) >= GetConVarInt(g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_AFK_TIME]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a (non-fake) client is an autism bot according to BotTargeting.
|
||||||
|
*
|
||||||
|
* @param client The client index. Must be in-game and not a fake client.
|
||||||
|
* @return True if BotTargeting is loaded and says the client is an autism bot.
|
||||||
|
*/
|
||||||
|
bool:InfectIsClientAutismBot(client)
|
||||||
|
{
|
||||||
|
// The native throws on unauthorized clients, so check that first.
|
||||||
|
return (g_BotTargetingLoaded && IsClientAuthorized(client) && IsClientAutismBot(client));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a client falls in one of the categories excluded from mother zombie
|
||||||
|
* by the zr_infect_mzombie_exclude_fakeclients/afk/autismbots cvars.
|
||||||
|
*
|
||||||
|
* This only looks at the category cvars, not at zr_infect_mzombie_exclude_min_real.
|
||||||
|
*
|
||||||
|
* @param client The client index. Must be in-game.
|
||||||
|
* @return True if the client is excluded, false otherwise.
|
||||||
|
*/
|
||||||
|
bool:InfectIsClientMotherExcluded(client)
|
||||||
|
{
|
||||||
|
// Bots / SourceTV.
|
||||||
|
if (IsFakeClient(client))
|
||||||
|
{
|
||||||
|
return GetConVarBool(g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_FAKECLIENTS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AFK players.
|
||||||
|
if (GetConVarBool(g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_AFK]) && InfectIsClientAFK(client))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Autism bots.
|
||||||
|
if (GetConVarBool(g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_AUTISMBOTS]) && InfectIsClientAutismBot(client))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a client is a "real" player, as used by zr_infect_mzombie_exclude_min_real.
|
||||||
|
*
|
||||||
|
* A real player is in-game, on a team (not spectate/unassigned), alive, and is
|
||||||
|
* not a fake client, not AFK and not an autism bot. This definition is fixed and
|
||||||
|
* does not depend on the zr_infect_mzombie_exclude_* category cvars.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @return True if the client is a real player, false otherwise.
|
||||||
|
*/
|
||||||
|
bool:InfectIsClientRealPlayer(client)
|
||||||
|
{
|
||||||
|
if (!IsClientInGame(client) || !ZRIsClientOnTeam(client) || !IsPlayerAlive(client))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsFakeClient(client) || InfectIsClientAFK(client) || InfectIsClientAutismBot(client))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the mother zombie exclusions currently apply, based on
|
||||||
|
* zr_infect_mzombie_exclude_min_real.
|
||||||
|
*
|
||||||
|
* @return True if there are at least zr_infect_mzombie_exclude_min_real real
|
||||||
|
* players (or the cvar is 0), false otherwise.
|
||||||
|
*/
|
||||||
|
bool:InfectMotherExclusionsActive()
|
||||||
|
{
|
||||||
|
new minreal = GetConVarInt(g_hCvarsList[CVAR_INFECT_MZOMBIE_EXCLUDE_MIN_REAL]);
|
||||||
|
if (minreal <= 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
new realplayers = 0;
|
||||||
|
for (new x = 1; x <= MaxClients; x++)
|
||||||
|
{
|
||||||
|
if (InfectIsClientRealPlayer(x))
|
||||||
|
{
|
||||||
|
realplayers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (realplayers >= minreal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the mother zombie candidate lists.
|
||||||
|
*
|
||||||
|
* All alive humans on a team that the API allows are split into two lists:
|
||||||
|
* - arrayEligibleClients: regular candidates. Only these go through the
|
||||||
|
* consecutive block / round-robin cycle logic.
|
||||||
|
* - arrayExcludedClients: fake clients, AFKs and autism bots excluded by the
|
||||||
|
* zr_infect_mzombie_exclude_* cvars. Only used as a last resort when the
|
||||||
|
* regular candidates can't fill the mother zombie count.
|
||||||
|
*
|
||||||
|
* When zr_infect_mzombie_exclude_min_real isn't reached, nobody is excluded.
|
||||||
|
*
|
||||||
|
* @param arrayEligibleClients Array to push regular candidates into.
|
||||||
|
* @param arrayExcludedClients Array to push excluded candidates into.
|
||||||
|
* @return Number of regular candidates.
|
||||||
|
*/
|
||||||
|
InfectCreateMotherCandidateLists(Handle:arrayEligibleClients, Handle:arrayExcludedClients)
|
||||||
|
{
|
||||||
|
new Handle:arrayAllClients = CreateArray();
|
||||||
|
new allclients = ZRCreateEligibleClientList(arrayAllClients, true, true, true, true);
|
||||||
|
|
||||||
|
new bool:exclude = InfectMotherExclusionsActive();
|
||||||
|
new eligibleclients = 0;
|
||||||
|
|
||||||
|
for (new n = 0; n < allclients; n++)
|
||||||
|
{
|
||||||
|
new client = GetArrayCell(arrayAllClients, n);
|
||||||
|
|
||||||
|
if (exclude && InfectIsClientMotherExcluded(client))
|
||||||
|
{
|
||||||
|
PushArrayCell(arrayExcludedClients, client);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PushArrayCell(arrayEligibleClients, client);
|
||||||
|
eligibleclients++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(arrayAllClients);
|
||||||
|
return eligibleclients;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Picks a random client from the list that is still human.
|
||||||
|
*
|
||||||
|
* @param arrayClients List of client indexes.
|
||||||
|
* @return Client index, or -1 if nobody in the list is human.
|
||||||
|
*/
|
||||||
|
InfectGetRandomHumanFromList(Handle:arrayClients)
|
||||||
|
{
|
||||||
|
new Handle:arrayHumans = CreateArray();
|
||||||
|
new size = GetArraySize(arrayClients);
|
||||||
|
|
||||||
|
for (new n = 0; n < size; n++)
|
||||||
|
{
|
||||||
|
new client = GetArrayCell(arrayClients, n);
|
||||||
|
if (IsClientInGame(client) && InfectIsClientHuman(client))
|
||||||
|
{
|
||||||
|
PushArrayCell(arrayHumans, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new client = -1;
|
||||||
|
new humans = GetArraySize(arrayHumans);
|
||||||
|
if (humans)
|
||||||
|
{
|
||||||
|
client = GetArrayCell(arrayHumans, Math_GetRandomInt(0, humans - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(arrayHumans);
|
||||||
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,15 +438,10 @@ InfectClientInit(client)
|
|||||||
if(!IsClientInGame(x))
|
if(!IsClientInGame(x))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
// Clients that can never be mother zombie are never in the cycle,
|
||||||
#if defined _AFKManager_Included
|
// don't let them water down the ratio.
|
||||||
if(g_AFKManagerLoaded)
|
if(InfectIsClientMotherExcluded(x))
|
||||||
{
|
continue;
|
||||||
if(GetClientIdleTime(x) > 3 * 60)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
players++;
|
players++;
|
||||||
|
|
||||||
@@ -580,15 +779,18 @@ public Action:InfectMotherZombie(Handle:timer)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create eligible player list.
|
// Create candidate lists: regular candidates and excluded (fake clients, AFKs, autism bots).
|
||||||
new Handle:arrayEligibleClients = CreateArray();
|
new Handle:arrayEligibleClients = CreateArray();
|
||||||
new eligibleclients = ZRCreateEligibleClientList(arrayEligibleClients, true, true, true, true);
|
new Handle:arrayExcludedClients = CreateArray();
|
||||||
|
new eligibleclients = InfectCreateMotherCandidateLists(arrayEligibleClients, arrayExcludedClients);
|
||||||
|
new excludedclients = GetArraySize(arrayExcludedClients);
|
||||||
|
|
||||||
// If there are no eligible client's then stop.
|
// If nobody is alive on a team (everyone dead or in spectate), then stop.
|
||||||
if (!eligibleclients)
|
if (!eligibleclients && !excludedclients)
|
||||||
{
|
{
|
||||||
// Destroy handle.
|
// Destroy handles.
|
||||||
CloseHandle(arrayEligibleClients);
|
CloseHandle(arrayEligibleClients);
|
||||||
|
CloseHandle(arrayExcludedClients);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,6 +892,15 @@ public Action:InfectMotherZombie(Handle:timer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Split excluded clients too, so the last resort prefers those who weren't mother zombie last round.
|
||||||
|
new Handle:aExcludedMain = CreateArray();
|
||||||
|
new Handle:aExcludedAlt = CreateArray();
|
||||||
|
for (new n = 0; n < excludedclients; n++)
|
||||||
|
{
|
||||||
|
new client = GetArrayCell(arrayExcludedClients, n);
|
||||||
|
PushArrayCell(g_bInfectMotherLast[client] ? aExcludedAlt : aExcludedMain, client);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove mother zombie last flag from all players.
|
// Remove mother zombie last flag from all players.
|
||||||
for (int client = 0; client <= MAXPLAYERS; client++)
|
for (int client = 0; client <= MAXPLAYERS; client++)
|
||||||
{
|
{
|
||||||
@@ -701,7 +912,11 @@ public Action:InfectMotherZombie(Handle:timer)
|
|||||||
// Infect players.
|
// Infect players.
|
||||||
new infected = 0;
|
new infected = 0;
|
||||||
new infected_human_to_zombie_failed = 0;
|
new infected_human_to_zombie_failed = 0;
|
||||||
while (infected < mothercount)
|
|
||||||
|
// Only run the regular selection (and its cycle reset) if there are regular candidates.
|
||||||
|
// If there are none, all alive players are excluded ones and the cycle of the regular
|
||||||
|
// players must not be touched.
|
||||||
|
while (eligibleclients && infected < mothercount)
|
||||||
{
|
{
|
||||||
// Infect one of the main candidates.
|
// Infect one of the main candidates.
|
||||||
if (candidatesMain)
|
if (candidatesMain)
|
||||||
@@ -751,40 +966,70 @@ public Action:InfectMotherZombie(Handle:timer)
|
|||||||
}
|
}
|
||||||
else // We have no candidates at all. time to fuck over random people!
|
else // We have no candidates at all. time to fuck over random people!
|
||||||
{
|
{
|
||||||
// Infect player.
|
// Pick a random regular candidate that is still human (ignores the consecutive block).
|
||||||
if (eligibleclients)
|
new client = InfectGetRandomHumanFromList(arrayEligibleClients);
|
||||||
|
if (client == -1)
|
||||||
{
|
{
|
||||||
new randindex = Math_GetRandomInt(0, eligibleclients - 1);
|
break; // All regular candidates are zombies already, fall through to the excluded clients.
|
||||||
new client = GetArrayCell(arrayEligibleClients, randindex);
|
}
|
||||||
if (InfectHumanToZombie(client, _, true))
|
|
||||||
{
|
// Infect player.
|
||||||
infected++;
|
if (InfectHumanToZombie(client, _, true))
|
||||||
}
|
{
|
||||||
else
|
infected++;
|
||||||
{
|
|
||||||
infected_human_to_zombie_failed++;
|
|
||||||
if (infected_human_to_zombie_failed > 100)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
//doing testround on dev server would cause script time execution, hence this was added.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break; //prevent infinite loop. should be very unlikely we end up here.
|
infected_human_to_zombie_failed++;
|
||||||
|
if (infected_human_to_zombie_failed > 100)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
//doing testround on dev server would cause script time execution, hence this was added.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Last resort: not enough regular candidates, so infect excluded clients (fake clients, AFKs,
|
||||||
|
// autism bots). A round must not start without mother zombies.
|
||||||
|
// Prefer those who weren't mother zombie last round.
|
||||||
|
while (infected < mothercount)
|
||||||
|
{
|
||||||
|
new Handle:aExcluded = INVALID_HANDLE;
|
||||||
|
if (GetArraySize(aExcludedMain))
|
||||||
|
{
|
||||||
|
aExcluded = aExcludedMain;
|
||||||
|
}
|
||||||
|
else if (GetArraySize(aExcludedAlt))
|
||||||
|
{
|
||||||
|
aExcluded = aExcludedAlt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break; // Nobody left.
|
||||||
|
}
|
||||||
|
|
||||||
|
new i = Math_GetRandomInt(0, GetArraySize(aExcluded) - 1);
|
||||||
|
new client = GetArrayCell(aExcluded, i);
|
||||||
|
RemoveFromArray(aExcluded, i);
|
||||||
|
|
||||||
|
if (IsClientInGame(client) && InfectIsClientHuman(client) && InfectHumanToZombie(client, _, true))
|
||||||
|
{
|
||||||
|
infected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mother zombies have been infected.
|
// Mother zombies have been infected.
|
||||||
g_bZombieSpawned = true;
|
g_bZombieSpawned = true;
|
||||||
|
|
||||||
// Destroy client list.
|
// Destroy client list.
|
||||||
CloseHandle(arrayEligibleClients);
|
CloseHandle(arrayEligibleClients);
|
||||||
|
CloseHandle(arrayExcludedClients);
|
||||||
CloseHandle(aCandidatesMain);
|
CloseHandle(aCandidatesMain);
|
||||||
CloseHandle(aCandidatesAlt);
|
CloseHandle(aCandidatesAlt);
|
||||||
|
CloseHandle(aExcludedMain);
|
||||||
|
CloseHandle(aExcludedAlt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user