mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-19 06:28:40 +03:00
# Description
They say Rome wasn't built in a day, well this entire PR was coded in a
single 6 hour Adderall binge. This PR represents the next big leap in
code capability for the PsionicSystem, completely reworking how Psionic
Powers are added and removed, such that like the TraitSystem, they
utilize modular functions governing how they work. Instead of there
being only 5 different hardcoded things that Psi Powers can do, there is
now a library containing 21 different modular functions, which are
slotted as desired into the power prototypes.
Additionally, a significant improvement in the logical flow of this is
that since each power is responsible for its own "removal codepath",
it's now possible to remove individual powers from a character, as
opposed to always needing to wipe the slate clean entirely.
I'm not going to add any new powers in this PR, nor am I touching the
code for the Psionic Actions themselves, that'll come in Part 2, in
which I refactor the Psionic-Actions so that they also operate on
similar stacks of modular functions.
This PR also makes extensive refactors to the PsionicPowerPrototype, as
well as PsionicAbilitiesSystem, so that it has all new hooks and
datafields for other systems to be able to modify a psion. It is now
entirely feasible to create unique "Types" of Psions, with their own
distinct power lists. It's also now possible to create "Tech Trees" of
powers, by setting up powers such that they write to and modify the
personalized pool of available powers to generate. For example,
Xenoglossy and Psychognomy are now dependent on Telepathy, and simply
won't appear in the list of available powers if a Psion doesn't first
have Telepathy.
# Changelog
🆑
- add: Psionic Refactor V3 is here! No new powers are added in this
update, but the options for creating new powers has been SIGNIFICANTLY
EXPANDED.
- add: Xenoglossy and Psychognomy now can only be rolled if you first
have the Telepathy power.
- add: Breath of Life can now only be rolled if you first have the
Healing Word power
- add: Pyrokinesis and Summon Imp now require the Pyroknetic Flare power
- add: All new Psychognomy descriptors for many pre-existing powers.
Have fun being unintentionally screamed at telepathically by someone
with the POWER OVERWHELMING trait.
(cherry picked from commit eb27db61dc42c00ea18198c094633692bf5baf0a)
172 lines
7.1 KiB
C#
172 lines
7.1 KiB
C#
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<HumanoidAppearanceComponent, GetPsychognomicDescriptorEvent>(DescribeHumanoid);
|
|
SubscribeLocalEvent<GrammarComponent, GetPsychognomicDescriptorEvent>(DescribeGrammar);
|
|
SubscribeLocalEvent<DamageableComponent, GetPsychognomicDescriptorEvent>(DescribeDamage);
|
|
SubscribeLocalEvent<MobStateComponent, GetPsychognomicDescriptorEvent>(DescribeMobState);
|
|
SubscribeLocalEvent<HungerComponent, GetPsychognomicDescriptorEvent>(DescribeHunger);
|
|
SubscribeLocalEvent<PhysicsComponent, GetPsychognomicDescriptorEvent>(DescribePhysics);
|
|
SubscribeLocalEvent<FixturesComponent, GetPsychognomicDescriptorEvent>(DescribeFixtures);
|
|
SubscribeLocalEvent<MetempsychosisKarmaComponent, GetPsychognomicDescriptorEvent>(DescribeKarma);
|
|
SubscribeLocalEvent<GlimmerSourceComponent, GetPsychognomicDescriptorEvent>(DescribeGlimmerSource);
|
|
SubscribeLocalEvent<PsionicComponent, GetPsychognomicDescriptorEvent>(DescribePsion);
|
|
SubscribeLocalEvent<InnatePsionicPowersComponent, GetPsychognomicDescriptorEvent>(DescribeInnatePsionics);
|
|
SubscribeLocalEvent<BloodSuckerComponent, GetPsychognomicDescriptorEvent>(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<HumanoidAppearanceComponent>(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.Count > 0)
|
|
{
|
|
foreach (var descriptor in component.PsychognomicDescriptors)
|
|
{
|
|
ev.Descriptors.Add(Loc.GetString(descriptor));
|
|
}
|
|
}
|
|
|
|
if (!HasComp<SpeechComponent>(uid) || HasComp<MutedComponent>(uid))
|
|
ev.Descriptors.Add(Loc.GetString("p-descriptor-dumb"));
|
|
|
|
if (!HasComp<CombatModeComponent>(uid) || HasComp<PacifiedComponent>(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<String> Descriptors = new List<String>();
|
|
}
|