Fixed immunity modes not obeying spawn protection. Implemented "kill" immunity mode.

This commit is contained in:
Richard Helgeby 2013-01-11 10:07:18 +01:00
parent 86319d21ac
commit 5b7d1b2ff3
6 changed files with 109 additions and 38 deletions

View File

@ -34,6 +34,7 @@
// 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.
// "kill" - Humans are instantly killed instead of turning zombies when attacked by zombies.
// "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.
// "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.

View File

@ -1257,6 +1257,11 @@ the admin-only flag in the <span class="code">flags</span> attribute.</p>
<td class="valueoption">none</td> <td class="valueoption">none</td>
<td>No immunity mode. Instant infection of humans.</td> <td>No immunity mode. Instant infection of humans.</td>
</tr> </tr>
<tr>
<td class="valueoption">kill</td>
<td><strong>Humans only.</strong> Humans will die instantly instead of turning
zombies when attacked by zombies.</td>
</tr>
<tr> <tr>
<td class="valueoption">full</td> <td class="valueoption">full</td>
<td>Completely immune. Careful with this mode, it will break the game. <td>Completely immune. Careful with this mode, it will break the game.
@ -1273,12 +1278,15 @@ the admin-only flag in the <span class="code">flags</span> attribute.</p>
<tr> <tr>
<td class="valueoption">damage</td> <td class="valueoption">damage</td>
<td><strong>Zombies only.</strong> Zombies are immune to damage from humans/ <td><strong>Zombies only.</strong> Zombies are immune to damage from humans/
grenades, but are still vulnerable to knock back.</td> grenades, but are still vulnerable to knock back. Since damage is blocked,
zombies aren't slowed down by bullet hits, but knock back alone. You might
need to increase knock back a bit.</td>
</tr> </tr>
<tr> <tr>
<td class="valueoption">delay</td> <td class="valueoption">delay</td>
<td><strong>Humans only.</strong> Delay infection for a certain amount of <td><strong>Humans only.</strong> Delay infection for a certain amount of
seconds (immunity_amount value). seconds (immunity_amount value). There's no notification, so humans need to
be careful.
<br/><br/> <br/><br/>
Subsequent zombie attacks will reduce the delay time with the number of Subsequent zombie attacks will reduce the delay time with the number of
seconds specified in the immunity_cooldown attribute. If you don't want seconds specified in the immunity_cooldown attribute. If you don't want

View File

@ -278,8 +278,6 @@ public Action:DamageOnTakeDamage(client, &attacker, &inflictor, &Float:damage, &
public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:damage, damagetype, ammotype) public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:damage, damagetype, ammotype)
#endif #endif
{ {
//PrintToChatAll("DamageOnTakeDamage - damage:%f", damage);
// Get classname of the inflictor. // Get classname of the inflictor.
decl String:classname[64]; decl String:classname[64];
GetEdictClassname(inflictor, classname, sizeof(classname)); GetEdictClassname(inflictor, classname, sizeof(classname));
@ -332,10 +330,12 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
return ACTION_CONTINUE; return ACTION_CONTINUE;
} }
// Check if immunity module blocked the damage. // Check if immunity module blocked or modified the damage.
if (ImmunityOnClientDamage(client, attacker, damage)) new Action:immunityAction = ImmunityOnClientDamage(client, attacker, damage);
if (immunityAction != Plugin_Continue)
{ {
return ACTION_HANDLED; // Damage was blocked or modified.
return immunityAction;
} }
// Client is about to be infected, re-add HP so they aren't killed by // Client is about to be infected, re-add HP so they aren't killed by

View File

