GUI blocking SetAsPlayer from triggering room transition?

Started by Laura Hunt, Sat 01/08/2020 18:25:04

Previous topic - Next topic

Laura Hunt

My player character is in room 10 and I want to change to a different one in room 51 for testing purposes. If I do the following:

Code: ags
function hHotspot13_Interact()
{
  gBigBlackGUI.Transparency = 100;
  gBigBlackGUI.Visible = true;
  gBigBlackGUI.TweenTransparency(1.0, 0, eEaseLinearTween, eBlockTween);
  SetNextScreenTransition(eTransitionInstant);
  cTestCharacter.SetAsPlayer();
}


The GUI fades in, and then... nothing happens. The room change never takes place.

But if I do simply:

Code: ags
function hHotspot13_Interact()
{
  cTestCharacter.SetAsPlayer();
}


Then it works normally and I get sent to room 51 as expected. And of course, it also works if I do:

Code: ags
function hHotspot13_Interact()
{
  gBigBlackGUI.Transparency = 100;
  gBigBlackGUI.Visible = true;
  gBigBlackGUI.TweenTransparency(1.0, 0, eEaseLinearTween, eBlockTween);
  SetNextScreenTransition(eTransitionInstant);
  player.ChangeRoom(51, 348, 217, eDirectionLeft);
}


I have no idea what could be making a GUI block a room change, and furthermore, only when I use SetAsPlayer. Any insights? ???

Slasher

what about setting the player just before player change room?

Something like this perhaps:

Code: ags

function hHotspot13_Interact()
{
  gBigBlackGUI.Transparency = 100;
  gBigBlackGUI.Visible = true;
  gBigBlackGUI.TweenTransparency(1.0, 0, eEaseLinearTween, eBlockTween);
  SetNextScreenTransition(eTransitionInstant);
  cTestCharacter.SetAsPlayer();
  player.ChangeRoom(51, 348, 217, eDirectionLeft);
}


Crimson Wizard

Your first code works for me (AGS 3.5.0).

How do you remove GUI in the other room? Is there any code that tests for particular character?

Laura Hunt

Slasher, if I try that, the game crashes with an error that says there's already a changeroom command in the queue. So this means that the room change does get triggered somehow but doesn't actually take place.

CW, I think it might have something to do with the Smooth Scrolling module, because when I turn it off, my first code also works for me. Furthermore, if I do:

Code: ags
targetCharacter = player;
cTestCharacter.SetAsPlayer();


rather than:

Code: ags
targetCharacter = player;
player.ChangeRoom(51, 348, 217, eDirectionLeft);


...then the previous player character ALSO gets teleported to room 51 and the viewport stays fixed on him, even though I am actually controlling cTestCharacter because I literally just set it as the player. It's the absolute weirdest thing.


Crimson Wizard

You probably need to switch the camera target character in the module too.

Laura Hunt

Quote from: Crimson Wizard on Sat 01/08/2020 21:33:34
You probably need to switch the camera target character in the module too.

It's supposed to be set at game_start and it gets checked every cycle in the module's repeatedly_execute_always:

Code: ags
function game_start(){
  
  targetCharacter = player;
  
  system.vsync=true;
}

function repeatedly_execute_always() {

  if (targetCharacter == null) targetCharacter = player;
  if (targetCharacter.Room != player.Room) targetCharacter.ChangeRoom (player.Room);
  //plus a bunch of other stuff to control the viewport
}


Can a module have its own game_start and repeatedly_execute_always? Or should I have copied these functions to my own global script?

Crimson Wizard

#6
I mean, you can probably just do "targetCharacter = newPlayer" before calling "SetAsPlayer"?




Quote from: Laura Hunt on Sat 01/08/2020 21:42:53
Can a module have its own game_start and repeatedly_execute_always?

Yes, every module can have these, they are called in the same order modules are in the project.

Laura Hunt

Quote from: Crimson Wizard on Sat 01/08/2020 22:56:09
I mean, you can probably just do "targetCharacter = newPlayer" before calling "SetAsPlayer"?

Sure, that works. I'm just confused by stuff that should be working but doesn't (like the assigning player as target character, which should happen automatically). Maybe it could even be the tween module interfering with... something... somehow? Who knows. But I managed to make things work, so that's what matters, I guess. Like the wise eri0o once said, "a game is a collection of hacks that ships".


Quote from: Crimson Wizard on Sat 01/08/2020 22:56:09
Quote from: Laura Hunt on Sat 01/08/2020 21:42:53
Can a module have its own game_start and repeatedly_execute_always?

Yes, every module can have these, they are called in the same order modules are in the project.

Good to know. BTW, something I've been asking myself these last few days and I'm really curious about: which one gets called first when a room loads? room_Load, or repeatedly_execute? Or in other words, does repeatedly_execute start ticking as soon as the room is loaded, or after fadein?



Crimson Wizard

#8
Quote from: Laura Hunt on Sun 02/08/2020 05:47:21
Sure, that works. I'm just confused by stuff that should be working but doesn't (like the assigning player as target character, which should happen automatically).

