Skip to content

Commit

Permalink
Psionic Refactor Version 2, Part 1 (#731)
Browse files Browse the repository at this point in the history
# Description

Finally, after many long months, and this project surviving a complete
restart from square one, I have now made actual, real progress on an
actual proper "Refactor" of Psionics. This PR primarily moves ALL of the
logic for initializing Psionic Powers into highly configurable YML. The
initialization of psionics is no longer handled by components, and is
instead now handled entirely by a centralized system. To even further
cut down on component bookkeeping, nearly all logic needed for
generating Psions has been moved to the PsionicComponent. The
PotentialPsionicComponent now no longer exists.

Additionally, and although they are not currently implemented(I will do
so in the next PR after this), I have also laid the groundwork for
substantial reworks to the other aspects of Psionics. Power generation,
casting stats, feedback messages, non-action powers, and so on. It's
actually possible to now add a psionic power that does not add any
active abilities at all, rather by adding one or more components, thus
enabling purely Passive Powers. Or a combination of the two,
active-powers with a passive component.

# Media


https://github.com/user-attachments/assets/0fd6b9a4-7d84-4e6e-980a-9d7dd4264f6f

# Changelog

:cl:
- add: Latent Psychic has been added as a new positive trait.
- tweak: Psionics have received a substantial refactor. While no new
powers have been added this patch, this initial refactor lays the
groundwork so that new psionic powers will be easier to create.
- tweak: Latent Psychic is now fully required to become psionic, or to
interact with Oracle.
- tweak: Psychics can now have more than one active power.
- remove: Mimes are no longer Psionic.
- tweak: Chaplain, Mantis, & Mystagogue all receive the Latent Psychic
trait for free, automatically.

---------

Signed-off-by: VMSolidus <[email protected]>
Co-authored-by: Danger Revolution! <[email protected]>
Co-authored-by: DEATHB4DEFEAT <[email protected]>
Co-authored-by: Pspritechologist <[email protected]>
  • Loading branch information
4 people authored Aug 20, 2024
1 parent bf1359f commit 495d331
Show file tree
Hide file tree
Showing 85 changed files with 916 additions and 762 deletions.
3 changes: 0 additions & 3 deletions Content.Server/Abilities/Mime/MimePowersSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ private void OnComponentInit(EntityUid uid, MimePowersComponent component, Compo
EnsureComp<MutedComponent>(uid);
_alertsSystem.ShowAlert(uid, AlertType.VowOfSilence);
_actionsSystem.AddAction(uid, ref component.InvisibleWallActionEntity, component.InvisibleWallAction, uid);
//Nyano - Summary: Add Psionic Ability to Mime.
if (TryComp<PsionicComponent>(uid, out var psionic) && psionic.PsionicAbility == null)
psionic.PsionicAbility = component.InvisibleWallActionEntity;
}

/// <summary>
Expand Down
33 changes: 0 additions & 33 deletions Content.Server/Abilities/Psionics/Abilities/DispelPowerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,31 @@
using Content.Shared.Actions;
using Content.Shared.StatusEffect;
using Content.Shared.Abilities.Psionics;
using Content.Shared.Damage;
using Content.Shared.Revenant.Components;
using Content.Server.Guardian;
using Content.Server.Bible.Components;
using Content.Server.Popups;
using Robust.Shared.Prototypes;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Content.Shared.Mind;
using Content.Shared.Actions.Events;
using Robust.Shared.Audio.Systems;

namespace Content.Server.Abilities.Psionics
{
public sealed class DispelPowerSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly GuardianSystem _guardianSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly SharedMindSystem _mindSystem = default!;


public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DispelPowerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<DispelPowerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<DispelPowerActionEvent>(OnPowerUsed);

SubscribeLocalEvent<DispellableComponent, DispelledEvent>(OnDispelled);
Expand All @@ -46,29 +36,6 @@ public override void Initialize()
SubscribeLocalEvent<RevenantComponent, DispelledEvent>(OnRevenantDispelled);
}

private void OnInit(EntityUid uid, DispelPowerComponent component, ComponentInit args)
{
_actions.AddAction(uid, ref component.DispelActionEntity, component.DispelActionId );
_actions.TryGetActionData( component.DispelActionEntity, out var actionData );
if (actionData is { UseDelay: not null })
_actions.StartUseDelay(component.DispelActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic) && psionic.PsionicAbility == null)
{
psionic.PsionicAbility = component.DispelActionEntity;
psionic.ActivePowers.Add(component);
}
}

