Zombies recover faster from crit. They heal Piercing damage (#16325)

This commit is contained in:
Tom Leys
2023-05-16 15:58:36 +12:00
committed by GitHub
parent 525d746d6e
commit eab0121744
4 changed files with 68 additions and 8 deletions

View File

@@ -14,6 +14,8 @@ using Content.Shared.Damage;
using Content.Shared.Inventory;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Popups;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.Zombies;
using Robust.Shared.Prototypes;
@@ -35,6 +37,9 @@ namespace Content.Server.Zombies
[Dependency] private readonly AutoEmoteSystem _autoEmote = default!;
[Dependency] private readonly EmoteOnDamageSystem _emoteOnDamage = default!;
[Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!;
[Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
@@ -60,12 +65,15 @@ namespace Content.Server.Zombies
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<PendingZombieComponent>();
var query = EntityQueryEnumerator<PendingZombieComponent, DamageableComponent>();
var curTime = _timing.CurTime;
var zombQuery = EntityQueryEnumerator<ZombieComponent, DamageableComponent, MobStateComponent>();
// Hurt the living infected
while (query.MoveNext(out var uid, out var comp))
while (query.MoveNext(out var uid, out var comp, out var damage))
{
// Process only once per second
if (comp.NextTick + TimeSpan.FromSeconds(1) > curTime)
continue;
@@ -74,18 +82,34 @@ namespace Content.Server.Zombies
// 1x at 30s, 3x at 60s, 6x at 90s, 10x at 120s.
var pain_multiple = 0.1 + 0.02 * comp.InfectedSecs + 0.0005 * comp.InfectedSecs * comp.InfectedSecs;
comp.NextTick = curTime;
_damageable.TryChangeDamage(uid, comp.Damage * pain_multiple, true, false);
_damageable.TryChangeDamage(uid, comp.Damage * pain_multiple, true, false, damage);
}
var zomb_query = EntityQueryEnumerator<ZombieComponent>();
// Heal the zombified
while (zomb_query.MoveNext(out var uid, out var comp))
while (zombQuery.MoveNext(out var uid, out var comp, out var damage, out var mobState))
{
// Process only once per second
if (comp.NextTick + TimeSpan.FromSeconds(1) > curTime)
continue;
comp.NextTick = curTime;
_damageable.TryChangeDamage(uid, comp.Damage, true, false);
if (comp.Permadeath)
{
// No healing
continue;
}
if (mobState.CurrentState == MobState.Alive)
{
// Gradual healing for living zombies.
_damageable.TryChangeDamage(uid, comp.Damage, true, false, damage);
}
else if (_random.Prob(comp.ZombieReviveChance))
{
// There's a small chance to reverse all the zombie's damage (damage.Damage) in one go
_damageable.TryChangeDamage(uid, -damage.Damage, true, false, damage);
}
}
}
@@ -128,6 +152,19 @@ namespace Content.Server.Zombies
// Stop random groaning
_autoEmote.RemoveEmote(uid, "ZombieGroan");
if (args.NewMobState == MobState.Dead)
{
// Roll to see if this zombie is not coming back.
// Note that due to damage reductions it takes a lot of hits to gib a zombie without this.
if (_random.Prob(component.ZombiePermadeathChance))
{
// You're dead! No reviving for you.
_mobThreshold.SetAllowRevives(uid, false);
component.Permadeath = true;
_popup.PopupEntity(Loc.GetString("zombie-permadeath"), uid, uid);
}
}
}
}