Prioritizing the dialogues in a function. [SOLVED]

Started by Pierrec, Fri 06/09/2013 10:10:34

Previous topic - Next topic

Pierrec

Hi!
I've been using AGS for more than two years for making small adventure/visual novel games, and it hass always been great. Now I would like to make a bigger, more complex game, and I realize my coding skills aren't close to be good enough. I encounter a lot of problems, and hopefully, the help file, the forums and the wiki almost always solve them for me. But this time, I didn't find anything...mostly because I don't know what to search for exactly.

I'll try to explain (it might be a bit complicated) :
The game is kind of like King of Dragon pass. I have several characters, I assign them some missions, and then I end my turn to see what happens.
So, let's say I've got 2 characters (in fact there are 10 of them), Clement and Jean-Charles. I assign them to dig (aClem=1, aJC=1) and end the turn. It first calls this script


Code: ags

// Define who's "acting"
function room_AfterFadeIn()
{
if(aClem==1){
 Who="Clement"; 
 WhoSuj="he";
 WhoComp="him";
 WhoPoss="his";
 Archeo();
 }
 if(aJc==1){
 Who="Jean-Charles"; 
 WhoSuj="he";
 WhoComp="him";
 WhoPoss="his";
 Archeo();
 }
}


//This determine what string should be used in the displays, and runs the Archeo function for each one of them. 

//Now here the Archeo Function : 


//The different events that may happen (randomly) 

function Archeo(){
  int randig=Random(99)+1;
  if(randig<=10){
    Display("%s dug all the afternoon, but it seems %s luck has abandonned him : %s couldn't find anything of interest", Who, WhoPoss, WhoSuj);
    }
    
  if((randig>10)&&(randig<=30)){
    Display("%s efforts weren't totally vain : %s found one rare material. Better than nothing!", Who, WhoSuj);
    RM=RM+1;
  }
  if((randig>30)&&(randig<=60)){
    Display("%s is exhausted for having dug all day, but it was worth it : %s found 2 rare materials", Who, WhoSuj);
    RM=RM+2;
  }
  if((randig>60)&&(randig<=90)){
    Display("%s's lucky star haven't failed %s : %s brought 3 rare materials to the camp, and didn't forget to brag about it!", Who,  WhoComp, WhoSuj);
    RM=RM+3;
  }
  if(randig>90){
    int randigevent=Random(99)+1;
      if(randigevent<=20){
        Display("When %s came back to the camp, nobody could believe his eyes. The blessed digger didn't find any rare material, but something much more worthy : BONES! Not chicken bones, not rabbit bones, but Dinosaur bones!", Who); 
      Display("It was easy to tell because they look pretty old, like millions years old, and there weren't any chicken or rabbit back then.", Who);
      Display("Though everyone was happy with this discovery, an argument broke out to know wether the bones were from a t-rex or an allosaurus. It escaladed very quickly. A decision has to be made.", Who);
        
        dDinosaur.Start();
       
      }
      if((randigevent>20)&&(randigevent<=40)){
        Display("It's a bad day for %s. Despite all %s efforts, %s couldn't find anything worthy. The night was falling, and %s was about to leave, when %s saw something shining in a dirt.", Who,  WhoPoss, WhoSuj, WhoSuj, WhoSuj);
        Display("A coin! It was a coin! A by the look of it, a very very old one, probably a Roman sestertium. By screwing up his eyes, %s could precognize Trajan portrait on it: yeah, totally a sestertium!", Who);
        Display("No doubt it would bring prestige to the clan!", Who);
        
      }
      if((randigevent>40)&&(randigevent<=60)){
        Display("When %s went digging this afternoon, %s felt a strange power coming from the dirt...well, as least that's what %s told the others. It was like someone â€" or something â€" was calling %s, telling %s where to dig.", Who, WhoSuj, WhoSuj, WhoComp, WhoComp);
        Display("%s followed the voice, and soon found a strange stone, glowing red in the dusk, definitely a magic stone! ''The most beautiful thing I've ever seen'', she said.", WhoSuj, WhoSuj);
     
        dStone.Start();
       }
      if((randigevent>60)&&(randigevent<=80)){
       dPickaxe.Start();
       }
      if((randigevent>80)&&(randigevent<=100)){
        Display("Woah, super cool");
      }
    
    }
}


It works great. First the game display the Clement's event, then the Jean-Charle's event.
BUT : If Clement, the first one, ends up with an event with a dialogue in it (dDinosaur, dStone...), the dialogue will be triggered AFTER the JC event!
I just can't understand why! Isn't the script supposed to be executed line by line ? Why does the dialogue wait until the end of the function to be triggered.
I don't think it's a bug, I think it's me not really understanding how programing works. Normally, I would fix this by using a bunch of variables (like : don't trigger JC's event until Clemsevent=1, and, in the end of Clem's dialogue : "Clemsevent=1", but as I said, I've got plenty of character and this could become very messy really quick! I'm sure there is an easier way, because I'm sure there's something I quite don't understand in the way AGS (and programming) is working. Could you enlighten me ?

thanks!     

Kitai

Hi Pierrec (glad to hear about a new game of yours!)

If you take a look at the AGS manual for the dialogs Start command, you'll see the following caveat:
QuoteNOTE: The conversation will not start immediately; instead, it will be run when the current script function finishes executing.
This means that in your code, if a dialog is called via Archeo in the first condition of your room_AfterFadeIn function and other (directly executed) commands (like Display) are further called in the second condition, then the effects of these second (directly executed) commands will show up before the dialog.
So as you guessed, this behavior is predicted to happen in AGS.

I can't think of a general and elegant solution for now, but I'm sure other people here will come with one soon.

Khris

This comes up every few weeks.
To quote the entry for Dialog.Start()
QuoteNOTE: The conversation will not start immediately; instead, it will be run when the current script function finishes executing.
This means that anything that's supposed to happen afterwards has to be either coded inside the dialog (you can use standard script commands of you indent them by at least one blank space).
Or you have to use another mechanism, for instance at the end of the dialog, a flag variable is set to true, and the room's repeatedly_execute will constantly check the variable and run code as soon as that happens.

Pierrec

Thank you for the quick replies! And sorry if the question has been asked before :-[ . the problem is indeed explained in the help file, but not his solution. Anyway, I get it now.
I was hoping for an easy way to bypass the problem, something like Dialog.Start(NOW); but since you tell me there is not such thing, I had to use a flaf variable as you suggested. It works, but it makes the code messy, I guess I have to get used to it ^^

Thanks a lot! I flag this topic "solved"



SMF spam blocked by CleanTalk