private void OnShutdown(EntityUid uid, DispelPowerComponent component, ComponentShutdown args)
{
_actions.RemoveAction(uid, component.DispelActionEntity);

if (TryComp<PsionicComponent>(uid, out var psionic))
{
psionic.ActivePowers.Remove(component);
}
}

private void OnPowerUsed(DispelPowerActionEvent args)
{
if (HasComp<PsionicInsulationComponent>(args.Target))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,22 @@
using Content.Shared.Actions;
using Content.Shared.Abilities.Psionics;
using Content.Shared.StatusEffect;
using Content.Shared.Popups;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Content.Shared.Mind;
using Content.Shared.Actions.Events;

namespace Content.Server.Abilities.Psionics
{
public sealed class MetapsionicPowerSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly SharedPopupSystem _popups = default!;
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly SharedMindSystem _mindSystem = default!;


public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MetapsionicPowerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<MetapsionicPowerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<MetapsionicPowerComponent, MetapsionicPowerActionEvent>(OnPowerUsed);
}

private void OnInit(EntityUid uid, MetapsionicPowerComponent component, ComponentInit args)
{
_actions.AddAction(uid, ref component.MetapsionicActionEntity, component.MetapsionicActionId );
_actions.TryGetActionData( component.MetapsionicActionEntity, out var actionData );
if (actionData is { UseDelay: not null })
_actions.StartUseDelay(component.MetapsionicActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic) && psionic.PsionicAbility == null)
{
psionic.PsionicAbility = component.MetapsionicActionEntity;
psionic.ActivePowers.Add(component);
}

}

private void OnShutdown(EntityUid uid, MetapsionicPowerComponent component, ComponentShutdown args)
{
_actions.RemoveAction(uid, component.MetapsionicActionEntity);

if (TryComp<PsionicComponent>(uid, out var psionic))
{
psionic.ActivePowers.Remove(component);
}
}

private void OnPowerUsed(EntityUid uid, MetapsionicPowerComponent component, MetapsionicPowerActionEvent args)
{
foreach (var entity in _lookup.GetEntitiesInRange(uid, component.Range))
Expand Down
30 changes: 0 additions & 30 deletions Content.Server/Abilities/Psionics/Abilities/MindSwapPowerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,15 @@
using Content.Server.Popups;
using Content.Server.Psionics;
using Content.Server.GameTicking;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Content.Shared.Mind;
using Content.Shared.Actions.Events;

namespace Content.Server.Abilities.Psionics
{
public sealed class MindSwapPowerSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly MindSystem _mindSystem = default!;
Expand All @@ -31,8 +27,6 @@ public sealed class MindSwapPowerSystem : EntitySystem
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MindSwapPowerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<MindSwapPowerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<MindSwapPowerActionEvent>(OnPowerUsed);
SubscribeLocalEvent<MindSwappedComponent, MindSwapPowerReturnActionEvent>(OnPowerReturned);
SubscribeLocalEvent<MindSwappedComponent, DispelledEvent>(OnDispelled);
Expand All @@ -42,28 +36,6 @@ public override void Initialize()
SubscribeLocalEvent<MindSwappedComponent, ComponentInit>(OnSwapInit);
}

private void OnInit(EntityUid uid, MindSwapPowerComponent component, ComponentInit args)
{
_actions.AddAction(uid, ref component.MindSwapActionEntity, component.MindSwapActionId );
_actions.TryGetActionData( component.MindSwapActionEntity, out var actionData );
if (actionData is { UseDelay: not null })
_actions.StartUseDelay(component.MindSwapActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic) && psionic.PsionicAbility == null)
{
psionic.PsionicAbility = component.MindSwapActionEntity;
psionic.ActivePowers.Add(component);
}
}

private void OnShutdown(EntityUid uid, MindSwapPowerComponent component, ComponentShutdown args)
{
_actions.RemoveAction(uid, component.MindSwapActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic))
{
psionic.ActivePowers.Remove(component);
}
}

private void OnPowerUsed(MindSwapPowerActionEvent args)
{
if (!(TryComp<DamageableComponent>(args.Target, out var damageable) && damageable.DamageContainerID == "Biological"))
Expand Down Expand Up @@ -151,8 +123,6 @@ private void OnSwapInit(EntityUid uid, MindSwappedComponent component, Component
_actions.TryGetActionData( component.MindSwapReturnActionEntity, out var actionData );
if (actionData is { UseDelay: not null })
_actions.StartUseDelay(component.MindSwapReturnActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic) && psionic.PsionicAbility == null)
psionic.PsionicAbility = component.MindSwapReturnActionEntity;
}

