I have my character speech set up to display on a GUI with a button. Using btn.Animate() I can show a view loop of a talking head alongside the characters text. I would like a similar display for when dialog options are presented. My dialog options are set to display on a drawing surface using the technique in the wiki (http://www.adventuregamestudio.co.uk/wiki/Custom_dialog_options_rendering).
Since dialog_options_render() uses a drawing surface to display it's text, I did some research into drawing surfaces. So far I have found no clear way to create a looping display of sprites. From my understanding, I would be using info.Surface.DrawImage() to place one frame of the talking head on the surface, then I would have to use info.Surface.Release() for it to actually display the sprite, and then redraw and re-release it again and again to create the animation effect, which would not tie in well with info.Surface, since the game releases it at a very specific time.
The second thing I tried is having a GUI with a button (as with speech), and placing g.Visible = true; btn.Animate() inside of dialog_options_get_dimensions(). That miraculously worked to display the talking head, only now I can't make it disappear! If only there was a way to hook g.Visible = false into the mouse clicking on a dialog option. Or if I could keep track of whether the player is not on a dialog options screen and have repeatedly_execute() turn g.Visible off.
If anyone has any information on how to proceed, I would be very grateful. Perhaps I missed some information to do with drawing surfaces, or there's a simple way to detect when I leave a dialog options display. Or is there an even more obvious thing I missed from the very beginning?
Quote from: an_epileptic_monkey on Thu 15/08/2013 00:08:44From my understanding, I would be using info.Surface.DrawImage() to place one frame of the talking head on the surface, then I would have to use info.Surface.Release() for it to actually display the sprite, and then redraw and re-release it again and again to create the animation effect, which would not tie in well with info.Surface, since the game releases it at a very specific time.
Since the engine does call info.Surface.Release as part of its own drawing of the dialog options (which are updated every frame), you
wouldn't have to call Release yourself. It doesn't matter
who calls Release, so long as it's called - that's what lets the engine know it needs to update the image (and possibly draw it to the screen). Typically you would be responsible for calling Release yourself, but in this case you wouldn't have to.
Quote from: an_epileptic_monkey on Thu 15/08/2013 00:08:44The second thing I tried is having a GUI with a button (as with speech), and placing g.Visible = true; btn.Animate() inside of dialog_options_get_dimensions(). That miraculously worked to display the talking head, only now I can't make it disappear! If only there was a way to hook g.Visible = false into the mouse clicking on a dialog option. Or if I could keep track of whether the player is not on a dialog options screen and have repeatedly_execute() turn g.Visible off.
If you want the GUI to actually disappear during the interactions (e.g., when the dialog options list is removed and the characters are speaking, etc.) then you could do this:
function dialog_options_render(DialogOptionsRenderingInfo *info)
{
// ...
g.Visible = true;
}
function repeatedly_execute_always()
{
g.Visible = false;
}
Note that this will
only work if "Run game loops while dialog options are displayed" is
false. I'm still trying to think of a way of working around that, but it seems there's no way to check that setting at run-time.
Something occurred to me after reading your post and fiddling around with things for a while. Since dialog options always take you to the appropriate number in the dialog script, I could tuck a GUI visibility toggle in there.
// Dialog script file
@S // Dialog startup entry point
return
@1
g.Visible = false;
ME: It even works if you don't have dialog or use stop.
return
@2
g.Visible = false;
stop
Was that pretty obvious or what? It also seems to work if tucked away inside of a custom function Speak(), as long as I make sure to call Speak() before any return or stop in dialog.
The only issue I have now is that the dialog drawing surface is on top of the animated button, obscuring it! Example here: http://i42.tinypic.com/2cmkpk1.png Is this just a z-ordering issue I can fix or is dialog always going to cover GUI elements?
As to turning the GUI off, I thought of that, but it means you'd have to do it for every single option manually. But I suppose that it could work.
As to the dialogs being drawn on top of the GUI, I don't know that you'll be able to work around that so easily. If you did go back to manually drawing it on the dialog's drawing surface, you'd have to create the surface large enough to account for the animation, and then offset where the options are drawn at appropriately. You'd also have to keep track of the animation frame's delay manually, and update to the next frame at the appropriate time. All-in-all it shouldn't be that difficult to manage that route if that's what you want to do. Again, you wouldn't have to call Release yourself.
After considering doing all that work, I went ahead and took the shortcut: I cheated, and chopped the background image in half: http://tinypic.com/view.php?pic=210ht7d&s=5
And I stuck the other half as the background image to the talking head GUI: http://tinypic.com/view.php?pic=10pztbl&s=5
Another way to do this would have been to put the background entirely on the GUI and just make the GUI bigger (since it's going BEHIND the dialog anyways...) but a simple cut and paste job was less effort than resizing/positioning the GUI.
Everything works fine now; they match up without any divide. My issue is solved now, everything works as expected with desired results. Thanks for lending your ideas and helping me keep on track!