using Content.Server.Administration; using Content.Server.Chat.Systems; using Content.Server.Popups; using Content.Server.Speech.Muting; using Content.Shared.Actions; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Robust.Server.Console; using Robust.Server.GameObjects; namespace Content.Server.Mobs; /// /// Handles performing crit-specific actions. /// public sealed class CritMobActionsSystem : EntitySystem { [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly DeathgaspSystem _deathgasp = default!; [Dependency] private readonly IServerConsoleHost _host = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly QuickDialogSystem _quickDialog = default!; private const int MaxLastWordsLength = 30; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnSuccumb); SubscribeLocalEvent(OnFakeDeath); SubscribeLocalEvent(OnLastWords); } private void OnSuccumb(EntityUid uid, MobStateActionsComponent component, CritSuccumbEvent args) { if (!TryComp(uid, out var actor) || !_mobState.IsCritical(uid)) return; _host.ExecuteCommand(actor.PlayerSession, "ghost"); args.Handled = true; } private void OnFakeDeath(EntityUid uid, MobStateActionsComponent component, CritFakeDeathEvent args) { if (!_mobState.IsCritical(uid)) return; if (HasComp(uid)) { _popupSystem.PopupEntity(Loc.GetString("fake-death-muted"), uid, uid); return; } args.Handled = _deathgasp.Deathgasp(uid); } private void OnLastWords(EntityUid uid, MobStateActionsComponent component, CritLastWordsEvent args) { if (!TryComp(uid, out var actor)) return; _quickDialog.OpenDialog(actor.PlayerSession, Loc.GetString("action-name-crit-last-words"), "", (string lastWords) => { // Intentionally does not check for muteness if (actor.PlayerSession.AttachedEntity != uid || !_mobState.IsCritical(uid)) return; if (lastWords.Length > MaxLastWordsLength) { lastWords = lastWords.Substring(0, MaxLastWordsLength); } lastWords += "..."; _chat.TrySendInGameICMessage(uid, lastWords, InGameICChatType.Whisper, ChatTransmitRange.Normal, ignoreActionBlocker: true); _host.ExecuteCommand(actor.PlayerSession, "ghost"); }); args.Handled = true; } } /// /// Only applies to mobs in crit capable of ghosting/succumbing /// public sealed partial class CritSuccumbEvent : InstantActionEvent { } /// /// Only applies/has functionality to mobs in crit that have /// public sealed partial class CritFakeDeathEvent : InstantActionEvent { } /// /// Only applies to mobs capable of speaking, as a last resort in crit /// public sealed partial class CritLastWordsEvent : InstantActionEvent { }