PDA

View Full Version : xml/script math questions



Insanity
June 5th, 2007, 16:35
I've completed my character sheets for my ruleset for the most part, the only challenge I've had is some math with ability bonuses and such. The d20 default uses the following script, which is in the charsheet_templates.xml, for calculating ability bonuses.

<script>
function onSourceUpdate()
setValue(math.floor((sources[scorefield[1]].getValue() - sources[damagefield[1]].getValue() - 10) / 2) + getModifier());
end

function onInit()
addSource(scorefield[1]);
addSource(damagefield[1]);

super.onInit();
end
</script>


d20 D&D ability bonus is easy, Ability Score - 10 divide by 2.

With my ruleset it is not that simple. A vital statistic (ability) can have several bonuses or related values.
Here is a screenshot of the main charsheet to illustrate what I mean...
https://i130.photobucket.com/albums/p248/Insanity42/BL23C_charsheet_main.png

i.e. Strength has three encumbrance scores, damage bonus, skill bonus; IQ has Power Points, Max Lang, skill bonus. The skill bonus from Strength will not necessarily equal the skill bonus from IQ of the same score. A Strength of 100 will not give the same skill bonus as a IQ score of 100. Vital stats can range from 1 to 150.

I thought the best way to handle this is with a lot of if x=>1, but <=20, y=5 type functions, but do not know enough about the math scripting to describe this.

Any assistance is appreciated...

Dachannien
June 5th, 2007, 22:42
Did you arrive at your ruleset by modifying the d20 ruleset, or did you start from scratch? If you're using the d20 ruleset as a basis, you can define the fields to the right of the base scores using the "linkednumber" template. You can then specify the source field as


<source><name>name of source field</name></source>


You would then need to define a custom update function for each:


<script>
function update()
-- put the guts of the function here
-- To reference a source field, use sources["name of source field"].getValue()
setValue(answer);
end
</script>


As for the specifics of using the scripting system, it works just like Lua. There are links to a Lua tutorial in the library (go to the scripting subsection in the ruleset modification guide).

Toadwart
June 6th, 2007, 01:49
I thought the best way to handle this is with a lot of if x=>1, but <=20, y=5 type functions, but do not know enough about the math scripting to describe this.

As Dachannien said using "linkednumber"'s for your derived fields will help keep the calculations separate.
In regards to the calculations if/elseif would work but could get very messy. As an alternative you might be able to make use of a static table

Here's a very simple example that should calculate a strength skill bonus of:
0 for a strength score less than 10
2 for strength 10-59
3 for strength 60-99
4 for strength >= 130
(note: the code may not be perfect as my lua skills aren't that great and I'm not able to test it right now)




local strengthSkillTable = { [10]=1, [60]=2, [100]=3, [130]=4};

function calculateStrengthSkillBonus(strengthvalue)
local skillBonus;

skillBonus= 0;

for each k, v in strengthSkillTable
if strengthvalue >= k then
skillBonus = v;
end
end

return skillBonus;
end

TarynWinterblade
June 6th, 2007, 02:43
local strengthSkillTable = { [10]=1, [60]=2, [100]=3, [130]=4};

function calculateStrengthSkillBonus(strengthvalue)
local skillBonus;

skillBonus= 0;

for each k, v in pairs(strengthSkillTable) do
if strengthvalue >= k then
skillBonus = v;
end
end

return skillBonus;
end



