From 6e94d23e054583ca31a640ecb24099cc7dfe1d7a Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sun, 2 Mar 2025 19:35:41 -0500 Subject: [PATCH] Add pickers to a bunch of dialogue nodes that didn't have them. This also includes something similar to the special node button dictionary for dialogue nodes. --- rsrc/dialogs/edit-talk-node.xml | 5 +- src/scenario/special.hpp | 2 +- src/scenedit/scen.townout.cpp | 130 +++++++++++++++++++++----------- 3 files changed, 90 insertions(+), 47 deletions(-) diff --git a/rsrc/dialogs/edit-talk-node.xml b/rsrc/dialogs/edit-talk-node.xml index bff6043f..ce14f3a5 100644 --- a/rsrc/dialogs/edit-talk-node.xml +++ b/rsrc/dialogs/edit-talk-node.xml @@ -40,7 +40,8 @@ Message 1: Message 2: + + - - + diff --git a/src/scenario/special.hpp b/src/scenario/special.hpp index 571d040a..30073ccd 100644 --- a/src/scenario/special.hpp +++ b/src/scenario/special.hpp @@ -156,7 +156,7 @@ enum class eSpecPicker { FIELD, DAMAGE_TYPE, EXPLOSION, STATUS, STATUS_PARTY, SDF, LOCATION, RECTANGLE, TOGGLE, - EVENT, ITEM_CLASS, + EVENT, ITEM_CLASS, QUEST, POINTER, }; diff --git a/src/scenedit/scen.townout.cpp b/src/scenedit/scen.townout.cpp index 1cba1581..0703965c 100644 --- a/src/scenedit/scen.townout.cpp +++ b/src/scenedit/scen.townout.cpp @@ -14,6 +14,7 @@ #include "scen.townout.hpp" #include "scen.keydlgs.hpp" #include "scen.locpicker.hpp" +#include "scen.sdfpicker.hpp" #include "scen.fileio.hpp" #include "scen.core.hpp" #include "mathutil.hpp" @@ -1242,6 +1243,25 @@ static bool save_talk_node(cDialog& me, std::stack& talk_edit_stack, return true; } +// TODO: Maybe I shouldn't reuse node_function_t here? It has some irrelevant data too. +static std::map> node_map = { + {eTalkNode::DEP_ON_SDF, {eSpecPicker::SDF}}, + {eTalkNode::SET_SDF, {eSpecPicker::SDF}}, + {eTalkNode::INN, {eSpecPicker::NONE, eSpecPicker::NONE, eSpecPicker::LOCATION}}, + {eTalkNode::DEP_ON_TIME_AND_EVENT, {eSpecPicker::NONE, eSpecPicker::EVENT}}, + {eTalkNode::DEP_ON_TOWN, {STRT_TOWN}}, + {eTalkNode::SHOP, {STRT_COST_ADJ, STRT_SHOP}}, + {eTalkNode::ENCHANT, {STRT_ENCHANT}}, + {eTalkNode::BUY_SDF, {eSpecPicker::NONE, eSpecPicker::SDF}}, + {eTalkNode::BUY_SHIP, {eSpecPicker::NONE, STRT_BOAT}}, + {eTalkNode::BUY_HORSE, {eSpecPicker::NONE, STRT_HORSE}}, + {eTalkNode::BUY_SPEC_ITEM, {STRT_SPEC_ITEM}}, + {eTalkNode::RECEIVE_QUEST, {eSpecPicker::QUEST}}, + {eTalkNode::BUY_TOWN_LOC, {STRT_TOWN}}, + {eTalkNode::CALL_TOWN_SPEC, {eSpecPicker::NODE}}, + {eTalkNode::CALL_SCEN_SPEC, {+eSpecPicker::NODE}}, +}; + static void put_talk_node_in_dlog(cDialog& me, std::stack& talk_edit_stack) { cSpeech::cNode& talk_node =talk_edit_stack.top().second; @@ -1268,20 +1288,23 @@ static void put_talk_node_in_dlog(cDialog& me, std::stack& talk_edit me["str1"].setText(talk_node.str1); me["str2"].setText(talk_node.str2); - if(talk_node.type == eTalkNode::SHOP || talk_node.type == eTalkNode::DEP_ON_TIME_AND_EVENT) - me["chooseB"].show(); - else me["chooseB"].hide(); - me["chooseA-regular"].hide(); - switch(talk_node.type){ - case eTalkNode::ENCHANT: - me["chooseA-regular"].show(); - break; - case eTalkNode::CALL_TOWN_SPEC: case eTalkNode::CALL_SCEN_SPEC: case eTalkNode::RECEIVE_QUEST: - me["chooseA"].show(); - break; - default: - me["chooseA"].hide(); - break; + const auto fcns = node_map[talk_node.type]; + for(int i = 0; i < fcns.size(); i++) { + std::ostringstream sout; + sout << "choose" << char('A' + i);; + auto& btn = dynamic_cast(me[sout.str()]); + if(fcns[i].button == eSpecPicker::NONE) { + btn.hide(); + continue; + } + btn.show(); + if(fcns[i].button == eSpecPicker::NODE || fcns[i].button == eSpecPicker::QUEST) { + btn.setText("Create/Edit"); + btn.setBtnType(BTN_LG); + } else { + btn.setText("Choose"); + btn.setBtnType(BTN_REG); + } } if(talk_edit_stack.size() > 1) @@ -1337,38 +1360,57 @@ static bool select_talk_node_personality(cDialog& me, std::stack& ta static bool select_talk_node_value(cDialog& me, std::string item_hit, const std::stack& talk_edit_stack) { const auto& talk_node = talk_edit_stack.top().second; - if(item_hit == "chooseB") { - if(talk_node.type == eTalkNode::SHOP) { - int i = me["extra2"].getTextAsNum(); - i = choose_text(STRT_SHOP,i,&me,"Which shop?"); - me["extra2"].setTextToNum(i); - } else if(talk_node.type == eTalkNode::DEP_ON_TIME_AND_EVENT) { - int value = me["extra2"].getTextAsNum(); - value = choose_text_editable(scenario.evt_names, value, &me, "Select an event:"); - me["extra2"].setTextToNum(value); + int which_field = item_hit.back() - 'A'; + std::string field_id = "extra" + std::to_string(which_field + 1); + std::string second_field_id = "extra" + std::to_string(which_field + 2); + const auto& fcn = node_map[talk_node.type][which_field]; + if(fcn.button == eSpecPicker::STRING) { + int i = me[field_id].getTextAsNum(); + std::string title; + switch(fcn.str_type) { + case STRT_TOWN: title = "Which town?"; break; + case STRT_COST_ADJ: title = "What cost adjust?"; break; + case STRT_SHOP: title = "Which shop?"; break; + case STRT_ENCHANT: title = "Which enchantment?"; break; + case STRT_BOAT: title = "Which boat?"; break; + case STRT_HORSE: title = "Which horse?"; break; + case STRT_SPEC_ITEM: title = "Which special item?"; break; + default: title = "Title not set for this string type!!!"; break; } - } else if(item_hit == "chooseA") { - int spec = me["extra1"].getTextAsNum(); - // Create/Edit a quest: - if(talk_node.type == eTalkNode::RECEIVE_QUEST){ - if(spec == -1){ - spec = scenario.quests.size(); - me["extra1"].setTextToNum(spec); - } - edit_quest(spec); + i = choose_text(fcn.str_type, i, &me, title); + me[field_id].setTextToNum(i); + } else if(fcn.button == eSpecPicker::EVENT) { + int value = me[field_id].getTextAsNum(); + value = choose_text_editable(scenario.evt_names, value, &me, "Select an event:"); + me[field_id].setTextToNum(value); + } else if(fcn.button == eSpecPicker::LOCATION) { + location loc(me[field_id].getTextAsNum(), me[second_field_id].getTextAsNum()); + cLocationPicker picker(loc, *town, "Choose a location:", &me); + loc = picker.run(); + if(picker->accepted()) { + me[field_id].setTextToNum(loc.x); + me[second_field_id].setTextToNum(loc.y); } - // Create/Edit a special node: - else{ - int mode = talk_node.type == eTalkNode::CALL_TOWN_SPEC ? 2 : 0; - if(spec < 0) - spec = get_fresh_spec(mode); - if(edit_spec_enc(spec,mode,&me)) - me["extra1"].setTextToNum(spec); + } else if(fcn.button == eSpecPicker::SDF) { + location sdf(me[second_field_id].getTextAsNum(), me[field_id].getTextAsNum()); + cStuffDonePicker picker(sdf); + sdf = picker.run(); + me[second_field_id].setTextToNum(sdf.x); + me[field_id].setTextToNum(sdf.y); + } else if(fcn.button == eSpecPicker::QUEST) { + int quest = me[field_id].getTextAsNum(); + if(quest < 0 || quest >= scenario.quests.size()){ + quest = scenario.quests.size(); + me[field_id].setTextToNum(quest); } - } else if(item_hit == "chooseA-regular") { - int i = me["extra1"].getTextAsNum(); - i = choose_text(STRT_ENCHANT,i,&me,"Which enchantment?"); - me["extra1"].setTextToNum(i); + edit_quest(quest); + } else if(fcn.button == eSpecPicker::NODE) { + int spec = me[field_id].getTextAsNum(); + int mode = fcn.force_global ? 0 : 2; + if(spec < 0) + spec = get_fresh_spec(mode); + if(edit_spec_enc(spec,mode,&me)) + me[field_id].setTextToNum(spec); } return true; } @@ -1387,7 +1429,7 @@ short edit_talk_node(short which_node) { talk_dlg["new"].attachClickHandler(std::bind(talk_node_branch, _1, std::ref(talk_edit_stack))); talk_dlg["choose-type"].attachClickHandler(std::bind(select_talk_node_type, _1, std::ref(talk_edit_stack))); talk_dlg["choose-personality"].attachClickHandler(std::bind(select_talk_node_personality, _1, std::ref(talk_edit_stack))); - talk_dlg.attachClickHandlers(std::bind(select_talk_node_value, _1, _2, std::ref(talk_edit_stack)), {"chooseA","chooseA-regular","chooseB"}); + talk_dlg.attachClickHandlers(std::bind(select_talk_node_value, _1, _2, std::ref(talk_edit_stack)), {"chooseA","chooseC","chooseB"}); talk_dlg["who"].attachFocusHandler(check_talk_personality); talk_dlg.attachFocusHandlers(check_talk_key, {"key1", "key2"}); talk_dlg.attachFocusHandlers(std::bind(check_talk_xtra, _1, std::ref(talk_edit_stack), _2, _3), {"extra1", "extra2", "extra3", "extra4"});