Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Body code cleanup #24946

Merged
merged 10 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 18 additions & 21 deletions Content.IntegrationTests/Tests/Body/LungTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using System.Linq;
using System.Numerics;

Expand Down Expand Up @@ -61,12 +60,11 @@ public async Task AirConsistencyTest()
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var mapLoader = entityManager.System<MapLoaderSystem>();
RespiratorSystem respSys = default;
MetabolizerSystem metaSys = default;

MapId mapId;
EntityUid? grid = null;
BodyComponent body = default;
RespiratorComponent resp = default;
EntityUid human = default;
GridAtmosphereComponent relevantAtmos = default;
var startingMoles = 0.0f;
Expand Down Expand Up @@ -99,17 +97,15 @@ float GetMapMoles()

await server.WaitAssertion(() =>
{
var coords = new Vector2(0.5f, -1f);
var coordinates = new EntityCoordinates(grid.Value, coords);
var center = new Vector2(0.5f, 0.5f);
var coordinates = new EntityCoordinates(grid.Value, center);
human = entityManager.SpawnEntity("HumanLungDummy", coordinates);
respSys = entityManager.System<RespiratorSystem>();
metaSys = entityManager.System<MetabolizerSystem>();
relevantAtmos = entityManager.GetComponent<GridAtmosphereComponent>(grid.Value);
startingMoles = GetMapMoles();
startingMoles = 100f; // Hardcoded because GetMapMoles returns 900 here for some reason.

#pragma warning disable NUnit2045
Assert.That(entityManager.TryGetComponent(human, out body), Is.True);
Assert.That(entityManager.HasComponent<RespiratorComponent>(human), Is.True);
Assert.That(entityManager.TryGetComponent(human, out resp), Is.True);
#pragma warning restore NUnit2045
});

