-
Notifications
You must be signed in to change notification settings - Fork 9
CustomDialogOptions
By default, AGS comes with two types of dialog options -- displaying them using the size and position of an existing GUI, or creating a text window to display the options in.
As of AGS 3.1 and above, if neither of these methods suit you (for example, because you want to use picture-based dialog options, or you want to add scroll arrows), you can now implement the dialog options display yourself in the script.
NOTE: This topic involves some advanced scripting. If you're just starting out with AGS, please just use one of the built-in dialog option styles for now, and come back to this later when you're comfortable with scripting.
To write your custom dialog options code, you need to add a number of even handlers in your script, taken from the list below. Two of them must be present (dialog_options_get_dimensions
and dialog_options_render
), but others are optional, so use only those that match your game needs. These function would work somewhat similar to the common event handlers, except they are only run whenever the dialog options are on screen.
All of these functions accept DialogOptionsRenderingInfo
object as a first argument. This object may be used to get and set various properties, including accessing current Dialog object.
NOTE: These functions don't have to go in the global script; you can put them in any script you like. However, beware that if the functions are present in more than one script they could interfere with each other and cause problems.
COMPATIBILITY NOTE: The older versions of AGS (pre-3.4.0) were working with somewhat different set of functions. There was no dialog_options_repexec
and dialog_options_key_press
, but you had to add dialog_options_get_active
function instead in which you'd set an active dialog option (or none) on each game update, for example, depending on the cursor position. Mouse clicks were processed by the engine, and if an active option was set in dialog_options_get_active
then it was run automatically.
There is a compatibility switch in the General Settings called "Use old-style dialog options rendering API" that toggles between the old and new behavior. If you have imported older project and want to keep old dialog option scripts, then make sure it's enabled. If you wish to update your game to the new behavior, then turn it off.
IMPORTANT: All of the Custom Dialog functions run on the non-blocking thread. That means that you should not make any blocking calls, such as Character.Say, Wait or Display within them, as they may not behave correctly.
dialog_options_get_dimensions(DialogOptionsRenderingInfo *info)
This is the first function that will be called before dialog options are shown. It is meant to find out which part of the screen you will be drawing onto. Do that by setting the X, Y, Width and Height properties of the info
struct. Only when the width and height are greater than 0 will the custom dialog system be activated.
NOTE: you may also use this function to set other things up, not only DialogOptionsRenderingInfo
.
dialog_options_render(DialogOptionsRenderingInfo *info)
This function is called right before the dialog options are shown or updated on screen. The info
struct will supply a DrawingSurface
which may be accessed using info.Surface
property, and which you may draw upon.
dialog_options_mouse_click(DialogOptionsRenderingInfo *info, MouseButton button)
This function is called if the player clicks the mouse anywhere on dialog options. It corresponds to the regular on_mouse_click
. You might want to use this to process clicks on dialog options, and also on some custom elements like scroll arrows, for example.
dialog_options_key_press(DialogOptionsRenderingInfo *info, eKeyCode keycode, int mod)
This function is called if the player presses any key while custom dialog options are shown on screen. It corresponds to the regular on_key_press
, and you can use this to implement key-controlled selection of dialog option, for example.
Compatibility: the optional mod
argument is supported since AGS 3.6.0. Please refer to the on_key_press
description for details.
dialog_options_text_input(DialogOptionsRenderingInfo *info, int ch)
This function is called if the player's key presses form a printable character. It corresponds to the regular on_text_input
, and you can use this to handle a custom text input in your dialog options.
Compatibility: Supported by AGS 3.6.0 and above. dialog_options_text_input
will only work if you have "Use old-style key handling" option disabled in the "General Settings".
dialog_options_repexec(DialogOptionsRenderingInfo *info)
This function works similar to a general repeatedly_execute
function, but is called only while the dialog options are shown on the screen. You may use this to update the dialog options state, for example, for determining which option the mouse is currently hovering over, or scripting timed actions.
dialog_options_close(DialogOptionsRenderingInfo *info)
This function will be called right before the dialog options are removed from the screen. This is a place to perform a "cleanup" in case you need to dispose temporary resources (like dynamic sprites), hide GUIs, stop sounds, and so forth.
NOTE: this is not the same as the end of the current dialog. Dialog options may be shown and hidden multiple times during the dialog, every time the game lets player to choose a dialog option.
Compatibility: Supported by AGS 3.6.0 and above.
dialog_options_get_active(DialogOptionsRenderingInfo *info)
Compatibility: dialog_options_get_active
is a deprecated function that works only if you have "Use old-style dialog options rendering API" enabled in General Settings. In a modern script use dialog_options_repexec
instead.
This function is called as the player moves the mouse around the screen. This needs to work out which option the mouse is currently hovering over, so that AGS knows which option to process if the player clicks the mouse button. Use it to set info.ActiveOptionID
property, or do any other changes.
int dlg_opt_color = 14;
int dlg_opt_acolor = 13;
int dlg_opt_ncolor = 4;
function dialog_options_get_dimensions(DialogOptionsRenderingInfo *info)
{
// Create a 200x200 dialog options area at (50,100)
info.X = 50;
info.Y = 100;
info.Width = 200;
info.Height = 200;
// Enable alpha channel for the drawing surface
info.HasAlphaChannel = true;
// Put the text parser at the bottom (if enabled)
info.ParserTextBoxX = 10;
info.ParserTextBoxY = 160;
info.ParserTextBoxWidth = 180;
}
function dialog_options_render(DialogOptionsRenderingInfo *info)
{
info.Surface.Clear(dlg_opt_color);
int ypos = 0;
// Render all the options that are enabled
for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
{
if (info.DialogToRender.GetOptionState(i) == eOptionOn)
{
if (info.ActiveOptionID == i)
info.Surface.DrawingColor = dlg_opt_acolor;
else
info.Surface.DrawingColor = dlg_opt_ncolor;
info.Surface.DrawStringWrapped(5, ypos, info.Width - 10, eFontNormal, eAlignLeft,
info.DialogToRender.GetOptionText(i));
ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontNormal, info.Width - 10);
}
}
}
function dialog_options_repexec(DialogOptionsRenderingInfo *info)
{
info.ActiveOptionID = 0;
if (mouse.y < info.Y || mouse.y >= info.Y + info.Height ||
mouse.x < info.X || mouse.x >= info.X + info.Width)
{
return; // return if the mouse is outside UI bounds
}
int ypos = 0;
// Find the option that corresponds to where the mouse cursor is
for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
{
if (info.DialogToRender.GetOptionState(i) == eOptionOn)
{
ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontNormal, info.Width - 10);
if ((mouse.y - info.Y) < ypos)
{
info.ActiveOptionID = i;
return;
}
}
}
}
function dialog_options_mouse_click(DialogOptionsRenderingInfo *info, MouseButton button)
{
if (info.ActiveOptionID > 0)
info.RunActiveOption();
}
The examples above are slightly naive; in reality you would probably want to track the Y position of each option in a variable to save having to continually scan through all the options.
int dlg_opt_color = 14;
int dlg_opt_acolor = 13;
int dlg_opt_ncolor = 4;
function dialog_options_get_dimensions(DialogOptionsRenderingInfo *info)
{
// Create a 200x200 dialog options area at (50,100)
info.X = 50;
info.Y = 100;
info.Width = 200;
info.Height = 200;
info.ActiveOptionID = 1; // set to first option
}
function dialog_options_render(DialogOptionsRenderingInfo *info)
{
info.Surface.Clear(dlg_opt_color);
int ypos = 0;
// Render all the options that are enabled
for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
{
if (info.DialogToRender.GetOptionState(i) == eOptionOn)
{
if (info.ActiveOptionID == i)
info.Surface.DrawingColor = dlg_opt_acolor;
else
info.Surface.DrawingColor = dlg_opt_ncolor;
info.Surface.DrawStringWrapped(5, ypos, info.Width - 10, eFontNormal, eAlignLeft,
info.DialogToRender.GetOptionText(i));
ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontNormal, info.Width - 10);
}
}
}
function dialog_options_key_press(DialogOptionsRenderingInfo *info, eKeyCode keycode, int mod)
{
if (keycode == eKeyUpArrow)
{
// check all options upwards until found an active one
for (int next_opt = info.ActiveOptionID - 1; next_opt >= 1; next_opt--)
{
if (info.DialogToRender.GetOptionState(next_opt) == eOptionOn)
{
info.ActiveOptionID = next_opt;
break;
}
}
}
else if (keycode == eKeyDownArrow)
{
// check all options downwards until found an active one
for (int next_opt = info.ActiveOptionID + 1; next_opt <= info.DialogToRender.OptionCount; next_opt++)
{
if (info.DialogToRender.GetOptionState(next_opt) == eOptionOn)
{
info.ActiveOptionID = next_opt;
break;
}
}
}
else if (keycode == eKeyReturn || keycode == eKeySpace)
{
info.RunActiveOption();
}
}
Getting Started in AGS
Editor
- New Game templates
- Editor Preferences
- General Settings
- Default Setup
- Colours Editor
- Room Editor
- Character Editor
- Cursor Editor
- Dialog Editor
- Font Preview
- GUI Editor
- Inventory Items Editor
- View Editor
- Sprite Manager
- Music and sound
- Voice speech
- Script Modules
- System limits
- Log Panel
- Plugins
- Other Features
Engine
Scripting
- Scripting Tutorial
- Scripting Language
-
Scripting API
- Script API Overview
- Standard Constants
- Standard Enumerated Types
- Standard Types
- Game variables
- Global arrays
- Global event handlers
- repeatedly_execute / repeatedly_execute_always
- Custom dialog options rendering
- Global functions: general
- Global functions: message display
- Global functions: multimedia actions
- Global functions: palette operations
- Global functions: room actions
- Global functions: screen effects
- Global functions: wait
- AudioChannel functions and properties
- AudioClip functions and properties
- Camera functions and properties
- Character functions and properties
- DateTime functions and properties
- Dialog functions and properties
- DialogOptionsRenderingInfo functions and properties
- Dictionary functions and properties
- DrawingSurface functions and properties
- DynamicSprite functions and properties
- File functions and properties
- Game functions and properties
- GUI functions and properties
- GUI control functions and properties
- GUI Button functions and properties
- GUI InvWindow functions and properties
- GUI Label functions and properties
- GUI List Box functions and properties
- GUI Slider properties
- GUI Text Box functions and properties
- Hotspot functions and properties
- Inventory item functions and properties
- Maths functions and properties
- Mouse functions and properties
- Object functions and properties
- Overlay functions and properties
- Parser functions
- Region functions and properties
- Room functions and properties
- Screen functions and properties
- Set functions and properties
- Speech functions and properties
- String functions
- System functions and properties
- TextWindowGUI functions and properties
- ViewFrame functions and properties
- Viewport functions and properties
- Obsolete Script API
- Event Types
- Key code table
- Audio in script
Legal Notice
Getting in touch
Misc