Multiple Dialogs help

Started by Kivrin, Thu 23/08/2007 06:40:18

Previous topic - Next topic

Kivrin

I'm trying to script a dialog puzzle that has running loops based on conditionals.  Since there doesn't seem to be a way to test a conditional within a conversation, I thought it would be better to break it up into separate parts and call them from the room script, so that certain parts would repeat until a certain line was selected.  However, when I try to run a dialog part from within a while loop, it exits with the error "RunDialog: Cannot queue action, post-script queue full" without showing any of the dialog text.

I thought maybe the dialog was non-blocking and attempting to run itself over and over again, but reading through the forum it looks like it is, plus adding a wait(1) loop caused it to run indefinitely.  Is this something I can fix, or should I redesign the whole setup?

Thanks

Terrorcell

coulc you give us a code example?

Khris

Dialogs won't run until the current function has finished. So whenever AGS encounters the command to start a dialog, it get's queued.
Hence putting a dialog-start command inside a while is not exactly recommended ;)

Use the dialog_request function to run standard code from within a dialog.

I'm not sure what you're trying to achieve, so I can't give you an example.

monkey0506

#3
Quote from: Kivrin on Thu 23/08/2007 06:40:18Since there doesn't seem to be a way to test a conditional within a conversation

Quote from: KhrisMUC on Thu 23/08/2007 10:11:53Use the dialog_request function to run standard code from within a dialog.

Code: ags
// dialog script
run-script 1


Code: ags
// global script
function dialog_request(int script) {
  if (script == 1) {
    if (CONDITIONAL) {
      // do stuff here
      // maybe something like:
      // player.LockView(EGO_LAUGH);
      // player.Animate(player.Loop, player.AnimationSpeed, eOnce, eBlock);
      // player.UnlockView();
      }
    }
  else if (script == 2) {
    if (OTHER_CONDITIONAL) {
      // do other stuff here
      }
    }
  }


Simply call run-script X within your dialog script (X must be a valid integer ;)), then run a test within your dialog_request function (which you may have to set up within the global script yourself; it may not exist) such as if (script == X) (where X is the integer you used with run-script). Include your scripts that you require to run, and you're set!

Edit (after Khris): I didn't remember if that created the function or not. Thanks. 8)

Khris

And btw, selecting "dialog_script" from the Script menu will add the function (if it doesn't exist already) and open the global script there.

Kivrin

I'm trying to make a conversation that cycles through a number of problems automatically until they're all solved.  I had it set up in a while loop in the room script like this:

while(!all_solved) {
    if(!p1_solved)
        dialog[1].Start();  (p1_solved set during the dialog)
    if(!p2_solved)
        dialog[2].Start();
  ...
    all_solved = p1_solved && p2_solved && ...
}

This is what gave me the "post-script queue full" error.  I've been trying to figure out how to move the dialog calls to the dialog_request function - I tried to make a parent dialog which would call the child dialogs through run-script x and just calling dialog[ x ].start() within the dialog_request, but when I end a child dialog the parent ends too.  Is there a way to call a specific topic within the dialog_request function?  I might be able to condense everything into one dialog structure and just switch between topics.

monkey0506

#6
The way I understand it, none of the dialog[ x ].Start() commands would be getting run from within the while loop, correct? They would all be waiting for the function to end, which means the while loop has to end which means that all the problems have to be solved which means that all the dialogs have to be run which are all waiting for the function to end....and you've created an infinite loop.

You would also be adding every dialog to the post-script queue...since the Dialog.Start command is delayed then you would be calling dialog[2].Start(), dialog[3].Start(), ..., and dialog[n].Start() every loop. You could presumably work around this part by simply changing the "if (!pX_solved)" lines (where X != 1) to "else if (!pX_solved)"...of course the dialog would still never start and you'd still be stuck in the infinite loop.

Regarding the parent/child setup are you calling StopDialog() from within dialog_request to end the child dialog? If so this explains why it ends the parent dialog also. Try putting "goto-previous" in the dialog script instead of calling StopDialog(). That will make it return to the parent dialog.

Khris

To return from a child dialog, use "goto-previous".

I'd do it like this:
Code: ags
// script header

#define DIALOGS 5
import int p_solved[DIALOGS];
import int dialog_to_run;

// global script

int p_solved[DIALOGS];
int dialog_to_run=DIALOGS+1;
export p_solved, dialog_to_run;

function p_check() {
  int i;
  dialog_to_run=DIALOGS;
  while (i<DIALOGS) {
    if (!p_solved[i]) {
      dialog_to_run=i;
      i=DIALOGS;
    }
    i++;
  }
}

function dialog_script(int p) {
  if (p>0 && p<=DIALOGS) {
    p_solved[p-1]=true;
    p_check();
  }
}

// room script 

// interaction:
  p_check();

// room's repeatedly_execute
  if (dialog_to_run<DIALOGS) dialog[dialog_to_run+1].Start();
  else if (dialog_to_run==DIALOGS) {
    dialog_to_run=DIALOGS+1;
    Display("You have won!");
  }


In dialog 1, call "run-script 1" if it has been solved.

To explain how this works:
p_check sets the variable dialog_to_run to the next unsolved dialog.
This makes the room's repeatedly_execute run this dialog.
If it has been solved, dialog_request sets the dialogs variable to true, then calls p_check().
If all dialogs have been solved, dialog_to_run is set to DIALOGS; in this case the room's repeatedly_execute displays a message and ends the loop by setting the variable to DIALOGS+1 (its initial value).

Kivrin

Ah, I see now - the functions in the room script run to their own completion, so any loops that depend on calling other scripts should be moved to repeatedly_execute.

Thank you very much!

SMF spam blocked by CleanTalk