// SPDX-FileCopyrightText: 2025 GoobBot // SPDX-FileCopyrightText: 2025 Solstice // SPDX-FileCopyrightText: 2025 SolsticeOfTheWinter // // SPDX-License-Identifier: AGPL-3.0-or-later using Content.Server._Goobstation.Devil.Contract; using Content.Server._Goobstation.Devil.Contract.Revival; using Content.Server._Goobstation.Devil.Grip; using Content.Shared._Goobstation.Devil; using Content.Shared._Goobstation.Devil.Actions; using Content.Shared._Goobstation.Devil.Condemned; using Content.Shared._Goobstation.Devil.Contract; using Content.Shared.IdentityManagement; namespace Content.Server._Goobstation.Devil; public sealed partial class DevilSystem { private void SubscribeAbilities() { SubscribeLocalEvent(OnContractCreated); SubscribeLocalEvent(OnRevivalContractCreated); SubscribeLocalEvent(OnShadowJaunt); SubscribeLocalEvent(OnDevilGrip); SubscribeLocalEvent(OnPossess); } private void OnContractCreated(Entity devil, ref CreateContractEvent args) { if (!TryUseAbility(args)) return; var contract = Spawn(devil.Comp.ContractPrototype, Transform(devil).Coordinates); _hands.TryPickupAnyHand(devil, contract); if (!TryComp(contract, out var contractComponent)) return; contractComponent.ContractOwner = args.Performer; PlayFwooshSound(devil); DoContractFlavor(devil, Identity.Name(devil, EntityManager)); } private void OnRevivalContractCreated(Entity devil, ref CreateRevivalContractEvent args) { if (!TryUseAbility(args)) return; var contract = Spawn(devil.Comp.RevivalContractPrototype, Transform(devil).Coordinates); _hands.TryPickupAnyHand(devil, contract); if (!TryComp(contract, out var contractComponent)) return; contractComponent.ContractOwner = args.Performer; PlayFwooshSound(devil); DoContractFlavor(devil, Identity.Name(devil, EntityManager)); } private void OnShadowJaunt(Entity devil, ref ShadowJauntEvent args) { if (!TryUseAbility(args)) return; Spawn(devil.Comp.JauntAnimationProto, Transform(devil).Coordinates); Spawn(devil.Comp.PentagramEffectProto, Transform(devil).Coordinates); _poly.PolymorphEntity(devil, devil.Comp.JauntEntityProto); } private void OnDevilGrip(Entity devil, ref DevilGripEvent args) { if (!TryUseAbility(args)) return; if (devil.Comp.DevilGrip != null) { foreach (var item in _hands.EnumerateHeld(devil)) { if (HasComp(item)) QueueDel(item); } } var grasp = Spawn(devil.Comp.GripPrototype, Transform(devil).Coordinates); if (!_hands.TryPickupAnyHand(devil, grasp)) QueueDel(grasp); devil.Comp.DevilGrip = args.Action.Owner; } private void OnPossess(Entity devil, ref DevilPossessionEvent args) { if (!TryComp(args.Target, out var condemned) || condemned.SoulOwnedNotDevil) { var message = Loc.GetString("invalid-possession-target"); _popup.PopupEntity(message, devil, devil); return; } if (!TryUseAbility(args)) return; if (devil.Comp.PowerLevel != DevilPowerLevel.None) devil.Comp.PossessionDuration *= (int)devil.Comp.PowerLevel; if (_possession.TryPossessTarget(args.Target, args.Performer, devil.Comp.PossessionDuration, true, polymorphPossessor: true)) { Spawn(devil.Comp.JauntAnimationProto, Transform(args.Target).Coordinates); Spawn(devil.Comp.PentagramEffectProto, Transform(args.Target).Coordinates); } } }