Editing Modding Tutorials/Custom Comp Classes
Jump to navigation
Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
− | + | Creating a custom comp class is a convenient way to add new functionality to RimWorld. | |
− | Creating a custom comp class is a convenient way to add new functionality to RimWorld | ||
− | = | + | == Prerequisites == |
− | + | * You need to have [[Modding Tutorials/Setting up a solution|set up your editor and environment]] | |
− | + | * You need to know [[Modding Tutorials/Writing custom code|how to write custom code]] | |
− | + | * You should probably understand Defs at least somewhat. | |
− | == | + | == def (xml) and C# structure == |
− | |||
− | |||
− | == | + | === Setup, Defs, and Classes === |
− | + | You will have some custom def and it will have something like this: | |
+ | ==== Defs (xml) ==== | ||
+ | <ThingDef ...> | ||
+ | ... | ||
+ | ... | ||
+ | <comps> | ||
+ | <<nowiki>li</nowiki> Class="MyNamespace.MyCompProperties"> | ||
+ | <myCustomCompProperty>some value</myCustomCompProperty> | ||
+ | <mySecondCompProp>4</mySecondCompProp> | ||
+ | </<nowiki>li</nowiki>> | ||
+ | <<nowiki>li</nowiki>> | ||
+ | ''<<nowiki>!--</nowiki> this is kind of like <tag>MN.MyCustomTag</tag>:-->'' | ||
+ | <compClass>MyNamespace.MyCustomThingComp</compClass> | ||
+ | </<nowiki>li</nowiki>> | ||
+ | </comps> | ||
+ | </ThingDef> | ||
+ | ==== C# ==== | ||
+ | namespace MyNamespace ''// For example, LWM.ModName - by using your '' | ||
+ | ''// handle/name/etc, you almost certainly guarantee uniqueness'' | ||
+ | { | ||
+ | '''//////////// <<nowiki>li</nowiki> Class="MyNamespace.MyCompProperties"> ////////////''' | ||
+ | public class MyCompProperties : CompProperties ''// Name this as you wish, of course'' | ||
+ | { | ||
+ | public Properties() { | ||
+ | this.compClass = typeof(MyNamespace.MyLinkedCompThing); ''// rename as appropriate'' | ||
+ | } | ||
+ | public string myCustomCompProperty; ''// Name matches def, of course'' | ||
+ | public int mySecondCompProp = 1; ''// Can set default values'' | ||
+ | } | ||
+ | |||
+ | ''// this ThingComp is used to actually access the comp property defined above'' | ||
+ | '''''// this is not "<compClass>MyNamespace.MyCustomThingComp</compClass>"''''' | ||
+ | public class MyLinkedCompThing : ThingComp | ||
+ | { | ||
+ | public string myCustomCompProperty | ||
+ | { | ||
+ | get | ||
+ | { | ||
+ | return ((MyCompProperties)this.props).myCustomCompProperty; | ||
+ | } | ||
+ | } | ||
+ | public int mySecondCompProperty ''// Have to get all the names right'' | ||
+ | { get { return ((MyCompProperties)this.props).mySecondCompProperty; } } ''//etc'' | ||
+ | } | ||
+ | '''//////////// <compClass>MyNamespace.MyCustomThingComp</compClass> ////////////''' | ||
+ | public class MyCustomThingComp : ThingComp | ||
+ | { | ||
+ | public override void CompTick() | ||
+ | { | ||
+ | // do stuff | ||
+ | } | ||
+ | public override void CompTickRare() //etc | ||
+ | public override ... // Check out Verse/ThingComp.cs for more ideas | ||
+ | } | ||
+ | } // end MyNamespace | ||
− | == | + | === Accessing your Comps === |
− | + | Just setting up your custom comps doesn't do you a lot of good if you can't access them! | |
− | |||
− | == | + | ==== Accessing CompProperty directly ==== |
− | + | This is the "hard" way, but doable if you want: | |
− | + | <source lang="C#"> | |
+ | int importantProperty = ((MyCompProperties)((ThingWithComps)myObject) | ||
+ | .GetComp<MyLinkedCompThing>().props).mySecondCompProp; | ||
+ | // The "(ThingWithComps)" cast may or may not be needed | ||
+ | </source> | ||
− | == | + | ==== Use the "get" method we created ==== |
− | {{ | + | <source lang="C#"> |
− | + | // real world example: | |
+ | SlotGroup slotGroup = GetSlotGroupInEarlierCode(); | ||
+ | MyLinkedCompThing comp = ((ThingWithComps)slotGroup.parent).GetComp<MyLinkedCompThing>(); | ||
+ | if (comp != null) { | ||
+ | string s = comp.myCustomCompProperty; | ||
+ | int x = otherObject.GetComp<MyLinkedCompThing>().mySecondCompProp; // be sure it exists, etc | ||
+ | } else { /* not a thing with my comp, etc */ } | ||
+ | </source> | ||
− | + | === Cautions, traps, etc === | |
− | + | If you have the same comp in an abstract (XML) def and attempt to redefine it in a (XML) child def, it will get counted twice. It's possible to get around this in the code, if you want to have default comps: | |
− | |||
− | |||
− | == | + | <ThingDef Name=ParentWithDefault ... Abstract=true> |
− | + | ... | |
+ | <comps> | ||
+ | <l<nowiki>i</nowiki> Class="MyCompPropertiesWithDefault"> | ||
+ | <myValue>3</myValue><!--default!--> | ||
+ | </l<nowiki>i</nowiki>> | ||
+ | </comps> | ||
+ | </ThingDef> | ||
+ | <ThingDef ParentName="ParentWihtDefault"> | ||
+ | ... | ||
+ | <comps> | ||
+ | <l<nowiki>i</nowiki> Class="MyCompPropertiesWithDefault"> | ||
+ | <myValue>5</myValue><!-- override default!--> | ||
+ | </<nowiki>l</nowiki>i> | ||
+ | </comps> | ||
+ | </ThingDef> | ||
− | |||
− | |||
− | [[Category:Modding tutorials]][[Category:Modding]] | + | public class MyLinkedCompThing : ThingComp |
+ | { | ||
+ | public string myCustomCompProperty //etc | ||
+ | |||
+ | public override void Initialize (CompProperties props) { | ||
+ | base.Initialize(props); | ||
+ | // Remove duplicate entries and ensure the last entry is the only one left | ||
+ | // This allows a default abstract def with the comp | ||
+ | // and child def to change the comp value: | ||
+ | MyCompProprtiesWithDefault[] list = this.parent.GetComps<MyCompPropertiesWithDefault>().ToArray(); | ||
+ | // Remove everything but the last entry; harmless if only one entry: | ||
+ | for (var i = 0; i < list.Length-1; i++) | ||
+ | { | ||
+ | this.parent.AllComps.Remove(list[i]); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | ///etc | ||
+ | } | ||
+ | |||
+ | [[Category:Modding tutorials]][[Category:Modding]][[Category:Defs]] |