Skip to content

Commit

Permalink
Psionic Power Rolling Rework (#830)
Browse files Browse the repository at this point in the history
# Description

This PR implements a long overdue rework of the underlying system for
actually giving Psions their powers, by making it a semi-deterministic
system that favors people having a small handful of powers, unless said
person has inherent modifiers that let them generate them more
consistently. A common complaint I received from the new Psionic System
is that stations tended to become "Space Hogwarts" given enough time,
since people could very easily game the system to consistently get new
powers every 20 minutes, until a majority of the station was throwing
fireballs at each other.

Now, obtaining new powers gets more difficult the more powers you have,
exponentially so. Powers can also declare in their prototype how many
"Slots" they occupy, meaning that certain powers can make this even more
difficult, or not at all, as desired.

# Changelog

:cl: VMSolidus & Rane
- add: Psionic Power "Rerolls" have been reworked. Psions now have a
stat called Potentia, which is increased by sources of Psionic Rerolls
such as Space Drugs, Loto Oil, and Random Events. Instead of being an
all-or-nothing "D100 with modifiers" roll, whatever you roll is added to
your Potentia stat, and when Potentia reaches a certain threshold, it is
automatically "Spent" to buy a random new power. Your first power costs
100 Potentia, your 2nd power costs 200, 3rd costs 400, and so on. The
more powers you have, the more difficult it is to obtain new ones.
- tweak: Some powers, such as Telepathy and Xenoglossy, do not count as
a power for the purpose of Potentia Cost

---------

Signed-off-by: VMSolidus <[email protected]>
  • Loading branch information
VMSolidus committed Sep 17, 2024
1 parent 3dd57ca commit 9e293ea
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 118 deletions.
24 changes: 24 additions & 0 deletions Content.Server/Abilities/Psionics/PsionicAbilitiesSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Linq;
using Robust.Server.Player;
using Content.Server.Chat.Managers;
using Content.Server.Psionics.Glimmer;

namespace Content.Server.Abilities.Psionics
{
Expand Down Expand Up @@ -122,6 +123,8 @@ public void InitializePsionicPower(EntityUid uid, PsionicPowerPrototype proto, P
AddPsionicStatSources(proto, psionic);
RefreshPsionicModifiers(uid, psionic);
SendFeedbackMessage(uid, proto, playFeedback);
UpdatePowerSlots(psionic);
//UpdatePsionicDanger(uid, psionic); // TODO: After Glimmer Refactor
//SendFeedbackAudio(uid, proto, playPopup); // TODO: This one is coming next!
}

Expand Down Expand Up @@ -297,6 +300,27 @@ private void SendFeedbackMessage(EntityUid uid, PsionicPowerPrototype proto, boo
session.Channel);
}

private void UpdatePowerSlots(PsionicComponent psionic)
{
var slotsUsed = 0;
foreach (var power in psionic.ActivePowers)
slotsUsed += power.PowerSlotCost;

psionic.PowerSlotsTaken = slotsUsed;
}

/// <summary>
/// Psions over a certain power threshold become a glimmer source. This cannot be fully implemented until after I rework Glimmer
/// </summary>
//private void UpdatePsionicDanger(EntityUid uid, PsionicComponent psionic)
//{
// if (psionic.PowerSlotsTaken <= psionic.PowerSlots)
// return;
//
// EnsureComp<GlimmerSourceComponent>(uid, out var glimmerSource);
// glimmerSource.SecondsPerGlimmer = 10 / (psionic.PowerSlotsTaken - psionic.PowerSlots);
//}

/// <summary>
/// Remove all Psychic Actions listed in an entity's Psionic Component. Unfortunately, removing actions associated with a specific Power Prototype is not supported.
/// </summary>
Expand Down
325 changes: 214 additions & 111 deletions Content.Server/Psionics/PsionicsSystem.cs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Content.Server/StationEvents/Events/NoosphericZapRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ protected override void Started(EntityUid uid, NoosphericZapRuleComponent compon
_stunSystem.TryParalyze(psion, TimeSpan.FromSeconds(component.StunDuration), false);
_statusEffectsSystem.TryAddStatusEffect(psion, "Stutter", TimeSpan.FromSeconds(component.StutterDuration), false, "StutteringAccent");

if (psionicComponent.CanReroll)
if (!psionicComponent.CanReroll)
{
psionicComponent.CanReroll = false;
psionicComponent.CanReroll = true;
_popupSystem.PopupEntity(Loc.GetString("noospheric-zap-seize-potential-regained"), psion, psion, Shared.Popups.PopupType.LargeCaution);
}
else
Expand Down
28 changes: 24 additions & 4 deletions Content.Shared/Psionics/PsionicComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@ namespace Content.Shared.Abilities.Psionics
public sealed partial class PsionicComponent : Component
{
/// <summary>
/// How close a Psion is to awakening a new power.
/// TODO: Implement this in a separate PR.
/// How close a Psion is to generating a new power. When Potentia reaches the NextPowerCost, it is "Spent" in order to "Buy" a random new power.
/// TODO: Psi-Potentiometry should be able to read how much Potentia a person has.
/// </summary>
[DataField]
public float Potentia;

/// <summary>
/// Each time a Psion rolls for a new power, they roll a number between 0 and 100, adding any relevant modifiers. This number is then added to Potentia,
/// meaning that it carries over between rolls. When a character has an amount of potentia equal to at least 100 * 2^(total powers), the potentia is then spent, and a power is generated.
/// This variable stores the cost of the next power.
/// </summary>
[DataField]
public float Potentia = 0;
public float NextPowerCost = 100;

/// <summary>
/// The baseline chance of obtaining a psionic power when rolling for one.
Expand All @@ -24,7 +32,7 @@ public sealed partial class PsionicComponent : Component
/// Whether or not a Psion has an available "Reroll" to spend on attempting to gain powers.
/// </summary>
[DataField]
public bool CanReroll;
public bool CanReroll = true;

/// <summary>
/// The Base amount of time (in minutes) this Psion is given the stutter effect if they become mindbroken.
Expand Down Expand Up @@ -142,6 +150,18 @@ private set
public float CurrentDampening;

/// <summary>
/// How many "Slots" an entity has for psionic powers. This is not a hard limit, and is instead used for calculating the cost to generate new powers.
/// Exceeding this limit causes an entity to become a Glimmer Source.
/// </summary>
[DataField]
public int PowerSlots = 1;

/// <summary>
/// How many "Slots" are currently occupied by psionic powers.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public int PowerSlotsTaken;

/// List of descriptors this entity will bring up for psychognomy. Used to remove
/// unneccesary subs for unique psionic entities like e.g. Oracle.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions Content.Shared/Psionics/PsionicPowerPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,10 @@ public sealed partial class PsionicPowerPrototype : IPrototype
/// </summary>
[DataField]
public float DampeningModifier = 0;

/// <summary>
/// How many "Power Slots" this power occupies.
/// </summary>
[DataField]
public int PowerSlotCost = 1;
}
4 changes: 3 additions & 1 deletion Resources/Locale/en-US/psionics/psionic-powers.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ telepathy-power-initialization-feedback =
The voices I've heard all my life begin to clear, yet they do not leave me. Before, they were as incoherent whispers,
now my senses broaden, I come to a realization that they are part of a communal shared hallucination. Behind every voice is a glimmering sentience.
# Psionic System Messages
mindbreaking-feedback = The light of life vanishes from {CAPITALIZE($entity)}'s eyes, leaving behind a husk pretending at sapience
examine-mindbroken-message =
Eyes unblinking, staring deep into the horizon. {CAPITALIZE($entity)} is a sack of meat pretending it has a soul.
There is nothing behind its gaze, no evidence there can be found of the divine light of creation.
There is nothing behind its gaze, no evidence there can be found of the divine light of creation.
psionic-roll-failed = For a moment, my consciousness expands, yet I feel that it is not enough.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- !type:AddComponentSpecial
components:
- type: Psionic
powerSlots: 2
- !type:AddComponentSpecial
components:
- type: InnatePsionicPowers
Expand Down
3 changes: 3 additions & 0 deletions Resources/Prototypes/Psionics/psionics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
- type: UniversalLanguageSpeaker
initializationFeedback: xenoglossy-power-initialization-feedback
metapsionicFeedback: psionic-language-power-feedback # Reuse for telepathy, clairaudience, etc
powerSlotCost: 0

- type: psionicPower
id: PsychognomyPower #i.e. reverse physiognomy
Expand All @@ -128,6 +129,7 @@
- type: Psychognomist
initializationFeedback: psychognomy-power-initialization-feedback
metapsionicFeedback: psionic-language-power-feedback
powerSlotCost: 0

- type: psionicPower
id: TelepathyPower
Expand All @@ -137,3 +139,4 @@
- type: Telepathy
initializationFeedback: telepathy-power-initialization-feedback
metapsionicFeedback: psionic-language-power-feedback # Reuse for telepathy, clairaudience, etc
powerSlotCost: 0
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
components:
- type: BibleUser # Nyano - Lets them heal with bibles
- type: Psionic # Nyano - They start with telepathic chat
powerSlots: 3
- !type:AddImplantSpecial
implants: [ MindShieldImplant ]
- !type:AddComponentSpecial
Expand Down

0 comments on commit 9e293ea

Please sign in to comment.