Timed sequence and background speech.

Started by GameMaker_95, Tue 27/10/2015 04:54:01

Previous topic - Next topic

GameMaker_95

Hey,

So I had one problem and that got solved and now I've run into another. So what I'm trying to do is that classic
puzzle in Point&Click games where you need to create a distraction so that a character will walk away and you can take something without
them looking. So let me lay out what I want to do. The location is a veterinary clinic.

I have a pair of gloves I want to pick up. I can't because of the desk clerk. There is a dog(a character) in a cage, I want to interact with the dog and
make it bark which will make the clerk leave her desk and I can take the gloves. I have a basic idea that involves if i get an item of the dog that lets me pick
up the gloves and I make the clerk walk to the dog but that would be too clunky. Is there a way to interact with the dog, make it bark in the background and allow me
to walk over to the desk, while the clerk goes to the cage and tells the dog to shut up (which stops it barking in the background.), allowing me to get the gloves, but not if the clerk comes back to the desk.
I believe I'd need to use the Set.Timer function but that's all I've got.

Thanks in advance.

Kumpel

#1
Yeah, I had a similar problem a few weeks ago. You are correct the SetTimer-command is the right choice but not (only) in the way of setting a specific time frame where you can grab the gloves. This frame you have to design has to include:
the clerk going away,
looking after the dog for a specific time frame and
coming back until the point where he can see you.

