Keeping character in same location they were in after switching rooms?

Started by skooperstooper, Thu 15/09/2022 01:20:04

Previous topic - Next topic

skooperstooper

Sorry if I remembered this wrong but it seems the default behavior in AGS is that a character's starting coordinates stay the same from room to room unless you manually change them. How do you get them to stay where they were last instead?

For example, what if I use a room switch as a cutaway? This isn't what I'm doing, it's just to explain what I mean. Say there's a phone in the room and the player goes up to it to make a call, then the game switches to another room showing the person on the other end of the line.

When the call ends and the game returns to the room the player is in, they should still be standing where they last were (at the phone), not back at wherever they started the room. How do I handle something like that?

You can just point me to a link if you want. I couldn't get to what I was looking for from search. Thanks!
Yes, I did the tutorial, went through the manual, and searched the forums and web. If I'm asking, it's because I missed it, forgot, or still don't get it.

Pax Animo

Not sure what the optimal solution is but you could save the characters coordinates in x/y global variables just before leaving the room and then call them back when returning to the room.

Code: ags
player.ChangeRoom("room number", x, y)


There is also https://adventuregamestudio.github.io/ags-manual/Character.html#characterpreviousroom

I wonder if there could be an extension to this such as "Character.PreviousRoomXY"
Misunderstood

skooperstooper

Ok, thanks. I'll work out how to do that. I guess I have to get their current XY coordinates right before the room switch, save that as a variable, then use that variable to set where they'll be when switching back.

I assume by global you mean to use the global variables panel to make it, not the global script? Because I'm sure there will be multiple occasions where I'll want characters to be wherever they last were without wanting to fully script that for every single instance. I'll want to be able to just say "put them blah" where blah = last coordinates.
Yes, I did the tutorial, went through the manual, and searched the forums and web. If I'm asking, it's because I missed it, forgot, or still don't get it.

Pax Animo

