diff --git a/Content.Client/Chat/ChatSystem.cs b/Content.Client/Chat/ChatSystem.cs index d91264eab1ab..58b78eb2d0ca 100644 --- a/Content.Client/Chat/ChatSystem.cs +++ b/Content.Client/Chat/ChatSystem.cs @@ -12,6 +12,7 @@ public sealed class ChatSystem : SharedChatSystem { [Dependency] private readonly IChatManager _manager = default!; [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly ExamineSystem _examineSystem = default!; public override void FrameUpdate(float frameTime) { @@ -23,6 +24,8 @@ public override void FrameUpdate(float frameTime) var bubbles = _manager.GetSpeechBubbles(); var playerPos = player != null ? Transform(player.Value).MapPosition : MapCoordinates.Nullspace; + var occluded = player != null && _examineSystem.IsOccluded(player.Value); + foreach (var (ent, bubs) in bubbles) { if (ent == player) @@ -33,7 +36,7 @@ public override void FrameUpdate(float frameTime) var otherPos = Transform(ent).MapPosition; - if (!ExamineSystemShared.InRangeUnOccluded( + if (occluded && !ExamineSystemShared.InRangeUnOccluded( playerPos, otherPos, 0f, (ent, player), predicate)) diff --git a/Content.Client/DoAfter/DoAfterSystem.cs b/Content.Client/DoAfter/DoAfterSystem.cs index c28b79a66446..7ad7701bc1c7 100644 --- a/Content.Client/DoAfter/DoAfterSystem.cs +++ b/Content.Client/DoAfter/DoAfterSystem.cs @@ -5,6 +5,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Graphics; +using Robust.Client.Player; using Robust.Shared.GameStates; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -27,19 +28,18 @@ public sealed class DoAfterSystem : EntitySystem */ [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly ExamineSystemShared _examineSystem = default!; /// /// We'll use an excess time so stuff like finishing effects can show. /// public const float ExcessTime = 0.5f; - private EntityUid? _attachedEntity; - public override void Initialize() { base.Initialize(); UpdatesOutsidePrediction = true; - SubscribeLocalEvent(HandlePlayerAttached); SubscribeNetworkEvent(OnCancelledDoAfter); SubscribeLocalEvent(OnDoAfterStartup); SubscribeLocalEvent(OnDoAfterShutdown); @@ -111,11 +111,6 @@ private void OnCancelledDoAfter(CancelledDoAfterMessage ev) Cancel(doAfter, ev.ID); } - private void HandlePlayerAttached(PlayerAttachSysMessage message) - { - _attachedEntity = message.AttachedEntity; - } - /// /// For handling PVS so we dispose of controls if they go out of range /// @@ -196,17 +191,19 @@ public override void Update(float frameTime) base.Update(frameTime); var currentTime = _gameTiming.CurTime; + var attached = _player.LocalPlayer?.ControlledEntity; // Can't see any I guess? - if (_attachedEntity is not {Valid: true} entity || Deleted(entity)) + if (attached == null || Deleted(attached)) return; // ReSharper disable once ConvertToLocalFunction var predicate = static (EntityUid uid, (EntityUid compOwner, EntityUid? attachedEntity) data) => uid == data.compOwner || uid == data.attachedEntity; + var occluded = _examineSystem.IsOccluded(attached.Value); var viewbox = _eyeManager.GetWorldViewport().Enlarged(2.0f); - var entXform = Transform(entity); + var entXform = Transform(attached.Value); var playerPos = entXform.MapPosition; foreach (var (comp, xform) in EntityManager.EntityQuery(true)) @@ -224,11 +221,12 @@ public override void Update(float frameTime) var range = (compPos.Position - playerPos.Position).Length + 0.01f; - if (comp.Owner != _attachedEntity && + if (occluded && + comp.Owner != attached && !ExamineSystemShared.InRangeUnOccluded( playerPos, compPos, range, - (comp.Owner, _attachedEntity), predicate)) + (comp.Owner, attached), predicate)) { Disable(comp); continue; diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index 4875442f99a4..f92bd879c524 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -20,6 +20,7 @@ public sealed class PopupSystem : SharedPopupSystem [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!; [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly ExamineSystemShared _examineSystem = default!; private readonly List _aliveLabels = new(); @@ -141,6 +142,7 @@ public override void FrameUpdate(float frameTime) // ReSharper disable once ConvertToLocalFunction var predicate = static (EntityUid uid, (EntityUid? compOwner, EntityUid? attachedEntity) data) => uid == data.compOwner || uid == data.attachedEntity; + var occluded = player != null && _examineSystem.IsOccluded(player.Value); for (var i = _aliveLabels.Count - 1; i >= 0; i--) { @@ -161,7 +163,7 @@ public override void FrameUpdate(float frameTime) var otherPos = label.Entity != null ? Transform(label.Entity.Value).MapPosition : label.InitialPos; - if (!ExamineSystemShared.InRangeUnOccluded( + if (occluded && !ExamineSystemShared.InRangeUnOccluded( playerPos, otherPos, 0f, (label.Entity, player), predicate)) diff --git a/Content.Shared/Examine/ExamineSystemShared.cs b/Content.Shared/Examine/ExamineSystemShared.cs index 12073c2e2920..257088dbcb68 100644 --- a/Content.Shared/Examine/ExamineSystemShared.cs +++ b/Content.Shared/Examine/ExamineSystemShared.cs @@ -102,6 +102,14 @@ public float GetExaminerRange(EntityUid examiner, MobStateComponent? mobState = return ExamineRange; } + /// + /// True if occluders are drawn for this entity, otherwise false. + /// + public bool IsOccluded(EntityUid uid) + { + return TryComp(uid, out var eye) && eye.DrawFov; + } + public static bool InRangeUnOccluded(MapCoordinates origin, MapCoordinates other, float range, Ignored? predicate, bool ignoreInsideBlocker = true, IEntityManager? entMan = null) { // No, rider. This is better.