It looks like the module it is not intended to switch to player character automatically, it only does at game start and if targetCharacter is not set (targetCharacter == null).
According to the comments to targetCharacter variable it was made so that you can aim camera at non-player character:
Quote
// v1.7 - Added targetCharacter pointer to make camera animation
//        possible without switching player characters.


Quote from: Laura Hunt on Sat 01/08/2020 21:42:53
Good to know. BTW, something I've been asking myself these last few days and I'm really curious about: which one gets called first when a room loads? room_Load, or repeatedly_execute? Or in other words, does repeatedly_execute start ticking as soon as the room is loaded, or after fadein?

"Room load" is called first before anything else. "repeatedly_execute" is only called after fade-in, because transition is a blocking operation.

Laura Hunt

Quote from: Crimson Wizard on Sun 02/08/2020 06:13:59
Quote from: Laura Hunt on Sun 02/08/2020 05:47:21
Sure, that works. I'm just confused by stuff that should be working but doesn't (like the assigning player as target character, which should happen automatically).

It looks like the module it is not intended to switch to player character automatically, it only does at game start and if targetCharacter is not set (targetCharacter == null).
According to the comments to targetCharacter variable it was made so that you can aim camera at non-player character:
Quote
// v1.7 - Added targetCharacter pointer to make camera animation
//        possible without switching player characters.

Yeah I know, my other issue is that when I switch the module on, the viewport doesn't track the player character even though supposedly it's been set as the target at game_start, and I have to do it manually. But I'll try to look into this with Ali.


Quote from: Crimson Wizard on Sun 02/08/2020 06:13:59
Quote from: Laura Hunt on Sat 01/08/2020 21:42:53
Good to know. BTW, something I've been asking myself these last few days and I'm really curious about: which one gets called first when a room loads? room_Load, or repeatedly_execute? Or in other words, does repeatedly_execute start ticking as soon as the room is loaded, or after fadein?
"Room load" is called first before anything else. "repeatedly_execute" is only called after fade-in, because transition is a blocking operation.

Ah, that explains a few things. Thanks!

Crimson Wizard

#10
In the previous posts, you had a code:

Quote from: Laura Hunt on Sat 01/08/2020 20:28:35Furthermore, if I do:
Code: ags
targetCharacter = player;
cTestCharacter.SetAsPlayer();


<...>

...then the previous player character ALSO gets teleported to room 51 and the viewport stays fixed on him, even though I am actually controlling cTestCharacter because I literally just set it as the player. It's the absolute weirdest thing.

Not sure (this thread starts to confuse me a little), but maybe there's a misunderstanding of what "player" is? Just in case, "player" is not a special value that will automatically switch the variable to player all the time, it is a Character* pointer that directs to current player.
In above code you set targetCharacter to current player character, and then switch player control to another character. But targetCharacter will stay the same. This is why both characters end up in the room (module teleports targetCharacter to where current player is located).

You may instead assign characters explicitly:
Code: ags
targetCharacter = cTestCharacter;
cTestCharacter.SetAsPlayer();


Or change the order of operations:
Code: ags
cTestCharacter.SetAsPlayer();
targetCharacter = player;

so you assign new player, and then assign new player to targetCharacter.

Laura Hunt

Quote from: Crimson Wizard on Sun 02/08/2020 14:03:03
Not sure (this thread starts to confuse me a little)

Yes, I'm sorry. This really has ended up in a totally different place.

I wouldn't be surprised if my initial issue had been a glitch, though. Sometimes I have things happen only once that can't be reproduced, and I'm thinking it might even be my hard drive or my RAM failing. For example, there was this one time in which I was testing my game, and clicking on an object was supposed to make the character walk up to it (blocking), and then start a dialogue. It had worked perfectly the 3572350 times I'd tested it before, but on this occasion the walking was skipped, and the dialogue was triggered immediately, as if the walk command had been set to noblock. I closed the game, ran it again, did the exact same thing, but I was never able to reproduce the issue. So go figure.


Quote from: Crimson Wizard on Sun 02/08/2020 14:03:03but maybe there's a misunderstanding of what "player" is? Just in case, "player" is not a special value that will automatically switch the variable to player all the time, it is a Character* pointer that directs to current player.
In above code you set targetCharacter to current player character, and then switch player control to another character. But targetCharacter will stay the same. This is why both characters end up in the room (module teleports targetCharacter to where current player is located).

Mind. Blown. Thank you, CW. I had no idea this was how it worked. Now it makes total sense.


Quote
Or change the order of operations:
Code: ags
cTestCharacter.SetAsPlayer();
targetCharacter = player;

so you assign new player, and then assign new player to targetCharacter.

Would this work, though? Wouldn't the room change from setting cTestCharacter as player be effective immediately, thus keeping the next line from running?

Crimson Wizard

Quote from: Laura Hunt on Sun 02/08/2020 15:39:38
Quote
Or change the order of operations:
Code: ags
cTestCharacter.SetAsPlayer();
targetCharacter = player;

so you assign new player, and then assign new player to targetCharacter.

Would this work, though? Wouldn't the room change from setting cTestCharacter as player be effective immediately, thus keeping the next line from running?

In AGS script room change is scheduled to when callback returns to the engine, same is for few other things like dialog start.
(Which is often a cause of inconvenience, but that's another issue...)

SMF spam blocked by CleanTalk