PDA

View Full Version : attempt to call global getDatabaseNode (a nil value)



bmos
May 16th, 2021, 14:21
I have an extension that modifies campaign/scripts/spell.lua from 3.5E.

I have this windowclass merge:

<windowclass name="spell_item" merge="join">
<script file="campaign/scripts/spell.lua" />
</windowclass>


and in my spell.lua file I have only:

function onMenuSelection(selection, subselection)
if selection == 6 and subselection == 7 then
getDatabaseNode().delete();
elseif selection == 4 then
SpellManager.parseSpell(getDatabaseNode());
-- bmos removing this line to keep script error away
-- activatedetail.setValue(1);
elseif selection == 3 then
if subselection == 2 then
createAction("cast");
activatedetail.setValue(1);
elseif subselection == 3 then
createAction("damage");
activatedetail.setValue(1);
elseif subselection == 4 then
createAction("heal");
activatedetail.setValue(1);
elseif subselection == 5 then
createAction("effect");
activatedetail.setValue(1);
end
end
end

but on some NPCs I get a bunch of script errors when I open their spell lists:

Script execution error: [string "campaign/scripts/spell.lua"]:54: attempt to call global 'getDatabaseNode' (a nil value)

As you can see, there is not getDatabaseNode function being called at a 54th line, so this is coming from the original file for some reason.

Why would this global function be missing?

Thanks for your time looking at this.

SilentRuin
May 16th, 2021, 14:26
Did you try window.getDatabaseNode?

bmos
May 16th, 2021, 14:44
Did you try window.getDatabaseNode?I don't have anywhere to change that to window.getDatabaseNode().
It's an error coming from a function that I haven't changed (onDisplayChanged in 3.5E's spell.lua)
I have tried adding that function to my spell.lua and commenting out everything in it (leaving the function empty) and it still has the same error!

Specifically this is my Upgrade NPC Actions extension and I'm testing this error by opening Demon, Nalfeshnee from an official Bestiary.
I have changed parseSpell to replace the spell entry (which means that the id-XXXXXX node changes) with one from a module when re-parsing the spell.
I get why getDatabaseNode() might return bad info, but I don't understand is why the global function would be missing completely.
I was hoping I could just empty the onDisplayChanged function since I don't care about its functionality, but for some reason that doesn't even fix the issue as my merged function isn't overriding the one in the ruleset.

SilentRuin
May 16th, 2021, 15:02
I don't have anywhere to change that to window.getDatabaseNode().
It's an error coming from a function that I haven't changed (onDisplayChanged in 3.5E's spell.lua)

I have tried adding that function to my spell.lua and commenting out everything in it (leaving the function empty) and it still has the same error!

Not sure what you mean in this answer. Sometimes things do not set that function and you have to call it off window. You saying you don’t have any place to try that confused me. If your menu function is calling it now adding window in front of it is where you would “call it”. It may not work - but it’s worth a try was all I was saying. But if it worked before as you have it in same circumstances (nothing has changed) not sure what would cause that.

bmos
May 16th, 2021, 15:12
Not sure what you mean in this answer. Sometimes things do not set that function and you have to call it off window. You saying you don’t have any place to try that confused me. If your menu function is calling it now adding window in front of it is where you would “call it”. It may not work - but it’s worth a try was all I was saying. But if it worked before as you have it in same circumstances (nothing has changed) not sure what would cause that.
The script error is coming from spell.lua's line 54 which is in the function onDisplayChanged().
I have not touched onDisplayChanged() so I have nowhere to change getDatabaseNode() to window.getDatabaseNode().

When I did try to replace onDisplayChanged() in my merged copy of spell.lua, it ignored my changes.

SilentRuin
May 16th, 2021, 15:37
The script error is coming from spell.lua's line 54 which is in the function onDisplayChanged().
I have not touched onDisplayChanged() so I have nowhere to change getDatabaseNode() to window.getDatabaseNode().

When I did try to replace onDisplayChanged() in my merged copy of spell.lua, it ignored my changes.

Is it possible its being triggered by a place other than normal somehow? For sure in 5E onDisplayChanged() only present in power_item.lua and power_page.lua (which work fine). But if yours in spell.lua? is somehow triggered during the OnInit cycle it may not be defined yet or something (seen that in other functions). In which case, you just check for nil and skip the call till it works. In other words, its a false error from startup maybe? As I only deal in 5E maybe something I've never seen is going on for you also. Sorry, that's the best I know on advice for this sort of thing which I've had to workaround for other functions in the past (usually involving delete node timing issues).

Kelrugem
May 16th, 2021, 15:59
To my knowledge you cannot merge windowclasses like that; you need to overwrite the full script and not just the part you edit :) (however, one could try super maybe for more compatibility.) (and I now did not read the full conversation here; sorry, if already discussed and mentioned :) )

