diff --git a/Content.Server/Backmen/Abilities/Psionics/Abilities/MindSwapPowerSystem.cs b/Content.Server/Backmen/Abilities/Psionics/Abilities/MindSwapPowerSystem.cs index fd9d646ca51..a0e4b5a7bdd 100644 --- a/Content.Server/Backmen/Abilities/Psionics/Abilities/MindSwapPowerSystem.cs +++ b/Content.Server/Backmen/Abilities/Psionics/Abilities/MindSwapPowerSystem.cs @@ -77,9 +77,11 @@ private void OnPowerUsed(MindSwapPowerActionEvent args) if (HasComp(args.Target)) return; - Swap(args.Performer, args.Target); - _psionics.LogPowerUsed(args.Performer, "mind swap"); + if (Swap(args.Performer, args.Target)) + { + GetTrapped(args.Performer); + } args.Handled = true; } @@ -160,11 +162,6 @@ private void OnGhostAttempt(GhostAttemptHandleEvent args) private void OnSwapInit(EntityUid uid, MindSwappedComponent component, ComponentInit args) { _actions.AddAction(uid, ref component.MindSwapReturn, ActionMindSwapReturn); - if (_actions.TryGetActionData(component.MindSwapReturn, out var action)) - { - _actions.SetCooldown(component.MindSwapReturn, _gameTiming.CurTime, - _gameTiming.CurTime + (TimeSpan) action?.UseDelay!); - } } public bool Swap(EntityUid performer, EntityUid target, bool end = false) diff --git a/Content.Server/Backmen/Abilities/Psionics/Abilities/TelegnosisPowerSystem.cs b/Content.Server/Backmen/Abilities/Psionics/Abilities/TelegnosisPowerSystem.cs index 2afdf4abcc7..14af9d3bf96 100644 --- a/Content.Server/Backmen/Abilities/Psionics/Abilities/TelegnosisPowerSystem.cs +++ b/Content.Server/Backmen/Abilities/Psionics/Abilities/TelegnosisPowerSystem.cs @@ -1,8 +1,12 @@ +using Content.Server.Mind; using Content.Shared.Actions; using Content.Shared.Backmen.Abilities.Psionics; using Content.Shared.Backmen.Psionics.Events; +using Content.Shared.Mind; using Content.Shared.Mind.Components; +using Content.Shared.Mobs; using Content.Shared.StatusEffect; +using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -10,12 +14,11 @@ namespace Content.Server.Backmen.Abilities.Psionics; public sealed class TelegnosisPowerSystem : EntitySystem { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly StatusEffectsSystem _statusEffects = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; - [Dependency] private readonly MindSwapPowerSystem _mindSwap = default!; + [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly TransformSystem _transformSystem = default!; + [Dependency] private readonly MindSwapPowerSystem _mindSwapPowerSystem = default!; public override void Initialize() { @@ -23,19 +26,35 @@ public override void Initialize() SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnPowerUsed); + SubscribeLocalEvent(OnMobStateChanged); + + + SubscribeLocalEvent(OnProjectionInit); + SubscribeLocalEvent(OnProjectionShutdown); + SubscribeLocalEvent(OnPowerReturnUsed); + + + SubscribeLocalEvent(OnMindRemoved); } + private void OnProjectionShutdown(EntityUid uid, TelegnosticProjectionComponent component, ComponentShutdown args) + { + _actions.RemoveAction(uid, component.TelegnosisPowerAction); + } + + private void OnProjectionInit(EntityUid uid, TelegnosticProjectionComponent component, ComponentStartup args) + { + _actions.AddAction(uid, ref component.TelegnosisPowerAction, ActionTelegnosisReturn); + } + [ValidatePrototypeId] private const string ActionTelegnosis = "ActionTelegnosis"; + [ValidatePrototypeId] private const string ActionTelegnosisReturn = "ActionTelegnosisReturn"; private void OnInit(EntityUid uid, TelegnosisPowerComponent component, ComponentInit args) { _actions.AddAction(uid, ref component.TelegnosisPowerAction, ActionTelegnosis); - if (_actions.TryGetActionData(component.TelegnosisPowerAction, out var action) && action?.UseDelay != null) - _actions.SetCooldown(component.TelegnosisPowerAction, _gameTiming.CurTime, - _gameTiming.CurTime + (TimeSpan) action?.UseDelay!); - if (TryComp(uid, out var psionic) && psionic.PsionicAbility == null) psionic.PsionicAbility = component.TelegnosisPowerAction; } @@ -45,11 +64,47 @@ private void OnShutdown(EntityUid uid, TelegnosisPowerComponent component, Compo _actions.RemoveAction(uid, component.TelegnosisPowerAction); } + private void OnMobStateChanged(EntityUid uid, TelegnosisPowerComponent component, MobStateChangedEvent args) + { + if (args.NewMobState != MobState.Dead) + return; + if (component.TelegnosisProjection == null || TerminatingOrDeleted(component.TelegnosisProjection.Value)) + return; + if (!_mindSystem.TryGetMind(uid, out var mindId, out var mind)) + return; + + _mindSwapPowerSystem.GetTrapped(component.TelegnosisProjection.Value); + _mindSystem.UnVisit(mindId, mind); + _mindSystem.TransferTo(mindId, component.TelegnosisProjection, true, false, mind); + } + + private void OnPowerReturnUsed(EntityUid uid, TelegnosticProjectionComponent component, TelegnosisPowerReturnActionEvent args) + { + if ( + !TryComp(args.Performer, out var mindId) || + mindId!.MindId == null || + !TryComp(mindId.MindId.Value, out var mind) + ) + return; + + _mindSystem.UnVisit(mindId.MindId.Value, mind); + QueueDel(args.Performer); + _psionics.LogPowerUsed(uid, "telegnosis"); + args.Handled = true; + } + private void OnPowerUsed(EntityUid uid, TelegnosisPowerComponent component, TelegnosisPowerActionEvent args) { - var projection = Spawn(component.Prototype, Transform(uid).Coordinates); - Transform(projection).AttachToGridOrMap(); - _mindSwap.Swap(uid, projection); + if (!_mindSystem.TryGetMind(args.Performer, out var mindId, out var mind)) + return; + + var projection = Spawn(component.Prototype, Transform(args.Performer).Coordinates); + _transformSystem.AttachToGridOrMap(projection); + + _mindSystem.Visit(mindId, projection, mind); + //_actions.GrantActions(projection, new []{ component.TelegnosisPowerAction!.Value }, uid); + + component.TelegnosisProjection = projection; _psionics.LogPowerUsed(uid, "telegnosis"); args.Handled = true; diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index 66e973cc4a6..499e0cb1155 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -27,7 +27,6 @@ public abstract class SharedActionsSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly ActionContainerSystem _actionContainer = default!; - [Dependency] private readonly INetManager _netMan = default!; public override void Initialize() { @@ -212,10 +211,7 @@ private void OnActionRequest(RequestPerformActionEvent ev, EntitySessionEventArg if (!TryGetActionData(actionEnt, out var action)) return; - if ((_netMan.IsClient && action.AttachedEntity != null) || _netMan.IsServer) - { - DebugTools.Assert(action.AttachedEntity == user); - } + DebugTools.Assert(action.AttachedEntity == user); if (!action.Enabled) diff --git a/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosisPowerComponent.cs b/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosisPowerComponent.cs index c2a56df63b3..11bc105af4c 100644 --- a/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosisPowerComponent.cs +++ b/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosisPowerComponent.cs @@ -1,9 +1,13 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + namespace Content.Shared.Backmen.Abilities.Psionics; [RegisterComponent] public sealed partial class TelegnosisPowerComponent : Component { - [DataField("prototype")] + [DataField("prototype", customTypeSerializer: typeof(PrototypeIdSerializer))] public string Prototype = "MobObserverTelegnostic"; - public EntityUid? TelegnosisPowerAction = null; + public EntityUid? TelegnosisPowerAction; + public EntityUid? TelegnosisProjection; } diff --git a/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosticProjectionComponent.cs b/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosticProjectionComponent.cs index 750185b16d0..54cf2a46e63 100644 --- a/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosticProjectionComponent.cs +++ b/Content.Shared/Backmen/Abilities/Psionics/Abilities/Telegnosis/TelegnosticProjectionComponent.cs @@ -2,4 +2,6 @@ namespace Content.Shared.Backmen.Abilities.Psionics; [RegisterComponent] public sealed partial class TelegnosticProjectionComponent : Component -{} +{ + public EntityUid? TelegnosisPowerAction; +} diff --git a/Content.Shared/Backmen/Psionics/Events.cs b/Content.Shared/Backmen/Psionics/Events.cs index cccb6aa1c63..0d09e977791 100644 --- a/Content.Shared/Backmen/Psionics/Events.cs +++ b/Content.Shared/Backmen/Psionics/Events.cs @@ -32,6 +32,7 @@ public sealed partial class PsionicInvisibilityPowerOffActionEvent : InstantActi public sealed partial class HairballActionEvent : InstantActionEvent {} public sealed partial class EatMouseActionEvent : InstantActionEvent {} public sealed partial class MetapsionicPowerActionEvent : InstantActionEvent {} +public sealed partial class TelegnosisPowerReturnActionEvent : InstantActionEvent {} public sealed partial class TelegnosisPowerActionEvent : InstantActionEvent {} public sealed partial class PsionicRegenerationPowerActionEvent : InstantActionEvent {} public sealed partial class NoosphericZapPowerActionEvent : EntityTargetActionEvent {} diff --git a/Resources/Prototypes/Backmen/Actions/types.yml b/Resources/Prototypes/Backmen/Actions/types.yml index 855d5c42e1f..b1eae32138f 100644 --- a/Resources/Prototypes/Backmen/Actions/types.yml +++ b/Resources/Prototypes/Backmen/Actions/types.yml @@ -104,6 +104,18 @@ useDelay: 150 event: !type:TelegnosisPowerActionEvent +- type: entity + id: ActionTelegnosisReturn + name: action-name-telegnosis + description: action-description-telegnosis + noSpawn: true + components: + - type: InstantAction + icon: Backmen/Interface/VerbIcons/psionic_invisibility_off.png + event: !type:TelegnosisPowerReturnActionEvent + checkCanInteract: false + useDelay: 20 + - type: entity id: ActionPsionicRegeneration name: action-name-psionic-regeneration diff --git a/Resources/Prototypes/Backmen/Entities/Mobs/NPC/special.yml b/Resources/Prototypes/Backmen/Entities/Mobs/NPC/special.yml index 505b34cd031..14965553faa 100644 --- a/Resources/Prototypes/Backmen/Entities/Mobs/NPC/special.yml +++ b/Resources/Prototypes/Backmen/Entities/Mobs/NPC/special.yml @@ -31,6 +31,8 @@ - type: ShipwreckedNPCHecate - type: NPCConversation tree: ShipwreckedPsychopompHecate + - type: TTS + voice: Npc1 # aliases: # - hekate # - katey diff --git a/Resources/Prototypes/Backmen/Entities/Mobs/Player/special.yml b/Resources/Prototypes/Backmen/Entities/Mobs/Player/special.yml index 0ad27ddf75e..b87b6d97a4a 100644 --- a/Resources/Prototypes/Backmen/Entities/Mobs/Player/special.yml +++ b/Resources/Prototypes/Backmen/Entities/Mobs/Player/special.yml @@ -14,6 +14,7 @@ layers: - state: eyeball shader: unshaded + - type: Dispellable - type: Psionic - type: MindContainer - type: Clickable @@ -39,13 +40,15 @@ - type: Appearance - type: Eye drawFov: false - visMask: PsionicInvisibility + visMask: + - Normal + - PsionicInvisibility - type: Input context: "ghost" - type: Examiner - type: TelegnosticProjection - type: Stealth - lastVisibility: 0.66 + lastVisibility: 0.33 - type: Visibility layer: 4 - type: NoNormalInteraction diff --git a/Resources/Prototypes/Backmen/Psionics/psionicsPowers.yml b/Resources/Prototypes/Backmen/Psionics/psionicsPowers.yml index 2779368d841..612cb5298e7 100644 --- a/Resources/Prototypes/Backmen/Psionics/psionicsPowers.yml +++ b/Resources/Prototypes/Backmen/Psionics/psionicsPowers.yml @@ -3,7 +3,7 @@ weights: MetapsionicPower: 1 DispelPower: 1 - #TelegnosisPower: 1 + TelegnosisPower: 1 PsionicRegenerationPower: 1 MassSleepPower: 0.3 PsionicInvisibilityPower: 0.15