ECS and cleanup body system, merge body templates and presets into body prototypes (#11991)
Co-authored-by: Jezithyr <Jezithyr@gmail.com>
This commit is contained in:
@@ -1,119 +1,148 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Humanoid;
|
||||
using Content.Server.Kitchen.Components;
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.Body.Systems;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Body.Systems
|
||||
namespace Content.Server.Body.Systems;
|
||||
|
||||
public sealed class BodySystem : SharedBodySystem
|
||||
{
|
||||
public sealed class BodySystem : EntitySystem
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
[Dependency] private readonly HumanoidSystem _humanoidSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
base.Initialize();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<BodyComponent, MoveInputEvent>(OnRelayMoveInput);
|
||||
SubscribeLocalEvent<BodyComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
SubscribeLocalEvent<BodyComponent, BeingMicrowavedEvent>(OnBeingMicrowaved);
|
||||
SubscribeLocalEvent<BodyPartComponent, MapInitEvent>((_, c, _) => c.MapInitialize());
|
||||
}
|
||||
SubscribeLocalEvent<BodyComponent, MoveInputEvent>(OnRelayMoveInput);
|
||||
SubscribeLocalEvent<BodyComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
SubscribeLocalEvent<BodyComponent, BeingMicrowavedEvent>(OnBeingMicrowaved);
|
||||
}
|
||||
|
||||
private void OnRelayMoveInput(EntityUid uid, BodyComponent component, ref MoveInputEvent args)
|
||||
private void OnRelayMoveInput(EntityUid uid, BodyComponent component, ref MoveInputEvent args)
|
||||
{
|
||||
if (EntityManager.TryGetComponent<MobStateComponent>(uid, out var mobState) &&
|
||||
mobState.IsDead() &&
|
||||
EntityManager.TryGetComponent<MindComponent>(uid, out var mind) &&
|
||||
mind.HasMind)
|
||||
{
|
||||
if (EntityManager.TryGetComponent<MobStateComponent>(uid, out var mobState) &&
|
||||
mobState.IsDead() &&
|
||||
EntityManager.TryGetComponent<MindComponent>(uid, out var mind) &&
|
||||
mind.HasMind)
|
||||
if (!mind.Mind!.TimeOfDeath.HasValue)
|
||||
{
|
||||
if (!mind.Mind!.TimeOfDeath.HasValue)
|
||||
{
|
||||
mind.Mind.TimeOfDeath = _gameTiming.RealTime;
|
||||
}
|
||||
|
||||
_ticker.OnGhostAttempt(mind.Mind!, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, BodyComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
foreach (var (part, _) in component.Parts)
|
||||
foreach (var mechanism in part.Mechanisms)
|
||||
{
|
||||
RaiseLocalEvent(mechanism.Owner, args, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeingMicrowaved(EntityUid uid, BodyComponent component, BeingMicrowavedEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
// Don't microwave animals, kids
|
||||
Transform(uid).AttachToGridOrMap();
|
||||
component.Gib();
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of ValueTuples of <see cref="T"/> and MechanismComponent on each mechanism
|
||||
/// in the given body.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity to check for the component on.</param>
|
||||
/// <param name="body">The body to check for mechanisms on.</param>
|
||||
/// <typeparam name="T">The component to check for.</typeparam>
|
||||
public List<(T Comp, MechanismComponent Mech)> GetComponentsOnMechanisms<T>(EntityUid uid,
|
||||
SharedBodyComponent? body=null) where T : Component
|
||||
{
|
||||
if (!Resolve(uid, ref body))
|
||||
return new();
|
||||
|
||||
var query = EntityManager.GetEntityQuery<T>();
|
||||
var list = new List<(T Comp, MechanismComponent Mech)>(3);
|
||||
foreach (var (part, _) in body.Parts)
|
||||
foreach (var mechanism in part.Mechanisms)
|
||||
{
|
||||
if (query.TryGetComponent(mechanism.Owner, out var comp))
|
||||
list.Add((comp, mechanism));
|
||||
mind.Mind.TimeOfDeath = _gameTiming.RealTime;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a list of ValueTuples of <see cref="T"/> and MechanismComponent on each mechanism
|
||||
/// in the given body.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity to check for the component on.</param>
|
||||
/// <param name="comps">The list of components.</param>
|
||||
/// <param name="body">The body to check for mechanisms on.</param>
|
||||
/// <typeparam name="T">The component to check for.</typeparam>
|
||||
/// <returns>Whether any were found.</returns>
|
||||
public bool TryGetComponentsOnMechanisms<T>(EntityUid uid,
|
||||
[NotNullWhen(true)] out List<(T Comp, MechanismComponent Mech)>? comps,
|
||||
SharedBodyComponent? body=null) where T: Component
|
||||
{
|
||||
if (!Resolve(uid, ref body))
|
||||
{
|
||||
comps = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
comps = GetComponentsOnMechanisms<T>(uid, body);
|
||||
|
||||
if (comps.Count == 0)
|
||||
{
|
||||
comps = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
_ticker.OnGhostAttempt(mind.Mind!, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, BodyComponent component,
|
||||
ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
foreach (var organ in GetBodyOrgans(uid, component))
|
||||
{
|
||||
RaiseLocalEvent(organ.Id, args);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeingMicrowaved(EntityUid uid, BodyComponent component, BeingMicrowavedEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
// Don't microwave animals, kids
|
||||
Transform(uid).AttachToGridOrMap();
|
||||
GibBody(uid, false, component);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
public override bool AttachPart(
|
||||
EntityUid? partId,
|
||||
BodyPartSlot slot,
|
||||
[NotNullWhen(true)] BodyPartComponent? part = null)
|
||||
{
|
||||
if (!base.AttachPart(partId, slot, part))
|
||||
return false;
|
||||
|
||||
if (part.Body is { } body &&
|
||||
TryComp<HumanoidComponent>(body, out var humanoid))
|
||||
{
|
||||
var layer = part.ToHumanoidLayers();
|
||||
if (layer != null)
|
||||
{
|
||||
var layers = HumanoidVisualLayersExtension.Sublayers(layer.Value);
|
||||
_humanoidSystem.SetLayersVisibility(body, layers, true, true, humanoid);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool DropPart(EntityUid? partId, BodyPartComponent? part = null)
|
||||
{
|
||||
var oldBody = CompOrNull<BodyPartComponent>(partId)?.Body;
|
||||
|
||||
if (!base.DropPart(partId, part))
|
||||
return false;
|
||||
|
||||
if (oldBody == null || !TryComp<HumanoidComponent>(oldBody, out var humanoid))
|
||||
return true;
|
||||
|
||||
var layer = part.ToHumanoidLayers();
|
||||
if (layer == null)
|
||||
return true;
|
||||
|
||||
var layers = HumanoidVisualLayersExtension.Sublayers(layer.Value);
|
||||
_humanoidSystem.SetLayersVisibility(oldBody.Value, layers, false, true, humanoid);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override HashSet<EntityUid> GibBody(EntityUid? bodyId, bool gibOrgans = false, BodyComponent? body = null)
|
||||
{
|
||||
if (bodyId == null || !Resolve(bodyId.Value, ref body, false))
|
||||
return new HashSet<EntityUid>();
|
||||
|
||||
var gibs = base.GibBody(bodyId, gibOrgans, body);
|
||||
|
||||
var xform = Transform(bodyId.Value);
|
||||
var coordinates = xform.Coordinates;
|
||||
var filter = Filter.Pvs(bodyId.Value, entityManager: EntityManager);
|
||||
var audio = AudioParams.Default.WithVariation(0.025f);
|
||||
|
||||
_audio.Play(body.GibSound, filter, coordinates, audio);
|
||||
|
||||
if (TryComp(bodyId, out ContainerManagerComponent? container))
|
||||
{
|
||||
foreach (var cont in container.GetAllContainers())
|
||||
{
|
||||
foreach (var ent in cont.ContainedEntities)
|
||||
{
|
||||
cont.ForceRemove(ent);
|
||||
Transform(ent).Coordinates = coordinates;
|
||||
ent.RandomOffset(0.25f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RaiseLocalEvent(bodyId.Value, new BeingGibbedEvent(gibs));
|
||||
QueueDel(bodyId.Value);
|
||||
|
||||
return gibs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Server.Ghost.Components;
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Events;
|
||||
using Content.Shared.Body.Organ;
|
||||
using Content.Shared.Movement.Components;
|
||||
|
||||
namespace Content.Server.Body.Systems
|
||||
@@ -13,21 +14,22 @@ namespace Content.Server.Body.Systems
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BrainComponent, AddedToBodyEvent>((uid, _, args) => HandleMind((args.Body).Owner, uid));
|
||||
SubscribeLocalEvent<BrainComponent, AddedToPartEvent>((uid, _, args) => HandleMind((args.Part).Owner, uid));
|
||||
SubscribeLocalEvent<BrainComponent, AddedToPartInBodyEvent>((uid, _, args) => HandleMind((args.Body).Owner, uid));
|
||||
SubscribeLocalEvent<BrainComponent, AddedToBodyEvent>((uid, _, args) => HandleMind(args.Body, uid));
|
||||
SubscribeLocalEvent<BrainComponent, AddedToPartEvent>((uid, _, args) => HandleMind(args.Part, uid));
|
||||
SubscribeLocalEvent<BrainComponent, AddedToPartInBodyEvent>((uid, _, args) => HandleMind(args.Body, uid));
|
||||
SubscribeLocalEvent<BrainComponent, RemovedFromBodyEvent>(OnRemovedFromBody);
|
||||
SubscribeLocalEvent<BrainComponent, RemovedFromPartEvent>((uid, _, args) => HandleMind(uid, (args.Old).Owner));
|
||||
SubscribeLocalEvent<BrainComponent, RemovedFromPartInBodyEvent>((uid, _, args) => HandleMind((args.OldBody).Owner, uid));
|
||||
SubscribeLocalEvent<BrainComponent, RemovedFromPartEvent>((uid, _, args) => HandleMind(uid, args.Old));
|
||||
SubscribeLocalEvent<BrainComponent, RemovedFromPartInBodyEvent>((uid, _, args) => HandleMind(args.OldBody, uid));
|
||||
}
|
||||
|
||||
private void OnRemovedFromBody(EntityUid uid, BrainComponent component, RemovedFromBodyEvent args)
|
||||
{
|
||||
// This one needs to be special, okay?
|
||||
if (!EntityManager.TryGetComponent(uid, out MechanismComponent? mech))
|
||||
if (!EntityManager.TryGetComponent(uid, out OrganComponent? organ) ||
|
||||
organ.ParentSlot is not {Parent: var parent})
|
||||
return;
|
||||
|
||||
HandleMind((mech.Part!).Owner, (args.Old).Owner);
|
||||
HandleMind(parent, args.Old);
|
||||
}
|
||||
|
||||
private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
|
||||
|
||||
@@ -3,7 +3,7 @@ using Content.Server.Body.Components;
|
||||
using Content.Server.Chemistry.Components.SolutionManager;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Organ;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Database;
|
||||
@@ -18,6 +18,7 @@ namespace Content.Server.Body.Systems
|
||||
[UsedImplicitly]
|
||||
public sealed class MetabolizerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly BodySystem _bodySystem = default!;
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
@@ -37,30 +38,27 @@ namespace Content.Server.Body.Systems
|
||||
{
|
||||
_solutionContainerSystem.EnsureSolution(uid, component.SolutionName);
|
||||
}
|
||||
else
|
||||
else if (CompOrNull<OrganComponent>(uid)?.Body is { } body)
|
||||
{
|
||||
if (EntityManager.TryGetComponent<MechanismComponent>(uid, out var mech))
|
||||
{
|
||||
if (mech.Body != null)
|
||||
{
|
||||
_solutionContainerSystem.EnsureSolution((mech.Body).Owner, component.SolutionName);
|
||||
}
|
||||
}
|
||||
_solutionContainerSystem.EnsureSolution(body, component.SolutionName);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, MetabolizerComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, MetabolizerComponent component,
|
||||
ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
{
|
||||
component.UpdateFrequency *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
|
||||
component.UpdateFrequency /= args.Multiplier;
|
||||
// Reset the accumulator properly
|
||||
if (component.AccumulatedFrametime >= component.UpdateFrequency)
|
||||
component.AccumulatedFrametime = component.UpdateFrequency;
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
@@ -78,33 +76,27 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
}
|
||||
|
||||
private void TryMetabolize(EntityUid uid, MetabolizerComponent? meta=null, MechanismComponent? mech=null)
|
||||
private void TryMetabolize(EntityUid uid, MetabolizerComponent? meta = null, OrganComponent? organ = null)
|
||||
{
|
||||
if (!Resolve(uid, ref meta))
|
||||
return;
|
||||
|
||||
Resolve(uid, ref mech, false);
|
||||
Resolve(uid, ref organ, false);
|
||||
|
||||
// First step is get the solution we actually care about
|
||||
Solution? solution = null;
|
||||
EntityUid? solutionEntityUid = null;
|
||||
EntityUid? bodyEntityUid = mech?.Body?.Owner;
|
||||
|
||||
SolutionContainerManagerComponent? manager = null;
|
||||
|
||||
if (meta.SolutionOnBody)
|
||||
{
|
||||
if (mech != null)
|
||||
if (organ?.Body is { } body)
|
||||
{
|
||||
var body = mech.Body;
|
||||
|
||||
if (body != null)
|
||||
{
|
||||
if (!Resolve((body).Owner, ref manager, false))
|
||||
return;
|
||||
_solutionContainerSystem.TryGetSolution((body).Owner, meta.SolutionName, out solution, manager);
|
||||
solutionEntityUid = body.Owner;
|
||||
}
|
||||
if (!Resolve(body, ref manager, false))
|
||||
return;
|
||||
_solutionContainerSystem.TryGetSolution(body, meta.SolutionName, out solution, manager);
|
||||
solutionEntityUid = body;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -133,7 +125,8 @@ namespace Content.Server.Body.Systems
|
||||
if (proto.Metabolisms == null)
|
||||
{
|
||||
if (meta.RemoveEmpty)
|
||||
_solutionContainerSystem.TryRemoveReagent(solutionEntityUid.Value, solution, reagent.ReagentId, FixedPoint2.New(1));
|
||||
_solutionContainerSystem.TryRemoveReagent(solutionEntityUid.Value, solution, reagent.ReagentId,
|
||||
FixedPoint2.New(1));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -170,7 +163,7 @@ namespace Content.Server.Body.Systems
|
||||
continue;
|
||||
}
|
||||
|
||||
var actualEntity = bodyEntityUid != null ? bodyEntityUid.Value : solutionEntityUid.Value;
|
||||
var actualEntity = organ?.Body ?? solutionEntityUid.Value;
|
||||
var args = new ReagentEffectArgs(actualEntity, (meta).Owner, solution, proto, mostToRemove,
|
||||
EntityManager, null, entry);
|
||||
|
||||
@@ -192,16 +185,20 @@ namespace Content.Server.Body.Systems
|
||||
|
||||
// remove a certain amount of reagent
|
||||
if (mostToRemove > FixedPoint2.Zero)
|
||||
_solutionContainerSystem.TryRemoveReagent(solutionEntityUid.Value, solution, reagent.ReagentId, mostToRemove);
|
||||
_solutionContainerSystem.TryRemoveReagent(solutionEntityUid.Value, solution, reagent.ReagentId,
|
||||
mostToRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ApplyMetabolicMultiplierEvent : EntityEventArgs
|
||||
{
|
||||
// The entity whose metabolism is being modified
|
||||
public EntityUid Uid;
|
||||
public EntityUid Uid;
|
||||
|
||||
// What the metabolism's update rate will be multiplied by
|
||||
public float Multiplier;
|
||||
public float Multiplier;
|
||||
|
||||
// Apply this multiplier or ignore / reset it?
|
||||
public bool Apply;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ using Content.Shared.Atmos;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.MobState.EntitySystems;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Player;
|
||||
@@ -42,8 +41,7 @@ namespace Content.Server.Body.Systems
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
foreach (var (respirator, body) in
|
||||
EntityManager.EntityQuery<RespiratorComponent, SharedBodyComponent>())
|
||||
foreach (var (respirator, body) in EntityManager.EntityQuery<RespiratorComponent, BodyComponent>())
|
||||
{
|
||||
var uid = respirator.Owner;
|
||||
|
||||
@@ -91,12 +89,13 @@ namespace Content.Server.Body.Systems
|
||||
respirator.SuffocationCycles = 0;
|
||||
}
|
||||
}
|
||||
public void Inhale(EntityUid uid, SharedBodyComponent? body=null)
|
||||
|
||||
public void Inhale(EntityUid uid, BodyComponent? body = null)
|
||||
{
|
||||
if (!Resolve(uid, ref body, false))
|
||||
return;
|
||||
|
||||
var organs = _bodySystem.GetComponentsOnMechanisms<LungComponent>(uid, body);
|
||||
var organs = _bodySystem.GetBodyOrganComponents<LungComponent>(uid, body);
|
||||
|
||||
// Inhale gas
|
||||
var ev = new InhaleLocationEvent();
|
||||
@@ -121,12 +120,12 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
}
|
||||
|
||||
public void Exhale(EntityUid uid, SharedBodyComponent? body=null)
|
||||
public void Exhale(EntityUid uid, BodyComponent? body = null)
|
||||
{
|
||||
if (!Resolve(uid, ref body, false))
|
||||
return;
|
||||
|
||||
var organs = _bodySystem.GetComponentsOnMechanisms<LungComponent>(uid, body);
|
||||
var organs = _bodySystem.GetBodyOrganComponents<LungComponent>(uid, body);
|
||||
|
||||
// exhale gas
|
||||
|
||||
@@ -187,7 +186,8 @@ namespace Content.Server.Body.Systems
|
||||
Math.Clamp(respirator.Saturation, respirator.MinSaturation, respirator.MaxSaturation);
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, RespiratorComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, RespiratorComponent component,
|
||||
ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
{
|
||||
@@ -197,6 +197,7 @@ namespace Content.Server.Body.Systems
|
||||
component.MinSaturation *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
|
||||
// This way we don't have to worry about it breaking if the stasis bed component is destroyed
|
||||
component.CycleDelay /= args.Multiplier;
|
||||
component.Saturation /= args.Multiplier;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Chemistry.Components.SolutionManager;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Organ;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Content.Server.Body.Systems
|
||||
{
|
||||
public sealed class StomachSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly BodySystem _bodySystem = default!;
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
|
||||
public const string DefaultSolutionName = "stomach";
|
||||
@@ -21,12 +22,8 @@ namespace Content.Server.Body.Systems
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
foreach (var (stomach, mech, sol)
|
||||
in EntityManager.EntityQuery<StomachComponent, MechanismComponent, SolutionContainerManagerComponent>(false))
|
||||
foreach (var (stomach, organ, sol)in EntityManager.EntityQuery<StomachComponent, OrganComponent, SolutionContainerManagerComponent>())
|
||||
{
|
||||
if (mech.Body == null)
|
||||
continue;
|
||||
|
||||
stomach.AccumulatedFrameTime += frameTime;
|
||||
|
||||
if (stomach.AccumulatedFrameTime < stomach.UpdateInterval)
|
||||
@@ -35,12 +32,11 @@ namespace Content.Server.Body.Systems
|
||||
stomach.AccumulatedFrameTime -= stomach.UpdateInterval;
|
||||
|
||||
// Get our solutions
|
||||
if (!_solutionContainerSystem.TryGetSolution((stomach).Owner, DefaultSolutionName,
|
||||
out var stomachSolution, sol))
|
||||
if (!_solutionContainerSystem.TryGetSolution(stomach.Owner, DefaultSolutionName,
|
||||
out var stomachSolution, sol))
|
||||
continue;
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution((mech.Body).Owner, stomach.BodySolutionName,
|
||||
out var bodySolution))
|
||||
if (organ.Body is not { } body || !_solutionContainerSystem.TryGetSolution(body, stomach.BodySolutionName, out var bodySolution))
|
||||
continue;
|
||||
|
||||
var transferSolution = new Solution();
|
||||
@@ -71,23 +67,25 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
|
||||
// Transfer everything to the body solution!
|
||||
_solutionContainerSystem.TryAddSolution((mech.Body).Owner, bodySolution, transferSolution);
|
||||
_solutionContainerSystem.TryAddSolution(body, bodySolution, transferSolution);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, StomachComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, StomachComponent component,
|
||||
ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
component.UpdateInterval *= args.Multiplier;
|
||||
return;
|
||||
if (args.Apply)
|
||||
{
|
||||
component.UpdateInterval *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
|
||||
// This way we don't have to worry about it breaking if the stasis bed component is destroyed
|
||||
component.UpdateInterval /= args.Multiplier;
|
||||
// Reset the accumulator properly
|
||||
if (component.AccumulatedFrameTime >= component.UpdateInterval)
|
||||
component.AccumulatedFrameTime = component.UpdateInterval;
|
||||
}
|
||||
// This way we don't have to worry about it breaking if the stasis bed component is destroyed
|
||||
component.UpdateInterval /= args.Multiplier;
|
||||
// Reset the accumulator properly
|
||||
if (component.AccumulatedFrameTime >= component.UpdateInterval)
|
||||
component.AccumulatedFrameTime = component.UpdateInterval;
|
||||
}
|
||||
|
||||
private void OnComponentInit(EntityUid uid, StomachComponent component, ComponentInit args)
|
||||
{
|
||||
@@ -96,7 +94,7 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
|
||||
public bool CanTransferSolution(EntityUid uid, Solution solution,
|
||||
SolutionContainerManagerComponent? solutions=null)
|
||||
SolutionContainerManagerComponent? solutions = null)
|
||||
{
|
||||
if (!Resolve(uid, ref solutions, false))
|
||||
return false;
|
||||
@@ -112,8 +110,8 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
|
||||
public bool TryTransferSolution(EntityUid uid, Solution solution,
|
||||
StomachComponent? stomach=null,
|
||||
SolutionContainerManagerComponent? solutions=null)
|
||||
StomachComponent? stomach = null,
|
||||
SolutionContainerManagerComponent? solutions = null)
|
||||
{
|
||||
if (!Resolve(uid, ref stomach, ref solutions, false))
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user