From e7d40d121cc95b43538c3b6a55119e5778108198 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Fri, 8 Nov 2024 13:58:04 -0500 Subject: [PATCH] Traits V2 (#1182) # Description Traits Version 2 implements a much needed overhaul of the Trait System, changing it so that it no longer uses hardcoded nullable lists of various entries required for the trait functions, and instead accepts a *single* Modular List of Functions, and then iterates through the list like a set of instructions on how to modify the character. This PR also features a few new Functions, such as AddImplant. Anyway, rather than hardcoding a new codepath for every new function, new functions can simply be made separate from the codepath entirely, and will only be called if they are included in the trait itself. # TODO - [x] Remove ALL pre-existing trait functions and move them over to the new system. - [x] Evaluate which System Dependencies are essential for a majority of functions, and make sure that TraitSystem is caching them on behalf of the functions that need them for performance reasons. This system has a fairly high startup cost for frametime to begin with. - [x] Update all pre-existing traits such that they use the new System. # BREAKING CHANGES ALL DOWNSTREAM TRAITS WILL NEED TO BE MODIFIED TO USE THE NEW SYSTEM. # Changelog :cl: - add: Traits can now add Implants directly. --------- Signed-off-by: VMSolidus Co-authored-by: gluesniffler <159397573+gluesniffler@users.noreply.github.com> Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> --- Content.Server/Jobs/AddComponentSpecial.cs | 3 +- .../Traits/TraitSystem.Functions.cs | 265 +++++++++++++ Content.Server/Traits/TraitSystem.cs | 198 +--------- .../Traits/Prototypes/TraitPrototype.cs | 88 +---- .../Prototypes/DeltaV/Traits/altvision.yml | 12 +- .../Prototypes/DeltaV/Traits/neutral.yml | 6 +- Resources/Prototypes/Traits/disabilities.yml | 158 ++++---- .../Prototypes/Traits/inconveniences.yml | 40 +- Resources/Prototypes/Traits/languages.yml | 70 ++-- Resources/Prototypes/Traits/mental.yml | 46 ++- Resources/Prototypes/Traits/neutral.yml | 64 ++-- Resources/Prototypes/Traits/physical.yml | 357 ++++++++++-------- Resources/Prototypes/Traits/skills.yml | 158 ++++---- Resources/Prototypes/Traits/species.yml | 60 +-- 14 files changed, 850 insertions(+), 675 deletions(-) create mode 100644 Content.Server/Traits/TraitSystem.Functions.cs diff --git a/Content.Server/Jobs/AddComponentSpecial.cs b/Content.Server/Jobs/AddComponentSpecial.cs index c57d7343543..3264c54cd57 100644 --- a/Content.Server/Jobs/AddComponentSpecial.cs +++ b/Content.Server/Jobs/AddComponentSpecial.cs @@ -8,8 +8,7 @@ namespace Content.Server.Jobs [UsedImplicitly] public sealed partial class AddComponentSpecial : JobSpecial { - [DataField("components")] - [AlwaysPushInheritance] + [DataField, AlwaysPushInheritance] public ComponentRegistry Components { get; private set; } = new(); public override void AfterEquip(EntityUid mob) diff --git a/Content.Server/Traits/TraitSystem.Functions.cs b/Content.Server/Traits/TraitSystem.Functions.cs new file mode 100644 index 00000000000..7cf02b6310a --- /dev/null +++ b/Content.Server/Traits/TraitSystem.Functions.cs @@ -0,0 +1,265 @@ +using Content.Shared.Traits; +using JetBrains.Annotations; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Manager; +using Content.Shared.Implants; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; +using Content.Shared.Actions; +using Content.Server.Abilities.Psionics; +using Content.Shared.Psionics; +using Content.Server.Language; +using Content.Shared.Mood; +using Content.Server.NPC.Systems; + +namespace Content.Server.Traits; + +/// Used for traits that add a Component upon spawning in, overwriting the pre-existing component if it already exists. +[UsedImplicitly] +public sealed partial class TraitReplaceComponent : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + foreach (var (name, data) in Components) + { + var component = (Component) factory.GetComponent(name); + + var temp = (object) component; + serializationManager.CopyTo(data.Component, ref temp); + entityManager.RemoveComponent(uid, temp!.GetType()); + entityManager.AddComponent(uid, (Component) temp, true); + } + } +} + +/// +/// Used for traits that add a Component upon spawning in. +/// This will do nothing if the Component already exists. +/// +[UsedImplicitly] +public sealed partial class TraitAddComponent : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + foreach (var (name, _) in Components) + { + var component = (Component) factory.GetComponent(name); + + entityManager.AddComponent(uid, component, true); + } + } +} + +/// Used for traits that remove a component upon a player spawning in. +[UsedImplicitly] +public sealed partial class TraitRemoveComponent : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + foreach (var (name, _) in Components) + entityManager.RemoveComponent(uid, (Component) factory.GetComponent(name)); + } +} + +/// Used for traits that add an action upon a player spawning in. +[UsedImplicitly] +public sealed partial class TraitAddActions : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public List Actions { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var actionSystem = entityManager.System(); + + foreach (var id in Actions) + { + EntityUid? actionId = null; + if (actionSystem.AddAction(uid, ref actionId, id)) + actionSystem.StartUseDelay(actionId); + } + } +} + +/// Used for traits that add an Implant upon spawning in. +[UsedImplicitly] +public sealed partial class TraitAddImplant : TraitFunction +{ + [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] + [AlwaysPushInheritance] + public HashSet Implants { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var implantSystem = entityManager.System(); + implantSystem.AddImplants(uid, Implants); + } +} + +/// +/// If a trait includes any Psionic Powers, this enters the powers into PsionicSystem to be initialized. +/// If the lack of logic here seems startling, it's okay. All of the logic necessary for adding Psionics is handled by InitializePsionicPower. +/// +[UsedImplicitly] +public sealed partial class TraitAddPsionics : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public List> PsionicPowers { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var prototype = IoCManager.Resolve(); + var psionic = entityManager.System(); + + foreach (var powerProto in PsionicPowers) + if (prototype.TryIndex(powerProto, out var psionicPower)) + psionic.InitializePsionicPower(uid, psionicPower, false); + } +} + +/// Handles all modification of Known Languages. Removes languages before adding them. +[UsedImplicitly] +public sealed partial class TraitModifyLanguages : TraitFunction +{ + /// The list of all Spoken Languages that this trait adds. + [DataField, AlwaysPushInheritance] + public List? LanguagesSpoken { get; private set; } = default!; + + /// The list of all Understood Languages that this trait adds. + [DataField, AlwaysPushInheritance] + public List? LanguagesUnderstood { get; private set; } = default!; + + /// The list of all Spoken Languages that this trait removes. + [DataField, AlwaysPushInheritance] + public List? RemoveLanguagesSpoken { get; private set; } = default!; + + /// The list of all Understood Languages that this trait removes. + [DataField, AlwaysPushInheritance] + public List? RemoveLanguagesUnderstood { get; private set; } = default!; + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var language = entityManager.System(); + + if (RemoveLanguagesSpoken is not null) + foreach (var lang in RemoveLanguagesSpoken) + language.RemoveLanguage(uid, lang, true, false); + + if (RemoveLanguagesUnderstood is not null) + foreach (var lang in RemoveLanguagesUnderstood) + language.RemoveLanguage(uid, lang, false, true); + + if (LanguagesSpoken is not null) + foreach (var lang in LanguagesSpoken) + language.AddLanguage(uid, lang, true, false); + + if (LanguagesUnderstood is not null) + foreach (var lang in LanguagesUnderstood) + language.AddLanguage(uid, lang, false, true); + } +} + +/// Handles adding Moodlets to a player character upon spawning in. Typically used for permanent moodlets or drug addictions. +[UsedImplicitly] +public sealed partial class TraitAddMoodlets : TraitFunction +{ + /// The list of all Moodlets that this trait adds. + [DataField, AlwaysPushInheritance] + public List> MoodEffects { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var prototype = IoCManager.Resolve(); + + foreach (var moodProto in MoodEffects) + if (prototype.TryIndex(moodProto, out var moodlet)) + entityManager.EventBus.RaiseLocalEvent(uid, new MoodEffectEvent(moodlet.ID)); + } +} + +/// Add or remove Factions from a player upon spawning in. +[UsedImplicitly] +public sealed partial class TraitModifyFactions : TraitFunction +{ + /// + /// The list of all Factions that this trait removes. + /// + /// + /// I can't actually Validate these because the proto lives in Shared. + /// + [DataField, AlwaysPushInheritance] + public List RemoveFactions { get; private set; } = new(); + + /// + /// The list of all Factions that this trait adds. + /// + /// + /// I can't actually Validate these because the proto lives in Shared. + /// + [DataField, AlwaysPushInheritance] + public List AddFactions { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var factionSystem = entityManager.System(); + + foreach (var faction in RemoveFactions) + factionSystem.RemoveFaction(uid, faction); + + foreach (var faction in AddFactions) + factionSystem.AddFaction(uid, faction); + } +} + +/// Only use this if you know what you're doing. This function directly writes to any arbitrary component. +[UsedImplicitly] +public sealed partial class TraitVVEdit : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public Dictionary VVEdit { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var vvm = IoCManager.Resolve(); + foreach (var (path, value) in VVEdit) + vvm.WritePath(path, value); + } +} diff --git a/Content.Server/Traits/TraitSystem.cs b/Content.Server/Traits/TraitSystem.cs index afdf01524de..75771a57432 100644 --- a/Content.Server/Traits/TraitSystem.cs +++ b/Content.Server/Traits/TraitSystem.cs @@ -1,5 +1,4 @@ using System.Linq; -using Content.Shared.Actions; using Content.Server.GameTicking; using Content.Server.Players.PlayTimeTracking; using Content.Shared.Customization.Systems; @@ -10,11 +9,6 @@ using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager; using Robust.Shared.Utility; -using Content.Server.Abilities.Psionics; -using Content.Shared.Psionics; -using Content.Server.Language; -using Content.Shared.Mood; -using Content.Server.NPC.Systems; namespace Content.Server.Traits; @@ -25,11 +19,7 @@ public sealed class TraitSystem : EntitySystem [Dependency] private readonly CharacterRequirementsSystem _characterRequirements = default!; [Dependency] private readonly PlayTimeTrackingManager _playTimeTracking = default!; [Dependency] private readonly IConfigurationManager _configuration = default!; - [Dependency] private readonly SharedActionsSystem _actions = default!; - [Dependency] private readonly PsionicAbilitiesSystem _psionicAbilities = default!; [Dependency] private readonly IComponentFactory _componentFactory = default!; - [Dependency] private readonly LanguageSystem _languageSystem = default!; - [Dependency] private readonly NpcFactionSystem _factionSystem = default!; public override void Initialize() { @@ -66,191 +56,7 @@ private void OnPlayerSpawnComplete(PlayerSpawnCompleteEvent args) /// public void AddTrait(EntityUid uid, TraitPrototype traitPrototype) { - RemoveTraitComponents(uid, traitPrototype); - AddTraitComponents(uid, traitPrototype); - AddTraitActions(uid, traitPrototype); - AddTraitPsionics(uid, traitPrototype); - AddTraitLanguage(uid, traitPrototype); - RemoveTraitLanguage(uid, traitPrototype); - AddTraitMoodlets(uid, traitPrototype); - RemoveTraitFactions(uid, traitPrototype); - AddTraitFactions(uid, traitPrototype); - } - - /// - /// Removes all components defined by a Trait. It's not possible to validate component removals, - /// so if an incorrect string is given, it's basically a skill issue. - /// - /// - /// This comes before AddTraitComponents for a good reason. - /// It allows for a component to optionally be fully wiped and replaced with a new component. - /// - public void RemoveTraitComponents(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.ComponentRemovals is null) - return; - - foreach (var entry in traitPrototype.ComponentRemovals) - { - if (!_componentFactory.TryGetRegistration(entry, out var comp)) - continue; - - EntityManager.RemoveComponent(uid, comp.Type); - } - } - - /// - /// Adds all Components included with a Trait. - /// - public void AddTraitComponents(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.Components is null) - return; - - foreach (var entry in traitPrototype.Components.Values) - { - if (HasComp(uid, entry.Component.GetType())) - continue; - - var comp = (Component) _serialization.CreateCopy(entry.Component, notNullableOverride: true); - comp.Owner = uid; - EntityManager.AddComponent(uid, comp); - } - } - - /// - /// Add all actions associated with a specific Trait - /// - public void AddTraitActions(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.Actions is null) - return; - - foreach (var id in traitPrototype.Actions) - { - EntityUid? actionId = null; - if (_actions.AddAction(uid, ref actionId, id)) - { - _actions.StartUseDelay(actionId); - } - } - } - - /// - /// If a trait includes any Psionic Powers, this enters the powers into PsionicSystem to be initialized. - /// If the lack of logic here seems startling, it's okay. All of the logic necessary for adding Psionics is handled by InitializePsionicPower. - /// - public void AddTraitPsionics(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.PsionicPowers is null) - return; - - foreach (var powerProto in traitPrototype.PsionicPowers) - if (_prototype.TryIndex(powerProto, out var psionicPower)) - _psionicAbilities.InitializePsionicPower(uid, psionicPower, false); - } - - /// - /// Initialize languages given by a Trait. - /// - private void AddTraitLanguage(EntityUid uid, TraitPrototype traitPrototype) - { - AddTraitLanguagesSpoken(uid, traitPrototype); - AddTraitLanguagesUnderstood(uid, traitPrototype); - } - - /// - /// If a trait includes any Spoken Languages, this sends them to LanguageSystem to be initialized. - /// - public void AddTraitLanguagesSpoken(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.LanguagesSpoken is null) - return; - - foreach (var language in traitPrototype.LanguagesSpoken) - _languageSystem.AddLanguage(uid, language, true, false); - } - - /// - /// If a trait includes any Understood Languages, this sends them to LanguageSystem to be initialized. - /// - public void AddTraitLanguagesUnderstood(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.LanguagesUnderstood is null) - return; - - foreach (var language in traitPrototype.LanguagesUnderstood) - _languageSystem.AddLanguage(uid, language, false, true); - } - - /// - /// Remove Languages given by a Trait. - /// - private void RemoveTraitLanguage(EntityUid uid, TraitPrototype traitPrototype) - { - RemoveTraitLanguagesSpoken(uid, traitPrototype); - RemoveTraitLanguagesUnderstood(uid, traitPrototype); - } - - /// - /// Removes any Spoken Languages if defined by a trait. - /// - public void RemoveTraitLanguagesSpoken(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.RemoveLanguagesSpoken is null) - return; - - foreach (var language in traitPrototype.RemoveLanguagesSpoken) - _languageSystem.RemoveLanguage(uid, language, true, false); - } - - /// - /// Removes any Understood Languages if defined by a trait. - /// - public void RemoveTraitLanguagesUnderstood(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.RemoveLanguagesUnderstood is null) - return; - - foreach (var language in traitPrototype.RemoveLanguagesUnderstood) - _languageSystem.RemoveLanguage(uid, language, false, true); - } - - /// - /// If a trait includes any moodlets, this adds the moodlets to the receiving entity. - /// While I can't stop you, you shouldn't use this to add temporary moodlets. - /// - public void AddTraitMoodlets(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.MoodEffects is null) - return; - - foreach (var moodProto in traitPrototype.MoodEffects) - if (_prototype.TryIndex(moodProto, out var moodlet)) - RaiseLocalEvent(uid, new MoodEffectEvent(moodlet.ID)); - } - - /// - /// If a trait includes any faction removals, this removes the faction from the receiving entity. - /// - public void RemoveTraitFactions(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.RemoveFactions is null) - return; - - foreach (var faction in traitPrototype.RemoveFactions) - _factionSystem.RemoveFaction(uid, faction); - } - - /// - /// If a trait includes any factions to add, this adds the factions to the receiving entity. - /// - public void AddTraitFactions(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.AddFactions is null) - return; - - foreach (var faction in traitPrototype.AddFactions) - _factionSystem.AddFaction(uid, faction); + foreach (var function in traitPrototype.Functions) + function.OnPlayerSpawn(uid, _componentFactory, EntityManager, _serialization); } } diff --git a/Content.Shared/Traits/Prototypes/TraitPrototype.cs b/Content.Shared/Traits/Prototypes/TraitPrototype.cs index fb8ccf54640..8ee3c55637d 100644 --- a/Content.Shared/Traits/Prototypes/TraitPrototype.cs +++ b/Content.Shared/Traits/Prototypes/TraitPrototype.cs @@ -1,8 +1,7 @@ using Content.Shared.Customization.Systems; -using Content.Shared.Mood; -using Content.Shared.Psionics; using Robust.Shared.Prototypes; -using Robust.Shared.Utility; +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization; namespace Content.Shared.Traits; @@ -33,76 +32,17 @@ public sealed partial class TraitPrototype : IPrototype [DataField] public List Requirements = new(); - /// - /// The components that get added to the player when they pick this trait. - /// - [DataField] - public ComponentRegistry? Components { get; private set; } = default!; - - /// - /// The components that will be removed from a player when they pick this trait. - /// Primarily used to remove species innate traits. - /// - [DataField] - public List? ComponentRemovals { get; private set; } = default!; - - /// - /// The list of each Action that this trait adds in the form of ActionId and ActionEntity - /// - [DataField] - public List? Actions { get; private set; } = default!; - - /// - /// The list of all Psionic Powers that this trait adds. If this list is not empty, the trait will also Ensure that a player is Psionic. - /// - [DataField] - public List? PsionicPowers { get; private set; } = default!; - - /// - /// The list of all Spoken Languages that this trait adds. - /// - [DataField] - public List? LanguagesSpoken { get; private set; } = default!; - - /// - /// The list of all Understood Languages that this trait adds. - /// - [DataField] - public List? LanguagesUnderstood { get; private set; } = default!; - - /// - /// The list of all Spoken Languages that this trait removes. - /// - [DataField] - public List? RemoveLanguagesSpoken { get; private set; } = default!; - - /// - /// The list of all Understood Languages that this trait removes. - /// - [DataField] - public List? RemoveLanguagesUnderstood { get; private set; } = default!; - - /// - /// The list of all Moodlets that this trait adds. - /// - [DataField] - public List>? MoodEffects { get; private set; } = default!; - - /// - /// The list of all Factions that this trait removes. - /// - /// - /// I can't actually Validate these because the proto lives in Shared. - /// - [DataField] - public List? RemoveFactions { get; private set; } = default!; + [DataField(serverOnly: true)] + public TraitFunction[] Functions { get; private set; } = Array.Empty(); +} - /// - /// The list of all Factions that this trait adds. - /// - /// - /// I can't actually Validate these because the proto lives in Shared. - /// - [DataField] - public List? AddFactions { get; private set; } = default!; +/// This serves as a hook for trait functions to modify a player character upon spawning in. +[ImplicitDataDefinitionForInheritors] +public abstract partial class TraitFunction +{ + public abstract void OnPlayerSpawn( + EntityUid mob, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager); } diff --git a/Resources/Prototypes/DeltaV/Traits/altvision.yml b/Resources/Prototypes/DeltaV/Traits/altvision.yml index 54fec7df8b9..31a67ad350c 100644 --- a/Resources/Prototypes/DeltaV/Traits/altvision.yml +++ b/Resources/Prototypes/DeltaV/Traits/altvision.yml @@ -12,8 +12,10 @@ inverted: true traits: - DogVision - components: - - type: UltraVision + functions: + - !type:TraitAddComponent + components: + - type: UltraVision - type: trait id: DogVision @@ -29,5 +31,7 @@ inverted: true traits: - UltraVision - components: - - type: DogVision + functions: + - !type:TraitAddComponent + components: + - type: DogVision diff --git a/Resources/Prototypes/DeltaV/Traits/neutral.yml b/Resources/Prototypes/DeltaV/Traits/neutral.yml index 469fa5b34b7..f8c4119f046 100644 --- a/Resources/Prototypes/DeltaV/Traits/neutral.yml +++ b/Resources/Prototypes/DeltaV/Traits/neutral.yml @@ -5,5 +5,7 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: ScottishAccent + functions: + - !type:TraitAddComponent + components: + - type: ScottishAccent diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index 5e5028035f5..efa77391013 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -8,8 +8,10 @@ jobs: - Borg - MedicalBorg - components: - - type: PermanentBlindness + functions: + - !type:TraitAddComponent + components: + - type: PermanentBlindness - type: trait id: Nearsighted @@ -21,9 +23,11 @@ jobs: - Borg - MedicalBorg - components: - - type: PermanentBlindness - blindness: 4 + functions: + - !type:TraitAddComponent + components: + - type: PermanentBlindness + blindness: 4 - type: trait id: Narcolepsy @@ -39,29 +43,35 @@ inverted: true species: - IPC - components: - - type: Narcolepsy - timeBetweenIncidents: 300, 600 - durationOfIncident: 10, 30 + functions: + - !type:TraitAddComponent + components: + - type: Narcolepsy + timeBetweenIncidents: 300, 600 + durationOfIncident: 10, 30 - type: trait id: Pacifist category: Mental points: 6 - components: - - type: Pacified + functions: + - !type:TraitAddComponent + components: + - type: Pacified - type: trait id: Paracusia category: Auditory points: 2 - components: - - type: Paracusia - minTimeBetweenIncidents: 0.1 - maxTimeBetweenIncidents: 300 - maxSoundDistance: 7 - sounds: - collection: Paracusia + functions: + - !type:TraitAddComponent + components: + - type: Paracusia + minTimeBetweenIncidents: 0.1 + maxTimeBetweenIncidents: 300 + maxSoundDistance: 7 + sounds: + collection: Paracusia - type: trait id: Muted @@ -73,8 +83,10 @@ jobs: - Borg - MedicalBorg - components: - - type: Muted + functions: + - !type:TraitAddComponent + components: + - type: Muted - type: trait id: Uncloneable @@ -86,8 +98,10 @@ jobs: - Borg - MedicalBorg - components: - - type: Uncloneable + functions: + - !type:TraitAddComponent + components: + - type: Uncloneable - type: trait id: FrontalLisp @@ -104,8 +118,10 @@ - IPC - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: FrontalLisp + functions: + - !type:TraitAddComponent + components: + - type: FrontalLisp - type: trait id: Snoring @@ -120,8 +136,10 @@ inverted: true species: - IPC - components: - - type: Snoring + functions: + - !type:TraitAddComponent + components: + - type: Snoring - type: trait id: Sluggish @@ -137,14 +155,16 @@ inverted: true species: - Diona - components: - - type: TraitSpeedModifier - sprintModifier: 0.85 - walkModifier: 0.85 - - type: ClimbDelayModifier - climbDelayMultiplier: 1.35 - - type: LayingDownModifier - layingDownCooldownMultiplier: 1.2 + functions: + - !type:TraitAddComponent + components: + - type: TraitSpeedModifier + sprintModifier: 0.85 + walkModifier: 0.85 + - type: ClimbDelayModifier + climbDelayMultiplier: 1.35 + - type: LayingDownModifier + layingDownCooldownMultiplier: 1.2 - type: trait id: SnailPaced @@ -160,14 +180,16 @@ inverted: true species: - Diona - components: - - type: TraitSpeedModifier - sprintModifier: 0.7 - walkModifier: 0.7 - - type: ClimbDelayModifier - climbDelayMultiplier: 1.66 - - type: LayingDownModifier - layingDownCooldownMultiplier: 1.6 + functions: + - !type:TraitAddComponent + components: + - type: TraitSpeedModifier + sprintModifier: 0.7 + walkModifier: 0.7 + - type: ClimbDelayModifier + climbDelayMultiplier: 1.66 + - type: LayingDownModifier + layingDownCooldownMultiplier: 1.6 - type: trait id: BloodDeficiency @@ -183,9 +205,11 @@ inverted: true species: - IPC - components: - - type: BloodDeficiency # by default, start taking bloodloss damage at around ~21.4 minutes, - bloodLossPercentage: 0.0002333333 # then become crit ~10 minutes + functions: + - !type:TraitAddComponent + components: + - type: BloodDeficiency # By default, start taking bloodloss damage at around ~21.4 minutes, + bloodLossPercentage: 0.0002333333 # then become crit ~10 minutes - type: trait id: Hemophilia @@ -201,12 +225,14 @@ inverted: true species: - IPC - components: - - type: Hemophilia - bleedReductionModifier: 0.5 - damageModifiers: - coefficients: - Blunt: 1.1 + functions: + - !type:TraitAddComponent + components: + - type: Hemophilia + bleedReductionModifier: 0.5 + damageModifiers: + coefficients: + Blunt: 1.1 - type: trait id: Photophobia @@ -218,11 +244,13 @@ species: - Vulpkanin # This trait functions exactly as-is for the Vulpkanin trait. - Shadowkin - components: - - type: Flashable - eyeDamageChance: 0.3 - eyeDamage: 1 - durationMultiplier: 1.5 + functions: + - !type:TraitAddComponent + components: + - type: Flashable + eyeDamageChance: 0.3 + eyeDamage: 1 + durationMultiplier: 1.5 - type: trait id: Clumsy @@ -238,11 +266,13 @@ departments: - Command # Because I know for a fact people will play Captain and grief with their inability to fight back. - Security # Because I know for a fact people will play Security and grief with their inability to use guns. - components: - - type: Clumsy - clumsyDamage: - types: - Blunt: 5 - Piercing: 4 - groups: - Burn: 3 + functions: + - !type:TraitAddComponent + components: + - type: Clumsy + clumsyDamage: + types: + Blunt: 5 + Piercing: 4 + groups: + Burn: 3 diff --git a/Resources/Prototypes/Traits/inconveniences.yml b/Resources/Prototypes/Traits/inconveniences.yml index 2c0df79264f..57d166d3e38 100644 --- a/Resources/Prototypes/Traits/inconveniences.yml +++ b/Resources/Prototypes/Traits/inconveniences.yml @@ -17,9 +17,11 @@ species: - Dwarf - IPC - components: - - type: LightweightDrunk - boozeStrengthMultiplier: 2 + functions: + - !type:TraitAddComponent + components: + - type: LightweightDrunk + boozeStrengthMultiplier: 2 - type: trait id: Stutter @@ -32,12 +34,14 @@ - MedicalBorg - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: StutteringAccent - matchRandomProb: 0.1 - fourRandomProb: 0 - threeRandomProb: 0 - cutRandomProb: 0 + functions: + - !type:TraitAddComponent + components: + - type: StutteringAccent + matchRandomProb: 0.1 + fourRandomProb: 0 + threeRandomProb: 0 + cutRandomProb: 0 - type: trait id: ForeignerLight @@ -48,10 +52,12 @@ inverted: true traits: - Foreigner - components: - - type: ForeignerTrait - cantUnderstand: false # Allows to understand - baseTranslator: TranslatorForeigner + functions: + - !type:TraitAddComponent + components: + - type: ForeignerTrait + cantUnderstand: false + baseTranslator: TranslatorForeigner - type: trait id: Foreigner @@ -62,6 +68,8 @@ inverted: true traits: - ForeignerLight - components: - - type: ForeignerTrait - baseTranslator: TranslatorForeigner + functions: + - !type:TraitAddComponent + components: + - type: ForeignerTrait + baseTranslator: TranslatorForeigner diff --git a/Resources/Prototypes/Traits/languages.yml b/Resources/Prototypes/Traits/languages.yml index 06b4890c112..a8bdeff4683 100644 --- a/Resources/Prototypes/Traits/languages.yml +++ b/Resources/Prototypes/Traits/languages.yml @@ -5,10 +5,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Sign - languagesUnderstood: - - Sign + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Sign + languagesUnderstood: + - Sign - type: trait id: SolCommon @@ -21,10 +23,12 @@ inverted: true species: - Human - languagesSpoken: - - SolCommon - languagesUnderstood: - - SolCommon + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - SolCommon + languagesUnderstood: + - SolCommon - type: trait id: Tradeband @@ -37,10 +41,12 @@ inverted: true species: - Harpy - languagesSpoken: - - Tradeband - languagesUnderstood: - - Tradeband + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Tradeband + languagesUnderstood: + - Tradeband - type: trait id: Freespeak @@ -49,10 +55,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Freespeak - languagesUnderstood: - - Freespeak + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Freespeak + languagesUnderstood: + - Freespeak - type: trait id: Elyran @@ -61,10 +69,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Elyran - languagesUnderstood: - - Elyran + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Elyran + languagesUnderstood: + - Elyran - type: trait id: ValyrianStandard @@ -73,10 +83,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - ValyrianStandard - languagesUnderstood: - - ValyrianStandard + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - ValyrianStandard + languagesUnderstood: + - ValyrianStandard - type: trait id: Azaziba @@ -88,7 +100,9 @@ - Reptilian - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Azaziba - languagesUnderstood: - - Azaziba \ No newline at end of file + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Azaziba + languagesUnderstood: + - Azaziba diff --git a/Resources/Prototypes/Traits/mental.yml b/Resources/Prototypes/Traits/mental.yml index 70fbfd24b79..5b4fc56bf02 100644 --- a/Resources/Prototypes/Traits/mental.yml +++ b/Resources/Prototypes/Traits/mental.yml @@ -32,9 +32,11 @@ inverted: true traits: - LowPotential - components: - - type: PotentiaModifier - potentiaMultiplier: 1.25 + functions: + - !type:TraitReplaceComponent + components: + - type: PotentiaModifier + potentiaMultiplier: 1.25 - type: trait id: LowPotential @@ -70,9 +72,11 @@ inverted: true traits: - HighPotential - components: - - type: PotentiaModifier - potentiaMultiplier: 0.75 + functions: + - !type:TraitReplaceComponent + components: + - type: PotentiaModifier + potentiaMultiplier: 0.75 - type: trait id: LowAmplification @@ -110,8 +114,10 @@ traits: - HighAmplification - PowerOverwhelming - psionicPowers: - - LowAmplification + functions: + - !type:TraitAddPsionics + psionicPowers: + - LowAmplification - type: trait id: HighAmplification @@ -149,8 +155,10 @@ traits: - LowAmplification - PowerOverwhelming - psionicPowers: - - HighAmplification + functions: + - !type:TraitAddPsionics + psionicPowers: + - HighAmplification - type: trait id: PowerOverwhelming @@ -188,8 +196,10 @@ traits: - LowAmplification - HighAmplification - psionicPowers: - - PowerOverwhelming + functions: + - !type:TraitAddPsionics + psionicPowers: + - PowerOverwhelming - type: trait id: LowDampening @@ -226,8 +236,10 @@ inverted: true traits: - HighDampening - psionicPowers: - - LowDampening + functions: + - !type:TraitAddPsionics + psionicPowers: + - LowDampening - type: trait id: HighDampening @@ -264,5 +276,7 @@ inverted: true traits: - LowDampening - psionicPowers: - - HighDampening + functions: + - !type:TraitAddPsionics + psionicPowers: + - HighDampening diff --git a/Resources/Prototypes/Traits/neutral.yml b/Resources/Prototypes/Traits/neutral.yml index 3b63c930e8e..8ea7006c0c8 100644 --- a/Resources/Prototypes/Traits/neutral.yml +++ b/Resources/Prototypes/Traits/neutral.yml @@ -4,8 +4,10 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: PirateAccent + functions: + - !type:TraitAddComponent + components: + - type: PirateAccent - type: trait id: Accentless @@ -19,13 +21,15 @@ - MedicalBorg - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: Accentless - removes: - - type: LizardAccent - - type: MothAccent - - type: ReplacementAccent - accent: dwarf + functions: + - !type:TraitAddComponent + components: + - type: Accentless + removes: + - type: LizardAccent + - type: MothAccent + - type: ReplacementAccent + accent: dwarf - type: trait id: Southern @@ -33,8 +37,10 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: SouthernAccent + functions: + - !type:TraitAddComponent + components: + - type: SouthernAccent - type: trait id: NormalVision @@ -44,9 +50,11 @@ species: - Harpy - Vulpkanin - componentRemovals: - - UltraVision - - DogVision + functions: + - !type:TraitRemoveComponent + components: + - type: UltraVision + - type: DogVision - type: trait id: Saturnine @@ -62,8 +70,10 @@ inverted: true traits: - Sanguine - moodEffects: - - TraitSaturnine + functions: + - !type:TraitAddMoodlets + moodEffects: + - TraitSaturnine - type: trait id: Sanguine @@ -79,8 +89,10 @@ inverted: true traits: - Saturnine - moodEffects: - - TraitSanguine + functions: + - !type:TraitAddMoodlets + moodEffects: + - TraitSanguine - type: trait id: AddictionNicotine @@ -96,13 +108,17 @@ inverted: true species: - IPC - moodEffects: - - NicotineWithdrawal + functions: + - !type:TraitAddMoodlets + moodEffects: + - NicotineWithdrawal - type: trait id: Liar category: Mental - components: - - type: ReplacementAccent - replacementChance: 0.15 - accent: liar + functions: + - !type:TraitAddComponent + components: + - type: ReplacementAccent + replacementChance: 0.15 + accent: liar diff --git a/Resources/Prototypes/Traits/physical.yml b/Resources/Prototypes/Traits/physical.yml index afaaf0b2cb4..083a91382f9 100644 --- a/Resources/Prototypes/Traits/physical.yml +++ b/Resources/Prototypes/Traits/physical.yml @@ -16,9 +16,11 @@ inverted: true traits: - WillToDie - components: - - type: DeadModifier - deadThresholdModifier: 10 + functions: + - !type:TraitReplaceComponent + components: + - type: DeadModifier + deadThresholdModifier: 10 - type: trait id: WillToDie @@ -38,9 +40,11 @@ inverted: true traits: - WillToLive - components: - - type: DeadModifier - deadThresholdModifier: -15 + functions: + - !type:TraitReplaceComponent + components: + - type: DeadModifier + deadThresholdModifier: -15 - type: trait id: Tenacity @@ -60,9 +64,11 @@ inverted: true traits: - GlassJaw - components: - - type: CritModifier - critThresholdModifier: 5 + functions: + - !type:TraitReplaceComponent + components: + - type: CritModifier + critThresholdModifier: 5 - type: trait id: GlassJaw @@ -82,9 +88,11 @@ inverted: true traits: - Tenacity - components: - - type: CritModifier - critThresholdModifier: -10 + functions: + - !type:TraitReplaceComponent + components: + - type: CritModifier + critThresholdModifier: -10 - type: trait id: Vigor @@ -105,9 +113,11 @@ species: - Oni - IPC - components: - - type: StaminaCritModifier - critThresholdModifier: 10 + functions: + - !type:TraitReplaceComponent + components: + - type: StaminaCritModifier + critThresholdModifier: 10 - type: trait id: Lethargy @@ -127,9 +137,11 @@ inverted: true species: - Felinid - components: - - type: StaminaCritModifier - critThresholdModifier: -15 + functions: + - !type:TraitReplaceComponent + components: + - type: StaminaCritModifier + critThresholdModifier: -15 - type: trait id: HighAdrenaline @@ -149,10 +161,12 @@ inverted: true traits: - AdrenalDysfunction - components: - - type: Adrenaline - rangeModifier: 0.4 - inverse: true + functions: + - !type:TraitReplaceComponent + components: + - type: Adrenaline + rangeModifier: 0.4 + inverse: true - type: trait id: AdrenalDysfunction @@ -172,9 +186,11 @@ inverted: true traits: - HighAdrenaline - components: - - type: Adrenaline - rangeModifier: 0.8 + functions: + - !type:TraitReplaceComponent + components: + - type: Adrenaline + rangeModifier: 0.8 - type: trait id: Masochism @@ -190,10 +206,12 @@ inverted: true traits: - LowPainTolerance - components: - - type: PainTolerance - rangeModifier: 0.4 - inverse: true + functions: + - !type:TraitReplaceComponent + components: + - type: PainTolerance + rangeModifier: 0.4 + inverse: true - type: trait id: LowPainTolerance @@ -209,9 +227,11 @@ inverted: true traits: - Masochism - components: - - type: PainTolerance - rangeModifier: 0.6 + functions: + - !type:TraitReplaceComponent + components: + - type: PainTolerance + rangeModifier: 0.6 - type: trait id: MartialArtist @@ -224,13 +244,15 @@ - Borg - MedicalBorg - Boxer - components: - - type: Boxer - modifiers: - coefficients: - Blunt: 1.5 - Slash: 1.5 - Piercing: 1.5 + functions: + - !type:TraitReplaceComponent + components: + - type: Boxer + modifiers: + coefficients: + Blunt: 1.5 + Slash: 1.5 + Piercing: 1.5 - type: trait id: Small @@ -245,13 +267,15 @@ max: 150 - !type:CharacterWidthRequirement max: 32 - components: - - type: PseudoItem - storedOffset: 0,17 - shape: - - 0,0,1,4 - - 0,2,3,4 - - 4,0,5,4 + functions: + - !type:TraitAddComponent + components: + - type: PseudoItem + storedOffset: 0,17 + shape: + - 0,0,1,4 + - 0,2,3,4 + - 4,0,5,4 - type: trait id: TemperatureTolerance @@ -262,9 +286,11 @@ inverted: true species: - Vulpkanin # This trait functions exactly as-is for the Vulpkanin trait. - components: - - type: TemperatureProtection - coefficient: 0.1 # Enough resistance to walk into the chef's freezer, or tolerate daytime temperatures on Glacier without a jacket. + functions: + - !type:TraitReplaceComponent + components: + - type: TemperatureProtection + coefficient: 0.1 # Enough resistance to walk into the chef's freezer, or tolerate daytime temperatures on Glacier without a jacket. # These traits largely exist to demonstrate more of the "Component Removals" functionality. This way contributors # can get used to seeing that they can "Remove and Replace" a pre-existing component. @@ -283,17 +309,17 @@ inverted: true traits: - Claws - componentRemovals: - - MeleeWeapon # Remove the original innate melee attack, so that it can be replaced with a new one. - components: - - type: MeleeWeapon - soundHit: - collection: AlienClaw - animation: WeaponArcClaw - damage: - types: - Piercing: 5 # No, this isn't "OP", this is literally the worst brute damage type in the game. - # Same deal as Slash, except that a majority of all armor provides Piercing resistance. + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: AlienClaw + animation: WeaponArcClaw + damage: + types: + Piercing: 5 # No, this isn't "OP", this is literally the worst brute damage type in the game. + # Same deal as Slash, except that a majority of all armor provides Piercing resistance. - type: trait id: Claws @@ -311,18 +337,18 @@ inverted: true traits: - Talons - componentRemovals: - - MeleeWeapon # Remove the original innate melee attack, so that it can be replaced with a new one. - components: - - type: MeleeWeapon - soundHit: - collection: AlienClaw - angle: 30 - animation: WeaponArcClaw - damage: - types: - Slash: 5 # Trade stamina damage on hit for a very minor amount of extra bleed. - # Blunt also deals bleed damage, so this is more of a sidegrade. + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: AlienClaw + angle: 30 + animation: WeaponArcClaw + damage: + types: + Slash: 5 # Trade stamina damage on hit for a very minor amount of extra bleed. + # Blunt also deals bleed damage, so this is more of a sidegrade. - type: trait id: NaturalWeaponRemoval @@ -340,17 +366,17 @@ traits: - Talons - Claws - componentRemovals: - - MeleeWeapon # Remove the original innate melee attack, so that it can be replaced with a new one. - components: - - type: MeleeWeapon - soundHit: - collection: Punch - angle: 30 - animation: WeaponArcFist - damage: - types: - Blunt: 5 + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: Punch + angle: 30 + animation: WeaponArcFist + damage: + types: + Blunt: 5 - type: trait id: StrikingCalluses @@ -378,17 +404,17 @@ - !type:CharacterJobRequirement jobs: - Boxer - componentRemovals: - - MeleeWeapon - components: - - type: MeleeWeapon - soundHit: - collection: Punch - angle: 30 - animation: WeaponArcFist - damage: - types: - Blunt: 6 + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: Punch + angle: 30 + animation: WeaponArcFist + damage: + types: + Blunt: 6 - type: trait id: Spinarette @@ -406,12 +432,14 @@ - Arachne - Shadowkin - IPC - components: - - type: Sericulture - action: ActionSericulture - productionLength: 2 - entityProduced: MaterialWebSilk1 - hungerCost: 4 + functions: + - !type:TraitAddComponent + components: + - type: Sericulture + action: ActionSericulture + productionLength: 2 + entityProduced: MaterialWebSilk1 + hungerCost: 4 - type: trait id: BionicArm @@ -422,10 +450,12 @@ inverted: true jobs: - Prisoner # Bionics should be "Confiscated" from long term prisoners. - components: - - type: Prying - speedModifier: 1 - pryPowered: true + functions: + - !type:TraitAddComponent + components: + - type: Prying + speedModifier: 1 + pryPowered: true - type: trait id: PlateletFactories @@ -440,21 +470,21 @@ inverted: true species: - IPC - componentRemovals: - - PassiveDamage - components: - - type: PassiveDamage - allowedStates: - - Alive - - Critical - damageCap: 200 - damage: - groups: - Brute: -0.07 - Burn: -0.07 - Airloss: -0.07 - Toxin: -0.07 - Genetic: -0.07 + functions: # TODO: Code Platelet factories as an actual obtainable implant, and replace this with TraitAddImplant + - !type:TraitReplaceComponent + components: + - type: PassiveDamage + allowedStates: + - Alive + - Critical + damageCap: 200 + damage: + groups: + Brute: -0.07 + Burn: -0.07 + Airloss: -0.07 + Toxin: -0.07 + Genetic: -0.07 - type: trait id: DermalArmor @@ -468,11 +498,11 @@ - !type:CharacterSpeciesRequirement species: - Human - componentRemovals: - - Damageable - components: - - type: Damageable - damageModifierSet: DermalArmor + functions: + - !type:TraitReplaceComponent + components: + - type: Damageable + damageModifierSet: DermalArmor - type: trait id: CyberEyes @@ -489,12 +519,15 @@ - Photophobia - Blindness - Nearsighted - componentRemovals: - - Flashable - components: - - type: FlashImmunity - - type: EyeProtection - - type: CyberEyes + functions: + - !type:TraitRemoveComponent + components: + - type: Flashable + - !type:TraitAddComponent + components: + - type: FlashImmunity + - type: EyeProtection + - type: CyberEyes - type: trait id: CyberEyesSecurity @@ -515,10 +548,12 @@ inverted: true traits: - CyberEyesOmni - components: - - type: ShowJobIcons - - type: ShowMindShieldIcons - - type: ShowCriminalRecordIcons + functions: + - !type:TraitAddComponent + components: + - type: ShowJobIcons + - type: ShowMindShieldIcons + - type: ShowCriminalRecordIcons - type: trait id: CyberEyesMedical @@ -537,13 +572,15 @@ traits: - CyberEyesDiagnostic - CyberEyesOmni - components: - - type: ShowHealthBars - damageContainers: - - Biological - - type: ShowHealthIcons - damageContainers: - - Biological + functions: + - !type:TraitAddComponent + components: + - type: ShowHealthBars + damageContainers: + - Biological + - type: ShowHealthIcons + damageContainers: + - Biological - type: trait id: CyberEyesDiagnostic @@ -562,11 +599,13 @@ traits: - CyberEyesMedical - CyberEyesOmni - components: - - type: ShowHealthBars - damageContainers: - - Inorganic - - Silicon + functions: + - !type:TraitAddComponent + components: + - type: ShowHealthBars + damageContainers: + - Inorganic + - Silicon - type: trait id: CyberEyesOmni @@ -589,15 +628,17 @@ - CyberEyesMedical - CyberEyesDiagnostic - CyberEyesSecurity - components: - - type: ShowJobIcons - - type: ShowMindShieldIcons - - type: ShowCriminalRecordIcons - - type: ShowHealthIcons - damageContainers: - - Biological - - type: ShowHealthBars - damageContainers: - - Biological - - Inorganic - - Silicon + functions: + - !type:TraitAddComponent + components: + - type: ShowJobIcons + - type: ShowMindShieldIcons + - type: ShowCriminalRecordIcons + - type: ShowHealthIcons + damageContainers: + - Biological + - type: ShowHealthBars + damageContainers: + - Biological + - Inorganic + - Silicon diff --git a/Resources/Prototypes/Traits/skills.yml b/Resources/Prototypes/Traits/skills.yml index fb0c6d4fc91..2306d254ed5 100644 --- a/Resources/Prototypes/Traits/skills.yml +++ b/Resources/Prototypes/Traits/skills.yml @@ -2,8 +2,10 @@ id: CPRTraining category: Mental points: -4 - components: - - type: CPRTraining + functions: + - !type:TraitAddComponent + components: + - type: CPRTraining requirements: - !type:CharacterJobRequirement inverted: true @@ -19,19 +21,21 @@ id: SelfAware category: Mental points: -4 - components: - - type: SelfAware - analyzableTypes: - - Blunt - - Slash - - Piercing - - Heat - - Shock - - Cold - - Caustic - detectableGroups: - - Airloss - - Toxin + functions: + - !type:TraitAddComponent + components: + - type: SelfAware + analyzableTypes: + - Blunt + - Slash + - Piercing + - Heat + - Shock + - Cold + - Caustic + detectableGroups: + - Airloss + - Toxin - type: trait id: HeavyweightDrunk @@ -53,9 +57,11 @@ species: - Dwarf - IPC - components: - - type: LightweightDrunk - boozeStrengthMultiplier: 0.5 + functions: + - !type:TraitReplaceComponent + components: + - type: LightweightDrunk + boozeStrengthMultiplier: 0.5 - type: trait id: LiquorLifeline @@ -77,21 +83,25 @@ species: - Dwarf - IPC - components: - - type: LiquorLifeline - - type: LightweightDrunk - boozeStrengthMultiplier: 0.5 + functions: + - !type:TraitReplaceComponent + components: + - type: LiquorLifeline + - type: LightweightDrunk + boozeStrengthMultiplier: 0.5 - type: trait id: Thieving category: Physical points: -8 - components: - - type: Thieving - ignoreStripHidden: true - stealth: Subtle - stripTimeReduction: 0 - stripTimeMultiplier: 0.667 + functions: + - !type:TraitReplaceComponent + components: + - type: Thieving + ignoreStripHidden: true + stealth: Subtle + stripTimeReduction: 0 + stripTimeMultiplier: 0.667 requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -102,10 +112,12 @@ id: Voracious category: Physical points: -2 - components: - - type: ConsumeDelayModifier - foodDelayMultiplier: 0.5 - drinkDelayMultiplier: 0.5 + functions: + - !type:TraitReplaceComponent + components: + - type: ConsumeDelayModifier + foodDelayMultiplier: 0.5 + drinkDelayMultiplier: 0.5 requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -127,21 +139,25 @@ inverted: true species: - Diona - components: - - type: ClimbDelayModifier - climbDelayMultiplier: 0.35 - - type: LayingDownModifier - layingDownCooldownMultiplier: 0.5 - downedSpeedMultiplierMultiplier: 1.65 + functions: + - !type:TraitReplaceComponent + components: + - type: ClimbDelayModifier + climbDelayMultiplier: 0.35 + - type: LayingDownModifier + layingDownCooldownMultiplier: 0.5 + downedSpeedMultiplierMultiplier: 1.65 - type: trait id: LightStep category: Auditory points: -2 - components: - - type: FootstepVolumeModifier - sprintVolumeModifier: -10 - walkVolumeModifier: -10 + functions: + - !type:TraitReplaceComponent + components: + - type: FootstepVolumeModifier + sprintVolumeModifier: -10 + walkVolumeModifier: -10 requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -157,16 +173,20 @@ inverted: true species: - Harpy - components: - - type: Singer - proto: NormalSinger + functions: + - !type:TraitAddComponent + components: + - type: Singer + proto: NormalSinger - type: trait id: LatentPsychic category: Mental points: -4 - components: - - type: Psionic + functions: + - !type:TraitAddComponent + components: + - type: Psionic requirements: - !type:CharacterJobRequirement inverted: true @@ -201,9 +221,11 @@ id: PsionicInsulation category: Mental points: -10 #Buy a significant disability to get this. - components: - - type: PsionicInsulation - - type: Mindbroken + functions: + - !type:TraitAddComponent + components: + - type: PsionicInsulation + - type: Mindbroken requirements: - !type:CharacterJobRequirement inverted: true @@ -238,8 +260,10 @@ id: NaturalTelepath category: Mental points: -2 - psionicPowers: - - TelepathyPower + functions: + - !type:TraitAddPsionics + psionicPowers: + - TelepathyPower requirements: - !type:CharacterJobRequirement inverted: true @@ -275,14 +299,16 @@ id: TrapAvoider category: Physical points: -3 - components: - - type: StepTriggerImmune - whitelist: - types: - - Shard - - Landmine - - Mousetrap - - SlipEntity + functions: + - !type:TraitAddComponent + components: + - type: StepTriggerImmune + whitelist: + types: + - Shard + - Landmine + - Mousetrap + - SlipEntity requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -294,8 +320,10 @@ id: AnomalousPositronics category: Mental points: -4 - componentRemovals: - - PsionicInsulation + functions: + - !type:TraitRemoveComponent + components: + - type: PsionicInsulation requirements: - !type:CharacterSpeciesRequirement species: @@ -305,5 +333,7 @@ id: AnimalFriend category: Mental points: -4 - addFactions: - - AnimalFriend + functions: + - !type:TraitModifyFactions + addFactions: + - AnimalFriend diff --git a/Resources/Prototypes/Traits/species.yml b/Resources/Prototypes/Traits/species.yml index 17be3489fe1..a3e29b37285 100644 --- a/Resources/Prototypes/Traits/species.yml +++ b/Resources/Prototypes/Traits/species.yml @@ -2,13 +2,15 @@ id: Swashbuckler category: Physical points: -2 - components: - - type: OniDamageModifier - modifiers: - coefficients: - Blunt: 1.2 - Slash: 1.35 - Piercing: 1.2 + functions: + - !type:TraitReplaceComponent + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.2 + Slash: 1.35 + Piercing: 1.2 requirements: - !type:CharacterSpeciesRequirement species: @@ -23,13 +25,15 @@ id: Spearmaster category: Physical points: -2 - components: - - type: OniDamageModifier - modifiers: - coefficients: - Blunt: 1.2 - Slash: 1.2 - Piercing: 1.35 + functions: + - !type:TraitReplaceComponent + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.2 + Slash: 1.2 + Piercing: 1.35 requirements: - !type:CharacterSpeciesRequirement species: @@ -44,13 +48,15 @@ id: WeaponsGeneralist category: Physical points: -2 - components: - - type: OniDamageModifier - modifiers: - coefficients: - Blunt: 1.25 - Slash: 1.25 - Piercing: 1.25 + functions: + - !type:TraitReplaceComponent + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.25 + Slash: 1.25 + Piercing: 1.25 requirements: - !type:CharacterSpeciesRequirement species: @@ -65,12 +71,12 @@ id: ShadowkinBlackeye category: Mental points: 4 - componentRemovals: - - Shadowkin - components: - - type: Shadowkin - blackeyeSpawn: true + functions: + - !type:TraitReplaceComponent + components: + - type: Shadowkin + blackeyeSpawn: true requirements: - !type:CharacterSpeciesRequirement species: - - Shadowkin \ No newline at end of file + - Shadowkin