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.
This commit is contained in:
2025-03-02 19:35:41 -05:00
committed by Celtic Minstrel
parent b546f9c5e5
commit 6e94d23e05
3 changed files with 90 additions and 47 deletions

View File

@@ -40,7 +40,8 @@
<text size='large' top='203' left='49' width='83' height='15'>Message 1:</text> <text size='large' top='203' left='49' width='83' height='15'>Message 1:</text>
<text size='large' top='309' left='49' width='80' height='14'>Message 2:</text> <text size='large' top='309' left='49' width='80' height='14'>Message 2:</text>
<button name='choose-personality' type='regular' top='24' left='256'>Choose</button> <button name='choose-personality' type='regular' top='24' left='256'>Choose</button>
<button name='chooseD' type='regular' top='181' left='414'>Choose</button>
<button name='chooseC' type='regular' top='158' left='414'>Choose</button>
<button name='chooseB' type='regular' top='135' left='414'>Choose</button> <button name='chooseB' type='regular' top='135' left='414'>Choose</button>
<button name='chooseA' type='large' top='112' left='414'>Create/Edit</button> <button name='chooseA' type='regular' top='112' left='414'>Choose</button>
<button name='chooseA-regular' type='regular' top='112' left='414'>Choose</button>
</dialog> </dialog>

View File

@@ -156,7 +156,7 @@ enum class eSpecPicker {
FIELD, DAMAGE_TYPE, EXPLOSION, FIELD, DAMAGE_TYPE, EXPLOSION,
STATUS, STATUS_PARTY, STATUS, STATUS_PARTY,
SDF, LOCATION, RECTANGLE, TOGGLE, SDF, LOCATION, RECTANGLE, TOGGLE,
EVENT, ITEM_CLASS, EVENT, ITEM_CLASS, QUEST,
POINTER, POINTER,
}; };

View File

