Implement a picker for major events, using the new editable string picker.

It's used not only in special node editing (for Event Happens and If Event Happened?)
but also in the Townperson Advanced, Talk Node, and Quest editors.
This commit is contained in:
2025-02-23 10:38:46 -05:00
committed by Celtic Minstrel
parent 97cba0471b
commit 62267261f3
15 changed files with 88 additions and 21 deletions

View File

@@ -947,6 +947,12 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
if(sndnum >= scenario.snd_names.size())
scenario.snd_names.resize(sndnum + 1);
edit->GetText(&scenario.snd_names[sndnum], false);
} else if(type == "event") {
int evtnum = 0;
edit->GetAttribute("id", &evtnum);
if(evtnum > scenario.evt_names.size())
scenario.evt_names.resize(evtnum);
edit->GetText(&scenario.evt_names[evtnum - 1], false);
} else if(type == "graphics") {
static const std::set<ePicType> valid_pictypes = {
PIC_TER, PIC_TER_ANIM, PIC_TER_MAP,

View File

@@ -202,6 +202,7 @@ void swap(cScenario& lhs, cScenario& rhs) {
swap(lhs.scen_file, rhs.scen_file);
swap(lhs.outdoors, rhs.outdoors);
swap(lhs.towns, rhs.towns);
swap(lhs.evt_names, rhs.evt_names);
}
cScenario::cItemStorage::cItemStorage() : ter_type(-1), property(0) {
@@ -600,4 +601,4 @@ std::string cScenario::get_feature_flag(std::string flag) {
std::map<std::string, std::string>::const_iterator iter = this->feature_flags.find(flag);
if(iter == this->feature_flags.end()) return "";
return iter->second;
}
}

View File

@@ -100,6 +100,7 @@ public:
std::vector<std::string> journal_strs;
std::vector<std::string> spec_strs;
std::vector<std::string> snd_names;
std::vector<std::string> evt_names;
bool adjust_diff;
bool is_legacy;
fs::path scen_file; // transient

View File

@@ -2173,6 +2173,12 @@ bool edit_quest(size_t which_quest) {
cDialog quest_dlg(*ResMgr::dialogs.get("edit-quest"));
quest_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
quest_dlg["okay"].attachClickHandler(std::bind(save_quest_from_dlog, _1, std::ref(quest), std::ref(which_quest), true));
quest_dlg["choose-evt"].attachClickHandler([](cDialog& me, std::string, eKeyMod) {
int value = me["evt"].getTextAsNum();
value = choose_text_editable(scenario.evt_names, value, &me, "Select an event:");
me["evt"].setTextToNum(value);
return true;
});
quest_dlg["inbank"].attachFocusHandler([](cDialog& me, std::string, bool losing) -> bool {
if(losing) {
me["bank1"].hide();

View File

@@ -394,6 +394,13 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
data.PushText(scenario.snd_names[i]);
data.CloseElement("sound");
}
for(int i = 0; i < scenario.evt_names.size(); i++) {
if(scenario.evt_names[i].empty()) continue;
data.OpenElement("event");
data.PushAttribute("id", i + 1);
data.PushText(scenario.evt_names[i]);
data.CloseElement("event");
}
data.CloseElement("editor");
data.CloseElement("scenario");
}

View File

@@ -501,6 +501,14 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, std
return dlog.show(cur_choice);
}
short choose_text_editable(std::vector<std::string>& list, short cur_choice, cDialog* parent, std::string title) {
cStringChoice choice(list, title, parent, true);
auto new_choice = choice.show(cur_choice <= 0 ? 0 : cur_choice - 1);
list = choice.getStrings();
if(choice->accepted()) return new_choice + 1;
return cur_choice;
}
static bool edit_text_event_filter(cDialog& me, std::string item_hit, short& which_str, eStrMode str_mode) {
std::string newVal = me["text"].getText();
fetch_str(str_mode, which_str) = newVal;
@@ -1033,6 +1041,7 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
case eSpecPicker::STATUS: store = choose_status_effect(val, false, &me); break;
case eSpecPicker::STATUS_PARTY: store = choose_status_effect(val, true, &me); break;
case eSpecPicker::SOUND: store = choose_sound(val, &me); break;
case eSpecPicker::EVENT: store = choose_text_editable(scenario.evt_names, val, &me, "Select an event:"); break;
case eSpecPicker::NONE: return false;
}
me[field].setTextToNum(store);

View File

@@ -12,6 +12,7 @@ pic_num_t choose_graphic(short cur_choice,ePicType g_type,cDialog* parent);
short choose_background(short cur_choice, cDialog* parent);
short choose_text_res(std::string res_list,short first_t,short last_t,unsigned short cur_choice,cDialog* parent,const char *title);
short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent,std::string title);
short choose_text_editable(std::vector<std::string>& list, short cur_choice, cDialog* parent, std::string title);
bool edit_text_str(short which_str,eStrMode mode);
bool edit_spec_enc(short which_node,short mode,cDialog* parent);
short get_fresh_spec(short which_mode);

View File

@@ -126,15 +126,16 @@ static void put_placed_monst_adv_in_dlog(cDialog& me, cTownperson& monst, const
me["num"].setTextToNum(which);
me["type"].setText(scenario.scen_monsters[monst.number].m_name);
int iTime = 0;
bool need_event = false;
switch(monst.time_flag) {
case eMonstTime::ALWAYS: iTime = 0; break;
case eMonstTime::APPEAR_ON_DAY: iTime = 1; break;
case eMonstTime::DISAPPEAR_ON_DAY: iTime = 2; break;
case eMonstTime::APPEAR_ON_DAY: iTime = 1; need_event = true; break;
case eMonstTime::DISAPPEAR_ON_DAY: iTime = 2; need_event = true; break;
case eMonstTime::SOMETIMES_A: iTime = 3; break;
case eMonstTime::SOMETIMES_B: iTime = 4; break;
case eMonstTime::SOMETIMES_C: iTime = 5; break;
case eMonstTime::APPEAR_WHEN_EVENT: iTime = 6; break;
case eMonstTime::DISAPPEAR_WHEN_EVENT: iTime = 7; break;
case eMonstTime::APPEAR_WHEN_EVENT: iTime = 6; need_event = true; break;
case eMonstTime::DISAPPEAR_WHEN_EVENT: iTime = 7; need_event = true; break;
case eMonstTime::APPEAR_AFTER_CHOP: iTime = 8; break;
}
dynamic_cast<cLedGroup&>(me["time"]).setSelected("time" + std::to_string(iTime + 1));
@@ -147,6 +148,11 @@ static void put_placed_monst_adv_in_dlog(cDialog& me, cTownperson& monst, const
me["hail"].setTextToNum(monst.special_on_talk);
me["sdfx"].setTextToNum(monst.spec1);
me["sdfy"].setTextToNum(monst.spec2);
if(need_event) {
me["choose-event"].show();
} else {
me["choose-event"].hide();
}
}
static bool get_placed_monst_adv_in_dlog(cDialog& me, cTownperson& monst) {
@@ -196,6 +202,11 @@ static bool edit_placed_monst_adv_time_flag(cDialog& me, std::string, bool losin
int item_hit = time.getSelected()[4] - '1';
me["extra1-lbl"].setText(day_str_1[item_hit]);
me["extra2-lbl"].setText(day_str_2[item_hit]);
if(item_hit == 1 || item_hit == 2 || item_hit == 6 || item_hit == 7) {
me["choose-event"].show();
} else {
me["choose-event"].hide();
}
return true;
}
@@ -226,6 +237,12 @@ cTownperson edit_placed_monst_adv(cTownperson initial, short which, cDialog& par
edit["editdeath"].attachClickHandler(std::bind(edit_placed_monst_adv_death, _1));
edit["edithail"].attachClickHandler(std::bind(edit_placed_monst_adv_hail, _1));
edit["time"].attachFocusHandler(edit_placed_monst_adv_time_flag);
edit["choose-event"].attachClickHandler([](cDialog& me, std::string, eKeyMod) {
int value = me["extra2"].getTextAsNum();
value = choose_text_editable(scenario.evt_names, value, &me, "Select an event:");
me["extra2"].setTextToNum(value);
return true;
});
put_placed_monst_adv_in_dlog(edit,initial,which);
@@ -1189,7 +1206,7 @@ static void put_talk_node_in_dlog(cDialog& me, std::stack<node_ref_t>& talk_edit
me["str1"].setText(talk_node.str1);
me["str2"].setText(talk_node.str2);
if(talk_node.type == eTalkNode::SHOP)
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();
@@ -1259,9 +1276,15 @@ 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) {
const auto& talk_node = talk_edit_stack.top().second;
if(item_hit == "chooseB") {
int i = me["extra2"].getTextAsNum();
i = choose_text(STRT_SHOP,i,&me,"Which shop?");
me["extra2"].setTextToNum(i);
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);
}
} else if(item_hit == "chooseA") {
int spec = me["extra1"].getTextAsNum();
// Create/Edit a quest: