Optimise drains (#32230)
* Optimise drains If it's still a problem then we do what I did for rmc14 and just dump all the active drains onto a job to getentitiesinrange in parallel. * Fixes
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
using Content.Server.DoAfter;
|
using Content.Server.DoAfter;
|
||||||
using Content.Server.Fluids.Components;
|
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Shared.Chemistry.EntitySystems;
|
using Content.Shared.Chemistry.EntitySystems;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
@@ -13,9 +12,7 @@ using Content.Shared.Fluids.Components;
|
|||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
using Robust.Server.GameObjects;
|
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Collections;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -32,19 +29,27 @@ public sealed class DrainSystem : SharedDrainSystem
|
|||||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||||
[Dependency] private readonly PuddleSystem _puddleSystem = default!;
|
[Dependency] private readonly PuddleSystem _puddleSystem = default!;
|
||||||
[Dependency] private readonly TransformSystem _transform = default!;
|
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
|
private readonly HashSet<Entity<PuddleComponent>> _puddles = new();
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<DrainComponent, MapInitEvent>(OnDrainMapInit);
|
||||||
SubscribeLocalEvent<DrainComponent, GetVerbsEvent<Verb>>(AddEmptyVerb);
|
SubscribeLocalEvent<DrainComponent, GetVerbsEvent<Verb>>(AddEmptyVerb);
|
||||||
SubscribeLocalEvent<DrainComponent, ExaminedEvent>(OnExamined);
|
SubscribeLocalEvent<DrainComponent, ExaminedEvent>(OnExamined);
|
||||||
SubscribeLocalEvent<DrainComponent, AfterInteractUsingEvent>(OnInteract);
|
SubscribeLocalEvent<DrainComponent, AfterInteractUsingEvent>(OnInteract);
|
||||||
SubscribeLocalEvent<DrainComponent, DrainDoAfterEvent>(OnDoAfter);
|
SubscribeLocalEvent<DrainComponent, DrainDoAfterEvent>(OnDoAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnDrainMapInit(Entity<DrainComponent> ent, ref MapInitEvent args)
|
||||||
|
{
|
||||||
|
// Randomise puddle drains so roundstart ones don't all dump at the same time.
|
||||||
|
ent.Comp.Accumulator = _random.NextFloat(ent.Comp.DrainFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
private void AddEmptyVerb(Entity<DrainComponent> entity, ref GetVerbsEvent<Verb> args)
|
private void AddEmptyVerb(Entity<DrainComponent> entity, ref GetVerbsEvent<Verb> args)
|
||||||
{
|
{
|
||||||
if (!args.CanAccess || !args.CanInteract || args.Using == null)
|
if (!args.CanAccess || !args.CanInteract || args.Using == null)
|
||||||
@@ -118,9 +123,6 @@ public sealed class DrainSystem : SharedDrainSystem
|
|||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
var managerQuery = GetEntityQuery<SolutionContainerManagerComponent>();
|
var managerQuery = GetEntityQuery<SolutionContainerManagerComponent>();
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
var puddleQuery = GetEntityQuery<PuddleComponent>();
|
|
||||||
var puddles = new ValueList<(Entity<PuddleComponent> Entity, string Solution)>();
|
|
||||||
|
|
||||||
var query = EntityQueryEnumerator<DrainComponent>();
|
var query = EntityQueryEnumerator<DrainComponent>();
|
||||||
while (query.MoveNext(out var uid, out var drain))
|
while (query.MoveNext(out var uid, out var drain))
|
||||||
@@ -158,22 +160,10 @@ public sealed class DrainSystem : SharedDrainSystem
|
|||||||
// This will ensure that UnitsPerSecond is per second...
|
// This will ensure that UnitsPerSecond is per second...
|
||||||
var amount = drain.UnitsPerSecond * drain.DrainFrequency;
|
var amount = drain.UnitsPerSecond * drain.DrainFrequency;
|
||||||
|
|
||||||
if (!xformQuery.TryGetComponent(uid, out var xform))
|
_puddles.Clear();
|
||||||
continue;
|
_lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles);
|
||||||
|
|
||||||
puddles.Clear();
|
if (_puddles.Count == 0)
|
||||||
|
|
||||||
foreach (var entity in _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(uid, xform), drain.Range))
|
|
||||||
{
|
|
||||||
// No InRangeUnobstructed because there's no collision group that fits right now
|
|
||||||
// and these are placed by mappers and not buildable/movable so shouldnt really be a problem...
|
|
||||||
if (puddleQuery.TryGetComponent(entity, out var puddle))
|
|
||||||
{
|
|
||||||
puddles.Add(((entity, puddle), puddle.SolutionName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (puddles.Count == 0)
|
|
||||||
{
|
{
|
||||||
_ambientSoundSystem.SetAmbience(uid, false);
|
_ambientSoundSystem.SetAmbience(uid, false);
|
||||||
continue;
|
continue;
|
||||||
@@ -181,13 +171,13 @@ public sealed class DrainSystem : SharedDrainSystem
|
|||||||
|
|
||||||
_ambientSoundSystem.SetAmbience(uid, true);
|
_ambientSoundSystem.SetAmbience(uid, true);
|
||||||
|
|
||||||
amount /= puddles.Count;
|
amount /= _puddles.Count;
|
||||||
|
|
||||||
foreach (var (puddle, solution) in puddles)
|
foreach (var puddle in _puddles)
|
||||||
{
|
{
|
||||||
// Queue the solution deletion if it's empty. EvaporationSystem might also do this
|
// Queue the solution deletion if it's empty. EvaporationSystem might also do this
|
||||||
// but queuedelete should be pretty safe.
|
// but queuedelete should be pretty safe.
|
||||||
if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, solution, ref puddle.Comp.Solution, out var puddleSolution))
|
if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, puddle.Comp.SolutionName, ref puddle.Comp.Solution, out var puddleSolution))
|
||||||
{
|
{
|
||||||
EntityManager.QueueDeleteEntity(puddle);
|
EntityManager.QueueDeleteEntity(puddle);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public sealed partial class DrainComponent : Component
|
|||||||
/// drain puddles from.
|
/// drain puddles from.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public float Range = 2f;
|
public float Range = 2.5f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How often in seconds the drain checks for puddles around it.
|
/// How often in seconds the drain checks for puddles around it.
|
||||||
|
|||||||
Reference in New Issue
Block a user