--- /dev/null
+#nullable enable
+using Content.Server.Body.Systems;
+using Robust.Shared.GameObjects;
+
+namespace Content.IntegrationTests.Tests.Body;
+
+[TestFixture]
+public sealed class GibTest
+{
+ [Test]
+ public async Task TestGib()
+ {
+ await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true });
+ var (server, client) = (pair.Server, pair.Client);
+ var map = await pair.CreateTestMap();
+
+ EntityUid target1 = default;
+ EntityUid target2 = default;
+
+ await server.WaitAssertion(() => target1 = server.EntMan.Spawn("MobHuman", map.MapCoords));
+ await server.WaitAssertion(() => target2 = server.EntMan.Spawn("MobHuman", map.MapCoords));
+ await pair.WaitCommand($"setoutfit {server.EntMan.GetNetEntity(target1)} CaptainGear");
+ await pair.WaitCommand($"setoutfit {server.EntMan.GetNetEntity(target2)} CaptainGear");
+
+ await pair.RunTicksSync(5);
+ var nuid1 = pair.ToClientUid(target1);
+ var nuid2 = pair.ToClientUid(target2);
+ Assert.That(client.EntMan.EntityExists(nuid1));
+ Assert.That(client.EntMan.EntityExists(nuid2));
+
+ await server.WaitAssertion(() => server.System<BodySystem>().GibBody(target1, gibOrgans: false));
+ await server.WaitAssertion(() => server.System<BodySystem>().GibBody(target2, gibOrgans: true));
+
+ await pair.RunTicksSync(5);
+ await pair.WaitCommand("dirty");
+ await pair.RunTicksSync(5);
+
+ Assert.That(!client.EntMan.EntityExists(nuid1));
+ Assert.That(!client.EntMan.EntityExists(nuid2));
+
+ await pair.CleanReturnAsync();
+ }
+}
using Content.Shared.Inventory.Events;
using Robust.Shared.Containers;
using Robust.Shared.Map;
+using Robust.Shared.Utility;
namespace Content.Shared.Body.Systems;
private void OnBodyRemoved(EntityUid uid, BodyComponent component, EntRemovedFromContainerMessage args)
{
- // TODO: lifestage shenanigans
- if (TerminatingOrDeleted(uid))
- return;
-
// Root body part?
var slotId = args.Container.ID;
return;
var entity = args.Entity;
+ DebugTools.Assert(!TryComp(entity, out BodyPartComponent? b) || b.Body == uid);
+ DebugTools.Assert(!TryComp(entity, out OrganComponent? o) || o.Body == uid);
if (TryComp(entity, out BodyPartComponent? childPart))
{
}
if (TryComp(entity, out OrganComponent? organ))
- {
RemoveOrgan(entity, uid, organ);
- }
}
private void OnBodyInit(EntityUid bodyId, BodyComponent body, ComponentInit args)
var entity = args.Entity;
var slotId = args.Container.ID;
- if (component.Body != null)
- {
- if (TryComp(entity, out BodyPartComponent? childPart))
- {
- AddPart(component.Body.Value, entity, slotId, childPart);
- RecursiveBodyUpdate(entity, component.Body.Value, childPart);
- }
+ if (component.Body == null)
+ return;
- if (TryComp(entity, out OrganComponent? organ))
- {
- AddOrgan(entity, component.Body.Value, uid, organ);
- }
+ if (TryComp(entity, out BodyPartComponent? childPart))
+ {
+ AddPart(component.Body.Value, entity, slotId, childPart);
+ RecursiveBodyUpdate(entity, component.Body.Value, childPart);
}
+
+ if (TryComp(entity, out OrganComponent? organ))
+ AddOrgan(entity, component.Body.Value, uid, organ);
}
private void OnBodyPartRemoved(EntityUid uid, BodyPartComponent component, EntRemovedFromContainerMessage args)
{
- // TODO: lifestage shenanigans
- if (TerminatingOrDeleted(uid))
- return;
-
// Body part removed from another body part.
var entity = args.Entity;
var slotId = args.Container.ID;
+ DebugTools.Assert(!TryComp(entity, out BodyPartComponent? b) || b.Body == component.Body);
+ DebugTools.Assert(!TryComp(entity, out OrganComponent? o) || o.Body == component.Body);
+
if (TryComp(entity, out BodyPartComponent? childPart) && childPart.Body != null)
{
RemovePart(childPart.Body.Value, entity, slotId, childPart);
}
if (TryComp(entity, out OrganComponent? organ))
- {
RemoveOrgan(entity, uid, organ);
- }
}
private void RecursiveBodyUpdate(EntityUid uid, EntityUid? bodyUid, BodyPartComponent component)
{
- foreach (var children in GetBodyPartChildren(uid, component))
+ component.Body = bodyUid;
+ Dirty(uid, component);
+
+ foreach (var slotId in component.Organs.Keys)
{
- if (children.Component.Body != bodyUid)
+ if (!Containers.TryGetContainer(uid, GetOrganContainerId(slotId), out var container))
+ continue;
+
+ foreach (var organ in container.ContainedEntities)
{
- children.Component.Body = bodyUid;
- Dirty(children.Id, children.Component);
+ if (!TryComp(organ, out OrganComponent? organComp))
+ continue;
- foreach (var slotId in children.Component.Organs.Keys)
- {
- var organContainerId = GetOrganContainerId(slotId);
+ Dirty(organ, organComp);
- if (!Containers.TryGetContainer(children.Id, organContainerId, out var container))
- continue;
+ if (organComp.Body != null)
+ RaiseLocalEvent(organ, new RemovedFromPartInBodyEvent(organComp.Body.Value, uid));
- foreach (var organ in container.ContainedEntities)
- {
- if (TryComp(organ, out OrganComponent? organComp))
- {
- var oldBody = organComp.Body;
- organComp.Body = bodyUid;
-
- if (bodyUid != null)
- {
- var ev = new AddedToPartInBodyEvent(bodyUid.Value, children.Id);
- RaiseLocalEvent(organ, ev);
- }
- else if (oldBody != null)
- {
- var ev = new RemovedFromPartInBodyEvent(oldBody.Value, children.Id);
- RaiseLocalEvent(organ, ev);
- }
-
- Dirty(organ, organComp);
- }
- }
- }
+ organComp.Body = bodyUid;
+ if (bodyUid != null)
+ RaiseLocalEvent(organ, new AddedToPartInBodyEvent(bodyUid.Value, uid));
+ }
+ }
+
+ foreach (var slotId in component.Children.Keys)
+ {
+ if (!Containers.TryGetContainer(uid, GetPartSlotContainerId(slotId), out var container))
+ continue;
+
+ foreach (var containedEnt in container.ContainedEntities)
+ {
+ if (TryComp(containedEnt, out BodyPartComponent? childPart))
+ RecursiveBodyUpdate(containedEnt, bodyUid, childPart);
}
}
}