@@ -14,6 +14,7 @@
#include "scen.townout.hpp" #include "scen.townout.hpp"
#include "scen.keydlgs.hpp" #include "scen.keydlgs.hpp"
#include "scen.locpicker.hpp" #include "scen.locpicker.hpp"
#include "scen.sdfpicker.hpp"
#include "scen.fileio.hpp" #include "scen.fileio.hpp"
#include "scen.core.hpp" #include "scen.core.hpp"
#include "mathutil.hpp" #include "mathutil.hpp"
@@ -1242,6 +1243,25 @@ static bool save_talk_node(cDialog& me, std::stack<node_ref_t>& talk_edit_stack,
return true; return true;
} }
// TODO: Maybe I shouldn't reuse node_function_t here? It has some irrelevant data too.
static std::map<eTalkNode, std::array<node_function_t, 4>> 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<node_ref_t>& talk_edit_stack) { static void put_talk_node_in_dlog(cDialog& me, std::stack<node_ref_t>& talk_edit_stack) {
cSpeech::cNode& talk_node =talk_edit_stack.top().second; cSpeech::cNode& talk_node =talk_edit_stack.top().second;
@@ -1268,20 +1288,23 @@ static void put_talk_node_in_dlog(cDialog& me, std::stack<node_ref_t>& talk_edit
me["str1"].setText(talk_node.str1); me["str1"].setText(talk_node.str1);
me["str2"].setText(talk_node.str2); me["str2"].setText(talk_node.str2);
if(talk_node.type == eTalkNode::SHOP || talk_node.type == eTalkNode::DEP_ON_TIME_AND_EVENT) const auto fcns = node_map[talk_node.type];
me["chooseB"].show(); for(int i = 0; i < fcns.size(); i++) {
else me["chooseB"].hide(); std::ostringstream sout;
me["chooseA-regular"].hide(); sout << "choose" << char('A' + i);;
switch(talk_node.type){ auto& btn = dynamic_cast<cButton&>(me[sout.str()]);
case eTalkNode::ENCHANT: if(fcns[i].button == eSpecPicker::NONE) {
me["chooseA-regular"].show(); btn.hide();
break; continue;
case eTalkNode::CALL_TOWN_SPEC: case eTalkNode::CALL_SCEN_SPEC: case eTalkNode::RECEIVE_QUEST: }
me["chooseA"].show(); btn.show();
break; if(fcns[i].button == eSpecPicker::NODE || fcns[i].button == eSpecPicker::QUEST) {
default: btn.setText("Create/Edit");
me["chooseA"].hide(); btn.setBtnType(BTN_LG);
break; } else {
btn.setText("Choose");
btn.setBtnType(BTN_REG);
}
} }
if(talk_edit_stack.size() > 1) if(talk_edit_stack.size() > 1)
@@ -1337,38 +1360,57 @@ static bool select_talk_node_personality(cDialog& me, std::stack<node_ref_t>& ta
static bool select_talk_node_value(cDialog& me, std::string item_hit, const std::stack<node_ref_t>& talk_edit_stack) { static bool select_talk_node_value(cDialog& me, std::string item_hit, const std::stack<node_ref_t>& talk_edit_stack) {
const auto& talk_node = talk_edit_stack.top().second; const auto& talk_node = talk_edit_stack.top().second;
if(item_hit == "chooseB") { int which_field = item_hit.back() - 'A';
if(talk_node.type == eTalkNode::SHOP) { std::string field_id = "extra" + std::to_string(which_field + 1);
int i = me["extra2"].getTextAsNum(); std::string second_field_id = "extra" + std::to_string(which_field + 2);
i = choose_text(STRT_SHOP,i,&me,"Which shop?"); const auto& fcn = node_map[talk_node.type][which_field];
me["extra2"].setTextToNum(i); if(fcn.button == eSpecPicker::STRING) {
} else if(talk_node.type == eTalkNode::DEP_ON_TIME_AND_EVENT) { int i = me[field_id].getTextAsNum();
int value = me["extra2"].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;
}
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:"); value = choose_text_editable(scenario.evt_names, value, &me, "Select an event:");
me["extra2"].setTextToNum(value); 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);
} }
} else if(item_hit == "chooseA") { } else if(fcn.button == eSpecPicker::SDF) {
int spec = me["extra1"].getTextAsNum(); location sdf(me[second_field_id].getTextAsNum(), me[field_id].getTextAsNum());
// Create/Edit a quest: cStuffDonePicker picker(sdf);
if(talk_node.type == eTalkNode::RECEIVE_QUEST){ sdf = picker.run();
if(spec == -1){ me[second_field_id].setTextToNum(sdf.x);
spec = scenario.quests.size(); me[field_id].setTextToNum(sdf.y);
me["extra1"].setTextToNum(spec); } 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);
} }
edit_quest(spec); edit_quest(quest);
} } else if(fcn.button == eSpecPicker::NODE) {
// Create/Edit a special node: int spec = me[field_id].getTextAsNum();
else{ int mode = fcn.force_global ? 0 : 2;
int mode = talk_node.type == eTalkNode::CALL_TOWN_SPEC ? 2 : 0;
if(spec < 0) if(spec < 0)
spec = get_fresh_spec(mode); spec = get_fresh_spec(mode);
if(edit_spec_enc(spec,mode,&me)) if(edit_spec_enc(spec,mode,&me))
me["extra1"].setTextToNum(spec); me[field_id].setTextToNum(spec);
}
} else if(item_hit == "chooseA-regular") {
int i = me["extra1"].getTextAsNum();
i = choose_text(STRT_ENCHANT,i,&me,"Which enchantment?");
me["extra1"].setTextToNum(i);
} }
return true; 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["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-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["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["who"].attachFocusHandler(check_talk_personality);
talk_dlg.attachFocusHandlers(check_talk_key, {"key1", "key2"}); 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"}); talk_dlg.attachFocusHandlers(std::bind(check_talk_xtra, _1, std::ref(talk_edit_stack), _2, _3), {"extra1", "extra2", "extra3", "extra4"});