changing accumulators to timespan targets (#12407)

* changing accumulators to timespan targets

* Update Content.Server/Abilities/Mime/MimePowersSystem.cs

Co-authored-by: 0x6273 <0x40@keemail.me>

* Update MimePowersSystem.cs

* serializing timespans and adding pausetime where applicable

* remove nullable

Co-authored-by: CommieFlowers <rasmus.cedergren@hotmail.com>
Co-authored-by: 0x6273 <0x40@keemail.me>
This commit is contained in:
rolfero
2022-11-08 20:59:34 +01:00
committed by GitHub
parent 3ec0202634
commit 1151ca42e5
11 changed files with 82 additions and 64 deletions

View File

@@ -36,7 +36,7 @@ namespace Content.Client.Audio
private bool _overlayEnabled; private bool _overlayEnabled;
private float _maxAmbientRange; private float _maxAmbientRange;
private float _cooldown; private float _cooldown;
private float _accumulator; private TimeSpan _targetTime = TimeSpan.Zero;
private float _ambienceVolume = 0.0f; private float _ambienceVolume = 0.0f;
/// <summary> /// <summary>
@@ -131,17 +131,16 @@ namespace Content.Client.Audio
{ {
base.Update(frameTime); base.Update(frameTime);
if (!_gameTiming.IsFirstTimePredicted) return; if (!_gameTiming.IsFirstTimePredicted)
return;
if (_cooldown <= 0f) if (_cooldown <= 0f)
{
_accumulator = 0f;
return; return;
}
_accumulator += frameTime; if (_gameTiming.CurTime < _targetTime)
if (_accumulator < _cooldown) return; return;
_accumulator -= _cooldown;
_targetTime = _gameTiming.CurTime+TimeSpan.FromSeconds(_cooldown);
var player = _playerManager.LocalPlayer?.ControlledEntity; var player = _playerManager.LocalPlayer?.ControlledEntity;
if (!EntityManager.TryGetComponent(player, out TransformComponent? playerManager)) if (!EntityManager.TryGetComponent(player, out TransformComponent? playerManager))

View File

@@ -46,10 +46,11 @@ public sealed class JetpackSystem : SharedJetpackSystem
foreach (var comp in EntityQuery<ActiveJetpackComponent>()) foreach (var comp in EntityQuery<ActiveJetpackComponent>())
{ {
comp.Accumulator += frameTime; if (_timing.CurTime < comp.TargetTime)
continue;
comp.TargetTime = _timing.CurTime + TimeSpan.FromSeconds(comp.EffectCooldown);
if (comp.Accumulator < comp.EffectCooldown) continue;
comp.Accumulator -= comp.EffectCooldown;
CreateParticles(comp.Owner); CreateParticles(comp.Owner);
} }
} }

View File

@@ -1,5 +1,6 @@
using Content.Shared.Actions.ActionTypes; using Content.Shared.Actions.ActionTypes;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -48,16 +49,15 @@ namespace Content.Server.Abilities.Mime
public bool ReadyToRepent = false; public bool ReadyToRepent = false;
/// <summary> /// <summary>
/// Accumulator for when the mime breaks their vows /// Time when the mime can repent their vow
/// </summary> /// </summary>
[DataField("vowRepentTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
[DataField("accumulator")] public TimeSpan VowRepentTime = TimeSpan.Zero;
public float Accumulator = 0f;
/// <summary> /// <summary>
/// How long it takes the mime to get their powers back /// How long it takes the mime to get their powers back
[DataField("vowCooldown")] [DataField("vowCooldown", customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan VowCooldown = TimeSpan.FromMinutes(5); public TimeSpan VowCooldown = TimeSpan.FromMinutes(5);
} }
} }

View File

@@ -9,6 +9,7 @@ using Content.Shared.Maps;
using Content.Shared.MobState.Components; using Content.Shared.MobState.Components;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Timing;
namespace Content.Server.Abilities.Mime namespace Content.Server.Abilities.Mime
{ {
@@ -18,6 +19,8 @@ namespace Content.Server.Abilities.Mime
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!; [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly AlertsSystem _alertsSystem = default!; [Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -34,8 +37,7 @@ namespace Content.Server.Abilities.Mime
if (!mime.VowBroken || mime.ReadyToRepent) if (!mime.VowBroken || mime.ReadyToRepent)
continue; continue;
mime.Accumulator += frameTime; if (_timing.CurTime < mime.VowRepentTime)
if (mime.Accumulator < mime.VowCooldown.TotalSeconds)
continue; continue;
mime.ReadyToRepent = true; mime.ReadyToRepent = true;
@@ -101,6 +103,7 @@ namespace Content.Server.Abilities.Mime
mimePowers.Enabled = false; mimePowers.Enabled = false;
mimePowers.VowBroken = true; mimePowers.VowBroken = true;
mimePowers.VowRepentTime = _timing.CurTime + mimePowers.VowCooldown;
_alertsSystem.ClearAlert(uid, AlertType.VowOfSilence); _alertsSystem.ClearAlert(uid, AlertType.VowOfSilence);
_alertsSystem.ShowAlert(uid, AlertType.VowBroken); _alertsSystem.ShowAlert(uid, AlertType.VowBroken);
_actionsSystem.RemoveAction(uid, mimePowers.InvisibleWallAction); _actionsSystem.RemoveAction(uid, mimePowers.InvisibleWallAction);
@@ -123,7 +126,6 @@ namespace Content.Server.Abilities.Mime
mimePowers.Enabled = true; mimePowers.Enabled = true;
mimePowers.ReadyToRepent = false; mimePowers.ReadyToRepent = false;
mimePowers.VowBroken = false; mimePowers.VowBroken = false;
mimePowers.Accumulator = 0f;
_alertsSystem.ClearAlert(uid, AlertType.VowBroken); _alertsSystem.ClearAlert(uid, AlertType.VowBroken);
_alertsSystem.ShowAlert(uid, AlertType.VowOfSilence); _alertsSystem.ShowAlert(uid, AlertType.VowOfSilence);
_actionsSystem.AddAction(uid, mimePowers.InvisibleWallAction, uid); _actionsSystem.AddAction(uid, mimePowers.InvisibleWallAction, uid);

View File

@@ -6,6 +6,7 @@ using Robust.Server.Player;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Server.Afk; namespace Content.Server.Afk;
@@ -17,10 +18,11 @@ public sealed class AFKSystem : EntitySystem
[Dependency] private readonly IAfkManager _afkManager = default!; [Dependency] private readonly IAfkManager _afkManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!; [Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly GameTicker _ticker = default!; [Dependency] private readonly GameTicker _ticker = default!;
private float _checkDelay; private float _checkDelay;
private float _accumulator; private TimeSpan _checkTime;
private readonly HashSet<IPlayerSession> _afkPlayers = new(); private readonly HashSet<IPlayerSession> _afkPlayers = new();
@@ -50,7 +52,6 @@ public sealed class AFKSystem : EntitySystem
{ {
base.Shutdown(); base.Shutdown();
_afkPlayers.Clear(); _afkPlayers.Clear();
_accumulator = 0f;
_playerManager.PlayerStatusChanged -= OnPlayerChange; _playerManager.PlayerStatusChanged -= OnPlayerChange;
_configManager.UnsubValueChanged(CCVars.AfkTime, SetAfkDelay); _configManager.UnsubValueChanged(CCVars.AfkTime, SetAfkDelay);
} }
@@ -62,16 +63,15 @@ public sealed class AFKSystem : EntitySystem
if (_ticker.RunLevel != GameRunLevel.InRound) if (_ticker.RunLevel != GameRunLevel.InRound)
{ {
_afkPlayers.Clear(); _afkPlayers.Clear();
_accumulator = 0f; _checkTime = TimeSpan.Zero;
return; return;
} }
_accumulator += frameTime;
// TODO: Should also listen to the input events for more accurate timings. // TODO: Should also listen to the input events for more accurate timings.
if (_accumulator < _checkDelay) return; if (_timing.CurTime < _checkTime)
return;
_accumulator -= _checkDelay; _checkTime = _timing.CurTime + TimeSpan.FromSeconds(_checkDelay);
foreach (var session in Filter.GetAllPlayers()) foreach (var session in Filter.GetAllPlayers())
{ {

View File

@@ -11,6 +11,7 @@ using Robust.Server.GameObjects;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Server.Atmos.Miasma namespace Content.Server.Atmos.Miasma
{ {
@@ -20,7 +21,9 @@ namespace Content.Server.Atmos.Miasma
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly SharedMobStateSystem _mobState = default!; [Dependency] private readonly SharedMobStateSystem _mobState = default!;
[Dependency] private readonly MetaDataSystem _metaDataSystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
/// System Variables /// System Variables
@@ -62,11 +65,11 @@ namespace Content.Server.Atmos.Miasma
/// </summary> /// </summary>
/// <summary> /// <summary>
/// This ticks up to PoolRepickTime. /// The target time it waits until..
/// After that, it resets to 0. /// After that, it resets current time + _poolRepickTime.
/// Any infection will also reset it to 0. /// Any infection will also reset it to current time + _poolRepickTime.
/// </summary> /// </summary>
private float _poolAccumulator = 0f; private TimeSpan _diseaseTime = TimeSpan.FromMinutes(5);
/// <summary> /// <summary>
/// How long without an infection before we pick a new disease. /// How long without an infection before we pick a new disease.
@@ -77,29 +80,26 @@ namespace Content.Server.Atmos.Miasma
{ {
base.Update(frameTime); base.Update(frameTime);
// Disease pool // Disease pool
_poolAccumulator += frameTime;
if (_poolAccumulator > _poolRepickTime.TotalSeconds) if (_timing.CurTime >= _diseaseTime)
{ {
_poolAccumulator = 0f; _diseaseTime = _timing.CurTime + _poolRepickTime;
_poolDisease = _random.Pick(MiasmaDiseasePool); _poolDisease = _random.Pick(MiasmaDiseasePool);
} }
// Rotting // Rotting
foreach (var (rotting, perishable) in EntityQuery<RottingComponent, PerishableComponent>()) foreach (var (rotting, perishable, metadata) in EntityQuery<RottingComponent, PerishableComponent, MetaDataComponent>())
{ {
if (!perishable.Progressing) if (!perishable.Progressing)
continue; continue;
perishable.DeathAccumulator += frameTime; if (!IsRotting(perishable, metadata))
if (perishable.DeathAccumulator < perishable.RotAfter.TotalSeconds)
continue; continue;
perishable.RotAccumulator += frameTime; if (_timing.CurTime < perishable.RotNextUpdate) // This is where it starts to get noticable on larger animals, no need to run every second
if (perishable.RotAccumulator < _rotUpdateRate) // This is where it starts to get noticable on larger animals, no need to run every second
continue; continue;
perishable.RotAccumulator -= _rotUpdateRate; perishable.RotNextUpdate = _timing.CurTime + TimeSpan.FromSeconds(_rotUpdateRate);
EnsureComp<FliesComponent>(perishable.Owner); EnsureComp<FliesComponent>(perishable.Owner);
@@ -152,8 +152,8 @@ namespace Content.Server.Atmos.Miasma
RemComp<FliesComponent>(uid); RemComp<FliesComponent>(uid);
if (TryComp<PerishableComponent>(uid, out var perishable)) if (TryComp<PerishableComponent>(uid, out var perishable))
{ {
perishable.DeathAccumulator = 0; perishable.TimeOfDeath = TimeSpan.Zero;
perishable.RotAccumulator = 0; perishable.RotNextUpdate = TimeSpan.Zero;
} }
} }
@@ -168,7 +168,20 @@ namespace Content.Server.Atmos.Miasma
private void OnMobStateChanged(EntityUid uid, PerishableComponent component, MobStateChangedEvent args) private void OnMobStateChanged(EntityUid uid, PerishableComponent component, MobStateChangedEvent args)
{ {
if (_mobState.IsDead(uid)) if (_mobState.IsDead(uid))
{
EnsureComp<RottingComponent>(uid); EnsureComp<RottingComponent>(uid);
component.TimeOfDeath = _timing.CurTime;
}
}
/// <summary>
/// Has enough time passed for <paramref name="perishable"/> to start rotting?
/// </summary>
private bool IsRotting(PerishableComponent perishable, MetaDataComponent? metadata = null)
{
if (_timing.CurTime >= perishable.TimeOfDeath + perishable.RotAfter + _metaDataSystem.GetPauseTime(perishable.Owner, metadata))
return true;
return false;
} }
private void OnGibbed(EntityUid uid, PerishableComponent component, BeingGibbedEvent args) private void OnGibbed(EntityUid uid, PerishableComponent component, BeingGibbedEvent args)
@@ -176,10 +189,10 @@ namespace Content.Server.Atmos.Miasma
if (!TryComp<PhysicsComponent>(uid, out var physics)) if (!TryComp<PhysicsComponent>(uid, out var physics))
return; return;
if (!component.Rotting) if (!IsRotting(component))
return; return;
var molsToDump = (component.MolsPerSecondPerUnitMass * physics.FixturesMass) * component.DeathAccumulator; var molsToDump = (component.MolsPerSecondPerUnitMass * physics.FixturesMass) * (float)(_timing.CurTime - component.TimeOfDeath).TotalSeconds;
var transform = Transform(uid); var transform = Transform(uid);
var indices = _transformSystem.GetGridOrMapTilePosition(uid, transform); var indices = _transformSystem.GetGridOrMapTilePosition(uid, transform);
var tileMix = _atmosphereSystem.GetTileMixture(transform.GridUid, null, indices, true); var tileMix = _atmosphereSystem.GetTileMixture(transform.GridUid, null, indices, true);
@@ -192,9 +205,10 @@ namespace Content.Server.Atmos.Miasma
private void OnExamined(EntityUid uid, PerishableComponent component, ExaminedEvent args) private void OnExamined(EntityUid uid, PerishableComponent component, ExaminedEvent args)
{ {
if (!component.Rotting) if (!IsRotting(component))
return; return;
var stage = component.DeathAccumulator / component.RotAfter.TotalSeconds;
var stage = (_timing.CurTime - component.TimeOfDeath).TotalSeconds / component.RotAfter.TotalSeconds;
var description = stage switch { var description = stage switch {
>= 3 => "miasma-extremely-bloated", >= 3 => "miasma-extremely-bloated",
>= 2 => "miasma-bloated", >= 2 => "miasma-bloated",
@@ -254,7 +268,7 @@ namespace Content.Server.Atmos.Miasma
perishable.Progressing = decompose; perishable.Progressing = decompose;
if (!perishable.Rotting) if (!IsRotting(perishable))
return; return;
if (decompose) if (decompose)
@@ -290,7 +304,7 @@ namespace Content.Server.Atmos.Miasma
public string RequestPoolDisease() public string RequestPoolDisease()
{ {
// We reset the current time on this outbreak so people don't get unlucky at the transition time // We reset the current time on this outbreak so people don't get unlucky at the transition time
_poolAccumulator = 0f; _diseaseTime = _timing.CurTime + _poolRepickTime;
return _poolDisease; return _poolDisease;
} }
} }

View File

@@ -1,3 +1,5 @@
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.Atmos.Miasma namespace Content.Server.Atmos.Miasma
{ {
[RegisterComponent] [RegisterComponent]
@@ -16,22 +18,20 @@ namespace Content.Server.Atmos.Miasma
/// <summary> /// <summary>
/// How long this creature has been dead. /// How long this creature has been dead.
/// </summary> /// </summary>
[DataField("deathAccumulator")] [DataField("timeOfDeath", customTypeSerializer: typeof(TimeOffsetSerializer))]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public float DeathAccumulator = 0f; public TimeSpan TimeOfDeath = TimeSpan.Zero;
/// <summary> /// <summary>
/// When DeathAccumulator is greater than this, start rotting. /// When DeathAccumulator is greater than this, start rotting.
/// </summary> /// </summary>
public TimeSpan RotAfter = TimeSpan.FromMinutes(5); public TimeSpan RotAfter = TimeSpan.FromMinutes(5);
public bool Rotting => (DeathAccumulator > RotAfter.TotalSeconds);
/// <summary> /// <summary>
/// Gasses are released every second. /// Gasses are released, this is when the next gas release update will be.
/// </summary> /// </summary>
[DataField("rotAccumulator")] [DataField("rotNextUpdate", customTypeSerializer: typeof(TimeOffsetSerializer))]
public float RotAccumulator = 0f; public TimeSpan RotNextUpdate = TimeSpan.Zero;
/// <summary> /// <summary>
/// How many moles of gas released per second, per unit of mass. /// How many moles of gas released per second, per unit of mass.

View File

@@ -15,6 +15,7 @@ using Content.Shared.Damage;
using Content.Shared.Emag.Systems; using Content.Shared.Emag.Systems;
using Content.Server.Construction; using Content.Server.Construction;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Server.Bed namespace Content.Server.Bed
{ {
@@ -26,6 +27,7 @@ namespace Content.Server.Bed
[Dependency] private readonly SleepingSystem _sleepingSystem = default!; [Dependency] private readonly SleepingSystem _sleepingSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -44,6 +46,7 @@ namespace Content.Server.Bed
if (args.Buckling) if (args.Buckling)
{ {
AddComp<HealOnBuckleHealingComponent>(uid); AddComp<HealOnBuckleHealingComponent>(uid);
component.NextHealTime = _timing.CurTime + TimeSpan.FromSeconds(component.HealTime);
if (sleepAction != null) if (sleepAction != null)
_actionsSystem.AddAction(args.BuckledEntity, new InstantAction(sleepAction), null); _actionsSystem.AddAction(args.BuckledEntity, new InstantAction(sleepAction), null);
return; return;
@@ -54,7 +57,6 @@ namespace Content.Server.Bed
_sleepingSystem.TryWaking(args.BuckledEntity); _sleepingSystem.TryWaking(args.BuckledEntity);
RemComp<HealOnBuckleHealingComponent>(uid); RemComp<HealOnBuckleHealingComponent>(uid);
component.Accumulator = 0;
} }
public override void Update(float frameTime) public override void Update(float frameTime)
@@ -63,12 +65,10 @@ namespace Content.Server.Bed
foreach (var (_, bedComponent, strapComponent) in EntityQuery<HealOnBuckleHealingComponent, HealOnBuckleComponent, StrapComponent>()) foreach (var (_, bedComponent, strapComponent) in EntityQuery<HealOnBuckleHealingComponent, HealOnBuckleComponent, StrapComponent>())
{ {
bedComponent.Accumulator += frameTime; if (_timing.CurTime < bedComponent.NextHealTime)
if (bedComponent.Accumulator < bedComponent.HealTime)
continue; continue;
bedComponent.Accumulator -= bedComponent.HealTime; bedComponent.NextHealTime += TimeSpan.FromSeconds(bedComponent.HealTime);
if (strapComponent.BuckledEntities.Count == 0) continue; if (strapComponent.BuckledEntities.Count == 0) continue;

View File

@@ -15,6 +15,7 @@ namespace Content.Server.Bed.Components
[DataField("sleepMultiplier")] [DataField("sleepMultiplier")]
public float SleepMultiplier = 3f; public float SleepMultiplier = 3f;
public float Accumulator = 0f; //Time accumulated
public TimeSpan NextHealTime = TimeSpan.Zero; //Next heal
} }
} }

View File

@@ -3,12 +3,14 @@ using Content.Server.Atmos.EntitySystems;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems; using Content.Shared.Movement.Systems;
using Robust.Shared.Collections; using Robust.Shared.Collections;
using Robust.Shared.Timing;
namespace Content.Server.Movement.Systems; namespace Content.Server.Movement.Systems;
public sealed class JetpackSystem : SharedJetpackSystem public sealed class JetpackSystem : SharedJetpackSystem
{ {
[Dependency] private readonly GasTankSystem _gasTank = default!; [Dependency] private readonly GasTankSystem _gasTank = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private const float UpdateCooldown = 0.5f; private const float UpdateCooldown = 0.5f;
@@ -25,10 +27,9 @@ public sealed class JetpackSystem : SharedJetpackSystem
foreach (var (active, comp, gasTank) in EntityQuery<ActiveJetpackComponent, JetpackComponent, GasTankComponent>()) foreach (var (active, comp, gasTank) in EntityQuery<ActiveJetpackComponent, JetpackComponent, GasTankComponent>())
{ {
active.Accumulator += frameTime; if (_timing.CurTime < active.TargetTime) continue;
if (active.Accumulator < UpdateCooldown) continue;
active.Accumulator -= UpdateCooldown; active.TargetTime = _timing.CurTime + TimeSpan.FromSeconds(active.EffectCooldown);
var air = _gasTank.RemoveAir(gasTank, comp.MoleUsage); var air = _gasTank.RemoveAir(gasTank, comp.MoleUsage);
if (air == null || !MathHelper.CloseTo(air.TotalMoles, comp.MoleUsage, 0.001f)) if (air == null || !MathHelper.CloseTo(air.TotalMoles, comp.MoleUsage, 0.001f))

View File

@@ -9,5 +9,5 @@ namespace Content.Shared.Movement.Components;
public sealed class ActiveJetpackComponent : Component public sealed class ActiveJetpackComponent : Component
{ {
public float EffectCooldown = 0.3f; public float EffectCooldown = 0.3f;
public float Accumulator = 0f; public TimeSpan TargetTime = TimeSpan.Zero;
} }