continue to check correct bounds when accessing scen_monsters, idem for party.summons

Scenario Editor: save default talking picture even if its value is NO_PICT
Character Editor: save correctly the number of days
This commit is contained in:
ALONSO Laurent
2021-11-14 12:57:32 +01:00
committed by Celtic Minstrel
parent c5044967aa
commit 5522c268bb
15 changed files with 95 additions and 76 deletions

View File

@@ -1146,7 +1146,7 @@ static bool handle_terpal_action(location cur_point, bool option_hit) {
set_string("Place the item:",scenario.get_item(mode_count).full_name);
break;
case DRAW_MONST:
if(k + 1 >= scenario.scen_monsters.size())
if(k + 1 < 0 || k + 1 >= scenario.scen_monsters.size())
break;
overall_mode = MODE_PLACE_CREATURE;
mode_count = k + 1;

View File

@@ -756,7 +756,7 @@ static bool edit_monst_type_event_filter(cDialog& me,std::string hit,cMonster& m
if(hit == "okay") {
if(save_monst_info(me,monst)) {
scenario.scen_monsters[which] = monst;
scenario.get_monster(which) = monst;
me.toast(true);
}
} else if(hit == "abils") {
@@ -767,17 +767,17 @@ static bool edit_monst_type_event_filter(cDialog& me,std::string hit,cMonster& m
put_monst_info_in_dlog(me,monst,which);
} else if(hit == "left") {
if(!save_monst_info(me,monst)) return false;
scenario.scen_monsters[which] = monst;
scenario.get_monster(which) = monst;
which--;
if(which < 1) which = scenario.scen_monsters.size() - 1;
monst = scenario.scen_monsters[which];
monst = scenario.get_monster(which);
put_monst_info_in_dlog(me,monst,which);
} else if(hit == "right") {
if(!save_monst_info(me,monst)) return false;
scenario.scen_monsters[which] = monst;
scenario.get_monster(which) = monst;
which++;
if(which >= scenario.scen_monsters.size()) which = 1;
monst = scenario.scen_monsters[which];
monst = scenario.get_monster(which);
put_monst_info_in_dlog(me,monst,which);
} else if(hit == "picktype") {
if(!save_monst_info(me,monst)) return false;
@@ -835,7 +835,7 @@ static bool pick_monst_picture(cDialog& me) {
bool edit_monst_type(short which) {
using namespace std::placeholders;
mon_num_t first = which;
cMonster monst = scenario.scen_monsters[which];
cMonster monst = scenario.get_monster(which);
cDialog monst_dlg("edit-monster");
monst_dlg["pickicon"].attachClickHandler(std::bind(pick_monst_picture,_1));
@@ -907,7 +907,7 @@ static void put_monst_abils_in_dlog(cDialog& me, cMonster& monst) {
} else if(i % 4 == 3) abils.addPage();
std::string name = abil.second.to_string(abil.first);
if(abil.first == eMonstAbil::SUMMON && abil.second.summon.type == eMonstSummon::TYPE)
name.replace(name.find("%s"), 2, scenario.scen_monsters[abil.second.summon.what].m_name);
name.replace(name.find("%s"), 2, scenario.get_monster(abil.second.summon.what).m_name);
me["abil-name" + id].setText(name);
me["abil-edit" + id].setText("Edit");
i++;
@@ -1000,7 +1000,7 @@ static void fill_monst_abil_detail(cDialog& me, cMonster& monst, eMonstAbil abil
me["monst"].setText(monst.m_name);
std::string name = detail.to_string(abil);
if(abil == eMonstAbil::SUMMON && detail.summon.type == eMonstSummon::TYPE)
name.replace(name.find("%s"), 2, scenario.scen_monsters[detail.summon.what].m_name);
name.replace(name.find("%s"), 2, scenario.get_monster(detail.summon.what).m_name);
me["name"].setText(detail.to_string(abil));
// These names start at line 80 in the strings file, but the first valid ability is ID 1, so add 79.
me["type"].setText(get_str("monster-abilities", 79 + int(abil)));
@@ -1098,7 +1098,7 @@ static void fill_monst_abil_detail(cDialog& me, cMonster& monst, eMonstAbil abil
else title.hide(), field.hide(), pick.hide();
} else if(cat == eMonstAbilCat::SUMMON) {
switch(detail.summon.type) {
case eMonstSummon::TYPE: me["summon"].setText(scenario.scen_monsters[detail.summon.what].m_name); break;
case eMonstSummon::TYPE: me["summon"].setText(scenario.get_monster(detail.summon.what).m_name); break;
case eMonstSummon::LEVEL: me["summon"].setTextToNum(detail.summon.what); break;
case eMonstSummon::SPECIES: me["summon"].setText(get_str("traits", detail.summon.what * 2 + 35)); break;
}
@@ -1526,7 +1526,7 @@ static void put_item_info_in_dlog(cDialog& me, cItem const &item, short which) {
std::string abil = item.getAbilName();
if(item.ability == eItemAbil::SUMMONING || item.ability == eItemAbil::MASS_SUMMONING)
abil.replace(abil.find("%s"), 2, scenario.scen_monsters[item.abil_data[1]].m_name);
abil.replace(abil.find("%s"), 2, scenario.get_monster(item.abil_data[1]).m_name);
me["abilname"].setText(abil);
}

View File

@@ -486,7 +486,7 @@ void writeMonstersToXml(ticpp::Printer&& data, cScenario& scenario) {
data.PushAttribute("id", i);
cMonster& monst = scenario.scen_monsters[i];
data.PushElement("name", monst.m_name);
if(monst.default_facial_pic > 0)
if(monst.default_facial_pic >= -1) // -1: means use monster pict
data.PushElement("default-face", monst.default_facial_pic);
data.OpenElement("pic");

View File

@@ -411,7 +411,7 @@ void set_up_terrain_buttons(bool reset) {
break;
}
case DRAW_MONST:
pic = scenario.scen_monsters[i].picture_num;
pic = scenario.get_monster(i).picture_num;
tiny_to = draw_rect;
frame_rect(mainPtr, tiny_to, sf::Color::Black);
if(pic >= 4000) {
@@ -716,7 +716,7 @@ void draw_terrain(){
need_hilite = true;
else if(overall_mode == MODE_PLACE_CREATURE || overall_mode == MODE_PLACE_SAME_CREATURE) {
extern short mode_count;
cMonster& monst = scenario.scen_monsters[mode_count];
cMonster& monst = scenario.get_monster(mode_count);
for(int x = 0; x < monst.x_width; x++) {
for(int y = 0; y < monst.y_width; y++) {
location this_spot = {where_draw.x - x, where_draw.y - y};
@@ -842,48 +842,49 @@ void draw_monsts() {
rectangle source_rect;
location where_draw,store_loc;
for(short i = 0; i < town->creatures.size(); i++)
if(town->creatures[i].number != 0) {
where_draw.x = town->creatures[i].start_loc.x - cen_x + 4;
where_draw.y = town->creatures[i].start_loc.y - cen_y + 4;
width = scenario.scen_monsters[town->creatures[i].number].x_width;
height = scenario.scen_monsters[town->creatures[i].number].y_width;
for(auto const &creature : town->creatures) {
if(creature.number == 0) continue;
where_draw.x = creature.start_loc.x - cen_x + 4;
where_draw.y = creature.start_loc.y - cen_y + 4;
auto const &monster=scenario.get_monster(creature.number);
width = monster.x_width;
height = monster.y_width;
for(short k = 0; k < width * height; k++) {
store_loc = where_draw;
if((where_draw.x == minmax(0,8,where_draw.x)) &&
(where_draw.y == minmax(0,8,where_draw.y)) &&
(scenario.scen_monsters[town->creatures[i].number].picture_num >= 1000)) {
std::tie(from_gworld,source_rect) = spec_scen_g.find_graphic((scenario.scen_monsters[town->creatures[i].number].picture_num + k) % 1000);
store_loc.x += k % width;
store_loc.y += k / width;
}
else if(scenario.scen_monsters[town->creatures[i].number].picture_num < 1000) {
m_start_pic = m_pic_index[scenario.scen_monsters[town->creatures[i].number].picture_num].i + k;
int which_sheet = m_start_pic / 20;
from_gworld = *ResMgr::textures.get("monst" + std::to_string(1 + which_sheet));
m_start_pic = m_start_pic % 20;
source_rect = calc_rect(2 * (m_start_pic / 10), m_start_pic % 10);
store_loc.x += k % width;
store_loc.y += k / width;
}
if(store_loc.x < 0 || store_loc.x > 8 || store_loc.y < 0 || store_loc.y > 8)
continue;
rectangle destrec;
destrec.left = 8 + BITMAP_WIDTH * store_loc.x;
destrec.right = destrec.left + BITMAP_WIDTH;
destrec.top = 8 + BITMAP_HEIGHT * store_loc.y;
destrec.bottom = destrec.top + BITMAP_HEIGHT;
destrec.left = destrec.right - (source_rect.right - source_rect.left);
destrec.top = destrec.bottom - (source_rect.bottom - source_rect.top);
destrec.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
rect_draw_some_item(from_gworld, source_rect, mainPtr, destrec, sf::BlendAlpha);
for(short k = 0; k < width * height; k++) {
store_loc = where_draw;
if(where_draw.x == minmax(0,8,where_draw.x) && where_draw.y == minmax(0,8,where_draw.y) && monster.picture_num >= 1000) {
std::tie(from_gworld,source_rect) = spec_scen_g.find_graphic((monster.picture_num + k) % 1000);
store_loc.x += k % width;
store_loc.y += k / width;
}
else if(monster.picture_num>=0 && monster.picture_num < 1000 && monster.picture_num<m_pic_index.size()) {
m_start_pic = m_pic_index[monster.picture_num].i + k;
int which_sheet = m_start_pic / 20;
from_gworld = *ResMgr::textures.get("monst" + std::to_string(1 + which_sheet));
m_start_pic = m_start_pic % 20;
source_rect = calc_rect(2 * (m_start_pic / 10), m_start_pic % 10);
store_loc.x += k % width;
store_loc.y += k / width;
}
else
continue;
if(store_loc.x < 0 || store_loc.x > 8 || store_loc.y < 0 || store_loc.y > 8)
continue;
rectangle destrec;
destrec.left = 8 + BITMAP_WIDTH * store_loc.x;
destrec.right = destrec.left + BITMAP_WIDTH;
destrec.top = 8 + BITMAP_HEIGHT * store_loc.y;
destrec.bottom = destrec.top + BITMAP_HEIGHT;
destrec.left = destrec.right - (source_rect.right - source_rect.left);
destrec.top = destrec.bottom - (source_rect.bottom - source_rect.top);
destrec.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
rect_draw_some_item(from_gworld, source_rect, mainPtr, destrec, sf::BlendAlpha);
}
}
}
static void update_item_rectangle(cPictNum const &pict, rectangle &rect)
@@ -1135,7 +1136,7 @@ void place_location() {
bool draw_field = false;
if(overall_mode == MODE_PLACE_CREATURE || overall_mode == MODE_PLACE_SAME_CREATURE) {
rectangle to_rect = draw_rect;
picture_wanted = scenario.scen_monsters[mode_count].picture_num;
picture_wanted = scenario.get_monster(mode_count).picture_num;
if(picture_wanted >= 4000) {
picture_wanted %= 1000;
to_rect.width() = to_rect.width() / 2;

View File

@@ -42,7 +42,7 @@ const char *day_str_2[] = {"Unused","Event code (0 - no event)","Event code (0 -
static void put_placed_monst_in_dlog(cDialog& me, cTownperson& monst, const short which) {
me["num"].setTextToNum(which);
me["type"].setText(scenario.scen_monsters[monst.number].m_name);
me["type"].setText(scenario.get_monster(monst.number).m_name);
// TODO: Make attitude an enum
dynamic_cast<cLedGroup&>(me["attitude"]).setSelected(boost::lexical_cast<std::string>(monst.start_attitude));
dynamic_cast<cLedGroup&>(me["mobility"]).setSelected("mob" + std::to_string(monst.mobility + 1));
@@ -50,7 +50,7 @@ static void put_placed_monst_in_dlog(cDialog& me, cTownperson& monst, const shor
me["picnum"].setTextToNum(monst.facial_pic);
// TODO: Use -1 instead of 0 for "no pic", since 0 is a valid talking picture
if(short(monst.facial_pic) < 0)
dynamic_cast<cPict&>(me["pic"]).setPict(scenario.scen_monsters[monst.number].picture_num, PIC_MONST);
dynamic_cast<cPict&>(me["pic"]).setPict(scenario.get_monster(monst.number).picture_num, PIC_MONST);
else if((monst.facial_pic >= 1000))
dynamic_cast<cPict&>(me["pic"]).setPict(monst.facial_pic - 1000,PIC_CUSTOM_TALK);
else dynamic_cast<cPict&>(me["pic"]).setPict(monst.facial_pic,PIC_TALK);
@@ -116,7 +116,7 @@ void edit_placed_monst(short which_m) {
static void put_placed_monst_adv_in_dlog(cDialog& me, cTownperson& monst, const short which) {
me["num"].setTextToNum(which);
me["type"].setText(scenario.scen_monsters[monst.number].m_name);
me["type"].setText(scenario.get_monster(monst.number).m_name);
int iTime = 0;
switch(monst.time_flag) {
case eMonstTime::ALWAYS: iTime = 0; break;
@@ -520,14 +520,14 @@ static void put_out_wand_in_dlog(cDialog& me, short which, const cOutdoors::cWan
if(wand.monst[i] == 0)
me[id].setText("Empty");
// TODO: Wait a second, if 0 is no monster, does that mean it's impossible to use monster 0? Should 1 be subtracted here?
else me[id].setText(scenario.scen_monsters[wand.monst[i]].m_name);
else me[id].setText(scenario.get_monster(wand.monst[i]).m_name);
}
for(short i = 0; i < 3; i++) {
std::string id = "ally" + std::to_string(i + 1);
if(wand.friendly[i] == 0)
me[id].setText("Empty");
// TODO: Wait a second, if 0 is no monster, does that mean it's impossible to use monster 0? Should 1 be subtracted here?
else me[id].setText(scenario.scen_monsters[wand.friendly[i]].m_name);
else me[id].setText(scenario.get_monster(wand.friendly[i]).m_name);
}
dynamic_cast<cLed&>(me["no-flee"]).setState(wand.cant_flee ? led_red : led_off);
dynamic_cast<cLed&>(me["forced"]).setState(wand.forced ? led_red : led_off);
@@ -604,7 +604,7 @@ static bool edit_out_wand_monst(cDialog& me, std::string hit, short which, cOutd
i = choose_text(STRT_MONST,wand.friendly[fld[4] - '1']-1,&me,"Choose Which Monster:") + 1;
if(i >= 0) wand.friendly[fld[4] - '1'] = i;
}
me[fld].setText(scenario.scen_monsters[i].m_name);
me[fld].setText(scenario.get_monster(i).m_name);
return true;
}