Added validation of immunity amount and cooldown settings. Cleaned up some comments in code and class config.

This commit is contained in:
Richard Helgeby 2013-01-06 00:25:57 +01:00
parent 666ac57836
commit d0d1de8197
4 changed files with 174 additions and 17 deletions

View File

@ -34,18 +34,18 @@
// napalm_time decimal Napalm burn duration. Zombies only. // napalm_time decimal Napalm burn duration. Zombies only.
// immunity_mode text Special immunity modes. Some modes only works on humans or zombies: // immunity_mode text Special immunity modes. Some modes only works on humans or zombies:
// "none" - Instant infection. // "none" - Instant infection.
// (Not implemented) "full" - Completely immune. Humans can't be infected, zombies don't receive damage or knock back. Careful with this, it might not be that fun. // "full" - Completely immune. Humans can't be infected, zombies don't receive damage or knock back. Careful with this, it might not be that fun.
// "infect" - Humans are immune to infections until HP go below a threshold. Threshold at zero enable stabbing to death. // "infect" - Humans are immune to infections until HP go below a threshold. Threshold at zero enable stabbing to death.
// (Not implemented) "damage" - Zombies are immune to damage from humans/grenades, but still vulnerable to knock back. // "damage" - Zombies are immune to damage from humans/grenades, but still vulnerable to knock back.
// "delay" - Delay infection for a certain number of seconds. // "delay" - Delay infection for a certain number of seconds.
// (Not implemented) "shield" - Shield against infections (humans) or knock back (zombies) for a certain amount of seconds (similar to TF2's übercharge). // (Not implemented) "shield" - Shield against infections (humans) or knock back (zombies) for a certain amount of seconds (similar to TF2's übercharge).
// immunity_amount number Immunity data value (humans only). Depends on the immunity mode above: // immunity_amount number Immunity data value (humans only). Depends on the immunity mode above:
// "infect" - HP threshold. Infection will be allowed when HP go below this value. Zero will enable stabbing to death. // "infect" - HP threshold. Infection will be allowed when HP go below this value. Zero will enable stabbing to death.
// (Not implemented) "delay" - Number of seconds the infection is delayed since first hit by a zombie. // "delay" - Number of seconds the infection is delayed since first hit by a zombie.
// (Not implemented) "shield" - Number of seconds the shield is active. // (Not implemented) "shield" - Number of seconds the shield is active.
// immunity_cooldown number Number of seconds of cooldown for temporary immunity effects, depending on mode. // immunity_cooldown number Number of seconds of cooldown for temporary immunity effects, depending on mode.
// "shield" - Number of seconds the player has to wait before the shield can be used again.
// "delay" - Number of seconds the delay is reduced every time a zombie attack, while a delayed infection is in progress. // "delay" - Number of seconds the delay is reduced every time a zombie attack, while a delayed infection is in progress.
// "shield" - Number of seconds the player has to wait before the shield can be used again.
// no_fall_damage on/off Disables fall damage. // no_fall_damage on/off Disables fall damage.
// health number How many health points to give. // health number How many health points to give.
// health_regen_interval decimal Sets the regeneration interval. 0 to disable. // health_regen_interval decimal Sets the regeneration interval. 0 to disable.
@ -503,9 +503,9 @@
"napalm_time" "0.0" "napalm_time" "0.0"
// Player behavior // Player behavior
"immunity_mode" "delay" // Delay infection "immunity_mode" "none"
"immunity_amount" "10" // 10 seconds. "immunity_amount" "1"
"immunity_cooldown" "2" // Reduce delay 2 seconds every subsequent attack (infect faster). "immunity_cooldown" "60"
"no_fall_damage" "0" "no_fall_damage" "0"
"health" "100" "health" "100"
@ -548,8 +548,8 @@
"napalm_time" "0.0" "napalm_time" "0.0"
// Player behavior // Player behavior
"immunity_mode" "infect" // Immune against infection, "immunity_mode" "none"
"immunity_amount" "10" // when HP is above 10. "immunity_amount" "1"
"immunity_cooldown" "60" "immunity_cooldown" "60"
"no_fall_damage" "yes" "no_fall_damage" "yes"

View File

@ -220,7 +220,6 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag
if (ImmunityOnClientTraceAttack(client, attacker, damage, hitgroup, damagetype)) if (ImmunityOnClientTraceAttack(client, attacker, damage, hitgroup, damagetype))
{ {
// Block damage. // Block damage.
PrintToChatAll("DamageTraceAttack - Blocking damage.");
return ACTION_HANDLED; return ACTION_HANDLED;
} }

View File

