Use an editable string picker for job boards when editing quests or dialogue nodes

This commit is contained in:
2025-03-02 19:49:45 -05:00
committed by Celtic Minstrel
parent 6e94d23e05
commit 50637d3ddd
10 changed files with 49 additions and 6 deletions

View File

@@ -24,7 +24,9 @@
<led name='start' wrap='true' top='246' left='345'>Player is given quest when scenario starts</led>
<led name='inbank' top='285' left='345'>Include in a job bank:</led>
<field name='bank1' top='306' left='359' width='110' height='16'/>
<button name='choose-bank1' type='regular' anchor='bank1' relative='pos pos-in' top='-4' left='8'>Choose</button>
<field name='bank2' top='332' left='359' width='110' height='16'/>
<button name='choose-bank2' type='regular' anchor='bank2' relative='pos pos-in' top='-4' left='8'>Choose</button>
<button name='left' type='left' def-key='left' top='358' left='50'/>
<button name='right' type='right' def-key='right' top='358' left='115'/>
<button name='cancel' type='regular' def-key='esc' top='358' left='322'>Cancel</button>

View File

@@ -314,6 +314,7 @@ attribute specifies which sound it applies to.
* `<event>` - (max unbounded) Gives a name to a major event flag. These names are shown (and editable) when showing the Pick Event dialog in various places. The required `id` attribute specifies which event.
* `<item-class>` - (max unbounded) Gives a name to an item special class. These names are shown (and editable) when showing the Pick Item Class dialog in various places. The required `id` attribute specifies which class.
* `<item-typeflag>` - (max unbounded) Gives a name to an item type flag. These names are shown (and editable) when showing the Pick Item Type Flag dialog in the item editor. The required `id` attribute specifies which flag.
* `<job-board>` - (max unbounded) Gives a name to a job board. These names are shown (and editable) when showing the Pick Job Board dialog in the item editor. The required `id` attribute specifies which board.
* `<sdf>` - (max unbounded) Gives a name to a Stuff Done Flag. These names are shown (and editable) when showing the Pick Stuff Done Flag dialog in the item editor. The required `row` and `col` attributes specify which flag.
Terrain Types

View File

@@ -391,6 +391,15 @@
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="job-board" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" use="required" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="sdf" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>

View File

@@ -965,6 +965,12 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
if(itfnum > scenario.itf_names.size())
scenario.itf_names.resize(itfnum);
edit->GetText(&scenario.itf_names[itfnum - 1], false);
} else if(type == "job-board") {
int qbnum = 0;
edit->GetAttribute("id", &qbnum);
if(qbnum > scenario.qb_names.size())
scenario.qb_names.resize(qbnum);
edit->GetText(&scenario.qb_names[qbnum - 1], false);
} else if(type == "sdf") {
int row, col;
edit->GetAttribute("row", &row);

View File

@@ -100,6 +100,7 @@ public:
std::vector<std::string> spec_strs;
std::vector<std::string> snd_names;
std::vector<std::string> evt_names;
std::vector<std::string> qb_names;
std::vector<std::string> ic_names;
std::vector<std::string> itf_names;
std::map<int, std::map<int, std::string>> sdf_names;

View File

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

View File

@@ -2124,9 +2124,13 @@ static void put_quest_in_dlog(cDialog& me, const cQuest& quest, size_t which_que
if(quest.bank1 < 0 && quest.bank2 < 0) {
me["bank1"].hide();
me["bank2"].hide();
me["choose-bank1"].hide();
me["choose-bank2"].hide();
} else {
me["bank1"].show();
me["bank2"].show();
me["choose-bank1"].show();
me["choose-bank2"].show();
}
}
@@ -2182,19 +2186,26 @@ 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);
quest_dlg.attachClickHandlers([](cDialog& me, std::string item_hit, eKeyMod) {
std::string field_id = item_hit.substr(7);
std::string title = field_id == "evt" ? "Select an event:" : "Select a job board:";
auto strings = field_id == "evt" ? scenario.evt_names : scenario.qb_names;
int value = me[field_id].getTextAsNum();
value = choose_text_editable(strings, value, &me, title);
me[field_id].setTextToNum(value);
return true;
});
}, {"choose-evt", "choose-bank1", "choose-bank2"});
quest_dlg["inbank"].attachFocusHandler([](cDialog& me, std::string, bool losing) -> bool {
if(losing) {
me["bank1"].hide();
me["bank2"].hide();
me["choose-bank1"].hide();
me["choose-bank2"].hide();
} else {
me["bank1"].show();
me["bank2"].show();
me["choose-bank1"].show();
me["choose-bank2"].show();
}
return true;
});

View File

@@ -413,6 +413,13 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
data.PushText(scenario.itf_names[i]);
data.CloseElement("item-typeflag");
}
for(int i = 0; i < scenario.qb_names.size(); i++) {
if(scenario.qb_names[i].empty()) continue;
data.OpenElement("job-board");
data.PushAttribute("id", i + 1);
data.PushText(scenario.qb_names[i]);
data.CloseElement("job-board");
}
for(int r = 0; r < SDF_ROWS; r++) {
for(int c = 0; c < SDF_COLUMNS; c++) {
if(scenario.get_sdf_name(r, c).empty()) continue;

View File

@@ -1137,6 +1137,7 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
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::ITEM_CLASS: store = choose_text_editable(scenario.ic_names, val, &me, "Select item class:"); break;
case eSpecPicker::JOB_BOARD: store = choose_text_editable(scenario.qb_names, val, &me, "Select a job board:"); break;
case eSpecPicker::NONE: return false;
}
me[field].setTextToNum(store);

View File

@@ -1251,6 +1251,7 @@ static std::map<eTalkNode, std::array<node_function_t, 4>> node_map = {
{eTalkNode::DEP_ON_TIME_AND_EVENT, {eSpecPicker::NONE, eSpecPicker::EVENT}},
{eTalkNode::DEP_ON_TOWN, {STRT_TOWN}},
{eTalkNode::SHOP, {STRT_COST_ADJ, STRT_SHOP}},
{eTalkNode::JOB_BANK, {eSpecPicker::JOB_BOARD}},
{eTalkNode::ENCHANT, {STRT_ENCHANT}},
{eTalkNode::BUY_SDF, {eSpecPicker::NONE, eSpecPicker::SDF}},
{eTalkNode::BUY_SHIP, {eSpecPicker::NONE, STRT_BOAT}},
@@ -1383,6 +1384,10 @@ static bool select_talk_node_value(cDialog& me, std::string item_hit, const std:
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::JOB_BOARD) {
int value = me[field_id].getTextAsNum();
value = choose_text_editable(scenario.qb_names, value, &me, "Select a job board:");
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);