But you need to use it in the repeatedly_execute_always function of your room though, to let the game do something while you can play and to check what you want (that it's save to take the gloves) in every time unit. But then you got a problem:
For your idea you can't use any game-blocking commands like "wait" or "say". Instead you have to use several SetTimers to simulate the "wait" which maybe also have to include for example your guy saying something to the dog with "SayBackground"(not blocking command) and waiting till he calms down.

Here is an idea:

Code: ags
{
//in room script header
bool dogbark = false;


function repeatedly_execute_always() 
{
  if (dogbark == true)
  cDog.SayBackground("bark bark"); // you need another SetTimer there if you want him to do that in a sequence with pauses
                                   // or use the "BackgroundSpeech" module (forum search) if you want him (or any other character ever) to SayBackground 
                                   // something with speech animation and "wait"s in beetween
                           

   if (IsTimerExpired(t)) // it is important to do SetTimer(t,1) after the (dogbark = true;) for the following actions and can be set optionally in advance, 
                          // if you want to let the character wait before he responds 
   {
    cClerk.UnlockView();  // Always good to do that before NPC actions
    if (dogbark == true)       // if the dog barks 
     {
     cClerk.Walk(x, y, eNoBlock, eWalkableAreas);
     cClerk.AddWaypoint(x, y); // make sure the character stands on the exact spot you want ( AGS is sometimes a bit buggy and not exact there)
     SetTimer(t, 200); // The timer for standing by the dog until he says or does something
     start=0; //prevents a loop
     }
    
    if (cClerk.x == x)
     {
     cClerk.LockView(view); 
     cClerk.Animate(loop, delay, eOnce, eNoBlock); 
     SetTimer(t2, 400);  // set this second timer to an amount your NPC needs to do all you want him to do until he walks back
     }
   }
    if (IsTimerExpired(t2))    
    cClerk.Walk(startx,starty,eNoBlock,eWalkableAreas); 

    if (cClerk.y <= [the "i see you" limit]) // to let him catch you
    {
     whatever you want to do
    }
}

   
Not sure if it's all correct but i think this could work :)

   


Khris

First and foremost, since this is a bit more complex: use proper indentation.

Next, stuff like this is best handled using a state variable. If you use an enum, the code will become MUCH more readable.

Code: ags
// top of room script

enum ClerkState {
  eStateBored, // at desk
  eStateGoingToDog,
  eStateTellingDogToShutUp,
  eStateReturningToDesk
};

// state variables
ClerkState clerkstate = eStateBored;
int dogbarking = -1; // barking state and timer, -1 = no barking, otherwise countdown to bark
Overlay *shutup;


Next, handle talking to clerk and dog (I'm using the BASS template here):

Code: ags
// GlobalScript.asc

function cClerk_Interact() {
  // handle in room script
  if (player.Room == 2) CallRoomScript(1);
}

function cDog_Interact() {
  if (player.Room == 2) CallRoomScript(2);
}


The actual handler code is in the room script, for tidiness reasons and access to room variables
Code: ags
void on_call(int p) {
  // talk to cClerk
  if (p == 1) {
    if (clerkstate == eStateBored) dClerk1.Start();
    else player.Say("She's busy.");
  }
  // talk to dog
  if (p == 2) {
    if (clerkstate != eStateBored) {
      player.SayBackground("Not now.");
      return;
    }
    // make dog bark, set stuff in motion
    player.Walk(cDog.x, cDog.y + 10, eBlock);
    player.FaceCharacter(cDog);
    player.Say("Hiya, doggie! Want to go for a walk?");
    // 20 frames till first bark
    dogbarking = 20;
  }
}


Finally, handle states in room's rep_ex_always:

Dog:
Code: ags
  // handle dog's barking
  if (dogbarking != -1) {
    dogbarking--; // count down frames to next bark
    if (dogbarking == 0) {
      cDog.SayBackground("BARK!");
      // first bark makes clerk walk over 
      if (clerkstate == eStateBored) {
        clerkstate = eStateGoingToDog;
        cClerk.SayBackground("Goddamn dog!");
        cClerk.Walk(cDog.x - 5, cDog.y + 15);
      }
      // next bark two seconds from now
      dogbarking = 80;
    }
  }

 
And clerk:
Code: ags
  // arrived at dog
  if (clerkstate == eStateGoingToDog && !cClerk.Moving) {
    clerkstate = eStateTellingDogToShutUp;
    cClerk.FaceCharacter(cDog, eNoBlock);
    shutup = cClerk.SayBackground("Shut up!");
    // dog stops barking
    dogbarking = -1;
  }
  // done telling dog to "Shut up"
  if (clerkstate == eStateTellingDogToShutUp && !shutup.Valid) {
    clerkstate = eStateReturningToDesk;
    cClerk.Walk(110, 225);
  }
  // arrived at desk
  if (clerkstate == eStateReturningToDesk && !cClerk.Moving) {
    cClerk.FaceLocation(cClerk.x, cClerk.y - 10, eNoBlock);
    clerkstate = eStateBored;
  }


Finally, getting the object:
Code: ags
function oBook_Interact()
{
  if (Region.GetAtRoomXY(player.x, player.y) != region[1]) {
    player.Say("I need to get closer.");
    return;
  }
  if (clerkstate == eStateBored || clerkstate == eStateReturningToDesk) {
    cClerk.SayBackground("Hey, you can't have that!");
    return;
  }
  player.SayBackground("YOINK");
  oBook.Visible = false;
  player.AddInventory(iBook);
}

I'm using a region to check if the player is near the book so everything keeps being non-blocking.

GameMaker_95

Hey guys,

Kumpel I tried to implement yours and when I do, i get an error saying unidentified symbol 't'. Any idea?

Khris, I also tried yours but I don't think I put the scripts in the right place, could you tell me in the simplest way
possible where to place each script and how.

Sorry for the trouble guys.
Thanks.

Khris

Where each part goes is mentioned every single time.

Here's the complete room script: http://pastebin.com/EnPusLKa
This will very likely not work as-is, which is why I provided separate snippets so you can add the code to your existing room script.

Note that the snippets that start with "function" need to be linked to the appropriate events and will not work after simply pasting them.
The second and final snippet are example implementations; your characters are most likely named differently, and with your object being gloves, it probably won't make sense to use oBook_Interact().

My post is not intended as a full beginner's step by step tutorial; it requires a basic understanding of how the functions and events of AGS work.

Kumpel

these stuff are just placeholders the t-timer and t2-timer needs a number of course.

GameMaker_95

Hey,

Kumpel I tried yours again, fixing up the t stuff but it came up with another error, about if.
Khris I tried yours again and I ran into a problem but It was because I didn't change the room number and
when I did it now works perfectly.

Thank you both so much. You've been a big help.

Khris


SMF spam blocked by CleanTalk