Issue with .ChangeRoom Timing

Started by RyanIsntAlive, Sat 20/02/2021 22:00:29

Previous topic - Next topic

RyanIsntAlive

Hi there.

I've been having an issue with my code timing, for context, I have a piece of code, which a character walks into an elevator, a gui appears with available floors, and the player can select which floor to go to.
The issue arises when the player selects a floor. The floor I'm focusing on is floor 5, listed as room 5 in the files.

Code: ags

function BFloor5_OnClick(GUIControl *control, MouseButton button)
{
  gLiftFloors.Visible = false;
  Jim.ChangeRoom(5, 550, 150, eDirectionDown);
  Jim.Walk(566, 167, eBlock, eAnywhere);
}


Each individual line works, just not in the right order.
First the Gui listed as gLiftFloors disappears, but then the character Jim walks to the co-ordinates, the screen fades out, fades back in, and Jim is at 550, 150. I've tried the wait function between changing room and walking, but that caused Jim to walk, the game to wait, and then to change rooms. The timing of this code is confusing me.

This code takes place in the Global script. I have other issues with this small section of code, but the timing is the main one currently.

I realise my code isn't too clean, but this is my first project, was hoping for advice.
The guy with the CRT Television Project!

Crimson Wizard

#1
In AGS ChangeRoom is only executed after the script ends. Same is true for few other functions, such as Dialog.Start, SaveGameSlot and RestoreGameSlot, and maybe something else I forgot.

This is mentioned in the manual's article for "ChangeRoom":
Quote
IMPORTANT: This command does not change the room immediately; instead, it will perform the actual room change once your script function has finished (This is to avoid problems with unloading the script while it is still running). This means that you should not use any other commands which rely on the new room (object positionings, and so on) after this command within the same function.

The solution in similar case is to do the remaining commands in the target room's "After fade-in" event. You may check "player.PreviousRoom" if you need to know that player got there from elevator room, or in a more complicated case set some global variable after elevator button is clicked and test it in the target room to see if player came by elevator.

RyanIsntAlive

Ah, okay, Thanks for the explanation.

So if I were to go the variable route
If I set a variable, when clicking the floor button, set the variable to true, and then put in a "if" function after fade in to check if Jim came through the elevator, then put all the stuff I need in that loop, that would probably work like:

Code: ags

function room_AfterFadeIn()
{
  if (Jim.GetProperty("UseLift") == true)
  {
    Jim.Walk(566, 167, eBlock, eAnywhere);
    Jim.SetProperty("UseLift",false);
  }
}


With the button push in global script setting the property "UseLift" to true and changing room.

Is there a more efficient way to do this? Or would player.previousroom be better?
The guy with the CRT Television Project!

Crimson Wizard

#3
Above might work.
If you dont feel like adding custom property (I don't know if you are already using a lot of these) you can also add regular global variable. There's a node called "Global Variables" in project tree that opens a table for variables. Or these may be added by hand as explained in this article: https://adventuregamestudio.github.io/ags-manual/ImportingFunctionsAndVariables.html

player.PreviousRoom is the most straightforward choice if the only condition necessary is that previous room was certain number. But... thinking more about this, maybe it's not really the best, as you may want to simulate some conditions for test game runs later in development, for example.

RyanIsntAlive

I've implimented the code and it seems to be working, thank you a bunch, I'll add the additional floors in and see it all go wrong, but I've got the framework so far.

The global variables might be good to consider, I'm currently unsure how to use them so I'll do some research, does this allow variables within the global script for say gui buttons?

The game is currently an apartment made up of living room, bedroom, bathroom, kitchen, and a hallway with 4 doors and an elevator, I'm focusing on building the game world before starting on any of the story aspects, I'm still early in my first project so my code is a little scrappy.
The guy with the CRT Television Project!

Crimson Wizard

Quote from: RyanIsntAlive on Sat 20/02/2021 23:13:20
The global variables might be good to consider, I'm currently unsure how to use them so I'll do some research, does this allow variables within the global script for say gui buttons?

Global variables are the most common way to store data in your game. Those defined in that table are available literally everywhere, because they are prepended as a autogenerated header to all scripts. They can be only of builtin types though. If you need a variable of your custom type you have to declare it properly in the script yourself.

SMF spam blocked by CleanTalk