Difference between revisions of "Modding Tutorials/Custom Comp Classes"
Jump to navigation
Jump to search
m (→C#) |
(→Cautions, traps, etc: better example) |
||
Line 72: | Line 72: | ||
=== Cautions, traps, etc === | === Cautions, traps, etc === | ||
If you have the same comp in an abstract def and attempt to redefine it in a child def, it will get counted twice. It's possible to get around this in the code, if you want to have default comps: | If you have the same comp in an abstract def and attempt to redefine it in a 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> | ||
+ | |||
+ | |||
public class MyLinkedCompThing : ThingComp | public class MyLinkedCompThing : ThingComp | ||
Line 82: | Line 101: | ||
// This allows a default abstract def with the comp | // This allows a default abstract def with the comp | ||
// and child def to change the comp value: | // 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: | // Remove everything but the last entry; harmless if only one entry: | ||
for (var i = 0; i < list.Length-1; i++) | for (var i = 0; i < list.Length-1; i++) |
Revision as of 16:33, 15 December 2018
Creating a custom comp class is a convenient way to add new functionality to RimWorld.
Prerequisites
- You need to have set up your editor and environment
- You need to know 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> <li Class="MyNamespace.MyCompProperties"> <myCustomCompProperty>some value</myCustomCompProperty> <mySecondCompProp>4</mySecondCompProp> </li> <li> <!-- this is kind of like <tag>MN.MyCustomTag</tag>:--> <compClass>MyNamespace.MyCustomThingComp</compClass> </li> </comps> </ThingDef>
C#
namespace MyNamespace // For example, LWM.ModName - by using your // handle/name/etc, you almost certainly guarantee uniqueness { //////////// <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! '''To do''' === Cautions, traps, etc === If you have the same comp in an abstract def and attempt to redefine it in a 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 Class="MyCompPropertiesWithDefault"> <myValue>3</myValue> </li> </comps> </ThingDef> <ThingDef ParentName="ParentWihtDefault"> ... <comps> <li Class="MyCompPropertiesWithDefault"> <myValue>5</myValue> </li> </comps> </ThingDef>
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 }