Forcing a segment of code to run (making a script blocking)

Started by TerranRich, Thu 22/10/2009 03:27:48

Previous topic - Next topic

TerranRich

I tried searching for this, but couldn't find anything, and I feel like I"m experiencing a mental block with this...

In the global script, I have a CallRoomScript() function that deals with objects in a particular room as long as the player is in that room. Then, the player changes room to a new one. (This is essentially a "taxi cab" system, where the taxi is shown arriving only in one particular room, and then the player is whisked away to a new room.)

Thing is, the script in CallRoomScript() (the room's on_call() function) never gets run, because the player.ChangeRoom() command is activated almost immediately. Is there a way to force the script within the on_call() function to block?

Here is the on_call() function code:
Code: ags

function on_call(int iValue)
{
    if (iValue == 1) {
        // This is reserved for showing the SkyCab driving in, and facing Ron toward it (south)
        oSkyCab.X = 1040;
        oSkyCab.Y = 1028;
        oSkyCab.Visible = true;
        oSkyCab.TweenPosition(1.5, 60, 950, eEaseOutTween, eBlockTween);
        player.FaceDirection(eSouth);
    }
}


As you can see, this sets the initial position of the SkyCab, makes it visible, then animates its movement using a blocking function. Once the SkyCab arrives, the player faces south (using a custom function I made).

Thing is, this script never gets called, even though I know it is supposed to. This is the global script that calls it:

Code: ags

if (player.Room == 3) {
    // Player is at home, so show the cab actually pulling in (via on_call() function)
    CallRoomScript(1);
}
if (sChoice == "Some Location Name") {
    player.ChangeRoom(3);
}
. . .


Or is there something else I'm missing that's causing the on_call() function to not run?
Status: Trying to come up with some ideas...

RickJ

I suspect the problem is that you are changing rooms before the on_call() is executed.  How about moving the change room stuff inside the on_call() thing.  You could create a global function in the global script and call it from on_call() if you want to have it organized that way.

monkey0506

I would imagine that if the Tween module has proper blocking capabilities that the eBlockTween should be sufficient to make the function call blocking (i.e., you shouldn't have to modify the code).

Other than that how is your Character.FaceDirection extender method implemented? Does it allow for a BlockingStyle parameter? If so try passing eBlock to that as well.

Those two things aside the last suggestion I could think of would be to use some Display commands (or the script debugger with break-points) to see if the function is getting called. With Display you can of course check the value of your variables as you go and get a real-time idea of what's taking place...

Edit: Beat by Rick. Who actually may have a point. Although you're calling CallRoomScript I'm not 100% certain when the room's on_call actually gets processed. It's possible it's just added to the function call stack (queue) and so the Character.ChangeRoom is actually being processed first. Try what he said. :P

TerranRich

I guess I could make the sChoice string variable a global variable and do it that way. I'll try as you suggested, Rick. Thanks!
Status: Trying to come up with some ideas...

tzachs

Quoting from the maual:

The function doesn't get called immediately; instead, the engine will run it in due course, probably during the next game loop, so you can't use any values set by it immediately.
Once the on_call function has executed (or not if there isn't one), the game.roomscript_finished variable will be set to 1, so you can check for that in your repeatedly_execute script if you need to do something afterwards.

TerranRich

OK, new problem. I have the following in my rep_ex function:

Code: ags

if (game.roomscript_finished == 1) {
    if (sSkyCabChoice == "Ronald's Home") {
        player.ChangeRoom(3);
    } else if (sSkyCabChoice == "Gryph Cafe") {
        player.ChangeRoom(4);
    } else if (sSkyCabChoice == "Richter Demolition") {
        player.ChangeRoom(8);
    } else if (sSkyCabChoice == "Police Station") {
        player.ChangeRoom(9);
    } else if (sSkyCabChoice == "SouthCoast Savings") {
        player.ChangeRoom(11);
    }
}


Thing is, once the room changes, it keeps changing, repeatedly. Can I change the value of game.roomscript_finished?
Status: Trying to come up with some ideas...

monkey0506

game.roomscript_finished (per the manual) is not read-only so yes, you can write it. Even if it was read-only you could always have just created yet another boolean variable... :P

Quote from: tzachs on Thu 22/10/2009 10:02:32Quoting from the maual:

The function doesn't get called immediately; instead, the engine will run it in due course, probably during the next game loop

Ah...caught me in the act of not actually looking things up again. ::) Otherwise I'd have known 100%.

RickJ

Why not do all that stuff in the on_call() function?

Code: ags

function on_call(int iValue)
{
    if (iValue == 1) {
        // This is reserved for showing the SkyCab driving in, and facing Ron toward it (south)
        oSkyCab.X = 1040;
        oSkyCab.Y = 1028;
        oSkyCab.Visible = true;
        oSkyCab.TweenPosition(1.5, 60, 950, eEaseOutTween, eBlockTween);
        player.FaceDirection(eSouth);

        if (sSkyCabChoice == "Ronald's Home") {
            player.ChangeRoom(3);
        } else if (sSkyCabChoice == "Gryph Cafe") {
            player.ChangeRoom(4);
        } else if (sSkyCabChoice == "Richter Demolition") {
            player.ChangeRoom(8);
        } else if (sSkyCabChoice == "Police Station") {
            player.ChangeRoom(9);
        } else if (sSkyCabChoice == "SouthCoast Savings") {
            player.ChangeRoom(11);
        }
    }
}


TerranRich

Let me try to explain. I have a taxi cab GUI, which is (obvioulsy) a global thing, so the script for the "Hail Taxi" button is global as well. However, in only one room, I will be using an animation of the taxi cab driving up to the player's position. In all other rooms, the player is just transported there instantly. Therefore, if the player is in that particular room (room #3), I want to show the SkyCab animation. Then, regardless of the current room, the selection is looked at, and the room changed accordingly.

However, I managed to work it out using a global boolean, like so... First, the _OnClick event for the GUI "hail cab" button:

Code: ags

control.OwningGUI.Visible = false;
sSkyCabChoice = lstSkyCab.Items[lstSkyCab.SelectedIndex];
if (player.Room == 3) {
    // Ron is at his home, so show the cab actually pulling in (via on_call script)
    CallRoomScript(1);
}/**/
bJustChangedRoomViaSkyCab = true;
// Now control is handed off to the global repeatedly_execute() function, which handles the changing of the rooms


And then the on_call() script for room #3:

Code: ags
function on_call(int iValue)
{
    if (iValue == 1) {
        // This is reserved for showing the SkyCab driving in, and facing Ron toward it (south)
        oSkyCab.X = 1040;
        oSkyCab.Y = 1028;
        oSkyCab.Visible = true;
        oSkyCab.TweenPosition(1.5, 60, 950, eEaseOutTween, eBlockTween);
        player.Walk(440, 710, eBlock, eWalkableAreas);
        player.FaceDirection(eSouth);
    }
}


Finally, the global rep_ex:

Code: ags
if (game.roomscript_finished == 1 && bJustChangedRoomViaSkyCab) {
    if (sSkyCabChoice == "Ronald's Home") {
        player.ChangeRoom(3);
    } else if (sSkyCabChoice == "Gryph Cafe") {
        player.ChangeRoom(4);
    } else if (sSkyCabChoice == "Richter Demolition") {
        player.ChangeRoom(8);
    } else if (sSkyCabChoice == "Police Station") {
        player.ChangeRoom(9);
    } else if (sSkyCabChoice == "SouthCoast Savings") {
        player.ChangeRoom(11);
    } else {
        Display("You chose a selection that was not accounted for. This is a game error and should be reported to the programmers as soon as you see this.");
    }
    bJustChangedRoomViaSkyCab = false;
}


This works perfectly as desired. Thanks for all your help guys!
Status: Trying to come up with some ideas...

SMF spam blocked by CleanTalk