Script Question

I am calling a function in a script, if I call it from an include the script does not work properly, but if I call it from the same script it works fine. What am I missing here?

From include (saved and included with no typos):

string GetToBString(object oObject, string sVar)
{
	object oPersistent;
	object oCheck = GetFirstItemInInventory(oObject);

	while (GetIsObjectValid(oCheck))
	{
		if (GetTag(oCheck) == "tob_backup")
		{
			oPersistent = oCheck;
			break;
		}

		oCheck = GetNextItemInInventory(oObject);
	}
	
	return GetLocalString(oPersistent, sVar);
}

In the script:

string EbonGetToBString(object oObject, string sVar)
{
	object oPersistent;
	object oCheck = GetFirstItemInInventory(oObject);

	while (GetIsObjectValid(oCheck))
	{
		if (GetTag(oCheck) == "tob_backup")
		{
			oPersistent = oCheck;
			break;
		}

		oCheck = GetNextItemInInventory(oObject);
	}
	
	return GetLocalString(oPersistent, sVar);
}

Prefixing the “Ebon” in the one in the script was intentional so the script can have access to both and I can switch which one it uses by adding or removing the prefix.

possibly 2+ versions of the #include tucked around someplace …

also possible if the calling script executes from a gui … gui scripts compile on-the-fly and the internal compiler for them is not quite always robust …

 
… what exactly do you mean by “the script does not work properly” ? Have you put debug in to see if it runs/where it fails?

 
and perhaps irrelevant but id form the return like so →

if (GetIsObjectValid(oPersistent))
    return GetLocalString(oPersistent, sVar);
return "";

Only one include. I just made it, so it is unique. Not a gui script.

Basically I am making wrapper functions for local variables. They find an item in a container and set a variable on it. I am still testing them, so I have one tester script that sets the variable, in this case a string, and one that gets it and displays a message if it is there.

This one sets it:

#include "bot9s_inc_levelup"
#include "ebon_inc_persist"

void EbonSetToBString(object oObject, string sVar, string sString)
{
	object oPersistent;
	object oCheck = GetFirstItemInInventory(oObject);

	while (GetIsObjectValid(oCheck))
	{
		if (GetTag(oCheck) == "tob_backup")
		{
			oPersistent = oCheck;
			break;
		}

		oCheck = GetNextItemInInventory(oObject);
	}
	
	SetLocalString(oPersistent, sVar, sString);
}

void main()
{
	object oPC = GetFirstPC(FALSE);
	
	object oToB = GetTomeOfBattle(oPC);
	
	SetToBString(oToB, "AMC_COPY_TEST", "It Worked!");
}

This one gets it and reports:

#include "bot9s_inc_levelup"
#include "ebon_inc_persist"

string EbonGetToBString(object oObject, string sVar)
{
	object oPersistent;
	object oCheck = GetFirstItemInInventory(oObject);

	while (GetIsObjectValid(oCheck))
	{
		if (GetTag(oCheck) == "tob_backup")
		{
			oPersistent = oCheck;
			break;
		}

		oCheck = GetNextItemInInventory(oObject);
	}
	
	return GetLocalString(oPersistent, sVar);
}

void main()
{
	object oPC = GetFirstPC(FALSE);
	
	object oToB = GetTomeOfBattle(oPC);	
	
	string sMessage = GetToBString(oToB, "AMC_COPY_TEST");
	
	SendMessageToPC(oPC, sMessage);
}

Set/GetToBString are in ebon_inc_persist and the prefixed functions are in the respective scripts. If I recompile them as EbonSetToBString and EbonGetToBString in void main() it works (sends me the “It Worked!” message when I run them from the console in succession). If I remove the prefix and call them from the include it does not work.

I think GetLocalString returns "" on error by default. Or at least it did in NWN1. The if conditional check in NWN1 for not there/invalid was if (GetLocalString(blah blah) != ""). But I am continually finding differences between the games, so very good chance I am wrong!

im sure it does in 2 also … /shrug

try putting a SendMessageToPC() first thing in the #include functs, to see if those functs fire up at all

1 Like

Good call - it is not firing from the include… One more piece of the puzzle.

Unsure why though… The include is unique, the name is spelled correctly in the script, and the function that works in the script is just a copy-paste of the one in the include.

are you using Skywing’s AdvancedScriptCompiler? If not try it, if so then try disabling it …

If ebon_inc_persist has a number of other functions, sometimes, if you have not done so already, I have found you need to recompile all scripts that rely on an include. I.e. try recompiling your include for all reliant scripts, even if they do not use that particular function themselves. This can also be a problem if you have been compiling stuff with similar function names.

Also, I assume you are manually adding/removing the prefix and not doing so via string variable handling, which does not work.

Also, make sure that the object being tested is unique. I.e. is there another oObject with sTag? It may be returning vars from that one. EDIT: Although a later post suggests the script was not even firing.

Also, I recently discovered closing and opening the toolset again can fix things.

1 Like

