Need help with LoadDataFromXmlCustom

Started by dninemfive, September 16, 2018, 08:02:02 PM

Previous topic - Next topic

dninemfive

So I'm working on updating Fertile Fields (with permission, of course), and I've fixed all errors but one. When I load the game, I get a series of errors like this:

Quote
XML format error: List item found with name that is not <li>, and which does not have a custom XML loader method, in <products><ChunkGranite>1</ChunkGranite></products>

The relevant def is as follows:


<ThingDef ParentName="RFF_TerraformBase">
<defName>Terraform_Stone-RockyDirt</defName>
<label>rocky dirt from stone</label>
<description>PLACE ON: Rough or Smooth Stone.\nRESULT: Rocky Dirt.\nGAIN: Rock Chunk (Sometimes).</description>
<modExtensions>
<li Class="FF_Code.Terrain">
<above>
<li>Granite_Rough</li> <!-- *any* vanilla or modded rough or smooth stone -->
</above>
<result>RockySoil</result>
<products>
<ChunkGranite>1</ChunkGranite> <!-- chance of appropriate chunk -->
</products>
</li>
</modExtensions>
<statBases>
<WorkToBuild>5000</WorkToBuild>
</statBases>
<researchPrerequisites><li>RFF_Terraforming</li></researchPrerequisites>
<costList>
<PileofDirt>1</PileofDirt>
</costList>
<uiIconPath>Icons/Stone-RockyDirt</uiIconPath>
</ThingDef>


What's interesting is that there are a number of vanilla defs which do this same thing without (as far as I can tell, with extensive ILSpy searching) having any different XML loading than a <li/> list would, for example RecipeDefs' products and skill requirements. Products, for example, are simply initialized as List<ThingDefCountClass> products = new List<ThingDefCountClass>(). My code does the same thing (namely
public class Terrain : DefModExtension
    {
        public List<TerrainDef> above;
        public List<TerrainDef> near;
        public TerrainDef result;
        public List<ThingCountClass> products = new List<ThingCountClass>();
    }


) but doesn't actually seem to load.

TL;DR How does the game determine how to load non-standard (non-<li/>-based) lists, and how can I write a custom XML loader?

mipen

The xml custom loading method is defined in the list item class. So:
ThingDefCountClass.XMLLoad()
Im not sure exactly what the method is called but it's something along those lines. Add that method to your list item class and add the proper logic and it will load. IIRC the method doesn't override anything so it must be invoke through reflection

dninemfive

#2
Thanks. The method name, by the way, is LoadDataFromXmlCustom(). I'm still confused, however, as things which hold a list defined in the way my XML does, such as RecipeDef, simply initialize as List<ThingCountClass> products = new List<ThingCountClass(); and allow ThingCountClass's LoadDataFromXMLCustom() to actually handle individual loading... but I'm also making a List<ThingCountClass> and that's not working.