using Content.Shared.Mind; using Content.Shared.Actions; using Content.Shared.Changeling.Components; using Content.Shared.Gibbing; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; namespace Content.Shared.Changeling.Systems; public abstract partial class ChangelingLastResortSystem : EntitySystem { [Dependency] private INetManager _net = default!; [Dependency] private GibbingSystem _gibbing = default!; [Dependency] private SharedMindSystem _mind = default!; [Dependency] private SharedActionsSystem _actions = default!; [Dependency] private DestructionResistanceSystem _destructionResistance = default!; [Dependency] protected SharedAudioSystem Audio = default!; [SubscribeLocalEvent] private void OnTakeOverMapInit(Entity ent, ref MapInitEvent args) { _actions.AddAction(ent, ref ent.Comp.ActionEntity, ent.Comp.Action); } [SubscribeLocalEvent] private void OnTakeOverShutdown(Entity ent, ref ComponentShutdown args) { if (ent.Comp.ActionEntity != null) _actions.RemoveAction(ent.Owner, ent.Comp.ActionEntity); } [SubscribeLocalEvent] private void OnLastResortAction(Entity ent, ref ChangelingLastResortActionEvent args) { if (args.Handled || !_mind.TryGetMind(args.Performer, out var mindId, out var mind)) return; args.Handled = true; Audio.PlayPredicted(ent.Comp.Sound, args.Performer, args.Performer); if (!_net.IsServer) return; // Transfer Mind is unpredictable. var slug = PredictedSpawnAtPosition(ent.Comp.SlugPrototype, Transform(args.Performer).Coordinates); _mind.MakeSentient(slug); _mind.TransferTo(mindId, slug, mind: mind); _destructionResistance.SetEnabled(args.Performer, false); _gibbing.Gib(args.Performer); } } /// /// Raised on a body after a headslug takes it over. /// /// Whether the body should instantly start regen stasis after being taken over. /// Time multiplier for the regen stasis, if one is started. [ByRefEvent] public record struct BodyTakenByHeadslugEvent(EntityUid Target, bool StartStasis = true, float StasisDurationMultiplier = 1f);