I'm trying to write a patch to add a comp to all items (i.e. ThingDefs with category set to "Item"). I use what seems to be an obvious solution:
<Operation Class="PatchOperationSequence">
<success>Always</success>
<operations>
<li Class="PatchOperationTest">
<xpath>/Defs/ThingDef[category="Item"]/comps</xpath>
<success>Invert</success>
</li>
<li Class="PatchOperationAdd">
<xpath>/Defs/ThingDef[category="Item"]</xpath>
<value>
<comps/>
</value>
</li>
</operations>
</Operation>
<Operation Class="PatchOperationAdd">
<success>Always</success>
<xpath>/Defs/ThingDef[category="Item"]/comps</xpath>
<value>
<li>
<compClass>DestroyItem.CompDestructible</compClass>
</li>
</value>
</Operation>
However, it mysteriously only applies to few items such as Apparel_ShieldBelt. I also tried to target abstract ThingDefs (e.g. with @Name="ApparelBase"), but the result is the same. Any ideas?
PS: I did some research and found that this code actually kind of works. But there are some ThingDefs it won't affect no matter what you do, because they are apparently not present in any XML files and are generated dynamically by the game. These include various types of meat, corpses, skill trainers etc. So I had to use C# instead to add the comp in code:
foreach (ThingDef def in DefDatabase<ThingDef>.AllDefs.Where(def => typeof(ThingWithComps).IsAssignableFrom(def.thingClass) && def.category == ThingCategory.Item).ToList())
def.comps.Add(new CompProperties(typeof(CompDestructible)));
It seems to work ok.