RogueLibs provides classes and methods to create custom traits, and an interface to make traits updateable. Just like items, custom traits derive from a hook class, CustomTrait, and their functionality can be expanded with interfaces: ITraitUpdateable, just one in this case. If you want the trait to have some kind of a passive effect, then you might need to patch that in yourself.
CustomTrait classTo make a custom trait, you need to create a class deriving from CustomTrait:
public class MyAwesomeTrait : CustomTrait{ /* ... */}There are 2 methods that you need to implement:
public class MyAwesomeTrait : CustomTrait{ public override void OnAdded() { /* ... */ } public override void OnRemoved() { /* ... */ }}OnAdded is called when the trait is added to a character, and OnRemoved is called when it's removed from a character.
You can make your trait updateable by implementing the ITraitUpdateable interface:
public class MyAwesomeTrait : CustomTrait, ITraitUpdateable{ public void OnUpdated(TraitUpdatedArgs e) { /* ... */ }}OnUpdated works like Unity's Update, but with a settable interval (default is 1 second):
public void OnUpdated(TraitUpdatedArgs e) { e.UpdateDelay = 0.5f; // 2 updates per second /* ... */ }Just call the CreateCustomTrait method with your trait's type as a parameter:
public class MyAwesomeTrait : CustomTrait{ [RLSetup] public static void Setup() { RogueLibs.CreateCustomTrait<MyAwesomeTrait>(); }}See more about the RLSetup attribute here.
You can set your trait's name and description using WithName and WithDescription methods:
public class MyAwesomeTrait : CustomTrait{ [RLSetup] public static void Setup() { RogueLibs.CreateCustomTrait<MyAwesomeTrait>() .WithName(new CustomNameInfo("My Awesome Trait")) .WithDescription(new CustomNameInfo("My Awesome Trait is very cool and does a lot of great stuff, and it's also awesome.")); }}You can do the same with sprites and unlocks:
public class MyAwesomeTrait : CustomTrait{ [RLSetup] public static void Setup() { RogueLibs.CreateCustomTrait<MyAwesomeTrait>() .WithName(new CustomNameInfo("My Awesome Trait")) .WithDescription(new CustomNameInfo("My Awesome Trait is very cool and does a lot of great stuff, and it's also awesome.")) // the sprite will be displayed only in the menus (optional) .WithSprite(Properties.Resources.MyAwesomeTrait) .WithUnlock(new TraitUnlock { UnlockCost = 10, CharacterCreationCost = 5 }); }}See Custom Names, Custom Sprites for more info.
You can use the following properties when initializing TraitUnlocks:
| Property | Default | Description |
|---|---|---|
UnlockCost | 0 | Unlock cost of the trait, in nuggets. If set to 0, it will unlock automatically, once all prerequisites are unlocked. |
CharacterCreationCost | 1 | Cost of the trait in Character Creation, in points. |
IsAvailable | true | Determines whether the trait is available in the Traits menu and on level-ups. If the trait is negative, set it to false. |
IsAvailableInCC | true | Determines whether the trait is available in the Character Creation menu. |
Cancellations | Determines what traits cannot co-exist with this trait. | |
Prerequisites | Determines what unlocks must be unlocked in order to unlock this trait. | |
Recommendations | Just shows these unlocks in a separate Recommendations paragraph in the menus. |
Other properties should not be used during initialization.
using System;using RogueLibsCore;namespace MyAwesomeMod{ public class Smoker : CustomTrait, ITraitUpdateable { [RLSetup] public static void Setup() { RogueLibs.CreateCustomTrait<Smoker>() .WithName(new CustomNameInfo("Smoker")) .WithDescription(new CustomNameInfo("Randomly cough, alerting enemies")) .WithUnlock(new TraitUnlock { CharacterCreationCost = -4 }); RogueLibs.CreateCustomName("Smoker_Cough1", NameTypes.Dialogue, new CustomNameInfo("*Cough*")); RogueLibs.CreateCustomName("Smoker_Cough2", NameTypes.Dialogue, new CustomNameInfo("*Cough* *CouGH*")); RogueLibs.CreateCustomName("Smoker_Cough3", NameTypes.Dialogue, new CustomNameInfo("*coUGH* *COUgh*")); } public override void OnAdded() { } public override void OnRemoved() { } public void OnUpdated(TraitUpdatedArgs e) { e.UpdateDelay = 5f; int rnd = new Random().Next(0, 5); if (rnd == 0) { rnd = new Random().Next(3) + 1; Owner.SayDialogue($"Smoker_Cough{rnd}"); gc.audioHandler.Play(Owner, VanillaAudio.AgentAnnoyed); Noise noise = gc.spawnerMain.SpawnNoise(Owner.tr.position, 1f, Owner, "Attract", Owner); noise.distraction = true; } } }}