Get the edit monster abilities dialog all working and updated (except for editing individual abilities)

Game changes:
- Remove support for playing a sound and displaying strings when a monster is first seen, since these behaviours can easily be obtained by using the special node called in the same context.
Dialog engine changes:
- Support for changing the font size of LEDs
- When setting the page, a stack now applies a default value if the map is missing the required data
- Add utility "addPage" method to stacks
- If reducing the page count means the current page is deleted, a stack now switches to the last page
This commit is contained in:
2015-01-18 17:25:08 -05:00
parent 1441f6bfe9
commit 7084991e55
14 changed files with 157 additions and 80 deletions

View File

@@ -229,24 +229,11 @@ void draw_monsters() {
}
void play_see_monster_str(unsigned short m, location monst_loc) {
short str1, str2, pic, snd, spec;
short pic, spec;
ePicType type;
str1 = univ.scenario.scen_monsters[m].see_str1;
str2 = univ.scenario.scen_monsters[m].see_str2;
pic = univ.scenario.scen_monsters[m].picture_num;
type = get_monst_pictype(m);
snd = univ.scenario.scen_monsters[m].see_sound;
spec = univ.scenario.scen_monsters[m].see_spec;
// First display strings, if any
if((str1 >= 0 && str1 < 100) || (str2 >= 0 && str2 < 100)) {
short where1 = is_out() ? univ.party.outdoor_corner.x + univ.party.i_w_c.x : univ.town.num;
short where2 = is_out() ? univ.party.outdoor_corner.y + univ.party.i_w_c.y : univ.town.num;
std::string placename = is_out() ? univ.out->out_name : univ.town->town_name;
cStrDlog display_strings(str1 < 100 ? univ.scenario.spec_strs[str1] : "", str2 < 100 ? univ.scenario.spec_strs[str2] : "", "", pic, type, NULL);
display_strings.setSound(snd);
display_strings.setRecordHandler(cStringRecorder(NOTE_SCEN).string1(str1).string2(str2).from(where1,where2).at(placename));
display_strings.show();
}
// Then run the special, if any
if(spec > -1){
queue_special(eSpecCtx::SEE_MONST, 0, spec, monst_loc);

View File

@@ -132,8 +132,6 @@ void cMonster::append(legacy::monster_record_type& old){
picture_num = old.picture_num;
if(picture_num == 122) picture_num = 119;
see_spec = -1;
see_str1 = see_str2 = -1;
see_sound = 0;
ambient_sound = 0;
}
@@ -371,8 +369,6 @@ void cMonster::addAbil(eMonstAbilTemplate what, int param) {
cMonster::cMonster(){
magic_res = poison_res = fire_res = cold_res = 100;
// TODO: Fill in
see_str1 = -1;
see_str2 = -1;
see_spec = -1;
}
@@ -792,17 +788,14 @@ void cMonster::writeTo(std::ostream& file) const {
}
void cMonster::readFrom(std::istream& file) {
// On-see event is not exported, so make sure the fields are not filled with garbage data
see_sound = 0;
see_str1 = -1;
see_str2 = -1;
// On-see event is not exported, so make sure the field ise not filled with garbage data
see_spec = -1;
std::istringstream bin;
std::string cur;
getline(file, cur, '\f');
bin.str(cur);
while(bin) {
int temp1, temp2, temp3;
int temp1, temp2;
getline(bin, cur);
std::istringstream line(cur);
line >> cur;

View File

@@ -140,8 +140,7 @@ public:
unsigned char summon_type;
pic_num_t default_facial_pic;
pic_num_t picture_num;
str_num_t see_str1, see_str2;
snd_num_t see_sound, ambient_sound; // ambient_sound has a chance of being played every move
snd_num_t ambient_sound; // has a chance of being played every move
spec_num_t see_spec;
public:

View File

@@ -225,11 +225,13 @@ bool cLed::triggerClickHandler(cDialog& me, std::string id, eKeyMod mods){
void cLed::setFormat(eFormat prop, short val) throw(xUnsupportedProp){
if(prop == TXT_FONT) textFont = (eFont) val;
else if(prop == TXT_SIZE) textSize = val;
else throw xUnsupportedProp(prop);
}
short cLed::getFormat(eFormat prop) throw(xUnsupportedProp){
if(prop == TXT_FONT) return textFont;
else if(prop == TXT_SIZE) return textSize;
else throw xUnsupportedProp(prop);
}
@@ -240,8 +242,8 @@ void cLed::draw(){
if(visible){
TextStyle style;
style.pointSize = 9;
style.lineHeight = 8;
style.pointSize = textSize;
style.lineHeight = textSize - 1;
from_rect = ledRects[state][depressed];
to_rect = frame;
to_rect.right = to_rect.left + 14;
@@ -265,6 +267,7 @@ void cLed::restore(storage_t to) {
cButton::restore(to);
if(to.find("led-state") != to.end())
setState(boost::any_cast<eLedState>(to["led-state"]));
else setState(led_off);
}
cLedGroup::cLedGroup(cDialog* parent) :
@@ -501,4 +504,5 @@ void cLedGroup::restore(storage_t to) {
cControl::restore(to);
if(to.find("led-select") != to.end())
setSelected(boost::any_cast<std::string>(to["led-select"]));
else setSelected("");
}

View File

@@ -326,4 +326,5 @@ cControl::storage_t cControl::store() {
void cControl::restore(storage_t to) {
if(to.find("text") != to.end())
lbl = boost::any_cast<std::string>(to["text"]);
else lbl = "";
}

View File

@@ -583,7 +583,7 @@ template<> pair<string,cLed*> cDialog::parse(Element& who /*LED*/){
p.second->setFormat(TXT_SIZE, 12);
else if(val == "small")
p.second->setFormat(TXT_SIZE, 10);
if(val == "title")
else if(val == "title")
p.second->setFormat(TXT_SIZE, 18);
else throw xBadVal("text",name,val,attr->Row(),attr->Column(),fname);
}else if(name == "color" || name == "colour"){

View File

@@ -493,6 +493,8 @@ void cTextField::restore(storage_t to) {
cControl::restore(to);
if(to.find("fld-ip") != to.end())
insertionPoint = boost::any_cast<int>(to["fld-ip"]);
else insertionPoint = getText().length();
if(to.find("fld-sp") != to.end())
selectionPoint = boost::any_cast<int>(to["fld-sp"]);
else selectionPoint = 0;
}

View File

@@ -1128,6 +1128,8 @@ void cPict::restore(storage_t to) {
cControl::restore(to);
if(to.find("pic-num") != to.end())
picNum = boost::any_cast<pic_num_t>(to["pic-num"]);
else picNum = -1;
if(to.find("pic-type") != to.end())
picType = boost::any_cast<ePicType>(to["pic-type"]);
else picNum = PIC_DLOG;
}

View File

@@ -199,4 +199,5 @@ void cScrollbar::restore(storage_t to) {
cControl::restore(to);
if(to.find("scroll-pos") != to.end())
pos = boost::any_cast<int>(to["scroll-pos"]);
else pos = 0;
}

View File

@@ -96,10 +96,16 @@ size_t cStack::getPage() {
}
void cStack::setPageCount(size_t n) {
if(curPage >= n && n > 0)
setPage(nPages - 1);
nPages = n;
storage.resize(nPages);
}
void cStack::addPage() {
setPageCount(getPageCount() + 1);
}
size_t cStack::getPageCount() {
return nPages;
}
@@ -142,5 +148,5 @@ void cStack::fillTabOrder(std::vector<int>& specificTabs, std::vector<int>& reve
}
}
cStack::cStack(cDialog& parent) : cControl(CTRL_STACK, parent) {}
cStack::cStack(cDialog& parent) : cControl(CTRL_STACK, parent), curPage(0), nPages(0) {}

View File

@@ -63,7 +63,11 @@ public:
/// Set the number of pages in the stack.
/// @param n The new number of pages
/// @note If you reduce the number of pages, some data will be destroyed.
/// @note If the current page is deleted by this function, the last page will be shown, if there are any left.
void setPageCount(size_t n);
/// Add a new page to the end of the stack.
/// This is equivalent to calling setPageCount(getPageCount() + 1).
void addPage();
// Get the number of pages in the stack.
/// @return The number of pages
size_t getPageCount();

View File

@@ -127,7 +127,7 @@ The `<led>` tag accepts the following attributes:
Attributes** above.
* `state` - Specifies the starting state of the LED. Can be one of
`red`, `green`, or `off`; defaults to `off`.
* `font`, `size`, `color`, `colour` - See **Common Attributes** above.
* `font`, `size`, `color`, `colour` - See **Common Attributes** above. Note that, for an LED, omitting the size attribute gives a different result than any of the possible values.
The `<group>` tag
-----------------

View File

@@ -19,6 +19,7 @@
#include "fileio.hpp"
#include "field.hpp"
#include "restypes.hpp"
#include "stack.hpp"
extern short cen_x, cen_y,cur_town;
extern bool mouse_button_held;
@@ -600,8 +601,46 @@ static void put_monst_abils_in_dlog(cDialog& me, cMonster& store_monst, short wh
me["loot-item"].setTextToNum(store_monst.corpse_item);
me["loot-chance"].setTextToNum(store_monst.corpse_item_chance);
me["magic-res"].setTextToNum(store_monst.magic_res);
me["fire-res"].setTextToNum(store_monst.fire_res);
me["cold-res"].setTextToNum(store_monst.cold_res);
me["poison-res"].setTextToNum(store_monst.poison_res);
me["onsee"].setTextToNum(store_monst.see_spec);
me["snd"].setTextToNum(store_monst.ambient_sound);
if(store_monst.mindless)
dynamic_cast<cLed&>(me["mindless"]).setState(led_red);
if(store_monst.invuln)
dynamic_cast<cLed&>(me["invuln"]).setState(led_red);
if(store_monst.invisible)
dynamic_cast<cLed&>(me["invis"]).setState(led_red);
if(store_monst.guard)
dynamic_cast<cLed&>(me["guard"]).setState(led_red);
dynamic_cast<cLedGroup&>(me["summon"]).setSelected("s" + boost::lexical_cast<std::string,short>(store_monst.summon_type));
cStack& abils = dynamic_cast<cStack&>(me["abils"]);
abils.setPageCount(0); // This clears out any data still in the stack
abils.setPageCount(1);
int i = 0;
for(auto& abil : store_monst.abil) {
if(!abil.second.active) continue;
std::string id = std::to_string((i % 4) + 1);
if(i % 4 == 0) abils.setPage(i / 4);
else if(i % 4 == 3) abils.addPage();
me["abil-name" + id].setText(abil.second.to_string(abil.first));
me["abil-edit" + id].setText("Edit");
i++;
}
abils.setPage(0);
if(abils.getPageCount() <= 1) {
me["abil-up"].hide();
me["abil-down"].hide();
} else {
me["abil-up"].show();
me["abil-down"].show();
}
}
static bool save_monst_abils(cDialog& me, cMonster& store_monst) {
@@ -609,10 +648,21 @@ static bool save_monst_abils(cDialog& me, cMonster& store_monst) {
store_monst.corpse_item = me["loot-item"].getTextAsNum();
store_monst.corpse_item_chance = me["loot-chance"].getTextAsNum();
store_monst.magic_res = me["magic-res"].getTextAsNum();
store_monst.fire_res = me["fire-res"].getTextAsNum();
store_monst.cold_res = me["cold-res"].getTextAsNum();
store_monst.poison_res = me["poison-res"].getTextAsNum();
store_monst.see_spec = me["onsee"].getTextAsNum();
store_monst.ambient_sound = me["snd"].getTextAsNum();
store_monst.mindless = dynamic_cast<cLed&>(me["mindless"]).getState() != led_off;
store_monst.invuln = dynamic_cast<cLed&>(me["invuln"]).getState() != led_off;
store_monst.invisible = dynamic_cast<cLed&>(me["invis"]).getState() != led_off;
store_monst.guard = dynamic_cast<cLed&>(me["guard"]).getState() != led_off;
return true;
}
static bool edit_monst_abil_event_filter(cDialog& me,std::string item_hit,cMonster& store_monst,short which_monst) {
static bool edit_monst_abil_event_filter(cDialog& me,std::string item_hit,cMonster& store_monst) {
using namespace std::placeholders;
if(item_hit == "cancel") {
@@ -621,6 +671,30 @@ static bool edit_monst_abil_event_filter(cDialog& me,std::string item_hit,cMonst
} else if(item_hit == "okay") {
if(save_monst_abils(me, store_monst))
me.toast(true);
} else if(item_hit == "abil-up") {
cStack& abils = dynamic_cast<cStack&>(me["abils"]);
if(abils.getPage() == 0) abils.setPage(abils.getPageCount() - 1);
else abils.setPage(abils.getPage() - 1);
} else if(item_hit == "abil-down") {
cStack& abils = dynamic_cast<cStack&>(me["abils"]);
if(abils.getPage() >= abils.getPageCount() - 1) abils.setPage(0);
else abils.setPage(abils.getPage() + 1);
} else if(item_hit == "edit-see") {
short spec = me["onsee"].getTextAsNum();
if(spec < 0 || spec > 255) {
spec = get_fresh_spec(0);
if(spec < 0) {
giveError("You can't create a new scenario special encounter because there are no more free special nodes.",
"To free a special node, set its type to No Special and set its Jump To special to -1.", &me);
return true;
}
}
if(edit_spec_enc(spec,0,&me))
me["onsee"].setTextToNum(spec);
} else if(item_hit == "pick-snd") {
int i = me["snd"].getTextAsNum();
i = choose_text(STRT_SND, i, &me, "Select monster vocalization sound:");
me["snd"].setTextToNum(i);
}
return true;
}
@@ -632,7 +706,7 @@ cMonster edit_monst_abil(cMonster starting_record,short which_monst) {
cDialog monst_dlg("edit-monster-abils");
monst_dlg["loot-item"].attachFocusHandler(std::bind(check_range_msg, _1, _2, _3, -1, 399, "Item To Drop", "-1 for no item"));
monst_dlg["loot-chance"].attachFocusHandler(std::bind(check_range_msg, _1, _2, _3, -1, 100, "Dropping Chance", "-1 for no item"));
monst_dlg.attachClickHandlers(std::bind(edit_monst_abil_event_filter, _1, _2, std::ref(store_monst),which_monst), {"okay", "cancel", "abils", "radiate"});
monst_dlg.attachClickHandlers(std::bind(edit_monst_abil_event_filter, _1, _2, std::ref(store_monst)), {"okay", "cancel", "abil-up", "abil-down", "edit-see", "pick-snd"});
put_monst_abils_in_dlog(monst_dlg, store_monst, which_monst);