From: Tom Leys Date: Tue, 9 May 2023 02:24:40 +0000 (+1200) Subject: Zombie disease is easier to spread and deadly in minutes. Zombies heal over time... X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=878272ecf32e60dc55d9bbbdcaf905f5fbed14e6;p=space-station-14.git Zombie disease is easier to spread and deadly in minutes. Zombies heal over time. (#16235) * Nerf Space zombies, get DoT in space (barotrauma) and spawn stunned. - Also discard any helmet or mask you might be wearing. * Zombies have heal over time, infection far more fatal - Stun time reduced to 2 seconds * Zombification occurs after you die, rather than after you crit. - Zombies cannot inflict Zombification DoT on other zombies. * Heal shock damage, space zombies are back. * Lower the chance of infection per hit * Removed the stun, reduced zombification virus slightly --- diff --git a/Content.Server/Zombies/PendingZombieComponent.cs b/Content.Server/Zombies/PendingZombieComponent.cs index 98d177c051..957e2a712a 100644 --- a/Content.Server/Zombies/PendingZombieComponent.cs +++ b/Content.Server/Zombies/PendingZombieComponent.cs @@ -12,12 +12,18 @@ public sealed class PendingZombieComponent : Component { [DataField("damage")] public DamageSpecifier Damage = new() { - DamageDict = new Dictionary() + DamageDict = new () { - { "Blunt", FixedPoint2.New(1) } + { "Blunt", 0.5 }, + { "Cellular", 0.2 }, + { "Toxin", 0.2 }, } }; [DataField("nextTick", customTypeSerializer:typeof(TimeOffsetSerializer))] public TimeSpan NextTick; + + // Scales damage over time. + [DataField("infectedSecs")] + public int InfectedSecs; } diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index 6330a2f7e7..8f4b737fb6 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -63,12 +63,28 @@ namespace Content.Server.Zombies var query = EntityQueryEnumerator(); var curTime = _timing.CurTime; + // Hurt the living infected while (query.MoveNext(out var uid, out var comp)) { - if (comp.NextTick < curTime) + if (comp.NextTick + TimeSpan.FromSeconds(1) > curTime) continue; - comp.NextTick += TimeSpan.FromSeconds(1); + comp.InfectedSecs += 1; + // Pain of becoming a zombie grows over time + // 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); + } + + var zomb_query = EntityQueryEnumerator(); + // Heal the zombified + while (zomb_query.MoveNext(out var uid, out var comp)) + { + if (comp.NextTick + TimeSpan.FromSeconds(1) > curTime) + continue; + + comp.NextTick = curTime; _damageable.TryChangeDamage(uid, comp.Damage, true, false); } } @@ -166,14 +182,18 @@ namespace Content.Server.Zombies if (!TryComp(entity, out var mobState) || HasComp(entity)) continue; - if (_random.Prob(GetZombieInfectionChance(entity, component))) - { - EnsureComp(entity); - EnsureComp(entity); - } - if (HasComp(entity)) + { args.BonusDamage = -args.BaseDamage * zombieComp.OtherZombieDamageCoefficient; + } + else + { + if (_random.Prob(GetZombieInfectionChance(entity, component))) + { + EnsureComp(entity); + EnsureComp(entity); + } + } if ((mobState.CurrentState == MobState.Dead || mobState.CurrentState == MobState.Critical) && !HasComp(entity)) diff --git a/Content.Server/Zombies/ZombifyOnDeathSystem.cs b/Content.Server/Zombies/ZombifyOnDeathSystem.cs index 926f3318a2..d77024efad 100644 --- a/Content.Server/Zombies/ZombifyOnDeathSystem.cs +++ b/Content.Server/Zombies/ZombifyOnDeathSystem.cs @@ -1,3 +1,4 @@ +using Content.Server.Administration.Commands; using Content.Server.Atmos.Components; using Content.Server.Body.Components; using Content.Server.Body.Systems; @@ -22,6 +23,7 @@ using Content.Shared.Hands.EntitySystems; using Content.Shared.Humanoid; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Content.Shared.Nutrition.Components; @@ -54,6 +56,8 @@ namespace Content.Server.Zombies [Dependency] private readonly SharedCombatModeSystem _combat = default!; [Dependency] private readonly IChatManager _chatMan = default!; [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; public override void Initialize() { @@ -67,8 +71,7 @@ namespace Content.Server.Zombies /// private void OnDamageChanged(EntityUid uid, ZombifyOnDeathComponent component, MobStateChangedEvent args) { - if (args.NewMobState == MobState.Dead || - args.NewMobState == MobState.Critical) + if (args.NewMobState == MobState.Dead) { ZombifyEntity(uid, args.Component); } @@ -181,10 +184,17 @@ namespace Content.Server.Zombies if (TryComp(target, out var tempComp)) tempComp.ColdDamage.ClampMax(0); + // Zombies can revive themselves + _mobThreshold.SetAllowRevives(target, true); + //Heals the zombie from all the damage it took while human if (TryComp(target, out var damageablecomp)) _damageable.SetAllDamage(target, damageablecomp, 0); + // Revive them now + if (TryComp(target, out var mobstate) && mobstate.CurrentState==MobState.Dead) + _mobState.ChangeMobState(target, MobState.Alive, mobstate); + //gives it the funny "Zombie ___" name. var meta = MetaData(target); zombiecomp.BeforeZombifiedEntityName = meta.EntityName; @@ -221,6 +231,8 @@ namespace Content.Server.Zombies _sharedHands.RemoveHand(target, hand.Name); } RemComp(target); + // No longer waiting to become a zombie: + RemComp(target); //zombie gamemode stuff RaiseLocalEvent(new EntityZombifiedEvent(target)); diff --git a/Content.Shared/Zombies/ZombieComponent.cs b/Content.Shared/Zombies/ZombieComponent.cs index 19fe721b71..02b5162634 100644 --- a/Content.Shared/Zombies/ZombieComponent.cs +++ b/Content.Shared/Zombies/ZombieComponent.cs @@ -1,8 +1,10 @@ using Content.Shared.Chat.Prototypes; +using Content.Shared.Damage; using Content.Shared.Roles; using Content.Shared.Humanoid; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using static Content.Shared.Humanoid.HumanoidAppearanceState; @@ -22,14 +24,14 @@ namespace Content.Shared.Zombies /// The baseline infection chance you have if you are completely nude /// [ViewVariables(VVAccess.ReadWrite)] - public float MaxZombieInfectionChance = 0.50f; + public float MaxZombieInfectionChance = 0.40f; /// /// The minimum infection chance possible. This is simply to prevent /// being invincible by bundling up. /// [ViewVariables(VVAccess.ReadWrite)] - public float MinZombieInfectionChance = 0.05f; + public float MinZombieInfectionChance = 0.10f; [ViewVariables(VVAccess.ReadWrite)] public float ZombieMovementSpeedDebuff = 0.75f; @@ -86,5 +88,21 @@ namespace Content.Shared.Zombies public string? EmoteSoundsId = "Zombie"; public EmoteSoundsPrototype? EmoteSounds; + + // Heal on tick + [DataField("nextTick", customTypeSerializer:typeof(TimeOffsetSerializer))] + public TimeSpan NextTick; + + [DataField("damage")] public DamageSpecifier Damage = new() + { + DamageDict = new () + { + { "Blunt", -0.3 }, + { "Slash", -0.2 }, + { "Heat", -0.2 }, + { "Cold", -0.2 }, + { "Shock", -0.2 }, + } + }; } }