SilentRuin
May 16th, 2021, 16:05
To my knowledge you cannot merge windowclasses like that; you need to overwrite the full script and not just the part you edit :) (however, one could try super maybe for more compatibility.) (and I now did not read the full conversation here; sorry, if already discussed and mentioned :) )

I assumed that was just a snippet. But if not - then Kelrugem is stating you need to do all the functions even if you don't use them (not sure that is a requirement but I always do it)...

For example...


function onInit()
if super and super.onInit then
super.onInit();
end
end

function onSummaryChanged()
if super and super.onSummaryChanged then
super.onSummaryChanged();
end
end

function updateControl(sControl, bReadOnly, bForceHide)
if super and super.updateControl then
super.updateControl(sControl, bReadOnly, bForceHide);
end
end

function update()
if super and super.update then
super.update();
end
end

function addTrait(sName, sDesc)
if super and super.addTrait then
super.addTrait(sName, sDesc);
end
end
...


But it gets even trickier. If something is actually triggered from one of these super calls and it calls something that you have actually replaced in the same file - then you will need to replace the super call to directly call your replacement else it will end up calling the super version (not yours). I've run into that also when dealing with a function when it is being called in the same .lua overridden file.

bmos
May 17th, 2021, 16:03
To my knowledge you cannot merge windowclasses like that; you need to overwrite the full script and not just the part you edit :) (however, one could try super maybe for more compatibility.) (and I now did not read the full conversation here; sorry, if already discussed and mentioned :) )I've done so in the past without any obvious issues, but maybe I was breaking things without knowing it.


I assumed that was just a snippet. But if not - then Kelrugem is stating you need to do all the functions even if you don't use them (not sure that is a requirement but I always do it)...

For example...


function onInit()
if super and super.onInit then
super.onInit();
end
end

function onSummaryChanged()
if super and super.onSummaryChanged then
super.onSummaryChanged();
end
end

function updateControl(sControl, bReadOnly, bForceHide)
if super and super.updateControl then
super.updateControl(sControl, bReadOnly, bForceHide);
end
end

function update()
if super and super.update then
super.update();
end
end

function addTrait(sName, sDesc)
if super and super.addTrait then
super.addTrait(sName, sDesc);
end
end
...


But it gets even trickier. If something is actually triggered from one of these super calls and it calls something that you have actually replaced in the same file - then you will need to replace the super call to directly call your replacement else it will end up calling the super version (not yours). I've run into that also when dealing with a function when it is being called in the same .lua overridden file.

Hopefully this will solve the issue.

bmos
May 17th, 2021, 17:58
Nope, same error.
I made my spell.lua file like this:

--
-- Please see the LICENSE.md file included with this distribution for
-- attribution and copyright information.
--

local bShow = super.bShow or true;

function setFilter(bFilter)
bShow = bFilter;
end

function getFilter()
return bShow;
end

function onInit()
-- trigger original function
if super and super.onInit then
super.onInit()
end
end

function update(bEditMode)
if minisheet or super.minisheet then
return;
end

-- trigger original function
if super and super.update then
super.update(bEditMode)
end
end

function onDisplayChanged()
if minisheet or super.minisheet then
return;
end

-- trigger original function
if super and super.onDisplayChanged then
super.onDisplayChanged()
end
end

function onHover(bOver)
-- trigger original function
if super and super.onHover then
super.onHover(bOver)
end
end

function createAction(sType)
-- trigger original function
if super and super.createAction then
super.createAction(sType)
end
end

function onMenuSelection(selection, subselection)
if selection == 6 and subselection == 7 then
getDatabaseNode().delete();
elseif selection == 4 then
SpellManager.parseSpell(getDatabaseNode());
-- bmos removing this line to keep script error away
-- activatedetail.setValue(1);
elseif selection == 3 then
if subselection == 2 then
createAction("cast");
activatedetail.setValue(1);
elseif subselection == 3 then
createAction("damage");
activatedetail.setValue(1);
elseif subselection == 4 then
createAction("heal");
activatedetail.setValue(1);
elseif subselection == 5 then
createAction("effect");
activatedetail.setValue(1);
end
end
end

function toggleDetail()
-- trigger original function
if super and super.toggleDetail then
super.toggleDetail()
end
end

function getDescription()
-- return output of original function
if super and super.getDescription then
return super.getDescription()
end
end

function activatePower()
-- trigger original function
if super and super.activatePower then
super.activatePower()
end
end

function usePower()
-- trigger original function
if super and super.usePower then
super.usePower()
end
end


so then I got rid of the merge="join" part in the xml file so it would overwrite the original script and just got a ton of errors about super not existing (which is really weird because I have it in an if statement so it not existing shouldn't even be an issue).

Kelrugem
May 17th, 2021, 18:10
Does it work if you avoid the super prefix? Just for testing purpose, to see where the problem lies. (So, simply overwrite that script by copy&paste and add your edits)

Maybe the super calls are not working nicely with getDatabaseNode()? I am not sure, I never tested the super calls

EDIT: and the mini sheet also calls this function by the way; may not be the culprit here, but for the purpose of your code you may also want to have an xml merge in that regard :)

