Using thingClass="..." for PatchOperations

Started by Syrus, September 02, 2020, 03:04:30 PM

Previous topic - Next topic

Syrus

I've been trying to make all turrets "minifiable". The problem with that is, I also want to apply it to all mods.

After some reading, thinking and figuring out the neatest way of doing that, I came up with a solution that should add <minifiedDef>MinifiedThing</minifiedDef> to all ThingDefs where thingClass = "Building_TurretGun".

The problem is, it does not work.
While there are no errors, there is no change either.
It seems like the <minifiedDef>MinifiedThing</minifiedDef> does not get applied.


<Operation Class="PatchOperationConditional">
<xpath>/Defs/ThingDef[thingClass="Building_TurretGun"]/minifiedDef</xpath>
<match Class="PatchOperationReplace">
<xpath>/Defs/ThingDef[thingClass="Building_TurretGun"]/minifiedDef</xpath>
<value>
<minifiedDef>MinifiedThing</minifiedDef>
</value>
</match>
<nomatch Class="PatchOperationAdd">
<xpath>/Defs/ThingDef[thingClass="Building_TurretGun"]</xpath>
<value>
<minifiedDef>MinifiedThing</minifiedDef>
</value>
</nomatch>
</Operation>
<Operation Class="PatchOperationConditional">
<success>Always</success>
<xpath>/Defs/ThingDef[thingClass="Building_TurretGun"]/thingCategories</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>/Defs/ThingDef[thingClass="Building_TurretGun"]</xpath>
<value>
<thingCategories>
  <li>BuildingsSecurity</li>
</thingCategories>
</value>
</nomatch>
</Operation>


When I change nomatch to match (while removing the match-part) for the minifiedDef-operation, the game will - as expected! - throw errors for duplicate minifiedDefs on all turrets which are already minifiable. To me is a sign that the code should work.
Another interesting thing I noticed was, that if I change the added value to be faulty, the game will throw errors as expected.

Previously I also tried using @Name="AutocannonTurret" instead of thingClass="Building_TurretGun". This worked, but sadly not all of the turrets I wish to change inherit from the AutocannonTurret-AbstractClass.
One thing to note though, this change was only for adding minifiedDef, and it still worked correctly, so the adding of the thingCategories seems to work - at least for vanilla turrets.


I've spend quite too much time on this issue already and I just cannot figure out what I'm doing wrong here, though I'm not fully knowledgable when it comes to this modding, from my understanding this should should...
Of course, there are other options, like adding it all directly to each thing I wish to change and that would probably work. By now that would also be less time and work spend on this, but a better solution would be appreciable.

RawCode

1) remove minifiendDefs from all turrets
2) add back to all turrets

this is most simple method to solve your issue without nesting conditions or using c#

Syrus

Good idea, had not thought of that at all.

It tested it, and it works.
But I noticed with this solution that no matter if the other solution had worked, I'd run into other problems (missing haul weight on some things, no thingCategories on others, mostly). Those can of course be fixed, but with the same trouble as before...

In the end I think I will go with "manually" adding the necessary things to the turrets I want minifiable.
Mainly I was wondering what I was doing wrong or whether I had some faulty syntax or misunderstanding of how the PatchOperationConditional works.

LWM

Your conditional xpath is looking for ...what?  Any entity that matches that first xpath? And if it finds one, it then proceeds to do your PatchOperationReplace, which only matches against things that already have a minified def?

You can probably do it all in one step with a PatchOperationAdd (unless there are other minified defs besides MinifiedThing out there?).  You'll need an xpath that looks something like:
<code>
<xpath>/Defs/ThingDef[thingClass="BuildingTurretGun" and not(minifiedDef)]</xpath>
</code>

Is that close to what you're trying to do?

Syrus

#4
Oh, I had no idea I can do that. Now that's a nice way to do what I had initially attempted. (Assuming it works, haven't tested it yet.)
Wish the Wiki had a bit more on XPaths, or maybe I'm just blind and missed it.

Definitely going to look through my patches and see if I can't use that elsewhere though, I feel like I had more constructs that could improved that way.

(Mind you, this is only for my personal mods, I don't release anything to the public, so dread not for the horribleness I conjure up in my attempts to get things to work!)

EDIT:
Thanks, that "and not(...)" really works wonderfully!
Found another mod that does some crazy XPath things, so I ended up with "/Defs/ThingDef[@ParentName="AutocannonTurret"]/comps[not(descendant::li[@Class="..."])]" for something I wanted to add if it does not exist. Makes all that PatchOperationConditional stuff I did so far unnecessary, which I'm quite happy for.

LWM

Quote from: Syrus on September 05, 2020, 03:40:22 PM
Wish the Wiki had a bit more on XPaths, or maybe I'm just blind and missed it.

Maybe the wiki needs a link to https://www.w3schools.com/xml/xpath_syntax.asp or something. Xpath is a widely used standard, so there are plenty of resources....if you know to go looking for them  ;) ;D 8)

I use that syntax page a fair bit when I'm making sure I'm doing complicated xpaths correctly.