Jump to content
sphereii

XPath Modding Explanation Thread

Recommended Posts

This is a large amount of information in these posts. I'll be working on a full, properly formed tutorial as we get access to A17 and we can really make the xpath system shine. I've listed some examples here, and we'll be posting a ton more xpath samples over the coming weeks, as we port the SDX modlets over to use the native hooks.

 

By all means, begin posting your comments, questions, or requests for clarity.

 

Since we now know that xpath support will be built-into the vanilla base game, and discussions earlier were getting a bit confusing, I've decided to make a new thread to try to demystify xpath and what it'll mean for mods and modders going forward in A17. The information in this thread has been pieced together from forum and discord discussions. They may not be 100% accurate, but I will update this thread when we know the full implementation.

 

XPath is a way of adding, changing, or removing XML lines and nodes, without directly editing the XML files. It allows you to apply patches to the XML files without manually editing the vanilla XML files.

 

SDX has had partial support for this since its initial release, and a lot of the SDX Modlets are already written this way. We will be using some of the SDX's xpath as examples in this thread, but SDX is not required to do this in A17 and onwards.

 

I believe in using examples to explain concept, so in the next few posts, you'll see a mixture of explanation, along with sample xpath code.

 

 

The following Mod structure is expected for A17 and beyond:

Mods/
   <ModName>/
       Config/
       UIAtlases/ItemIconAtlas/
       ModInfo.xml

   <ModName2>/
       Config/
       ModInfo.xml

 

You will be able to have multiple mods loaded, and loading will occur as long as the ModInfo.xml exists. This is unchanged from what we've been doing doing with other alphas, with the exception of the Config folder.

 

This Config folder will support loading XML files, written using xpath, in the following folder structure:

 

Config/entityclasses.xml
Config/gamestages.xml
Config/items.xml

The files in the Config folder will not be a full copy of the vanilla file with your changes. Rather, it'll contain the changes you want done to the vanilla files. The files under the Config must match the vanilla file name. You cannot create an entityclasses2.xml file, and expect it to work. Any changes in the entityclasses.xml will have to be done in the same file. However, each mod can have its own entityclasses.xml.

 

During the game's initialization, it will perform the xpath merge in-memory only; no files will be actually be modified. This would allow us to remove mods we no longer want, without re-validating against steam, or previous copies of the xml. That's a big one. No more half merging of a mod, and not having it work, then trying to pull it back out.

 

What this means for us is that we'll be able to make a variety of smaller mods, which I've been calling modlets, which can add, remove and change smaller pieces of the game. They can be used together, or they could be added to an overhaul mod, in order to style your game play easier.

 

These modlets would also exists outside of the Data/Config folder, so if you have made direct XML changes in your Alpha 17.1 Data/Config files, and Steam updated the game to 17.2, you would have lost your changes, or would have to re-merge them in. We've all been there before. But if they existed as modlets, under the Mods folder, they would be safe. And as long as your xpath is still valid to the new XML, it should load up with no additional work on your part.

 

If we could use xyth's JunkItems modlet, which adds random, scrappable junk items to loot containers, and add them to Valmod Overhaul. Likewise, if Valmod Overhaul did not have the No Ammo modlet (which gives you the ability to unload a gun and get its bullets back without disassembling it), you could drop the NoAmmo modlet into your Mods folder. Headshots only? Want to increase stack sizes? Same deal.

 

With a properly constructed modlet, we'll be able to piece together new play styles for people to enjoy and share. A modder working on a large overhaul won't have to duplicate work. If they wanted to include the No Ammo mod, they wouldn't have to code it themselves, letting them focus on the bits that make their mod really unique.

 

Let's get started on your journey...

Edited by SylenThunder
adding new ItemIcon location (see edit history)
  • Like 10

Share this post


Link to post
Share on other sites

XPath Dissected

 

XPath may look a bit intimidating to people unfamiliar with the syntax.

 

Let's see if we can go through an example explaining the format of a simple xpath. To start off, we'll be using the xpath command for set, which lets us change an attribute, or value. Another post will show more of xpath commands, but we'll begin with the simplest.

 

