From 8f9642cd965c46b51c31a1e04dda6cf943b0f69e Mon Sep 17 00:00:00 2001 From: Kara D Date: Thu, 30 Jun 2022 22:58:36 -0700 Subject: [PATCH] Fix collisions passing firestacks between mobs --- .../Atmos/Components/FlammableComponent.cs | 7 ++++ .../Atmos/EntitySystems/FlammableSystem.cs | 35 ++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Content.Server/Atmos/Components/FlammableComponent.cs b/Content.Server/Atmos/Components/FlammableComponent.cs index 7c1799cd7184..e7a5fd18fffe 100644 --- a/Content.Server/Atmos/Components/FlammableComponent.cs +++ b/Content.Server/Atmos/Components/FlammableComponent.cs @@ -1,4 +1,5 @@ using Content.Shared.Damage; +using Robust.Shared.Physics.Collision.Shapes; namespace Content.Server.Atmos.Components { @@ -28,5 +29,11 @@ public sealed class FlammableComponent : Component [DataField("damage", required: true)] [ViewVariables(VVAccess.ReadWrite)] public DamageSpecifier Damage = new(); // Empty by default, we don't want any funny NREs. + + /// + /// Used for the fixture created to handle passing firestacks when two flammable objects collide. + /// + [DataField("flammableCollisionShape")] + public IPhysShape FlammableCollisionShape = new PhysShapeCircle() { Radius = 0.35f }; } } diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index f1e0a6cd149d..51d4eb52b465 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.Interaction; +using Content.Shared.Physics; using Content.Shared.Popups; using Content.Shared.Temperature; using Robust.Shared.Physics; @@ -25,6 +26,7 @@ internal sealed class FlammableSystem : EntitySystem [Dependency] private readonly TemperatureSystem _temperatureSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly AlertsSystem _alertsSystem = default!; + [Dependency] private readonly FixtureSystem _fixture = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; private const float MinimumFireStacks = -10f; @@ -32,16 +34,17 @@ internal sealed class FlammableSystem : EntitySystem private const float UpdateTime = 1f; private const float MinIgnitionTemperature = 373.15f; + public const string FlammableFixtureID = "flammable"; private float _timer = 0f; private Dictionary _fireEvents = new(); - // TODO: Port the rest of Flammable. public override void Initialize() { UpdatesAfter.Add(typeof(AtmosphereSystem)); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnInteractUsingEvent); SubscribeLocalEvent(OnCollideEvent); SubscribeLocalEvent(OnIsHotEvent); @@ -60,7 +63,7 @@ private void OnMeleeHit(EntityUid uid, IgniteOnMeleeHitComponent component, Mele flammable.FireStacks += component.FireStacks; Ignite(entity, flammable); } - + } private void IgniteOnCollide(EntityUid uid, IgniteOnCollideComponent component, StartCollideEvent args) @@ -74,13 +77,30 @@ private void IgniteOnCollide(EntityUid uid, IgniteOnCollideComponent component, Ignite(otherFixture, flammable); } + private void OnMapInit(EntityUid uid, FlammableComponent component, MapInitEvent args) + { + // Sets up a fixture for flammable collisions. + // TODO: Should this be generalized into a general non-hard 'effects' fixture or something? I can't think of other use cases for it. + // This doesn't seem great either (lots more collisions generated) but there isn't a better way to solve it either that I can think of. + + if (!TryComp(uid, out var body)) + return; + + _fixture.TryCreateFixture(body, new Fixture(body, component.FlammableCollisionShape) + { + Hard = false, + ID = FlammableFixtureID, + CollisionMask = (int) CollisionGroup.FullTileLayer + }); + } + private void OnInteractUsingEvent(EntityUid uid, FlammableComponent flammable, InteractUsingEvent args) { if (args.Handled) return; var isHotEvent = new IsHotEvent(); - RaiseLocalEvent(args.Used, isHotEvent, false); + RaiseLocalEvent(args.Used, isHotEvent); if (!isHotEvent.IsHot) return; @@ -92,6 +112,12 @@ private void OnInteractUsingEvent(EntityUid uid, FlammableComponent flammable, I private void OnCollideEvent(EntityUid uid, FlammableComponent flammable, StartCollideEvent args) { var otherUid = args.OtherFixture.Body.Owner; + + // Normal hard collisions, though this isn't generally possible since most flammable things are mobs + // which don't collide with one another, shouldn't work here. + if (args.OtherFixture.ID != FlammableFixtureID && args.OurFixture.ID != FlammableFixtureID) + return; + if (!EntityManager.TryGetComponent(otherUid, out FlammableComponent? otherFlammable)) return; @@ -112,7 +138,8 @@ private void OnCollideEvent(EntityUid uid, FlammableComponent flammable, StartCo otherFlammable.FireStacks += flammable.FireStacks; Ignite(otherUid, otherFlammable); } - } else if (otherFlammable.OnFire) + } + else if (otherFlammable.OnFire) { otherFlammable.FireStacks /= 2; flammable.FireStacks += otherFlammable.FireStacks;