@ -26,9 +26,14 @@
*/ */
/** /**
* Current immunity modes. * Maximum delay of infection.
*/ */
//new ImmunityMode:PlayerImmunityMode[MAXPLAYERS + 1] = {Immunity_None, ...}; #define IMMUNITY_MAX_DELAY 300
/**
* Maximum shield duration.
*/
#define IMMUNITY_MAX_SHIELD_TIME 300
/** /**
* Timers for handling timed immunity actions. * Timers for handling timed immunity actions.
@ -139,7 +144,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
{ {
case Immunity_Full: case Immunity_Full:
{ {
// Block damage. // Block damage (implies blocking knock back on zombies).
return true; return true;
} }
case Immunity_Infect: case Immunity_Infect:
@ -166,6 +171,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
// Client must be zombie. // Client must be zombie.
if (!InfectIsClientInfected(client)) if (!InfectIsClientInfected(client))
{ {
// Allow damage.
return false; return false;
} }
@ -192,6 +198,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
} }
} }
// Allow damage.
return false; return false;
} }
@ -364,7 +371,6 @@ public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
if (!IsClientInGame(client) || !IsPlayerAlive(client)) if (!IsClientInGame(client) || !IsPlayerAlive(client))
{ {
// Client disconnected or died. Abort immunity action. // Client disconnected or died. Abort immunity action.
PlayerImmunityTimer[client] = INVALID_HANDLE;
ImmunityAbortHandler(client, false); ImmunityAbortHandler(client, false);
return Plugin_Stop; return Plugin_Stop;
} }
@ -377,7 +383,6 @@ public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
{ {
// Time is up. Reset data. // Time is up. Reset data.
PlayerImmunityDuration[client] = 0; PlayerImmunityDuration[client] = 0;
//PlayerImmunityTimer[client] = INVALID_HANDLE;
ImmunityAbortHandler(client); ImmunityAbortHandler(client);
// Infect client. // Infect client.
@ -405,7 +410,7 @@ public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
*/ */
bool:ImmunityShieldModeHandler(client, bool:asZombie = true) bool:ImmunityShieldModeHandler(client, bool:asZombie = true)
{ {
// Check cooldown. // Stop if cooldown is still in progress.
// Deploy shield. // Deploy shield.
if (asZombie) if (asZombie)
@ -681,3 +686,137 @@ ImmunityModeToString(ImmunityMode:mode, String:buffer[], maxlen)
return 0; return 0;
} }
/**
* Returns whether the amount value is valid for the specified mode.
*
* @param mode Immunity mode to validate against.
* @param amount Amount value to test.
*
* @return True if valid, false otherwise.
*/
bool:ImmunityIsValidAmount(ImmunityMode:mode, amount)
{
switch (mode)
{
case Immunity_Invalid:
{
return false;
}
case Immunity_None:
{
// Immunity mode disabled, amount ignored.
return true;
}
case Immunity_Full:
{
// Amount isn't used in this mode.
return true;
}
case Immunity_Infect:
{
// Check if HP threshold is negative.
if (amount < 0)
{
return false;
}
// There's no upper limit. If the value is too high it will
// overflow and become negative.
}
case Immunity_Damage:
{
// Amount isn't used in this mode.
return true;
}
case Immunity_Delay:
{
if (amount <= 0 || amount > IMMUNITY_MAX_DELAY)
{
return false;
}
}
case Immunity_Shield:
{
if (amount <= 0 || amount > IMMUNITY_MAX_SHIELD_TIME)
{
return false;
}
}
default:
{
// Invalid mode.
return false;
}
}
// Passed.
return true;
}
/**
* Returns whether the cooldown value is valid for the specified mode.
*
* @param mode Immunity mode to validate against.
* @param cooldown Cooldown value to test.
*
* @return True if valid, false otherwise.
*/
bool:ImmunityIsValidCooldown(ImmunityMode:mode, cooldown)
{
switch (mode)
{
case Immunity_Invalid:
{
return false;
}
case Immunity_None:
{
// Immunity mode disabled, amount ignored.
return true;
}
case Immunity_Full:
{
// Cooldown isn't used in this mode.
return true;
}
case Immunity_Infect:
{
// Cooldown isn't used in this mode.
return true;
}
case Immunity_Damage:
{
// Cooldown isn't used in this mode.
return true;
}
case Immunity_Delay:
{
if (cooldown < 0)
{
return false;
}
// No upper limit. It may be intentional to use a high value so that
// the section attack will remove all delay and infect instantly.
}
case Immunity_Shield:
{
if (cooldown < 0)
{
return false;
}
// No upper limit. It may be intentional to use a high value so that
// the shield can only be used once per life.
}
default:
{
// Invalid mode.
return false;
}
}
// Passed.
return true;
}

View File

@ -297,7 +297,26 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
} }
// Immunity amount. // Immunity amount.
// TODO: Validate amount value. This depends on the immunity mode. new immunityAmount = ClassData[classindex][Class_ImmunityAmount];
if (!ImmunityIsValidAmount(immunityMode, immunityAmount))
{
flags += ZR_CLASS_IMMUNITY_AMOUNT;
if (logErrors)
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid immunity_amount at index %d.", classindex);
}
}
// Immunity cooldown.
new immunityCooldown = ClassData[classindex][Class_ImmunityCooldown];
if (!ImmunityIsValidCooldown(immunityMode, immunityCooldown))
{
flags += ZR_CLASS_IMMUNITY_COOLDOWN;
if (logErrors)
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid immunity_cooldown at index %d.", classindex);
}
}
// Health. // Health.
new health = ClassData[classindex][Class_Health]; new health = ClassData[classindex][Class_Health];