All of the xpath commands take an xpath="" parameter that tells the game where you want to make a change. A change is either changing a value, removing a value, adding a new entity, or whatever you are trying to do.

 

For this example, we want to change the size of the minibike container.

 

<lootcontainers>
<!-- Other loot container lines -->
<!-- minibike storage -->
<lootcontainer id="62" count="0" size="4,3" sound_open="UseActions/open_shopping_basket" open_time="0" sound_close="UseActions/close_shopping_basket" loot_quality_template="baseTemplate">
</lootcontainer>
<!-- other loot container lines -->
</lootcontainers>

 

We need to be able to identify the XML node we want, as precisely as we can. Since the lootcontainers' contain an ID, we'll see that as our target. We want to actually change the size attribute, but it's not unique enough to find directly. We want to give xpath the direct path to there we want to make a change at.

 

When we want to reference the XML nodes in xpath, we'll use the / separator.

 

[highlight]xpath="/lootcontainers/lootcontainer" [/highlight] gets us pretty close. However, there are a lot of lootcontainters, and we only want to change the one with the ID of 62. The ID is an attribute, so we'll have to set a condition to check to make sure the attribute matches 62.

 

[highlight]xpath="/lootcontainers/lootcontainer[@id=62][/highlight] gets us to the right loot container. There's no other lootcontainer with an id of 62, so we won't run the risk of changing more than we want. But we wanted to change the size attribute specifically.

 

[highlight]xpath="/lootcontainers/lootcontainer[@id=62]/@size"[/highlight] gives us direct access to the value in size.

 

So our full set xpath command would look like this:

<set xpath="/lootcontainers/lootcontainer[@id='62']/@size">7,6</set>

 

 

Here's another example. This time, we want to add a new ammo type called "NoAmmo" to the gunPistol. With the loot container, we only wanted to modify a single container. For the ammo type, we want to add NoAmmo to every gun that uses 9mmBullet. There could be a single gun for that, or there could be multiple guns that use it. Either way, we want to change them all.

 

Since we are changing all guns that uses 9mmBullet, we don't have to specify an ID or name. Instead, we'll be looking for every Magazine_items that also has a value of "9mmBullet".

 

Here's a snippet of the XML. To save space, I removed the extra lines, and left just the ones we want to see.

<items>
<item id="40" name="gunPistol">
	<!-- snip -->
	<property class="Action0">
		<!-- snip -->
		<property name="Magazine_items" value="9mmBullet" />
	</property>
</item>
</items>

 

Here's the full xpath code:

<set xpath="/items/item/property[@class='Action0']/property[@name='Magazine_items'][@value='9mmBullet']/@value">9mmBullet,NoAmmo</set>

 

For every item that has a property class of "Action0", that has a property called "Magazine_Items" with a value of 9mmBullet, change the value to 9mmBullet,NoAmmo

 

Note the [highlight] [@name=Magazine_items][@value=9mmBullet][/highlight] ? We are telling xpath that the property name has to be Magazine_Items, AND its value has to be 9mmBullet, before we add NoAmmo.

 

Why do we need to check the property name and its value? Because of things like the paintTool item, which has a Magazine_items with a value of paint. We don't really need to change that one.

Share this post


Link to post
Share on other sites

Previously, we've covered the set command, that let us change individual values and attributes. I'd like to dedicate this section to the append command, since it will likely be the second most used xpath command.

 

The append command can do two things: Add a large block of new XML, or add on an additional value..

 

[ Additional Value ]

 

In the previous post, we covered how to add the NoAmmo mod using the set command. In that example, we had to also specify the existing value of, then add NoAmmo to it:

<set xpath="/items/item/property[@class='Action0']/property[@name='Magazine_items' and @value='9mmBullet']/@value">9mmBullet,NoAmmo</set>

 

The append command can help us make this a little bit easier. Using append, we won't have to specify the existing value, but rather just what we want to add to it:

<append xpath="/items/item/property[@class='Action0']/property[@name='Magazine_items' and @value='9mmBullet']/@value">,NoAmmo</append>

 

[ Additional Nodes ]

 

