using Content.Shared.DoAfter; using Content.Shared.Psionics; using Content.Shared.Random; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; namespace Content.Shared.Abilities.Psionics { [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class PsionicComponent : Component { [DataField] public bool BypassManaCheck; /// /// 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. /// [DataField] public float Potentia; /// /// The base cost for new powers. /// [DataField] public float BaselinePowerCost = 100; /// /// 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. /// [DataField] public float NextPowerCost = 100; /// /// The baseline chance of obtaining a psionic power when rolling for one. /// [DataField] public float Chance = 0.04f; /// /// Whether or not a Psion has an available "Reroll" to spend on attempting to gain powers. /// [DataField] public bool CanReroll = true; /// /// The Base amount of time (in minutes) this Psion is given the stutter effect if they become mindbroken. /// [DataField] public float MindbreakingStutterTime = 5; public string MindbreakingStutterCondition = "Stutter"; public string MindbreakingStutterAccent = "StutteringAccent"; /// /// The message feedback given on mindbreak. /// [DataField] public string MindbreakingFeedback = "mindbreaking-feedback"; /// /// [DataField] public string HardMindbreakingFeedback = "hard-mindbreaking-feedback"; /// /// How much should the odds of obtaining a Psionic Power be multiplied when rolling for one. /// [DataField] public float PowerRollMultiplier = 1f; /// /// How much the odds of obtaining a Psionic Power should be multiplied when rolling for one. /// [DataField] public float PowerRollFlatBonus = 0; private (float, float) _baselineAmplification = (0.4f, 1.2f); /// /// Use this datafield to change the range of Baseline Amplification. /// [DataField] private (float, float) _baselineAmplificationFactors = (0.4f, 1.2f); /// /// All Psionics automatically possess a random amount of initial starting Amplification, regardless of if they have any powers or not. /// The game will crash if Robust.Random is handed a (bigger number, smaller number), so the logic here prevents any funny business. /// public (float, float) BaselineAmplification { get { return _baselineAmplification; } private set { _baselineAmplification = (Math.Min( _baselineAmplificationFactors.Item1, _baselineAmplificationFactors.Item2), Math.Max(_baselineAmplificationFactors.Item1, _baselineAmplificationFactors.Item2)); } } private (float, float) _baselineDampening = (0.4f, 1.2f); /// /// Use this datafield to change the range of Baseline Amplification. /// [DataField] private (float, float) _baselineDampeningFactors = (0.4f, 1.2f); /// /// All Psionics automatically possess a random amount of initial starting Dampening, regardless of if they have any powers or not. /// The game will crash if Robust.Random is handed a (bigger number, smaller number), so the logic here prevents any funny business. /// public (float, float) BaselineDampening { get { return _baselineDampening; } private set { _baselineDampening = (Math.Min( _baselineDampeningFactors.Item1, _baselineDampeningFactors.Item2), Math.Max(_baselineDampeningFactors.Item1, _baselineDampeningFactors.Item2)); } } /// /// Whether this entity is capable of randomly rolling for powers. /// [DataField] public bool Roller = true; /// /// Ifrits, revenants, etc are explicitly magical beings that shouldn't get mindbroken /// [DataField] public bool Removable = true; /// /// The list of all powers currently active on a Psionic, by power Prototype. /// TODO: Not in this PR due to scope, but this needs to go to Server and not Shared. /// [ViewVariables(VVAccess.ReadOnly)] public HashSet ActivePowers = new(); /// /// The list of each Psionic Power by prototype with entityUid. /// [ViewVariables(VVAccess.ReadOnly)] public Dictionary Actions = new(); /// /// What sources of Amplification does this Psion have? /// [ViewVariables(VVAccess.ReadOnly)] public readonly Dictionary AmplificationSources = new(); /// /// A measure of how "Powerful" a Psion is. /// TODO: Implement this in a separate PR. /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float CurrentAmplification; /// /// What sources of Dampening does this Psion have? /// [ViewVariables(VVAccess.ReadOnly)] public readonly Dictionary DampeningSources = new(); /// /// A measure of how "Controlled" a Psion is. /// TODO: Implement this in a separate PR. /// [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float CurrentDampening; /// /// 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. /// [DataField] public int PowerSlots = 1; /// /// How many "Slots" are currently occupied by psionic powers. /// [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. /// [DataField] public List PsychognomicDescriptors = new(); /// Used for tracking what spell a Psion is actively casting [DataField] public DoAfterId? DoAfter; /// Popup to play if a Psion attempts to start casting a power while already casting one [DataField] public string AlreadyCasting = "already-casting"; /// /// The list of Familiars currently bound to this Psion. /// [DataField] public List Familiars = new(); /// /// The maximum number of Familiars a Psion may bind. /// [DataField] public int FamiliarLimit = 1; /// /// The list of all potential Assay messages that can be obtained from this Psion. /// [DataField] public List AssayFeedback = new(); /// /// The list of powers that this Psion is eligible to roll new abilities from. /// This generates the initial ability pool, but can also be modified by other systems. /// [DataField] public ProtoId PowerPool = "RandomPsionicPowerPool"; [DataField] public Dictionary AvailablePowers = new(); } }