Yes within the global variable panel. (i guess there is a better way of tracking previous room character x/y without the repetition of doing it after every room leave, but i don't know how)

Then pretty much something like this:

Code: ags
function room_Leave()  //the room you are leaving
{
  prev_room_x = player.x;
  prev_room_y = player.y;
}


Edit: or
Code: ags
function room_Leave() 
{
  prev_room_x = player.x; prev_room_y = player.y;
}

I think this works as a short cut.

Then when you are ready to go back to the room:

Code: ags
player.ChangeRoom(player.PreviousRoom, prev_room_x, prev_room_y);
Misunderstood

Snarky

Unless I'm missing something, doesn't it already work the way you want? Character coordinates should remain wherever they are through changerooms, not reset to the entry coordinates, as long as you don't override them. So in this case, just leave your player character by the phone, and when you return to the room, that's where they'll be.

(To switch to the other room, you would either Change Room with the player character and hide them, or--better--just temporarily change the player character to the character in the cutscenes.)

Khris

Here's a small module you can add:

Header:
Code: ags
import function StorePosition(this Character*);
import function ChangeRoomLastPos(this Character*,  int room);


Main Script:
Code: ags
Point* rc[];

void game_start() {
  rc = new Point[Game.CharacterCount];
}

function StorePosition(this Character*) {
  if (rc[this.ID] == null) rc[this.ID] = new Point();
  rc[this.ID].x = this.x;
  rc[this.ID].y = this.y;
}

function ChangeRoomLastPos(this Character*,  int room) {
  if (rc[this.ID]) player.ChangeRoom(room, rc[this.ID].x, rc[this.ID].y);
}



When your player leaves for the cutscene, call  player.StorePosition();  right before sending them to the cutscene room.
When they return to the game room, simply call  player.ChangeRoomLastPos(ROOM_NUMBER);  to use the stored coordinates.

skooperstooper

Snarky, I thought it did what I want by default because I assumed the character position is part of the room state that saves when you exit it, but it seems to carry over any coordinates set for previous rooms instead.

Meaning if I manually set the coordinates for room 2, then the player goes to room 3, they start with the same coordinates I set for room 2 unless I manually change it.

Sometimes, that's fine, but if the player walks around, once I switch to any room where the coordinates are set, they won't be wherever they walked when I go back. They again start at whatever coordinates were set in the room they just left.

Either way, I'm asking for instances where I do manually set the character's starting coordinates for that room, so I'll need to override that by going back to wherever the player just was instead of reverting to the manual coordinates I set for it.

Sticking with the example I gave, say the room with the phone in it has a visible door. I set the player's starting coordinates to always be at the door because in 99% of cases, the game will only be switching to that room because the player literally walked into it.

And I like the continuity of them entering at the door each time instead of poofing somewhere else in the room.

But for this situation, the room switch won't be from them walking in, it'll be from a cutaway, so I'll need to tell it to ignore my manual coordinates and use the last ones instead.

ETA: Khris, I'll take a look at that code, thanks! I don't think I'll be doing a cutaway like that more than once or twice so tiny script that won't impact anything else in the game is good.
Yes, I did the tutorial, went through the manual, and searched the forums and web. If I'm asking, it's because I missed it, forgot, or still don't get it.

Snarky

Like I said, in the scenario you describe (a cut scene showing the other end of a phone call in a room the player isn't in), the best thing would be to not send the player character to the room at all, but to simply switch to make one of the characters who is in the room the player character temporarily, and then switch back when you cut back to the player character. That way you avoid all of this, and it's better because it means the logic of the code is a closer match to the logic of what's happening in-game.

The thing that breaks normal AGS behavior here is you snapping the character to the door any time they enter the room. If the above solution is not applicable in your "actual" scenario, I would suggest adding a flag to disable that snapping feature. (I do understand why you have it, it's a justifiable workaround for the bad design of AGS's room change API.)

I forget if it's already a ticket, but in AGS 4 (though not necessarily 4.0), it would be nice if you could do somethings like player.ChangeRoom(RoomStudy, RoomStudy.DoorPoint, eDirectionDown); (i.e., add the ability to define named coordinates as part of the room data, and make rooms a data type to give access to their data even when outside of the room, and to refer to them by name instead of number). That should make your workaround unnecessary.

skooperstooper

Yes, I read what you said about switching which character is the active player character, but the phone thing was just an example I gave. There's no character in the cutaway and it's not a phone call. I'm just asking about different ways to accomplish switching rooms and retaining position in general.

Manually setting the position obviously overrides wherever the player last was. That's why I asked for a way to store wherever the player last was.

What I'm asking now though is for clarification on how player coordinates are supposed to behave regardless. Is it room specific or not? Should coordinates set in another room carry over to the next room the character changes to? What's the default behavior in AGS?

Like I said, I thought the default behavior would be that rooms function independently with player coordinates. So if I manually set player coordinates in room 1, it would only apply to when the character is in room 1. Instead, it applies to every single subsequent room they enter. Is that the normal behavior?

That makes sense if player XY is global so when you change the coordinates, it's not specific to that room. It just changes their coordinates for the entire game until they're changed again.

I just want to verify that's what's happening, and I did read the manual about XY way back when I started playing around with AGS so if it specifically states that, I don't remember.
Yes, I did the tutorial, went through the manual, and searched the forums and web. If I'm asking, it's because I missed it, forgot, or still don't get it.

Crimson Wizard

Quote from: skooperstooper on Sat 17/09/2022 03:12:05
Should previous coordinates carry over to the next room the character changes to or shouldn't it? What is supposed to be the default behavior in AGS?

The default AGS behavior is that if no coordinates are given in ChangeRoom command, the current character's coordinates are carried over.

Characters do not remember "per-room" positions, they only have one current position and nothing else.

Snarky

Quote from: skooperstooper on Sat 17/09/2022 03:12:05
Yes, I read what you said about switching which character is the active player character, but the phone thing was just an example I gave. There's no character in the cutaway and it's not a phone call. I'm just asking about different ways to accomplish switching rooms and retaining position in general.

I know, but I can only go by the problem as you describe it. If there is no character in the cutscene, I would just create an invisible dummy character, e.g. cCutsceneObserver. It doesn't really change anything. My point is that sending the player character to a different room just to play a cutscene in that room (when the character is not actually there) is a workaround in the first place, and if it causes side-effects, it's better to not use that method than to build ever-more-elaborate fixes for the problems it introduces.

Now, one might ask what would be the best way to go about it if the cutscene was something like a flashback with the character. In that case, I'd say you could either save-and-restore the current character state before and after the flashback (IOW your approach), or make a duplicate character, e.g. cGuybrushFlashback, to use in the flashback scenes to sidestep the need, depending on what's easiest. (A game that uses a lot of flashback cutscenes is If on a Winter's Night, Four Travelers, so we could ask Laura how they go about it there; though typically they transition smoothly in and out of the flashback rather than jump to a completely different scene, so it's not quite the same. Maybe Unavowed would be a better example.)

Quote from: skooperstooper on Sat 17/09/2022 03:12:05What I'm asking now though is for clarification on how player coordinates are supposed to behave regardless. Is it room specific or not? Should coordinates set in another room carry over to the next room the character changes to? What's the default behavior in AGS?

Like I said, I thought the default behavior would be that rooms function independently with player coordinates. So if I manually set player coordinates in room 1, it would only apply to when the character is in room 1. Instead, it applies to every single subsequent room they enter. Is that the normal behavior?

As CW explains, yes that is normal. I mean, would the alternative even make sense? Your position is a property of the current moment. Once you have left a room, your position is no longer at any coordinates in that room. There's no reason in general why the next time you go there your last position in that room should be restored. (More often the starting position would depend on the particular entry you used, or in Sierra-style games, on where along the edge you exited the previous room.)

Cassiebsg

What I normally do, is just check the player.PreviousRoom, like this:

Code: ags

function room_AfterFadeIn()
{		
if (player.PreviousRoom==28)
	player.Walk(90, 561);
else
	player.Walk(730, 547);
}

function room_LeaveLeft()
{
player.ChangeRoom(28, 573, 345);
}

function room_LeaveRight()
{
player.ChangeRoom(30, 5, 546);
}



Of course, you instead of adding the coordinates on the player.ChangeRoom, you can also just add the check of player.PreviousRoom to room_Load() and then set the player x,y.

This works, good, as long as you don't have multiple arrival points to the same room from the previous room.
Otherwise, you'll just need to store players last coordinates, so you can easily return to them.
There are those who believe that life here began out there...

SMF spam blocked by CleanTalk