The other way that append can help us is by adding larger blocks of code. I'll use a part of xyth's Junk Items mod to show where we can add multiple items to the items.xml.

 

The xpath specifies append to the bottom of the /items node. This keeps it within the <items> </items> blocks, but adds it to the end of the file.

 

Mods/JunkItems/Config/items.xml:

<configs>
<append xpath="/items">
	<!-- items needed to scrap Xyth junk into -->
	<item  name="itemMaster">
		<property name="Meshfile" value="Items/Misc/sackPrefab" />
		<property name="DropMeshfile" value="Items/Misc/sack_droppedPrefab" />
		<property name="Material" value="organic" />
		<property name="HoldType" value="45" />
		<property name="Stacknumber" value="500" />
		<property name="Weight" value="5" />
		<property name="Group" value="Resources" />
		<property name="SellableToTrader" value="false" />
	</item>
	<item name="scrapSteel">
		<property name="Extends" value="itemMaster" />
		<property name="CustomIcon" value="ui_game_symbol_scrapSteel" />
		<property name="Material" value="Msteel" />
		<property name="Weight" value="1" />
		<property name="MeltTimePerUnit" value="0.5" />
		<property name="RepairAmount" value="10" />
	</item>
</append>
</configs>

 

Note that we are closing the </append> at the end of the items we are adding.

Edited by sphereii (see edit history)

Share this post


Link to post
Share on other sites

Previously, we've just covered the set command to change individual values. The following commands are also supported in xpath. There may be more, but these are the ones that will cover most of our uses.

 

<set xpath="">

- Allow you to change a value

Example:

This line changes loot container id 62, and changes it's size to 7,6.

<set xpath="/lootcontainers/lootcontainer[@id='62']/@size">7,6</set>

 

<append xpath="">

- This allows you to add whatever XML exists in between the <append> and </append>, at the end of the location in xpath, but still within its scope. You can use the append to add large chunks of XML nodes.

Example:

This line adds in a new entity to the bottom of the entity_classes. It will be added within the top level <entity_classes> </entity_classes> xml.

 

<append xpath="/entity_classes">
<entity_class name="PassiveFlight" extends="animalChicken">
<!-- snip -->
</append>

 

- It also may allow us to append a value to an existing value. ( This needs testing )

Example:

This line could potentially add NoAmmo to the existing value of 9mmBullet.

<append xpath="/items/item/property[@class='Action0']/property[@name='Magazine_items' and @value='9mmBullet']/@value">,NoAmmo</append>

 

<insertAfter xpath="">

- Allows you to add nodes after the specified xpath. It finds the XML node you are searching for, and adds whatever is inside the <insertAfter> blocks after that.

Example:

The snippet bellow allows you to add in the new panel in the windowVehicleStats window, after the rect called 'content', in the XUi/windows.xml:

<insertAfter xpath="/windows/window[@name='windowVehicleStats']/rect[@name='content']" >
<panel pos="240, 0" style="header.panel">
<sprite style="header.icon" sprite="ui_game_symbol_add"/>
<label style="header.name" text="COMBINE" text_key="xuiCombine"/>
</panel>
</insertAfter>

 

<insertBefore xpath="">

- Same as insertAfter above, but adds in the new XML before the node that matches the specified xpath.

 

<remove xpath="">

- Allows you to remove an XML node

Example:

This snippet was used in the ClearUI. It removed the HUDLeftStatBars from the UI.

<remove xpath="/xui/ruleset[@name='default']/window_group[@name='toolbelt']/window[@name='HUDLeftStatBars']" />

 

<setattribute xpath="">

- Allows you to add a new attribute

Example:

This adds a new max_level attribute to the attribute with the name attPerception

<setattribute xpath="/progression/attributes/attribute[@name='attPerception']" name="max_level">1000</setattribute>

 

<removeattribute xpath="">

- Allows you to remove an attribute ( New in A18 )

Example:

This will remove the value attribute

<removeattribute xpath="/progression/attributes/attribute[@name='attPerception']/@value" />

Edited by sphereii
Add missing @ to the removeattribute (see edit history)

Share this post