Expand All @@ -118,18 +114,19 @@ await server.WaitAssertion(() =>
var inhaleCycles = 100;
for (var i = 0; i < inhaleCycles; i++)
{
await server.WaitAssertion(() =>
{
// inhale
respSys.Update(2.0f);
Assert.That(GetMapMoles(), Is.LessThan(startingMoles));

// metabolize + exhale
metaSys.Update(1.0f);
metaSys.Update(1.0f);
respSys.Update(2.0f);
Assert.That(GetMapMoles(), Is.EqualTo(startingMoles).Within(0.0002));
});
// Breathe in
await PoolManager.WaitUntil(server, () => resp.Status == RespiratorStatus.Exhaling);
Assert.That(
GetMapMoles(), Is.LessThan(startingMoles),
"Did not inhale in any gas"
);

// Breathe out
await PoolManager.WaitUntil(server, () => resp.Status == RespiratorStatus.Inhaling);
Assert.That(
GetMapMoles(), Is.EqualTo(startingMoles).Within(0.0002),
"Did not exhale as much gas as was inhaled"
);
}

await pair.CleanReturnAsync();
Expand Down
10 changes: 4 additions & 6 deletions Content.Server/Bed/BedSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@ private void OnBuckleChange(EntityUid uid, StasisBedComponent component, ref Buc
if (!this.IsPowered(uid, EntityManager))
return;

var metabolicEvent = new ApplyMetabolicMultiplierEvent
{Uid = args.BuckledEntity, Multiplier = component.Multiplier, Apply = args.Buckling};
RaiseLocalEvent(args.BuckledEntity, metabolicEvent);
var metabolicEvent = new ApplyMetabolicMultiplierEvent(args.BuckledEntity, component.Multiplier, args.Buckling);
RaiseLocalEvent(args.BuckledEntity, ref metabolicEvent);
}

private void OnPowerChanged(EntityUid uid, StasisBedComponent component, ref PowerChangedEvent args)
Expand All @@ -121,9 +120,8 @@ private void UpdateMetabolisms(EntityUid uid, StasisBedComponent component, bool

foreach (var buckledEntity in strap.BuckledEntities)
{
var metabolicEvent = new ApplyMetabolicMultiplierEvent
{Uid = buckledEntity, Multiplier = component.Multiplier, Apply = shouldApply};
RaiseLocalEvent(buckledEntity, metabolicEvent);
var metabolicEvent = new ApplyMetabolicMultiplierEvent(buckledEntity, component.Multiplier, shouldApply);
RaiseLocalEvent(buckledEntity, ref metabolicEvent);
}
}
}
Expand Down
86 changes: 41 additions & 45 deletions Content.Server/Body/Commands/AddHandCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
switch (args.Length)
{
case 0:
{
if (player == null)
{
shell.WriteLine("Only a player can run this command without arguments.");
Expand All @@ -50,71 +49,68 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
entity = player.AttachedEntity.Value;
hand = _entManager.SpawnEntity(DefaultHandPrototype, _entManager.GetComponent<TransformComponent>(entity).Coordinates);
break;
}
case 1:
{
if (NetEntity.TryParse(args[0], out var uidNet) && _entManager.TryGetEntity(uidNet, out var uid))
{
if (!_entManager.EntityExists(uid))
if (NetEntity.TryParse(args[0], out var uidNet) && _entManager.TryGetEntity(uidNet, out var uid))
{
shell.WriteLine($"No entity found with uid {uid}");
return;
if (!_entManager.EntityExists(uid))
{
shell.WriteLine($"No entity found with uid {uid}");
return;
}

entity = uid.Value;
hand = _entManager.SpawnEntity(DefaultHandPrototype, _entManager.GetComponent<TransformComponent>(entity).Coordinates);
}
else
{
if (player == null)
{
shell.WriteLine("You must specify an entity to add a hand to when using this command from the server terminal.");
return;
}

if (player.AttachedEntity == null)
{
shell.WriteLine("You don't have an entity to add a hand to.");
return;
}

entity = player.AttachedEntity.Value;
hand = _entManager.SpawnEntity(args[0], _entManager.GetComponent<TransformComponent>(entity).Coordinates);
}

entity = uid.Value;
hand = _entManager.SpawnEntity(DefaultHandPrototype, _entManager.GetComponent<TransformComponent>(entity).Coordinates);
break;
}
else
case 2:
{
if (player == null)
if (!NetEntity.TryParse(args[0], out var netEnt) || !_entManager.TryGetEntity(netEnt, out var uid))
{
shell.WriteLine("You must specify an entity to add a hand to when using this command from the server terminal.");
shell.WriteLine($"{args[0]} is not a valid entity uid.");
return;
}

if (player.AttachedEntity == null)
if (!_entManager.EntityExists(uid))
{
shell.WriteLine("You don't have an entity to add a hand to.");
shell.WriteLine($"No entity exists with uid {uid}.");
return;
}

entity = player.AttachedEntity.Value;
hand = _entManager.SpawnEntity(args[0], _entManager.GetComponent<TransformComponent>(entity).Coordinates);
}

break;
}
case 2:
{
if (!NetEntity.TryParse(args[0], out var netEnt) || !_entManager.TryGetEntity(netEnt, out var uid))
{
shell.WriteLine($"{args[0]} is not a valid entity uid.");
return;
}
entity = uid.Value;

if (!_entManager.EntityExists(uid))
{
shell.WriteLine($"No entity exists with uid {uid}.");
return;
}
if (!_protoManager.HasIndex<EntityPrototype>(args[1]))
{
shell.WriteLine($"No hand entity exists with id {args[1]}.");
return;
}

entity = uid.Value;
hand = _entManager.SpawnEntity(args[1], _entManager.GetComponent<TransformComponent>(entity).Coordinates);

if (!_protoManager.HasIndex<EntityPrototype>(args[1]))
{
shell.WriteLine($"No hand entity exists with id {args[1]}.");
return;
break;
}

hand = _entManager.SpawnEntity(args[1], _entManager.GetComponent<TransformComponent>(entity).Coordinates);

break;
}
default:
{
shell.WriteLine(Help);
return;
}
}

if (!_entManager.TryGetComponent(entity, out BodyComponent? body) || body.RootContainer.ContainedEntity == null)
Expand All @@ -139,7 +135,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)

var slotId = part.GetHashCode().ToString();

