using System; using Content.Server.Administration.Logs; using Content.Server.Doors.Components; using Content.Server.Explosion.Components; using Content.Server.Flash; using Content.Server.Flash.Components; using Content.Server.Projectiles.Components; using Content.Shared.Audio; using Content.Shared.Database; using Content.Shared.Doors; using Content.Shared.Throwing; using JetBrains.Annotations; using Robust.Shared.Audio; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Physics.Dynamics; using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Explosion.EntitySystems { /// /// Raised whenever something is Triggered on the entity. /// public class TriggerEvent : HandledEntityEventArgs { public IEntity Triggered { get; } public EntityUid? User { get; } public TriggerEvent(IEntity triggered, EntityUid? user = null) { Triggered = triggered; User = user; } } [UsedImplicitly] public sealed class TriggerSystem : EntitySystem { [Dependency] private readonly ExplosionSystem _explosions = default!; [Dependency] private readonly FlashSystem _flashSystem = default!; [Dependency] private readonly AdminLogSystem _logSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(HandleCollide); SubscribeLocalEvent(HandleDeleteTrigger); SubscribeLocalEvent(HandleSoundTrigger); SubscribeLocalEvent(HandleExplodeTrigger); SubscribeLocalEvent(HandleFlashTrigger); SubscribeLocalEvent(HandleDoorTrigger); } #region Explosions private void HandleExplodeTrigger(EntityUid uid, ExplodeOnTriggerComponent component, TriggerEvent args) { if (!EntityManager.TryGetComponent(uid, out ExplosiveComponent? explosiveComponent)) return; Explode(uid, explosiveComponent, args.User); } // You really shouldn't call this directly (TODO Change that when ExplosionHelper gets changed). public void Explode(EntityUid uid, ExplosiveComponent component, EntityUid? user = null) { if (component.Exploding) { return; } component.Exploding = true; _explosions.SpawnExplosion(uid, component.DevastationRange, component.HeavyImpactRange, component.LightImpactRange, component.FlashRange, user); EntityManager.QueueDeleteEntity(uid); } #endregion #region Flash private void HandleFlashTrigger(EntityUid uid, FlashOnTriggerComponent component, TriggerEvent args) { if (component.Flashed) return; // TODO Make flash durations sane ffs. _flashSystem.FlashArea(uid, args.User, component.Range, component.Duration * 1000f); component.Flashed = true; } #endregion private void HandleSoundTrigger(EntityUid uid, SoundOnTriggerComponent component, TriggerEvent args) { if (component.Sound == null) return; SoundSystem.Play(Filter.Pvs(component.Owner), component.Sound.GetSound(), AudioHelpers.WithVariation(0.01f)); } private void HandleDeleteTrigger(EntityUid uid, DeleteOnTriggerComponent component, TriggerEvent args) { EntityManager.QueueDeleteEntity(uid); } private void HandleDoorTrigger(EntityUid uid, ToggleDoorOnTriggerComponent component, TriggerEvent args) { if (EntityManager.TryGetComponent(uid, out var door)) { switch (door.State) { case SharedDoorComponent.DoorState.Open: door.Close(); break; case SharedDoorComponent.DoorState.Closed: door.Open(); break; case SharedDoorComponent.DoorState.Closing: case SharedDoorComponent.DoorState.Opening: break; } } } private void HandleCollide(EntityUid uid, TriggerOnCollideComponent component, StartCollideEvent args) { EntityUid? user = null; if (EntityManager.TryGetComponent(uid, out ProjectileComponent projectile)) user = projectile.Shooter; else if (EntityManager.TryGetComponent(uid, out ThrownItemComponent thrown)) user = thrown.Thrower?.Uid; Trigger(component.Owner, user); } public void Trigger(IEntity trigger, EntityUid? user = null) { var triggerEvent = new TriggerEvent(trigger, user); EntityManager.EventBus.RaiseLocalEvent(trigger.Uid, triggerEvent); } public void HandleTimerTrigger(TimeSpan delay, IEntity triggered, EntityUid? user = null) { if (delay.TotalSeconds <= 0) { Trigger(triggered, user); return; } Timer.Spawn(delay, () => { if (triggered.Deleted) return; Trigger(triggered, user); }); } } }