From 2eb9937ecba41727112c029785e028fb56cf345c Mon Sep 17 00:00:00 2001 From: metalgearsloth Date: Thu, 15 Aug 2024 17:36:47 +1000 Subject: [PATCH] Move viewsubscriber to shared + handle eye targets Need this stuff for AI. --- .../EntitySystems/ViewSubscriberSystem.cs | 8 ++++ .../Components/Eye/ViewSubscriberComponent.cs | 12 ----- .../EntitySystems/ViewSubscriberSystem.cs | 19 +++----- .../Components/Eye/ViewSubscriberComponent.cs | 11 +++++ .../GameObjects/Systems/SharedEyeSystem.cs | 48 +++++++++++++++++++ .../Systems/SharedViewSubscriberSystem.cs | 26 ++++++++++ 6 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 Robust.Client/GameObjects/EntitySystems/ViewSubscriberSystem.cs delete mode 100644 Robust.Server/GameObjects/Components/Eye/ViewSubscriberComponent.cs create mode 100644 Robust.Shared/GameObjects/Components/Eye/ViewSubscriberComponent.cs create mode 100644 Robust.Shared/GameObjects/Systems/SharedViewSubscriberSystem.cs diff --git a/Robust.Client/GameObjects/EntitySystems/ViewSubscriberSystem.cs b/Robust.Client/GameObjects/EntitySystems/ViewSubscriberSystem.cs new file mode 100644 index 00000000000..dd5833b9daf --- /dev/null +++ b/Robust.Client/GameObjects/EntitySystems/ViewSubscriberSystem.cs @@ -0,0 +1,8 @@ +using Robust.Shared.GameObjects; + +namespace Robust.Client.GameObjects; + +public sealed class ViewSubscriberSystem : SharedViewSubscriberSystem +{ + +} diff --git a/Robust.Server/GameObjects/Components/Eye/ViewSubscriberComponent.cs b/Robust.Server/GameObjects/Components/Eye/ViewSubscriberComponent.cs deleted file mode 100644 index eb078fc7058..00000000000 --- a/Robust.Server/GameObjects/Components/Eye/ViewSubscriberComponent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; -using Robust.Shared.GameObjects; -using Robust.Shared.Player; - -namespace Robust.Server.GameObjects -{ - [RegisterComponent] - internal sealed partial class ViewSubscriberComponent : Component - { - internal readonly HashSet SubscribedSessions = new(); - } -} diff --git a/Robust.Server/GameObjects/EntitySystems/ViewSubscriberSystem.cs b/Robust.Server/GameObjects/EntitySystems/ViewSubscriberSystem.cs index 9784d02f30d..f619278baec 100644 --- a/Robust.Server/GameObjects/EntitySystems/ViewSubscriberSystem.cs +++ b/Robust.Server/GameObjects/EntitySystems/ViewSubscriberSystem.cs @@ -6,22 +6,15 @@ namespace Robust.Server.GameObjects /// /// Entity System that handles subscribing and unsubscribing to PVS views. /// - public sealed class ViewSubscriberSystem : EntitySystem + public sealed class ViewSubscriberSystem : SharedViewSubscriberSystem { - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnViewSubscriberShutdown); - } - /// /// Subscribes the session to get PVS updates from the point of view of the specified entity. /// - public void AddViewSubscriber(EntityUid uid, ICommonSession session) + public override void AddViewSubscriber(EntityUid uid, ICommonSession session) { // If the entity doesn't have the component, it will be added. - var viewSubscriber = EntityManager.EnsureComponent(uid); + var viewSubscriber = EntityManager.EnsureComponent(uid); if (viewSubscriber.SubscribedSessions.Contains(session)) return; // Already subscribed, do nothing else. @@ -35,9 +28,9 @@ public void AddViewSubscriber(EntityUid uid, ICommonSession session) /// /// Unsubscribes the session from getting PVS updates from the point of view of the specified entity. /// - public void RemoveViewSubscriber(EntityUid uid, ICommonSession session) + public override void RemoveViewSubscriber(EntityUid uid, ICommonSession session) { - if(!EntityManager.TryGetComponent(uid, out ViewSubscriberComponent? viewSubscriber)) + if(!EntityManager.TryGetComponent(uid, out Shared.GameObjects.ViewSubscriberComponent? viewSubscriber)) return; // Entity didn't have any subscriptions, do nothing. if (!viewSubscriber.SubscribedSessions.Remove(session)) @@ -47,7 +40,7 @@ public void RemoveViewSubscriber(EntityUid uid, ICommonSession session) RaiseLocalEvent(uid, new ViewSubscriberRemovedEvent(uid, session), true); } - private void OnViewSubscriberShutdown(EntityUid uid, ViewSubscriberComponent component, ComponentShutdown _) + protected override void OnViewSubscriberShutdown(EntityUid uid, ViewSubscriberComponent component, ComponentShutdown _) { foreach (var session in component.SubscribedSessions) { diff --git a/Robust.Shared/GameObjects/Components/Eye/ViewSubscriberComponent.cs b/Robust.Shared/GameObjects/Components/Eye/ViewSubscriberComponent.cs new file mode 100644 index 00000000000..09e84fee9cd --- /dev/null +++ b/Robust.Shared/GameObjects/Components/Eye/ViewSubscriberComponent.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using Robust.Shared.Player; + +namespace Robust.Shared.GameObjects; + +// Not networked because doesn't do anything on client. +[RegisterComponent] +public sealed partial class ViewSubscriberComponent : Component +{ + internal readonly HashSet SubscribedSessions = new(); +} diff --git a/Robust.Shared/GameObjects/Systems/SharedEyeSystem.cs b/Robust.Shared/GameObjects/Systems/SharedEyeSystem.cs index 039201ca8dc..542ae037e44 100644 --- a/Robust.Shared/GameObjects/Systems/SharedEyeSystem.cs +++ b/Robust.Shared/GameObjects/Systems/SharedEyeSystem.cs @@ -2,11 +2,41 @@ using System.Numerics; using Robust.Shared.IoC; using Robust.Shared.Maths; +using Robust.Shared.Player; namespace Robust.Shared.GameObjects; public abstract class SharedEyeSystem : EntitySystem { + [Dependency] private readonly SharedViewSubscriberSystem _views = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnEyePlayerAttached); + SubscribeLocalEvent(OnEyePlayerDetached); + } + + private void OnEyePlayerAttached(Entity ent, ref PlayerAttachedEvent args) + { + var value = ent.Comp.Target; + + if (value != null && TryComp(ent.Owner, out ActorComponent? actorComp)) + { + _views.AddViewSubscriber(value.Value, actorComp.PlayerSession); + } + } + + private void OnEyePlayerDetached(Entity ent, ref PlayerDetachedEvent args) + { + var value = ent.Comp.Target; + + if (value == null && TryComp(ent.Owner, out ActorComponent? actorComp)) + { + _views.RemoveViewSubscriber(ent.Comp.Target!.Value, actorComp.PlayerSession); + } + } + /// /// Refreshes all values for IEye with the component. /// @@ -74,6 +104,10 @@ public void SetRotation(EntityUid uid, Angle rotation, EyeComponent? eyeComponen eyeComponent.Eye.Rotation = rotation; } + /// + /// Sets the eye component as tracking another entity. + /// Will also add the target to view subscribers so they can leave range and still work with PVS. + /// public void SetTarget(EntityUid uid, EntityUid? value, EyeComponent? eyeComponent = null) { if (!Resolve(uid, ref eyeComponent)) @@ -82,6 +116,20 @@ public void SetTarget(EntityUid uid, EntityUid? value, EyeComponent? eyeComponen if (eyeComponent.Target.Equals(value)) return; + // Automatically handle view subs. + if (TryComp(uid, out ActorComponent? actorComp)) + { + if (value != null) + { + _views.AddViewSubscriber(value.Value, actorComp.PlayerSession); + } + else + { + // Should never be null here + _views.RemoveViewSubscriber(eyeComponent.Target!.Value, actorComp.PlayerSession); + } + } + eyeComponent.Target = value; Dirty(uid, eyeComponent); } diff --git a/Robust.Shared/GameObjects/Systems/SharedViewSubscriberSystem.cs b/Robust.Shared/GameObjects/Systems/SharedViewSubscriberSystem.cs new file mode 100644 index 00000000000..28a230ecbc4 --- /dev/null +++ b/Robust.Shared/GameObjects/Systems/SharedViewSubscriberSystem.cs @@ -0,0 +1,26 @@ +using Robust.Shared.Player; + +namespace Robust.Shared.GameObjects; + +public abstract class SharedViewSubscriberSystem : EntitySystem +{ + // NOOP on client + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnViewSubscriberShutdown); + } + + /// + /// Subscribes the session to get PVS updates from the point of view of the specified entity. + /// + public virtual void AddViewSubscriber(EntityUid uid, ICommonSession session) {} + + /// + /// Unsubscribes the session from getting PVS updates from the point of view of the specified entity. + /// + public virtual void RemoveViewSubscriber(EntityUid uid, ICommonSession session) {} + + protected virtual void OnViewSubscriberShutdown(EntityUid uid, ViewSubscriberComponent component, ComponentShutdown _) {} +}