5454
5555using namespace AGS ::Common;
5656using namespace AGS ::Engine;
57+ struct DialogExec ;
5758
5859extern GameSetupStruct game;
5960extern int in_new_room;
@@ -66,6 +67,7 @@ extern IGraphicsDriver *gfxDriver;
6667std::vector<DialogTopic> dialog;
6768ScriptDialogOptionsRendering ccDialogOptionsRendering;
6869ScriptDrawingSurface* dialogOptionsRenderingSurface;
70+ std::unique_ptr<DialogExec> dialogExec; // current running dialog
6971
7072int 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!
12861289struct 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
14281454RuntimeScriptValue 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)
14341475RuntimeScriptValue 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