using Content.Server.Administration.Logs;
using Content.Server.Ghost;
using Content.Server.Mind;
using Content.Server.NPC;
using Content.Server.NPC.HTN;
using Content.Server.NPC.Systems;
using Content.Server.Popups;
using Content.Shared.Clothing;
using Content.Shared.Clothing.Components;
using Content.Shared.Database;
using Content.Shared.NPC.Components;
using Content.Shared.NPC.Systems;
using Content.Shared.Players;
using Content.Shared.Popups;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Server.Clothing.Systems;
///
public sealed class CursedMaskSystem : SharedCursedMaskSystem
{
[Dependency] private readonly IAdminLogManager _adminLog = default!;
[Dependency] private readonly GhostSystem _ghostSystem = default!;
[Dependency] private readonly HTNSystem _htn = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly NPCSystem _npc = default!;
[Dependency] private readonly NpcFactionSystem _npcFaction = default!;
[Dependency] private readonly PopupSystem _popup = default!;
// We can't store this info on the component easily
private static readonly ProtoId TakeoverRootTask = "SimpleHostileCompound";
protected override void TryTakeover(Entity ent, EntityUid wearer)
{
if (ent.Comp.CurrentState != CursedMaskExpression.Anger)
return;
if (TryComp(wearer, out var actor) && actor.PlayerSession.GetMind() is { } mind)
{
var session = actor.PlayerSession;
if (!_ghostSystem.OnGhostAttempt(mind, false))
return;
ent.Comp.StolenMind = mind;
_popup.PopupEntity(Loc.GetString("cursed-mask-takeover-popup"), wearer, session, PopupType.LargeCaution);
_adminLog.Add(LogType.Action,
LogImpact.Extreme,
$"{ToPrettyString(wearer):player} had their body taken over and turned into an enemy through the cursed mask {ToPrettyString(ent):entity}");
}
var npcFaction = EnsureComp(wearer);
ent.Comp.OldFactions.Clear();
ent.Comp.OldFactions.UnionWith(npcFaction.Factions);
_npcFaction.ClearFactions((wearer, npcFaction), false);
_npcFaction.AddFaction((wearer, npcFaction), ent.Comp.CursedMaskFaction);
ent.Comp.HasNpc = !EnsureComp(wearer, out var htn);
htn.RootTask = new HTNCompoundTask { Task = TakeoverRootTask };
htn.Blackboard.SetValue(NPCBlackboard.Owner, wearer);
_npc.WakeNPC(wearer, htn);
_htn.Replan(htn);
}
protected override void OnClothingUnequip(Entity ent, ref ClothingGotUnequippedEvent args)
{
// If we are taking off the cursed mask
if (ent.Comp.CurrentState == CursedMaskExpression.Anger)
{
if (ent.Comp.HasNpc)
RemComp(args.Wearer);
var npcFaction = EnsureComp(args.Wearer);
_npcFaction.RemoveFaction((args.Wearer, npcFaction), ent.Comp.CursedMaskFaction, false);
_npcFaction.AddFactions((args.Wearer, npcFaction), ent.Comp.OldFactions);
ent.Comp.HasNpc = false;
ent.Comp.OldFactions.Clear();
if (Exists(ent.Comp.StolenMind))
{
_mind.TransferTo(ent.Comp.StolenMind.Value, args.Wearer);
_adminLog.Add(LogType.Action,
LogImpact.Extreme,
$"{ToPrettyString(args.Wearer):player} was restored to their body after the removal of {ToPrettyString(ent):entity}.");
ent.Comp.StolenMind = null;
}
}
RandomizeCursedMask(ent, args.Wearer);
}
}