diff --git a/Content.Server/Pointing/Components/RoguePointingArrowComponent.cs b/Content.Server/Pointing/Components/RoguePointingArrowComponent.cs index f6ab0364e1..35c813283c 100644 --- a/Content.Server/Pointing/Components/RoguePointingArrowComponent.cs +++ b/Content.Server/Pointing/Components/RoguePointingArrowComponent.cs @@ -1,131 +1,33 @@ -using System.Linq; -using Content.Server.Explosion; +using Content.Server.Pointing.EntitySystems; using Content.Shared.Pointing.Components; using Content.Shared.Sound; -using Robust.Server.GameObjects; -using Robust.Server.Player; -using Robust.Shared.Audio; +using Robust.Shared.Analyzers; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Maths; -using Robust.Shared.Player; -using Robust.Shared.Random; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; -using DrawDepth = Content.Shared.DrawDepth.DrawDepth; namespace Content.Server.Pointing.Components { [RegisterComponent] + [Friend(typeof(RoguePointingSystem))] public class RoguePointingArrowComponent : SharedRoguePointingArrowComponent { - [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IRobustRandom _random = default!; - [ViewVariables] - private IEntity? _chasing; + public IEntity? Chasing; [ViewVariables(VVAccess.ReadWrite)] [DataField("turningDelay")] - private float _turningDelay = 2; - - [ViewVariables(VVAccess.ReadWrite)] - [DataField("chasingDelay")] - private float _chasingDelay = 1; + public float TurningDelay = 2; [ViewVariables(VVAccess.ReadWrite)] [DataField("chasingSpeed")] - private float _chasingSpeed = 5; + public float ChasingSpeed = 5; [ViewVariables(VVAccess.ReadWrite)] [DataField("chasingTime")] - private float _chasingTime = 1; + public float ChasingTime = 1; [DataField("explosionSound")] - private SoundSpecifier _explosionSound = new SoundCollectionSpecifier("explosion"); - - private IEntity? RandomNearbyPlayer() - { - var players = _playerManager - .GetPlayersInRange(Owner.Transform.Coordinates, 15) - .Where(player => player.AttachedEntity != null) - .ToArray(); - - if (players.Length == 0) - { - return null; - } - - return _random.Pick(players).AttachedEntity; - } - - private void UpdateAppearance() - { - if (_chasing == null || - !Owner.TryGetComponent(out AppearanceComponent? appearance)) - { - return; - } - - appearance.SetData(RoguePointingArrowVisuals.Rotation, Owner.Transform.LocalRotation.Degrees); - } - - protected override void Startup() - { - base.Startup(); - - if (Owner.TryGetComponent(out SpriteComponent? sprite)) - { - sprite.DrawDepth = (int) DrawDepth.Overlays; - } - } - - public void Update(float frameTime) - { - _chasing ??= RandomNearbyPlayer(); - - if (_chasing == null) - { - Owner.Delete(); - return; - } - - _turningDelay -= frameTime; - - if (_turningDelay > 0) - { - var difference = _chasing.Transform.WorldPosition - Owner.Transform.WorldPosition; - var angle = difference.ToAngle(); - var adjusted = angle.Degrees + 90; - var newAngle = Angle.FromDegrees(adjusted); - - Owner.Transform.LocalRotation = newAngle; - - UpdateAppearance(); - return; - } - - _chasingDelay -= frameTime; - - Owner.Transform.WorldRotation += Angle.FromDegrees(20); - - UpdateAppearance(); - - var toChased = _chasing.Transform.WorldPosition - Owner.Transform.WorldPosition; - - Owner.Transform.WorldPosition += toChased * frameTime * _chasingSpeed; - - _chasingTime -= frameTime; - - if (_chasingTime > 0) - { - return; - } - - Owner.SpawnExplosion(0, 2, 1, 1); - SoundSystem.Play(Filter.Pvs(Owner), _explosionSound.GetSound(), Owner); - - Owner.Delete(); - } + public SoundSpecifier ExplosionSound = new SoundCollectionSpecifier("explosion"); } } diff --git a/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs b/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs index 3042dc3e94..ef910b3c8c 100644 --- a/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs @@ -1,17 +1,115 @@ -using Content.Server.Pointing.Components; +using System.Linq; +using Content.Server.Explosion; +using Content.Server.Pointing.Components; +using Content.Shared.MobState; +using Content.Shared.Pointing.Components; using JetBrains.Annotations; +using Robust.Server.GameObjects; +using Robust.Server.Player; +using Robust.Shared.Audio; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Player; +using Robust.Shared.Random; +using DrawDepth = Content.Shared.DrawDepth.DrawDepth; namespace Content.Server.Pointing.EntitySystems { [UsedImplicitly] internal sealed class RoguePointingSystem : EntitySystem { + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, RoguePointingArrowComponent component, ComponentStartup args) + { + if (EntityManager.TryGetComponent(uid, out SpriteComponent? sprite)) + { + sprite.DrawDepth = (int) DrawDepth.Overlays; + } + } + + private IEntity? RandomNearbyPlayer(EntityUid uid, RoguePointingArrowComponent? component = null, ITransformComponent? transform = null) + { + if (!Resolve(uid, ref component, ref transform)) + return null; + + var players = _playerManager + .GetPlayersInRange(transform.Coordinates, 15) + .Where(player => player.AttachedEntity != null && player.AttachedEntity.TryGetComponent(out IMobStateComponent? mobStateComponent) && !mobStateComponent.IsDead()) + .ToArray(); + + if (players.Length == 0) + { + return null; + } + + return _random.Pick(players).AttachedEntity; + } + + private void UpdateAppearance(EntityUid uid, RoguePointingArrowComponent? component = null, ITransformComponent? transform = null, AppearanceComponent? appearance = null) + { + if (!Resolve(uid, ref component, ref transform, ref appearance) || component.Chasing == null) + return; + + appearance.SetData(RoguePointingArrowVisuals.Rotation, transform.LocalRotation.Degrees); + } + public override void Update(float frameTime) { - foreach (var component in EntityManager.EntityQuery()) + foreach (var (component, transform) in EntityManager.EntityQuery()) { - component.Update(frameTime); + var uid = component.Owner.Uid; + component.Chasing ??= RandomNearbyPlayer(uid, component, transform); + + if (component.Chasing == null) + { + EntityManager.QueueDeleteEntity(uid); + return; + } + + component.TurningDelay -= frameTime; + + if (component.TurningDelay > 0) + { + var difference = component.Chasing.Transform.WorldPosition - transform.WorldPosition; + var angle = difference.ToAngle(); + var adjusted = angle.Degrees + 90; + var newAngle = Angle.FromDegrees(adjusted); + + transform.LocalRotation = newAngle; + + UpdateAppearance(uid, component, transform); + return; + } + + transform.WorldRotation += Angle.FromDegrees(20); + + UpdateAppearance(uid, component, transform); + + var toChased = component.Chasing.Transform.WorldPosition - transform.WorldPosition; + + transform.WorldPosition += toChased * frameTime * component.ChasingSpeed; + + component.ChasingTime -= frameTime; + + if (component.ChasingTime > 0) + { + return; + } + + component.Owner.SpawnExplosion(0, 2, 1, 1); + SoundSystem.Play(Filter.Pvs(uid, entityManager: EntityManager), component.ExplosionSound.GetSound(), uid); + + EntityManager.QueueDeleteEntity(uid); } } }