diff --git a/Robust.Shared/Physics/Events/MassChangedEvent.cs b/Robust.Shared/Physics/Events/MassChangedEvent.cs new file mode 100644 index 00000000000..b7324290466 --- /dev/null +++ b/Robust.Shared/Physics/Events/MassChangedEvent.cs @@ -0,0 +1,28 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.Physics.Components; +using System.Numerics; + +namespace Robust.Shared.Physics.Events; + +/// +/// By-ref directed event raised when the mass or angular inertia or center of mass of a physics body changes. +/// +/// The physics body that changed. +/// The old mass of the physics body. +/// The old angular inertia of the physics body. +/// The old (local) center of mass of the physics body. +[ByRefEvent] +public readonly record struct MassDataChangedEvent( + Entity Entity, + float OldMass, + float OldInertia, + Vector2 OldCenter +) +{ + public float NewMass => Entity.Comp1._mass; + public float NewInertia => Entity.Comp1._inertia; + public Vector2 NewCenter => Entity.Comp1._localCenter; + public bool MassChanged => NewMass != OldMass; + public bool InertiaChanged => NewInertia != OldInertia; + public bool CenterChanged => NewCenter != OldCenter; +} diff --git a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Components.cs b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Components.cs index 73e1b891f04..adecf575f70 100644 --- a/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Components.cs +++ b/Robust.Shared/Physics/Systems/SharedPhysicsSystem.Components.cs @@ -256,6 +256,9 @@ public void ResetMassData(EntityUid uid, FixturesComponent? manager = null, Phys if (!_fixturesQuery.Resolve(uid, ref manager)) return; + var oldMass = body._mass; + var oldInertia = body._inertia; + body._mass = 0.0f; body._invMass = 0.0f; body._inertia = 0.0f; @@ -314,6 +317,12 @@ public void ResetMassData(EntityUid uid, FixturesComponent? manager = null, Phys // Update center of mass velocity. body.LinearVelocity += Vector2Helpers.Cross(body.AngularVelocity, localCenter - oldCenter); Dirty(uid, body); + + if (body._mass == oldMass && body._inertia == oldInertia && oldCenter == localCenter) + return; + + var ev = new MassDataChangedEvent((uid, body, manager), oldMass, oldInertia, oldCenter); + RaiseLocalEvent(uid, ref ev); } public bool SetAngularVelocity(EntityUid uid, float value, bool dirty = true, FixturesComponent? manager = null, PhysicsComponent? body = null)