Injected/dynamic Defs & stockpile (filters)

Started by DoctorVanGogh, June 24, 2017, 04:10:05 AM

Previous topic - Next topic

DoctorVanGogh

I'm working on an assembly based mod that'll probably create tons of runtime generated Defs.

I've got things working insofar that I can create all the ThingDefs I need, I can spawn the items in (using debug mode) and they happily persists though saves.

Just for the life of me I cannot get the new Defs to show up in stockpile filters. If I do an xml based definition like
Code (xml) Select
  <ThingDef>
    <defname>R3Bar</defname>
    <label>R3Bar</label>
<thingClass>ThingWithComps</thingClass>
<category>Item</category>
<description>This is an R³ bar item</description>
    <thingCategories>
      <li>BodyPartsReclaimed</li>
      <li>BodyParts</li>
    </thingCategories>
    <graphicData>
        <texPath>Things/Item/BodyPart/Organ</texPath>
        <graphicClass>Graphic_Single</graphicClass>       
    </graphicData>
<comps>
<li Class="CompProperties_Forbiddable"></li>
</comps>   
    <selectable>true</selectable>
  </ThingDef>
it'll happily appear in the filter.

If I do the code equivalent of
Code (csharp) Select

var foo = new ThingDef {
defName = "R3Foo",
label = "R3Foo",
thingClass = typeof(ThingWithComps),
category = ThingCategory.Item,
description = "This is an R3 foo item",
thingCategories = new List<ThingCategoryDef> {
   DefDatabase<ThingCategoryDef>.GetNamed("BodyParts"),
   DefDatabase<ThingCategoryDef>.GetNamed("BodyPartsReclaimed"),
   },
graphicData = new GraphicData {
   graphicClass = typeof(Graphic_Single),
   texPath = "Things/Item/BodyPart/Organ"
   },
comps = new List<CompProperties> {new CompProperties_Forbiddable()},
selectable = true,                         
};

InjectedDefHasher.GiveShortHasToDef(foo, typeof(ThingDef));
DefDatabase<ThingDef>.Add(foo);

it wont show.

What am I doing wrong? Do I need to call some method to force a refresh/rebuild on the filter tree?
I tried doing things by hand (deriving from Mod) and using HugsLib (which talks about injected Defs in their DefsLoaded override so expected more success there) - sadly things just don't work yet.

I can see a really convoluted rube-goldberg injection method of writing a custom xml def file inside the mod directory on assembly load, then creating a DefPackage for that, adding it to the ModContent and hoping this works.... But honestly, that's just plain wrong.... Besides, I fully expect this to fail too.

So... Any ideas? Suggestions? Any working examples out there?

[attachment deleted by admin due to age]
Appreciate my mods? Buy me a coffee

DoctorVanGogh

For posterity's sake - and if anyone else runs into this problem:

Solution A (the hacky one - manually create the correct 'mirrored' structures in the categories):

        foreach (ThingDef def in injected) {
            foreach (var thingCategoryDef in def .thingCategories) {
                thingCategoryDef.childThingDefs.Add(def );
            }
        }


Solution B: (How vanilla does it)
- Create the Blueprints in DefGenerator.GenerateImpliedDefs_PreResolve() (Harmony patch)
- Change the def generation code to mirror vanilla:

var foo = new ThingDef {
...
thingCategories = new List<ThingCategoryDef>(),
        ...
};
...
DirectXmlCrossRefLoader.RegisterListWantsCrossRef(d.thingCategories, fooThingCategory1.defName);     
...


Appreciate my mods? Buy me a coffee