-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Mod Friendly Overrides is a Def injector that uses simple yet powerful xml syntax to alter vanilla Core Rimworld XML files before they are processed.
It introduces the Override.Def which is the base of the whole mod.
<Override.Def Target="Gold">
<description>Basic Usage</description>
</Override.Def>
In this example MFO is directed to find the target defName "Gold". After MFO locates the target it proceeds to replace the contents of every field it finds inside, in this case the field ThingDef.description is set to "Basic Usage". When you load Rimworld, you will find that the description of Gold has been changed.
Override.Def has the Filter attribute, their job is to select a defName for MFO to inject the fields, these simplify many tasks and can even target multiple defName. Several useful filters are offered by default, they are pretty flexible and if none suits your needs, MFO offers an interface for custom Filters.
By default, if Filter attribute is ommited, it sets to the Name Filter. It overrides a single named def target.
- Type
- Optional. Defaults to ThingDef. A classType to be searched in the DefDatabase, ThingDef, RaceDef, RecipeDef, etc. Even modded Defs are supported.
- Target
- Required. The defName of your target, pretty much the identifier. It can be given a comma separated list of defNames.
<Override.Def Filter="Name" Type="ThingDef" Target="Jade,Silver">
<description>Name Filter test</description>
</Override.Def>
<!-- Shiny metals -->
<Override.Def Target="Gold,Silver">
<description>Component Insert test</description>
<comps>
<li Class="CompProperties_Glower">
<glowRadius>15</glowRadius>
<glowColor>(217,112,33,0)</glowColor>
</li>
</comps>
</Override.Def>
<!-- ResearchPrerequisites -->
<Override.Def Target="TableSculpting">
<description>Research Prerequisites test</description>
<researchPrerequisites>
<li>MicroelectronicsBasics</li>
</researchPrerequisites>
</Override.Def>
<!-- Miniaturisation -->
<Override.Def Target="TableButcher">
<description>Miniaturisation test</description>
<minifiedDef>MinifiedFurniture</minifiedDef>
</Override.Def>
Searches ThingDef.category for matches. Multiple Return.
- Category
- It's the enum from Verse.ThingCategory
- It can be: None, Pawn, Item, Plant, Building, Filth, Projectile, Mote, Ethereal, Attachment, Skyfaller
<Override.Def Filter="Category" Category="Skyfaller">
<description>Category Filter test</description>
</Override.Def>
Searches ThingDef.race. Multiple return.
- Race
- Available races are: Human, Humanlike, Animal, Mechanoid
<Override.Def Filter="Race" Race="Humanlike">
<description>Race Filter test</description>
</Override.Def>
Searches ThingDef.thingClass. Multiple return.
- Target
- Any subclass of Rimworld.Thing, even modded.
<Override.Def Filter="Class" Target="Medicine">
<description>Class Filter test</description>
</Override.Def>
Helpful to add items to multiple traders in one go. Searches through TraderKinDefs. Pretty much a regex for their defName. Multiple return.
- Category
- Required. Available Categories: Caravan, FactionBase, Orbital, Visitor
- Tech
- Optional. Available Tech: Neolithic, Outlander
- Role
- Required. Available Roles: BulkGoods, CombatSupplier, Exotic, PirateMerchant, Slaver, Standard
<Override.Def Filter="Trader" Category="Caravan" Tech="Outlander" Role="BulkGoods">
<stockGenerators>
<li Class="StockGenerator_SingleDef">
<thingDef>Jade</thingDef>
<countRange>
<min>400</min>
<max>600</max>
</countRange>
</li>
</stockGenerators>
</Override.Def>
A very flexible filter, can filter for any field in the Type. It understand all the basic types, string, numeric, enums. It tries to suit the value to the selected field, very friendly and forgiving.
- Type
- Required. The class Type to target. Can be any Def.
- Match
- Required. An expression to filter for. Separate multiple fields with or or and. The syntax is field=Value.
<Override.Def Filter="Match" Type="ThingDef" Match="mineable=True">
<description>Match Filter test</description>
</Override.Def>
An even more powerful version of the Match filter, when you want to do complex operations, it can do math, call functions and more. It's seemingly similar to SQL language. The tradeof is in complexity. It's more rigid when it comes to field values to compare, obeys all LinQ rules.
- Type
- Required. The class Type to target. Can be any Def.
- Match
- Required. A valid LinQ Expression.
<Override.Def Filter="Linq" Type="ThingDef" Match="mineable=True">
<description>Linq Filter test</description>
</Override.Def>
When it comes to lists MFO offers modes of operation. By Default MFO tries to insert your xml at the beginning when it encounters a field of list type. Sometimes it may not be desired. You may want to replace an element or clear the entire list, or perhaps insert in a determined index or simply append at the end.
This is the default mode of operation. It accepts the Index="n" attribute to select where it should insert in the list. By default Index is "0". If Index is out of bounds, it'll append.
<!-- Mode="Insert" -->
<Override.Def Target="Apparel_CowboyHat">
<statBases Mode="Insert" Index="2">
<WorkToMake>700</WorkToMake>
</statBases>
</Override.Def>
It merely inserts at the end of the list. No arguments needed.
<!-- Mode="Append" -->
<Override.Def Target="Apparel_CowboyHat">
<statBases Mode="Append">
<WorkToMake>700</WorkToMake>
</statBases>
</Override.Def>
As the name implies, it clears the list. Then inserts the contents. Use with care. Useful when dealing with ingredients, you don't want to leave the last ones.
<!-- Mode="Clear" -->
<Override.Def Target="MakeAdvancedComponent">
<ingredients Mode="Clear">
<li>
<filter>
<thingDefs>
<li>Plasteel</li>
</thingDefs>
</filter>
<count>5</count>
</li>
<li>
<filter>
<thingDefs>
<li>Component</li>
</thingDefs>
</filter>
<count>1</count>
</li>
</ingredients>
<fixedIngredientFilter>
<thingDefs>
<li>Component</li>
<li>Plasteel</li>
</thingDefs>
</fixedIngredientFilter>
</Override.Def>
Replace Mode makes use of Comparers which can be custom by inheriting from FieldComparer. It evaluates the contents of the field to replace a certain element in the list. MFO comes with the following stock Comparers: StatModifier, VerbProperties, CompProperties. By default it'll try to infer which it can use if you omit the Replace attribute.
public abstract class FieldComparer {
public bool delay;
public FieldComparer(bool delay) {
this.delay = delay;
}
public abstract bool Compare (object x, object y);
}
<!-- Mode="Replace" with inferred, custom comparer or stock -->
<Override.Def Target="Apparel_CowboyHat">
<statBases Mode="Replace">
<WorkToMake>700</WorkToMake>
</statBases>
<statBases Mode="Replace" Replace="Override.StatModifierComparer">
<ArmorRating_Blunt>0.05</ArmorRating_Blunt>
</statBases>
<statBases Mode="Replace" Replace="StatModifier">
<ArmorRating_Sharp>0.05</ArmorRating_Sharp>
</statBases>
</Override.Def>
Parsers convert strings to values before setting the value in the field. You will want to implement from Override.FieldParser. Their use case is for things that can't be expressed in simple text. MFO comes with Default and ITab parser. Default parser uses Rimworld own XmlParser to extract objects from text. It's implyed when omited.
public interface FieldParser {
Func<XmlNode, object> makeParser(params Type[] arguments);
}
<!-- Parser="ITab" -->
<Override.Def Filter="Race" Race="Humanlike">
<inspectorTabs>
<li>Hospitality.ITab_Pawn_Guest</li>
</inspectorTabs>
<inspectorTabsResolved Mode="Append" Parser="ITab">
<li>Hospitality.ITab_Pawn_Guest</li>
</inspectorTabsResolved>
</Override.Def>
You will want to enable debugging when you are testing filters. To enable verbose output you add the attribute Debug="True" to the Override.Def tag. It'll output helpful information in Rimworld console.
<Override.Def Target="Gold" Debug="True">
<description>Debug test</description>
</Override.Def>