Scenario editor: add a function get_item to check bounds...

This commit is contained in:
ALONSO Laurent
2021-10-19 11:56:00 +02:00
committed by Celtic Minstrel
parent 0e44c89286
commit f52c227516
6 changed files with 69 additions and 39 deletions

View File

@@ -212,13 +212,41 @@ cScenario::cItemStorage::cItemStorage() : ter_type(-1), property(0) {
item_odds[i] = 0;
}
static cItem getBadItem() {
cItem badItem;
badItem.graphic_num = 9999;
return badItem;
}
cItem const &cScenario::get_item(item_num_t item) const
{
if (item>=0 && item<scen_items.size())
return scen_items[item];
static cItem badItem=getBadItem();
return badItem;
}
cItem &cScenario::get_item(item_num_t item)
{
if (item>=0 && item<scen_items.size())
return scen_items[item];
static cItem badItem;
badItem=getBadItem();
return badItem;
}
static cTerrain getBadTerrain() {
cTerrain badTerrain;
badTerrain.picture = -3;
badTerrain.map_pic = -3;
return badTerrain;
}
cTerrain const &cScenario::get_terrain(ter_num_t ter) const
{
if (ter<ter_types.size())
return ter_types[ter];
static cTerrain badTerrain;
badTerrain.picture = -3;
badTerrain.map_pic = -3;
static cTerrain badTerrain=getBadTerrain();
return badTerrain;
}
@@ -227,8 +255,7 @@ cTerrain &cScenario::get_terrain(ter_num_t ter)
if (ter<ter_types.size())
return ter_types[ter];
static cTerrain badTerrain;
badTerrain.picture = -3;
badTerrain.map_pic = -3;
badTerrain=getBadTerrain();
return badTerrain;
}

View File

@@ -51,6 +51,8 @@ public:
void destroy_terrain();
cTerrain const &get_terrain(ter_num_t ter) const;
cTerrain &get_terrain(ter_num_t ter);
cItem const &get_item(item_num_t item) const;
cItem &get_item(item_num_t item);
public:
unsigned short difficulty,intro_pic,default_ground;
int bg_out, bg_fight, bg_town, bg_dungeon;

View File

@@ -363,13 +363,13 @@ static bool handle_rb_action(location the_point, bool option_hit) {
else if(j == size_before) {
scenario.scen_items.resize(size_before + 8);
for(; j < scenario.scen_items.size(); j++) {
scenario.scen_items[j].full_name = "New Item";
scenario.scen_items[j].name = "Item";
scenario.get_item(j).full_name = "New Item";
scenario.get_item(j).name = "Item";
}
} else {
scenario.scen_items[j] = cItem();
scenario.scen_items[j].full_name = "Unused Item";
scenario.scen_items[j].name = "Item";
scenario.get_item(j) = cItem();
scenario.get_item(j).full_name = "Unused Item";
scenario.get_item(j).name = "Item";
}
} else {
if(j == size_before) {
@@ -832,11 +832,11 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
return item.code < 0;
});
if(iter != town->preset_items.end()) {
*iter = {spot_hit, mode_count, scenario.scen_items[mode_count]};
*iter = {spot_hit, mode_count, scenario.get_item(mode_count)};
if(container_there(spot_hit)) iter->contained = true;
store_place_item = *iter;
} else {
town->preset_items.push_back({spot_hit, mode_count, scenario.scen_items[mode_count]});
town->preset_items.push_back({spot_hit, mode_count, scenario.get_item(mode_count)});
if(container_there(spot_hit)) town->preset_items.back().contained = true;
store_place_item = town->preset_items.back();
}
@@ -1201,13 +1201,13 @@ static bool handle_terpal_action(location cur_point, bool option_hit) {
case DRAW_ITEM:
if(k >= scenario.scen_items.size())
break;
if(scenario.scen_items[k].variety == eItemType::NO_ITEM) {
if(scenario.get_item(k).variety == eItemType::NO_ITEM) {
showError("This item has its Variety set to No Item. You can only place items with a Variety set to an actual item type.");
break;
}
overall_mode = MODE_PLACE_ITEM;
mode_count = k;
set_string("Place the item:",scenario.scen_items[mode_count].full_name);
set_string("Place the item:",scenario.get_item(mode_count).full_name);
break;
case DRAW_MONST:
if(k + 1 >= scenario.scen_monsters.size())
@@ -2116,19 +2116,19 @@ bool place_item(location spot_hit,short which_item,bool property,bool always,sho
// odds 0 - 100, with 100 always
if((which_item < 0) || (which_item >= scenario.scen_items.size()))
return true;
if(scenario.scen_items[which_item].variety == eItemType::NO_ITEM)
if(scenario.get_item(which_item).variety == eItemType::NO_ITEM)
return true;
if(get_ran(1,1,100) > odds)
return false;
for(short x = 0; x < town->preset_items.size(); x++)
if(town->preset_items[x].code < 0) {
town->preset_items[x] = {spot_hit, which_item, scenario.scen_items[which_item]};
town->preset_items[x] = {spot_hit, which_item, scenario.get_item(which_item)};
town->preset_items[x].contained = container_there(spot_hit);
town->preset_items[x].property = property;
town->preset_items[x].always_there = always;
return true;
}
town->preset_items.push_back({spot_hit, which_item, scenario.scen_items[which_item]});
town->preset_items.push_back({spot_hit, which_item, scenario.get_item(which_item)});
town->preset_items.back().contained = container_there(spot_hit);
town->preset_items.back().property = property;
town->preset_items.back().always_there = always;
@@ -2439,7 +2439,7 @@ void start_item_editing(bool just_redo_text) {
std::string title;
if(i == scenario.scen_items.size())
title = "Create New Item";
else title = scenario.scen_items[i].full_name;
else title = scenario.get_item(i).full_name;
title = std::to_string(i) + " - " + title;
set_rb(i,RB_ITEM, i, title);
}

View File

@@ -1636,20 +1636,20 @@ static bool edit_item_type_event_filter(cDialog& me, std::string hit, cItem& ite
} else if(hit == "okay") {
save_item_info(me, item);
if(!me.toast(true)) return true;
scenario.scen_items[which] = item;
scenario.get_item(which) = item;
} else if(hit == "prev") {
save_item_info(me, item);
scenario.scen_items[which] = item;
scenario.get_item(which) = item;
which--;
if(which < 0) which = scenario.scen_items.size() - 1;
item = scenario.scen_items[which];
item = scenario.get_item(which);
put_item_info_in_dlog(me, item, which);
} else if(hit == "next") {
save_item_info(me, item);
scenario.scen_items[which] = item;
scenario.get_item(which) = item;
which++;
if(which >= scenario.scen_items.size()) which = 0;
item = scenario.scen_items[which];
item = scenario.get_item(which);
put_item_info_in_dlog(me, item, which);
} else if(hit == "choosepic") {
save_item_info(me, item);
@@ -1746,7 +1746,7 @@ bool edit_item_type(short which) {
using namespace std::placeholders;
if(which == scenario.scen_items.size())
scenario.scen_items.resize(which + 1);
cItem item = scenario.scen_items[which];
cItem item = scenario.get_item(which);
cDialog item_dlg("edit-item");
item_dlg["level"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 50, "Item Level"));
@@ -2310,10 +2310,10 @@ static void edit_shop_item(cDialog& parent, size_t& item, size_t& quantity, bool
item_dlg["chance-prompt"].hide();
}
item_dlg["item"].setText(scenario.scen_items[item].full_name);
item_dlg["item"].setText(scenario.get_item(item).full_name);
item_dlg["choose"].attachClickHandler([&item](cDialog& me, std::string, eKeyMod) -> bool {
item = choose_text(STRT_ITEM, item, &me, "Which item?");
me["item"].setText(scenario.scen_items[item].full_name);
me["item"].setText(scenario.get_item(item).full_name);
return true;
});
@@ -2371,7 +2371,7 @@ static bool edit_shop_entry(cDialog& me, std::string which, cShop& shop) {
case eShopItemType::ITEM:
case eShopItemType::OPT_ITEM:
edit_shop_item(me, entry.index, entry.quantity, entry.type == eShopItemType::OPT_ITEM);
entry.item = scenario.scen_items[entry.index];
entry.item = scenario.get_item(entry.index);
shop.replaceItem(i, entry);
need_string = false;
break;
@@ -2425,13 +2425,14 @@ static bool add_shop_entry(cDialog& me, std::string type, cShop& shop, size_t wh
if(type == "item" || type == "opt") {
size_t which_item = 0, amount = 0;
edit_shop_item(me, which_item, amount, type == "opt");
if(scenario.scen_items[which_item].variety == eItemType::NO_ITEM)
cItem const &item=scenario.get_item(which_item);
if(item.variety == eItemType::NO_ITEM)
return true;
if(scenario.scen_items[which_item].variety == eItemType::GOLD)
if(item.variety == eItemType::GOLD)
return true;
if(type == "item")
shop.addItem(which_item, scenario.scen_items[which_item], amount);
else shop.addItem(which_item, scenario.scen_items[which_item], amount % 1000, amount / 1000);
shop.addItem(which_item, item, amount);
else shop.addItem(which_item, item, amount % 1000, amount / 1000);
} else if(type == "spec") {
cItem item(ITEM_SPECIAL);
size_t amount = 0;

View File

@@ -647,7 +647,7 @@ void set_up_terrain_buttons(bool reset) {
}
break;
case DRAW_ITEM:
pic = scenario.scen_items[i].graphic_num;
pic = scenario.get_item(i).graphic_num;
tiny_to = draw_rect;
frame_rect(mainPtr, tiny_to, sf::Color::Black);
if(pic >= 1000) {
@@ -1052,7 +1052,7 @@ void draw_items() {
if(town->preset_items[i].code >= 0) {
where_draw.x = town->preset_items[i].loc.x - cen_x + 4;
where_draw.y = town->preset_items[i].loc.y - cen_y + 4;
pic_num = scenario.scen_items[town->preset_items[i].code].graphic_num;
pic_num = scenario.get_item(town->preset_items[i].code).graphic_num;
if((where_draw.x >= 0) && (where_draw.x <= 8) &&
(where_draw.y >= 0) && (where_draw.y <= 8)) {
@@ -1242,11 +1242,11 @@ void place_location() {
sout << "Terrain: " << scenario.ter_types[first + i].name;
break;
case DRAW_ITEM:
if(first + i < scenario.scen_items.size())
if(first+i >= 0 && first + i < scenario.scen_items.size())
sout << "Item: " << scenario.scen_items[first + i].full_name;
break;
case DRAW_MONST:
if(first + i + 1 < scenario.scen_monsters.size())
if(first+i >= 0 && first + i + 1 < scenario.scen_monsters.size())
sout << "Monster: " << scenario.scen_monsters[first + i + 1].m_name;
break;
}
@@ -1394,7 +1394,7 @@ void place_location() {
}
}
} else if(overall_mode == MODE_PLACE_ITEM || overall_mode == MODE_PLACE_SAME_ITEM) {
picture_wanted = scenario.scen_items[mode_count].graphic_num;
picture_wanted = scenario.get_item(mode_count).graphic_num;
if(picture_wanted >= 1000) {
Texture source_gworld;
std::tie(source_gworld,source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);

View File

@@ -229,7 +229,7 @@ cTownperson edit_placed_monst_adv(cTownperson initial, short which, cDialog& par
static bool put_placed_item_in_dlog(cDialog& me, const cTown::cItem& item, const short which) {
std::ostringstream loc;
cItem base = scenario.scen_items[item.code];
cItem base = scenario.get_item(item.code);
if(item.ability >= 0 && item.ability <= int(eEnchant::BLESSED) && (base.variety == eItemType::ONE_HANDED || base.variety == eItemType::TWO_HANDED)) {
base.enchant_weapon(eEnchant(item.ability), 0);
}
@@ -284,7 +284,7 @@ static bool get_placed_item_in_dlog(cDialog& me, cTown::cItem& item, const short
return true;
}
eItemType type = scenario.scen_items[item.code].variety;
eItemType type = scenario.get_item(item.code).variety;
if(item.charges == 0 && (type == eItemType::GOLD || type == eItemType::FOOD)) {
showError("You must assign gold or food an amount of at least 1.","",&me);
return false;
@@ -310,7 +310,7 @@ static bool edit_placed_item_type(cDialog& me, cTown::cItem& item, const short w
static bool edit_placed_item_abil(cDialog& me, std::string item_hit, cTown::cItem& item, const short which) {
item.charges = me["charges"].getTextAsNum();
cItem& base = scenario.scen_items[item.code];
cItem& base = scenario.get_item(item.code);
short i = item.ability;
if(item_hit == "abil") { // User entered a number directly
i = me["abil"].getTextAsNum();