Link to post
Share on other sites

XPath Advanced Conditionals

===========================

 

Up until now, we've just been covering how to find xpath using direct matches (@name='toolbelt'), but xpath can provide us with more flexibility. Most of the time, you will not need these advanced conditionals, but beware they exist for some more complex things you want to try.

 

starts-with( s1, s2 ) - Matches if s1 starts with whatever word you put in s2. In this example, @name is s1, and 'zombieTemp' is s2

<set xpath="/entity_classes/entity_class[starts-with(@name, 'zombieTemp')]/property[@name='Class']/@value">EntityZombieSDX, Mods</set>

 

ends-with( s1, s2 ) - Matches if s1 ends with whatever word you put in s2. In this example, @name is s1, and 'lateMale' is s2

<set xpath="/entity_classes/entity_class[ends-with(@name, 'lateMale')]/property[@name='Class']/@value">EntityZombieSDX, Mods</set>

 

contains( s1, s2 ) - Similar to starts-with, but s1 just needs to have some kind of match.

<set xpath="/entity_classes/entity_class[contains(@name, 'Template')]/property[@name='Class']/@value">EntityZombieSDX, Mods</set>

 

not - Flips the conditions around.

<set xpath="/entity_classes/entity_class[not (contains(@name, 'zombie'))]/property[@name='Class']/@value">EntityZombieSDX, Mods</set>

This would change every entity_class that does not contain the name zombie.

 

Another example:

<set xpath="/items/item[starts-with(@name, 'drinkJar') and not(contains(@name, 'Empty'))]/property[@name='Stacknumber']/@value">64</set>

 

and - Multi conditions. We used this above in the magazine_items, but we didn't explicitly type it out. An examples mean the same thing:

<set xpath="/items/item/property[@class='Action0']/property[@name='Magazine_items' and @value='9mmBullet']/@value">9mmBullet,NoAmmo</set>

or - Multi conditions, but only needs to match one. In the below example, it'll only make changes if the property name is magazine_items OR if the value is a 9mm bullet.

<set xpath="/items/item/property[@class='Action0']/property[@name='Magazine_items' or @value='9mmBullet']/@value">9mmBullet,NoAmmo</set>

Edited by sphereii (see edit history)
  • Like 2

Share this post


Link to post
Share on other sites

Modlet Example

==========

 

Here's an example on what a Modlet would look like. It's a very simple one, but just shows how a single model can change how horde night plays out.

 

 