if (!bodySystem.TryCreatePartSlotAndAttach(attachAt.Id, slotId, hand, BodyPartType.Hand,attachAt.Component, part))
if (!bodySystem.TryCreatePartSlotAndAttach(attachAt.Id, slotId, hand, BodyPartType.Hand, attachAt.Component, part))
{
shell.WriteError($"Couldn't create a slot with id {slotId} on entity {_entManager.ToPrettyString(entity)}");
return;
Expand Down
4 changes: 2 additions & 2 deletions Content.Server/Body/Commands/AttachBodyPartCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (body.RootContainer.ContainedEntity != null)
{
bodySystem.AttachPartToRoot(bodyId,partUid.Value, body ,part);
bodySystem.AttachPartToRoot(bodyId, partUid.Value, body, part);
}
else
{
var (rootPartId,rootPart) = bodySystem.GetRootPartOrNull(bodyId, body)!.Value;
var (rootPartId, rootPart) = bodySystem.GetRootPartOrNull(bodyId, body)!.Value;
if (!bodySystem.TryCreatePartSlotAndAttach(rootPartId, slotId, partUid.Value, part.PartType, rootPart, part))
{
shell.WriteError($"Could not create slot {slotId} on entity {_entManager.ToPrettyString(bodyId)}");
Expand Down
14 changes: 5 additions & 9 deletions Content.Server/Body/Components/BeingGibbedEvent.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
namespace Content.Server.Body.Components;

public sealed class BeingGibbedEvent : EntityEventArgs
{
public readonly HashSet<EntityUid> GibbedParts;

public BeingGibbedEvent(HashSet<EntityUid> gibbedParts)
{
GibbedParts = gibbedParts;
}
}
/// <summary>
/// Raised when a body gets gibbed, before it is deleted.
/// </summary>
[ByRefEvent]
public readonly record struct BeingGibbedEvent(HashSet<EntityUid> GibbedParts);
34 changes: 20 additions & 14 deletions Content.Server/Body/Components/BloodstreamComponent.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Content.Server.Body.Systems;
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Server.Body.Components
{
Expand All @@ -16,7 +18,17 @@ public sealed partial class BloodstreamComponent : Component
public static string DefaultBloodSolutionName = "bloodstream";
public static string DefaultBloodTemporarySolutionName = "bloodstreamTemporary";

public float AccumulatedFrametime = 0.0f;
/// <summary>
/// The next time that blood level will be updated and bloodloss damage dealt.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextUpdate;

/// <summary>
/// The interval at which this component updates.
/// </summary>
[DataField]
public TimeSpan UpdateInterval = TimeSpan.FromSeconds(3);

/// <summary>
/// How much is this entity currently bleeding?
Expand All @@ -32,7 +44,7 @@ public sealed partial class BloodstreamComponent : Component
public float BleedAmount;

/// <summary>
/// How much should bleeding should be reduced every update interval?
/// How much should bleeding be reduced every update interval?
/// </summary>
[DataField]
public float BleedReductionAmount = 0.33f;
Expand Down Expand Up @@ -63,18 +75,12 @@ public sealed partial class BloodstreamComponent : Component
[DataField(required: true)]
public DamageSpecifier BloodlossHealDamage = new();

/// <summary>
/// How frequently should this bloodstream update, in seconds?
/// </summary>
[DataField]
public float UpdateInterval = 3.0f;

// TODO shouldn't be hardcoded, should just use some organ simulation like bone marrow or smth.
/// <summary>
/// How much reagent of blood should be restored each update interval?
/// </summary>
[DataField]
public float BloodRefreshAmount = 1.0f;
public FixedPoint2 BloodRefreshAmount = 1.0f;

/// <summary>
/// How much blood needs to be in the temporary solution in order to create a puddle?
Expand All @@ -89,8 +95,8 @@ public sealed partial class BloodstreamComponent : Component
/// <remarks>
/// For example, piercing damage is increased while poison damage is nullified entirely.
/// </remarks>
[DataField(customTypeSerializer:typeof(PrototypeIdSerializer<DamageModifierSetPrototype>))]
public string DamageBleedModifiers = "BloodlossHuman";
[DataField]
public ProtoId<DamageModifierSetPrototype> DamageBleedModifiers = "BloodlossHuman";

/// <summary>
/// The sound to be played when a weapon instantly deals blood loss damage.
Expand Down Expand Up @@ -126,7 +132,7 @@ public sealed partial class BloodstreamComponent : Component
/// Slime-people might use slime as their blood or something like that.
/// </remarks>
[DataField]
public string BloodReagent = "Blood";
public ProtoId<ReagentPrototype> BloodReagent = "Blood";

/// <summary>Name/Key that <see cref="BloodSolution"/> is indexed by.</summary>
[DataField]
Expand Down Expand Up @@ -164,6 +170,6 @@ public sealed partial class BloodstreamComponent : Component
/// Variable that stores the amount of status time added by having a low blood level.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float StatusTime;
public TimeSpan StatusTime;
}
}
14 changes: 8 additions & 6 deletions Content.Server/Body/Components/InternalsComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Threading;
namespace Content.Server.Body.Components
{
/// <summary>
Expand All @@ -7,14 +6,17 @@ namespace Content.Server.Body.Components
[RegisterComponent]
public sealed partial class InternalsComponent : Component
{
[ViewVariables] public EntityUid? GasTankEntity { get; set; }
[ViewVariables] public EntityUid? BreathToolEntity { get; set; }
[ViewVariables]
public EntityUid? GasTankEntity;

[ViewVariables]
public EntityUid? BreathToolEntity;

/// <summary>
/// Toggle Internals delay (seconds) when the target is not you.
/// Toggle Internals delay when the target is not you.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("delay")]
public float Delay = 3;
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(3);
}
}
4 changes: 2 additions & 2 deletions Content.Server/Body/Components/LungComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Content.Server.Atmos;
using Content.Server.Atmos;
using Content.Server.Body.Systems;
using Content.Shared.Alert;
using Content.Shared.Atmos;
Expand All @@ -11,7 +11,7 @@ public sealed partial class LungComponent : Component
{
[DataField]
[Access(typeof(LungSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
public GasMixture Air { get; set; } = new()
public GasMixture Air = new()
{
Volume = 6,
Temperature = Atmospherics.NormalBodyTemperature
Expand Down
Loading
Loading