2013-01-04 18:24:32 +01:00
|
|
|
/*
|
|
|
|
* ============================================================================
|
|
|
|
*
|
|
|
|
* Zombie:Reloaded
|
|
|
|
*
|
|
|
|
* File: immunityhandler.inc
|
|
|
|
* Type: Core module
|
|
|
|
* Description: Manages infection immunity modes for every player.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
|
|
|
*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* ============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Current immunity modes.
|
|
|
|
*/
|
2013-01-05 21:10:38 +01:00
|
|
|
//new ImmunityMode:PlayerImmunityMode[MAXPLAYERS + 1] = {Immunity_None, ...};
|
2013-01-04 18:24:32 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Timers for handling timed immunity actions.
|
|
|
|
*/
|
|
|
|
new Handle:PlayerImmunityTimer[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
|
|
|
|
|
|
|
|
/**
|
2013-01-05 02:44:46 +01:00
|
|
|
* Remaining time of timed immunity actions.
|
2013-01-04 18:24:32 +01:00
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
new PlayerImmunityDuration[MAXPLAYERS + 1] = {-1, ...};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Cached attacker index for delayed infections, if available.
|
|
|
|
*/
|
|
|
|
new PlayerImmunityAttacker[MAXPLAYERS + 1] = {0, ...};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Timestamp of last action. Usage depends on mode (cooldown, etc).
|
|
|
|
*/
|
|
|
|
new PlayerImmunityLastUse[MAXPLAYERS + 1] = {0, ...};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether the player has passed a threshold (infect mode).
|
|
|
|
*/
|
|
|
|
new bool:PlayerImmunityThresholdPassed[MAXPLAYERS + 1] = {false, ...};
|
2013-01-04 18:24:32 +01:00
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
|
|
|
* Handles immunity when a client is about to be infected. This function may
|
|
|
|
* delay or block infection according to the immunity mode class settings.
|
|
|
|
*
|
|
|
|
* @param client Client that's being infected.
|
2013-01-05 02:44:46 +01:00
|
|
|
* @param attacker Attacker client (zombie).
|
2013-01-04 18:24:32 +01:00
|
|
|
*
|
|
|
|
* @return True if infection will be handled by this module, false if
|
|
|
|
* infection can be applied instantly.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
bool:ImmunityOnClientInfect(client, attacker)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 03:06:28 +01:00
|
|
|
//PrintToChatAll("ImmunityOnClientInfect(client=%d, attacker=%d)", client, attacker);
|
2013-01-05 02:44:46 +01:00
|
|
|
|
|
|
|
// Get immunity mode from client class.
|
2013-01-04 18:24:32 +01:00
|
|
|
new ImmunityMode:mode = ClassGetImmunityMode(client);
|
|
|
|
|
|
|
|
// Check mode.
|
|
|
|
switch(mode)
|
|
|
|
{
|
|
|
|
case Immunity_None:
|
|
|
|
{
|
|
|
|
// Instant infection.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case Immunity_Full:
|
|
|
|
{
|
|
|
|
// Full immunity, do nothing.
|
|
|
|
return true;
|
|
|
|
}
|
2013-01-05 02:44:46 +01:00
|
|
|
case Immunity_Infect:
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 21:10:38 +01:00
|
|
|
return ImmunityInfectModeHandler(client);
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
case Immunity_Delay:
|
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
return ImmunityDelayModeHandler(client, attacker);
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
case Immunity_Shield:
|
|
|
|
{
|
|
|
|
return ImmunityShieldModeHandler(client);
|
|
|
|
}
|
2013-01-05 02:44:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Current mode doesn't apply to infection.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-05 02:44:46 +01:00
|
|
|
/**
|
|
|
|
* TraceAttack hook.
|
|
|
|
*
|
|
|
|
* Returns whether attacker damage should be blocked. If damage is blocked this
|
|
|
|
* module will handle it.
|
|
|
|
*
|
|
|
|
* @param client Client index.
|
|
|
|
* @param attacker Attacker client, if any.
|
|
|
|
* @param damage Damage received by client.
|
|
|
|
* @param hitgroup Hitgroup receiving damage.
|
|
|
|
*
|
|
|
|
* @return True if damage should be blocked, false otherwise.
|
|
|
|
*/
|
|
|
|
bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damageType)
|
|
|
|
{
|
2013-01-05 03:06:28 +01:00
|
|
|
//PrintToChatAll("ImmunityOnClientTraceAttack(client=%d, attacker=%d, damage=%f, hitgroup=%d, damageType=%d)", client, attacker, damage, hitgroup, damageType);
|
2013-01-05 02:44:46 +01:00
|
|
|
|
|
|
|
// Check if there is no attacker (world damage).
|
|
|
|
if (!ZRIsClientValid(attacker))
|
|
|
|
{
|
|
|
|
// Allow damage.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get immunity mode from client class.
|
|
|
|
new ImmunityMode:mode = ClassGetImmunityMode(client);
|
|
|
|
|
|
|
|
// Check mode.
|
|
|
|
switch(mode)
|
|
|
|
{
|
|
|
|
case Immunity_Full:
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
// Block damage.
|
2013-01-04 18:24:32 +01:00
|
|
|
return true;
|
|
|
|
}
|
2013-01-05 02:44:46 +01:00
|
|
|
case Immunity_Infect:
|
|
|
|
{
|
|
|
|
// Client must be human.
|
|
|
|
if (InfectIsClientInfected(client))
|
|
|
|
{
|
|
|
|
// Allow damage.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if damage give HP below the infection threshold.
|
|
|
|
if (ImmunityBelowInfectThreshold(client, damage))
|
|
|
|
{
|
|
|
|
PlayerImmunityThresholdPassed[client] = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PlayerImmunityThresholdPassed[client] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case Immunity_Damage:
|
|
|
|
{
|
|
|
|
// Client must be zombie.
|
|
|
|
if (!InfectIsClientInfected(client))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get attacker weapon.
|
|
|
|
decl String:weapon[32];
|
|
|
|
weapon[0] = 0;
|
|
|
|
if (damageType == DMG_BLAST)
|
|
|
|
{
|
|
|
|
// Most likely a HE grenade. GetClientWeapon can't be used if
|
|
|
|
// the attacker throw grenades. The attacker may switch weapon
|
|
|
|
// before the grenade explodes.
|
|
|
|
strcopy(weapon, sizeof(weapon), "hegrenade");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GetClientWeapon(attacker, weapon, sizeof(weapon));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Since damage is blocked, trigger knock back hurt event manually.
|
|
|
|
KnockbackOnClientHurt(client, attacker, weapon, hitgroup, RoundToNearest(damage));
|
|
|
|
|
|
|
|
// Block damage from attacker.
|
|
|
|
return true;
|
|
|
|
}
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
2013-01-05 02:44:46 +01:00
|
|
|
|
|
|
|
return false;
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
2013-01-05 02:44:46 +01:00
|
|
|
* TakeDamage hook.
|
|
|
|
*
|
|
|
|
* Blocks or modifies damage in certain situations.
|
2013-01-04 18:24:32 +01:00
|
|
|
*
|
2013-01-05 02:44:46 +01:00
|
|
|
* @param client Client index.
|
|
|
|
* @param attacker Attacker client, if any.
|
|
|
|
* @param damage Damage received by client.
|
2013-01-04 18:24:32 +01:00
|
|
|
*
|
2013-01-05 02:44:46 +01:00
|
|
|
* @return True if damage was blocked, false otherwise.
|
2013-01-04 18:24:32 +01:00
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
// Check if there is no attacker (world damage).
|
|
|
|
if (!ZRIsClientValid(attacker))
|
|
|
|
{
|
|
|
|
// Allow damage.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get immunity mode from client class.
|
|
|
|
new ImmunityMode:mode = ClassGetImmunityMode(client);
|
|
|
|
|
|
|
|
switch(mode)
|
|
|
|
{
|
|
|
|
case Immunity_Infect:
|
|
|
|
{
|
|
|
|
// Prevent humans with low HP from dying when a zombie is
|
|
|
|
// attacking, and stab to death is disabled (threshold above zero).
|
|
|
|
if (ImmunityBelowInfectThreshold(client, damage))
|
|
|
|
{
|
|
|
|
// Fake hurt event because it's not triggered when the damage
|
|
|
|
// was removed (because no one is actually hurt).
|
|
|
|
InfectOnClientHurt(client, attacker, "knife");
|
|
|
|
|
|
|
|
// Block damage to prevent player from dying.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2013-01-05 22:58:43 +01:00
|
|
|
case Immunity_Delay:
|
|
|
|
{
|
|
|
|
// Fake hurt event because it's not triggered when the damage
|
|
|
|
// was removed (because no one is actually hurt). This event must
|
|
|
|
// still be triggered so that subsequent attacks are registered,
|
|
|
|
// without dealing any damage.
|
|
|
|
InfectOnClientHurt(client, attacker, "knife");
|
|
|
|
|
|
|
|
// Block damage to prevent player from dying.
|
|
|
|
return true;
|
|
|
|
}
|
2013-01-05 02:44:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Allow damage.
|
|
|
|
return false;
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
|
|
|
* Client is about to receive knock back (zombie).
|
|
|
|
*
|
|
|
|
* @param Client that's receiving knock back.
|
|
|
|
*
|
|
|
|
* @return True if knock back should be blocked, false otherwise.
|
|
|
|
*/
|
2013-01-05 21:10:38 +01:00
|
|
|
/*bool:ImmunityOnClientKnockBack(client)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 21:10:38 +01:00
|
|
|
}*/
|
2013-01-04 18:24:32 +01:00
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
2013-01-05 02:44:46 +01:00
|
|
|
* Handles infect mode immunity.
|
|
|
|
*
|
|
|
|
* Allow humans to receive damage from zombies until HP is below a certain
|
|
|
|
* threshold. If the threshold is zero, never infect.
|
2013-01-04 18:24:32 +01:00
|
|
|
*
|
|
|
|
* @param client Client that's being infected.
|
2013-01-05 02:44:46 +01:00
|
|
|
* @param attacker Attacker client (zombie).
|
2013-01-04 18:24:32 +01:00
|
|
|
*
|
|
|
|
* @return True if infection will be handled by this module, false if
|
|
|
|
* infection can be applied instantly.
|
|
|
|
*/
|
2013-01-05 21:10:38 +01:00
|
|
|
bool:ImmunityInfectModeHandler(client)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
// Note: ImmunityOnClientDamage and ImmunityOnClientTraceAttack hook into
|
|
|
|
// the damage module to prevent humans with low HP from dying when
|
|
|
|
// they're not supposed to.
|
|
|
|
|
|
|
|
new threshold = ClassGetImmunityAmount(client);
|
|
|
|
// Check if infection is disabled.
|
|
|
|
if (threshold == 0)
|
|
|
|
{
|
|
|
|
// Infection is handled here: blocked.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PlayerImmunityThresholdPassed[client])
|
|
|
|
{
|
|
|
|
// Client HP below threshold, allow instant infection.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
|
|
|
* Handles delayed infections.
|
|
|
|
*
|
|
|
|
* @param client Client that's being infected.
|
|
|
|
*
|
|
|
|
* @return True if infection will be handled by this module, false if
|
|
|
|
* infection can be applied instantly.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
bool:ImmunityDelayModeHandler(client, attacker)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
// Check if an infection is in progress
|
|
|
|
if (PlayerImmunityTimer[client] != INVALID_HANDLE)
|
|
|
|
{
|
|
|
|
// Additional attacks while a delayed infection is in progress will
|
|
|
|
// speedup the infection.
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
// Get reduction amount for subsequent zombie attack.
|
|
|
|
new reduction = ClassGetImmunityCooldown(client);
|
|
|
|
if (reduction > 0)
|
|
|
|
{
|
|
|
|
// Reduce duration. Add one because the timer handler itself reduce
|
|
|
|
// duration by one.
|
|
|
|
PlayerImmunityDuration[client] -= reduction + 1;
|
|
|
|
|
|
|
|
// Note: This feature can be used to trigger an instant infection
|
|
|
|
// when a human receive a second attack, by setting the
|
|
|
|
// reduction value high enough.
|
|
|
|
|
|
|
|
// Trigger timer event to reduce delay and infect faster.
|
|
|
|
ImmunityDelayTimerHandler(PlayerImmunityTimer[client], client);
|
|
|
|
}
|
2013-01-05 02:44:46 +01:00
|
|
|
|
|
|
|
// Block infection.
|
2013-01-05 22:58:43 +01:00
|
|
|
return true;
|
2013-01-05 02:44:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start a delayed infection. Initialize duration and attacker.
|
|
|
|
PlayerImmunityDuration[client] = ClassGetImmunityAmount(client);
|
|
|
|
PlayerImmunityAttacker[client] = attacker;
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
// Create repated 1-second timer for handling the countdown.
|
2013-01-05 02:44:46 +01:00
|
|
|
PlayerImmunityTimer[client] = CreateTimer(1.0, ImmunityDelayTimerHandler, client, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT);
|
|
|
|
|
|
|
|
// Block infection.
|
2013-01-05 22:58:43 +01:00
|
|
|
return true;
|
2013-01-05 02:44:46 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delayed infection timer handler. Handles countdown and infection when time
|
|
|
|
* is up.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
|
|
|
|
{
|
2013-01-05 22:58:43 +01:00
|
|
|
// Verify that client is still connected and alive.
|
2013-01-05 02:44:46 +01:00
|
|
|
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
|
|
|
{
|
|
|
|
// Client disconnected or died. Abort immunity action.
|
|
|
|
PlayerImmunityTimer[client] = INVALID_HANDLE;
|
|
|
|
ImmunityAbortHandler(client, false);
|
|
|
|
return Plugin_Stop;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reduce duration.
|
2013-01-05 22:58:43 +01:00
|
|
|
PlayerImmunityDuration[client] -= 1;
|
2013-01-05 02:44:46 +01:00
|
|
|
|
|
|
|
// Check if time is up.
|
|
|
|
if (PlayerImmunityDuration[client] <= 0)
|
|
|
|
{
|
|
|
|
// Time is up. Reset data.
|
|
|
|
PlayerImmunityDuration[client] = 0;
|
2013-01-05 22:58:43 +01:00
|
|
|
//PlayerImmunityTimer[client] = INVALID_HANDLE;
|
|
|
|
ImmunityAbortHandler(client);
|
2013-01-05 02:44:46 +01:00
|
|
|
|
|
|
|
// Infect client.
|
|
|
|
InfectHumanToZombie(client, PlayerImmunityAttacker[client]);
|
|
|
|
|
|
|
|
return Plugin_Stop;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Plugin_Continue;
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
|
|
|
* Handles shield mode immunity.
|
|
|
|
*
|
2013-01-05 02:44:46 +01:00
|
|
|
* Zombies will get a shield against knock back, while humans become immune of
|
|
|
|
* infections.
|
|
|
|
*
|
|
|
|
* @param client Client deploying shield.
|
|
|
|
* @param asZombie Client is a zombie.
|
2013-01-04 18:24:32 +01:00
|
|
|
*
|
|
|
|
* @return True if infection will be handled by this module, false if
|
|
|
|
* infection can be applied instantly.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
bool:ImmunityShieldModeHandler(client, bool:asZombie = true)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 21:10:38 +01:00
|
|
|
// Check cooldown.
|
|
|
|
|
|
|
|
// Deploy shield.
|
|
|
|
if (asZombie)
|
|
|
|
{
|
|
|
|
// Enable knock back shield.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Enable infection shield.
|
|
|
|
}
|
|
|
|
|
2013-01-05 02:44:46 +01:00
|
|
|
return false;
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
2013-01-05 02:44:46 +01:00
|
|
|
* Aborts any immunity mode in action (shields, delays, etc.). Resets values.
|
2013-01-04 18:24:32 +01:00
|
|
|
*
|
2013-01-05 02:44:46 +01:00
|
|
|
* @param client Client that's aborting immunity mode actions.
|
|
|
|
* @param resetLastUse Reset timestamp of last use. This will reset cooldown.
|
2013-01-04 18:24:32 +01:00
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityAbortHandler(client, bool:resetLastUse = true)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
// Stop timer, if running.
|
|
|
|
ZREndTimer(PlayerImmunityTimer[client]);
|
|
|
|
|
|
|
|
// Reset data.
|
|
|
|
PlayerImmunityDuration[client] = -1;
|
|
|
|
PlayerImmunityAttacker[client] = 0;
|
|
|
|
PlayerImmunityThresholdPassed[client] = false;
|
|
|
|
|
|
|
|
if (resetLastUse)
|
|
|
|
{
|
|
|
|
PlayerImmunityLastUse[client] = 0;
|
|
|
|
}
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-05 02:44:46 +01:00
|
|
|
/**
|
|
|
|
* Aborts all immunity modes in action.
|
|
|
|
*
|
|
|
|
* @param resetLastUse Reset timestamp of last use. This will reset cooldown.
|
|
|
|
*/
|
|
|
|
ImmunityAbortAll(bool:resetLastUse = true)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
for (new client = 0; client < MAXPLAYERS + 1; client++)
|
|
|
|
{
|
|
|
|
ImmunityAbortHandler(resetLastUse);
|
|
|
|
}
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Client was infected.
|
|
|
|
*/
|
|
|
|
ImmunityOnClientInfected(client)
|
|
|
|
{
|
|
|
|
// In case client was infected through an admin command or mother zombie
|
|
|
|
// selection, abort other actions in progress.
|
|
|
|
ImmunityAbortHandler(client);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Client was turned back into a human.
|
|
|
|
*/
|
2013-01-04 18:24:32 +01:00
|
|
|
ImmunityOnClientHuman(client)
|
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityAbortHandler(client);
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Client died.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityOnClientDeath(client)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityAbortHandler(client, false);
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Client connected to the server.
|
|
|
|
*/
|
2013-01-04 18:24:32 +01:00
|
|
|
ImmunityClientInit(client)
|
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityAbortHandler(client);
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Client spawned.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityClientSpawn(client)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityAbortHandler(client, false);
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Client disconnected.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityOnClientDisconnect(client)
|
2013-01-04 18:24:32 +01:00
|
|
|
{
|
2013-01-05 21:10:38 +01:00
|
|
|
ImmunityAbortHandler(client);
|
|
|
|
|
2013-01-05 02:44:46 +01:00
|
|
|
// Loop through attacker cache and remove client (set to 0).
|
2013-01-05 21:10:38 +01:00
|
|
|
for (new victim = 0; victim < sizeof(PlayerImmunityAttacker); victim++)
|
|
|
|
{
|
|
|
|
if (PlayerImmunityAttacker[victim] == client)
|
|
|
|
{
|
|
|
|
// The victim was attacked by this client, but the client is
|
|
|
|
// disconnecting now. Reset the attacker index to the world index.
|
|
|
|
PlayerImmunityAttacker[victim] = 0;
|
|
|
|
}
|
|
|
|
}
|
2013-01-05 02:44:46 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Client changed team.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
ImmunityOnClientTeam(client)
|
|
|
|
{
|
|
|
|
ImmunityAbortHandler(client);
|
2013-01-04 18:24:32 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Round ended.
|
|
|
|
*/
|
2013-01-04 18:24:32 +01:00
|
|
|
ImmunityOnRoundEnd()
|
|
|
|
{
|
|
|
|
ImmunityAbortAll();
|
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Map ended.
|
|
|
|
*/
|
2013-01-04 18:24:32 +01:00
|
|
|
ImmunityOnMapEnd()
|
|
|
|
{
|
|
|
|
ImmunityAbortAll();
|
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether the specified damage will take a client's HP below the
|
|
|
|
* infection threshold. Only used by "infect" immunity mode.
|
|
|
|
*
|
|
|
|
* @param client Client index.
|
|
|
|
* @param damage Damage applied to client.
|
|
|
|
*
|
|
|
|
* @return True if client HP go below threshold (immunity_amount) when
|
|
|
|
* applying damage, false otherwise.
|
|
|
|
*/
|
2013-01-05 02:44:46 +01:00
|
|
|
bool:ImmunityBelowInfectThreshold(client, Float:damage)
|
|
|
|
{
|
|
|
|
new threshold = ClassGetImmunityAmount(client);
|
|
|
|
new clientHP = GetClientHealth(client);
|
|
|
|
new dmg = RoundToNearest(damage);
|
|
|
|
|
|
|
|
// Check if the damage go below the HP threshold.
|
|
|
|
if (clientHP - dmg <= 0.0 && threshold > 0)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-05 22:58:43 +01:00
|
|
|
/*____________________________________________________________________________*/
|
|
|
|
|
2013-01-04 18:24:32 +01:00
|
|
|
/**
|
|
|
|
* Converts a string to an immunity mode.
|
|
|
|
*
|
|
|
|
* @param mode String to convert.
|
|
|
|
*
|
|
|
|
* @return Immunity mode or Immunity_Invalid on error.
|
|
|
|
*/
|
|
|
|
ImmunityMode:ImmunityStringToMode(const String:mode[])
|
|
|
|
{
|
|
|
|
if (strlen(mode) == 0)
|
|
|
|
{
|
|
|
|
return Immunity_Invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (StrEqual(mode, "none", false))
|
|
|
|
{
|
|
|
|
return Immunity_None;
|
|
|
|
}
|
|
|
|
else if (StrEqual(mode, "full", false))
|
|
|
|
{
|
|
|
|
return Immunity_Full;
|
|
|
|
}
|
|
|
|
else if (StrEqual(mode, "infect", false))
|
|
|
|
{
|
|
|
|
return Immunity_Infect;
|
|
|
|
}
|
|
|
|
else if (StrEqual(mode, "damage", false))
|
|
|
|
{
|
|
|
|
return Immunity_Damage;
|
|
|
|
}
|
|
|
|
else if (StrEqual(mode, "delay", false))
|
|
|
|
{
|
|
|
|
return Immunity_Delay;
|
|
|
|
}
|
|
|
|
else if (StrEqual(mode, "shield", false))
|
|
|
|
{
|
|
|
|
return Immunity_Shield;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Immunity_Invalid;
|
|
|
|
}
|
2013-01-05 22:58:43 +01:00
|
|
|
|
|
|
|
/*____________________________________________________________________________*/
|
2013-01-05 21:10:38 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts an immunity mode to a string.
|
|
|
|
*
|
|
|
|
* @param mode Mode to convert.
|
|
|
|
* @param buffer Destination string buffer.
|
|
|
|
* @param maxlen Size of buffer.
|
|
|
|
*
|
|
|
|
* @return Number of cells written.
|
|
|
|
*/
|
|
|
|
ImmunityModeToString(ImmunityMode:mode, String:buffer[], maxlen)
|
|
|
|
{
|
|
|
|
if (mode == Immunity_Invalid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case Immunity_None:
|
|
|
|
{
|
|
|
|
return strcopy(buffer, maxlen, "none");
|
|
|
|
}
|
|
|
|
case Immunity_Full:
|
|
|
|
{
|
|
|
|
return strcopy(buffer, maxlen, "full");
|
|
|
|
}
|
|
|
|
case Immunity_Infect:
|
|
|
|
{
|
|
|
|
return strcopy(buffer, maxlen, "infect");
|
|
|
|
}
|
|
|
|
case Immunity_Damage:
|
|
|
|
{
|
|
|
|
return strcopy(buffer, maxlen, "damage");
|
|
|
|
}
|
|
|
|
case Immunity_Delay:
|
|
|
|
{
|
|
|
|
return strcopy(buffer, maxlen, "delay");
|
|
|
|
}
|
|
|
|
case Immunity_Shield:
|
|
|
|
{
|
|
|
|
return strcopy(buffer, maxlen, "shield");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|