reworked mother zombie "randomizer"

uses randomized round-robin ensuring that a client will not be infected twice in a row
This commit is contained in:
BotoX 2016-02-17 09:03:40 +01:00
parent db0de91a18
commit 1bd2fb7354
3 changed files with 87 additions and 30 deletions

View File

@ -278,7 +278,7 @@ Action:ImmunityOnClientDamage(client, attacker, &Float:damage)
} }
// Check if spawn protection is on. // Check if spawn protection is on.
if (bInfectImmune[client][INFECT_TYPE_NORMAL]) if (bInfectImmune[client])
{ {
// Block damage. // Block damage.
return Plugin_Handled; return Plugin_Handled;

View File

@ -65,18 +65,24 @@ new Handle:hInfectCountdownData = INVALID_HANDLE;
new bool:bZombie[MAXPLAYERS + 1]; new bool:bZombie[MAXPLAYERS + 1];
/** /**
* @section bInfectImmune indexes * Array for flagging client to be protected.
*/
#define INFECT_TYPE_MOTHER 0
#define INFECT_TYPE_NORMAL 1
/**
* @endsection
*/ */
new bool:bInfectImmune[MAXPLAYERS + 1];
/** /**
* Array for flagging client to be protected. (See defines above) * Available mother zombie infection status.
*/ */
new bool:bInfectImmune[MAXPLAYERS + 1][2]; enum InfectMotherStatus
{
MotherStatus_None = 0,
MotherStatus_Chosen = 1,
MotherStatus_Last = 2
}
/**
* Array for storing client mother zombie protection status.
*/
new InfectMotherStatus:g_InfectMotherStatus[MAXPLAYERS + 1];
/** /**
* Available mother zombie infection modes. * Available mother zombie infection modes.
@ -139,9 +145,11 @@ InfectOnCommandsCreate()
*/ */
InfectClientInit(client) InfectClientInit(client)
{ {
// Reset infect immunity flags. // Reset infect immunity flag.
bInfectImmune[client][INFECT_TYPE_MOTHER] = false; bInfectImmune[client] = false;
bInfectImmune[client][INFECT_TYPE_NORMAL] = false;
// Reset mother zombie protection.
g_InfectMotherStatus[client] = MotherStatus_None;
} }
/** /**
@ -340,7 +348,7 @@ InfectOnClientHurt(client, attacker, const String:weapon[])
} }
// If client has infect immunity, then stop. // If client has infect immunity, then stop.
if (bInfectImmune[client][INFECT_TYPE_NORMAL]) if (bInfectImmune[client])
{ {
return; return;
} }
@ -460,7 +468,7 @@ public Action:InfectMotherZombie(Handle:timer)
} }
// Prune list of immune clients. // Prune list of immune clients.
eligibleclients = InfectRemoveImmuneClients(arrayEligibleClients); //eligibleclients = InfectRemoveImmuneClients(arrayEligibleClients);
// Move all clients to CT. // Move all clients to CT.
InfectMoveAllToCT(); InfectMoveAllToCT();
@ -531,29 +539,77 @@ public Action:InfectMotherZombie(Handle:timer)
} }
} }
new candidates = 0;
new Handle:aCandidates = CreateArray();
for (new n = 0; n < eligibleclients; n++)
{
// Get the client stored in the array index.
new client = GetArrayCell(arrayEligibleClients, n);
// If client hasn't been chosen this cycle, put into aCandidates array.
if (g_InfectMotherStatus[client] == MotherStatus_None)
{
PushArrayCell(aCandidates, client);
candidates++;
}
}
// Not enough candidates found.
if (candidates < mothercount)
{
for (new n = 0; n < eligibleclients; n++)
{
// Get the client stored in the array index.
new client = GetArrayCell(arrayEligibleClients, n);
// If client hasn't been chosen last round, put into aCandidates array,
// but only until we have enough candidates.
if (!(g_InfectMotherStatus[client] & MotherStatus_Last))
{
PushArrayCell(aCandidates, client);
candidates++;
// Enough candidates found.
if(candidates >= mothercount)
break;
}
}
// Restart the cycle.
// Reset all players MotherStatus.
for (int client = 0; client <= MAXPLAYERS; client++)
{
g_InfectMotherStatus[client] = MotherStatus_None;
}
}
// Remove MotherStatus_Last flag from all players.
for (int client = 0; client <= MAXPLAYERS; client++)
{
g_InfectMotherStatus[client] &= ~MotherStatus_Last;
}
// Infect players. // Infect players.
for (new n = 0; n < mothercount; n++) for (new n = 0; n < mothercount; n++)
{ {
// Recount eligible clients. // Stop if there are no more candidates.
eligibleclients = GetArraySize(arrayEligibleClients); if (candidates <= 0)
// Stop if there are no more eligible clients.
if (eligibleclients <= 0)
{ {
break; break;
} }
// Get a random array index. // Get a random array index.
new i = Math_GetRandomInt(0, eligibleclients - 1); new i = Math_GetRandomInt(0, candidates - 1);
// Get the client stored in the random array index. // Get the client stored in the random array index.
new client = GetArrayCell(arrayEligibleClients, i); new client = GetArrayCell(aCandidates, i);
// Infect player. // Infect player.
InfectHumanToZombie(client, _, true); InfectHumanToZombie(client, _, true);
// Remove player from eligible client list. // Remove player from eligible client list.
RemoveFromArray(arrayEligibleClients, i); RemoveFromArray(aCandidates, i);
candidates--;
} }
// Mother zombies have been infected. // Mother zombies have been infected.
@ -561,6 +617,7 @@ public Action:InfectMotherZombie(Handle:timer)
// Destroy client list. // Destroy client list.
CloseHandle(arrayEligibleClients); CloseHandle(arrayEligibleClients);
CloseHandle(aCandidates);
} }
/** /**
@ -596,7 +653,7 @@ InfectMoveAllToCT()
* @param keepLastPlayer Don't remove if there's only one player left. * @param keepLastPlayer Don't remove if there's only one player left.
* *
* @return Number of clients remaining. * @return Number of clients remaining.
*/
InfectRemoveImmuneClients(Handle:clientList, bool:keepLastPlayer = true) InfectRemoveImmuneClients(Handle:clientList, bool:keepLastPlayer = true)
{ {
new len = GetArraySize(clientList); new len = GetArraySize(clientList);
@ -632,6 +689,7 @@ InfectRemoveImmuneClients(Handle:clientList, bool:keepLastPlayer = true)
return len; return len;
} }
*/
/** /**
* Timer callback, displays countdown to clients. * Timer callback, displays countdown to clients.
@ -716,17 +774,16 @@ InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respa
new bool:infectconsecutiveblock = GetConVarBool(g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK]); new bool:infectconsecutiveblock = GetConVarBool(g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK]);
if (infectconsecutiveblock) if (infectconsecutiveblock)
{ {
// If this is a mother infect, flag the player as immune for next mother // If this is a mother infect, update the mother zombie protection status
// infection. Otherwise do nothing and keep the current flag.
if (motherinfect) if (motherinfect)
{ {
bInfectImmune[client][INFECT_TYPE_MOTHER] = true; g_InfectMotherStatus[client] = MotherStatus_Chosen | MotherStatus_Last;
} }
} }
else else
{ {
// Consecutive infection protection is disabled. No immunity. // Consecutive infection protection is disabled. No immunity.
bInfectImmune[client][INFECT_TYPE_MOTHER] = false; g_InfectMotherStatus[client] = MotherStatus_None;
} }
// Apply effects. // Apply effects.

View File

@ -76,7 +76,7 @@ SpawnProtectOnClientSpawnPost(client)
} }
// Disable spawn protection on client. // Disable spawn protection on client.
bInfectImmune[client][INFECT_TYPE_NORMAL] = false; bInfectImmune[client] = false;
// Start spawn protection. // Start spawn protection.
SpawnProtectStart(client); SpawnProtectStart(client);
@ -158,7 +158,7 @@ SpawnProtectStart(client)
} }
// Set spawn protect flag on client. // Set spawn protect flag on client.
bInfectImmune[client][INFECT_TYPE_NORMAL] = true; bInfectImmune[client] = true;
// Set spawn protect attributes. // Set spawn protect attributes.
ClassApplySpeedEx(client, speed); ClassApplySpeedEx(client, speed);
@ -212,7 +212,7 @@ public Action:SpawnProtectTimer(Handle:timer, any:client)
if (pSpawnProtectTime[client] <= 0) if (pSpawnProtectTime[client] <= 0)
{ {
// Remove protect flag. // Remove protect flag.
bInfectImmune[client][INFECT_TYPE_NORMAL] = false; bInfectImmune[client] = false;
// Tell client spawn protection is over. // Tell client spawn protection is over.
TranslationPrintHintText(client, "Spawn protection end"); TranslationPrintHintText(client, "Spawn protection end");