Zombie virus delayed from 20-30 minutes from rule start. (#16346)
This commit is contained in:
@@ -55,6 +55,7 @@ namespace Content.Server.Zombies
|
||||
SubscribeLocalEvent<ZombieComponent, TryingToSleepEvent>(OnSleepAttempt);
|
||||
|
||||
SubscribeLocalEvent<PendingZombieComponent, MapInitEvent>(OnPendingMapInit);
|
||||
SubscribeLocalEvent<PendingZombieComponent, MobStateChangedEvent>(OnPendingMobState);
|
||||
}
|
||||
|
||||
private void OnPendingMapInit(EntityUid uid, PendingZombieComponent component, MapInitEvent args)
|
||||
@@ -65,24 +66,47 @@ namespace Content.Server.Zombies
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
var query = EntityQueryEnumerator<PendingZombieComponent, DamageableComponent>();
|
||||
var query = EntityQueryEnumerator<PendingZombieComponent, DamageableComponent, MobStateComponent>();
|
||||
var curTime = _timing.CurTime;
|
||||
|
||||
var zombQuery = EntityQueryEnumerator<ZombieComponent, DamageableComponent, MobStateComponent>();
|
||||
|
||||
// Hurt the living infected
|
||||
while (query.MoveNext(out var uid, out var comp, out var damage))
|
||||
while (query.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.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, damage);
|
||||
|
||||
comp.InfectedSecs += 1;
|
||||
// See if there should be a warning popup for the player.
|
||||
if (comp.InfectionWarnings.TryGetValue(comp.InfectedSecs, out var popupStr))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString(popupStr), uid, uid);
|
||||
}
|
||||
|
||||
if (comp.InfectedSecs < 0)
|
||||
{
|
||||
// This zombie has a latent virus, probably set up by ZombieRuleSystem. No damage yet.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pain of becoming a zombie grows over time
|
||||
// By scaling the number of seconds we have an accessible way to scale this exponential function.
|
||||
// The function was hand tuned to 120 seconds, hence the 120 constant here.
|
||||
var scaledSeconds = (120.0f / comp.MaxInfectionLength) * comp.InfectedSecs;
|
||||
|
||||
// 1x at 30s, 3x at 60s, 6x at 90s, 10x at 120s. Limit at 20x so we don't gib you.
|
||||
var painMultiple = Math.Min(20f, 0.1f + 0.02f * scaledSeconds + 0.0005f * scaledSeconds * scaledSeconds);
|
||||
if (mobState.CurrentState == MobState.Critical)
|
||||
{
|
||||
// Speed up their transformation when they are (or have been) in crit by ensuring their damage
|
||||
// multiplier is at least 10x
|
||||
painMultiple = Math.Max(comp.MinimumCritMultiplier, painMultiple);
|
||||
}
|
||||
_damageable.TryChangeDamage(uid, comp.Damage * painMultiple, true, false, damage);
|
||||
}
|
||||
|
||||
// Heal the zombified
|
||||
@@ -168,6 +192,15 @@ namespace Content.Server.Zombies
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPendingMobState(EntityUid uid, PendingZombieComponent pending, MobStateChangedEvent args)
|
||||
{
|
||||
if (args.NewMobState == MobState.Critical)
|
||||
{
|
||||
// Immediately jump to an active virus when you crit
|
||||
pending.InfectedSecs = Math.Max(0, pending.InfectedSecs);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetZombieInfectionChance(EntityUid uid, ZombieComponent component)
|
||||
{
|
||||
var baseChance = component.MaxZombieInfectionChance;
|
||||
@@ -227,7 +260,8 @@ namespace Content.Server.Zombies
|
||||
{
|
||||
if (_random.Prob(GetZombieInfectionChance(entity, component)))
|
||||
{
|
||||
EnsureComp<PendingZombieComponent>(entity);
|
||||
var pending = EnsureComp<PendingZombieComponent>(entity);
|
||||
pending.MaxInfectionLength = _random.NextFloat(0.25f, 1.0f) * component.ZombieInfectionTurnTime;
|
||||
EnsureComp<ZombifyOnDeathComponent>(entity);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user