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:
@@ -336,6 +336,7 @@ the response changes (the first field) to 90, and the Event which prevents the c
|
||||
second field) to 4. If Fred was killed (i.e. if the Goblin Chief was not killed before Day
|
||||
90), she will respond with the second text field. Otherwise, she will respond with the
|
||||
first.</p>
|
||||
<p>You can also use events in quests. An quest can be set to expire if an event hasn't happened by a certain day. This is more or less the same as making dialogue vary.</p>
|
||||
<p>Finally, you can use the If-Then Special Node Type 150: Special Thing happened?, which
|
||||
calls different special nodes depending on whether a day has been reached and whether an
|
||||
Event has happened before that day or not.</p>
|
||||
|
@@ -252,7 +252,7 @@ occurred. See <a href="../Specials.html#time">Passage of Time</a> in the chapter
|
||||
explanation.
|
||||
<dl>
|
||||
<dt>Mess1, Mess2:</dt><dd>Standard usage.</dd>
|
||||
<dt>Extra 1a:</dt><dd>The number of the special event. (Range 1 ... 20)</dd>
|
||||
<dt>Extra 1a:</dt><dd>The number of the special event.</dd>
|
||||
<dt>Example:</dt><dd>If the slaying of the goblin king is event 4, when it is killed, call
|
||||
this special node with Extra 1a set to 4.</dd></dd>
|
||||
|
||||
@@ -1310,7 +1310,7 @@ reached before a given event happened (see the chapter on the passage of time fo
|
||||
explanation).
|
||||
<dl>
|
||||
<dt>Extra 1a:</dt><dd>The day some special thing is supposed to happen.</dd>
|
||||
<dt>Extra 1b:</dt><dd>The number of an event (0 .. 20). This is the event that would
|
||||
<dt>Extra 1b:</dt><dd>The number of an event. This is the event that would
|
||||
prevent the special thing from happening (leave at 0 for no event). If the day in 1a has
|
||||
been reached, and this special event did not occur before the day in 1a, then the special
|
||||
in Extra 2b is called.</dd>
|
||||
|
@@ -10,20 +10,21 @@
|
||||
<text top='85' left='50' width='118' height='16'>Quest Description:</text>
|
||||
<field name='name' top='57' left='205' width='252' height='16'/>
|
||||
<field name='descr' top='84' left='205' width='252' height='104'/>
|
||||
<text top='209' left='50' width='160' height='28'>Must be completed by day:<br/>(-1 for no deadline)</text>
|
||||
<text top='209' left='50' width='170' height='28'>Must be completed by day:<br/>(-1 for no deadline)</text>
|
||||
<field name='chop' top='208' left='205' width='110' height='16'/>
|
||||
<text top='247' left='50' width='150' height='28'>Event to waive deadline:<br/>(-1 for none)</text>
|
||||
<field name='evt' top='246' left='205' width='100' height='16'/>
|
||||
<text top='247' left='50' width='170' height='28'>Event to waive deadline:<br/>(-1 for none)</text>
|
||||
<field name='evt' top='246' left='205' width='60' height='16'/>
|
||||
<button name='choose-evt' type='regular' anchor='evt' relative='pos pos-in' top='-4' left='8'>Choose</button>
|
||||
<text size='large' top='280' left='50' width='220' height='17'>Reward for completing:</text>
|
||||
<text top='307' left='50' width='150' height='16'>Experience Points:</text>
|
||||
<field name='xp' top='306' left='205' width='110' height='16'/>
|
||||
<text top='333' left='50' width='150' height='16'>Gold:</text>
|
||||
<field name='gold' top='332' left='205' width='110' height='16'/>
|
||||
<led name='rel' wrap='true' top='208' left='330'>Deadline is relative to start day</led>
|
||||
<led name='start' wrap='true' top='246' left='330'>Player is given quest when scenario starts</led>
|
||||
<led name='inbank' top='285' left='330'>Include in a job bank:</led>
|
||||
<field name='bank1' top='306' left='344' width='110' height='16'/>
|
||||
<field name='bank2' top='332' left='344' width='110' height='16'/>
|
||||
<led name='rel' wrap='true' top='208' left='345'>Deadline is relative to start day</led>
|
||||
<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'/>
|
||||
<field name='bank2' top='332' left='359' width='110' height='16'/>
|
||||
<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>
|
||||
|
@@ -57,8 +57,9 @@
|
||||
A creature which is part of a special group does not exist until it's created by a special encounter
|
||||
(like special node type One-Time Place Town Encounter).
|
||||
</text>
|
||||
<text top='133' left='301' width='222' height='44'>
|
||||
<text top='133' left='366' width='222' height='44'>
|
||||
For an explanation on how event codes work,
|
||||
see the chapter in the instructions on the passing of time.
|
||||
</text>
|
||||
<button name='choose-event' type='regular' top='150' left='296'>Choose</button>
|
||||
</dialog>
|
||||
|
@@ -311,6 +311,7 @@ subtags:
|
||||
* `<sound>` - (max unbounded) Gives a name for a custom sound (ID 100 or greater). These
|
||||
names are used when showing the Pick Sound dialog in various places. The required `id`
|
||||
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.
|
||||
|
||||
Terrain Types
|
||||
-------------
|
||||
|
@@ -364,6 +364,15 @@
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="event" 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:sequence>
|
||||
</xs:complexType>
|
||||
<xs:element name="scenario">
|
||||
|
@@ -312,7 +312,7 @@ Second part of message
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Number of Special Event (0 .. 9)
|
||||
Number of Special Event
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
|
@@ -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,
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
@@ -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");
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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") {
|
||||
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:
|
||||
|
Reference in New Issue
Block a user