diff --git a/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs b/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs index 0e5bd87125..777d238060 100644 --- a/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs @@ -2,37 +2,39 @@ using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces; using Content.Server.Interfaces.GameObjects.Components.Items; +using Content.Server.Utility; using Content.Shared.Atmos; using Content.Shared.GameObjects.Components; using Content.Shared.GameObjects.EntitySystems; -using Content.Shared.Interfaces; using Content.Shared.Interfaces.GameObjects.Components; -using Content.Shared.Utility; using Robust.Server.GameObjects.Components.UserInterface; using Robust.Server.Interfaces.GameObjects; using Robust.Server.Interfaces.Player; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Map; -using Robust.Shared.Utility; -using System; +using Robust.Shared.Maths; using System.Collections.Generic; namespace Content.Server.GameObjects.Components.Atmos { [RegisterComponent] - public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped + public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped, IUse { #pragma warning disable 649 [Dependency] private IServerNotifyManager _notifyManager = default!; + [Dependency] private IMapManager _mapManager = default!; #pragma warning restore 649 private BoundUserInterface _userInterface = default!; private GasAnalyzerDanger _pressureDanger; private float _timeSinceSync; - private const float TimeBetweenSyncs = 10f; + private const float TimeBetweenSyncs = 2f; + private bool _checkPlayer = false; // Check at the player pos or at some other tile? + private GridCoordinates? _position; // The tile that we scanned public override void Initialize() { @@ -49,9 +51,28 @@ namespace Content.Server.GameObjects.Components.Atmos /// /// Call this from other components to open the gas analyzer UI. + /// Uses the player position. /// + /// The session to open the ui for public void OpenInterface(IPlayerSession session) { + _checkPlayer = true; + _position = null; + _userInterface.Open(session); + UpdateUserInterface(); + Resync(); + } + + /// + /// Call this from other components to open the gas analyzer UI. + /// Uses a given position. + /// + /// The session to open the ui for + /// The position to analyze the gas + public void OpenInterface(IPlayerSession session, GridCoordinates pos) + { + _checkPlayer = false; + _position = pos; _userInterface.Open(session); UpdateUserInterface(); Resync(); @@ -59,6 +80,7 @@ namespace Content.Server.GameObjects.Components.Atmos public void CloseInterface(IPlayerSession session) { + _position = null; _userInterface.Close(session); Resync(); } @@ -69,6 +91,7 @@ namespace Content.Server.GameObjects.Components.Atmos if (_timeSinceSync > TimeBetweenSyncs) { Resync(); + UpdateUserInterface(); } } @@ -103,9 +126,35 @@ namespace Content.Server.GameObjects.Components.Atmos private void UpdateUserInterface() { string? error = null; - var gam = EntitySystem.Get().GetGridAtmosphere(Owner.Transform.GridID); - var tile = gam?.GetTile(Owner.Transform.GridPosition).Air; + // Check if the player is still holding the gas analyzer => if not, don't update + foreach (var session in _userInterface.SubscribedSessions) + { + if (session.AttachedEntity == null) + return; + + if (!session.AttachedEntity.TryGetComponent(out IHandsComponent handsComponent)) + return; + + var activeHandEntity = handsComponent?.GetActiveHand?.Owner; + if (activeHandEntity == null || !activeHandEntity.TryGetComponent(out GasAnalyzerComponent gasAnalyzer)) + { + return; + } + } + + var pos = Owner.Transform.GridPosition; + if (!_checkPlayer && _position.HasValue) + { + // Check if position is out of range => don't update + if (!_position.Value.InRange(_mapManager, pos, SharedInteractionSystem.InteractionRange)) + return; + + pos = _position.Value; + } + + var gam = EntitySystem.Get().GetGridAtmosphere(pos.GridID); + var tile = gam?.GetTile(pos).Air; if (tile == null) { error = "No Atmosphere!"; @@ -172,13 +221,21 @@ namespace Content.Server.GameObjects.Components.Atmos void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { + if (!eventArgs.CanReach) + { + _notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("You can't reach there!")); + return; + } + if (eventArgs.User.TryGetComponent(out IActorComponent actor)) { - OpenInterface(actor.playerSession); + OpenInterface(actor.playerSession, eventArgs.ClickLocation); //TODO: show other sprite when ui open? } } + + void IDropped.Dropped(DroppedEventArgs eventArgs) { if (eventArgs.User.TryGetComponent(out IActorComponent actor)) @@ -187,5 +244,16 @@ namespace Content.Server.GameObjects.Components.Atmos //TODO: if other sprite is shown, change again } } + + bool IUse.UseEntity(UseEntityEventArgs eventArgs) + { + if (eventArgs.User.TryGetComponent(out IActorComponent actor)) + { + OpenInterface(actor.playerSession); + //TODO: show other sprite when ui open? + return true; + } + return false; + } } }