PDA

View Full Version : Having trouble figuring out how to read a "WindowReference" node



Varsuuk
January 30th, 2021, 18:00
I am embarrassed posting this question, but I have many times worked with passed in sRecords (foo@bar links) where I get it from a passed in string. But I also have examples in code where I read it from a character+node.


This is the record in question from the campaign db.xml:


<id-00007>
<aac>
<armour type="number">10</armour>
<bonus type="number">0</bonus>
<dex type="number">0</dex>
</aac>
...
<pcclass type="string">Fighter</pcclass>
<pcclasslevel type="number">2</pcclasslevel>
<pcclasslink type="windowreference">
<class>pcclass</class>
<recordname>referencepcclass.fighter@MCSWWB</recordname>
</pcclasslink>
<pcrace type="string">Halfling</pcrace>
<pcracelink type="windowreference">
<class>pcrace</class>
<recordname>referencepcrace.halfling@MCSWWB</recordname>
</pcracelink>
...





function onModHandler(rSource, rTarget, rRoll)
Debug.console("== SW) onModHandler: ")
-- Check source for race. If it is a halfling and using a ranged tagged weapon, add
-- indicated bonus.
local nodePCClassLink = DB.findNode(rSource.sCreatureNode .. ".pcclasslink")
local _, sPCClassRecord = DB.getValue(rSource.sCreatureNode, "pcclasslink")

Debug.console(nodePCClassLink)
Debug.console(rSource.sCreatureNode)
Debug.console(sPCClassRecord)



This is the output of the above:


Runtime Notice: databasenode = { charsheet.id-00007.pcclasslink }
Runtime Notice: s'charsheet.id-00007'
Runtime Notice: nil


I am TRYING to get at:
<recordname>referencepcclass.fighter@MCSWWB</recordname>

or rather, the contents: "referencepcclass.fighter@MCSWWB"


WHAT am I completely messing up here?

Varsuuk
January 30th, 2021, 18:05
THIS is working elsewhere in my code:



function onClassLevelChanged(nodeChar)
--Debug.console("[[onClassLevelChanged]]")
local _, sPCClassRecord = DB.getValue(nodeChar, "pcclasslink")
local sClassID = NodeUtils.getLeafNameFromRecord(sPCClassRecord)

local _, sPCRaceRecord = DB.getValue(nodeChar, "pcracelink")
local sRaceID = NodeUtils.getLeafNameFromRecord(sPCRaceRecord)

local nLevel = DB.getValue(nodeChar, "pcclasslevel", 0)
local nPriorLevel = DB.getValue(nodeChar, "hd_roll_history_level", 0)
local nPriorMaxLevel = DB.getValue(nodeChar, "hd_roll_history_maxlevel", 0)



After typing this, I got the idea to add a log to the "nodeChar" to see if differs from my log above...



EDIT: Result of printing nodeChar:
Runtime Notice: databasenode = { charsheet.id-00013 }


One is a "string" (above) and this one is a "node" but the getValue() is setup to work with both.

SilentRuin
January 30th, 2021, 18:09
I can't see where your rSource is coming from but I'd print that out. I've found that using the structure to get data instead of directly grabbing it yourself can sometimes be unreliable based on where that structure (rSource in your case) originates from. Hence, I've distrusted accessing things like sCreatureNode without verification it is really there.

SilentRuin
January 30th, 2021, 18:12
I can't see where your rSource is coming from but I'd print that out. I've found that using the structure to get data instead of directly grabbing it yourself can sometimes be unreliable based on where that structure (rSource in your case) originates from. Hence, I've distrusted accessing things like sCreatureNode without verification it is really there.

Never mind.

