diff --git a/Content.Server/Conveyor/ConveyorSystem.cs b/Content.Server/Conveyor/ConveyorSystem.cs index 6216ccfc0a..f4f586fed2 100644 --- a/Content.Server/Conveyor/ConveyorSystem.cs +++ b/Content.Server/Conveyor/ConveyorSystem.cs @@ -21,7 +21,6 @@ namespace Content.Server.Conveyor public class ConveyorSystem : EntitySystem { [Dependency] private StunSystem _stunSystem = default!; - [Dependency] private IEntityLookup _entityLookup = default!; public override void Initialize() { @@ -111,55 +110,5 @@ namespace Content.Server.Conveyor return true; } - - /// - /// Calculates the angle in which entities on top of this conveyor - /// belt are pushed in - /// - /// - /// The angle when taking into account if the conveyor is reversed - /// - public Angle GetAngle(ConveyorComponent component) - { - var adjustment = component.State == ConveyorState.Reversed ? MathHelper.Pi/2 : -MathHelper.Pi/2; - var radians = MathHelper.DegreesToRadians(component.Angle); - - return new Angle(EntityManager.GetComponent(component.Owner).LocalRotation.Theta + radians + adjustment); - } - - public IEnumerable<(EntityUid, IPhysBody)> GetEntitiesToMove(ConveyorComponent comp) - { - //todo uuuhhh cache this - foreach (var entity in _entityLookup.GetEntitiesIntersecting(comp.Owner, flags: LookupFlags.Approximate)) - { - if (Deleted(entity)) - { - continue; - } - - if (entity == comp.Owner) - { - continue; - } - - if (!EntityManager.TryGetComponent(entity, out IPhysBody? physics) || - physics.BodyType == BodyType.Static || physics.BodyStatus == BodyStatus.InAir || entity.IsWeightless()) - { - continue; - } - - if (EntityManager.HasComponent(entity)) - { - continue; - } - - if (entity.IsInContainer()) - { - continue; - } - - yield return (entity, physics); - } - } } } diff --git a/Content.Server/MachineLinking/System/SignalLinkerSystem.cs b/Content.Server/MachineLinking/System/SignalLinkerSystem.cs index 549731ab9a..88b5f09bd2 100644 --- a/Content.Server/MachineLinking/System/SignalLinkerSystem.cs +++ b/Content.Server/MachineLinking/System/SignalLinkerSystem.cs @@ -256,7 +256,7 @@ namespace Content.Server.MachineLinking.System new SignalReceivedEvent(receiverPort, link.Transmitterport.Signal)); entity.PopupMessageCursor(Loc.GetString("signal-linker-component-linked-port", ("port", receiverPort), - ("machine", receiver))); + ("machine", receiver.Owner))); } } diff --git a/Content.Server/Physics/Controllers/ConveyorController.cs b/Content.Server/Physics/Controllers/ConveyorController.cs index faee4d2ef3..aff5e7b9d4 100644 --- a/Content.Server/Physics/Controllers/ConveyorController.cs +++ b/Content.Server/Physics/Controllers/ConveyorController.cs @@ -1,19 +1,24 @@ using System; using System.Collections.Generic; using Content.Server.Conveyor; -using Content.Server.Recycling.Components; +using Content.Shared.Conveyor; using Content.Shared.Movement.Components; +using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.IoC; +using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; using Robust.Shared.Physics.Controllers; namespace Content.Server.Physics.Controllers { - internal sealed class ConveyorController : VirtualController + public sealed class ConveyorController : VirtualController { + [Dependency] private readonly IEntityLookup _lookup = default!; + [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly ConveyorSystem _conveyor = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; public override void Initialize() { @@ -25,43 +30,110 @@ namespace Content.Server.Physics.Controllers public override void UpdateBeforeSolve(bool prediction, float frameTime) { base.UpdateBeforeSolve(prediction, frameTime); - foreach (var comp in EntityManager.EntityQuery()) + + var conveyed = new HashSet(); + + // TODO: This won't work if someone wants a massive fuckoff conveyor so look at using StartCollide or something. + foreach (var (comp, xform) in EntityManager.EntityQuery()) { - Convey(_conveyor, comp, frameTime); + Convey(comp, xform, conveyed, frameTime); } } - private void Convey(ConveyorSystem system, ConveyorComponent comp, float frameTime) + private void Convey(ConveyorComponent comp, TransformComponent xform, HashSet conveyed, float frameTime) { // Use an event for conveyors to know what needs to run - if (!system.CanRun(comp)) + if (!_conveyor.CanRun(comp)) { return; } - var direction = system.GetAngle(comp).ToVec(); - var entMan = IoCManager.Resolve(); - var ownerPos = entMan.GetComponent(comp.Owner).WorldPosition; + var speed = comp.Speed; - foreach (var (entity, physics) in EntitySystem.Get().GetEntitiesToMove(comp)) + if (speed <= 0f) return; + + var (conveyorPos, conveyorRot) = xform.GetWorldPositionRotation(); + + conveyorRot += comp.Angle; + + if (comp.State == ConveyorState.Reversed) { - var itemRelativeToConveyor = entMan.GetComponent(entity).WorldPosition - ownerPos; - physics.LinearVelocity += Convey(direction, comp.Speed, frameTime, itemRelativeToConveyor); + conveyorRot += MathF.PI; + } + + var direction = conveyorRot.ToWorldVec(); + + foreach (var (entity, transform) in GetEntitiesToMove(comp, xform)) + { + if (!conveyed.Add(entity)) continue; + + var worldPos = transform.WorldPosition; + var itemRelative = conveyorPos - worldPos; + + worldPos += Convey(direction, speed, frameTime, itemRelative); + transform.WorldPosition = worldPos; } } - private Vector2 Convey(Vector2 direction, float speed, float frameTime, Vector2 itemRelativeToConveyor) + 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; + + /* TODO: Figure out how to fix corner cuts. direction = direction.Normalized; var dirNormal = new Vector2(direction.Y, direction.X); - var dot = Vector2.Dot(itemRelativeToConveyor, dirNormal); + var dot = Vector2.Dot(itemRelative, dirNormal); + */ - var velocity = direction * speed * 5; + var velocity = direction * speed; + + return velocity * frameTime; + + /* velocity += dirNormal * speed * -dot; return velocity * frameTime; + */ + } + + public IEnumerable<(EntityUid, TransformComponent)> GetEntitiesToMove(ConveyorComponent comp, TransformComponent xform) + { + if (!_mapManager.TryGetGrid(xform.GridID, out var grid) || + !grid.TryGetTileRef(xform.Coordinates, out var tile)) yield break; + + var tileAABB = _lookup.GetLocalBounds(tile, grid.TileSize).Enlarged(0.01f); + var gridMatrix = Transform(grid.GridEntityId).InvWorldMatrix; + + foreach (var entity in _lookup.GetEntitiesIntersecting(tile)) + { + if (entity == comp.Owner || + Deleted(entity) || + HasComp(entity)) continue; + + if (!TryComp(entity, out PhysicsComponent? physics) || + physics.BodyType == BodyType.Static || + physics.BodyStatus == BodyStatus.InAir || + entity.IsWeightless(physics, entityManager: EntityManager)) + { + continue; + } + + if (_container.IsEntityInContainer(entity)) + { + continue; + } + + // Yes there's still going to be the occasional rounding issue where it stops getting conveyed + // When you fix the corner issue that will fix this anyway. + var transform = Transform(entity); + var gridPos = gridMatrix.Transform(transform.WorldPosition); + var gridAABB = new Box2(gridPos - 0.1f, gridPos + 0.1f); + + if (!tileAABB.Intersects(gridAABB)) continue; + + yield return (entity, transform); + } } } } diff --git a/Resources/Prototypes/Entities/Structures/conveyor.yml b/Resources/Prototypes/Entities/Structures/conveyor.yml index e901582856..8a662675a2 100644 --- a/Resources/Prototypes/Entities/Structures/conveyor.yml +++ b/Resources/Prototypes/Entities/Structures/conveyor.yml @@ -5,20 +5,10 @@ placement: mode: SnapgridCenter components: + - type: Rotatable + rotateWhileAnchored: true - type: Clickable - type: InteractionOutline - - type: Physics - - type: Fixtures - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" - hard: false - layer: - - Opaque - - Impassable - - MobImpassable - - VaultImpassable - type: Transform anchored: true - type: Sprite @@ -66,6 +56,8 @@ id: TwoWayLever name: two way lever description: A two way lever. + placement: + mode: SnapgridCenter components: - type: Clickable - type: InteractionOutline