@kevL_s
I did not know that was a thing. I did all my NWN1 scripting in VSCode and I really do not like using the toolset for NWN2. I installed that - I like the advanced debugging messages, but it did not fix the issue.

@Lance_Botelle
The include is only used by those two scripts right now. Just in case, I re-compiled my entire scripting folder which includes every script that could possibly use the other include, bot9s_in_levelup, as well for good measure. Nothing.

Correct, I am manually changing the function name from SetToBString to EbonSetToBString, for instance.

Yeah it’s not even firing, but to your point, that object is unique. Before testing the scripts, I run a script that adds it and gives me feedback telling me it is there. If there is more than one it will give me more than one indicator message.

I have closed and opened a bunch now. Most recently to install the advanced compiler - no dice.

Here are all the scripts involved if anyone wants to take a look:
amc_make_tob.NSS (588 Bytes) [This one makes the object I am setting variables on]
amc_get_tobint.NSS (612 Bytes)
amc_set_tobint.NSS (586 Bytes)
bot9s_inc_levelup.NSS (38.3 KB)
ebon_inc_persist.NSS (6.7 KB)

I think bot9s_inc_levelup is part of an include daisy chain, so you probably can’t compile without the rest of the ToB scripts, but maybe I made some dumb error that will become obvious when looking at the stuff involved.

If this is used elsewhere, then I believe you would probably need to recompile that with all scripts it covers too (for the same reasons I say above).

EDIT: I just saw you did that. :thinking:

I already did - I recompiled everything that could possibly be using it by re-compiling my whole directory (every Tome of Battle script is in there, as are all the ones I have added).

The function coming from that include, GetTomeOfBattle, is working just fine as well.

EDIT: I just saw you saw :wink:

1 Like

Have you tried to change the library to a void function, recompile and then change it back to a library and recompile? I.e. I believe that somehow helps reset the library to do a fresh recompile using just the scripts you have that call upon it. EDIT: At least, that has helped me before.

I.e. All dependant scripts (that you are currently using) will “fail” the compile and you recompile to fix after reverting back to a library and recompiling again for just the scripts you have.

Like putting void main(){} in there and compiling it then commenting it out? Yeah, did that. Also, originally all those functions were in bot9s_inc_levelup, but then I moved them to their own include when I couldn’t figure out why they weren’t working (they are not in bot9s_inc_levelup anymore). Not sure if that is important info.

Fair enough …

Now here is one last issue I have had in the past, which is extremely rare, but … it went something like this …

I have had a second library (same scripts but different library name to one I am replacing) , and I made a change in a reliant script to use my new renamed library instead of the original … and I even left the original library commented out … BUT … it still failed to work with my replacement library.

So, my point is, make sure your scripts do not have any commented out libraries with functions you want to use from your new library, as I believe the compiler can get confused about the libraries, even though you may have commented them out.

EG:

// #include “alb_test”
#include “alb_test2”

This does not appear to work if your functions in “alb_test” one are the same as “alb_test2” and the script had previously been compiled using the original library.

This happened to me once, and I was stumped for days. I still don’t know if it was a “thing” or just where my compilations got confused. It was probably the latter, but it did not sort itself out until I removed the commented library completely.

Wow that is crazy. I just went back to check and it looks like I deleted all the stuff I added rather than commenting it out. I’m going to rename all the functions in the include and see if that works.

What you are describing sounds similar to what I am experiencing, if not exactly the same chain of events. When I first made the functions in bot9s_inc_levelup it didn’t work and then I noticed when I double-clicked the function name it would display a completely different function in the box at the bottom. After that, I closed and opened the toolset, axed all that stuff in the bot9s_inc_levelup include, and made the new include. Now it correctly displays the function when the name is double-clicked.

My point is, it seems like the compiler has a “memory” of some kind even after you comment stuff out.

Or, more likely, I just made a stupid mistake somewhere and haven’t found it yet.

2 Likes

This sounds similar to my own experience that time, which does sound like the kind of thing you are doing … Let us know how you get on.

Ironically, I just renamed the function in the include, saved, and renamed it in the script, and look what happens when I double-click the name:


It’s still displaying the old function that doesn’t exist anymore…

Now, even after compiling the script it is still displaying the old function when double-clicked.

Yeh, that’s the sort of thing that messed with me too when I had it.

You may have to …

  1. Remove the original library completely.
  2. Make your new library “void”, and recompile so all reliant scripts fail.
  3. Turn void back to library - now the only one, regardless of name. (*)
  4. Test again.

(*) Worse case, you may have to even change the name to test … then possibly revert name and recompile.

Well I haven’t tried 2 or 3 yet!

Let us know how you get on.

EDIT: Sometimes you can get away with just changing the name of the function that you have been messing around with for the new library copy. I.e. Try renaming the function to something else to force the compiler to look at new stuff.

i … literally won’t use the toolset’s ScriptEditor … haven’t use it for a decade.

if you’re an avid scripter, try Geany or setting up one of the better text-editors that can invoke Skywing’s standalone compiler, and just say byby to the stock script editor

1 Like