Fixes asleep entities not colliding with conveyor belts. (#11521)

This commit is contained in:
keronshb
2022-09-29 20:44:28 -04:00
committed by GitHub
parent 0c020c5c93
commit aed4e78460

View File

@@ -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<ActiveConveyorComponent>(uid);
@@ -101,10 +104,16 @@ 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);
}
/// <summary>
/// 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.
/// </summary>
private void AwakenEntities(ConveyorComponent component)
{
var xformQuery = GetEntityQuery<TransformComponent>();
var bodyQuery = GetEntityQuery<PhysicsComponent>();
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,