XML Manipulation Functions: Test Code

Freeform discussion about anything related to modding Transcendence.
Post Reply
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

I'm spending the day trying out the XML manipulation functions George gave us in API 23. This thread will contain examples of code that works, using pixelfck's Console Dockscreen as a tool. I'll also describe examples of what happens when I break the code intentionally.

My current goal is to create a mod that's like Weapon Labs but doesn't require any weapons to actually be defined in the mod's XML. All the weapons will get their characteristics from modified vanilla, extension, and mod weapons using typGetXML and typCreate.

API 23:
http://multiverse.kronosaur.com/news.hexm?id=1063
XML Manipulation & Override
Another major feature in 1.5 is the ability to modify the XML for a given type. This is a feature based on suggestions from this forum thread.

The basic recipe looks like this:

In the root element of your extension (<TranscendenceExtension>), add usesXML="true". This tells the engine that you need the XML for all the types to be kept around for you.
In <OnGlobalTypesInit>, you may use a new function, typGetXML to get the XML for a type that you wish to override.
There are new functions that manipulate the XML returned by typGetXML. For example, you can set attributes or add elements.
Once you've manipulated the XML, you may call typCreate to dynamically create a new type or override an existing type.
Here is an example:


...
<OnGlobalTypesInit>
(block (cannonXML)
; Get the XML for the recoilless cannon
(setq cannonXML (typGetXML &itRecoillessCannon;))

; Change the name of the item

(xmlSetAttribute cannonXML 'name "my recoilless cannon")

; Redefine

(typCreate &itRecoillessCannon; cannonXML)
)
</OnGlobalTypesInit>
...

XML Manipulation Functions
There are several new functions that allow you to manipulate the XML returned by typGetXML:


(xmlAppendSubElement xml xmlToAdd [index]) -> True/Nil
(xmlAppendText xml text [index]) -> True/Nil
(xmlCreate xml) -> xml
(xmlDeleteSubElement xml index) -> True/Nil
(xmlGetAttrib xml attrib) -> value
(xmlGetAttribList xml) -> list of attribs
(xmlGetSubElement xml tag|index) -> xml
(xmlGetSubElementCount xml) -> number of sub-elements
(xmlGetSubElementList xml [tag]) -> list of xml
(xmlGetText xml [index]) -> text
(xmlGetTag xml) -> tag
(xmlSetAttrib xml attrib value) -> value
(xmlSetText xml text [index]) -> True/Nil
Warnings & Precautions
This functionality gives you a powerful new way to override the core XML, but it requires thought and finesse to implement properly.
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

This code uses typGetXML with the recoilless cannon. It returns 15.
xml functions test (returns 15) 2016 04 08a.PNG
xml functions test (returns 15) 2016 04 08a.PNG (18.69 KiB) Viewed 10134 times
Changing 'fireRate to 'fireRat returns Nil.

Changing 'weapon to a tag that doesn't exist (or exists at a higher level in the XML structure, such as ItemType) returns an error.

Changing line 16 to attribute returns this:
commonwealth, majorItem, NAMI
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

This code uses typGetXML with the laser cannon array. It returns 3, which is the number of shots that the weapon fires simultaneously based on the weapon's <Configuration> element.
xml functions test (returns 3) 2016 04 09a.PNG
xml functions test (returns 3) 2016 04 09a.PNG (26.26 KiB) Viewed 10134 times
<!-- Laser Array -->

<ItemType UNID="&itLaserArray;"
name= "laser cannon array"
attributes= "commonwealth, EI, energyWeapon, majorItem"

level= "3"
frequency= "rare"

value= "2700"
mass= "3000"

description= "The laser cannon array consists of three laser cannons joined in a forward spread pattern."
>

<Image imageID="&rsItemsEI1;" imageX="288" imageY="96" imageWidth="96" imageHeight="96"/>

<Weapon
type= "beam"

damage= "laser:1d4"
fireRate= "10"
lifetime= "30"
powerUse= "60"

effect= "&efLaserBeamDefault;"
sound= "&snLaserCannon;"
>
<Configuration aimTolerance="6">
<Shot angle="-3"/>
<Shot angle="0"/>
<Shot angle="3"/>
</Configuration>
</Weapon>
</ItemType>
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

To do this successfully, we will also need to utilize the new floating-point functions George made available in API 27.

For example, if we assume that a weapon should increase by one level as it increases 60% in damage, there needs to be a way to account for an increase in a third of a level, which would involve taking the third root of 1.6. This suggests that a third of a level damage increase is an increase of 17%. This calculation would not have been possible using the old functions due to roundoff, but it should work with the functions below. (pow 1.6 0.33)

https://ministry.kronosaur.com/record.hexm?id=275
Floating-Point Support
1.6 includes support for floating-point math in the core TLisp engine. New functions evaluate to floating-point values:

(+ 0.5 2) -> 2.5
(- 2.0 0.5) -> 1.5
(* 10 0.5) -> 5.0
(/ 5 2) -> 2.5
(mod 5.25 0.5) -> 0.25
(pow 2.0 0.5) -> 1.414213562373095
(sqrtn 2.0) -> 1.414213562373095
(typeof 0.5) -> real
EDIT: There doesn't seem to be support for calcuating logarithms in API 29, so I may need to write something.
Last edited by gunship256 on Sun Apr 10, 2016 7:58 pm, edited 1 time in total.
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

The examples below again use the code for the laser cannon array.

This code returns "ItemType":
xml functions test (returns ItemType) 2016 04 10a.PNG
xml functions test (returns ItemType) 2016 04 10a.PNG (9.76 KiB) Viewed 10113 times
This code returns 2:
xml functions test (returns 2) 2016 04 10b.PNG
xml functions test (returns 2) 2016 04 10b.PNG (9.8 KiB) Viewed 10111 times
The code below returns an <Image> element (<Image imageID="&rsItemsEI1;" imageX="288" imageY="96" imageWidth="96" imageHeight="96"/>), so it appears that the element index starts at zero.

Using index position 1 returns the <Weapon> element.

Using index position 2 returns Nil. (Heads up: Don't try to pass Nil to any function that requires XML, or the function will throw an error. When trying to iterate through all of the XML elements, we have to start at zero and end at the proper place to prevent errors from being generated.)
xml functions test (returns an Image element) 2016 04 10c.PNG
xml functions test (returns an Image element) 2016 04 10c.PNG (9.95 KiB) Viewed 10111 times
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

The code below successfully changes the name of the laser cannon array to "hi". The changes are automatically made to thisXML without needing to use (setq).
xml functions test (changes name to hi) 2016 04 10e.PNG
xml functions test (changes name to hi) 2016 04 10e.PNG (15.05 KiB) Viewed 10109 times
The code below throws an error. xmlAppendSubElement doesn't think that the string "<weapon></weapon" is actually XML and is not afraid to say so.
xml functions test (throws error) 2016 04 10f.PNG
xml functions test (throws error) 2016 04 10f.PNG (15.94 KiB) Viewed 10108 times
The code below generates an XML parser error ("close tag does not match open"):
xml functions test (generates close tag does not match open error) 2016 04 10g.PNG
xml functions test (generates close tag does not match open error) 2016 04 10g.PNG (18.47 KiB) Viewed 10108 times
Last edited by gunship256 on Sun Apr 10, 2016 8:49 pm, edited 2 times in total.
User avatar
pixelfck
Militia Captain
Militia Captain
Posts: 571
Joined: Tue Aug 11, 2009 8:47 pm
Location: Travelling around in Europe

Note: I updated the Console Dockscreen mod
~Pixelfck
Image
Download the Black Market Expansion from Xelerus.de today!
My other mods at xelerus.de
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

The code below adds an empty <weapon /> element at the end of the <ItemType> element. (Yes, the engine did edit my <weapon></weapon>, turning my code into something more concise.)
xml functions test (adds empty weapon element) 2016 04 10h.PNG
xml functions test (adds empty weapon element) 2016 04 10h.PNG (14.27 KiB) Viewed 10104 times
Adding line 6 deletes the original <weapon> element, which was at index position 1. Line 12 then adds the new empy <weapon /> element.
xml functions test (deletes original weapon element and adds a new one) 2016 04 10i.PNG
xml functions test (deletes original weapon element and adds a new one) 2016 04 10i.PNG (16.32 KiB) Viewed 10104 times
pixelfck wrote:Note: I updated the Console Dockscreen mod
~Pixelfck
Thanks! Downloading now...
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

Through testing, I've found that an item created using typCreate functions normally in-game, but typGetXML does NOT pull up XML for the item. It returns Nil.

This creates serious limitations for a mod that would disassemble weapons and re-assemble them based purely on XML. I'm going to have to store the necessary information somewhere other than in the XML of the disassembled weapon components.
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

The code below deletes the laser cannon array's <weapon> element and adds a second <image> element that is identical to the first <image> element without deleting the first one.
xml functions test (deletes weapon element and adds a second image element without deleting the first) 2016 04 16a.PNG
xml functions test (deletes weapon element and adds a second image element without deleting the first) 2016 04 16a.PNG (17.16 KiB) Viewed 10081 times
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

Here's a mod that is the simplest possible example of using typGetXML and typCreate together:

Reprogrammed Launchers
https://forums.kronosaur.com/viewtopic.php?f=25&t=7577

It was a proof-of-concept that also gave me an item I wanted in the game pretty badly anyway. I've linked to it several times in IRC, so I thought I'd post a link here as well.
User avatar
TheLoneWolf
Militia Captain
Militia Captain
Posts: 802
Joined: Thu Nov 28, 2013 5:03 pm
Location: Aboard the CSS Radiant

This thread is PARADISE!
gunship256
Militia Commander
Militia Commander
Posts: 451
Joined: Sat Jul 25, 2015 11:41 pm
Location: repairing armor

Are you using typGetXML?

Join us in IRC sometime. There are several of us that are trying to figure it out.
User avatar
TheLoneWolf
Militia Captain
Militia Captain
Posts: 802
Joined: Thu Nov 28, 2013 5:03 pm
Location: Aboard the CSS Radiant

gunship256 wrote:Are you using typGetXML?

Join us in IRC sometime. There are several of us that are trying to figure it out.
Nah. I don't know much. But I'm learning general XML. Maybe I can contribute some :D
RPC
Fleet Admiral
Fleet Admiral
Posts: 2876
Joined: Thu Feb 03, 2011 5:21 am
Location: Hmm... I'm confused. Anybody have a starmap to the Core?

I would say go on IRC just so you can learn the language in general. I would have never got anywhere with modding had I not talked to Alterecco/Prophet/*weaver on IRC.
Tutorial List on the Wiki and Installing Mods
Get on Discord for mod help and general chat
Image
Image
Der Tod ist der zeitlose Frieden und das leben ist der Krieg
Wir müssen wissen — wir werden wissen!
I don't want any sort of copyright on my Transcendence mods. Feel free to take/modify whatever you want.
Post Reply