Mass-patching things. Can I target the parent instead?

Started by alleZSoyez, January 12, 2019, 11:33:40 PM

Previous topic - Next topic

alleZSoyez

I want to add a new dresser, but I also want it to affect all the beds. While this xpath does work, it's definitely not how I wanted to do it.


<xpath>Defs/ThingDef[
defName = "Bed" or
defName = "DoubleBed" or
defName = "RoyalBed" or
defName = "HospitalBed" or
defName = "Bedroll" or
defName = "BedrollDouble"
]/comps/*/linkableFacilities</xpath>


I was hoping it could be done by targeting the parent instead, but it fails every time.
<xpath>Defs/ThingDef[ParentName = "BedWithQualityBase"]/comps/*/linkableFacilities</xpath>

Is it even possible to target the parent def of several things?

Pelador

<Operation Class="PatchOperationAdd">
<xpath>*/FactionDef[@Name="OutlanderFactionBase"]/caravanTraderKinds</xpath>
<value>
<li>Caravan_VBWB</li>
</value>
</Operation>


Example of patching an abstract. The "@Name" in this case.

alleZSoyez

I must be doing something wrong here. I keep getting the most generic "patch failed" error when trying to patch this.

<Operation Class="PatchOperationAdd">
<xpath>Def/ThingDef[@ParentName = "BedWithQualityBase"]/comps/*/linkableFacilities</xpath>
<value>
<li>TatesTFM_Dresser</li>
</value>
</Operation>


I also tried to be more specific like this and got the same result (I assumed the @ would work for targeting that Class? But trying without it didn't work either)
<Operation Class="PatchOperationAdd">
<xpath>Def/ThingDef[@ParentName = "BedWithQualityBase"]/comps/li[@Class = "CompProperties_AffectedByFacilities"]/linkableFacilities</xpath>
<value>
<li>TatesTFM_Dresser</li>
</value>
</Operation>


Is there something I'm missing?

Pelador

#3
Change @ParentName to @Name.

It is looking at the definition of the parent for the xpath to then cascade them to the children.

The only other consideration is whether the thing you are changing exists in the parent definition. For my example it does, but unsure if the linkable facilities are in the parent definitions for beds. This may be a limitation of the xpath operation if the path value your searching for doesn't exist in the parent and it is needed. But for abstracts you are using the parent definitions not the childs to kick off the operation so the @Name is used instead.

alleZSoyez

Ah, you're right. The linkable facilities are only in the children, so targeting the parent won't work. So there's no way to target everything that is the child of the bed base?

Pelador

#5
Quote from: alleZSoyez on January 14, 2019, 01:06:56 AM
Ah, you're right. The linkable facilities are only in the children, so targeting the parent won't work. So there's no way to target everything that is the child of the bed base?

tbh, never tried it in that manner, so unsure if it will work or not. Worth a try.

I think most of the time abstracts are the "set-theory" definitions that make processes like these more manageable, in that if they are grouped in a way to demonstrate similar behaviour/operations then you can make macro changes to them from the parent definitions. So well defined abstracts that contain most of the root characteristics are the order of the day really.

Otherwise, all I can suggest is using a C# operation to loop through the ThingDefs and make changes based on the qualifiers you want when all the defs have been initialised for the game.

alleZSoyez

I found the problem and I feel a little silly now. I was typing Def/ instead of Defs/ ...
This path worked and lets me target all the beds (I also didn't realize the double beds also have a different parent):

<xpath>Defs/ThingDef[@ParentName = "BedWithQualityBase" or @ParentName = "ArtableBedBase"]/comps/li[@Class = "CompProperties_AffectedByFacilities"]/linkableFacilities</xpath>

Thank you for your help!