[SOLVED] Countdown from character speech

Started by BrainMayhem, Thu 10/08/2017 14:42:58

Previous topic - Next topic

BrainMayhem

Hi everyone!
I got stuck on what I think is easy to solve, however I still don't have the necessary programming knowledge to come up with a solution :-[

I need a NPC to start a countdown. While he's counting I want to be able to move around the room and leave it if I want.
My problem is that I can't bypass the blocking speech. Tried with Say and the character does count from 20 to 0, but I can't move. Tried with SayBackground and he just says "0"; the loop doesn't work.
Read around the forum and one possible solution would be using GUI, but maybe there's something I'm missing here that could work faster...

Room asc
Code: ags

function room_FirstLoad()
{
  dFirstDialog.Start();
    
  if(isTimHideandSeeking == true) 
  {
      SetTimer(1,800);
  }
    
}

function room_RepExec()
{
  while(counter > 0) //counter is an int defined in 'global variables'
  {
    counter = counter-1;
    textParse = String.Format("%d", counter);  //textParse is a String defined in 'global variables'
    //cTim.Say(textParse);      
    cTim.SayBackground(textParse);      
    SetTimer(1,800);
  }


Thanks in advance!

dayowlron

#1
well I am sure someone can jump in and give you some code examples but a few things I see is:
1) there is nothing to initialize counter to be 20 so I suppose you are doing that fine.
2) I see you setting the timer but never checking to see if the timer has expired. SetTimer does not stop the program from executing for the specified amount of time, it just sets a timer that you need to call IsTimerExpired(timer#).
3) the reason you only see "0" is it runs through all 20 say backgrounds in the very first processing loop.

Something you can try and not sure if it will work but in the room_RepExec change
while(counter > 0)
to
if (IsTimerExpired(1) && counter>0)
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

Khris

First of all note that starting a dialog is queued until the current event handler finishes, meaning this part:
Code: ags
  if (isTimHideandSeeking) SetTimer(1,800); // shortened 

will run before the dialog, not after. The solution is to simply move the statement(s) into the dialog script, right before the stop command. Indent them by at least one space so AGS treats them as AGScript commands, not dialog script commands.

As for the timer, something like this should work:

Code: ags
int counter = 20;

function room_RepExec()
{
  if (IsTimerExpired(1))
  {
    textParse = String.Format("%d", counter);  //textParse is a String defined in 'global variables'
    //cTim.Say(textParse);      
    cTim.SayBackground(textParse);      
    if (counter == 0) {
      // something terrible happens
    }
    else
    {
      counter--;
      SetTimer(1, 20 * GetGameSpeed()); // 20 seconds
    }
  }
}

BrainMayhem

None of the solutions work : /
The NPC doesn't say anything.

By putting the IsTimerExpired() inside the 'if' condition doesn't imply that the Timer has run out? If so, it's not what I'm looking for. I would like the NPC to voice the countdown, so the player can see it.
Maybe using SetTimer is not adequate for this?

dayowlron

room_RepExec gets executed with every game loop which by default is 40 times per second (if i remember correctly)
The call to IsTimerExpired checks during that execution of the function whether the timer has expired and if it has then it returns true causing the statements to be executed every second.

Khris, why did you have SetTimer(1, 20 * GetGameSpeed()) and not just SetTimer(1, GetGameSpeed())? He needs it to go into the if statement every second so you see the countdown.

By saying none of the solutions work can you tell us more about what it is doing?
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

BrainMayhem

Quoteroom_RepExec gets executed with every game loop which by default is 40 times per second (if i remember correctly)
It's correct, 40 loops = 1 second
SetTimer(1, 20 * GetGameSpeed()) is because the game speed is 40. I need 20 seconds, hence the *20.

QuoteBy saying none of the solutions work can you tell us more about what it is doing?
I had some spare time during work, so I tested the game again.
Both solutions (yours and Khris') work partially...the speech is appearing within 20 seconds apart from each other. Like: NPC says "20"; then it takes 20 seconds for him to say "19", and so on.
But I can move the character freely now.

dayowlron

#6
Something else I noticed.
You have the timer starting if you have isTimHideandSeeking set to true and you are running this from the room_FirstLoad event.
Does the flag get set to true before you enter this room for the first time? if not then the timer would never be started so it would never "expire".
Maybe that code belongs somewhere else. maybe room_Load instead?

you need him to count down every second 20...19...18...17, not 20 then 20 seconds later say 19.

Just remove the 20* and it should work
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

BrainMayhem

I've set the default value of "isTimHideandSeeking" to true just for testing. Since the hide and seek game is only for the intro, I don't plan on having it later on.
And yes, the countdown should be in our flow of time :)

I removed the *20, now he's counting right! Here's the final code:

Room asc
Code: ags
function room_RepExec()
{
  if (IsTimerExpired(1) && counter>0)
  {
    textParse = String.Format("%d", counter);
    cTim.SayBackground(textParse);
    counter--;
    SetTimer(1, GetGameSpeed());
    
    if (counter == 0) 
    {
      cTim.SayBackground("Ready or not, here I come!");
    }
}


However, it was still taking 20 seconds for him to begin counting. I bypassed this by putting the SetTimer(1,800) as my first line on the dialog. So when it ends, the countdown immediately begins.
It will only be a problem if the player skips the dialog, causing the countdown to being latter. But I can address to this some other time.
Anyway, thanks guys for the help, you rock! :-D

dayowlron

well SetTimer(1,800) says to not fire off for 20 seconds. try moving the 800 down to like 40.
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

BrainMayhem

You are a genius dayowlron! That fixed it :-D

SMF spam blocked by CleanTalk