public void Swap(EntityUid performer, EntityUid target, bool end = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,27 @@
using Content.Shared.Actions;
using Content.Shared.Abilities.Psionics;
using Content.Server.Psionics;
using Content.Shared.StatusEffect;
using Content.Server.Stunnable;
using Content.Server.Beam;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Content.Server.Mind;
using Content.Shared.Actions.Events;

namespace Content.Server.Abilities.Psionics
{
public sealed class NoosphericZapPowerSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly BeamSystem _beam = default!;
[Dependency] private readonly MindSystem _mindSystem = default!;


public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<NoosphericZapPowerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<NoosphericZapPowerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<NoosphericZapPowerActionEvent>(OnPowerUsed);
}

private void OnInit(EntityUid uid, NoosphericZapPowerComponent component, ComponentInit args)
{
_actions.AddAction(uid, ref component.NoosphericZapActionEntity, component.NoosphericZapActionId );
_actions.TryGetActionData( component.NoosphericZapActionEntity, out var actionData );
if (actionData is { UseDelay: not null })
_actions.StartUseDelay(component.NoosphericZapActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic) && psionic.PsionicAbility == null)
{
psionic.PsionicAbility = component.NoosphericZapActionEntity;
psionic.ActivePowers.Add(component);
}
}

private void OnShutdown(EntityUid uid, NoosphericZapPowerComponent component, ComponentShutdown args)
{
_actions.RemoveAction(uid, component.NoosphericZapActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic))
{
psionic.ActivePowers.Remove(component);
}
}

private void OnPowerUsed(NoosphericZapPowerActionEvent args)
{
if (!HasComp<PotentialPsionicComponent>(args.Target))
return;

if (HasComp<PsionicInsulationComponent>(args.Target))
return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,29 @@
using Content.Shared.Stealth;
using Content.Shared.Stealth.Components;
using Content.Server.Psionics;
using Robust.Shared.Prototypes;
using Robust.Shared.Player;
using Robust.Shared.Audio;
using Robust.Shared.Timing;
using Content.Server.Mind;
using Content.Shared.Actions.Events;
using Robust.Shared.Audio.Systems;

namespace Content.Server.Abilities.Psionics
{
public sealed class PsionicInvisibilityPowerSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
[Dependency] private readonly SharedStealthSystem _stealth = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PsionicInvisibilityPowerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<PsionicInvisibilityPowerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<PsionicInvisibilityPowerComponent, PsionicInvisibilityPowerActionEvent>(OnPowerUsed);
SubscribeLocalEvent<RemovePsionicInvisibilityOffPowerActionEvent>(OnPowerOff);
SubscribeLocalEvent<PsionicInvisibilityUsedComponent, ComponentInit>(OnStart);
SubscribeLocalEvent<PsionicInvisibilityUsedComponent, ComponentShutdown>(OnEnd);
SubscribeLocalEvent<PsionicInvisibilityUsedComponent, DamageChangedEvent>(OnDamageChanged);
}

private void OnInit(EntityUid uid, PsionicInvisibilityPowerComponent component, ComponentInit args)
{
_actions.AddAction(uid, ref component.PsionicInvisibilityActionEntity, component.PsionicInvisibilityActionId );
_actions.TryGetActionData( component.PsionicInvisibilityActionEntity, out var actionData );
if (actionData is { UseDelay: not null })
_actions.StartUseDelay(component.PsionicInvisibilityActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic) && psionic.PsionicAbility == null)
{
psionic.PsionicAbility = component.PsionicInvisibilityActionEntity;
psionic.ActivePowers.Add(component);
}
}

private void OnShutdown(EntityUid uid, PsionicInvisibilityPowerComponent component, ComponentShutdown args)
{
_actions.RemoveAction(uid, component.PsionicInvisibilityActionEntity);
if (TryComp<PsionicComponent>(uid, out var psionic))
{
psionic.ActivePowers.Remove(component);
}
}

private void OnPowerUsed(EntityUid uid, PsionicInvisibilityPowerComponent component, PsionicInvisibilityPowerActionEvent args)
{
if (HasComp<PsionicInvisibilityUsedComponent>(uid))
Expand Down
Loading

0 comments on commit 495d331

Please sign in to comment.