diff --git a/cstrike/addons/sourcemod/configs/zr/playerclasses.txt b/cstrike/addons/sourcemod/configs/zr/playerclasses.txt
index 9ca0a15..86ab719 100644
--- a/cstrike/addons/sourcemod/configs/zr/playerclasses.txt
+++ b/cstrike/addons/sourcemod/configs/zr/playerclasses.txt
@@ -34,6 +34,7 @@
// napalm_time decimal Napalm burn duration. Zombies only.
// immunity_mode text Special immunity modes. Some modes only works on humans or zombies:
// "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.
// "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.
diff --git a/docs/zr_manual.htm b/docs/zr_manual.htm
index 35f71b1..9e6ac54 100644
--- a/docs/zr_manual.htm
+++ b/docs/zr_manual.htm
@@ -1257,6 +1257,11 @@ the admin-only flag in the flags attribute.
delay |
Humans only. 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.
Subsequent zombie attacks will reduce the delay time with the number of
seconds specified in the immunity_cooldown attribute. If you don't want
diff --git a/src/zr/damage.inc b/src/zr/damage.inc
index c739f68..4793955 100644
--- a/src/zr/damage.inc
+++ b/src/zr/damage.inc
@@ -278,8 +278,6 @@ public Action:DamageOnTakeDamage(client, &attacker, &inflictor, &Float:damage, &
public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:damage, damagetype, ammotype)
#endif
{
- //PrintToChatAll("DamageOnTakeDamage - damage:%f", damage);
-
// Get classname of the inflictor.
decl String:classname[64];
GetEdictClassname(inflictor, classname, sizeof(classname));
@@ -332,10 +330,12 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
return ACTION_CONTINUE;
}
- // Check if immunity module blocked the damage.
- if (ImmunityOnClientDamage(client, attacker, damage))
+ // Check if immunity module blocked or modified the 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
diff --git a/src/zr/immunityhandler.h.inc b/src/zr/immunityhandler.h.inc
index 7181634..f2b78e6 100644
--- a/src/zr/immunityhandler.h.inc
+++ b/src/zr/immunityhandler.h.inc
@@ -32,7 +32,7 @@ enum ImmunityMode
{
Immunity_Invalid = -1, /** Invalid immunity mode. Used by validators. */
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_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. */
diff --git a/src/zr/immunityhandler.inc b/src/zr/immunityhandler.inc
index 7f88406..1b026f1 100644
--- a/src/zr/immunityhandler.inc
+++ b/src/zr/immunityhandler.inc
@@ -107,8 +107,6 @@ public Action:Command_DeployShield(client, argc)
*/
bool:ImmunityOnClientInfect(client, attacker)
{
- //PrintToChatAll("ImmunityOnClientInfect(client=%d, attacker=%d)", client, attacker);
-
// Get immunity mode from client class.
new ImmunityMode:mode = ClassGetImmunityMode(client);
@@ -120,6 +118,11 @@ bool:ImmunityOnClientInfect(client, attacker)
// Instant infection.
return false;
}
+ case Immunity_Kill:
+ {
+ // Block infection. Damage is increased in ImmunityOnClientDamage.
+ return true;
+ }
case Immunity_Full:
{
// Full immunity, do nothing.
@@ -160,8 +163,6 @@ bool:ImmunityOnClientInfect(client, attacker)
*/
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).
if (!ZRIsClientValid(attacker))
{
@@ -262,16 +263,25 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
* @param client Client index.
* @param attacker Attacker client, if any.
* @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).
if (!ZRIsClientValid(attacker))
{
// 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.
@@ -279,6 +289,27 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
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:
{
// 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");
// Block damage to prevent player from dying.
- return true;
+ return Plugin_Handled;
}
}
case Immunity_Delay:
@@ -302,12 +333,12 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
InfectOnClientHurt(client, attacker, "knife");
// Block damage to prevent player from dying.
- return true;
+ return Plugin_Handled;
}
}
// 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
* infection threshold. Only used by "infect" immunity mode.
*
+ * If threshold is disabled (zero) this function will always return false.
+ *
* @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.
+ * applying damage, false if above threshold or if threshold
+ * is disabled (zero).
*/
bool:ImmunityBelowInfectThreshold(client, Float:damage)
{
@@ -708,8 +742,9 @@ bool:ImmunityBelowInfectThreshold(client, Float:damage)
new clientHP = GetClientHealth(client);
new dmg = RoundToNearest(damage);
- // Check if the damage go below the HP threshold.
- if (clientHP - dmg <= 0.0 && threshold > 0)
+ // Check if the damage go below the HP threshold. Client can only go below
+ // threshold when threshold is enabled (above zero).
+ if (clientHP - dmg <= threshold && threshold > 0)
{
return true;
}
@@ -737,6 +772,10 @@ ImmunityMode:ImmunityStringToMode(const String:mode[])
{
return Immunity_None;
}
+ if (StrEqual(mode, "kill", false))
+ {
+ return Immunity_Kill;
+ }
else if (StrEqual(mode, "full", false))
{
return Immunity_Full;
@@ -785,6 +824,10 @@ ImmunityModeToString(ImmunityMode:mode, String:buffer[], maxlen)
{
return strcopy(buffer, maxlen, "none");
}
+ case Immunity_Kill:
+ {
+ return strcopy(buffer, maxlen, "kill");
+ }
case Immunity_Full:
{
return strcopy(buffer, maxlen, "full");
@@ -833,6 +876,11 @@ bool:ImmunityIsValidAmount(ImmunityMode:mode, amount)
// Immunity mode disabled, amount ignored.
return true;
}
+ case Immunity_Kill:
+ {
+ // Amount isn't used in this mode.
+ return true;
+ }
case Immunity_Full:
{
// Amount isn't used in this mode.
@@ -902,6 +950,11 @@ bool:ImmunityIsValidCooldown(ImmunityMode:mode, cooldown)
// Immunity mode disabled, amount ignored.
return true;
}
+ case Immunity_Kill:
+ {
+ // Cooldown isn't used in this mode.
+ return true;
+ }
case Immunity_Full:
{
// Cooldown isn't used in this mode.
diff --git a/src/zr/infect.inc b/src/zr/infect.inc
index f7957f6..fceb51c 100644
--- a/src/zr/infect.inc
+++ b/src/zr/infect.inc
@@ -751,23 +751,8 @@ InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respa
FireEvent(event, false);
}
- // 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(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);
+ // Apply score and health gain.
+ InfectUpdateScore(attacker, client);
}
// Get a list of all client's weapon indexes.
@@ -880,6 +865,30 @@ InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
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.
*
|