Files
tbd-station-14/Content.Shared/Chemistry/EntitySystems/SolutionRegenerationSystem.cs
Perry Fraser c802b8bbb2 Make mopping predicted (and some other stuff) (#38749)
* refactor: move puddle evaporation + absorbents to shared

* refactor: move SolutionRegeneration to shared

* refactor: make AbsorbentSystem visuals clientside

* style: general formatting/cleanup on touched files

- Few logical simplifications
- Add field for hard-coded sparkle effect ent
- Switch stuff to Entity<T>

No actual prediction fixes in this commit (though in
retrospect I should've done this commit last).

* fix: use predicted variants for predicted code

* fix: average out evaporation rates in mixtures

* refactor: move SolutionPurge to shared

* style: Basic SolutionPurgeComponent field cleanup

* fix: general prediction + timing + networking fixes

- Moves client side visuals back to shared because other
  players exist
- Don't accumulate CurTime in Purge/RegenerationSystem
- Network the next update field in Purge/RegenerationSystem to
  deal with UI mispredictions???

* fix: add udder bug workaround

Not needed for SolutionPurgeSystem which doesn't resolve
solutions (probably fine that SolutionPurgeSystem doesn't
cache since it's much rarer, though it probably should), and
likely not needed for AbsorbentSystem since it only resolves
against puddles which, I don't think can be in containers.

* fix: don't divide by zero for evaporation speed = 0.

* refactor: revert evaporation changes

Will cherry-pick these out in another PR.

Also reverting the evaporation speed bugfix since it's easier
to revert all at once. :)

* fix: component cleanup; autopause fields, use ProtoID

* fix: remove unused AbsorbentComponentState

* fix: ProtoId is not string

* refactor: move PuddleSystem.UpdateAppearance to shared

* style: general PuddleSystem.UpdateAppearance tweaks

- Switch to Entity<T>
- Use ProtoIds
- Minor simplifications

* fix: add udderly silly PVS workaround

* cleanup

* fix

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2025-07-09 05:17:55 +02:00

70 lines
2.6 KiB
C#

using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.FixedPoint;
using Robust.Shared.Containers;
using Robust.Shared.Timing;
namespace Content.Shared.Chemistry.EntitySystems;
public sealed class SolutionRegenerationSystem : EntitySystem
{
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SolutionRegenerationComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<SolutionRegenerationComponent, EntRemovedFromContainerMessage>(OnEntRemoved);
}
private void OnMapInit(Entity<SolutionRegenerationComponent> ent, ref MapInitEvent args)
{
ent.Comp.NextRegenTime = _timing.CurTime + ent.Comp.Duration;
Dirty(ent);
}
// Workaround for https://github.com/space-wizards/space-station-14/pull/35314
private void OnEntRemoved(Entity<SolutionRegenerationComponent> ent, ref EntRemovedFromContainerMessage args)
{
// Make sure the removed entity was our contained solution and clear our cached reference
if (args.Entity == ent.Comp.SolutionRef?.Owner)
ent.Comp.SolutionRef = null;
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<SolutionRegenerationComponent, SolutionContainerManagerComponent>();
while (query.MoveNext(out var uid, out var regen, out var manager))
{
if (_timing.CurTime < regen.NextRegenTime)
continue;
// timer ignores if its full, it's just a fixed cycle
regen.NextRegenTime += regen.Duration;
// Needs to be networked and dirtied so that the client can reroll it during prediction
Dirty(uid, regen);
if (!_solutionContainer.ResolveSolution((uid, manager),
regen.SolutionName,
ref regen.SolutionRef,
out var solution))
continue;
var amount = FixedPoint2.Min(solution.AvailableVolume, regen.Generated.Volume);
if (amount <= FixedPoint2.Zero)
continue;
// Don't bother cloning and splitting if adding the whole thing
var generated = amount == regen.Generated.Volume
? regen.Generated
: regen.Generated.Clone().SplitSolution(amount);
_solutionContainer.TryAddSolution(regen.SolutionRef.Value, generated);
}
}
}