(rSource.sCreatureNode

in


local _, sPCClassRecord = DB.getValue(rSource.sCreatureNode, "pcclasslink")

Is the problem - thats a string not a node.

SilentRuin
January 30th, 2021, 18:22
EDIT: Result of printing nodeChar:
Runtime Notice: databasenode = { charsheet.id-00013 }


One is a "string" (above) and this one is a "node" but the getValue() is setup to work with both.

I have never tried to access it without the node itself. Document does not seem to say you can do that without the node defined as I read it (this is FGU). If you provide string as sub path you still need a node do you not? Maybe I'm wrong. Never tried it your way.


getValue

function getValue(sourcenode, [subpath], [default])
Returns the value contained in the specified database node. The return value(s) vary depending on the type of the node. If the node does not exist or if the node is a non-value type, then the default values passed in will be returned or nil if no default values are specified.

Parameters

sourcenode (string (or databasenode))
A data node identifier path (or a databasenode object) representing the target node

subpath (string) [optional]
If the first parameter has type databasenode, then this parameter specifies the relative data node identifier path from the specified node object.

default (...) [optional]
The value(s) to be returned if getValue fails. (node does not exist; or non-value node)

Return values

(...)
Returns data contained in the database node

SilentRuin
January 30th, 2021, 18:28
Also is this child data? Might try getChild? Just shooting down possible problems - not really done what your doing the way your doing it.

SilentRuin
January 30th, 2021, 18:36
Never mind - this is not child data my bad.

Varsuuk
January 30th, 2021, 18:38
I have never tried to access it without the node itself. Document does not seem to say you can do that without the node defined as I read it (this is FGU). If you provide string as sub path you still need a node do you not? Maybe I'm wrong. Never tried it your way.

In the documentation you quoted, the "source node" param can be:


sourcenode (string (or databasenode))
A data node identifier path (or a databasenode object) representing the target node


>I< was in the habit of using "nodes" but seeing so much code just working with the strings and I think asking and getting a "meh response on if it was more efficient (figure string version had repeated lookups to the node) I went with what I kept seeing - using strings mostly.

BUT - I am going to rule it out using node.

Thanks for your help on this :)

Varsuuk
January 30th, 2021, 18:44
And YOU SIR ... have SUCCEEDED in helping me out :)


Now can go back to laundry with clear mind and his this hard when done*



local CHARNODE = DB.findNode(rSource.sCreatureNode)
local A,B = DB.getValue(CHARNODE, "pcclasslink")
Debug.console(A, B)
Debug.console("------")




Runtime Notice: s'== SW) onModHandler: '
Runtime Notice: databasenode = { charsheet.id-00007.pcclasslink }
Runtime Notice: s'charsheet.id-00007'
Runtime Notice: nil
Runtime Notice: s'pcclass' | s'referencepcclass.fighter@MCSWWB'
Runtime Notice: s'------'



*Safety tip:
When one wishes to shake the "Kraft's Honey Barbecue" sauce container prior to mixing it with their "Ken's Chunky Blue Cheese Salad Dressing" to use as dip for their "Perdue Chicken Nuggets":
BE AWARE TOP IS SCREWED ON TIGHT!

Thank god MacBook cover was closed. Had to wash table covering, rug, various items of clothes, Apple Watch and assorted other house items.

SilentRuin
January 30th, 2021, 18:45
In the documentation you quoted, the "source node" param can be:


sourcenode (string (or databasenode))
A data node identifier path (or a databasenode object) representing the target node


>I< was in the habit of using "nodes" but seeing so much code just working with the strings and I think asking and getting a "meh response on if it was more efficient (figure string version had repeated lookups to the node) I went with what I kept seeing - using strings mostly.

BUT - I am going to rule it out using node.

Thanks for your help on this :)

Good luck - I personally have had to trial and error my way through some pretty bizarre stuff. Scripting can get weird and unpredictable with some minor un-seeable error by you - or mistakes in the documentation. I can never tell which so just have to plug away till it works.

Moon Wizard
January 30th, 2021, 18:50
Just a bit of advice, I wouldn't access the .sCreatureNode directly in ActorManager. There is an ActorManager.getCreatureNode(rActor) and ActorManager.getCreatureNodeName(rActor) set of functions for this. It may save you trouble down the line, if anything inside actor "records" change.

Regards,
JPG

Varsuuk
January 30th, 2021, 18:55
Oh cool thank you Moon! I always appreciate your insights :)

I borrowed the access method from some other code - now that know will look at it closer because I have only just now started working on CT related things.

Varsuuk
January 30th, 2021, 19:59
Just a bit of advice, I wouldn't access the .sCreatureNode directly in ActorManager. There is an ActorManager.getCreatureNode(rActor) and ActorManager.getCreatureNodeName(rActor) set of functions for this. It may save you trouble down the line, if anything inside actor "records" change.

Regards,
JPG

Perfect, now that know that rSource and rTarget are "Actors". or as referenced in CoreRPG "varActor", I get what to do.
I will also rename my args to indicate they are Actors, source and target to help with my documentation when I come back to it in future.

Many thanks,
Dan