PDA

View Full Version : Conflicts in getValue and setValue



SilentRuin
August 19th, 2020, 17:46
I have found that an override of applyDamage() I use is somehow conflicting with another extension (Death Indicator). Both seem to be using 5E code - and it seems there is some kind of race condition between 5E\scripts\manager_action_damage.lua applyDamage() and \5E\scripts\manager_actor2.lua getPercentWounded2(). I admit its very confusing to me.

One extension has a copy of applyDamage() which has a set of 4 calls that set HP values at the end of it. Pure 5E. Another extension has numerous calls to getPercentWounded2() every time they want to find out if they have 0 HP (not sure why they do it that way). Also pure 5E.

Works all the time except when processing a test druid in combat tracker. At that point the getPercentWounded2() will be doing a getValue() on one of the hp* values and fail - immediately followed by a failure of a setValue() in applyDamage() call for the same value. Because its a string of 4 sets in a row for different HP values I've seen it fail on two different ones which makes me think its a race condition. But I have no idea how its happening.

Turning off the one one extension (Death Indicator) which errors first seems to make the problem never happen. And I can never get it to happen on anything else - NPC or PC - except this one druid PC combat tracker entry which I looked in db.xml and see nothing unusual or different about it.

Any clues would be helpful. Thanks for looking.

The errors that starts the two failures (this being the first) is in red below...

Handler error: [string "scripts/manager_actor2.lua"]:25: getValue: Invalid parameter 1


function getPercentWounded2(sNodeType, node)
local nHP, nWounds, nDeathSaveFail;
if sNodeType == "pc" then
nHP = math.max(DB.getValue(node, "hp.total", 0), 0);
nWounds = math.max(DB.getValue(node, "hp.wounds", 0), 0);
nDeathSaveFail = DB.getValue(node, "hp.deathsavefail", 0);
elseif sNodeType == "ct" then
nHP = math.max(DB.getValue(node, "hptotal", 0), 0);
nWounds = math.max(DB.getValue(node, "wounds", 0), 0);
nDeathSaveFail = DB.getValue(node, "deathsavefail", 0);
end



The second error our of applyDamage() is in red below...

setValue: Invalid parameter 1


-- Set health fields
if sTargetType == "pc" then
DB.setValue(nodeTarget, "hp.deathsavesuccess", "number", math.min(nDeathSaveSuccess, 3));
DB.setValue(nodeTarget, "hp.deathsavefail", "number", math.min(nDeathSaveFail, 3));
DB.setValue(nodeTarget, "hp.temporary", "number", nTempHP);
DB.setValue(nodeTarget, "hp.wounds", "number", nWounds);
else
DB.setValue(nodeTarget, "deathsavesuccess", "number", math.min(nDeathSaveSuccess, 3));
DB.setValue(nodeTarget, "deathsavefail", "number", math.min(nDeathSaveFail, 3));
DB.setValue(nodeTarget, "hptemp", "number", nTempHP);
DB.setValue(nodeTarget, "wounds", "number", nWounds);
end


And I have seen it fail on wounds also which makes me think its some kind of race condition. Only the host is running - so I would have thought only one thread was happening.

SilentRuin
August 19th, 2020, 19:23
Grrrrrrr...... That stupid extension triggers on "deathsavefail" changes which then triggers getPercentWounded2() down in the depths of what its doing. That is a different thread as its a handler triggering it. Since I happen to own addDamage() in this case and nobody else seems to suffer from this (not even me most of the time) I've simply reordered the sequence I set things and as predicted in my theory - no more conflict. Though beware world. Ye be warned.



DB.setValue(nodeTarget, "hptemp", "number", nTempHP);
DB.setValue(nodeTarget, "wounds", "number", nWounds);
DB.setValue(nodeTarget, "deathsavesuccess", "number", math.min(nDeathSaveSuccess, 3));
DB.setValue(nodeTarget, "deathsavefail", "number", math.min(nDeathSaveFail, 3));