Puzzles based on NPC location

Started by Bagge, Fri 18/05/2012 00:23:03

Previous topic - Next topic

Bagge

Hello World. First post here.

I just implemented a puzzle in an AGS game I'm working on that works like this:
A man is reading a book at a table in a cafe. You need that book. If you try to take it, he will shod you off. However, if you go over to the jukebox and change the song to something obnoxious, the guy will leave his table and book and head over to the jukebox to change back.
Of course, while he is away from his book, you can steal it.

I managed to get the puzzle working, but I feel like the code is a bit shoddy, and I'm wondering if there's a cleaner, better way than to solve it like this.

(I am using the SCUMM-like 9-verb GUI that came with the latest version of AGS, but I believe the principle would be the same no matter what GUI you use.)

Here is the code for when the player USES the jukebox:
Code: AGS

function oJukebox_AnyClick()
{
  if(UsedAction(eGA_Use)) {
    player.Walk(224, 72, eBlock, eWalkableAreas);
    player.FaceDirection(eDir_Up); // Player walks over to the jukebox and face it
    SetGameOption(OPT_CROSSFADEMUSIC, 0); // I want abrubt change of music
    aClub_Diver.Play(); // Play obnoxious song
    Wait(40); // There needs to be a delay from when the music starts to when the guy leaves his table
    SetGameOption(OPT_CROSSFADEMUSIC, 3); // In case the player leaves the room while the new music is playing
    cBarPatron4.Walk(218, 73, eNoBlock, eAnywhere); // The Guy walks to the jukebox.
  }
}


Then, in the room_RepExec function I put the following code:

Code: AGS
   
if(cBarPatron4.x == 218 && cBarPatron4.y == 73 && jukebox_limiter == true) { // Repeatedly check if the NPC is at the location he was told to walk to.
      jukebox_limiter = false; // This is here to stop the game from freezing when the NPC reaches his destination. It's a boolean, with a default value of "true".
      SetGameOption(OPT_CROSSFADEMUSIC, 0); //I want abrubt change of music
      aBass_Vibes.Play(); // Play the calm music again
      cBarPatron4.Walk(68, 86, eNoBlock, eAnywhere); // The NPC heads back to his table
      SetGameOption(OPT_CROSSFADEMUSIC, 3);
    }
    if(cBarPatron4.y == 74) { // Once the NPC is on his way back, it is possible to change the music again.
      jukebox_limiter = true;
    }
 


The code for picking up the book is a simple "if" checking if the NPCs x-coordinates are above a certain value.

Is this a good way of solving this? It feels a bit unelegant to do a constant check in the room_RepExec function to see if the NPC is at a given location. Is it possible to stop the game from running the next line of code in the function until the previous line has been completed? In this case, that would mean that the game would not change the music or send the NPC back to his original location before he reached the jukebox, even if I put all the code in a single function (all while the player is free to move and interact, so I can't use eBlock).

Tips and pointers greatly appreciated!

Kweepa

#1
It looks like you're doing pretty much the right thing.
I would change it from detecting exact x,y coordinates for the character to instead use room regions. You just need one region placed at the jukebox.
Code: AGS

Region *r = Region.GetAtRoomXY(cBarPatron4.x, cBarPatron4.y);
if (r == region[1])
{
  if (jukebox_limiter == true)
  {
    // stuff
    jukebox_limiter = false;
  }
}
else
{
  jukebox_limiter = true;
}

Still waiting for Purity of the Surf II

SMF spam blocked by CleanTalk