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.
if (bInfectImmune[client][INFECT_TYPE_NORMAL])
if (bInfectImmune[client])
{
// Block damage.
return Plugin_Handled;

View File

@ -65,18 +65,24 @@ new Handle:hInfectCountdownData = INVALID_HANDLE;
new bool:bZombie[MAXPLAYERS + 1];
/**
* @section bInfectImmune indexes
*/
#define INFECT_TYPE_MOTHER 0
#define INFECT_TYPE_NORMAL 1
/**
* @endsection
* Array for flagging client to be protected.
*/
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.
@ -139,9 +145,11 @@ InfectOnCommandsCreate()
*/
InfectClientInit(client)
{
// Reset infect immunity flags.
bInfectImmune[client][INFECT_TYPE_MOTHER] = false;
bInfectImmune[client][INFECT_TYPE_NORMAL] = false;
// Reset infect immunity flag.
bInfectImmune[client] = 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 (bInfectImmune[client][INFECT_TYPE_NORMAL])
if (bInfectImmune[client])
{
return;
}
@ -460,7 +468,7 @@ public Action:InfectMotherZombie(Handle:timer)
}
// Prune list of immune clients.
eligibleclients = InfectRemoveImmuneClients(arrayEligibleClients);
//eligibleclients = InfectRemoveImmuneClients(arrayEligibleClients);
// Move all clients to CT.
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.
for (new n = 0; n < mothercount; n++)
{
// Recount eligible clients.
eligibleclients = GetArraySize(arrayEligibleClients);
// Stop if there are no more eligible clients.
if (eligibleclients <= 0)
// Stop if there are no more candidates.
if (candidates <= 0)
{
break;
}
// 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.
new client = GetArrayCell(arrayEligibleClients, i);
new client = GetArrayCell(aCandidates, i);
// Infect player.
InfectHumanToZombie(client, _, true);
// Remove player from eligible client list.
RemoveFromArray(arrayEligibleClients, i);
RemoveFromArray(aCandidates, i);
candidates--;
}
// Mother zombies have been infected.
@ -561,6 +617,7 @@ public Action:InfectMotherZombie(Handle:timer)
// Destroy client list.
CloseHandle(arrayEligibleClients);
CloseHandle(aCandidates);
}
/**
@ -596,7 +653,7 @@ InfectMoveAllToCT()
* @param keepLastPlayer Don't remove if there's only one player left.
*
* @return Number of clients remaining.
*/
InfectRemoveImmuneClients(Handle:clientList, bool:keepLastPlayer = true)
{
new len = GetArraySize(clientList);
@ -632,6 +689,7 @@ InfectRemoveImmuneClients(Handle:clientList, bool:keepLastPlayer = true)
return len;
}
*/
/**
* 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]);
if (infectconsecutiveblock)
{
// If this is a mother infect, flag the player as immune for next mother
// infection. Otherwise do nothing and keep the current flag.
// If this is a mother infect, update the mother zombie protection status
if (motherinfect)
{
bInfectImmune[client][INFECT_TYPE_MOTHER] = true;
g_InfectMotherStatus[client] = MotherStatus_Chosen | MotherStatus_Last;
}
}
else
{
// Consecutive infection protection is disabled. No immunity.
bInfectImmune[client][INFECT_TYPE_MOTHER] = false;
g_InfectMotherStatus[client] = MotherStatus_None;
}
// Apply effects.

View File

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