diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index 7b1def620b..656c247a6a 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -4,7 +4,7 @@ using Content.Server.Administration.Managers; using Content.Server.Administration.UI; using Content.Server.Chemistry.Components.SolutionManager; using Content.Server.Chemistry.EntitySystems; -using Content.Server.Configurable; +using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Server.EUI; using Content.Server.Ghost.Roles; @@ -45,6 +45,7 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly DisposalTubeSystem _disposalTubes = default!; [Dependency] private readonly EuiManager _euiManager = default!; [Dependency] private readonly GhostRoleSystem _ghostRoleSystem = default!; [Dependency] private readonly ArtifactSystem _artifactSystem = default!; @@ -312,14 +313,14 @@ namespace Content.Server.Administration.Systems // Get Disposal tube direction verb if (_groupController.CanCommand(player, "tubeconnections") && - EntityManager.TryGetComponent(args.Target, out var tube)) + EntityManager.TryGetComponent(args.Target, out var tube)) { Verb verb = new() { Text = Loc.GetString("tube-direction-verb-get-data-text"), Category = VerbCategory.Debug, Icon = new SpriteSpecifier.Texture(new ResourcePath("/Textures/Interface/VerbIcons/information.svg.192dpi.png")), - Act = () => tube.PopupDirections(args.User) + Act = () => _disposalTubes.PopupDirections(args.Target, tube, args.User) }; args.Verbs.Add(verb); } diff --git a/Content.Server/Disposal/Tube/Components/DisposalBendComponent.cs b/Content.Server/Disposal/Tube/Components/DisposalBendComponent.cs index 3ef3cf5b2d..caae2e1036 100644 --- a/Content.Server/Disposal/Tube/Components/DisposalBendComponent.cs +++ b/Content.Server/Disposal/Tube/Components/DisposalBendComponent.cs @@ -1,36 +1,7 @@ -using Content.Server.Disposal.Unit.Components; +namespace Content.Server.Disposal.Tube.Components; -namespace Content.Server.Disposal.Tube.Components +[RegisterComponent] +[Access(typeof(DisposalTubeSystem))] +public sealed class DisposalBendComponent : Component { - [RegisterComponent] - [ComponentReference(typeof(IDisposalTubeComponent))] - [ComponentReference(typeof(DisposalTubeComponent))] - public sealed class DisposalBendComponent : DisposalTubeComponent - { - public override string ContainerId => "DisposalBend"; - - [DataField("sideDegrees")] - private int _sideDegrees = -90; - - protected override Direction[] ConnectableDirections() - { - var direction = IoCManager.Resolve().GetComponent(Owner).LocalRotation; - var side = new Angle(MathHelper.DegreesToRadians(direction.Degrees + _sideDegrees)); - - return new[] {direction.GetDir(), side.GetDir()}; - } - - public override Direction NextDirection(DisposalHolderComponent holder) - { - var directions = ConnectableDirections(); - var previousDF = holder.PreviousDirectionFrom; - - if (previousDF == Direction.Invalid) - { - return directions[0]; - } - - return previousDF == directions[0] ? directions[1] : directions[0]; - } - } } diff --git a/Content.Server/Disposal/Tube/Components/DisposalEntryComponent.cs b/Content.Server/Disposal/Tube/Components/DisposalEntryComponent.cs index e6c3fcf8e2..a9fc1ae4cf 100644 --- a/Content.Server/Disposal/Tube/Components/DisposalEntryComponent.cs +++ b/Content.Server/Disposal/Tube/Components/DisposalEntryComponent.cs @@ -6,14 +6,12 @@ using Content.Server.Disposal.Unit.EntitySystems; namespace Content.Server.Disposal.Tube.Components { [RegisterComponent] - [ComponentReference(typeof(IDisposalTubeComponent))] - [ComponentReference(typeof(DisposalTubeComponent))] - public sealed class DisposalEntryComponent : DisposalTubeComponent + [Access(typeof(DisposalTubeSystem), typeof(DisposalUnitSystem))] + public sealed class DisposalEntryComponent : Component { [Dependency] private readonly IEntityManager _entMan = default!; private const string HolderPrototypeId = "DisposalHolder"; - public override string ContainerId => "DisposalEntry"; public bool TryInsert(DisposalUnitComponent from, IEnumerable? tags = default) { @@ -31,25 +29,7 @@ namespace Content.Server.Disposal.Tube.Components if (tags != default) holderComponent.Tags.UnionWith(tags); - return EntitySystem.Get().EnterTube((holderComponent).Owner, Owner, holderComponent, null, this); - } - - protected override Direction[] ConnectableDirections() - { - return new[] {_entMan.GetComponent(Owner).LocalRotation.GetDir()}; - } - - /// - /// Ejects contents when they come from the same direction the entry is facing. - /// - public override Direction NextDirection(DisposalHolderComponent holder) - { - if (holder.PreviousDirectionFrom != Direction.Invalid) - { - return Direction.Invalid; - } - - return ConnectableDirections()[0]; + return EntitySystem.Get().EnterTube((holderComponent).Owner, Owner, holderComponent); } } } diff --git a/Content.Server/Disposal/Tube/Components/DisposalJunctionComponent.cs b/Content.Server/Disposal/Tube/Components/DisposalJunctionComponent.cs index b546a9692f..ca1a4cb585 100644 --- a/Content.Server/Disposal/Tube/Components/DisposalJunctionComponent.cs +++ b/Content.Server/Disposal/Tube/Components/DisposalJunctionComponent.cs @@ -1,45 +1,12 @@ -using System.Linq; -using Content.Server.Disposal.Unit.Components; -using Robust.Shared.Random; +namespace Content.Server.Disposal.Tube.Components; -namespace Content.Server.Disposal.Tube.Components +[RegisterComponent] +[Access(typeof(DisposalTubeSystem))] +[Virtual] +public class DisposalJunctionComponent : Component { - [Virtual] - [RegisterComponent] - [ComponentReference(typeof(IDisposalTubeComponent))] - [ComponentReference(typeof(DisposalTubeComponent))] - public class DisposalJunctionComponent : DisposalTubeComponent - { - public override string ContainerId => "DisposalJunction"; - - [Dependency] private readonly IEntityManager _entMan = default!; - [Dependency] private readonly IRobustRandom _random = default!; - - /// - /// The angles to connect to. - /// - [DataField("degrees")] - private List _degrees = new(); - - protected override Direction[] ConnectableDirections() - { - var direction = _entMan.GetComponent(Owner).LocalRotation; - - return _degrees.Select(degree => new Angle(degree.Theta + direction.Theta).GetDir()).ToArray(); - } - - public override Direction NextDirection(DisposalHolderComponent holder) - { - var next = _entMan.GetComponent(Owner).LocalRotation.GetDir(); - var directions = ConnectableDirections().Skip(1).ToArray(); - - if (holder.PreviousDirectionFrom == Direction.Invalid || - holder.PreviousDirectionFrom == next) - { - return _random.Pick(directions); - } - - return next; - } - } + /// + /// The angles to connect to. + /// + [DataField("degrees")] public List Degrees = new(); } diff --git a/Content.Server/Disposal/Tube/Components/DisposalRouterComponent.cs b/Content.Server/Disposal/Tube/Components/DisposalRouterComponent.cs index 5ac8dd0c7b..1f5214282f 100644 --- a/Content.Server/Disposal/Tube/Components/DisposalRouterComponent.cs +++ b/Content.Server/Disposal/Tube/Components/DisposalRouterComponent.cs @@ -1,4 +1,3 @@ -using Content.Server.Disposal.Unit.Components; using Content.Server.UserInterface; using Robust.Server.GameObjects; using Robust.Shared.Audio; @@ -10,12 +9,9 @@ using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent; namespace Content.Server.Disposal.Tube.Components { [RegisterComponent] - [ComponentReference(typeof(IDisposalTubeComponent))] - [ComponentReference(typeof(DisposalTubeComponent))] + [Access(typeof(DisposalTubeSystem))] public sealed class DisposalRouterComponent : DisposalJunctionComponent { - public override string ContainerId => "DisposalRouter"; - [Dependency] private readonly IEntityManager _entMan = default!; [DataField("tags")] @@ -30,18 +26,6 @@ namespace Content.Server.Disposal.Tube.Components [DataField("clickSound")] private SoundSpecifier _clickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"); - public override Direction NextDirection(DisposalHolderComponent holder) - { - var directions = ConnectableDirections(); - - if (holder.Tags.Overlaps(Tags)) - { - return directions[1]; - } - - return _entMan.GetComponent(Owner).LocalRotation.GetDir(); - } - protected override void Initialize() { base.Initialize(); diff --git a/Content.Server/Disposal/Tube/Components/DisposalTaggerComponent.cs b/Content.Server/Disposal/Tube/Components/DisposalTaggerComponent.cs index a60062fa79..1c37ae25cc 100644 --- a/Content.Server/Disposal/Tube/Components/DisposalTaggerComponent.cs +++ b/Content.Server/Disposal/Tube/Components/DisposalTaggerComponent.cs @@ -10,14 +10,10 @@ using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent; namespace Content.Server.Disposal.Tube.Components { [RegisterComponent] - [ComponentReference(typeof(IDisposalTubeComponent))] - [ComponentReference(typeof(DisposalTubeComponent))] public sealed class DisposalTaggerComponent : DisposalTransitComponent { [Dependency] private readonly IEntityManager _entMan = default!; - public override string ContainerId => "DisposalTagger"; - [ViewVariables(VVAccess.ReadWrite)] [DataField("tag")] public string Tag = ""; @@ -31,12 +27,6 @@ namespace Content.Server.Disposal.Tube.Components [DataField("clickSound")] private SoundSpecifier _clickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"); - public override Direction NextDirection(DisposalHolderComponent holder) - { - holder.Tags.Add(Tag); - return base.NextDirection(holder); - } - protected override void Initialize() { base.Initialize(); diff --git a/Content.Server/Disposal/Tube/Components/DisposalTransitComponent.cs b/Content.Server/Disposal/Tube/Components/DisposalTransitComponent.cs index 984be69018..9753978cd1 100644 --- a/Content.Server/Disposal/Tube/Components/DisposalTransitComponent.cs +++ b/Content.Server/Disposal/Tube/Components/DisposalTransitComponent.cs @@ -1,37 +1,10 @@ -using Content.Server.Disposal.Unit.Components; - namespace Content.Server.Disposal.Tube.Components { // TODO: Different types of tubes eject in random direction with no exit point [RegisterComponent] - [ComponentReference(typeof(IDisposalTubeComponent))] + [Access(typeof(DisposalTubeSystem))] [Virtual] - [ComponentReference(typeof(DisposalTubeComponent))] - public class DisposalTransitComponent : DisposalTubeComponent + public class DisposalTransitComponent : Component { - public override string ContainerId => "DisposalTransit"; - - protected override Direction[] ConnectableDirections() - { - var rotation = IoCManager.Resolve().GetComponent(Owner).LocalRotation; - var opposite = new Angle(rotation.Theta + Math.PI); - - return new[] {rotation.GetDir(), opposite.GetDir()}; - } - - public override Direction NextDirection(DisposalHolderComponent holder) - { - var directions = ConnectableDirections(); - var previousDF = holder.PreviousDirectionFrom; - var forward = directions[0]; - - if (previousDF == Direction.Invalid) - { - return forward; - } - - var backward = directions[1]; - return previousDF == forward ? backward : forward; - } } } diff --git a/Content.Server/Disposal/Tube/Components/DisposalTubeComponent.cs b/Content.Server/Disposal/Tube/Components/DisposalTubeComponent.cs index 44fab27a48..f6bfc00a63 100644 --- a/Content.Server/Disposal/Tube/Components/DisposalTubeComponent.cs +++ b/Content.Server/Disposal/Tube/Components/DisposalTubeComponent.cs @@ -2,24 +2,24 @@ using System.Linq; using Content.Server.Disposal.Unit.Components; using Content.Server.Disposal.Unit.EntitySystems; using Content.Shared.Construction.Components; -using Content.Shared.Disposal.Components; using Content.Shared.Popups; using Robust.Shared.Audio; using Robust.Shared.Containers; -using Robust.Shared.Physics; namespace Content.Server.Disposal.Tube.Components { - public abstract class DisposalTubeComponent : Component, IDisposalTubeComponent + [RegisterComponent] + [Access(typeof(DisposalTubeSystem), typeof(DisposableSystem))] + public sealed class DisposalTubeComponent : Component { - public virtual string ContainerId => "DisposalTube"; + [DataField("containerId")] public string ContainerId { get; set; } = "DisposalTube"; [Dependency] private readonly IEntityManager _entMan = default!; public static readonly TimeSpan ClangDelay = TimeSpan.FromSeconds(0.5); public TimeSpan LastClang; - private bool _connected; + public bool Connected; [DataField("clangSound")] public SoundSpecifier ClangSound = new SoundPathSpecifier("/Audio/Effects/clang.ogg"); /// @@ -28,49 +28,26 @@ namespace Content.Server.Disposal.Tube.Components [ViewVariables] public Container Contents { get; private set; } = default!; - /// - /// The directions that this tube can connect to others from - /// - /// a new array of the directions - protected abstract Direction[] ConnectableDirections(); - - public abstract Direction NextDirection(DisposalHolderComponent holder); - // TODO: Make disposal pipes extend the grid // ??? public void Connect() { - if (_connected) + if (Connected) { return; } - _connected = true; - } - - public bool CanConnect(Direction direction, IDisposalTubeComponent with) - { - if (!_connected) - { - return false; - } - - if (!ConnectableDirections().Contains(direction)) - { - return false; - } - - return true; + Connected = true; } public void Disconnect() { - if (!_connected) + if (!Connected) { return; } - _connected = false; + Connected = false; foreach (var entity in Contents.ContainedEntities.ToArray()) { @@ -83,13 +60,6 @@ namespace Content.Server.Disposal.Tube.Components } } - public void PopupDirections(EntityUid entity) - { - var directions = string.Join(", ", ConnectableDirections()); - - Owner.PopupMessage(entity, Loc.GetString("disposal-tube-component-popup-directions-text", ("directions", directions))); - } - protected override void Initialize() { base.Initialize(); diff --git a/Content.Server/Disposal/Tube/Components/IDisposalTubeComponent.cs b/Content.Server/Disposal/Tube/Components/IDisposalTubeComponent.cs deleted file mode 100644 index 8f798c7920..0000000000 --- a/Content.Server/Disposal/Tube/Components/IDisposalTubeComponent.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Content.Server.Disposal.Unit.Components; -using Robust.Shared.Containers; - -namespace Content.Server.Disposal.Tube.Components -{ - public interface IDisposalTubeComponent : IComponent - { - Container Contents { get; } - - Direction NextDirection(DisposalHolderComponent holder); - bool CanConnect(Direction direction, IDisposalTubeComponent with); - void PopupDirections(EntityUid entity); - } -} diff --git a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs index acade65155..52200e49e3 100644 --- a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs +++ b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs @@ -1,6 +1,9 @@ +using System.Linq; +using System.Text; using Content.Server.Construction.Completions; using Content.Server.Disposal.Tube.Components; using Content.Server.Hands.Components; +using Content.Server.Popups; using Content.Server.UserInterface; using Content.Shared.Destructible; using Content.Shared.Disposal.Components; @@ -9,8 +12,8 @@ using Content.Shared.Popups; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Random; using Robust.Shared.Timing; -using System.Text; namespace Content.Server.Disposal.Tube { @@ -18,7 +21,9 @@ namespace Content.Server.Disposal.Tube { [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; + [Dependency] private readonly PopupSystem _popups = default!; public override void Initialize() { @@ -27,10 +32,153 @@ namespace Content.Server.Disposal.Tube SubscribeLocalEvent(OnAnchorChange); SubscribeLocalEvent(OnRelayMovement); SubscribeLocalEvent(OnBreak); - SubscribeLocalEvent(OnOpenRouterUIAttempt); - SubscribeLocalEvent(OnOpenTaggerUIAttempt); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnDeconstruct); + + SubscribeLocalEvent(OnGetBendConnectableDirections); + SubscribeLocalEvent(OnGetBendNextDirection); + + SubscribeLocalEvent(OnGetEntryConnectableDirections); + SubscribeLocalEvent(OnGetEntryNextDirection); + + SubscribeLocalEvent(OnGetJunctionConnectableDirections); + SubscribeLocalEvent(OnGetJunctionNextDirection); + + SubscribeLocalEvent(OnGetRouterConnectableDirections); + SubscribeLocalEvent(OnGetRouterNextDirection); + + SubscribeLocalEvent(OnGetTransitConnectableDirections); + SubscribeLocalEvent(OnGetTransitNextDirection); + + SubscribeLocalEvent(OnGetTaggerConnectableDirections); + SubscribeLocalEvent(OnGetTaggerNextDirection); + + SubscribeLocalEvent(OnOpenRouterUIAttempt); + SubscribeLocalEvent(OnOpenTaggerUIAttempt); + } + + private void OnGetBendConnectableDirections(EntityUid uid, DisposalBendComponent component, ref GetDisposalsConnectableDirectionsEvent args) + { + var direction = Transform(uid).LocalRotation; + var side = new Angle(MathHelper.DegreesToRadians(direction.Degrees - 90)); + + args.Connectable = new[] {direction.GetDir(), side.GetDir()}; + } + + private void OnGetBendNextDirection(EntityUid uid, DisposalBendComponent component, ref GetDisposalsNextDirectionEvent args) + { + var ev = new GetDisposalsConnectableDirectionsEvent(); + RaiseLocalEvent(uid, ref ev); + + var previousDF = args.Holder.PreviousDirectionFrom; + + if (previousDF == Direction.Invalid) + { + args.Next = ev.Connectable[0]; + return; + } + + args.Next = previousDF == ev.Connectable[0] ? ev.Connectable[1] : ev.Connectable[0]; + } + + private void OnGetEntryConnectableDirections(EntityUid uid, DisposalEntryComponent component, ref GetDisposalsConnectableDirectionsEvent args) + { + args.Connectable = new[] {Transform(uid).LocalRotation.GetDir()}; + } + + private void OnGetEntryNextDirection(EntityUid uid, DisposalEntryComponent component, ref GetDisposalsNextDirectionEvent args) + { + // Ejects contents when they come from the same direction the entry is facing. + if (args.Holder.PreviousDirectionFrom != Direction.Invalid) + { + args.Next = Direction.Invalid; + return; + } + + var ev = new GetDisposalsConnectableDirectionsEvent(); + RaiseLocalEvent(uid, ref ev); + args.Next = ev.Connectable[0]; + } + + private void OnGetJunctionConnectableDirections(EntityUid uid, DisposalJunctionComponent component, ref GetDisposalsConnectableDirectionsEvent args) + { + var direction = Transform(uid).LocalRotation; + + args.Connectable = component.Degrees + .Select(degree => new Angle(degree.Theta + direction.Theta).GetDir()) + .ToArray(); + } + + private void OnGetJunctionNextDirection(EntityUid uid, DisposalJunctionComponent component, ref GetDisposalsNextDirectionEvent args) + { + var next = Transform(uid).LocalRotation.GetDir(); + var ev = new GetDisposalsConnectableDirectionsEvent(); + RaiseLocalEvent(uid, ref ev); + var directions = ev.Connectable.Skip(1).ToArray(); + + if (args.Holder.PreviousDirectionFrom == Direction.Invalid || + args.Holder.PreviousDirectionFrom == next) + { + args.Next = _random.Pick(directions); + return; + } + + args.Next = next; + } + + private void OnGetRouterConnectableDirections(EntityUid uid, DisposalRouterComponent component, ref GetDisposalsConnectableDirectionsEvent args) + { + OnGetJunctionConnectableDirections(uid, component, ref args); + } + + private void OnGetRouterNextDirection(EntityUid uid, DisposalRouterComponent component, ref GetDisposalsNextDirectionEvent args) + { + var ev = new GetDisposalsConnectableDirectionsEvent(); + RaiseLocalEvent(uid, ref ev); + + if (args.Holder.Tags.Overlaps(component.Tags)) + { + args.Next = ev.Connectable[1]; + return; + } + + args.Next = Transform(uid).LocalRotation.GetDir(); + } + + private void OnGetTransitConnectableDirections(EntityUid uid, DisposalTransitComponent component, ref GetDisposalsConnectableDirectionsEvent args) + { + var rotation = Transform(uid).LocalRotation; + var opposite = new Angle(rotation.Theta + Math.PI); + + args.Connectable = new[] {rotation.GetDir(), opposite.GetDir()}; + } + + private void OnGetTransitNextDirection(EntityUid uid, DisposalTransitComponent component, ref GetDisposalsNextDirectionEvent args) + { + var ev = new GetDisposalsConnectableDirectionsEvent(); + RaiseLocalEvent(uid, ref ev); + var previousDF = args.Holder.PreviousDirectionFrom; + var forward = ev.Connectable[0]; + + if (previousDF == Direction.Invalid) + { + args.Next = forward; + return; + } + + var backward = ev.Connectable[1]; + args.Next = previousDF == forward ? backward : forward; + } + + private void OnGetTaggerConnectableDirections(EntityUid uid, DisposalTaggerComponent component, ref GetDisposalsConnectableDirectionsEvent args) + { + OnGetTransitConnectableDirections(uid, component, ref args); + } + + private void OnGetTaggerNextDirection(EntityUid uid, DisposalTaggerComponent component, ref GetDisposalsNextDirectionEvent args) + { + args.Holder.Tags.Add(component.Tag); + OnGetTransitNextDirection(uid, component, ref args); } private void OnDeconstruct(EntityUid uid, DisposalTubeComponent component, ConstructionBeforeDeleteEvent args) @@ -139,7 +287,7 @@ namespace Content.Server.Disposal.Tube } } - public IDisposalTubeComponent? NextTubeFor(EntityUid target, Direction nextDirection, IDisposalTubeComponent? targetTube = null) + public DisposalTubeComponent? NextTubeFor(EntityUid target, Direction nextDirection, DisposalTubeComponent? targetTube = null) { if (!Resolve(target, ref targetTube)) return null; @@ -152,17 +300,17 @@ namespace Content.Server.Disposal.Tube var position = xform.Coordinates; foreach (var entity in grid.GetInDir(position, nextDirection)) { - if (!EntityManager.TryGetComponent(entity, out IDisposalTubeComponent? tube)) + if (!TryComp(entity, out DisposalTubeComponent? tube)) { continue; } - if (!tube.CanConnect(oppositeDirection, targetTube)) + if (!CanConnect(entity, tube, oppositeDirection)) { continue; } - if (!targetTube.CanConnect(nextDirection, tube)) + if (!CanConnect(target, targetTube, nextDirection)) { continue; } @@ -172,5 +320,27 @@ namespace Content.Server.Disposal.Tube return null; } + + + public bool CanConnect(EntityUid tubeId, DisposalTubeComponent tube, Direction direction) + { + if (!tube.Connected) + { + return false; + } + + var ev = new GetDisposalsConnectableDirectionsEvent(); + RaiseLocalEvent(tubeId, ref ev); + return ev.Connectable.Contains(direction); + } + + public void PopupDirections(EntityUid tubeId, DisposalTubeComponent tube, EntityUid recipient) + { + var ev = new GetDisposalsConnectableDirectionsEvent(); + RaiseLocalEvent(tubeId, ref ev); + var directions = string.Join(", ", ev.Connectable); + + _popups.PopupEntity(Loc.GetString("disposal-tube-component-popup-directions-text", ("directions", directions)), tubeId, recipient); + } } } diff --git a/Content.Server/Disposal/Tube/GetDisposalsConnectableDirectionsEvent.cs b/Content.Server/Disposal/Tube/GetDisposalsConnectableDirectionsEvent.cs new file mode 100644 index 0000000000..c2a6fb7075 --- /dev/null +++ b/Content.Server/Disposal/Tube/GetDisposalsConnectableDirectionsEvent.cs @@ -0,0 +1,9 @@ +using Content.Server.Disposal.Unit.Components; + +namespace Content.Server.Disposal.Tube; + +[ByRefEvent] +public record struct GetDisposalsConnectableDirectionsEvent +{ + public Direction[] Connectable; +} diff --git a/Content.Server/Disposal/Tube/GetDisposalsNextDirectionEvent.cs b/Content.Server/Disposal/Tube/GetDisposalsNextDirectionEvent.cs new file mode 100644 index 0000000000..2872a0e6d0 --- /dev/null +++ b/Content.Server/Disposal/Tube/GetDisposalsNextDirectionEvent.cs @@ -0,0 +1,9 @@ +using Content.Server.Disposal.Unit.Components; + +namespace Content.Server.Disposal.Tube; + +[ByRefEvent] +public record struct GetDisposalsNextDirectionEvent(DisposalHolderComponent Holder) +{ + public Direction Next; +} diff --git a/Content.Server/Disposal/TubeConnectionsCommand.cs b/Content.Server/Disposal/TubeConnectionsCommand.cs index 6ead9fb1ea..98f8a2bfe0 100644 --- a/Content.Server/Disposal/TubeConnectionsCommand.cs +++ b/Content.Server/Disposal/TubeConnectionsCommand.cs @@ -1,4 +1,5 @@ using Content.Server.Administration; +using Content.Server.Disposal.Tube; using Content.Server.Disposal.Tube.Components; using Content.Shared.Administration; using Robust.Server.Player; @@ -9,6 +10,8 @@ namespace Content.Server.Disposal [AdminCommand(AdminFlags.Debug)] public sealed class TubeConnectionsCommand : IConsoleCommand { + [Dependency] private readonly IEntityManager _entities = default!; + public string Command => "tubeconnections"; public string Description => Loc.GetString("tube-connections-command-description"); public string Help => Loc.GetString("tube-connections-command-help-text", ("command", Command)); @@ -34,22 +37,21 @@ namespace Content.Server.Disposal return; } - var entityManager = IoCManager.Resolve(); - if (!entityManager.EntityExists(id)) + if (!_entities.EntityExists(id)) { shell.WriteLine(Loc.GetString("shell-could-not-find-entity-with-uid",("uid", id))); return; } - if (!entityManager.TryGetComponent(id, out IDisposalTubeComponent? tube)) + if (!_entities.TryGetComponent(id, out DisposalTubeComponent? tube)) { shell.WriteLine(Loc.GetString("shell-entity-with-uid-lacks-component", ("uid", id), - ("componentName", nameof(IDisposalTubeComponent)))); + ("componentName", nameof(DisposalTubeComponent)))); return; } - tube.PopupDirections(player.AttachedEntity.Value); + _entities.System().PopupDirections(id, tube, player.AttachedEntity.Value); } } } diff --git a/Content.Server/Disposal/Unit/Components/DisposalHolderComponent.cs b/Content.Server/Disposal/Unit/Components/DisposalHolderComponent.cs index aa8b7e5a87..e6fe9998b2 100644 --- a/Content.Server/Disposal/Unit/Components/DisposalHolderComponent.cs +++ b/Content.Server/Disposal/Unit/Components/DisposalHolderComponent.cs @@ -3,13 +3,11 @@ using Content.Server.Disposal.Tube.Components; using Content.Shared.Body.Components; using Content.Shared.Item; using Robust.Shared.Containers; -using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; namespace Content.Server.Disposal.Unit.Components { - // TODO: Add gas [RegisterComponent] public sealed class DisposalHolderComponent : Component, IGasMixtureHolder { @@ -31,7 +29,7 @@ namespace Content.Server.Disposal.Unit.Components public float TimeLeft { get; set; } [ViewVariables] - public IDisposalTubeComponent? PreviousTube { get; set; } + public DisposalTubeComponent? PreviousTube { get; set; } [ViewVariables] public Direction PreviousDirection { get; set; } = Direction.Invalid; @@ -40,7 +38,7 @@ namespace Content.Server.Disposal.Unit.Components public Direction PreviousDirectionFrom => (PreviousDirection == Direction.Invalid) ? Direction.Invalid : PreviousDirection.GetOpposite(); [ViewVariables] - public IDisposalTubeComponent? CurrentTube { get; set; } + public DisposalTubeComponent? CurrentTube { get; set; } // CurrentDirection is not null when CurrentTube isn't null. [ViewVariables] diff --git a/Content.Server/Disposal/Unit/EntitySystems/DisposableSystem.cs b/Content.Server/Disposal/Unit/EntitySystems/DisposableSystem.cs index 8c1a4d376a..0f8d14670f 100644 --- a/Content.Server/Disposal/Unit/EntitySystems/DisposableSystem.cs +++ b/Content.Server/Disposal/Unit/EntitySystems/DisposableSystem.cs @@ -1,14 +1,12 @@ using System.Linq; using Content.Server.Atmos.EntitySystems; -using Content.Server.Disposal.Tube.Components; using Content.Server.Disposal.Tube; +using Content.Server.Disposal.Tube.Components; using Content.Server.Disposal.Unit.Components; using JetBrains.Annotations; -using Robust.Shared.Containers; using Robust.Shared.Map; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Systems; using Robust.Shared.Physics.Components; +using Robust.Shared.Physics.Systems; namespace Content.Server.Disposal.Unit.EntitySystems { @@ -90,7 +88,7 @@ namespace Content.Server.Disposal.Unit.EntitySystems } // Note: This function will cause an ExitDisposals on any failure that does not make an ExitDisposals impossible. - public bool EnterTube(EntityUid holderUid, EntityUid toUid, DisposalHolderComponent? holder = null, TransformComponent? holderTransform = null, IDisposalTubeComponent? to = null, TransformComponent? toTransform = null) + public bool EnterTube(EntityUid holderUid, EntityUid toUid, DisposalHolderComponent? holder = null, TransformComponent? holderTransform = null, DisposalTubeComponent? to = null, TransformComponent? toTransform = null) { if (!Resolve(holderUid, ref holder, ref holderTransform)) return false; @@ -124,7 +122,9 @@ namespace Content.Server.Disposal.Unit.EntitySystems holder.PreviousDirection = holder.CurrentDirection; } holder.CurrentTube = to; - holder.CurrentDirection = to.NextDirection(holder); + var ev = new GetDisposalsNextDirectionEvent(holder); + RaiseLocalEvent(toUid, ref ev); + holder.CurrentDirection = ev.Next; holder.StartingTime = 0.1f; holder.TimeLeft = 0.1f; // Logger.InfoS("c.s.disposal.holder", $"Disposals dir {holder.CurrentDirection}"); @@ -192,7 +192,7 @@ namespace Content.Server.Disposal.Unit.EntitySystems } // Perform remainder of entry process - if (!EnterTube((holder).Owner, nextTube.Owner, holder, null, nextTube, null)) + if (!EnterTube((holder).Owner, nextTube.Owner, holder)) { break; } diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml index 075f538735..e80a01be01 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/pipes.yml @@ -96,6 +96,8 @@ layers: - map: [ "pipe" ] state: conpipe-s + - type: DisposalTube + containerId: DisposalTransit - type: DisposalTransit - type: ContainerContainer containers: @@ -122,6 +124,8 @@ layers: - map: [ "pipe" ] state: conpipe-tagger + - type: DisposalTube + containerId: DisposalTagger - type: DisposalTagger - type: ContainerContainer containers: @@ -154,6 +158,8 @@ layers: - map: [ "pipe" ] state: conpipe-t + - type: DisposalTube + containerId: DisposalEntry - type: DisposalEntry - type: ContainerContainer containers: @@ -187,6 +193,8 @@ layers: - map: [ "pipe" ] state: conpipe-j1s + - type: DisposalTube + containerId: DisposalRouter - type: DisposalRouter degrees: - 0 @@ -232,6 +240,8 @@ layers: - map: [ "pipe" ] state: conpipe-j2s + - type: DisposalTube + containerId: DisposalRouter - type: DisposalRouter degrees: - 0 @@ -269,6 +279,8 @@ - map: [ "pipe" ] state: conpipe-j1 visible: true + - type: DisposalTube + containerId: DisposalJunction - type: DisposalJunction degrees: - 0 @@ -308,6 +320,8 @@ layers: - map: [ "pipe" ] state: conpipe-j2 + - type: DisposalTube + containerId: DisposalJunction - type: DisposalJunction degrees: - 0 @@ -344,6 +358,8 @@ layers: - map: [ "pipe" ] state: conpipe-y + - type: DisposalTube + containerId: DisposalJunction - type: DisposalJunction degrees: - 0 @@ -381,6 +397,8 @@ layers: - map: [ "pipe" ] state: conpipe-c + - type: DisposalTube + containerId: DisposalBend - type: DisposalBend - type: ContainerContainer containers: