PDA

View Full Version : Updating controls in window from a function



irpagan
May 18th, 2015, 15:41
I'm missing something here, pretty sure its simple but for the life of me I'm missing it.

The short of it is, I have a function called performRestRecovery(rActor) which is supposed to perform some calculations based on the health of a character and then update the appropriate window controls which would then trigger the onValueChanged() function for those fields. Updating the value of lethal or subdual values triggers the onValueChanged() and updates current. Modifying the HP value also triggers an onValueChanged() which recalculates everything.

In template_char.xml I defined the button control as



<template name="button_char_rest">
<button_roll>
<tooltip textres="spell_tooltip_cc" />
<script>
function onButtonPress()
local rActor = ActorManager.getActor("pc", window.getDatabaseNode());
ActorManager2.performRestRecovery(rActor));
end
</script>
</button_roll>
</template>


Then in manager_actor2.lua I defined my function



-- @comment: Talislanta 5e
-- Recover Hit Points after rest and Recovery
function performRestRecovery(rActor)

local sActorType, nodeActor = ActorManager.getTypeAndNode(rActor);
if not nodeActor then
return 0;
end

local ttlHp, hpDelta, sbdl, lthl, currHp = 0;
local newCurrHp, hpHealed, pCon = 0;

if sActorType == "pc" then
ttlHp = DB.getValue(nodeActor, "abilities.hitpoints.score", 0);
sbdl = DB.getValue(nodeActor, "health.subdual.score", 0);
lthl = DB.getValue(nodeActor, "health.lethal.score", 0);
currHp = DB.getValue(nodeActor, "health.currenthitpoints.score", 0);
pCon = DB.getValue(nodeActor, "abilities.constitution.score", 0);
end

-- calculations
hpHealed = 5 + pCon;
hpDelta = ttlHp - currHp;

-- if a neg or zero make 1
if hpHealed <= 0 then
hpHealed = 1;
end

-- Make sure we have something to heal
if hpDelta > 0 then

-- subdual damage should heal first
if sbdl > 0 then

if sbdl <= hpHealed then
--[[ If subdual damage is less than the hpHealed, subtract subdual from Hp Healed, set db value for
subdual to 0 which should trigger updateCurrentHitpoints(rActor) I think* ]]--
hpHealed = hpHealed - sbdl;
sbdl = 0;
else
--[[ other wise same thing excapt we still have damage to heal after this set ]]--
sbdl = sbdl - hpHealed;
end
--DB.setValue(nodeChar, "health.subdual.score", "number", tonumber(sbdl));
charsheet_main.hpsubdual.setValue(tonumber(sbdl));
end

--[[ Subdual damage was 0 or subdual was less than hp Healed and we still have hp to heal ]]--
if sbdl == 0 and lthl > 0 then
if lthl <= hpHealed then
--[[ If LETHAL damage is less than the hpHealed, subtract LETHAL from Hp Healed, set db value for
lthl to 0 which should trigger updateCurrentHitpoints(rActor) I think* ]]--
hpHealed = hpHealed - lthl;
lthl = 0;
else
--[[ other wise same thing excapt we still have damage to heal after this set ]]--
lthl = lthl - hpHealed;
end
--DB.setValue(nodeChar, "health.lethal.score", "number", tonumber(lthl));
window.hplethal.setValue(tonumber(lthl));
end
end

end


I did try updating the underlying db with a DB.setValue() but the only thing I accomplished was corrupting the character record and it did not trigger any onValueChanged() event.

Any advice would be welcome.

Regards,
-d0gb0y

Trenloe
May 18th, 2015, 15:53
It's not clear what your actual issue is here - can you be more specific about what isn't working?

irpagan
May 18th, 2015, 16:08
Thanks for the quick reply.

When I fire the button the behavior I expect is for the subdual and possibly lethal window controls to update with the new value. What I get is the error; Script Error: [string "scripts/manager_actor2.lua"]:381: attempt to index global 'window' (a nil value) ... I assume this is because I don't know how to reference the window from which the button was pushed. The line of code in question reads;

window.hpsubdual.setValue(tonumber(sbdl));

What I am hoping to have occur is set the value of the character sheet subdual hitpoints and trigger the onValueChanged()

Did that make it better or worse?

Regards,
-d0gb0y

Trenloe
May 18th, 2015, 16:17
Did that make it better or worse?
That helped a lot.

The issue you have is that you're calling ActorManager2.performRestRecovery(rActor)); where ActorManager2 is a global package that isn't aware of the window where you are running the code. Which is what you suspected.

You could add window as a second argument to the function, i.e.:

function performRestRecovery(rActor, healthWindow)

and call this with performRestRecovery(rActor, window) to pass the window variable to the function, then use healthWindow within your function wherever you currently have window.

Trenloe
May 18th, 2015, 16:19
And the above assumes that the button you're pressing is in the same window as the health controls. Is this the case?

irpagan
May 18th, 2015, 17:48
Thank you that was definitely the advice I needed.

It was in the same window (charsheet_main), I haven't gotten as far along as to update say one tab's windows controls while operating in another or even a completely new window, although I am highly excited that I can (well maybe I can't ... yet). Not really sure why I'd need to just yet but it excites me anyway.

So I ended up doing something like this;


rWindow.getDatabaseNode().getChild("health.lethal.score").setValue(tonumber(lthl));

so what happens is when this control updates it auto-fires its onValueChanged() event which I am happy to say works like a charm. I could have truncated it a bit by creating a variable but I can read what its doing this way and it's only two lines of code.

Regards,
-d0gb0y

Trenloe
May 18th, 2015, 17:56
So I ended up doing something like this;

...

so what happens is when this control updates it auto-fires its onValueChanged() event which I am happy to say works like a charm. I could have truncated it a bit by creating a variable but I can read what its doing this way and it's only two lines of code.
This is definitely the best way to do updates like this - update the underlying database entry. This results in changes being pushed via the onValueChanged event and also means your code is not tied to a GUI window. This makes it easier to move your code to a more central location - e.g. a button the GM presses to push rest/recovery to all PCs.

irpagan
May 18th, 2015, 18:04
:) Exactly my thought. Onward and upwards as they say "Skills" are next on my list. Thank you again.