From 66ddb7473fcd107322d55f05e2474b8278ed91fe Mon Sep 17 00:00:00 2001 From: pathetic meowmeow Date: Wed, 14 Jan 2026 00:57:08 -0500 Subject: [PATCH] Decouple gibbing from the body system (#42405) * Decouple gibbing from the body system * allow gibs that don't drop giblets * pass through user * prediction gon * comment * destructible * playpvs * very very very very very very very minor cleanup --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Tests/Body/GibTest.cs | 43 --- .../Tests/Gibbing/GibTest.cs | 36 ++ .../Systems/AdminVerbSystem.Smites.cs | 4 +- .../Anomaly/Effects/InnerBodyAnomalySystem.cs | 6 +- Content.Server/Atmos/Rotting/RottingSystem.cs | 5 +- Content.Server/Body/Systems/BodySystem.cs | 93 ----- .../Destructible/DestructibleSystem.cs | 6 +- .../Thresholds/Behaviors/GibBehavior.cs | 8 +- .../Forensics/Systems/ForensicsSystem.cs | 9 +- .../Gibbing/Systems/GibOnRoundEndSystem.cs | 6 +- Content.Server/Guardian/GuardianSystem.cs | 6 +- .../ImmovableRod/ImmovableRodSystem.cs | 5 +- Content.Server/Implants/ImplantedSystem.cs | 5 +- .../Kitchen/EntitySystems/SharpSystem.cs | 9 +- .../Materials/MaterialReclaimerSystem.cs | 8 +- .../Mind/TransferMindOnGibSystem.cs | 14 +- .../Systems/ShuttleSystem.FasterThanLight.cs | 2 +- .../Shuttles/Systems/ShuttleSystem.cs | 4 +- .../Systems/ArtifactCrusherSystem.cs | 3 +- .../Thresholds/Behaviors/GibPartBehavior.cs | 2 +- .../Body/Events/BeingGibbedEvent.cs | 7 - .../Body/Systems/SharedBloodstreamSystem.cs | 5 +- .../Body/Systems/SharedBodySystem.Body.cs | 152 ++------ Content.Shared/Devour/DevourSystem.cs | 8 +- .../Gibbing/Components/GibbableComponent.cs | 34 -- .../Gibbing/Events/GibbingEvents.cs | 50 --- .../GibOnRoundEndComponent.cs | 0 Content.Shared/Gibbing/GibbingSystem.cs | 84 +++++ .../Gibbing/Systems/GibbingSystem.cs | 344 ------------------ .../Kitchen/SharedKitchenSpikeSystem.cs | 7 +- Content.Shared/Magic/SharedMagicSystem.cs | 11 +- .../Silicons/Borgs/SharedBorgSystem.cs | 5 +- .../Species/Systems/GibActionSystem.cs | 6 +- .../Trigger/Systems/GibOnTriggerSystem.cs | 6 +- .../Prototypes/Body/Organs/Animal/animal.yml | 9 +- Resources/Prototypes/Body/Organs/human.yml | 11 +- Resources/Prototypes/Body/Parts/base.yml | 1 - .../Prototypes/Entities/Mobs/NPCs/animals.yml | 1 - .../Entities/Mobs/Species/skeleton.yml | 1 - .../_Shitmed/Body/Organs/Animal/animal.yml | 2 +- 40 files changed, 222 insertions(+), 796 deletions(-) delete mode 100644 Content.IntegrationTests/Tests/Body/GibTest.cs create mode 100644 Content.IntegrationTests/Tests/Gibbing/GibTest.cs delete mode 100644 Content.Shared/Body/Events/BeingGibbedEvent.cs delete mode 100644 Content.Shared/Gibbing/Components/GibbableComponent.cs delete mode 100644 Content.Shared/Gibbing/Events/GibbingEvents.cs rename Content.Shared/Gibbing/{Components => }/GibOnRoundEndComponent.cs (100%) create mode 100644 Content.Shared/Gibbing/GibbingSystem.cs delete mode 100644 Content.Shared/Gibbing/Systems/GibbingSystem.cs diff --git a/Content.IntegrationTests/Tests/Body/GibTest.cs b/Content.IntegrationTests/Tests/Body/GibTest.cs deleted file mode 100644 index e3d5dac33c..0000000000 --- a/Content.IntegrationTests/Tests/Body/GibTest.cs +++ /dev/null @@ -1,43 +0,0 @@ -#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().GibBody(target1, acidify: false)); - await server.WaitAssertion(() => server.System().GibBody(target2, acidify: 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(); - } -} diff --git a/Content.IntegrationTests/Tests/Gibbing/GibTest.cs b/Content.IntegrationTests/Tests/Gibbing/GibTest.cs new file mode 100644 index 0000000000..ee0f7a742d --- /dev/null +++ b/Content.IntegrationTests/Tests/Gibbing/GibTest.cs @@ -0,0 +1,36 @@ +#nullable enable +using Content.Shared.Gibbing; +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 target = default; + + await server.WaitAssertion(() => target = server.EntMan.Spawn("MobHuman", map.MapCoords)); + await pair.WaitCommand($"setoutfit {server.EntMan.GetNetEntity(target)} CaptainGear"); + + await pair.RunTicksSync(5); + var nuid = pair.ToClientUid(target); + Assert.That(client.EntMan.EntityExists(nuid)); + + await server.WaitAssertion(() => server.System().Gib(target)); + + await pair.RunTicksSync(5); + await pair.WaitCommand("dirty"); + await pair.RunTicksSync(5); + + Assert.That(!client.EntMan.EntityExists(nuid)); + + await pair.CleanReturnAsync(); + } +} diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs index 5301031636..306508835a 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs @@ -29,6 +29,7 @@ using Content.Shared.Damage.Components; using Content.Shared.Damage.Systems; using Content.Shared.Database; using Content.Shared.Electrocution; +using Content.Shared.Gibbing; using Content.Shared.Gravity; using Content.Shared.Interaction.Components; using Content.Shared.Inventory; @@ -92,6 +93,7 @@ public sealed partial class AdminVerbSystem [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly SuperBonkSystem _superBonkSystem = default!; [Dependency] private readonly SlipperySystem _slipperySystem = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; private readonly EntProtoId _actionViewLawsProtoId = "ActionViewLaws"; private readonly ProtoId _crewsimovLawset = "Crewsimov"; @@ -128,7 +130,7 @@ public sealed partial class AdminVerbSystem 4, 1, 2, args.Target, maxTileBreak: 0), // it gibs, damage doesn't need to be high. CancellationToken.None); - _bodySystem.GibBody(args.Target); + _gibbing.Gib(args.Target); }, Impact = LogImpact.Extreme, Message = string.Join(": ", explodeName, Loc.GetString("admin-smite-explode-description")) // we do this so the description tells admins the Text to run it via console. diff --git a/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs b/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs index f040514424..06a2e11089 100644 --- a/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Anomaly.Effects; using Content.Shared.Body.Components; using Content.Shared.Chat; using Content.Shared.Database; +using Content.Shared.Gibbing; using Content.Shared.Mobs; using Content.Shared.Popups; using Content.Shared.Whitelist; @@ -25,7 +26,7 @@ public sealed class InnerBodyAnomalySystem : SharedInnerBodyAnomalySystem [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly AnomalySystem _anomaly = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly BodySystem _body = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly IChatManager _chat = default!; [Dependency] private readonly ISharedPlayerManager _player = default!; [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; @@ -139,8 +140,7 @@ public sealed class InnerBodyAnomalySystem : SharedInnerBodyAnomalySystem if (!TryComp(ent, out var body)) return; - // DeltaV acidify: false preserves inventory items when anomaly goes supercritical - _body.GibBody(ent, false, body, splatModifier: 5f); + _gibbing.Gib(ent.Owner); } private void OnSeverityChanged(Entity ent, ref AnomalySeverityChangedEvent args) diff --git a/Content.Server/Atmos/Rotting/RottingSystem.cs b/Content.Server/Atmos/Rotting/RottingSystem.cs index e83d80748b..ea45bf5ed6 100644 --- a/Content.Server/Atmos/Rotting/RottingSystem.cs +++ b/Content.Server/Atmos/Rotting/RottingSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.Atmos; using Content.Shared.Atmos.Rotting; using Content.Shared.Body.Events; using Content.Shared.Damage.Systems; +using Content.Shared.Gibbing; using Content.Shared.Temperature.Components; using Robust.Server.Containers; using Robust.Shared.Physics.Components; @@ -21,12 +22,12 @@ public sealed class RottingSystem : SharedRottingSystem { base.Initialize(); - SubscribeLocalEvent(OnGibbed); + SubscribeLocalEvent(OnGibbed); SubscribeLocalEvent(OnTempIsRotting); } - private void OnGibbed(EntityUid uid, RottingComponent component, BeingGibbedEvent args) + private void OnGibbed(EntityUid uid, RottingComponent component, GibbedBeforeDeletionEvent args) { if (!TryComp(uid, out var physics)) return; diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index 3cf09a122b..1b906e5319 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -22,7 +22,6 @@ using Content.Shared.Damage.Components; // Shitmed Change using System.Linq; using Content.Shared.Damage; -using Content.Shared.Gibbing.Events; namespace Content.Server.Body.Systems; @@ -107,99 +106,7 @@ public sealed class BodySystem : SharedBodySystem _appearance.SetData(bodyEnt, layer, true); // Shitmed Change } - public override HashSet GibBody( - EntityUid bodyId, - bool acidify = false, // DeltaV - Changed paramater from gibOrgans - BodyComponent? body = null, - bool launchGibs = true, - Vector2? splatDirection = null, - float splatModifier = 1, - Angle splatCone = default, - SoundSpecifier? gibSoundOverride = null, - // Shitmed Change - GibType gib = GibType.Gib, - GibContentsOption contents = GibContentsOption.Drop) - { - if (!Resolve(bodyId, ref body, logMissing: false) - || TerminatingOrDeleted(bodyId) - || EntityManager.IsQueuedForDeletion(bodyId)) - { - return new HashSet(); - } - - if (HasComp(bodyId)) - return new HashSet(); - - // DeltaV - If a polymorph configured to revert on death is gibbed without dying, - // revert it then gib so the parent is gibbed instead of the polymorph. - if (TryComp(bodyId, out var polymorph) - && !polymorph.Reverted - && polymorph.Configuration.RevertOnDeath) - { - _polymorph.Revert(bodyId); - if (polymorph.Configuration.TransferDamage && polymorph.Parent.HasValue) - GibBody(polymorph.Parent.Value, acidify, null, launchGibs: launchGibs, splatDirection: splatDirection, - splatModifier: splatModifier, splatCone: splatCone); - return new HashSet(); - } - // END DeltaV - - var xform = Transform(bodyId); - if (xform.MapUid is null) - return new HashSet(); - - var gibs = base.GibBody(bodyId, acidify, body, launchGibs: launchGibs, - splatDirection: splatDirection, splatModifier: splatModifier, splatCone: splatCone, - gib: gib, contents: contents); // Shitmed Change - - var ev = new BeingGibbedEvent(gibs); - RaiseLocalEvent(bodyId, ref ev); - - QueueDel(bodyId); - - return gibs; - } - // Shitmed Change Start - public override HashSet GibPart( - EntityUid partId, - BodyPartComponent? part = null, - bool launchGibs = true, - Vector2? splatDirection = null, - float splatModifier = 1, - Angle splatCone = default, - SoundSpecifier? gibSoundOverride = null) - { - if (!Resolve(partId, ref part, logMissing: false) - || TerminatingOrDeleted(partId) - || EntityManager.IsQueuedForDeletion(partId)) - return new HashSet(); - - if (Transform(partId).MapUid is null) - return new HashSet(); - - var gibs = base.GibPart(partId, part, launchGibs: launchGibs, - splatDirection: splatDirection, splatModifier: splatModifier, splatCone: splatCone); - - var ev = new BeingGibbedEvent(gibs); - RaiseLocalEvent(partId, ref ev); - - if (gibs.Any()) - QueueDel(partId); - - return gibs; - } - - public override bool BurnPart(EntityUid partId, BodyPartComponent? part = null) - { - if (!Resolve(partId, ref part, logMissing: false) - || TerminatingOrDeleted(partId) - || EntityManager.IsQueuedForDeletion(partId)) - return false; - - return base.BurnPart(partId, part); - } - protected override void ApplyPartMarkings(EntityUid target, BodyPartAppearanceComponent component) { return; diff --git a/Content.Server/Destructible/DestructibleSystem.cs b/Content.Server/Destructible/DestructibleSystem.cs index 01118db1ff..b39a6fe183 100644 --- a/Content.Server/Destructible/DestructibleSystem.cs +++ b/Content.Server/Destructible/DestructibleSystem.cs @@ -3,7 +3,7 @@ using System.Linq; using Content.Server._DV.Administration; // DeltaV - Admin QOL using Content.Server.Administration.Logs; using Content.Server.Atmos.EntitySystems; -using Content.Server.Body.Systems; +using Content.Server.Body.Systems; // DeltaV Keep body here for shitmed using Content.Server.Construction; using Content.Server.Destructible.Thresholds; using Content.Server.Destructible.Thresholds.Behaviors; @@ -17,6 +17,7 @@ using Content.Shared.Database; using Content.Shared.Destructible; using Content.Shared.Destructible.Thresholds.Triggers; using Content.Shared.FixedPoint; +using Content.Shared.Gibbing; using Content.Shared.Humanoid; using Content.Shared.Trigger.Systems; using JetBrains.Annotations; @@ -35,7 +36,8 @@ namespace Content.Server.Destructible [Dependency] public readonly AtmosphereSystem AtmosphereSystem = default!; [Dependency] public readonly AudioSystem AudioSystem = default!; - [Dependency] public readonly BodySystem BodySystem = default!; + [Dependency] public readonly GibbingSystem Gibbing = default!; + [Dependency] public readonly BodySystem BodySystem = default!; // Delta-V - Keep body here for shitmed [Dependency] public readonly ConstructionSystem ConstructionSystem = default!; [Dependency] public readonly ExplosionSystem ExplosionSystem = default!; [Dependency] public readonly StackSystem StackSystem = default!; diff --git a/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs index 5cc0fb39de..1addf96b62 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs @@ -1,6 +1,5 @@ using Content.Shared.Body.Components; using Content.Shared.Database; -using Content.Shared.Gibbing.Events; // Shitmed Change using JetBrains.Annotations; namespace Content.Server.Destructible.Thresholds.Behaviors @@ -9,18 +8,13 @@ namespace Content.Server.Destructible.Thresholds.Behaviors [DataDefinition] public sealed partial class GibBehavior : IThresholdBehavior { - [DataField] public GibType GibType = GibType.Gib; // Shitmed Change - [DataField] public GibContentsOption GibContents = GibContentsOption.Drop; // Shitmed Change [DataField("recursive")] private bool _recursive = true; public LogImpact Impact => LogImpact.Extreme; public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null) { - if (system.EntityManager.TryGetComponent(owner, out BodyComponent? body)) - { - system.BodySystem.GibBody(owner, _recursive, body, gib: GibType, contents: GibContents); // Shitmed Change - } + system.Gibbing.Gib(owner, _recursive); } } } diff --git a/Content.Server/Forensics/Systems/ForensicsSystem.cs b/Content.Server/Forensics/Systems/ForensicsSystem.cs index f0f8fc2541..787c054b94 100644 --- a/Content.Server/Forensics/Systems/ForensicsSystem.cs +++ b/Content.Server/Forensics/Systems/ForensicsSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.DoAfter; using Content.Shared.Forensics; using Content.Shared.Forensics.Components; using Content.Shared.Forensics.Systems; +using Content.Shared.Gibbing; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Inventory; @@ -40,7 +41,7 @@ namespace Content.Server.Forensics // The solution entities are spawned on MapInit as well, so we have to wait for that to be able to set the DNA in the bloodstream correctly without ResolveSolution failing SubscribeLocalEvent(OnDNAInit, after: new[] { typeof(BloodstreamSystem) }); - SubscribeLocalEvent(OnBeingGibbed); + SubscribeLocalEvent(OnBeingGibbed); SubscribeLocalEvent(OnMeleeHit); SubscribeLocalEvent(OnRehydrated); SubscribeLocalEvent(OnAfterInteract, after: new[] { typeof(AbsorbentSystem) }); @@ -94,14 +95,14 @@ namespace Content.Server.Forensics } } - private void OnBeingGibbed(EntityUid uid, ForensicsComponent component, BeingGibbedEvent args) + private void OnBeingGibbed(Entity ent, ref GibbedBeforeDeletionEvent args) { string dna = Loc.GetString("forensics-dna-unknown"); - if (TryComp(uid, out DnaComponent? dnaComp) && dnaComp.DNA != null) + if (TryComp(ent, out DnaComponent? dnaComp) && dnaComp.DNA != null) dna = dnaComp.DNA; - foreach (EntityUid part in args.GibbedParts) + foreach (var part in args.Giblets) { var partComp = EnsureComp(part); partComp.DNAs.Add(dna); diff --git a/Content.Server/Gibbing/Systems/GibOnRoundEndSystem.cs b/Content.Server/Gibbing/Systems/GibOnRoundEndSystem.cs index d23832984f..8736908da6 100644 --- a/Content.Server/Gibbing/Systems/GibOnRoundEndSystem.cs +++ b/Content.Server/Gibbing/Systems/GibOnRoundEndSystem.cs @@ -2,12 +2,12 @@ using Content.Shared.Gibbing.Components; using Content.Shared.Mind; using Content.Shared.Objectives.Systems; -using Content.Server.Body.Systems; +using Content.Shared.Gibbing; namespace Content.Server.Gibbing.Systems; public sealed class GibOnRoundEndSystem : EntitySystem { - [Dependency] private readonly BodySystem _body = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly SharedMindSystem _mind = default!; [Dependency] private readonly SharedObjectivesSystem _objectives = default!; @@ -49,7 +49,7 @@ public sealed class GibOnRoundEndSystem : EntitySystem if (gibComp.SpawnProto != null) SpawnAtPosition(gibComp.SpawnProto, Transform(uid).Coordinates); - _body.GibBody(uid, splatModifier: 5f); + _gibbing.Gib(uid); } } } diff --git a/Content.Server/Guardian/GuardianSystem.cs b/Content.Server/Guardian/GuardianSystem.cs index 5f2597afef..16907dda8d 100644 --- a/Content.Server/Guardian/GuardianSystem.cs +++ b/Content.Server/Guardian/GuardianSystem.cs @@ -1,9 +1,9 @@ -using Content.Server.Body.Systems; using Content.Server.Popups; using Content.Shared.Actions; using Content.Shared.Damage.Systems; using Content.Shared.DoAfter; using Content.Shared.Examine; +using Content.Shared.Gibbing; using Content.Shared.Guardian; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; @@ -31,7 +31,7 @@ namespace Content.Server.Guardian [Dependency] private readonly SharedActionsSystem _actionSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; @@ -130,7 +130,7 @@ namespace Content.Server.Guardian // Ensure held items are dropped before deleting guardian. if (HasComp(guardian)) - _bodySystem.GibBody(component.HostedGuardian.Value); + _gibbing.Gib(component.HostedGuardian.Value); QueueDel(guardian); QueueDel(component.ActionEntity); diff --git a/Content.Server/ImmovableRod/ImmovableRodSystem.cs b/Content.Server/ImmovableRod/ImmovableRodSystem.cs index 646b5c97bb..a06d521a3b 100644 --- a/Content.Server/ImmovableRod/ImmovableRodSystem.cs +++ b/Content.Server/ImmovableRod/ImmovableRodSystem.cs @@ -5,6 +5,7 @@ using Content.Server.Popups; using Content.Shared.Body.Components; using Content.Shared.Damage.Systems; using Content.Shared.Examine; +using Content.Shared.Gibbing; using Content.Shared.Popups; using Robust.Shared.Audio.Systems; using Robust.Shared.Map; @@ -20,7 +21,7 @@ public sealed class ImmovableRodSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; @@ -125,7 +126,7 @@ public sealed class ImmovableRodSystem : EntitySystem return; } - _bodySystem.GibBody(ent, body: body); + _gibbing.Gib(ent); return; } diff --git a/Content.Server/Implants/ImplantedSystem.cs b/Content.Server/Implants/ImplantedSystem.cs index 7851758730..be477119a0 100644 --- a/Content.Server/Implants/ImplantedSystem.cs +++ b/Content.Server/Implants/ImplantedSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Body.Events; +using Content.Shared.Gibbing; using Content.Shared.Implants.Components; using Content.Shared.Storage; using Robust.Shared.Containers; @@ -11,7 +12,7 @@ public sealed partial class ImplanterSystem { SubscribeLocalEvent(OnImplantedInit); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnGibbed); + SubscribeLocalEvent(OnGibbed); } private void OnImplantedInit(Entity ent, ref ComponentInit args) @@ -26,7 +27,7 @@ public sealed partial class ImplanterSystem _container.CleanContainer(ent.Comp.ImplantContainer); } - private void OnGibbed(Entity ent, ref BeingGibbedEvent args) + private void OnGibbed(Entity ent, ref GibbedBeforeDeletionEvent args) { // Drop the storage implant contents before the implants are deleted by the body being gibbed foreach (var implant in ent.Comp.ImplantContainer.ContainedEntities) diff --git a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs index 39a3ecb7bb..29c4d65d5b 100644 --- a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs @@ -1,9 +1,8 @@ -using Content.Server.Body.Systems; -using Content.Shared.Administration.Logs; -using Content.Shared.Body.Components; +using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Destructible; using Content.Shared.DoAfter; +using Content.Shared.Gibbing; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Kitchen; @@ -24,7 +23,7 @@ namespace Content.Server.Kitchen.EntitySystems; public sealed class SharpSystem : EntitySystem { - [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly SharedDestructibleSystem _destructibleSystem = default!; [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; @@ -134,7 +133,7 @@ public sealed class SharpSystem : EntitySystem args.Args.User, popupType); - _bodySystem.GibBody(args.Args.Target.Value); // does nothing if ent can't be gibbed + _gibbing.Gib(args.Args.Target.Value); // does nothing if ent can't be gibbed _destructibleSystem.DestroyEntity(args.Args.Target.Value); args.Handled = true; diff --git a/Content.Server/Materials/MaterialReclaimerSystem.cs b/Content.Server/Materials/MaterialReclaimerSystem.cs index 15ff93833d..7af39b84a1 100644 --- a/Content.Server/Materials/MaterialReclaimerSystem.cs +++ b/Content.Server/Materials/MaterialReclaimerSystem.cs @@ -4,7 +4,6 @@ using Content.Server.Ghost; using Content.Server.Popups; using Content.Server.Stack; using Content.Server.Wires; -using Content.Shared.Body.Systems; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; @@ -25,6 +24,7 @@ using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; using System.Linq; +using Content.Shared.Gibbing; using Content.Shared.Humanoid; namespace Content.Server.Materials; @@ -39,7 +39,7 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem [Dependency] private readonly OpenableSystem _openable = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!; - [Dependency] private readonly SharedBodySystem _body = default!; //bobby + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly PuddleSystem _puddle = default!; [Dependency] private readonly StackSystem _stack = default!; [Dependency] private readonly SharedMindSystem _mind = default!; @@ -112,7 +112,7 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem Filter.PvsExcept(victim, entityManager: EntityManager), true); - _body.GibBody(victim, true); + _gibbing.Gib(victim); _appearance.SetData(entity.Owner, RecyclerVisuals.Bloody, true); args.Handled = true; } @@ -193,7 +193,7 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem _adminLogger.Add(LogType.Gib, logImpact, $"{ToPrettyString(item):victim} was gibbed by {ToPrettyString(uid):entity} "); if (component.ReclaimSolutions) SpawnChemicalsFromComposition(uid, item, completion, false, component, xform); - _body.GibBody(item, true); + _gibbing.Gib(item); _appearance.SetData(uid, RecyclerVisuals.Bloody, true); } else diff --git a/Content.Server/Mind/TransferMindOnGibSystem.cs b/Content.Server/Mind/TransferMindOnGibSystem.cs index ff71fa0560..81ebf96a87 100644 --- a/Content.Server/Mind/TransferMindOnGibSystem.cs +++ b/Content.Server/Mind/TransferMindOnGibSystem.cs @@ -1,5 +1,5 @@ using System.Linq; -using Content.Shared.Body.Events; +using Content.Shared.Gibbing; using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Tag; @@ -21,19 +21,19 @@ public sealed class TransferMindOnGibSystem : EntitySystem /// public override void Initialize() { - SubscribeLocalEvent(OnGib); + SubscribeLocalEvent(OnGib); } - private void OnGib(EntityUid uid, TransferMindOnGibComponent component, BeingGibbedEvent args) + private void OnGib(Entity ent, ref GibbedBeforeDeletionEvent args) { - if (!_mindSystem.TryGetMind(uid, out var mindId, out var mind)) + if (!_mindSystem.TryGetMind(ent, out var mindId, out var mind)) return; - var validParts = args.GibbedParts.Where(p => _tag.HasTag(p, component.TargetTag)).ToHashSet(); + var validParts = args.Giblets.Where(p => _tag.HasTag(p, ent.Comp.TargetTag)).ToHashSet(); if (!validParts.Any()) return; - var ent = _random.Pick(validParts); - _mindSystem.TransferTo(mindId, ent, mind: mind); + var transfer = _random.Pick(validParts); + _mindSystem.TransferTo(mindId, transfer, mind: mind); } } diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs index 9ef26fd0ea..d135e7c7eb 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs @@ -1004,7 +1004,7 @@ public sealed partial class ShuttleSystem { _logger.Add(LogType.Gib, LogImpact.Extreme, $"{ToPrettyString(ent):player} got gibbed by the shuttle" + $" {ToPrettyString(uid)} arriving from FTL at {xform.Coordinates:coordinates}"); - var gibs = _bobby.GibBody(ent, body: mob); + var gibs = _gibbing.Gib(ent); _immuneEnts.UnionWith(gibs); continue; } diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.cs index 86b97c40a6..43607ea1ea 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.cs @@ -1,5 +1,4 @@ using Content.Server.Administration.Logs; -using Content.Server.Body.Systems; using Content.Server.Buckle.Systems; using Content.Server.Parallax; using Content.Server.Procedural; @@ -9,6 +8,7 @@ using Content.Server.Station.Systems; using Content.Server.Stunnable; using Content.Shared.Buckle.Components; using Content.Shared.Damage.Systems; +using Content.Shared.Gibbing; using Content.Shared.Light.Components; using Content.Shared.Movement.Events; using Content.Shared.Salvage; @@ -42,7 +42,7 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly BiomeSystem _biomes = default!; - [Dependency] private readonly BodySystem _bobby = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly BuckleSystem _buckle = default!; [Dependency] private readonly DamageableSystem _damageSys = default!; [Dependency] private readonly DockingSystem _dockSystem = default!; diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs index 3a32e55665..73fd14c4e9 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs @@ -1,6 +1,7 @@ using Content.Server.Body.Systems; using Content.Server.Stack; using Content.Shared.Body.Components; +using Content.Shared.Gibbing; using Content.Shared.Storage.Components; using Content.Shared.Whitelist; using Content.Shared.Xenoarchaeology.Equipment; @@ -14,7 +15,7 @@ namespace Content.Server.Xenoarchaeology.Equipment.Systems; public sealed class ArtifactCrusherSystem : SharedArtifactCrusherSystem { [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly BodySystem _body = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly StackSystem _stack = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; diff --git a/Content.Server/_Shitmed/Destructible/Thresholds/Behaviors/GibPartBehavior.cs b/Content.Server/_Shitmed/Destructible/Thresholds/Behaviors/GibPartBehavior.cs index abbbd0928a..a2bd729129 100644 --- a/Content.Server/_Shitmed/Destructible/Thresholds/Behaviors/GibPartBehavior.cs +++ b/Content.Server/_Shitmed/Destructible/Thresholds/Behaviors/GibPartBehavior.cs @@ -2,7 +2,7 @@ using Content.Shared.Body.Components; using Content.Shared.Body.Part; using JetBrains.Annotations; -// Leaving this one in the default namespace because I am afraid to test it +// Leaving this one in the default namespace because I am afraid to test it // in the Shitmed namespace lmao. namespace Content.Server.Destructible.Thresholds.Behaviors; diff --git a/Content.Shared/Body/Events/BeingGibbedEvent.cs b/Content.Shared/Body/Events/BeingGibbedEvent.cs deleted file mode 100644 index 7ab34f2e18..0000000000 --- a/Content.Shared/Body/Events/BeingGibbedEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Content.Shared.Body.Events; - -/// -/// Raised when a body gets gibbed, before it is deleted. -/// -[ByRefEvent] -public readonly record struct BeingGibbedEvent(HashSet GibbedParts); diff --git a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs index e86fd0c06b..2bce22c045 100644 --- a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs +++ b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs @@ -11,6 +11,7 @@ using Content.Shared.EntityEffects.Effects.Solution; using Content.Shared.FixedPoint; using Content.Shared.Fluids; using Content.Shared.Forensics.Components; +using Content.Shared.Gibbing; using Content.Shared.HealthExaminable; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; @@ -50,7 +51,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem SubscribeLocalEvent>(OnReactionAttempt); SubscribeLocalEvent(OnDamageChanged); SubscribeLocalEvent(OnHealthBeingExamined); - SubscribeLocalEvent(OnBeingGibbed); + SubscribeLocalEvent(OnBeingGibbed); SubscribeLocalEvent(OnApplyMetabolicMultiplier); SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(OnMetabolismExclusion); @@ -262,7 +263,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem } } - private void OnBeingGibbed(Entity ent, ref BeingGibbedEvent args) + private void OnBeingGibbed(Entity ent, ref GibbedBeforeDeletionEvent args) { SpillAllSolutions(ent.AsNullable()); } diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs index 69b7ac7023..102f1015d3 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs @@ -5,9 +5,7 @@ using Content.Shared.Body.Organ; using Content.Shared.Body.Part; using Content.Shared.Body.Prototypes; using Content.Shared.DragDrop; -using Content.Shared.Gibbing.Components; -using Content.Shared.Gibbing.Events; -using Content.Shared.Gibbing.Systems; +using Content.Shared.Gibbing; using Content.Shared.Inventory; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; @@ -42,7 +40,6 @@ public partial class SharedBodySystem */ // [Dependency] private readonly InventorySystem _inventory = default!; // Shitmed - Declared in SharedBodySystem.cs - [Dependency] private readonly GibbingSystem _gibbingSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly ItemSlotsSystem _slots = default!; // Shitmed Change @@ -62,6 +59,8 @@ public partial class SharedBodySystem SubscribeLocalEvent(OnProfileLoadFinished); // Shitmed change SubscribeLocalEvent(OnBeingEquippedAttempt); // Shitmed Change + SubscribeLocalEvent(OnBeingGibbed); + SubscribeLocalEvent(OnPartBeingGibbed); // Shitmed Change } private void OnBodyInserted(Entity ent, ref EntInsertedIntoContainerMessage args) @@ -309,152 +308,51 @@ public partial class SharedBodySystem } } - public virtual HashSet GibBody( - EntityUid bodyId, - bool acidify = false, - BodyComponent? body = null, - bool launchGibs = true, - Vector2? splatDirection = null, - float splatModifier = 1, - Angle splatCone = default, - SoundSpecifier? gibSoundOverride = null, - // Shitmed Change - GibType gib = GibType.Gib, - GibContentsOption contents = GibContentsOption.Drop) + private void OnBeingGibbed(Entity ent, ref BeingGibbedEvent args) { - var gibs = new HashSet(); - - if (!Resolve(bodyId, ref body, logMissing: false)) - return gibs; - - var root = GetRootPartOrNull(bodyId, body); - if (root != null && TryComp(root.Value.Entity, out GibbableComponent? gibbable)) - { - gibSoundOverride ??= gibbable.GibSound; - } - var parts = GetBodyChildren(bodyId, body).ToArray(); - gibs.EnsureCapacity(parts.Length); + var parts = GetBodyChildren(ent, ent).ToArray(); + args.Giblets.EnsureCapacity(args.Giblets.Capacity + parts.Length); foreach (var part in parts) { - - _gibbingSystem.TryGibEntityWithRef(bodyId, part.Id, gib, contents, ref gibs, // Shitmed Change - playAudio: false, launchGibs: true, launchDirection: splatDirection, launchImpulse: GibletLaunchImpulse * splatModifier, - launchImpulseVariance: GibletLaunchImpulseVariance, launchCone: splatCone); - - if (!acidify) - continue; - foreach (var organ in GetPartOrgans(part.Id, part.Component)) { - _gibbingSystem.TryGibEntityWithRef(bodyId, organ.Id, GibType.Drop, GibContentsOption.Skip, - ref gibs, playAudio: false, launchImpulse: GibletLaunchImpulse * splatModifier, - launchImpulseVariance:GibletLaunchImpulseVariance, launchCone: splatCone); + args.Giblets.Add(organ.Id); } + PredictedQueueDel(part.Id); } - var bodyTransform = Transform(bodyId); - _audioSystem.PlayPredicted(gibSoundOverride, bodyTransform.Coordinates, null); - - // Begin DeltaV Additions - var ev = new BodyGibbedEvent(gibs); - RaiseLocalEvent(bodyId, ref ev); - // End DeltaV Additions - - if (acidify) - return gibs; - - if (TryComp(bodyId, out var inventory)) + foreach (var item in _inventory.GetHandOrInventoryEntities(ent.Owner)) { - foreach (var item in _inventory.GetHandOrInventoryEntities(bodyId)) - { - SharedTransform.DropNextTo(item, (bodyId, bodyTransform)); - gibs.Add(item); - } + args.Giblets.Add(item); } - return gibs; } // Shitmed Change Start - - public virtual HashSet GibPart( - EntityUid partId, - BodyPartComponent? part = null, - bool launchGibs = true, - Vector2? splatDirection = null, - float splatModifier = 1, - Angle splatCone = default, - SoundSpecifier? gibSoundOverride = null) + private void OnPartBeingGibbed(Entity part, ref BeingGibbedEvent args) { - var gibs = new HashSet(); - - if (!Resolve(partId, ref part, logMissing: false)) - return gibs; - - if (part.Body is { } bodyEnt) + if (part.Comp.Body is { } bodyEnt) { - if (IsPartRoot(bodyEnt, partId, part: part) || !part.CanSever) - return gibs; + if (IsPartRoot(bodyEnt, part, part: part) || !part.Comp.CanSever) + return; - DropSlotContents((partId, part)); - RemovePartChildren((partId, part), bodyEnt); - foreach (var organ in GetPartOrgans(partId, part)) + DropSlotContents(part); + RemovePartChildren(part, bodyEnt); + + var organs = GetPartOrgans(part, part).ToArray(); + args.Giblets.EnsureCapacity(args.Giblets.Capacity + organs.Length); + foreach (var organ in organs) { - _gibbingSystem.TryGibEntityWithRef(bodyEnt, organ.Id, GibType.Drop, GibContentsOption.Skip, - ref gibs, playAudio: false, launchImpulse: GibletLaunchImpulse * splatModifier, - launchImpulseVariance: GibletLaunchImpulseVariance, launchCone: splatCone); + args.Giblets.Add(organ.Id); } - var ev = new BodyPartDroppedEvent((partId, part)); + + var ev = new BodyPartDroppedEvent(part); RaiseLocalEvent(bodyEnt, ref ev); } - _gibbingSystem.TryGibEntityWithRef(partId, partId, GibType.Gib, GibContentsOption.Drop, ref gibs, - playAudio: true, launchGibs: true, launchDirection: splatDirection, launchImpulse: GibletLaunchImpulse * splatModifier, - launchImpulseVariance: GibletLaunchImpulseVariance, launchCone: splatCone); - - - if (HasComp(partId)) + foreach (var item in _inventory.GetHandOrInventoryEntities(part.Owner)) { - foreach (var item in _inventory.GetHandOrInventoryEntities(partId)) - { - SharedTransform.AttachToGridOrMap(item); - gibs.Add(item); - } + args.Giblets.Add(item); } - _audioSystem.PlayPredicted(gibSoundOverride, Transform(partId).Coordinates, null); - return gibs; - } - - public virtual bool BurnPart(EntityUid partId, - BodyPartComponent? part = null) - { - if (!Resolve(partId, ref part, logMissing: false)) - return false; - - if (part.Body is { } bodyEnt) - { - if (IsPartRoot(bodyEnt, partId, part: part)) - return false; - - var gibs = new HashSet(); - // Todo: Kill this in favor of husking. - DropSlotContents((partId, part)); - RemovePartChildren((partId, part), bodyEnt); - foreach (var organ in GetPartOrgans(partId, part)) - _gibbingSystem.TryGibEntityWithRef(bodyEnt, organ.Id, GibType.Drop, GibContentsOption.Skip, - ref gibs, playAudio: false, launchImpulse: GibletLaunchImpulse, launchImpulseVariance: GibletLaunchImpulseVariance); - - _gibbingSystem.TryGibEntityWithRef(partId, partId, GibType.Gib, GibContentsOption.Gib, ref gibs, - playAudio: false, launchGibs: true, launchImpulse: GibletLaunchImpulse, launchImpulseVariance: GibletLaunchImpulseVariance); - - if (HasComp(partId)) - foreach (var item in _inventory.GetHandOrInventoryEntities(partId)) - SharedTransform.AttachToGridOrMap(item); - - QueueDel(partId); - return true; - } - - return false; } private void OnProfileLoadFinished(EntityUid uid, BodyComponent component, ProfileLoadFinishedEvent args) diff --git a/Content.Shared/Devour/DevourSystem.cs b/Content.Shared/Devour/DevourSystem.cs index c63ffb34f1..fc905a1eef 100644 --- a/Content.Shared/Devour/DevourSystem.cs +++ b/Content.Shared/Devour/DevourSystem.cs @@ -1,10 +1,10 @@ using Content.Shared._Goobstation.Devour; using Content.Shared.Actions; -using Content.Shared.Body.Events; using Content.Shared.Body.Systems; using Content.Shared.Chemistry.Components; using Content.Shared.Devour.Components; using Content.Shared.DoAfter; +using Content.Shared.Gibbing; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Popups; @@ -34,7 +34,7 @@ public sealed class DevourSystem : EntitySystem SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnDevourAction); SubscribeLocalEvent(OnDoAfter); - SubscribeLocalEvent(OnGibContents); + SubscribeLocalEvent(OnGibContents); } private void OnStartup(Entity ent, ref ComponentStartup args) @@ -135,13 +135,11 @@ public sealed class DevourSystem : EntitySystem _audioSystem.PlayPredicted(ent.Comp.SoundDevour, ent.Owner, ent.Owner); } - private void OnGibContents(Entity ent, ref BeingGibbedEvent args) + private void OnGibContents(Entity ent, ref GibbedBeforeDeletionEvent args) { if (ent.Comp.StomachStorageWhitelist == null) return; - // For some reason we have two different systems that should handle gibbing, - // and for some another reason GibbingSystem, which should empty all containers, doesn't get involved in this process _containerSystem.EmptyContainer(ent.Comp.Stomach); } } diff --git a/Content.Shared/Gibbing/Components/GibbableComponent.cs b/Content.Shared/Gibbing/Components/GibbableComponent.cs deleted file mode 100644 index 9c7501f028..0000000000 --- a/Content.Shared/Gibbing/Components/GibbableComponent.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Content.Shared.Gibbing.Systems; -using Robust.Shared.Audio; -using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; - -namespace Content.Shared.Gibbing.Components; - -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(GibbingSystem))] -public sealed partial class GibbableComponent : Component -{ - /// - /// Giblet entity prototypes to randomly select from when spawning additional giblets - /// - [DataField, AutoNetworkedField] - public List GibPrototypes = new(); - - /// - /// Number of giblet entities to spawn in addition to entity contents - /// - [DataField, AutoNetworkedField] - public int GibCount; - - /// - /// Sound to be played when this entity is gibbed, only played when playsound is true on the gibbing function - /// - [DataField, AutoNetworkedField] - public SoundSpecifier? GibSound = new SoundCollectionSpecifier("gib", AudioParams.Default.WithVariation(0.025f)); - - /// - /// Max distance giblets can be dropped from an entity when NOT using physics-based scattering - /// - [DataField, AutoNetworkedField] - public float GibScatterRange = 0.3f; -} diff --git a/Content.Shared/Gibbing/Events/GibbingEvents.cs b/Content.Shared/Gibbing/Events/GibbingEvents.cs deleted file mode 100644 index 949b10eab9..0000000000 --- a/Content.Shared/Gibbing/Events/GibbingEvents.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Robust.Shared.Serialization; - -namespace Content.Shared.Gibbing.Events; - - - -/// -/// Called just before we actually gib the target entity -/// -/// The entity being gibed -/// What type of gibbing is occuring -/// Containers we are allow to gib -/// Containers we are allow not allowed to gib -[ByRefEvent] public record struct AttemptEntityContentsGibEvent( - EntityUid Target, - GibContentsOption GibType, - List? AllowedContainers, - List? ExcludedContainers - ); - - -/// -/// Called just before we actually gib the target entity -/// -/// The entity being gibed -/// how many giblets to spawn -/// What type of gibbing is occuring -[ByRefEvent] public record struct AttemptEntityGibEvent(EntityUid Target, int GibletCount, GibType GibType); - -/// -/// Called immediately after we gib the target entity -/// -/// The entity being gibbed -/// Any entities that are spilled out (if any) -[ByRefEvent] public record struct EntityGibbedEvent(EntityUid Target, List DroppedEntities); - -[Serializable, NetSerializable] -public enum GibType : byte -{ - Skip, - Drop, - Gib, -} - -public enum GibContentsOption : byte -{ - Skip, - Drop, - Gib -} diff --git a/Content.Shared/Gibbing/Components/GibOnRoundEndComponent.cs b/Content.Shared/Gibbing/GibOnRoundEndComponent.cs similarity index 100% rename from Content.Shared/Gibbing/Components/GibOnRoundEndComponent.cs rename to Content.Shared/Gibbing/GibOnRoundEndComponent.cs diff --git a/Content.Shared/Gibbing/GibbingSystem.cs b/Content.Shared/Gibbing/GibbingSystem.cs new file mode 100644 index 0000000000..08c8fc268e --- /dev/null +++ b/Content.Shared/Gibbing/GibbingSystem.cs @@ -0,0 +1,84 @@ +using Content.Shared.Destructible; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Audio; +using Robust.Shared.Network; +using Robust.Shared.Physics.Systems; +using Robust.Shared.Random; + +namespace Content.Shared.Gibbing; + +public sealed class GibbingSystem : EntitySystem +{ + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedDestructibleSystem _destructible = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + + private static readonly SoundSpecifier? GibSound = new SoundCollectionSpecifier("gib", AudioParams.Default.WithVariation(0.025f)); + + /// + /// Gibs an entity. + /// + /// The entity to gib. + /// Whether or not to drop giblets. + /// The user gibbing the entity, if any. + /// The set of giblets for this entity, if any. + public HashSet Gib(EntityUid ent, bool dropGiblets = true, EntityUid? user = null) + { + // user is unused because of prediction woes, eventually it'll be used for audio + + // BodySystem handles prediction rather poorly and causes client-sided bugs when we gib on the client + // This guard can be removed once it is gone and replaced by a prediction-safe system. + if (!_net.IsServer) + return new(); + + if (!_destructible.DestroyEntity(ent)) + return new(); + + _audio.PlayPvs(GibSound, ent); + + var gibbed = new HashSet(); + var beingGibbed = new BeingGibbedEvent(gibbed); + RaiseLocalEvent(ent, ref beingGibbed); + + if (dropGiblets) + { + foreach (var giblet in gibbed) + { + _transform.DropNextTo(giblet, ent); + FlingDroppedEntity(giblet); + } + } + + var beforeDeletion = new GibbedBeforeDeletionEvent(gibbed); + RaiseLocalEvent(ent, ref beforeDeletion); + + return gibbed; + } + + private const float GibletLaunchImpulse = 8; + private const float GibletLaunchImpulseVariance = 3; + + private void FlingDroppedEntity(EntityUid target) + { + var impulse = GibletLaunchImpulse + _random.NextFloat(GibletLaunchImpulseVariance); + var scatterVec = _random.NextAngle().ToVec() * impulse; + _physics.ApplyLinearImpulse(target, scatterVec); + } +} + +/// +/// Raised on an entity when it is being gibbed. +/// +/// If a component wants to provide giblets to scatter, add them to this hashset. +[ByRefEvent] +public readonly record struct BeingGibbedEvent(HashSet Giblets); + +/// +/// Raised on an entity when it is about to be deleted after being gibbed. +/// +/// The set of giblets this entity produced. +[ByRefEvent] +public readonly record struct GibbedBeforeDeletionEvent(HashSet Giblets); diff --git a/Content.Shared/Gibbing/Systems/GibbingSystem.cs b/Content.Shared/Gibbing/Systems/GibbingSystem.cs deleted file mode 100644 index 9eaadbb970..0000000000 --- a/Content.Shared/Gibbing/Systems/GibbingSystem.cs +++ /dev/null @@ -1,344 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Numerics; -using Content.Shared.Gibbing.Components; -using Content.Shared.Gibbing.Events; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Containers; -using Robust.Shared.Map; -using Robust.Shared.Physics.Systems; -using Robust.Shared.Prototypes; -using Robust.Shared.Random; - -namespace Content.Shared.Gibbing.Systems; - -public sealed class GibbingSystem : EntitySystem -{ - [Dependency] private readonly SharedContainerSystem _containerSystem = default!; - [Dependency] private readonly SharedTransformSystem _transformSystem = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!; - [Dependency] private readonly IRobustRandom _random = default!; - - //TODO: (future optimization) implement a system that "caps" giblet entities by deleting the oldest ones once we reach a certain limit, customizable via CVAR - - /// - /// Attempt to gib a specified entity. That entity must have a gibable components. This method is NOT recursive will only - /// work on the target and any entities it contains (depending on gibContentsOption) - /// - /// The outermost entity we care about, used to place the dropped items - /// Target entity/comp we wish to gib - /// What type of gibing are we performing - /// What type of gibing do we perform on any container contents? - /// a hashset containing all the entities that have been dropped/created - /// How much to multiply the random spread on dropped giblets(if we are dropping them!) - /// Should we play audio - /// A list of containerIds on the target that permit gibing - /// A list of containerIds on the target that DO NOT permit gibing - /// The cone we are launching giblets in (if we are launching them!) - /// Should we launch giblets or just drop them - /// The direction to launch giblets (if we are launching them!) - /// The impluse to launch giblets at(if we are launching them!) - /// /// Should we log if we are missing a gibbableComp when we call this function - /// The variation in giblet launch impulse (if we are launching them!) - /// True if successful, false if not - public bool TryGibEntity(Entity outerEntity, Entity gibbable, GibType gibType, - GibContentsOption gibContentsOption, - out HashSet droppedEntities, bool launchGibs = true, - Vector2 launchDirection = default, float launchImpulse = 0f, float launchImpulseVariance = 0f, - Angle launchCone = default, - float randomSpreadMod = 1.0f, bool playAudio = true, List? allowedContainers = null, - List? excludedContainers = null, bool logMissingGibable = false) - { - droppedEntities = new(); - return TryGibEntityWithRef(outerEntity, gibbable, gibType, gibContentsOption, ref droppedEntities, - launchGibs, launchDirection, launchImpulse, launchImpulseVariance, launchCone, randomSpreadMod, playAudio, - allowedContainers, excludedContainers, logMissingGibable); - } - - - /// - /// Attempt to gib a specified entity. That entity must have a gibable components. This method is NOT recursive will only - /// work on the target and any entities it contains (depending on gibContentsOption) - /// - /// The outermost entity we care about, used to place the dropped items - /// Target entity/comp we wish to gib - /// What type of gibing are we performing - /// What type of gibing do we perform on any container contents? - /// a hashset containing all the entities that have been dropped/created - /// How much to multiply the random spread on dropped giblets(if we are dropping them!) - /// Should we play audio - /// A list of containerIds on the target that permit gibing - /// A list of containerIds on the target that DO NOT permit gibing - /// The cone we are launching giblets in (if we are launching them!) - /// Should we launch giblets or just drop them - /// The direction to launch giblets (if we are launching them!) - /// The impluse to launch giblets at(if we are launching them!) - /// The variation in giblet launch impulse (if we are launching them!) - /// Should we log if we are missing a gibbableComp when we call this function - /// True if successful, false if not - public bool TryGibEntityWithRef( - Entity outerEntity, - Entity gibbable, - GibType gibType, - GibContentsOption gibContentsOption, - ref HashSet droppedEntities, - bool launchGibs = true, - Vector2? launchDirection = null, - float launchImpulse = 0f, - float launchImpulseVariance = 0f, - Angle launchCone = default, - float randomSpreadMod = 1.0f, - bool playAudio = true, - List? allowedContainers = null, - List? excludedContainers = null, - bool logMissingGibable = false) - { - if (!Resolve(gibbable, ref gibbable.Comp, logMissing: false)) - { - DropEntity(gibbable, (outerEntity, Transform(outerEntity)), randomSpreadMod, ref droppedEntities, - launchGibs, launchDirection, launchImpulse, launchImpulseVariance, launchCone); - if (logMissingGibable) - { - Log.Warning($"{ToPrettyString(gibbable)} does not have a GibbableComponent! " + - $"This is not required but may cause issues contained items to not be dropped."); - } - - return false; - } - - if (gibType == GibType.Skip && gibContentsOption == GibContentsOption.Skip) - return true; - if (launchGibs) - { - randomSpreadMod = 0; - } - - HashSet validContainers = new(); - var gibContentsAttempt = - new AttemptEntityContentsGibEvent(gibbable, gibContentsOption, allowedContainers, excludedContainers); - RaiseLocalEvent(gibbable, ref gibContentsAttempt); - - foreach (var container in _containerSystem.GetAllContainers(gibbable)) - { - var valid = true; - if (allowedContainers != null) - valid = allowedContainers.Contains(container.ID); - if (excludedContainers != null) - valid = valid && !excludedContainers.Contains(container.ID); - if (valid) - validContainers.Add(container); - } - - switch (gibContentsOption) - { - case GibContentsOption.Skip: - break; - case GibContentsOption.Drop: - { - foreach (var container in validContainers) - { - foreach (var ent in container.ContainedEntities) - { - DropEntity(new Entity(ent, null), outerEntity, randomSpreadMod, - ref droppedEntities, launchGibs, - launchDirection, launchImpulse, launchImpulseVariance, launchCone); - } - } - - break; - } - case GibContentsOption.Gib: - { - foreach (var container in validContainers) - { - foreach (var ent in container.ContainedEntities) - { - GibEntity(new Entity(ent, null), outerEntity, randomSpreadMod, - ref droppedEntities, launchGibs, - launchDirection, launchImpulse, launchImpulseVariance, launchCone); - } - } - - break; - } - } - - switch (gibType) - { - case GibType.Skip: - break; - case GibType.Drop: - { - DropEntity(gibbable, outerEntity, randomSpreadMod, ref droppedEntities, launchGibs, - launchDirection, launchImpulse, launchImpulseVariance, launchCone); - break; - } - case GibType.Gib: - { - GibEntity(gibbable, outerEntity, randomSpreadMod, ref droppedEntities, launchGibs, - launchDirection, launchImpulse, launchImpulseVariance, launchCone); - break; - } - } - - if (playAudio) - { - _audioSystem.PlayPredicted(gibbable.Comp.GibSound, outerEntity, null); - } - - if (gibType == GibType.Gib) - PredictedQueueDel(gibbable.Owner); - return true; - } - - private void DropEntity(Entity gibbable, Entity parent, float randomSpreadMod, - ref HashSet droppedEntities, bool flingEntity, Vector2? scatterDirection, float scatterImpulse, - float scatterImpulseVariance, Angle scatterCone) - { - var gibCount = 0; - if (Resolve(gibbable, ref gibbable.Comp, logMissing: false)) - { - gibCount = gibbable.Comp.GibCount; - } - - if (!Resolve(parent, ref parent.Comp, logMissing: false)) - return; - - var gibAttemptEvent = new AttemptEntityGibEvent(gibbable, gibCount, GibType.Drop); - RaiseLocalEvent(gibbable, ref gibAttemptEvent); - switch (gibAttemptEvent.GibType) - { - case GibType.Skip: - return; - case GibType.Gib: - GibEntity(gibbable, parent, randomSpreadMod, ref droppedEntities, flingEntity, scatterDirection, - scatterImpulse, scatterImpulseVariance, scatterCone, deleteTarget: false); - return; - } - - _transformSystem.DropNextTo(gibbable.Owner, parent); - _transformSystem.SetWorldRotation(gibbable, _random.NextAngle()); - droppedEntities.Add(gibbable); - if (flingEntity) - { - FlingDroppedEntity(gibbable, scatterDirection, scatterImpulse, scatterImpulseVariance, scatterCone); - } - - var gibbedEvent = new EntityGibbedEvent(gibbable, new List {gibbable}); - RaiseLocalEvent(gibbable, ref gibbedEvent); - } - - private List GibEntity(Entity gibbable, Entity parent, - float randomSpreadMod, - ref HashSet droppedEntities, bool flingEntity, Vector2? scatterDirection, float scatterImpulse, - float scatterImpulseVariance, Angle scatterCone, bool deleteTarget = true) - { - var localGibs = new List(); - var gibCount = 0; - var gibProtoCount = 0; - if (Resolve(gibbable, ref gibbable.Comp, logMissing: false)) - { - gibCount = gibbable.Comp.GibCount; - gibProtoCount = gibbable.Comp.GibPrototypes.Count; - } - - if (!Resolve(parent, ref parent.Comp, logMissing: false)) - return []; - - var gibAttemptEvent = new AttemptEntityGibEvent(gibbable, gibCount, GibType.Drop); - RaiseLocalEvent(gibbable, ref gibAttemptEvent); - switch (gibAttemptEvent.GibType) - { - case GibType.Skip: - return localGibs; - case GibType.Drop: - DropEntity(gibbable, parent, randomSpreadMod, ref droppedEntities, flingEntity, - scatterDirection, scatterImpulse, scatterImpulseVariance, scatterCone); - localGibs.Add(gibbable); - return localGibs; - } - - if (gibbable.Comp != null && gibProtoCount > 0) - { - if (flingEntity) - { - for (var i = 0; i < gibAttemptEvent.GibletCount; i++) - { - if (!TryCreateRandomGiblet(gibbable.Comp, parent.Comp.Coordinates, false, out var giblet, - randomSpreadMod)) - continue; - FlingDroppedEntity(giblet.Value, scatterDirection, scatterImpulse, scatterImpulseVariance, - scatterCone); - droppedEntities.Add(giblet.Value); - } - } - else - { - for (var i = 0; i < gibAttemptEvent.GibletCount; i++) - { - if (TryCreateRandomGiblet(gibbable.Comp, parent.Comp.Coordinates, false, out var giblet, - randomSpreadMod)) - droppedEntities.Add(giblet.Value); - } - } - } - - _transformSystem.AttachToGridOrMap(gibbable, Transform(gibbable)); - if (flingEntity) - { - FlingDroppedEntity(gibbable, scatterDirection, scatterImpulse, scatterImpulseVariance, scatterCone); - } - - var gibbedEvent = new EntityGibbedEvent(gibbable, localGibs); - RaiseLocalEvent(gibbable, ref gibbedEvent); - if (deleteTarget) - PredictedQueueDel(gibbable.Owner); - return localGibs; - } - - - public bool TryCreateRandomGiblet(Entity gibbable, [NotNullWhen(true)] out EntityUid? gibletEntity, - float randomSpreadModifier = 1.0f, bool playSound = true) - { - gibletEntity = null; - return Resolve(gibbable, ref gibbable.Comp) && TryCreateRandomGiblet(gibbable.Comp, Transform(gibbable).Coordinates, - playSound, out gibletEntity, randomSpreadModifier); - } - - public bool TryCreateAndFlingRandomGiblet(Entity gibbable, [NotNullWhen(true)] out EntityUid? gibletEntity, - Vector2 scatterDirection, float force, float scatterImpulseVariance, Angle scatterCone = default, - bool playSound = true) - { - gibletEntity = null; - if (!Resolve(gibbable, ref gibbable.Comp) || - !TryCreateRandomGiblet(gibbable.Comp, Transform(gibbable).Coordinates, playSound, out gibletEntity)) - return false; - FlingDroppedEntity(gibletEntity.Value, scatterDirection, force, scatterImpulseVariance, scatterCone); - return true; - } - - private void FlingDroppedEntity(EntityUid target, Vector2? direction, float impulse, float impulseVariance, - Angle scatterConeAngle) - { - var scatterAngle = direction?.ToAngle() ?? _random.NextAngle(); - var scatterVector = _random.NextAngle(scatterAngle - scatterConeAngle / 2, scatterAngle + scatterConeAngle / 2) - .ToVec() * (impulse + _random.NextFloat(impulseVariance)); - _physicsSystem.ApplyLinearImpulse(target, scatterVector); - } - - private bool TryCreateRandomGiblet(GibbableComponent gibbable, EntityCoordinates coords, - bool playSound, [NotNullWhen(true)] out EntityUid? gibletEntity, float? randomSpreadModifier = null) - { - gibletEntity = null; - if (gibbable.GibPrototypes.Count == 0) - return false; - gibletEntity = Spawn(gibbable.GibPrototypes[_random.Next(0, gibbable.GibPrototypes.Count)], - randomSpreadModifier == null - ? coords - : coords.Offset(_random.NextVector2(gibbable.GibScatterRange * randomSpreadModifier.Value))); - if (playSound) - _audioSystem.PlayPredicted(gibbable.GibSound, coords, null); - _transformSystem.SetWorldRotation(gibletEntity.Value, _random.NextAngle()); - return true; - } -} diff --git a/Content.Shared/Kitchen/SharedKitchenSpikeSystem.cs b/Content.Shared/Kitchen/SharedKitchenSpikeSystem.cs index 59535eee50..6e8dbd19fd 100644 --- a/Content.Shared/Kitchen/SharedKitchenSpikeSystem.cs +++ b/Content.Shared/Kitchen/SharedKitchenSpikeSystem.cs @@ -1,12 +1,12 @@ using Content.Shared.Administration.Logs; using Content.Shared.Body.Part; // DeltaV -using Content.Shared.Body.Systems; using Content.Shared.Damage.Systems; using Content.Shared.Database; using Content.Shared.Destructible; using Content.Shared.DoAfter; using Content.Shared.DragDrop; using Content.Shared.Examine; +using Content.Shared.Gibbing; using Content.Shared.Hands; using Content.Shared.Humanoid; using Content.Shared.IdentityManagement; @@ -44,7 +44,7 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem [Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly SharedBodySystem _bodySystem = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; @@ -339,8 +339,7 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem if (butcherable.SpawnedEntities.Count == 0) { // DeltaV - Gib the body, then body parts, but leave the organs - var gibs = _bodySystem.GibBody(args.Target.Value, true); - + var gibs = _gibbing.Gib(args.Target.Value); foreach (var gib in gibs) { if (HasComp(gib)) diff --git a/Content.Shared/Magic/SharedMagicSystem.cs b/Content.Shared/Magic/SharedMagicSystem.cs index 50ef5f413a..82cae19ec1 100644 --- a/Content.Shared/Magic/SharedMagicSystem.cs +++ b/Content.Shared/Magic/SharedMagicSystem.cs @@ -1,12 +1,11 @@ using System.Numerics; -using Content.Shared.Body.Components; -using Content.Shared.Body.Systems; using Content.Shared.Charges.Components; using Content.Shared.Charges.Systems; using Content.Shared.Coordinates.Helpers; using Content.Shared.Doors.Components; using Content.Shared.Doors.Systems; using Content.Shared.Examine; +using Content.Shared.Gibbing; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; @@ -53,7 +52,7 @@ public abstract class SharedMagicSystem : EntitySystem [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly INetManager _net = default!; - [Dependency] private readonly SharedBodySystem _body = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly SharedDoorSystem _door = default!; [Dependency] private readonly InventorySystem _inventory = default!; @@ -390,11 +389,7 @@ public abstract class SharedMagicSystem : EntitySystem var impulseVector = direction * 10000; _physics.ApplyLinearImpulse(ev.Target, impulseVector); - - if (!TryComp(ev.Target, out var body)) - return; - - _body.GibBody(ev.Target, true, body); + _gibbing.Gib(ev.Target); } // End Touch Spells diff --git a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs index 9c28f5eb04..42da1c6d5d 100644 --- a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs +++ b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Administration.Logs; using Content.Shared.Body.Events; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; +using Content.Shared.Gibbing; using Content.Shared.Hands.EntitySystems; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; @@ -88,7 +89,7 @@ public abstract partial class SharedBorgSystem : EntitySystem SubscribeLocalEvent(OnRefreshMovementSpeedModifiers); SubscribeLocalEvent(OnUIOpenAttempt); SubscribeLocalEvent(OnMobStateChanged); - SubscribeLocalEvent(OnBeingGibbed); + SubscribeLocalEvent(OnBeingGibbed); SubscribeLocalEvent(OnGetDeadIC); SubscribeLocalEvent(OnGetUnrevivableIC); SubscribeLocalEvent(OnPowerCellSlotEmpty); @@ -293,7 +294,7 @@ public abstract partial class SharedBorgSystem : EntitySystem SetActive(chassis, false, user: args.Origin); } - private void OnBeingGibbed(Entity chassis, ref BeingGibbedEvent args) + private void OnBeingGibbed(Entity chassis, ref GibbedBeforeDeletionEvent args) { // Don't use the ItemSlotsSystem eject method since we don't want to play a sound and want we to eject the battery even if the slot is locked. if (TryComp(chassis, out var slotComp) && diff --git a/Content.Shared/Species/Systems/GibActionSystem.cs b/Content.Shared/Species/Systems/GibActionSystem.cs index 85a99fe4e4..26c14f8699 100644 --- a/Content.Shared/Species/Systems/GibActionSystem.cs +++ b/Content.Shared/Species/Systems/GibActionSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Species.Components; using Content.Shared.Actions; using Content.Shared.Body.Systems; +using Content.Shared.Gibbing; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Popups; @@ -12,7 +13,7 @@ namespace Content.Shared.Species; public sealed partial class GibActionSystem : EntitySystem { [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; - [Dependency] private readonly SharedBodySystem _bodySystem = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; @@ -52,8 +53,7 @@ public sealed partial class GibActionSystem : EntitySystem { // When they use the action, gib them. _popupSystem.PopupClient(Loc.GetString(comp.PopupText, ("name", uid)), uid, uid); - // DeltaV acidify: false drops inventory items instead of deleting them - _bodySystem.GibBody(uid, false); + _gibbing.Gib(uid, user: args.Performer); } diff --git a/Content.Shared/Trigger/Systems/GibOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/GibOnTriggerSystem.cs index 237c925716..83b4790af9 100644 --- a/Content.Shared/Trigger/Systems/GibOnTriggerSystem.cs +++ b/Content.Shared/Trigger/Systems/GibOnTriggerSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Body.Systems; +using Content.Shared.Gibbing; using Content.Shared.Inventory; using Content.Shared.Trigger.Components.Effects; @@ -6,7 +6,7 @@ namespace Content.Shared.Trigger.Systems; public sealed class GibOnTriggerSystem : XOnTriggerSystem { - [Dependency] private readonly SharedBodySystem _body = default!; + [Dependency] private readonly GibbingSystem _gibbing = default!; [Dependency] private readonly InventorySystem _inventory = default!; protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) @@ -20,7 +20,7 @@ public sealed class GibOnTriggerSystem : XOnTriggerSystem } } - _body.GibBody(target, true); + _gibbing.Gib(target, user: args.User); args.Handled = true; } } diff --git a/Resources/Prototypes/Body/Organs/Animal/animal.yml b/Resources/Prototypes/Body/Organs/Animal/animal.yml index 643a086c80..f9cf8b7fcd 100644 --- a/Resources/Prototypes/Body/Organs/Animal/animal.yml +++ b/Resources/Prototypes/Body/Organs/Animal/animal.yml @@ -1,5 +1,5 @@ - type: entity - id: BaseAnimalOrganUnGibbable + id: BaseAnimalOrgan parent: BaseItem abstract: true components: @@ -23,13 +23,6 @@ tags: - Meat -- type: entity - id: BaseAnimalOrgan - parent: BaseAnimalOrganUnGibbable - abstract: true - components: - - type: Gibbable - - type: entity id: OrganAnimalLungs parent: BaseAnimalOrgan diff --git a/Resources/Prototypes/Body/Organs/human.yml b/Resources/Prototypes/Body/Organs/human.yml index 923289fc47..1881aade70 100644 --- a/Resources/Prototypes/Body/Organs/human.yml +++ b/Resources/Prototypes/Body/Organs/human.yml @@ -1,5 +1,5 @@ - type: entity - id: BaseHumanOrganUnGibbable + id: BaseHumanOrgan parent: BaseItem abstract: true components: @@ -27,16 +27,9 @@ tags: - Meat -- type: entity - id: BaseHumanOrgan - parent: BaseHumanOrganUnGibbable - abstract: true - components: - - type: Gibbable - - type: entity id: OrganHumanBrain - parent: BaseHumanOrganUnGibbable + parent: BaseHumanOrgan name: brain description: "The source of incredible, unending intelligence. Honk." components: diff --git a/Resources/Prototypes/Body/Parts/base.yml b/Resources/Prototypes/Body/Parts/base.yml index 0f9087a94c..75270eeaf8 100644 --- a/Resources/Prototypes/Body/Parts/base.yml +++ b/Resources/Prototypes/Body/Parts/base.yml @@ -19,7 +19,6 @@ path: /Audio/_Shitmed/Medical/Surgery/organ1.ogg endSound: path: /Audio/_Shitmed/Medical/Surgery/organ2.ogg - - type: Gibbable - type: ContainerContainer containers: bodypart: !type:Container diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index d0ddde80d8..8979c908f7 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -440,7 +440,6 @@ damage: 10 behaviors: - !type:GibBehavior - gibContents: Skip # Shitmed Change recursive: false - type: NonSpreaderZombie - type: StepTrigger diff --git a/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml b/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml index 1e53816aa2..6943447f82 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml @@ -40,7 +40,6 @@ damage: 150 behaviors: - !type:GibBehavior # Shitmed Change - gibContents: Skip # Shitmed Change - type: SlowOnDamage #modified speeds because they're so weak speedModifierThresholds: 60: 0.9 diff --git a/Resources/Prototypes/_Shitmed/Body/Organs/Animal/animal.yml b/Resources/Prototypes/_Shitmed/Body/Organs/Animal/animal.yml index ed87d11ae3..273a5375f8 100644 --- a/Resources/Prototypes/_Shitmed/Body/Organs/Animal/animal.yml +++ b/Resources/Prototypes/_Shitmed/Body/Organs/Animal/animal.yml @@ -1,6 +1,6 @@ - type: entity id: OrganAnimalBrain - parent: BaseAnimalOrganUnGibbable + parent: BaseAnimalOrgan name: animal brain description: "Not so intelligence, not so honk." components: