Skip to content

Commit 135bd7b

Browse files
committed
Script API: add Dialog.CurrentDialog, ExecutedOption, AreOptionsDisplayed
1 parent 853cd16 commit 135bd7b

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

Editor/AGS.Editor/Resources/agsdefns.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,14 @@ builtin managed struct Dialog {
21932193
/// Gets the script name of this dialog.
21942194
import readonly attribute String ScriptName;
21952195
#endif
2196+
#ifdef SCRIPT_API_v362
2197+
/// Gets the currently running dialog, returns null if no dialog is run
2198+
import static readonly attribute Dialog* CurrentDialog; // $AUTOCOMPLETESTATICONLY$
2199+
/// Gets the currently executed dialog option, or -1 if none is
2200+
import static readonly attribute int ExecutedOption; // $AUTOCOMPLETESTATICONLY$
2201+
/// Gets if the dialog options are currently displayed on screen
2202+
import static readonly attribute bool AreOptionsDisplayed; // $AUTOCOMPLETESTATICONLY$
2203+
#endif
21962204
21972205
int reserved[2]; // $AUTOCOMPLETEIGNORE$
21982206
};

Engine/ac/dialog.cpp

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454

5555
using namespace AGS::Common;
5656
using namespace AGS::Engine;
57+
struct DialogExec;
5758

5859
extern GameSetupStruct game;
5960
extern int in_new_room;
@@ -66,6 +67,7 @@ extern IGraphicsDriver *gfxDriver;
6667
std::vector<DialogTopic> dialog;
6768
ScriptDialogOptionsRendering ccDialogOptionsRendering;
6869
ScriptDrawingSurface* dialogOptionsRenderingSurface;
70+
std::unique_ptr<DialogExec> dialogExec; // current running dialog
6971

7072
int said_speech_line; // used while in dialog to track whether screen needs updating
7173

@@ -119,7 +121,7 @@ int Dialog_HasOptionBeenChosen(ScriptDialog *sd, int option)
119121
{
120122
if ((option < 1) || (option > dialog[sd->id].numoptions))
121123
quit("!Dialog.HasOptionBeenChosen: Invalid option number specified");
122-
option--;
124+
option--; // option id is 1-based in script, and 0 is entry point
123125

124126
if (dialog[sd->id].optionflags[option] & DFLG_HASBEENCHOSEN)
125127
return 1;
@@ -132,7 +134,7 @@ void Dialog_SetHasOptionBeenChosen(ScriptDialog *sd, int option, bool chosen)
132134
{
133135
quit("!Dialog.HasOptionBeenChosen: Invalid option number specified");
134136
}
135-
option--;
137+
option--; // option id is 1-based in script, and 0 is entry point
136138
if (chosen)
137139
{
138140
dialog[sd->id].optionflags[option] |= DFLG_HASBEENCHOSEN;
@@ -158,7 +160,7 @@ const char* Dialog_GetOptionText(ScriptDialog *sd, int option)
158160
if ((option < 1) || (option > dialog[sd->id].numoptions))
159161
quit("!Dialog.GetOptionText: Invalid option number specified");
160162

161-
option--;
163+
option--; // option id is 1-based in script, and 0 is entry point
162164

163165
return CreateNewScriptString(get_translation(dialog[sd->id].optionnames[option]));
164166
}
@@ -1283,6 +1285,7 @@ int show_dialog_options(int dlgnum, bool runGameLoopsInBackground)
12831285
}
12841286

12851287
// Dialog execution state
1288+
// TODO: reform into GameState implementation, similar to DialogOptions!
12861289
struct DialogExec
12871290
{
12881291
int DlgNum = -1;
@@ -1291,6 +1294,8 @@ struct DialogExec
12911294
bool IsFirstEntry = true;
12921295
// nested dialogs "stack"
12931296
std::stack<int> TopicHist;
1297+
int ExecutedOption = -1; // option which is currently run (or -1)
1298+
bool AreOptionsDisplayed = false; // if dialog options are displayed on screen
12941299

12951300
DialogExec(int start_dlgnum) : DlgNum(start_dlgnum) {}
12961301
int HandleDialogResult(int res);
@@ -1331,8 +1336,10 @@ void DialogExec::Run()
13311336
// If a new dialog topic: run dialog entry point
13321337
if (DlgNum != DlgWas)
13331338
{
1339+
ExecutedOption = 0;
13341340
res = run_dialog_entry(DlgNum);
13351341
DlgWas = DlgNum;
1342+
ExecutedOption = -1;
13361343

13371344
// Handle the dialog entry's result
13381345
res = HandleDialogResult(res);
@@ -1344,7 +1351,9 @@ void DialogExec::Run()
13441351
}
13451352

13461353
// Show current dialog's options
1354+
AreOptionsDisplayed = true;
13471355
int chose = show_dialog_options(DlgNum, (game.options[OPT_RUNGAMEDLGOPTS] != 0));
1356+
AreOptionsDisplayed = false;
13481357

13491358
if (chose == CHOSE_TEXTPARSER)
13501359
{
@@ -1361,8 +1370,10 @@ void DialogExec::Run()
13611370
}
13621371
else if (chose >= 0)
13631372
{
1373+
ExecutedOption = chose + 1; // option id is 1-based in script, and 0 is entry point
13641374
// chose some option - handle it and run its script
13651375
res = run_dialog_option(DlgNum, chose, SAYCHOSEN_USEFLAG, true /* run script */);
1376+
ExecutedOption = -1;
13661377
}
13671378
else
13681379
{
@@ -1388,18 +1399,19 @@ void do_conversation(int dlgnum)
13881399
// Run the global DialogStart event
13891400
run_on_event(kScriptEvent_DialogStart, RuntimeScriptValue().SetInt32(dlgnum));
13901401

1391-
DialogExec dlgexec(dlgnum);
1392-
dlgexec.Run();
1402+
dialogExec.reset(new DialogExec(dlgnum));
1403+
dialogExec->Run();
13931404
// CHECKME: find out if this is safe to do always, regardless of number of iterations
1394-
if (dlgexec.IsFirstEntry)
1405+
if (dialogExec->IsFirstEntry)
13951406
{
13961407
// bail out from first startup script
13971408
remove_screen_overlay(OVER_COMPLETE);
13981409
play.in_conversation--;
13991410
}
14001411

14011412
// Run the global DialogStop event; NOTE: DlgNum may be different in the end
1402-
run_on_event(kScriptEvent_DialogStop, RuntimeScriptValue().SetInt32(dlgexec.DlgNum));
1413+
run_on_event(kScriptEvent_DialogStop, RuntimeScriptValue().SetInt32(dialogExec->DlgNum));
1414+
dialogExec = {};
14031415
}
14041416

14051417
// end dialog manager
@@ -1424,12 +1436,41 @@ ScriptDialog *Dialog_GetByName(const char *name)
14241436
return static_cast<ScriptDialog*>(ccGetScriptObjectAddress(name, ccDynamicDialog.GetType()));
14251437
}
14261438

1439+
ScriptDialog *Dialog_GetCurrentDialog()
1440+
{
1441+
return dialogExec ? &scrDialog[dialogExec->DlgNum] : nullptr;
1442+
}
1443+
1444+
int Dialog_GetExecutedOption()
1445+
{
1446+
return dialogExec ? dialogExec->ExecutedOption : -1;
1447+
}
1448+
1449+
bool Dialog_GetAreOptionsDisplayed()
1450+
{
1451+
return dialogExec ? dialogExec->AreOptionsDisplayed : false;
1452+
}
14271453

14281454
RuntimeScriptValue Sc_Dialog_GetByName(const RuntimeScriptValue *params, int32_t param_count)
14291455
{
14301456
API_SCALL_OBJ_POBJ(ScriptDialog, ccDynamicDialog, Dialog_GetByName, const char);
14311457
}
14321458

1459+
RuntimeScriptValue Sc_Dialog_GetCurrentDialog(const RuntimeScriptValue *params, int32_t param_count)
1460+
{
1461+
API_SCALL_OBJ(ScriptDialog, ccDynamicDialog, Dialog_GetCurrentDialog);
1462+
}
1463+
1464+
RuntimeScriptValue Sc_Dialog_GetExecutedOption(const RuntimeScriptValue *params, int32_t param_count)
1465+
{
1466+
API_SCALL_INT(Dialog_GetExecutedOption);
1467+
}
1468+
1469+
RuntimeScriptValue Sc_Dialog_GetAreOptionsDisplayed(const RuntimeScriptValue *params, int32_t param_count)
1470+
{
1471+
API_SCALL_BOOL(Dialog_GetAreOptionsDisplayed);
1472+
}
1473+
14331474
// int (ScriptDialog *sd)
14341475
RuntimeScriptValue Sc_Dialog_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count)
14351476
{
@@ -1498,6 +1539,9 @@ void RegisterDialogAPI()
14981539
{
14991540
ScFnRegister dialog_api[] = {
15001541
{ "Dialog::GetByName", API_FN_PAIR(Dialog_GetByName) },
1542+
{ "Dialog::get_CurrentDialog", API_FN_PAIR(Dialog_GetCurrentDialog) },
1543+
{ "Dialog::get_ExecutedOption", API_FN_PAIR(Dialog_GetExecutedOption) },
1544+
{ "Dialog::get_AreOptionsDisplayed", API_FN_PAIR(Dialog_GetAreOptionsDisplayed) },
15011545
{ "Dialog::get_ID", API_FN_PAIR(Dialog_GetID) },
15021546
{ "Dialog::get_OptionCount", API_FN_PAIR(Dialog_GetOptionCount) },
15031547
{ "Dialog::get_ScriptName", API_FN_PAIR(Dialog_GetScriptName) },

0 commit comments

Comments
 (0)