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

View File

@@ -46,10 +46,11 @@ public sealed class JetpackSystem : SharedJetpackSystem
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);
}
}

View File

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

View File

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

View File

@@ -6,6 +6,7 @@ using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Server.Afk;
@@ -17,10 +18,11 @@ public sealed class AFKSystem : EntitySystem
[Dependency] private readonly IAfkManager _afkManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly GameTicker _ticker = default!;
private float _checkDelay;
private float _accumulator;
private TimeSpan _checkTime;
private readonly HashSet<IPlayerSession> _afkPlayers = new();
@@ -50,7 +52,6 @@ public sealed class AFKSystem : EntitySystem
{
base.Shutdown();
_afkPlayers.Clear();
_accumulator = 0f;
_playerManager.PlayerStatusChanged -= OnPlayerChange;
_configManager.UnsubValueChanged(CCVars.AfkTime, SetAfkDelay);
}
@@ -62,16 +63,15 @@ public sealed class AFKSystem : EntitySystem
if (_ticker.RunLevel != GameRunLevel.InRound)
{
_afkPlayers.Clear();
_accumulator = 0f;
_checkTime = TimeSpan.Zero;
return;
}
_accumulator += frameTime;
// 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())
{

View File

@@ -11,6 +11,7 @@ using Robust.Server.GameObjects;
using Robust.Shared.Containers;
using Robust.Shared.Physics.Components;
using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Server.Atmos.Miasma
{
@@ -20,7 +21,9 @@ namespace Content.Server.Atmos.Miasma
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = 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!;
/// System Variables
@@ -62,11 +65,11 @@ namespace Content.Server.Atmos.Miasma
/// </summary>
/// <summary>
/// This ticks up to PoolRepickTime.
/// After that, it resets to 0.
/// Any infection will also reset it to 0.
/// The target time it waits until..
/// After that, it resets current time + _poolRepickTime.
/// Any infection will also reset it to current time + _poolRepickTime.
/// </summary>
private float _poolAccumulator = 0f;
private TimeSpan _diseaseTime = TimeSpan.FromMinutes(5);
/// <summary>
/// How long without an infection before we pick a new disease.
@@ -77,29 +80,26 @@ namespace Content.Server.Atmos.Miasma
{
base.Update(frameTime);
// Disease pool
_poolAccumulator += frameTime;
if (_poolAccumulator > _poolRepickTime.TotalSeconds)
if (_timing.CurTime >= _diseaseTime)
{
_poolAccumulator = 0f;
_diseaseTime = _timing.CurTime + _poolRepickTime;
_poolDisease = _random.Pick(MiasmaDiseasePool);
}
// Rotting
foreach (var (rotting, perishable) in EntityQuery<RottingComponent, PerishableComponent>())
foreach (var (rotting, perishable, metadata) in EntityQuery<RottingComponent, PerishableComponent, MetaDataComponent>())
{
if (!perishable.Progressing)
continue;
perishable.DeathAccumulator += frameTime;
if (perishable.DeathAccumulator < perishable.RotAfter.TotalSeconds)
if (!IsRotting(perishable, metadata))
continue;
perishable.RotAccumulator += frameTime;
if (perishable.RotAccumulator < _rotUpdateRate) // This is where it starts to get noticable on larger animals, no need to run every second
if (_timing.CurTime < perishable.RotNextUpdate) // This is where it starts to get noticable on larger animals, no need to run every second
continue;
perishable.RotAccumulator -= _rotUpdateRate;
perishable.RotNextUpdate = _timing.CurTime + TimeSpan.FromSeconds(_rotUpdateRate);
EnsureComp<FliesComponent>(perishable.Owner);
@@ -152,8 +152,8 @@ namespace Content.Server.Atmos.Miasma
RemComp<FliesComponent>(uid);
if (TryComp<PerishableComponent>(uid, out var perishable))
{
perishable.DeathAccumulator = 0;
perishable.RotAccumulator = 0;
perishable.TimeOfDeath = TimeSpan.Zero;
perishable.RotNextUpdate = TimeSpan.Zero;
}
}
@@ -168,7 +168,20 @@ namespace Content.Server.Atmos.Miasma
private void OnMobStateChanged(EntityUid uid, PerishableComponent component, MobStateChangedEvent args)
{
if (_mobState.IsDead(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)
@@ -176,10 +189,10 @@ namespace Content.Server.Atmos.Miasma
if (!TryComp<PhysicsComponent>(uid, out var physics))
return;
if (!component.Rotting)
if (!IsRotting(component))
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 indices = _transformSystem.GetGridOrMapTilePosition(uid, transform);
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)
{
if (!component.Rotting)
if (!IsRotting(component))
return;
var stage = component.DeathAccumulator / component.RotAfter.TotalSeconds;
var stage = (_timing.CurTime - component.TimeOfDeath).TotalSeconds / component.RotAfter.TotalSeconds;
var description = stage switch {
>= 3 => "miasma-extremely-bloated",
>= 2 => "miasma-bloated",
@@ -254,7 +268,7 @@ namespace Content.Server.Atmos.Miasma
perishable.Progressing = decompose;
if (!perishable.Rotting)
if (!IsRotting(perishable))
return;
if (decompose)
@@ -290,7 +304,7 @@ namespace Content.Server.Atmos.Miasma
public string RequestPoolDisease()
{
// 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;
}
}

View File

@@ -1,3 +1,5 @@
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.Atmos.Miasma
{
[RegisterComponent]
@@ -16,22 +18,20 @@ namespace Content.Server.Atmos.Miasma
/// <summary>
/// How long this creature has been dead.
/// </summary>
[DataField("deathAccumulator")]
[DataField("timeOfDeath", customTypeSerializer: typeof(TimeOffsetSerializer))]
[ViewVariables(VVAccess.ReadWrite)]
public float DeathAccumulator = 0f;
public TimeSpan TimeOfDeath = TimeSpan.Zero;
/// <summary>
/// When DeathAccumulator is greater than this, start rotting.
/// </summary>
public TimeSpan RotAfter = TimeSpan.FromMinutes(5);
public bool Rotting => (DeathAccumulator > RotAfter.TotalSeconds);
/// <summary>
/// Gasses are released every second.
/// Gasses are released, this is when the next gas release update will be.
/// </summary>
[DataField("rotAccumulator")]
public float RotAccumulator = 0f;
[DataField("rotNextUpdate", customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan RotNextUpdate = TimeSpan.Zero;
/// <summary>
/// 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.Server.Construction;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Server.Bed
{
@@ -26,6 +27,7 @@ namespace Content.Server.Bed
[Dependency] private readonly SleepingSystem _sleepingSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize()
{
@@ -44,6 +46,7 @@ namespace Content.Server.Bed
if (args.Buckling)
{
AddComp<HealOnBuckleHealingComponent>(uid);
component.NextHealTime = _timing.CurTime + TimeSpan.FromSeconds(component.HealTime);
if (sleepAction != null)
_actionsSystem.AddAction(args.BuckledEntity, new InstantAction(sleepAction), null);
return;
@@ -54,7 +57,6 @@ namespace Content.Server.Bed
_sleepingSystem.TryWaking(args.BuckledEntity);
RemComp<HealOnBuckleHealingComponent>(uid);
component.Accumulator = 0;
}
public override void Update(float frameTime)
@@ -63,12 +65,10 @@ namespace Content.Server.Bed
foreach (var (_, bedComponent, strapComponent) in EntityQuery<HealOnBuckleHealingComponent, HealOnBuckleComponent, StrapComponent>())
{
bedComponent.Accumulator += frameTime;
if (bedComponent.Accumulator < bedComponent.HealTime)
if (_timing.CurTime < bedComponent.NextHealTime)
continue;
bedComponent.Accumulator -= bedComponent.HealTime;
bedComponent.NextHealTime += TimeSpan.FromSeconds(bedComponent.HealTime);
if (strapComponent.BuckledEntities.Count == 0) continue;

View File

@@ -15,6 +15,7 @@ namespace Content.Server.Bed.Components
[DataField("sleepMultiplier")]
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.Systems;
using Robust.Shared.Collections;
using Robust.Shared.Timing;
namespace Content.Server.Movement.Systems;
public sealed class JetpackSystem : SharedJetpackSystem
{
[Dependency] private readonly GasTankSystem _gasTank = default!;
[Dependency] private readonly IGameTiming _timing = default!;
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>())
{
active.Accumulator += frameTime;
if (active.Accumulator < UpdateCooldown) continue;
if (_timing.CurTime < active.TargetTime) continue;
active.Accumulator -= UpdateCooldown;
active.TargetTime = _timing.CurTime + TimeSpan.FromSeconds(active.EffectCooldown);
var air = _gasTank.RemoveAir(gasTank, comp.MoleUsage);
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 float EffectCooldown = 0.3f;
public float Accumulator = 0f;
public TimeSpan TargetTime = TimeSpan.Zero;
}