diff --git a/Content.Server/Chat/TelepathicChatSystem.Psychognomy.cs b/Content.Server/Chat/TelepathicChatSystem.Psychognomy.cs new file mode 100644 index 00000000000..4ba990466c6 --- /dev/null +++ b/Content.Server/Chat/TelepathicChatSystem.Psychognomy.cs @@ -0,0 +1,171 @@ +using Content.Shared.Humanoid; +using Content.Shared.Damage; +using Content.Shared.Mobs.Components; +using Content.Shared.Physics; +using Content.Shared.Speech; +using Content.Shared.Speech.Muting; +using Content.Shared.CombatMode.Pacification; +using Content.Shared.CombatMode; +using Content.Shared.Nutrition.Components; +using Content.Server.Vampiric; +using Content.Shared.Abilities.Psionics; +using Content.Server.Abilities.Psionics; +using Content.Server.Cloning.Components; +using Content.Server.Psionics.Glimmer; +using Robust.Shared.GameObjects.Components.Localization; +using Robust.Shared.Enums; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Components; +using Robust.Shared.Random; + +namespace Content.Server.Chat; +public sealed partial class TelepathicChatSystem +{ + public string SourceToDescriptor(EntityUid source) + { + var ev = new GetPsychognomicDescriptorEvent(); + RaiseLocalEvent(source, ev); + + ev.Descriptors.Add(Loc.GetString("p-descriptor-ignorant")); + + return _random.Pick(ev.Descriptors); + } + private void InitializePsychognomy() + { + SubscribeLocalEvent(DescribeHumanoid); + SubscribeLocalEvent(DescribeGrammar); + SubscribeLocalEvent(DescribeDamage); + SubscribeLocalEvent(DescribeMobState); + SubscribeLocalEvent(DescribeHunger); + SubscribeLocalEvent(DescribePhysics); + SubscribeLocalEvent(DescribeFixtures); + SubscribeLocalEvent(DescribeKarma); + SubscribeLocalEvent(DescribeGlimmerSource); + SubscribeLocalEvent(DescribePsion); + SubscribeLocalEvent(DescribeInnatePsionics); + SubscribeLocalEvent(DescribeBloodsucker); + } + + private void DescribeHumanoid(EntityUid uid, HumanoidAppearanceComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.Sex != Sex.Unsexed) + ev.Descriptors.Add(component.Sex == Sex.Male ? Loc.GetString("p-descriptor-male") : Loc.GetString("p-descriptor-female")); + + // Deliberately obfuscating a bit; psionic signatures use different standards + ev.Descriptors.Add(component.Age >= 100 ? Loc.GetString("p-descriptor-old") : Loc.GetString("p-descriptor-young")); + } + + private void DescribeGrammar(EntityUid uid, GrammarComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.Gender == Gender.Male || component.Gender == Gender.Female) + ev.Descriptors.Add(component.Gender == Gender.Male ? Loc.GetString("p-descriptor-masculine") : Loc.GetString("p-descriptor-feminine")); + } + + private void DescribeDamage(EntityUid uid, DamageableComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.DamageContainerID == "CorporealSpirit") + { + ev.Descriptors.Add(Loc.GetString("p-descriptor-liminal")); + if (!HasComp(uid)) + ev.Descriptors.Add(Loc.GetString("p-descriptor-old")); + return; + } + + ev.Descriptors.Add(Loc.GetString("p-descriptor-hylic")); + } + + private void DescribeMobState(EntityUid uid, MobStateComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.CurrentState != Shared.Mobs.MobState.Critical) + return; + + ev.Descriptors.Add(Loc.GetString("p-descriptor-liminal")); + } + + private void DescribeHunger(EntityUid uid, HungerComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.CurrentThreshold > HungerThreshold.Peckish) + return; + + ev.Descriptors.Add(Loc.GetString("p-descriptor-hungry")); + } + + private void DescribeFixtures(EntityUid uid, FixturesComponent component, GetPsychognomicDescriptorEvent ev) + { + foreach (var fixture in component.Fixtures.Values) + if (fixture.CollisionMask == (int) CollisionGroup.GhostImpassable) + { + ev.Descriptors.Add(Loc.GetString("p-descriptor-pneumatic")); + return; + } + } + + private void DescribePhysics(EntityUid uid, PhysicsComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.FixturesMass < 45) + ev.Descriptors.Add(Loc.GetString("p-descriptor-light")); + else if (component.FixturesMass > 70) + ev.Descriptors.Add(Loc.GetString("p-descriptor-heavy")); + } + + private void DescribeKarma(EntityUid uid, MetempsychosisKarmaComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.Score == 0) + return; + + ev.Descriptors.Add(Loc.GetString("p-descriptor-cyclic")); + } + + private void DescribeGlimmerSource(EntityUid uid, GlimmerSourceComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.AddToGlimmer) + ev.Descriptors.Add(Loc.GetString("p-descriptor-emanative")); + else + { + ev.Descriptors.Add(Loc.GetString("p-descriptor-vampiric")); + ev.Descriptors.Add(Loc.GetString("p-descriptor-hungry")); + } + } + + // This one's also a bit of a catch-all for "lacks component" + private void DescribePsion(EntityUid uid, PsionicComponent component, GetPsychognomicDescriptorEvent ev) + { + if (component.PsychognomicDescriptors != null) + { + foreach (var descriptor in component.PsychognomicDescriptors) + { + ev.Descriptors.Add(Loc.GetString(descriptor)); + } + } + + if (!HasComp(uid) || HasComp(uid)) + ev.Descriptors.Add(Loc.GetString("p-descriptor-dumb")); + + if (!HasComp(uid) || HasComp(uid)) + ev.Descriptors.Add(Loc.GetString("p-descriptor-passive")); + + foreach (var power in component.ActivePowers) + { + // TODO: Mime counts too and isn't added back to psions yet + if (power.ID != "PyrokinesisPower" && power.ID != "NoosphericZapPower") + continue; + + ev.Descriptors.Add(Loc.GetString("p-descriptor-kinetic")); + return; + } + } + + private void DescribeInnatePsionics(EntityUid uid, InnatePsionicPowersComponent component, GetPsychognomicDescriptorEvent ev) + { + ev.Descriptors.Add(Loc.GetString("p-descriptor-gnostic")); + } + + private void DescribeBloodsucker(EntityUid uid, BloodSuckerComponent component, GetPsychognomicDescriptorEvent ev) + { + ev.Descriptors.Add(Loc.GetString("p-descriptor-vampiric")); + } +} +public sealed class GetPsychognomicDescriptorEvent : EntityEventArgs +{ + public List Descriptors = new List(); +} diff --git a/Content.Server/Chat/TelepathicChatSystem.cs b/Content.Server/Chat/TelepathicChatSystem.cs index 86e46427d27..b1338035adb 100644 --- a/Content.Server/Chat/TelepathicChatSystem.cs +++ b/Content.Server/Chat/TelepathicChatSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Chat.Managers; using Content.Server.Chat.Systems; using Content.Shared.Abilities.Psionics; +using Content.Shared.Psionics.Passives; using Content.Shared.Bed.Sleep; using Content.Shared.Chat; using Content.Shared.Database; @@ -19,9 +20,9 @@ namespace Content.Server.Chat; /// -/// Extensions for Telepathic chat stuff +/// Extensions for Telepathic chat stuff /// -public sealed class TelepathicChatSystem : EntitySystem +public sealed partial class TelepathicChatSystem : EntitySystem { [Dependency] private readonly IAdminManager _adminManager = default!; [Dependency] private readonly IChatManager _chatManager = default!; @@ -29,12 +30,23 @@ public sealed class TelepathicChatSystem : EntitySystem [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly GlimmerSystem _glimmerSystem = default!; [Dependency] private readonly ChatSystem _chatSystem = default!; - private IEnumerable GetPsionicChatClients() + + public override void Initialize() + { + base.Initialize(); + InitializePsychognomy(); + } + + private (IEnumerable normal, IEnumerable psychog) GetPsionicChatClients() { - return Filter.Empty() + var psions = Filter.Empty() .AddWhereAttachedEntity(IsEligibleForTelepathy) - .Recipients - .Select(p => p.ConnectedClient); + .Recipients; + + var normalSessions = psions.Where(p => !HasComp(p.AttachedEntity)).Select(p => p.Channel); + var psychogSessions = psions.Where(p => HasComp(p.AttachedEntity)).Select(p => p.Channel); + + return (normalSessions, psychogSessions); } private IEnumerable GetAdminClients() @@ -87,18 +99,29 @@ public void SendTelepathicChat(EntityUid source, string message, bool hideChat) _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Telepathic chat from {ToPrettyString(source):Player}: {message}"); - _chatManager.ChatMessageToMany(ChatChannel.Telepathic, message, messageWrap, source, hideChat, true, clients.ToList(), Color.PaleVioletRed); + _chatManager.ChatMessageToMany(ChatChannel.Telepathic, message, messageWrap, source, hideChat, true, clients.normal.ToList(), Color.PaleVioletRed); _chatManager.ChatMessageToMany(ChatChannel.Telepathic, message, adminMessageWrap, source, hideChat, true, admins, Color.PaleVioletRed); + if (clients.psychog.Count() > 0) + { + var descriptor = SourceToDescriptor(source); + string psychogMessageWrap; + + psychogMessageWrap = Loc.GetString("chat-manager-send-telepathic-chat-wrap-message-psychognomy", + ("source", descriptor.ToUpper()), ("message", message)); + + _chatManager.ChatMessageToMany(ChatChannel.Telepathic, message, psychogMessageWrap, source, hideChat, true, clients.psychog.ToList(), Color.PaleVioletRed); + } + if (_random.Prob(0.1f)) _glimmerSystem.Glimmer++; - if (_random.Prob(Math.Min(0.33f + ((float) _glimmerSystem.Glimmer / 1500), 1))) + if (_random.Prob(Math.Min(0.33f + (float) _glimmerSystem.Glimmer / 1500, 1))) { - float obfuscation = (0.25f + (float) _glimmerSystem.Glimmer / 2000); + float obfuscation = 0.25f + (float) _glimmerSystem.Glimmer / 2000; var obfuscated = ObfuscateMessageReadability(message, obfuscation); - _chatManager.ChatMessageToMany(ChatChannel.Telepathic, obfuscated, messageWrap, source, hideChat, false, GetDreamers(clients), Color.PaleVioletRed); + _chatManager.ChatMessageToMany(ChatChannel.Telepathic, obfuscated, messageWrap, source, hideChat, false, GetDreamers(clients.normal.Concat(clients.psychog)), Color.PaleVioletRed); } foreach (var repeater in EntityQuery()) @@ -124,4 +147,4 @@ private string ObfuscateMessageReadability(string message, float chance) return modifiedMessage.ToString(); } -} +} \ No newline at end of file diff --git a/Content.Server/Research/Oracle/OracleSystem.cs b/Content.Server/Research/Oracle/OracleSystem.cs index a93627dbd3a..15f0a474470 100644 --- a/Content.Server/Research/Oracle/OracleSystem.cs +++ b/Content.Server/Research/Oracle/OracleSystem.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.Botany; +using Content.Server.Chat; using Content.Server.Chat.Managers; using Content.Server.Chat.Systems; using Content.Server.Chemistry.Containers.EntitySystems; @@ -13,6 +14,7 @@ using Content.Shared.Interaction; using Content.Shared.Mobs.Components; using Content.Shared.Psionics.Glimmer; +using Content.Shared.Psionics.Passives; using Content.Shared.Random.Helpers; using Content.Shared.Research.Components; using Content.Shared.Research.Prototypes; @@ -29,6 +31,7 @@ namespace Content.Server.Research.Oracle; public sealed class OracleSystem : EntitySystem { [Dependency] private readonly ChatSystem _chat = default!; + [Dependency] private readonly TelepathicChatSystem _tChat = default!; [Dependency] private readonly IChatManager _chatMan = default!; [Dependency] private readonly GlimmerSystem _glimmer = default!; [Dependency] private readonly IPrototypeManager _protoMan = default!; @@ -78,11 +81,11 @@ private void OnInteractHand(Entity oracle, ref InteractHandEven return; SendTelepathicInfo(oracle, actor.PlayerSession.Channel, - Loc.GetString("oracle-current-item", ("item", oracle.Comp.DesiredPrototype.Name))); + Loc.GetString("oracle-current-item", ("item", oracle.Comp.DesiredPrototype.Name)), HasComp(args.User)); if (oracle.Comp.LastDesiredPrototype != null) SendTelepathicInfo(oracle, actor.PlayerSession.Channel, - Loc.GetString("oracle-previous-item", ("item", oracle.Comp.LastDesiredPrototype.Name))); + Loc.GetString("oracle-previous-item", ("item", oracle.Comp.LastDesiredPrototype.Name)), HasComp(args.User)); } private void OnInteractUsing(Entity oracle, ref InteractUsingEvent args) @@ -123,14 +126,25 @@ private void OnInteractUsing(Entity oracle, ref InteractUsingEv NextItem(oracle); } - private void SendTelepathicInfo(Entity oracle, INetChannel client, string message) + private void SendTelepathicInfo(Entity oracle, INetChannel client, string message, bool psychognomist = false) { - var messageWrap = Loc.GetString("chat-manager-send-telepathic-chat-wrap-message", - ("telepathicChannelName", Loc.GetString("chat-manager-telepathic-channel-name")), - ("message", message)); + if (!psychognomist) + { + var messageWrap = Loc.GetString("chat-manager-send-telepathic-chat-wrap-message", + ("telepathicChannelName", Loc.GetString("chat-manager-telepathic-channel-name")), + ("message", message)); - _chatMan.ChatMessageToOne(ChatChannel.Telepathic, - message, messageWrap, oracle, false, client, Color.PaleVioletRed); + _chatMan.ChatMessageToOne(ChatChannel.Telepathic, + message, messageWrap, oracle, false, client, Color.PaleVioletRed); + } + else + { + var descriptor = _tChat.SourceToDescriptor(oracle); + var psychogMessageWrap = Loc.GetString("chat-manager-send-telepathic-chat-wrap-message-psychognomy", + ("source", descriptor.ToUpper()), ("message", message)); + + _chatMan.ChatMessageToOne(ChatChannel.Telepathic, message, psychogMessageWrap, oracle, false, client, Color.PaleVioletRed); + } } private bool IsCorrectItem(EntityPrototype given, EntityPrototype target) diff --git a/Content.Shared/Psionics/Passives/Psychognomy/PsychognomistComponent.cs b/Content.Shared/Psionics/Passives/Psychognomy/PsychognomistComponent.cs new file mode 100644 index 00000000000..5108ef5b410 --- /dev/null +++ b/Content.Shared/Psionics/Passives/Psychognomy/PsychognomistComponent.cs @@ -0,0 +1,5 @@ +namespace Content.Shared.Psionics.Passives; + +[RegisterComponent] +public sealed partial class PsychognomistComponent : Component { } + diff --git a/Content.Shared/Psionics/PsionicComponent.cs b/Content.Shared/Psionics/PsionicComponent.cs index 9ff332327a4..63529576152 100644 --- a/Content.Shared/Psionics/PsionicComponent.cs +++ b/Content.Shared/Psionics/PsionicComponent.cs @@ -140,5 +140,12 @@ private set /// [ViewVariables(VVAccess.ReadWrite)] public float CurrentDampening; + + /// + /// 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 = null; } } diff --git a/Resources/Locale/en-US/psionics/psionic-chat.ftl b/Resources/Locale/en-US/psionics/psionic-chat.ftl index b7fe23b7510..45444d0d10a 100644 --- a/Resources/Locale/en-US/psionics/psionic-chat.ftl +++ b/Resources/Locale/en-US/psionics/psionic-chat.ftl @@ -1,4 +1,5 @@ chat-manager-send-telepathic-chat-wrap-message = {$telepathicChannelName}: {$message} +chat-manager-send-telepathic-chat-wrap-message-psychognomy = {$source}: {$message} chat-manager-send-telepathic-chat-wrap-message-admin = {$source} (Ψ): {$message} chat-manager-telepathic-channel-name = TELEPATHIC hud-chatbox-select-channel-Telepathic = Telepathic diff --git a/Resources/Locale/en-US/psionics/psionic-powers.ftl b/Resources/Locale/en-US/psionics/psionic-powers.ftl index 535c4ef3286..ad6bbef02bd 100644 --- a/Resources/Locale/en-US/psionics/psionic-powers.ftl +++ b/Resources/Locale/en-US/psionics/psionic-powers.ftl @@ -74,6 +74,12 @@ xenoglossy-power-initialization-feedback = psionic-language-power-metapsionic-feedback = The noösphere flows freely through {CAPITALIZE($entity)}, who seems to digest it and pass it back out undisturbed. +# Psychognomy +psychognomy-power-description = You have some vague sense of the form of the source of telepathic messages. +psychognomy-power-initialization-feedback = + I have pierced the veil, and I know I'm not alone. More concerning, the piercing I made seems to be still indefinitely permeable. + When energy passes through the perforations in the noösphere, I get a faint glimpse of the material origin. + # Telepathy telepathy-power-description = You are capable of both sending and receiving telepathic messages. telepathy-power-initialization-feedback = diff --git a/Resources/Locale/en-US/psionics/psychognomic-descriptors.ftl b/Resources/Locale/en-US/psionics/psychognomic-descriptors.ftl new file mode 100644 index 00000000000..d91f0f25245 --- /dev/null +++ b/Resources/Locale/en-US/psionics/psychognomic-descriptors.ftl @@ -0,0 +1,23 @@ +p-descriptor-mysterious = mysterious +p-descriptor-male = male +p-descriptor-female = female +p-descriptor-young = young +p-descriptor-old = old +p-descriptor-masculine = masculine +p-descriptor-feminine = feminine +p-descriptor-hylic = hylic +p-descriptor-pneumatic = pneumatic +p-descriptor-liminal = liminal +p-descriptor-bound = bound +p-descriptor-ignorant = ignorant +p-descriptor-demiurgic = demiurgic +p-descriptor-emanative = emanative +p-descriptor-light = light +p-descriptor-heavy = heavy +p-descriptor-cyclic = cyclic +p-descriptor-hungry = hungry +p-descriptor-vampiric = vampiric +p-descriptor-kinetic = kinetic +p-descriptor-gnostic = gnostic +p-descriptor-dumb = dumb +p-descriptor-passive = passive \ No newline at end of file diff --git a/Resources/Migrations/eeMigration.yml b/Resources/Migrations/eeMigration.yml index 26713f6cbac..8d95da53bcb 100644 --- a/Resources/Migrations/eeMigration.yml +++ b/Resources/Migrations/eeMigration.yml @@ -1,3 +1,7 @@ # 2024-06-08 CrateFunPlushie: CrateFunToyBox CrateFunLizardPlushieBulk: CrateFunToyBox + +# 2024-08-27 +Oracle: OracleSpawner +SophicScribe: SophicScribeSpawner \ No newline at end of file diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/NPCs/familiars.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/NPCs/familiars.yml index 4c623cb02ee..364907ff9c4 100644 --- a/Resources/Prototypes/DeltaV/Entities/Mobs/NPCs/familiars.yml +++ b/Resources/Prototypes/DeltaV/Entities/Mobs/NPCs/familiars.yml @@ -92,6 +92,9 @@ nameSegments: [names_golem] - type: Psionic removable: false + psychognomicDescriptors: + - p-descriptor-bound + - p-descriptor-cyclic - type: InnatePsionicPowers powersToAdd: - PyrokinesisPower diff --git a/Resources/Prototypes/Entities/Markers/Spawners/statues.yml b/Resources/Prototypes/Entities/Markers/Spawners/statues.yml new file mode 100644 index 00000000000..4a3b89e4019 --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/Spawners/statues.yml @@ -0,0 +1,25 @@ +- type: entity + name: Oracle Spawner + id: OracleSpawner + parent: MarkerBase + components: + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - type: ConditionalSpawner + prototypes: + - Oracle + +- type: entity + name: Sophia Spawner + id: SophicScribeSpawner + parent: MarkerBase + components: + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - type: ConditionalSpawner + prototypes: + - SophicScribe diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml index bc049abb83a..47ce0f9d490 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml @@ -99,6 +99,8 @@ speechVerb: Ghost - type: Psionic removable: false + psychognomicDescriptors: + - p-descriptor-vampiric - type: InnatePsionicPowers powersToAdd: - XenoglossyPower diff --git a/Resources/Prototypes/Entities/Mobs/Player/familiars.yml b/Resources/Prototypes/Entities/Mobs/Player/familiars.yml index 11c47972f31..ab479e0332f 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/familiars.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/familiars.yml @@ -34,8 +34,11 @@ - PsionicInterloper #Nyano - Summary: makes a part of the psionic faction. - type: Alerts - type: Familiar - - type: Psionic #Nyano - Summary: Makes psionic on creation. + - type: Psionic removable: false + psychognomicDescriptors: + - p-descriptor-bound + - p-descriptor-cyclic - type: InnatePsionicPowers powersToAdd: - TelepathyPower diff --git a/Resources/Prototypes/Entities/Structures/Specific/oracle.yml b/Resources/Prototypes/Entities/Structures/Specific/oracle.yml index 64f3b2c4d9b..b60906b55e0 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/oracle.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/oracle.yml @@ -18,6 +18,11 @@ - type: Actions - type: Psionic removable: false + psychognomicDescriptors: + - p-descriptor-old + - p-descriptor-demiurgic + - p-descriptor-mysterious + - p-descriptor-emanative - type: InnatePsionicPowers powersToAdd: - XenoglossyPower diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml index b00e93e783d..1a065b001c1 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml @@ -31,6 +31,10 @@ - type: Actions - type: Psionic removable: false + psychognomicDescriptors: + - p-descriptor-old + - p-descriptor-demiurgic + - p-descriptor-mysterious - type: InnatePsionicPowers powersToAdd: - XenoglossyPower diff --git a/Resources/Prototypes/Nyanotrasen/psionicPowers.yml b/Resources/Prototypes/Nyanotrasen/psionicPowers.yml index 7cb38b2c543..0781122b8ec 100644 --- a/Resources/Prototypes/Nyanotrasen/psionicPowers.yml +++ b/Resources/Prototypes/Nyanotrasen/psionicPowers.yml @@ -6,6 +6,7 @@ #TelegnosisPower: 1 PsionicRegenerationPower: 1 XenoglossyPower: 0.75 + PsychognomyPower: 0.75 MassSleepPower: 0.3 # PsionicInvisibilityPower: 0.15 MindSwapPower: 0.15 diff --git a/Resources/Prototypes/Psionics/psionics.yml b/Resources/Prototypes/Psionics/psionics.yml index 132365a37b0..b8f798d4b63 100644 --- a/Resources/Prototypes/Psionics/psionics.yml +++ b/Resources/Prototypes/Psionics/psionics.yml @@ -120,6 +120,15 @@ initializationFeedback: xenoglossy-power-initialization-feedback metapsionicFeedback: psionic-language-power-feedback # Reuse for telepathy, clairaudience, etc +- type: psionicPower + id: PsychognomyPower #i.e. reverse physiognomy + name: Psychognomy #psycho- + -gnomy. I reccomend starting with your language's equilvalent of "physiognomy" and working backwards. i.e. психо(г)номика + description: psychognomy-power-description + components: + - type: Psychognomist + initializationFeedback: psychognomy-power-initialization-feedback + metapsionicFeedback: psionic-language-power-feedback + - type: psionicPower id: TelepathyPower name: Telepathy @@ -127,4 +136,4 @@ components: - type: Telepathy initializationFeedback: telepathy-power-initialization-feedback - metapsionicFeedback: psionic-language-power-feedback # Reuse for telepathy, clairaudience, etc \ No newline at end of file + metapsionicFeedback: psionic-language-power-feedback # Reuse for telepathy, clairaudience, etc