Trenloe
May 17th, 2021, 18:22
For testing, put a printstack(); command in spell.lua before the line that's causing the error.

Then, when the error occurs, look at console.log and see what function is calling onDisplayChanged() and causing the error.

For example, this is normal (being called as part of onInit):


stack traceback:
[string "campaign/scripts/spell.lua"]:54: in function 'onDisplayChanged'
[string "campaign/scripts/spell.lua"]:38: in function <[string "campaign/scripts/spell.lua"]:16>

SilentRuin
May 17th, 2021, 19:24
I have no idea what spell.lua is and your dealing with a ruleset I know nothing about - but templates don't support "super" if its one of those. And also you have to actually have something already in existence (say base.xml before your .xml is defined) that has the functions your trying to override - or there will be no super then either.

Also, you got rid of the merge? If you don't have the merge then when you give a commonly named class YOU have to supply EVERY SINGLE LINE OF CODE. As that would mean you're outright replacing that class entirely.

bmos
May 17th, 2021, 21:19
Does it work if you avoid the super prefix? Just for testing purpose, to see where the problem lies. (So, simply overwrite that script by copy&paste and add your edits)

Maybe the super calls are not working nicely with getDatabaseNode()? I am not sure, I never tested the super calls

EDIT: and the mini sheet also calls this function by the way; may not be the culprit here, but for the purpose of your code you may also want to have an xml merge in that regard :)I also have changed it in the minisheet, but thanks for the reminder :)


I have no idea what spell.lua is and your dealing with a ruleset I know nothing about - but templates don't support "super" if its one of those. And also you have to actually have something already in existence (say base.xml before your .xml is defined) that has the functions your trying to override - or there will be no super then either.

Also, you got rid of the merge? If you don't have the merge then when you give a commonly named class YOU have to supply EVERY SINGLE LINE OF CODE. As that would mean you're outright replacing that class entirely.not a template, and tried first with merge before attempting without out of curiosity.
I know super doesn't exist without a merge but thought it should just skip that if block since it doesn't exist. Probably not though, because I was then asking for the existence of a function within super (which I assume is why it errors).

bmos
May 17th, 2021, 21:29
For testing, put a printstack(); command in spell.lua before the line that's causing the error.

Then, when the error occurs, look at console.log and see what function is calling onDisplayChanged() and causing the error.

For example, this is normal (being called as part of onInit):


stack traceback:
[string "campaign/scripts/spell.lua"]:54: in function 'onDisplayChanged'
[string "campaign/scripts/spell.lua"]:38: in function <[string "campaign/scripts/spell.lua"]:16>Thanks for this suggestion, I added the onDisplayChanged() function back into my merged spell.lua and added printstack() right before the offending line.
This time when the console opened it was... entirely the same: no output from printstack().

This reinforces my assumption from the last page of this thread:

I have tried adding that function to my spell.lua and commenting out everything in it (leaving the function empty) and it still has the same error!
I was hoping I could just empty the onDisplayChanged function since I don't care about its functionality, but for some reason that doesn't even fix the issue as my merged function isn't overriding the one in the ruleset.
The bizarre part is that the other function I'm overriding in this exact spell.lua is working correctly. So once is overriding correctly and one is not.

EDIT: ok this is even weirder. I added printstack() to the function that IS overriding (onMenuSelection) and printstack was not found. So I tried Debug.printstack() and Debug was not found either.

Trenloe
May 17th, 2021, 22:00
My suggestion was to add printstack() to the original 3.5E code. That is, for testing purposes, extract 3.5E.pak into a 3.5E directory within the rulesets directory, and add that code to see what is calling the original code and producing the error. Then, of course, remember to delete the 3.5E directory when you're finished.

However, it sounds like you have more issues if printstack() raises an error? If so, what error? debug.printstack isn't a valid API function, so you will get an error trying to call that.

Moon Wizard
May 17th, 2021, 22:09
Can you create a simple extension that just attempts to append to spell.lua; and just print out a message?
If that works, can you add more code until it stops working?

In that way, you'll either fine the issue through building up; or you can provide a minimum viable case for me to look at. Sorry I can't jump in deeper than that to help, but my hands are full right now. ;)

Thanks,
JPG

bmos
May 17th, 2021, 23:30
The solution was to replace the onInit function and the onDisplayChanged function. Then I was able to make changes to the onDisplayChanged function (and have them work).
onInit was calling the orignal onDisplayChanged because it was in the original file.

Thank you to all for the help :)

CaptJack2883
May 20th, 2021, 09:30
Please disregard.