View Full Version : adding up windowlist values
GMBazUK
June 9th, 2011, 16:55
By way of assistance with my current conundrum and as something of an education in clarifying my misunderstandings (as a total beginner), I would be grateful if someone could shed some light. I've been scratching my head over this one for a while.
I'm trying to copy the functionality of the d20JPG Inventory list whereby the weight of objects (if carried) are added together and output in the Encumbranceload numberfield, which does not reside in the inventorylist windowclass.
I have a windowlist called critdamage which references a windowclass which contains all the various string/numberfields etc... one of which is called critamnt. This numberfield is where the amount of critical hits is entered for each of the critical damage windowlist entries.
In my windowlist a function is called:
<windowlist name="critdamage">
<anchored>
<to>critlabel</to>
<position>over</position>
<offset>0,-10</offset>
</anchored>
<class>charsheet_criticalswindow</class>
<datasource>.critdamage</datasource>
<allowcreate />
<allowdelete />
<script>
function updatehitpoints()
local criticalstotal = 0;
for i, w in ipairs(getWindows())do
local crit = w.critamnt.getValue();
end
criticalstotal = criticalstotal + crit
end
if window.criticals then
window.criticals.setValue(criticalstotal);
end
end
function onInit()
updatehitpoints();
end
</script>
<skipempty/>
</windowlist>
Now heres what I think it is doing:
A function I have called updatehitpoints (I have a parent node called hitpoints. The inventory list script example I'm following references a parent node called Encumberance) is started which after setting up a temporary holding variable (criticalstotal) and establishing a starting value for it, then goes on to iterate through the critdamage childnodes (because thats the name of my windowclass data) storing their indices and windowvalues(?) (for i, w in ipairs (getWindows()).
The function then looks at this info and if the data it has stored relates to a childnode called critamnt, it takes the first value it has and stores it in a temporary variable called crit.
The value of crittotal is then recalculated to be equal to the value of crittotal (0) plus the value of crit.
The next bit is something of a mystery (based on the little I know about navigating the database nodes)
Having interrogated the child nodes for critdamage, the function then goes up to the parent node using window (critdamage) and then "if" it finds a node (from there!) called criticals(which in my case is childnode of hitpoints and which is a hidden numberfield on the charactersheet) it should set its value to be equal to crittotal.(!?)
Having run the function thus far and as it has been initialised, go back to the beginning of the function and run the function (updatehitpoints) again.
Extract from my database:
<id-00002>
<critamnt type="number">4</critamnt>
<hitpoints>
<criticals type="number">0</criticals>
</hitpoints>
<location type="string">bert</location>
</id-00002>
</critdamage>
<encumbrance>
<load type="number">5</load>
</encumbrance>
<hitpoints>
<criticals type="number">0</criticals>
<hits type="number">0</hits>
<lethamnt type="number">0</lethamnt>
<totalamnt type="number">0</totalamnt>
</hitpoints>
I'm sure I've misunderstood quiet a bit, but I'm determined to get a handle on the LUA logic.
Thanks in advance.
Baz.
Moon Wizard
June 9th, 2011, 17:19
Not sure if this solves it completely, but it should solve a script error or 2. You had an extra end statement in updatehitpoints, and the crit variable was defined as local inside the for loop (i.e. it would be undefined or nil outside the for loop).
function updatehitpoints()
local crit;
local criticalstotal = 0;
for i, w in ipairs(getWindows())do
crit = w.critamnt.getValue();
end
criticalstotal = criticalstotal + crit;
if window.criticals then
window.criticals.setValue(criticalstotal);
end
end
Also, you might want to get in the habit of indenting your LUA code for each section (function, for loop, if statement). It helps you read your code a little easier and find missing end statements easier as well.
Cheers,
JPG
Sorcerer
June 9th, 2011, 17:32
Also if you want to total all values of crit then the statement
criticalstotal = criticalstotal + crit;
needs to be nested within the for statement otherwise it will cycle through all windows giving crit the value, but not summing them, at the end only the last value of crit will be returned and added to crit total.
function updatehitpoints()
local crit;
local criticalstotal = 0;
for i, w in ipairs(getWindows())do
crit = w.critamnt.getValue();
criticalstotal = criticalstotal + crit;
end
if window.criticals then
window.criticals.setValue(criticalstotal);
end
end
GMBazUK
June 9th, 2011, 18:14
Thank you both for your responses, and Moon Wizard (like you don't have enough to do, I suspect) for the advice concerning formatting.
Unfortunately the script at this stage isn't doing what I had hoped, but the console is no longer throwing an error.
I'm going to carefully pick over the setup for the Inventory page again and try to ascertain how the script relates to the database structure.
Hopefully this will throw up where I'm going wrong.
Thanks again.
Baz.
Sorcerer
June 9th, 2011, 18:47
when things are not going as I intend, I usually reach for a "print" statement
if the values outputted are not what you think they should be, insert
print(somevariable) into the code.
then when you start up FG type /console into the chat window (usually /c is sufficient) and open whatever you were working on and see what value the variable has when its printed.
After you exit FG you can also find a full list of what has printed (or what errors were received) in the console.log, which should be in the dataApps folder.
in this case you could try
function updatehitpoints()
local crit;
local criticalstotal = 0;
for i, w in ipairs(getWindows())do
crit = w.critamnt.getValue();
print(crit)
criticalstotal = criticalstotal + crit;
print(criticalstotal )
end
if window.criticals then
window.criticals.setValue(criticalstotal);
end
end
if you see "Script:" with no value after it then you know that it has found no value at all, otherwise it might give "Script: 25" or something.
additionally you can get it to print datanode names (very useful if you are having trouble navigating the database)
eg. print(getDatabaseNode().getNodeName())
that should print the whole path from the root directory to where the piece of code is currently operating in the database.
you might need to but a "window." in front of it if you are with a window.
you can also use print(getDatabaseNode().getName())
which returns only the name of the current node child you are dealing with.
anyway it certainly helps me track down errors.
GMBazUK
June 9th, 2011, 18:56
Hmm... After following the earlier advice my windowlist script now looks like this:
<script>
function updatehitpoints()
local crit;
local criticalstotal = 0;
for i, w in ipairs(getWindows())do
crit = w.critamnt.getValue();
criticalstotal = criticalstotal + crit
end
if window.criticals then
window.criticals.setValue(criticalstotal);
end
end
function onInit()
updatehitpoints();
end
</script>
..but there was a further issue with my critamnt numberfield (as defined in the windowclass). I had added a script to this numberfield so as to update hitpointcriticals, as and when this field was updated in the windowlist entries; but the reference I had defined as to what to update (hitpointscriticals) was not correct.
After adjusting it as below:
<script>
function onValueChanged()
window.windowlist.updatehitpoints();
end
</script>
...bingo!:D Hopefully this thread will help someone else.
Baz.
Moon Wizard
June 9th, 2011, 19:22
You might find the Debug extension that I published on the Downloads page to be useful.
You load it up with your ruleset, then you can use Debug.chat(...) and Debug.console(...) messages in your LUA code to output any kind of variable without having to worry about object types or nil values.
Cheers,
JPG
GMBazUK
June 9th, 2011, 21:14
With reference to Print and Debug, thats really useful information. I did check out your Debug thread the other day Moon Wizard, but with Sorcerers graphic illustration as to the print function, I feel even more confident I will be able to get it working.
I'm clutching at straws a lot of the time, not being a programmer, and often I'm deliberately breaking scripts, looking at effects on database structures, tracking down the roots of template definitions in other rulesets, in order to build up an "idea", as to "what on earth is going on!":D . Its an arduous process, and generates a potentially dangerous understanding (in terms of rule-set functionality), but its fun and challenging, and progress is being made, with the help of FG's fantastic community.
With reference to the Anatomy of a rule-set I'm currently trying to figure out what that hidden "order" numberfield does to the characteristics windowlist script. I couldn't follow the description unfortunately.
I'm going to use the same concept (windowlist and windowclass) for another part of my sheet, but dont know if I need to create another hidden "order" numberfield, in which case I will need to rename it, and if that is the case, then I will need to rename it in the windowlist script, but with a local variable called order as well...
The battles only about to begin though, and I'm more prepared than I was this morning thanks to your help.
Baz.
Sorcerer
June 10th, 2011, 00:21
Glad you got it working..
another point I forgot to mention was that you can add text to the print statements so that you can easily identify the differences between variables, or just so you can see that a piece of code has actually fired up, just put the text in inverted commas
print("Hello")
or in conjunction with a variable or function put in two dots .. to concat the text and variable .
print("Crit variable "..crit)
print(Crit Total "..criticalstotal)
The Ruleset in the Anatomy tutorial is a little bit different from most. As you have seen the Characteristics are not set in predefined fields, but are created in a window list. I have not read over the tutorial for a while, but as I recall (and I might be Misrecalling!) the "order" field is there to fix the order and ensure it Windowlist does not sort or change order. A feature of lists is that they can be sorted and change order. Here you want the characteristics to always appear in a set order, which might not be the natural order that the list might sort them to - i.e. Alphabetical.
If you are not trying to set up something with a fixed order then you probably don't need it, but it depends on what you are trying to achieve.
You can always go back and add it in later to see what the difference is.
GMBazUK
June 10th, 2011, 10:28
Thanks for the additional advice Sorcerer.
I went ahead and created another windowlist/windowclass setup based on the Anatomy Characteristics, (whats the worst that could happen?) and simply created another order numberfield (to ensure the list wasn't sorted in alphabetical order, which I was beginning to understand, (but thanks for the confirmation) and I guess (really I guessed) that because the second order numberfield was inside the windowclass definitions it wasn't conflicting with the other order numberfield in the Characteristics Windowclass. Again this is an assumption but so far so good.
Baz.
Sorcerer
June 10th, 2011, 10:59
your assumption is correct they are unlikely to "see" each other when they are nested in different windowlists, but of course if they were on the same window, you could have just changed the name of the field and any calls to it to something else so that they didn't interfere with each other. You cannot have 2 fields with the same name under the same parent database node, but if they do not have a common parent there is no problem.
In this case you are happy they are on different window/windowlists, the problem will be when you have something in one window/windowlist and you DO want it to interact with the other list, trying to get them to talk to each other can be a challenge (I'm currently struggling with windowlists of windowlists, contained within subwindows of windows...)
GMBazUK
June 10th, 2011, 17:09
... (I'm currently struggling with windowlists of windowlists, contained within subwindows of windows...)
Now that's a character sheet, I'd like to see.:)
Baz.
Sorcerer
June 10th, 2011, 17:26
well, if you are messing about with d20_JPG, you have probably already seen something like that - although it doesn't look that complicated to the naked eye.
The spells page of the character sheet is a sub window of charactersheet, and it contains a window list for classes (the d20 rulesets allow you to have 3 multiclasses, all of which could be spellcasting)
each class windowlist contains a windowlist for spell levels, and each spell level contains another windowlist that contains the actual spells for that level (and class).
On the page it looks much simpler, but the code behind it is quite complex, with a number of separate script files to support the actions of the main Charactersheet_spells.xml file.
GMBazUK
June 10th, 2011, 18:36
I am using the d20_JPG ruleset for reference along with a couple of other rule-sets, but I'm still working on my main page which thankfully doesn't reference spells and combat. I have had the occasional "brush" with these sections, but I was deliberately looking away.:D
As far as hidden complexities, that is what has suprised me; the way in which templates, and referenced LUA scripts etc can hide the web of complexity that these rule-sets have.
Baz.
Elawyn
August 12th, 2024, 23:01
I know this is an old thread. But i really want to say thank you to All forum members. Here Are so many helpful explainations. And its possible to create a lua script, that solves a Problem i had, to sum up list values constantly. So, Cheers to All of you.
Powered by vBulletin® Version 4.2.1 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.