@ -32,7 +32,7 @@ enum ImmunityMode
{ {
Immunity_Invalid = -1, /** Invalid immunity mode. Used by validators. */ Immunity_Invalid = -1, /** Invalid immunity mode. Used by validators. */
Immunity_None, /** No immunity mode. */ Immunity_None, /** No immunity mode. */
Immunity_Kill, /** Humans are instantly killed when infected by zombies. */
Immunity_Full, /** Completely immune. Humans can't be infected, zombies don't receive damage or knock back. Admin commands may override this. */ Immunity_Full, /** Completely immune. Humans can't be infected, zombies don't receive damage or knock back. Admin commands may override this. */
Immunity_Infect, /** Humans are immune to infections until HP go below a threshold. Threshold at zero enable stabbing to death. */ Immunity_Infect, /** Humans are immune to infections until HP go below a threshold. Threshold at zero enable stabbing to death. */
Immunity_Damage, /** Zombies are immune to damage from humans/grenades, but still vulnerable to knock back. */ Immunity_Damage, /** Zombies are immune to damage from humans/grenades, but still vulnerable to knock back. */

View File

@ -107,8 +107,6 @@ public Action:Command_DeployShield(client, argc)
*/ */
bool:ImmunityOnClientInfect(client, attacker) bool:ImmunityOnClientInfect(client, attacker)
{ {
//PrintToChatAll("ImmunityOnClientInfect(client=%d, attacker=%d)", client, attacker);
// Get immunity mode from client class. // Get immunity mode from client class.
new ImmunityMode:mode = ClassGetImmunityMode(client); new ImmunityMode:mode = ClassGetImmunityMode(client);
@ -120,6 +118,11 @@ bool:ImmunityOnClientInfect(client, attacker)
// Instant infection. // Instant infection.
return false; return false;
} }
case Immunity_Kill:
{
// Block infection. Damage is increased in ImmunityOnClientDamage.
return true;
}
case Immunity_Full: case Immunity_Full:
{ {
// Full immunity, do nothing. // Full immunity, do nothing.
@ -160,8 +163,6 @@ bool:ImmunityOnClientInfect(client, attacker)
*/ */
bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damageType) bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damageType)
{ {
//PrintToChatAll("ImmunityOnClientTraceAttack(client=%d, attacker=%d, damage=%f, hitgroup=%d, damageType=%d)", client, attacker, damage, hitgroup, damageType);
// Check if there is no attacker (world damage). // Check if there is no attacker (world damage).
if (!ZRIsClientValid(attacker)) if (!ZRIsClientValid(attacker))
{ {
@ -262,16 +263,25 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
* @param client Client index. * @param client Client index.
* @param attacker Attacker client, if any. * @param attacker Attacker client, if any.
* @param damage Damage received by client. * @param damage Damage received by client.
* @param weapon Weapon entity.
* *
* @return True if damage was blocked, false otherwise. * @return Plugin_Handled if damage was blocked, Plugin_Changed if
* damage was modified, Plugin_Continue otherwise.
*/ */
bool:ImmunityOnClientDamage(client, attacker, &Float:damage) Action:ImmunityOnClientDamage(client, attacker, &Float:damage)
{ {
// Check if there is no attacker (world damage). // Check if there is no attacker (world damage).
if (!ZRIsClientValid(attacker)) if (!ZRIsClientValid(attacker))
{ {
// Allow damage. // Allow damage.
return false; return Plugin_Continue;
}
// Check if spawn protection is on.
if (bInfectImmune[client][INFECT_TYPE_NORMAL])
{
// Block damage.
return Plugin_Handled;
} }
// Get immunity mode from client class. // Get immunity mode from client class.
@ -279,6 +289,27 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
switch(mode) switch(mode)
{ {
case Immunity_Kill:
{
// Client must be human and attacker must be zombie.
if (InfectIsClientInfected(client)
|| !InfectIsClientInfected(attacker))
{
// Don't modify damage.
return Plugin_Continue;
}
// A zombie is attacking a human in kill immunity mode. Increase
// damage so human will be instantly killed. (Using a high damage
// value in case the human class has a lot of HP.)
damage = 60000.0;
// Update score and health gain.
InfectUpdateScore(attacker, client);
// Damage was changed.
return Plugin_Changed;
}
case Immunity_Infect: case Immunity_Infect:
{ {
// Prevent humans with low HP from dying when a zombie is // Prevent humans with low HP from dying when a zombie is
@ -290,7 +321,7 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
InfectOnClientHurt(client, attacker, "knife"); InfectOnClientHurt(client, attacker, "knife");
// Block damage to prevent player from dying. // Block damage to prevent player from dying.
return true; return Plugin_Handled;
} }
} }
case Immunity_Delay: case Immunity_Delay:
@ -302,12 +333,12 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
InfectOnClientHurt(client, attacker, "knife"); InfectOnClientHurt(client, attacker, "knife");
// Block damage to prevent player from dying. // Block damage to prevent player from dying.
return true; return Plugin_Handled;
} }
} }
// Allow damage. // Allow damage.
return false; return Plugin_Continue;
} }
/*____________________________________________________________________________*/ /*____________________________________________________________________________*/
@ -696,11 +727,14 @@ ImmunityOnMapEnd()
* Returns whether the specified damage will take a client's HP below the * Returns whether the specified damage will take a client's HP below the
* infection threshold. Only used by "infect" immunity mode. * infection threshold. Only used by "infect" immunity mode.
* *
* If threshold is disabled (zero) this function will always return false.
*
* @param client Client index. * @param client Client index.
* @param damage Damage applied to client. * @param damage Damage applied to client.
* *
* @return True if client HP go below threshold (immunity_amount) when * @return True if client HP go below threshold (immunity_amount) when
* applying damage, false otherwise. * applying damage, false if above threshold or if threshold
* is disabled (zero).
*/ */
bool:ImmunityBelowInfectThreshold(client, Float:damage) bool:ImmunityBelowInfectThreshold(client, Float:damage)
{ {
@ -708,8 +742,9 @@ bool:ImmunityBelowInfectThreshold(client, Float:damage)
new clientHP = GetClientHealth(client); new clientHP = GetClientHealth(client);
new dmg = RoundToNearest(damage); new dmg = RoundToNearest(damage);
// Check if the damage go below the HP threshold. // Check if the damage go below the HP threshold. Client can only go below
if (clientHP - dmg <= 0.0 && threshold > 0) // threshold when threshold is enabled (above zero).
if (clientHP - dmg <= threshold && threshold > 0)
{ {
return true; return true;
} }
@ -737,6 +772,10 @@ ImmunityMode:ImmunityStringToMode(const String:mode[])
{ {
return Immunity_None; return Immunity_None;
} }
if (StrEqual(mode, "kill", false))
{
return Immunity_Kill;
}
else if (StrEqual(mode, "full", false)) else if (StrEqual(mode, "full", false))
{ {
return Immunity_Full; return Immunity_Full;
@ -785,6 +824,10 @@ ImmunityModeToString(ImmunityMode:mode, String:buffer[], maxlen)
{ {
return strcopy(buffer, maxlen, "none"); return strcopy(buffer, maxlen, "none");
} }
case Immunity_Kill:
{
return strcopy(buffer, maxlen, "kill");
}
case Immunity_Full: case Immunity_Full:
{ {
return strcopy(buffer, maxlen, "full"); return strcopy(buffer, maxlen, "full");
@ -833,6 +876,11 @@ bool:ImmunityIsValidAmount(ImmunityMode:mode, amount)
// Immunity mode disabled, amount ignored. // Immunity mode disabled, amount ignored.
return true; return true;
} }
case Immunity_Kill:
{
// Amount isn't used in this mode.
return true;
}
case Immunity_Full: case Immunity_Full:
{ {
// Amount isn't used in this mode. // Amount isn't used in this mode.
@ -902,6 +950,11 @@ bool:ImmunityIsValidCooldown(ImmunityMode:mode, cooldown)
// Immunity mode disabled, amount ignored. // Immunity mode disabled, amount ignored.
return true; return true;
} }
case Immunity_Kill:
{
// Cooldown isn't used in this mode.
return true;
}
case Immunity_Full: case Immunity_Full:
{ {
// Cooldown isn't used in this mode. // Cooldown isn't used in this mode.

View File

@ -751,23 +751,8 @@ InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respa
FireEvent(event, false); FireEvent(event, false);
} }
// Give client's infector a point. // Apply score and health gain.
new score = ToolsClientScore(attacker, true, false); InfectUpdateScore(attacker, client);
ToolsClientScore(attacker, true, true, ++score);
// Add a death to the zombie's score.
new deaths = ToolsClientScore(client, false, false);
ToolsClientScore(client, false, true, ++deaths);
// Apply infect HP gain.
new healthgain = ClassGetHealthInfectGain(attacker);
new health = GetClientHealth(attacker);
// Set attacker's new health.
SetEntityHealth(attacker, health + healthgain);
// Forward event to modules.
ZHPOnHealthInfectGain(attacker);
} }
// Get a list of all client's weapon indexes. // Get a list of all client's weapon indexes.
@ -880,6 +865,30 @@ InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
ImmunityOnClientHuman(client); ImmunityOnClientHuman(client);
} }
/**
* Updates score for attacker and victim. Applies health gain for attacker.
*/
InfectUpdateScore(attacker, victim)
{
// Give client's infector a point.
new score = ToolsClientScore(attacker, true, false);
ToolsClientScore(attacker, true, true, ++score);
// Add a death to the zombie's score.
new deaths = ToolsClientScore(victim, false, false);
ToolsClientScore(victim, false, true, ++deaths);
// Apply infect HP gain.
new healthgain = ClassGetHealthInfectGain(attacker);
new health = GetClientHealth(attacker);
// Set attacker's new health.
SetEntityHealth(attacker, health + healthgain);
// Forward event to modules.
ZHPOnHealthInfectGain(attacker);
}
/** /**
* Creates effects on a newly infected client. * Creates effects on a newly infected client.
* *