diff --git a/Content.Server/Physics/Controllers/ConveyorController.cs b/Content.Server/Physics/Controllers/ConveyorController.cs index bbd924ca2f..e70eec6181 100644 --- a/Content.Server/Physics/Controllers/ConveyorController.cs +++ b/Content.Server/Physics/Controllers/ConveyorController.cs @@ -8,6 +8,7 @@ using Content.Server.Recycling; using Content.Server.Recycling.Components; using Content.Shared.Conveyor; using Content.Shared.Item; +using Content.Shared.Maps; using Content.Shared.Movement.Components; using Content.Shared.Physics; using Robust.Shared.Containers; @@ -30,6 +31,7 @@ namespace Content.Server.Physics.Controllers [Dependency] private readonly GravitySystem _gravity = default!; [Dependency] private readonly RecyclerSystem _recycler = default!; [Dependency] private readonly SignalLinkerSystem _signalSystem = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; public const string ConveyorFixture = "conveyor"; @@ -60,7 +62,8 @@ namespace Content.Server.Physics.Controllers { var otherUid = args.OtherFixture.Body.Owner; - if (args.OtherFixture.Body.BodyType == BodyType.Static) return; + if (args.OtherFixture.Body.BodyType == BodyType.Static) + return; component.Intersecting.Add(otherUid); EnsureComp(uid); @@ -101,9 +104,15 @@ namespace Content.Server.Physics.Controllers if (args.Port == component.OffPort) SetState(component, ConveyorState.Off); else if (args.Port == component.ForwardPort) + { + AwakenEntities(component); SetState(component, ConveyorState.Forward); + } else if (args.Port == component.ReversePort) + { + AwakenEntities(component); SetState(component, ConveyorState.Reverse); + } } private void SetState(ConveyorComponent component, ConveyorState state) @@ -121,6 +130,34 @@ namespace Content.Server.Physics.Controllers UpdateAppearance(component); } + /// + /// Awakens sleeping entities on the conveyor belt's tile when it's turned on. + /// Fixes an issue where non-hard/sleeping entities refuse to wake up + collide if a belt is turned off and on again. + /// + private void AwakenEntities(ConveyorComponent component) + { + var xformQuery = GetEntityQuery(); + var bodyQuery = GetEntityQuery(); + + if (!xformQuery.TryGetComponent(component.Owner, out var xform)) + return; + + var beltTileRef = xform.Coordinates.GetTileRef(EntityManager, _mapManager); + + if (beltTileRef != null) + { + var intersecting = _lookup.GetEntitiesIntersecting(beltTileRef.Value); + + foreach (var entity in intersecting) + { + if (!bodyQuery.TryGetComponent(entity, out var physics)) + continue; + + _physics.WakeBody(physics); + } + } + } + public bool CanRun(ConveyorComponent component) { return component.State != ConveyorState.Off && this.IsPowered(component.Owner, EntityManager); @@ -197,7 +234,8 @@ namespace Content.Server.Physics.Controllers private static Vector2 Convey(Vector2 direction, float speed, float frameTime, Vector2 itemRelative) { - if (speed == 0 || direction.Length == 0) return Vector2.Zero; + if (speed == 0 || direction.Length == 0) + return Vector2.Zero; /* * Basic idea: if the item is not in the middle of the conveyor in the direction that the conveyor is running,