[Solved] Assigning a local value to an object global pointer

Started by Lord Vetinari, Sat 14/10/2017 18:10:49

Previous topic - Next topic

Lord Vetinari

Hi everybody, I run into another issue.
There's a random chance that an object appears on the floor as my character moves between rooms.
I set up one copy of the object in each room and set it to initially invisible.
Then I defined a global Object *currentRoomLostObject in the global script header (which I know works, because I used it for other global pointers, and they work fine), tried to assign it a value in the room_load function and made a global function that randomizes the chance of it happaning and turns the object visible. In theory. In practice, the pointer is always null, therefore the test run crashes and highlights the line in the method to tell me that there's no value to use in that pointer, but I can't figure out why the assignment does not work.

Code: ags

//this in each room script

function room_Load()
{
    currentRoomLostObject = objLostObject1 //whatever the object script name is in the current room
}

function room_AfterFadeIn()
{
    object_appears_event();
}

// this in the global script

void object_appears_event () {
    int RandomChance = Random (100);
    if ((RandomChance > 90) && (ObjectCanAppear == true)) { //the second one is a global varialbe that tracks if the player has solved a certain other puzzle elsewhere
        currentRoomLostObject.visible = true;
    }
}


Here I simplified the object_appears_event function to remove some bits of irrelevant coreography (that anyway work properly, as the test run complains about the pointer, not everything else), hoing that this helps.
The same error happens even if I assign currentRoomLostObject in the room_AfterFadeIn function, I tried.

I suppose I could repeat the function code in each room rather than make a single global function, but that seems a less elegant solution (besides, I might have another situation that requires to be handled in a similar way, so it's helpful to understand what I'm doing wrong here even if there is a better solution for this case - mind you, advice on how to handle this differently, if needed, are very welcome anyway).

Help, please? I reckon that the issue is that I'm not assigning a value to the pointer in the same function that uses it, but how can a global function figure out which object should become visible if assigning it each time I enter a room doesn't work? Besides, what's the point of a global pointer if I can't assign it's value in one place and then use it in another?

Snarky

So my first impulse is to say that instead of this approach you should just use a character, which can then appear in any room.

But as for your problem...

Quote from: Lord Vetinari on Sat 14/10/2017 18:10:49
Then I defined a global Object *currentRoomLostObject in the global script header (which I know works, because I used it for other global pointers, and they work fine)

How, precisely, do you do this? Because if it's just...

Code: ags
// Global Script Header
Object *currentRoomLostObject;


... then that's not the correct way, and explains why this is happening.

A header is essentially a bunch of code that gets copied into each and every script below it. So what this means is that you're creating separate currentRoomLostObject variables for each script and each room.

What you instead have to do is define the variable in the Global Script itself, and just put the import line in the header:

Code: ags
// Global Script
Object *currentRoomLostObject;
export currentRoomLostObject;

Code: ags
// Global Script Header
import Object *currentRoomLostObject;


You should do this for all the other global pointers as well. Even if it seems like it's working for now, you may experience similar bugs later on.

Lord Vetinari

#2
Thanks, that was the issue. I'm not used to the old way of define global variables, and the global variables window for some reason seeom to allow the creation of character* pointers, but not objects*.

Anyway,using a character is a good suggestion for this one, I'll try it, thanks. As I said, though, there is another thing later down the line that might need the solution I described here, so this has been very useful (if anything, at least I understood something).

One bonus question: why the other pointers, defined the same way as the troubling one, worked? Was it because I assigned them a value on the fly via mouse coordinates in the same function I used them?

Snarky

Cool, glad you got it working.

Quote from: Lord Vetinari on Sun 15/10/2017 08:13:38
One bonus question: why the other pointers, defined the same way as the troubling one, worked? Was it because I assigned them a value on the fly via mouse coordinates in the same function I used them?

Yeah. Like I said, by doing it the way you did, each script gets its own separate variable with the same name. That variable works fine, it's just that other scripts can't access it: they'll always just see their own variable instead.

Of course, if you're just using the pointer in a single script, there's no need to make it a truly global variable in the first place â€" it can just be "script-global": defined globally in the script (rather than the header), but not exported.

Lord Vetinari

Quote from: Snarky on Sun 15/10/2017 08:23:27
Of course, if you're just using the pointer in a single script, there's no need to make it a truly global variable in the first place â€" it can just be "script-global": defined globally in the script (rather than the header), but not exported.

I know, but there's something on the back of my mind that tells me that I may get a use out of being able to track those values between scripts. If when I wrap up the game it turns out that I don't need that or that I'm running out of global variables (actually, I don't even know if there's still a limit on those I think I remember being a cap at something like 500 in some very old versions; or maybe I just dreamed about that), I'll move the definitions in the script that uses the pointers.

SMF spam blocked by CleanTalk