You always want to enclose a table in pairs() (or ipairs, but that wouldn't work in this instance) if you're iterating over it with a for loop. And there's also the necessity for a "do" statement.

Now to hope that I didn't miss anything... :o

Toadwart
June 6th, 2007, 07:56
Ah, now that I can test it there were a few more flaws...
However, this code works:




function calculateStrengthSkillBonus(strengthvalue)
local strengthSkillTable = { {10,1}, {60,2}, {100,3}, {130,4} };

local skillBonus;


skillBonus= 0;


for k, v in pairs(strengthSkillTable) do
if strengthvalue >= v[1] then
skillBonus = v[2];
end
end


return skillBonus;
end

Insanity
June 6th, 2007, 12:25
bear with me please...

what i've done with my ruleset so far, using the d20 default as a guide, I have a template prepared for vital stats as follows:



<template name="vitalstat">
<numberfield>
<anchored>
<position>belowleft</position>
<offset>0,7</offset>
<size>
<width>32</width>
<height>20</height>
</size>
</anchored>
<frame>
<name>bonus</name>
<offset>5,5,5,5</offset>
</frame>
<keyeditframe>
<name>sheetfocus</name>
<offset>5,5,5,5</offset>
</keyeditframe>
<font>sheetnumber</font>
<script>
function onInit()
if getValue() == 0 then
setValue(50);
end
end
</script>
</numberfield>
</template>


and then for each vital stat I have assigned a source name, I won't show the full code, but looks like this:



<vitalstat name="strength" source="vital.strength.score">

<vitalstat name="manualdexterity" source="vital.manualdexterity.score">


Much the same for all 10 stats, and done the same for the bonuses as well, again using a template:



<vitalbonus name="strengthskillbonus" source="vital.strength.skillbonus">

<vitalbonus name="rangedbonus" source="vital.manualdexterity.rangedbonus">


Strength score ranges from 0 to 150, with values 40-60 having a skill bonus of 0, and in this example, lets then assume scores 40-60 have +0, 61-70 have +1, 71-80 +2, 81-90 +3, 91-100, +4, 101-110 +5, 111-120 +6, 121-130 +7, 131-140 +8, 141-150 +9...

My code would look like this?




function calculatevital.strength.skillbonus(vital.strength. score)
local strengthSkillTable = { {61,1}, {71,2}, {81,3}, {91,4}, {101,5}, {111,6}, {121,7}, {131,8}, {141,9} };

local skillBonus;


skillBonus= 0;


for k, v in pairs(strengthSkillTable) do
if strengthvalue >= v[1] then
skillBonus = v[2];
end
end


return skillBonus;
end

Toadwart
June 9th, 2007, 03:21
I'm still a bit of an lua noob and am having trouble getting my head around how the linkednumberfield works. So heres a simpler bit of code that will work for a single field.



<template name="vitalstat">
<numberfield>
<anchored>
<position mergerule="replace">insidetopleft</position>
<offset mergerule="replace">32,20</offset>
<size mergerule="replace">
<width>32</width>
<height>20</height>
</size>
</anchored>
<frame mergerule="replace">
<name>bonus</name>
<offset>5,5,5,5</offset>
</frame>
<keyeditframe mergerule="replace">
<name>sheetfocus</name>
<offset>5,5,5,5</offset>
</keyeditframe>
<font mergerule="replace">sheetnumber</font>
<script>
local strengthSkillTable = { {61,1}, {71,2}, {81,3}, {91,4}, {101,5}, {111,6} };
function recalculate(source)
local sourceValue = source.getValue();
local skillBonus = 0;
for k, v in pairs(strengthSkillTable) do
if sourceValue >= v[1] then
skillBonus = v[2];
end
end
setValue(skillBonus);
end
function onInit()
if source then
sourcenode = window.getDatabaseNode().getChild(source[1]);
if sourcenode then
sourcenode.onUpdate = recalculate;
end
end
end
</script>
</numberfield>
</template>


An example of the template being used on the charsheet


<vitalstat name="strength_vitalstat">
<source>abilities.strength.score</source>
<anchored>
<to>strength</to>
<position>left</position>
</anchored>
</vitalstat>


Also, you might want to remove the anchored node from the template and just define it when you use the template. The "anchored" behaviour is based on the control it is anchored to. If no "to" anchor is specified it would try to anchor itself to it's container (which may well be the charactersheet itself - in which case it would resize itself to be as tall as the whole sheet).

TarynWinterblade
June 9th, 2007, 07:13
Psst... merge rules default to replace, so you don't need to add in all of the mergerule="replace". :)

What I would suggest is changing the template a bit to make it more generic:

First, add the following in the template's body:


<table>
<entry mergerule="resetandadd" />
</table>


Next, we put change the script a bit:


local strengthSkillTable = { {61,1}, {71,2}, {81,3}, {91,4}, {101,5}, {111,6} };


local sourcetable = {};


function recalculate(source)
local sourceValue = source.getValue();
local skillBonus = 0;
for k, v in pairs(sourcetable) do
if sourceValue >= v[1] then
skillBonus = v[2];
end
end
setValue(skillBonus);
end

function buildTable()
if table and type(table) == "table" then
for _, v in pairs(table) do
if v.value and v.score then
table.insert(sourcetable,{v.source[1],v.score[1]})
end
end
end
end

function onInit()
buildTable()

if source then
sourcenode = window.getDatabaseNode().getChild(source[1]);
if sourcenode then
sourcenode.onUpdate = recalculate;
end
end
end



Now... what that should do... you can build a table in the xml side without having to deal with modifying the script, as such:



<vitalstat>
<table>
<entry>
<value>61</value>
<score>1</score>
</entry>

<entry>
<value>71</value>
<score>2</score>
</entry>

<entry>
<value>81</value>
<score>3</score>
</entry>
</table>
</vitalstat>


Hopefully, I think that works... but it's been a 15 hour work day so far, so... I'm sleepy... >.<

Edit: As an example of my sleepiness, I forgot to include that, in the above code: blue means remove and red means add... I know, I'm backwards...

Toadwart
June 10th, 2007, 02:38
Nicely done Taryn. We like code that is generic. Just hard to figure it out sometimes :)



