Starting a dialogue option from the script.

Started by Ali, Mon 24/01/2011 12:59:23

Previous topic - Next topic

Ali

Hello,

I am working on my custom dialogue module, which previously did not use AGS's dialog scripts to allow for a custom speech functon. I now want to be able to use the built-in scripts to make things like translation / voices easier to add at a later date.

My problem is that there doesn't seem to be a function for running a dialogue option (the equivalent of clicking on it) in the script. Is there anything you can suggest?

Alternatively, is there a way of getting AGS to wait before drawing the custom dialogue window to allow me to fade in a backdrop and stop allow the smooth scrolling to stop? Because the built in custom dialogue system runs on the non-blocking thread I can't make this work.

Wersus

Quote from: Ali on Mon 24/01/2011 12:59:23
...a function for running a dialogue option...
Sorry, no help from here, but I would also be interested in this.

Yeppoh

I had an equivalent issue with running a dialog option, when I did my own custom dialog options window prior to version 3.1. My solution, I used a GUI with a list containing the dialog options and I returned the index of the list added to the dialog ID multiplied by 1000. Then I called a custom dialog function with this resulted value, and run the dialog.
The drawback of this, I have all dialogs of the game in one single function (which is functional, but not the best).

There was this idea where, when the dialog is run, I would first create a buffer array containing all option states. Then I would switch off all options of the dialog, but the one I want to run. Normally if there is only one option active, AGS should run it automatically by default. After the dialog is finished, I would set all options back to their former state using the array (and maybe set the activated option, to its new state at the end).
But I didn't test this idea and don't know if it would work.

Ali

I'm in exactly the position you describe Nefasto! I had also considered your workaround, but throught it worth looking for something less hack-ish.


Quote from: Ali on Mon 24/01/2011 12:59:23
Alternatively, is there a way of getting AGS to wait before drawing the custom dialogue window to allow me to fade in a backdrop and stop allow the smooth scrolling to stop? Because the built in custom dialogue system runs on the non-blocking thread I can't make this work.

I have found a way of doing this, by putting starting the dialogue from within a custom function which sets everything else up.

Yeppoh

There's also the Dialog.HasOptionBeenChosen(int option) function, but I don't have an idea if it can be of any use in this case.

Ali

#5
Unfortunately that changes only the first time on option is chosen, but thanks for the suggestion

EDIT: I thought I could get this to work by drawing the dialogue options above a GUI (for nice alpha-channel edges). Unfortunately, I still need to know that an option has been clicked (irrespective of which one) in order to make the GUI disappear when the dialogue begins.

Any ideas how I can detect that click?

Wersus

I don't think there's a clean solution for that. One thing you could do is make a variable for it and check it in repeatedly_execute_always().

Ali

That's what I've done. I now have it working at the expense of the dialogue options fading in and out nicely, but there's nothing I can do about that!

I'm not going to add 'solved' to the thread, because it isn't really solved. Thanks for helping me find a workaround guys.

monkey0506

#8
You could try doing something like:

Code: ags
Dialog *lastProcessedDialog;
DialogOptionState processedDialogOptionStates[];
bool showSingleDialogOption;

void RestoreProcessedDialog()
{
  if (lastProcessedDialog == null) return; // nothing to restore..
  int i = 0;
  while (i < lastProcessedDialog.OptionCount)
  {
    if (processedDialogOptionStates[i] == eOptionOn) lastProcessedDialog.SetOptionState(i + 1, eOptionOn);
    i++;
  }
  processedDialogOptionStates = null;
  lastProcessedDialog = null;
  game.show_single_dialog_option = showSingleDialogOption;
}

void ProcessOptionClick(this Dialog*, int option)
{
  if ((option <= 0) || (option > this.OptionCount)) return; // ..do some error handling here?
  if (this.GetOptionState(option) == eOptionOffForever) return; // ..more error handling perhaps?
  if (lastProcessedDialog != null) RestoreProcessedDialog();
  processedDialogOptionStates = new DialogOptionState[this.OptionCount];
  int i = 0;
  while (i < this.OptionCount)
  {
    processedDialogOptionStates[i] = this.GetOptionState(i + 1);
    if ((i + 1) == option) this.SetOptionState(i + 1, eOptionOn);
    else if (this.GetOptionState(i + 1) == eOptionOn) this.SetOptionState(i + 1, eOptionOff);
    i++;
  }
  showSingleDialogOption = game.show_single_dialog_option;
  game.show_single_dialog_option = 0;
  lastProcessedDialog = this;
  this.Start(); // keep in mind this is a delayed function..so inherently ProcessOptionClick would be too..
}

function repeatedly_execute()
{
  if (lastProcessedDialog != null) RestoreProcessedDialog(); // this shouldn't run until the next game loop after the simulated click..I think..
}


I haven't tested this, but it seems like it might work, maybe. Also I'd like to move the RestoreProcessedDialog function to above the ProcessOptionClick function to make sure it doesn't overwrite any option states without restoring the temporary ones first..but I'm typing this on a phone that isn't wanting to let me cut and paste right now.

One last thing to keep in mind is that if this does actually work, since it's reliant on Dialog.Start, it will be a delayed function. When I'm home tonight I'll test this, and if it works add a function to let you know when the processing of the simulated click is done.

Edit: I updated the code to correct some issues (the one mentioned above, options are now referenced from 1 as they should be instead of 0, etc.). The function appears to be working, with some peculiarities. Because of the delayed execution of Dialog.Start, this function is, as I said, also delayed. If you call this function more than once in the same game loop, the result is then that the last processed option is called once for each call to this function in that loop.

Depending on your usage, this might be sufficient for you. Because I think it's a good idea, I'll continue thinking what else I can do to work around the current delayed processing peculiarities.. ;)

Oh, also, I never provided an example of usage..basically I'd put this code into a separate script and import the ProcessOptionClick function:

Code: ags
// Script.ash

import void ProcessOptionClick(this Dialog*, int option);


Then you can simulate clicks on dialog options by calling the function, such as:

Code: ags
dMerchant.ProcessOptionClick(4);

SMF spam blocked by CleanTalk