using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.Body.Components; using Content.Server.GameTicking; using Content.Server.Mind.Components; using Content.Shared.Body.Components; using Content.Shared.MobState.Components; using Content.Shared.Movement.EntitySystems; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Timing; namespace Content.Server.Body.Systems { public sealed class BodySystem : EntitySystem { [Dependency] private readonly GameTicker _ticker = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnRelayMoveInput); } private void OnRelayMoveInput(EntityUid uid, BodyComponent component, RelayMoveInputEvent args) { if (EntityManager.TryGetComponent(uid, out var mobState) && mobState.IsDead() && EntityManager.TryGetComponent(uid, out var mind) && mind.HasMind) { if (!mind.Mind!.TimeOfDeath.HasValue) { mind.Mind.TimeOfDeath = _gameTiming.RealTime; } _ticker.OnGhostAttempt(mind.Mind!, true); } } /// /// Returns a list of ValueTuples of and SharedMechanismComponent on each mechanism /// in the given body. /// /// The entity to check for the component on. /// The body to check for mechanisms on. /// The component to check for. public IEnumerable<(T Comp, SharedMechanismComponent Mech)> GetComponentsOnMechanisms(EntityUid uid, SharedBodyComponent? body=null) where T : Component { if (!Resolve(uid, ref body)) yield break; foreach (var (part, _) in body.Parts) foreach (var mechanism in part.Mechanisms) { if (EntityManager.TryGetComponent(mechanism.OwnerUid, out var comp)) yield return (comp, mechanism); } } /// /// Tries to get a list of ValueTuples of and SharedMechanismComponent on each mechanism /// in the given body. /// /// The entity to check for the component on. /// The list of components. /// The body to check for mechanisms on. /// The component to check for. /// Whether any were found. public bool TryGetComponentsOnMechanisms(EntityUid uid, [NotNullWhen(true)] out IEnumerable<(T Comp, SharedMechanismComponent Mech)>? comps, SharedBodyComponent? body=null) where T: Component { if (!Resolve(uid, ref body)) { comps = null; return false; } comps = GetComponentsOnMechanisms(uid, body).ToArray(); if (!comps.Any()) { comps = null; return false; } return true; } } }