Psst... merge rules default to replace, so you don't need to add in all of the mergerule="replace". :)

You sure bout this? The documentation says that 'merge' is the default behaviour.

TarynWinterblade
June 10th, 2007, 07:25
You sure bout this? The documentation says that 'merge' is the default behaviour.

Hmm... that it does. I wonder what the difference between "merge" and "replace" is then...?

Aha... the difference is that with merge, if you have a template with tags named table with child elements chair and lamp, and an instance of that with only table and lamp, you'd still get a chair in there. On the other hand, with replace, you'd end up only with table and lamp.

I learn something new every day... (now if only I'd remember half of it... :o )

Insanity
June 18th, 2007, 18:44
Okay, I'll show the code as it is, with the changes of the script as indicated...

First the template, anything in blue is what was indicated to add in...


<template name="vitalbonus">
<numberfield>
<anchored>
<position>right</position>
<offset>9,0</offset>
<size>
<width>36</width>
</size>
</anchored>
<table>
<entry mergerule="resetandadd" />
</table>
<frame>
<name>bonus</name>
<offset>3,5,3,5</offset>
</frame>
<keyeditframe>
<name>sheetfocus</name>
<offset>5,5,5,5</offset>
</keyeditframe>
<font>sheetnumber</font>
<displaysign />
<script>
local sourcetable = {};


function recalculate(source)
local sourceValue = source.getValue();
local skillBonus = 0;
for k, v in pairs(sourcetable) do
if sourceValue >= v[1] then
skillBonus = v[2];
end
end
setValue(skillBonus);
end

function buildTable()
if table and type(table) == "table" then
for _, v in pairs(table) do
if v.value and v.score then
table.insert(sourcetable,{v.source[1],v.score[1]})
end
end
end
end

function onInit()
buildTable()

if source then
sourcenode = window.getDatabaseNode().getChild(source[1]);
if sourcenode then
sourcenode.onUpdate = recalculate;
end
end
end
</script>
</numberfield>
</template>


Now the vitalbonus in the charsheet_main.xml
I did not make changes to the table, I thought add the code, see if it works first.


<vitalbonus name="strengthdamagebonus" source="vital.strength.damagebonus">
<anchored>
<to>strength</to>
<offset>115,0</offset>
</anchored>
<table>
<entry>
<value>61</value>
<score>1</score>
</entry>

<entry>
<value>71</value>
<score>2</score>
</entry>

<entry>
<value>81</value>
<score>3</score>
</entry>
</table>
<scorefield>vital.strength.score</scorefield>
<description>
<text>Strength damage bonus</text>
</description>
</vitalbonus>


The results is, after creating a campaign for the ruleset, it loads fine. When I create a new character and open the charsheet, I get the following error messages.
[18.06.2007 13:40] Script Error: [string "charsheet_main:strengthdamagebonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:strengthskillbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:rangedbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:dexskillbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:iqskillbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:initmodifier"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:defensivemodifier"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:handattackbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:agilityskillbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:bonusbodypoints"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:smrmodifier"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:mentalbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:sensebonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:intuitionskillbonus"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Script Error: [string "charsheet_main:reactionmodifier"]:1: attempt to index local 'v' (a function value)
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static width ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored
[18.06.2007 13:40] Ruleset Warning: Anchored control static height ignored


I've checked and every string with a script error is one in which the vitalstat template is used. I assume the static height issue is not related to the script, but still something I will need to resolve.

Any feedback is appreciated. I not know what is causing the error...

Dachannien
June 18th, 2007, 20:21
I think the problem comes from using "table" as the name of your table. It's not technically a reserved word in Lua, but it is used as the name of the holder for the standard table manipulation library.

Toadwart
June 18th, 2007, 20:25
Hmm, I'm at work at the mo so can't test this but I think it may just be the node name you've used in buildTable. Try changing source to value.


function buildTable()
if table and type(table) == "table" then
for _, v in pairs(table) do
if v.value and v.score then
table.insert(sourcetable,{v.source[1],v.score[1]})
end
end
end
end

Insanity
June 19th, 2007, 02:23
Hmm, I'm at work at the mo so can't test this but I think it may just be the node name you've used in buildTable. Try changing source to value.


function buildTable()
if table and type(table) == "table" then
for _, v in pairs(table) do
if v.value and v.score then
table.insert(sourcetable,{v.source[1],v.score[1]})
end
end
end
end


same error message, thanks for the suggestion though.

joshuha
June 19th, 2007, 03:20
Put it in a script file. I believe > and < for comparision cause weird issues unless you escape them using &gt and &lt.

You'll also be able to debug the line number easier.

Dachannien
June 19th, 2007, 03:35
Joshuha is correct that you have to use the XML entities to represent > and < for inline scripts, as well as the part about getting an actual line number when the script is in a separate file.

As I mentioned above, though, the problem comes from using the name "table", because when you do "for _, v in pairs(table)" in buildTable, it doesn't take the definition of table from your XML. It instead takes the definition of table from the standard libraries that come with Lua, which is a table of functions. Hence the eventual error message (probably in recalculate), "attempt to index local 'v' (a function value)."

Insanity
June 19th, 2007, 04:10
okay, here are the further changes I've made with the template


<template name="vitalbonus">
<numberfield>
<anchored>
<position>right</position>
<offset>9,0</offset>
<size>
<width>36</width>
</size>
</anchored>
<table>
<entry mergerule="resetandadd" />
</table>
<frame>
<name>bonus</name>
<offset>3,5,3,5</offset>
</frame>
<keyeditframe>
<name>sheetfocus</name>
<offset>5,5,5,5</offset>
</keyeditframe>
<font>sheetnumber</font>
<displaysign />
<script>
local sourcetable = {};

function recalculate(source)
local sourceValue = source.getValue();
local skillBonus = 0;
for k, v in pairs(sourcetable) do
if sourceValue >= v[1] then
skillBonus = v[2];
end
end
setValue(skillBonus);
end

function buildTable()
if table and type(table) == "calcbonus" then
for _, v in pairs(table) do
if v.value and v.score then
table.insert(sourcetable,{v.value[1],v.score[1]})
end
end
end
end

function onInit()
buildTable()

if source then
sourcenode = window.getDatabaseNode().getChild(source[1]);
if sourcenode then
sourcenode.onUpdate = recalculate;
end
end
end
</script>
</numberfield>
</template>


and then with the main xml


<vitalbonus name="strengthdamagebonus" source="vital.strength.damagebonus">
<anchored>
<to>strength</to>
<offset>115,0</offset>
</anchored>
<calcbonus>
<entry>
<value>61</value>
<score>1</score>
</entry>

<entry>
<value>71</value>
<score>2</score>
</entry>

<entry>
<value>81</value>
<score>3</score>
</entry>
</calcbonus>
<scorefield>vital.strength.score</scorefield>
<description>
<text>Strength damage bonus</text>
</description>
</vitalbonus>


I am no longer getting any error messages, but it is not doing what I've wanted to do.

i.e. I set the Strength score to 61, the damage bonus remains unchanged.

Dachannien
June 19th, 2007, 05:15
Your function buildTable() still references the "table" library in places you probably don't mean to. I don't know if this is what you're trying to do, but I'll post it and you can look to see if it's right:



function buildTable()
if calcbonus and type(calcbonus) == "table" then
for _, v in pairs(calcbonus) do
if v.value and v.score then
table.insert(sourcetable,{v.value[1],v.score[1]})
end
end
end
end


I also suspect you have some problems in recalculate, specifically that I think (not sure, haven't checked) that source.getValue() returns the string "vital.strength.damagebonus" and not the value in the database corresponding to that.

I'm also not sure that's what you want in the first place - as I understand it, you should be reading from the database field specified in the scorefield tag, your update handler in onInit should be hooked onto that database field, and in recalculate(), you should be pulling the value from that field as well. I may just be misunderstanding what you're trying to do, though :)

Toadwart
June 19th, 2007, 10:46
Err... there were more than a few problems with that code. Not sure I'm fit to explain them at the moment due to too many hours in front of the screen :square:
Try this


<template name="vitalbonus">
<numberfield>
<anchored>
<position>right</position>
<offset>9,0</offset>
<size>
<width>36</width>
</size>
</anchored>
<mytable>
<entry mergerule="resetandadd" />
</mytable>
<frame>
<name>bonus</name>
<offset>3,5,3,5</offset>
</frame>
<keyeditframe>
<name>sheetfocus</name>
<offset>5,5,5,5</offset>
</keyeditframe>
<font>sheetnumber</font>
<displaysign />
<script>
local sourcetable = {};
function recalculate(source)
local sourceValue = source.getValue();
local skillBonus = 0;
for k, v in pairs(sourcetable) do
if sourceValue >= v[1] then
skillBonus = v[2];
end
end
setValue(skillBonus);
end

function buildTable()
if mytable and type(mytable) == "table" then
if mytable[1].entry then
for k, v in pairs(mytable[1].entry) do
if v then
if v then
if v.value and v.score then
table.insert(sourcetable,{0+v.value[1],0+v.score[1]})
end
end
end
end
end
end
end
function onInit()
buildTable()
if scorefield then
sourcenode = window.getDatabaseNode().getChild(scorefield[1]);
if sourcenode then
sourcenode.onUpdate = recalculate;
end
end
end
</script>
</numberfield>
</template>


and



<vitalbonus name="strengthdamagebonus" source="vital.strength.damagebonus">
<anchored>
<to>strength</to>
<offset>115,0</offset>
</anchored>
<mytable>
<entry>
<value>61</value>
<score>1</score>
</entry>
<entry>
<value>71</value>
<score>2</score>
</entry>
<entry>
<value>81</value>
<score>3</score>
</entry>
</mytable>
<scorefield>abilities.strength.score</scorefield>
<description>
<text>Strength damage bonus</text>
</description>
</vitalbonus>



Briefly:

the word "table" appears to have special meaning in an lua script. Hence the change to "mytable", most-any other name you'd like to use should work, just not "table"
scorefield is used to define the field that we are 'watching' i.e. the strength score. While source tells fg where in db.xml to record the value of our strengthdamagebonus field.
when retrieving the values from the xml to add to sourcetable (v.value[1] and v.score[1]) the values are always treated as strings. However, when lua sees 0+v.value[1] it casts v.value[1] to a number and adds zero to it so the result is a number (which is stored in sourcetable). If we don't do this we would have problems later with errors saying "trying to compare a number to a string"Hope it all works for ya now but yell out if there are still problems, or you need a clearer description of something in here.
Tired Toadwart probably not making much sense...

Insanity
June 19th, 2007, 12:23
Thanks all, I think it working fine now. I can show what code is there so you all can check it anways.



<template name="vitalbonus">
<numberfield>
<anchored>
<position>right</position>
<offset>9,0</offset>
<size>
<width>36</width>
</size>
</anchored>
<table>
<entry mergerule="resetandadd" />
</table>
<frame>
<name>bonus</name>
<offset>3,5,3,5</offset>
</frame>
<keyeditframe>
<name>sheetfocus</name>
<offset>5,5,5,5</offset>
</keyeditframe>
<font>sheetnumber</font>
<displaysign />
<script>
local sourcetable = {};
function recalculate(source)
local sourceValue = source.getValue();
local skillBonus = 0;
for k, v in pairs(sourcetable) do
if sourceValue >= v[1] then
skillBonus = v[2];
end
end
setValue(skillBonus);
end

function buildTable()
if calcbonus and type(calcbonus) == "table" then
if calcbonus[1].entry then
for k, v in pairs(calcbonus[1].entry) do
if v then
if v then
if v.value and v.score then
table.insert(sourcetable,{0+v.value[1],0+v.score[1]})
end
end
end
end
end
end
end

function onInit()
buildTable()
if scorefield then
sourcenode = window.getDatabaseNode().getChild(scorefield[1]);
if sourcenode then
sourcenode.onUpdate = recalculate;
end
end
end
</script>
</numberfield>
</template>




<vitalbonus name="strengthdamagebonus" source="vital.strength.damagebonus">
<anchored>
<to>strength</to>
<offset>115,0</offset>
</anchored>
<calcbonus>
<entry>
<value>61</value>
<score>1</score>
</entry>

<entry>
<value>71</value>
<score>2</score>
</entry>

<entry>
<value>81</value>
<score>3</score>
</entry>
</calcbonus>
<scorefield>vital.strength.score</scorefield>
<description>
<text>Strength damage bonus</text>
</description>
</vitalbonus>


If I understand this, for each bonus, I would need to include a new table with entries, correct?

Again, thanks all.

Toadwart
June 19th, 2007, 20:58
If I understand this, for each bonus, I would need to include a new table with entries, correct?


Correct. Each vitalbonus field would have to have a calcbonus node with entries for the calculations.

Of course there are many ways to extend this depending on your needs.
If most of your fields use the same calculation you could define a 'default' calculation in the template.
e.g.


template name="vitalbonus">
<numberfield>
<anchored>
<position>right</position>
<offset>9,0</offset>
<size>
<width>36</width>
</size>
</anchored>
<calcbonus mergerule="resetandadd">
<entry>
<value>61</value>
<score>1</score>
</entry>

<entry>
<value>71</value>
<score>2</score>
</entry>

<entry>
<value>81</value>
<score>3</score>
</entry>
</calcbonus>
<frame>
.
.
.

The "resetandadd" merge rule tells FG to use the calcbonus field from the template unless the field defines it's own calcbonus node. In which case the calcbonus node in the field replaces the one defined in the template.
Then for any field that just uses the 'default' caclulation you specify the field with no calcbonus node like this:


<vitalbonus name="strengthdamagebonus" source="vital.strength.damagebonus">
<anchored>
<to>strength</to>
<offset>115,0</offset>
</anchored>
<scorefield>abilities.strength.score</scorefield>
<description>
<text>Strength damage bonus</text>
</description>
</vitalbonus>


But you can still have other fields that use a different calculation e.g.


<vitalbonus name="dexdefensebonus" source="vital.dexterity.defensebonus">
<anchored>
<to>strength</to>
<offset>115,0</offset>
</anchored>
<calcbonus mergerule="resetandadd">
<entry>
<value>31</value>
<score>1</score>
</entry>
<entry>
<value>41</value>
<score>2</score>
</entry>
<entry>
<value>51</value>
<score>3</score>
</entry>
<entry>
<value>61</value>
<score>4</score>
</entry>
</calcbonus>
<scorefield>abilities.dexterity.score</scorefield>
<description>
<text>Dexterity defense bonus</text>
</description>
</vitalbonus>


note:your current template still has the "table" node. should be "calcbonus" or you could remove it from the template if you aren't going to define any default values for it.

---------------------------------------------------------------------------

You might also have problems with some of the the other nodes in the template that don't specifically define a mergerule (because they will default to using mergerule="merge").
e.g. if you try to use a different font for a field:


<vitalbonus name="strengthdamagebonus" source="vital.strength.damagebonus">
<font>someotherfont</font>
.
.
.

I think FG will just combine the templatewith the field and end up with


<vitalbonus name="strengthdamagebonus" source="vital.strength.damagebonus">
<font>sheetnumber</font>
<font>someotherfont</font>
.
.
.

It might work or it might not.
I'd recommend using mergerule="replace" for the font because we want a font node in a field to override the default font defined in the template.

Have a good read /re-read through the library documentation on mergerules https://www.fantasygrounds.com/modguide/templates.xcp
Had to read it a couple of times and do some experimentation before it made sense to me.

Insanity
June 19th, 2007, 21:18
Unfortunately it is not that easy with this ruleset. i.e.
If you look at the screenshot earlier, the stat Stength has three encumbrance, and then a damage bonus and skill bonus. Neither of them follow the same advancement. When encumbrance increases by one step, the damage or skill bonus may not. If the damage bonus increases one step, the skill bonus may not. Sometimes it in scales of 10s (i.e. Str 11, 21, 31) sometimes not (Agl 33,45, 67). That is the main reason I wanted to get the script to work in the way it is.

I am not sure if any table is identical with the exception of the Intuition bonuses, they are the same values.