[ Guppycur's Blood Moon ]

 

Guppycur made some tweaks to the gamestages.xml when Alpha 16 first came out. During a horde night, if you reached the 4th wave, you'd only get a trickle of zombies until the blood moon was over. Often times, this meant that a single zombie would spawn in for you to kill. Once that was done, another one would spawn in. This was somewhat tedious for experienced players. Guppycur's mod changed the trickle value to be spawning 50 zombies, instead of a single one.

 

The original mod was a complete copy of the gamestages.xml. If someone had already modified their gamestages.xml, and wanted to include his changes, they would have had to manually merge, and update their XML with his changes.

 

XPath Modlet for Guppycur's Blood Moon

 

The following files would be copied into the game folder:

Mods/BloodMoonTrickle/Config/gamestages.xml
Mods/BloodMoonTrickle/ModInfo.xml

 

Contents of the gamestages.xml:

 

<configs>
<!-- Updates the Game stages, under the BloodMoonHorde, to change the maxAlive to 50 for all nodes -->
<!-- By default, it only looks at the the game stages that have a 4 element into it, so it doesn't kick in until gamestage 23 -->
 	<set xpath="/gamestages/spawner[@name='BloodMoonHorde']/*/spawn[4]/@maxAlive">50</set>
</configs>

 

The xpath command is a set, meaning it's changing an existing value. Let's read it out:

 

Under the <gamestages> node, look for the <spawner> code that's called "BloodMoonHode". The /*/ is a wild card match.

 

You'll also notice that spawn[4] is different than anything else we covered.

 

What is that reference? In some rare cases, we may not be able to write a properly formed xpath that targets the line we want. If the xpath is too general, it may make more changes than we intend. When that happens, we can fall back to using an index. In this case, we want to change the 4th spawn line.

 

Here is vanilla's gamestage 64 entry:

<gamestage stage="64">
<spawn group="feralHordeStageGS54" num="21" maxAlive="8" duration="2" interval="38" />
<spawn group="feralHordeStageGS59" num="21" maxAlive="8" duration="2" />
<spawn group="feralHordeStageGS64" num="21" maxAlive="8" duration="2" />
<spawn group="ZombiesNight" num="65" maxAlive="1" />
</gamestage>

 

The spawn[4] references the 4th line, the ZombiesNight group. The reason I had to use the index value was because I did not want to change all the maxAlive's in the spawn group, only the 4th one.

 

Earlier gamestages do not have a 4th line, so the change did not affect them. This gave the players more breathing room if their game stage was smaller.

 

 

 

Localization Support ( A18 and Beyond )

 

As of A18, Localization support from the Mods folder is available in vanilla.

 

In the Config folder, create a Localization.txt and a Localization - Quest.txt. This file must match case and spelling of the vanilla entries.

 

The localization files files have a heading, like the vanilla version, as a comma delimited line. For mod localization support, you only need to specify the heading that you are adding. For example, if your mod only contains localization for English, you do not need to specify the other language in the heading line.

 

If your new localization key matches a vanilla value, or a value from a previously loaded mod, then that value will be updated, with the last mod loaded having the final effect.

 

The format of the file is this:

 

HEADER

ENTRY

 

Example:

 

Key,Source,Context,Changes,English
myKey,UI,Item stat,New,This is my English Key

 

Note: If you are only including non-English translation, such as French, and leave the English blank or out, then a user loading the Spanish version will get the localization key. This is because English is the fall back translation. If you specify an English, then the spanish player will see the English localization.

Edited by sphereii (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

Blob of information is now done. Thank you for your patience.

 

Please feel free to post any questions, clarifications or what have you here. This isn't a final tutorial, but more of a rough dump to get people started and slightly up to speed.

  • Like 4

Share this post


Link to post
Share on other sites
Nice work.

 

I think condition last() ,pick up last node from current nodes, is useful for some case.

 

I'd be interested to see if those style syntaxes will work for us, and in which context.

 

- - - Updated - - -

 

Looks great Sphereii keep up the good work. Cant wait for A17 to try it out

 

Definitely exciting times coming up.

Share this post


Link to post
Share on other sites
I'm voting not to adopt the term "modlet" =) Great work!!

 

It's a good thing its not up for re-election! :)

 

But the term modlet is just used to separate these from what we've been calling mods.

 

Modlet - Small standalone mod that is re-distributed and works with others

 

Mod - Some sort of overhaul, like Ravenhearst, Valmod, Starvation, etc.

 

 

Ideally, we'd get to a point where we'd call modlets as mods, and what we currently call mods as overhauls, or something to that effect.

Share this post


Link to post
Share on other sites
Excellent info.

 

Cheers

 

-edit- hope you dont get any PM's asking if and where you got A17 ;)

 

If I had access to it, I doubt I'd be here :)

 

I'd be in-game :)

Share this post


Link to post
Share on other sites
If I had access to it, I doubt I'd be here :)

 

I'd be in-game :)

 

Yeh lmao! My thoughts. There are others though who have a strange way of thinking ;)

 

Cheers

Share this post


Link to post
Share on other sites

Good tut.

 

I have a question. Here is a set of commands I've converted to xpath. Now, if the property "MaxDamage" is not in the xml for the block with the name @name='so-and-so', will it automatically be added or nah? If nah, is there a function that will only add the property if it's not there already? And if there is no way to automatically add it only if it's not there, what if I added the property to a block that already has it, would my addition overwrite the existing property or add it a 2nd time (which should be illegal)?

 

Is there, in other words, a method that will either change a property, or, if the property does not even exist, add it, so I do not have to know if it's there or not?

Share this post


Link to post
Share on other sites
Good tut.

 

I have a question. Here is a set of commands I've converted to xpath. Now, if the property "MaxDamage" is not in the xml for the block with the name @name='so-and-so', will it automatically be added or nah? If nah, is there a function that will only add the property if it's not there already? And if there is no way to automatically add it only if it's not there, what if I added the property to a block that already has it, would my addition overwrite the existing property or add it a 2nd time (which should be illegal)?

 

Is there, in other words, a method that will either change a property, or, if the property does not even exist, add it, so I do not have to know if it's there or not?

 

I don't believe SDX had something like that. It'd be worth trying it out when we get the experimental release and see what actually works and doesn't.

  • Like 1

Share this post


Link to post
Share on other sites
Good tut.

 

I have a question. Here is a set of commands I've converted to xpath. Now, if the property "MaxDamage" is not in the xml for the block with the name @name='so-and-so', will it automatically be added or nah? If nah, is there a function that will only add the property if it's not there already? And if there is no way to automatically add it only if it's not there, what if I added the property to a block that already has it, would my addition overwrite the existing property or add it a 2nd time (which should be illegal)?

 

Is there, in other words, a method that will either change a property, or, if the property does not even exist, add it, so I do not have to know if it's there or not?

 

Can be done by using operators. TheElement[not(@attribute= 'whatevervalue')]

 

This will skip (or use depending on what you want) elements that do not contain the attribute or contain it but dont have expected value.

 

Cheers

 

-edit- all depending on xpath functions implemented by TFP of course.

Edited by Prisma501 (see edit history)

Share this post


Link to post
Share on other sites
Can be done by using operators. TheElement[not(@attribute= 'whatevervalue')]

 

This will skip (or use depending on what you want) elements that do not contain the attribute or contain it but dont have expected value.

 

Cheers

 

-edit- all depending on xpath functions implemented by TFP of course.

I don't want it to skip if the property is already there. If it's already there, the value should be changed. If the property is not already there, it should be added with the value. For example:

 

<block id="150" name="woodFrameWedge">
<property name="Extends" value="woodFrameMaster"/>
<property name="CreativeMode" value="Player"/>
<property name="Shape" value="New"/>
<property name="Model" value="wedge60"/> <property name="Place" value="TowardsPlacerInverted"/>
<property name="CanPickup" value="true"/>
<property class="UpgradeBlock"> <property name="ToBlock" value="woodWedge"/>	</property>
</block>

This one has no "MaxDamage" property. It should be added with the value I want like so:

 

<block id="150" name="woodFrameWedge">
<property name="MaxDamage" value="75"/>
<property name="Extends" value="woodFrameMaster"/>
<property name="CreativeMode" value="Player"/>
<property name="Shape" value="New"/>
<property name="Model" value="wedge60"/> <property name="Place" value="TowardsPlacerInverted"/>
<property name="CanPickup" value="true"/>
<property class="UpgradeBlock"> <property name="ToBlock" value="woodWedge"/>	</property>
</block>

This one already has the property (it does not actually, but let's say):

 

<block id="830" name="woodHalf">
<property name="MaxDamage" value="100"/>
<property name="Extends" value="woodMaster" />
<property name="Shape" value="New" />
<property name="Model" value="cube_half" />
<property class="UpgradeBlock"> <property name="ToBlock" value="rWoodHalf" /> </property>
<property name="DowngradeBlock" value="solidWoodFrameHalf" />
</block>

And in this case, I want the command to change the value, like so:

 

<block id="830" name="woodHalf">
<property name="MaxDamage" value="50"/>
<property name="Extends" value="woodMaster" />
<property name="Shape" value="New" />
<property name="Model" value="cube_half" />
<property class="UpgradeBlock"> <property name="ToBlock" value="rWoodHalf" /> </property>
<property name="DowngradeBlock" value="solidWoodFrameHalf" />
</block>

And what I don't want is something like this:

 

<block id="830" name="woodHalf">
<property name="MaxDamage" value="50"/>
<property name="MaxDamage" value="100"/>
<property name="Extends" value="woodMaster" />
<property name="Shape" value="New" />
<property name="Model" value="cube_half" />
<property class="UpgradeBlock"> <property name="ToBlock" value="rWoodHalf" /> </property>
<property name="DowngradeBlock" value="solidWoodFrameHalf" />
</block>

Same property twice.

 

So I don't want to have to check wether the property exists or not.

Share this post


Link to post
Share on other sites
I don't want it to skip if the property is already there. If it's already there, the value should be changed. If the property is not already there, it should be added with the value. For example:

 

<block id="150" name="woodFrameWedge">
<property name="Extends" value="woodFrameMaster"/>
<property name="CreativeMode" value="Player"/>
<property name="Shape" value="New"/>
<property name="Model" value="wedge60"/> <property name="Place" value="TowardsPlacerInverted"/>
<property name="CanPickup" value="true"/>
<property class="UpgradeBlock"> <property name="ToBlock" value="woodWedge"/>	</property>
</block>

This one has no "MaxDamage" property. It should be added with the value I want like so:

 

<block id="150" name="woodFrameWedge">
<property name="MaxDamage" value="75"/>
<property name="Extends" value="woodFrameMaster"/>
<property name="CreativeMode" value="Player"/>
<property name="Shape" value="New"/>
<property name="Model" value="wedge60"/> <property name="Place" value="TowardsPlacerInverted"/>
<property name="CanPickup" value="true"/>
<property class="UpgradeBlock"> <property name="ToBlock" value="woodWedge"/>	</property>
</block>

This one already has the property (it does not actually, but let's say):

 

<block id="830" name="woodHalf">
<property name="MaxDamage" value="100"/>
<property name="Extends" value="woodMaster" />
<property name="Shape" value="New" />
<property name="Model" value="cube_half" />
<property class="UpgradeBlock"> <property name="ToBlock" value="rWoodHalf" /> </property>
<property name="DowngradeBlock" value="solidWoodFrameHalf" />
</block>

And in this case, I want the command to change the value, like so:

 

<block id="830" name="woodHalf">
<property name="MaxDamage" value="50"/>
<property name="Extends" value="woodMaster" />
<property name="Shape" value="New" />
<property name="Model" value="cube_half" />
<property class="UpgradeBlock"> <property name="ToBlock" value="rWoodHalf" /> </property>
<property name="DowngradeBlock" value="solidWoodFrameHalf" />
</block>

And what I don't want is something like this:

 

<block id="830" name="woodHalf">
<property name="MaxDamage" value="50"/>
<property name="MaxDamage" value="100"/>
<property name="Extends" value="woodMaster" />
<property name="Shape" value="New" />
<property name="Model" value="cube_half" />
<property class="UpgradeBlock"> <property name="ToBlock" value="rWoodHalf" /> </property>
<property name="DowngradeBlock" value="solidWoodFrameHalf" />
</block>

Same property twice.

 

So I don't want to have to check wether the property exists or not.

 

Yes and thats possible in xpath using operators, queries and stringlen checks, but as said, the pimps implementation is what has to support it. Depending if they implement that sort of advanced usage, we will be able to use. We will have to wait and see.

 

Cheers

Share this post


Link to post
Share on other sites
Yes and thats possible in xpath using operators, queries and stringlen checks, but as said, the pimps implementation is what has to support it. Depending if they implement that sort of advanced usage, we will be able to use. We will have to wait and see.

 

Cheers

If you know how exactly the command would have to look for that, might you provide an example..? I (briefly) looked into other tutorials and could not find what I'm looking for.

 

If the game won't support such stuff, it should be a good idea to find something that does, I find an option like this fairly essential. How does it work anyway, what turns the commands into actual xml-code? I'm not much of a programmer, so I don't know what's it called, a compiler? Interpreter? If the game can't do, are there stand alone programs available or easy to make?

 

 

Edit: I have, btw, understood that whatever the game uses will not even put out any actualy xml-files anymore. But I assume there are such programs, so... No confusion plz.

Edited by Kubikus (see edit history)

Share this post


Link to post
Share on other sites

A quick and easy solution to the issue is to use two xpath commands:

 

<remove xpath="//property" />

<append xpath="//property/@value>50</append>

 

The remove should fail silently if its not there, and remove if it its there. the append would put it back.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...