From 1406c6eeef657cb4ae28efa8184a2551c1513678 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sun, 24 Aug 2025 20:51:55 -0500 Subject: [PATCH] allow preview story dialog in editor --- src/dialogxml/dialogs/dialog.cpp | 25 +++++++++++++++++++++++++ src/dialogxml/dialogs/dialog.hpp | 4 ++++ src/game/boe.items.cpp | 24 ------------------------ src/game/boe.items.hpp | 1 - src/game/boe.specials.cpp | 2 +- src/scenario/special-general.cpp | 4 +--- src/scenedit/scen.keydlgs.cpp | 9 +++++++++ 7 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/dialogxml/dialogs/dialog.cpp b/src/dialogxml/dialogs/dialog.cpp index a826307a..fe53c3e2 100644 --- a/src/dialogxml/dialogs/dialog.cpp +++ b/src/dialogxml/dialogs/dialog.cpp @@ -36,6 +36,7 @@ #include "replay.hpp" #include #include "scenario/scenario.hpp" +#include "universe/universe.hpp" using namespace std; using namespace ticpp; @@ -1314,3 +1315,27 @@ void setup_dialog_pict_anim(cDialog& dialog, std::string pict_id, short anim_loo dialog.setAnimPictFPS(anim_fps); dialog.setDoAnimations(true); } + +void story_dialog(cUniverse& univ, std::string title, str_num_t first, str_num_t last, eSpecCtxType which_str_type, pic_num_t pic, ePicType pt, short anim_loops, int anim_fps) { + cDialog story_dlg(*ResMgr::dialogs.get("many-str")); + dynamic_cast(story_dlg["pict"]).setPict(pic, pt); + setup_dialog_pict_anim(story_dlg, "pict", anim_loops, anim_fps); + str_num_t cur = first; + story_dlg.attachClickHandlers([&cur,&univ,first,last,which_str_type](cDialog& me, std::string clicked, eKeyMod) -> bool { + if(clicked == "left") { + if(cur > first) cur--; + } else if(clicked == "done" || cur == last) { + me.toast(false); + return true; + } else if(clicked == "right") { + cur++; + } + std::string text; + univ.get_str(text, which_str_type, cur); + me["str"].setText(text); + return true; + }, {"left", "right", "done"}); + story_dlg["left"].triggerClickHandler(story_dlg, "left", eKeyMod()); + story_dlg["title"].setText(title); + story_dlg.run(); +} diff --git a/src/dialogxml/dialogs/dialog.hpp b/src/dialogxml/dialogs/dialog.hpp index 95380ab3..69e739f6 100644 --- a/src/dialogxml/dialogs/dialog.hpp +++ b/src/dialogxml/dialogs/dialog.hpp @@ -31,11 +31,13 @@ #include #include "tools/prefs.hpp" #include "tools/framerate_limiter.hpp" +#include "special.hpp" class cControl; class cContainer; class cTextField; struct DialogDefn; +class cUniverse; /// Specifies the relative position of a control's labelling text. enum eLabelPos { @@ -393,6 +395,8 @@ public: void setup_dialog_pict_anim(cDialog& dialog, std::string pict_id, short anim_loops, short anim_fps); +void story_dialog(cUniverse& univ, std::string title, str_num_t first, str_num_t last, eSpecCtxType which_str_type, pic_num_t pic, ePicType pt, short anim_loops, int anim_fps); + // For development/debugging only. void preview_dialog_xml(fs::path dialog_xml); diff --git a/src/game/boe.items.cpp b/src/game/boe.items.cpp index 3826f96a..efe2bd66 100644 --- a/src/game/boe.items.cpp +++ b/src/game/boe.items.cpp @@ -631,30 +631,6 @@ void custom_pic_dialog(std::string title, pic_num_t bigpic) { pic_dlg.run(); } -void story_dialog(std::string title, str_num_t first, str_num_t last, eSpecCtxType which_str_type, pic_num_t pic, ePicType pt, short anim_loops, int anim_fps) { - cDialog story_dlg(*ResMgr::dialogs.get("many-str")); - dynamic_cast(story_dlg["pict"]).setPict(pic, pt); - setup_dialog_pict_anim(story_dlg, "pict", anim_loops, anim_fps); - str_num_t cur = first; - story_dlg.attachClickHandlers([&cur,first,last,which_str_type](cDialog& me, std::string clicked, eKeyMod) -> bool { - if(clicked == "left") { - if(cur > first) cur--; - } else if(clicked == "done" || cur == last) { - me.toast(false); - return true; - } else if(clicked == "right") { - cur++; - } - std::string text; - univ.get_str(text, which_str_type, cur); - me["str"].setText(text); - return true; - }, {"left", "right", "done"}); - story_dlg["left"].triggerClickHandler(story_dlg, "left", eKeyMod()); - story_dlg["title"].setText(title); - story_dlg.run(); -} - static bool get_num_of_items_event_filter(cDialog& me, std::string item_hit, eKeyMod) { if(item_hit == "cancel"){ me.setResult(0); diff --git a/src/game/boe.items.hpp b/src/game/boe.items.hpp index 6a727512..796a80fc 100644 --- a/src/game/boe.items.hpp +++ b/src/game/boe.items.hpp @@ -25,7 +25,6 @@ void set_town_attitude(short lo,short hi,eAttitude att); bool show_get_items(std::string titleText, std::vector& itemRefs, short pc_getting, bool overload = false); bool display_item(location from_loc,short pc_num,short mode, bool check_container); void custom_pic_dialog(std::string title, pic_num_t bigpic); -void story_dialog(std::string title, str_num_t first, str_num_t last, eSpecCtxType which_str_type, pic_num_t pic, ePicType pt, short anim_loops, int anim_fps); short get_num_of_items(short max_num); void init_mini_map(); void draw_help_dialog_item_buttons(cDialog& dialog,short item); diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index 2041a28b..2e36a1ec 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -2464,7 +2464,7 @@ void general_spec(const runtime_state& ctx) { break; case eSpecType::STORY_DIALOG: univ.get_str(str1,ctx.cur_spec_type,spec.m1); - story_dialog(str1, spec.m2, spec.m3, ctx.cur_spec_type, spec.pic, ePicType(spec.pictype), spec.ex1c, spec.ex2c); + story_dialog(univ, str1, spec.m2, spec.m3, ctx.cur_spec_type, spec.pic, ePicType(spec.pictype), spec.ex1c, spec.ex2c); break; case eSpecType::CLEAR_BUF: univ.get_buf().clear(); diff --git a/src/scenario/special-general.cpp b/src/scenario/special-general.cpp index b8c7cf03..968cd7fb 100644 --- a/src/scenario/special-general.cpp +++ b/src/scenario/special-general.cpp @@ -47,12 +47,10 @@ namespace{ .sdf(eSpecField::EX1A, eSpecField::EX1B) .sdf(eSpecField::EX2A, eSpecField::EX2B) .msg(); - // TODO implement preview node_properties_t S_STORY = node_builder_t(eSpecType::STORY_DIALOG) .msg1(eSpecPicker::MSG_SINGLE) .field_pair(eSpecField::MSG2, eSpecField::MSG3, eSpecPicker::MSG_SEQUENCE_VAR) - .pic() - .no_preview(); + .pic(); node_properties_t S_PREVENT = node_builder_t(eSpecType::CANT_ENTER) .msg() .ex1a(eSpecPicker::TOGGLE) diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index 37da1f11..f6c86946 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -870,6 +870,15 @@ static bool preview_spec_enc_dlog(cDialog& me, std::string, cSpecial& special, s pic_num_t pic = scenario.intro_pic; switch(special.type){ + case eSpecType::STORY_DIALOG:{ + std::string str1; + univ.get_str(str1,cur_type,special.m1); + // Use dark background that the game uses: + short defaultBackground = cDialog::defaultBackground; + cDialog::defaultBackground = cDialog::BG_DARK; + story_dialog(univ, str1, special.m2, special.m3, cur_type, special.pic, ePicType(special.pictype), special.ex1c, special.ex2c); + cDialog::defaultBackground = defaultBackground; + }break; case eSpecType::ONCE_DIALOG: once_dialog(univ, special, cur_type, &me); break;