forked from Simple-Station/Einstein-Engines
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Shadeskip Power (Simple-Station#987)
# Description This PR adds the first of the "Anomalist" powers, that of Shadeskip. Upon activation, Shadeskip summons a small amount of living shadows around the caster, functioning almost exactly like a Shadow Anomaly, only smaller. <details><summary><h1>Media</h1></summary> <p> A very early rendition of Shadeskip: https://github.com/user-attachments/assets/2425aca8-4d09-48a2-80f5-572b3aa864b1 </p> </details> # Changelog :cl: - add: Added Shadeskip as a new psionic power. --------- Signed-off-by: VMSolidus <[email protected]> Co-authored-by: DEATHB4DEFEAT <[email protected]>
- Loading branch information
1 parent
ce9d9aa
commit 13f52f7
Showing
9 changed files
with
298 additions
and
2 deletions.
There are no files selected for viewing
146 changes: 146 additions & 0 deletions
146
Content.Server/Abilities/Psionics/AnomalyPowerSystem.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
using Content.Shared.Abilities.Psionics; | ||
using Content.Shared.Actions.Events; | ||
using Content.Shared.Psionics.Glimmer; | ||
using Content.Shared.Random.Helpers; | ||
using Robust.Shared.Random; | ||
using Content.Shared.Anomaly.Effects.Components; | ||
using Robust.Shared.Map.Components; | ||
using Content.Shared.Anomaly; | ||
using Robust.Shared.Audio.Systems; | ||
using Content.Shared.Actions; | ||
using Content.Shared.Damage; | ||
using Content.Server.Popups; | ||
|
||
namespace Content.Server.Abilities.Psionics; | ||
|
||
public sealed class AnomalyPowerSystem : EntitySystem | ||
{ | ||
[Dependency] private readonly IRobustRandom _random = default!; | ||
[Dependency] private readonly GlimmerSystem _glimmerSystem = default!; | ||
[Dependency] private readonly SharedAnomalySystem _anomalySystem = default!; | ||
[Dependency] private readonly SharedMapSystem _mapSystem = default!; | ||
[Dependency] private readonly SharedAudioSystem _audio = default!; | ||
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!; | ||
[Dependency] private readonly SharedActionsSystem _actions = default!; | ||
[Dependency] private readonly DamageableSystem _damageable = default!; | ||
[Dependency] private readonly PopupSystem _popup = default!; | ||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
SubscribeLocalEvent<PsionicComponent, AnomalyPowerActionEvent>(OnPowerUsed); | ||
} | ||
|
||
private void OnPowerUsed(EntityUid uid, PsionicComponent component, AnomalyPowerActionEvent args) | ||
{ | ||
if (HasComp<PsionicInsulationComponent>(uid) | ||
|| HasComp<MindbrokenComponent>(uid)) | ||
return; | ||
|
||
var overcharged = _glimmerSystem.Glimmer * component.CurrentAmplification | ||
> Math.Min(args.SupercriticalThreshold * component.CurrentDampening, args.MaxSupercriticalThreshold); | ||
|
||
// I already hate this, so much. | ||
//DoBluespaceAnomalyEffects(uid, component, args, overcharged); | ||
//DoElectricityAnomalyEffects(uid, component, args, overcharged); | ||
DoEntityAnomalyEffects(uid, component, args, overcharged); | ||
//DoExplosionAnomalyEffects(uid, component, args, overcharged); | ||
//DoGasProducerAnomalyEffects(uid, component, args, overcharged); | ||
//DoGravityAnomalyEffects(uid, component, args, overcharged); | ||
//DoInjectionAnomalyEffects(uid, component, args, overcharged); | ||
//DoPuddleCreateAnomalyEffects(uid, component, args, overcharged); | ||
//DoPyroclasticAnomalyEffects(uid, component, args, overcharged); | ||
//DoTemperatureAnomalyEffects(uid, component, args, overcharged); | ||
|
||
DoAnomalySounds(uid, component, args, overcharged); | ||
DoGlimmerEffects(uid, component, args, overcharged); | ||
|
||
if (overcharged) | ||
DoOverchargedEffects(uid, component, args); | ||
|
||
args.Handled = true; | ||
} | ||
|
||
public void DoEntityAnomalyEffects(EntityUid uid, PsionicComponent component, AnomalyPowerActionEvent args, bool overcharged) | ||
{ | ||
if (args.EntitySpawnEntries is null) | ||
return; | ||
|
||
if (overcharged) | ||
foreach (var entry in args.EntitySpawnEntries) | ||
{ | ||
if (!entry.Settings.SpawnOnSuperCritical) | ||
continue; | ||
|
||
SpawnEntities(uid, component, entry); | ||
} | ||
else foreach (var entry in args.EntitySpawnEntries) | ||
{ | ||
if (!entry.Settings.SpawnOnPulse) | ||
continue; | ||
|
||
SpawnEntities(uid, component, entry); | ||
} | ||
} | ||
|
||
public void SpawnEntities(EntityUid uid, PsionicComponent component, EntitySpawnSettingsEntry entry) | ||
{ | ||
if (!TryComp<MapGridComponent>(Transform(uid).GridUid, out var grid)) | ||
return; | ||
|
||
var tiles = _anomalySystem.GetSpawningPoints(uid, | ||
component.CurrentDampening, | ||
component.CurrentAmplification, | ||
entry.Settings, | ||
_glimmerSystem.Glimmer / 1000, | ||
component.CurrentAmplification, | ||
component.CurrentAmplification); | ||
|
||
if (tiles is null) | ||
return; | ||
|
||
foreach (var tileref in tiles) | ||
Spawn(_random.Pick(entry.Spawns), _mapSystem.ToCenterCoordinates(tileref, grid)); | ||
} | ||
|
||
public void DoAnomalySounds(EntityUid uid, PsionicComponent component, AnomalyPowerActionEvent args, bool overcharged = false) | ||
{ | ||
if (overcharged && args.SupercriticalSound is not null) | ||
{ | ||
_audio.PlayPvs(args.SupercriticalSound, uid); | ||
return; | ||
} | ||
|
||
if (args.PulseSound is null | ||
|| _glimmerSystem.Glimmer < args.GlimmerSoundThreshold * component.CurrentDampening) | ||
return; | ||
|
||
_audio.PlayEntity(args.PulseSound, uid, uid); | ||
} | ||
|
||
public void DoGlimmerEffects(EntityUid uid, PsionicComponent component, AnomalyPowerActionEvent args, bool overcharged = false) | ||
{ | ||
var minGlimmer = (int) Math.Round(MathF.MinMagnitude(args.MinGlimmer, args.MaxGlimmer) | ||
* (overcharged ? args.SupercriticalGlimmerMultiplier : 1) | ||
* component.CurrentAmplification - component.CurrentDampening); | ||
var maxGlimmer = (int) Math.Round(MathF.MaxMagnitude(args.MinGlimmer, args.MaxGlimmer) | ||
* (overcharged ? args.SupercriticalGlimmerMultiplier : 1) | ||
* component.CurrentAmplification - component.CurrentDampening); | ||
|
||
_psionics.LogPowerUsed(uid, args.PowerName, minGlimmer, maxGlimmer); | ||
} | ||
|
||
public void DoOverchargedEffects(EntityUid uid, PsionicComponent component, AnomalyPowerActionEvent args) | ||
{ | ||
if (args.OverchargeFeedback is not null | ||
&& Loc.TryGetString(args.OverchargeFeedback, out var popup)) | ||
_popup.PopupEntity(popup, uid, uid); | ||
|
||
if (args.OverchargeRecoil is not null | ||
&& TryComp<DamageableComponent>(uid, out var damageable)) | ||
_damageable.TryChangeDamage(uid, args.OverchargeRecoil / component.CurrentDampening, true, true, damageable, uid); | ||
|
||
if (args.OverchargeCooldown > 0) | ||
foreach (var action in component.Actions) | ||
_actions.SetCooldown(action.Value, TimeSpan.FromSeconds(args.OverchargeCooldown / component.CurrentDampening)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using Content.Shared.Anomaly.Effects.Components; | ||
using Content.Shared.Damage; | ||
using Robust.Shared.Audio; | ||
|
||
namespace Content.Shared.Actions.Events; | ||
|
||
public sealed partial class AnomalyPowerActionEvent : InstantActionEvent | ||
{ | ||
|
||
[DataField] | ||
public string PowerName; | ||
|
||
/// <summary> | ||
/// When casting above the Supercritical Threshold, if not 0, this will cause all powers to enter cooldown for the given duration. | ||
/// </summary> | ||
[DataField] | ||
public float OverchargeCooldown; | ||
|
||
/// <summary> | ||
/// When casting above the Supercritical Threshold, if not 0, this will deal recoil damage to the caster of the specified amounts. | ||
/// </summary> | ||
[DataField] | ||
public DamageSpecifier? OverchargeRecoil; | ||
|
||
/// <summary> | ||
/// When casting above the Supercritical Threshold, play a popup above the caster's head. | ||
/// </summary> | ||
[DataField] | ||
public string? OverchargeFeedback; | ||
|
||
/// <summary> | ||
/// The minimum amount of glimmer generated by this power. | ||
/// </summary> | ||
[DataField] | ||
public int MinGlimmer; | ||
|
||
/// <summary> | ||
/// The maximum amount of glimmer generated by this power. | ||
/// </summary> | ||
[DataField] | ||
public int MaxGlimmer; | ||
|
||
/// <summary> | ||
/// The amount to multiply glimmer generation by when above the Supercritical Threshold | ||
/// </summary> | ||
[DataField] | ||
public int SupercriticalGlimmerMultiplier = 1; | ||
|
||
/// <summary> | ||
/// The threshold of glimmer at which this power will play a sound. | ||
/// </summary> | ||
[DataField] | ||
public float GlimmerSoundThreshold; | ||
|
||
/// <summary> | ||
/// The glimmer threshold(divided by amplification and multiplied by dampening) at which this power will act as a Supercritical Anomaly. | ||
/// </summary> | ||
[DataField] | ||
public float SupercriticalThreshold = 500f; | ||
|
||
/// <summary> | ||
/// The maximum amount Dampening can increase the Supercritical threshold to. | ||
/// </summary> | ||
[DataField] | ||
public float MaxSupercriticalThreshold = 800f; | ||
|
||
/// <summary> | ||
/// What entities will be spawned by this action, using the same arguments as an EntitySpawnAnomalyComponent? | ||
/// </summary> | ||
[DataField] | ||
public List<EntitySpawnSettingsEntry>? EntitySpawnEntries; | ||
|
||
/// <summary> | ||
/// The sound to be played upon activating this power(and not Supercritically) | ||
/// </summary> | ||
[DataField] | ||
public SoundSpecifier? PulseSound = new SoundCollectionSpecifier("RadiationPulse"); | ||
|
||
/// <summary> | ||
/// The sound plays when this power is activated above a Supercritical glimmer threshold | ||
/// </summary> | ||
[DataField] | ||
public SoundSpecifier? SupercriticalSound = new SoundCollectionSpecifier("Explosion"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ | |
TelepathyPower: 1 | ||
HealingWordPower: 0.85 | ||
RevivifyPower: 0.1 | ||
ShadeskipPower: 0.15 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,9 @@ | |
}, | ||
{ | ||
"name": "revivify" | ||
}, | ||
{ | ||
"name": "shadeskip" | ||
} | ||
] | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.