diff --git a/src/fileio/fileio_scen.cpp b/src/fileio/fileio_scen.cpp index 6afa2e99..01a252b2 100644 --- a/src/fileio/fileio_scen.cpp +++ b/src/fileio/fileio_scen.cpp @@ -1956,7 +1956,6 @@ void readDialogueFromXml(ticpp::Document&& data, cSpeech& talk, int town_num) { void loadOutMapData(map_data&& data, location which, cScenario& scen) { cOutdoors& out = *scen.outdoors[which.x][which.y]; - int num_towns = 0; for(int x = 0; x < 48; x++) { for(int y = 0; y < 48; y++) { out.terrain[x][y] = data.get(x,y); @@ -1973,11 +1972,7 @@ void loadOutMapData(map_data&& data, location which, cScenario& scen) { case eMapFeature::ENTRANCE_WEST: case eMapFeature::ITEM: case eMapFeature::CREATURE: break; case eMapFeature::TOWN: - out.city_locs.emplace_back(); - out.city_locs[num_towns].x = x; - out.city_locs[num_towns].y = y; - out.city_locs[num_towns].spec = feat.second; - num_towns++; + out.city_locs.push_back({x, y, feat.second}); break; case eMapFeature::SPECIAL_NODE: out.special_locs.push_back({x, y, feat.second}); diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index b3705df9..0ecc6a3f 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -407,7 +407,7 @@ static void handle_pause(bool& did_something, bool& need_redraw) { move_to_zero(pc.status[eStatus::WEBS]); } if(univ.party.in_horse >= 0) { - cVehicle& horse = univ.party.horses[univ.party.in_horse]; + cVehicle& horse = univ.party.get_horse(univ.party.in_horse); if(overall_mode == MODE_OUTDOORS) { horse.which_town = 200; horse.loc = global_to_local(univ.party.out_loc); @@ -422,7 +422,7 @@ static void handle_pause(bool& did_something, bool& need_redraw) { } if(univ.party.in_boat >= 0) { // If you pause on a bridge or other passable terrain, leave boat. - cVehicle& boat = univ.party.boats[univ.party.in_boat]; + cVehicle& boat = univ.party.get_boat(univ.party.in_boat); if(overall_mode == MODE_OUTDOORS && !impassable(univ.out[univ.party.out_loc.x][univ.party.out_loc.y])) { boat.which_town = 200; boat.loc = global_to_local(univ.party.out_loc); @@ -553,9 +553,9 @@ static void handle_move(location destination, bool& did_something, bool& need_re need_redraw = false; i = 8; if(univ.party.in_boat >= 0) - univ.party.boats[univ.party.in_boat].which_town = univ.party.town_num; + univ.party.get_boat(univ.party.in_boat).which_town = univ.party.town_num; if(univ.party.in_horse >= 0) - univ.party.horses[univ.party.in_horse].which_town = univ.party.town_num; + univ.party.get_horse(univ.party.in_horse).which_town = univ.party.town_num; } } } @@ -2792,13 +2792,13 @@ static void run_waterfalls(short mode){ // mode 0 - town, 1 - outdoors pause(8); } if(mode == 0){ - univ.party.boats[univ.party.in_boat].loc = univ.party.town_loc; - univ.party.boats[univ.party.in_boat].which_town = univ.party.town_num; + univ.party.get_boat(univ.party.in_boat).loc = univ.party.town_loc; + univ.party.get_boat(univ.party.in_boat).which_town = univ.party.town_num; }else{ - univ.party.boats[univ.party.in_boat].which_town = 200; - univ.party.boats[univ.party.in_boat].loc = global_to_local(univ.party.out_loc); - univ.party.boats[univ.party.in_boat].sector.x = univ.party.outdoor_corner.x + univ.party.i_w_c.x; - univ.party.boats[univ.party.in_boat].sector.y = univ.party.outdoor_corner.y + univ.party.i_w_c.y; + univ.party.get_boat(univ.party.in_boat).which_town = 200; + univ.party.get_boat(univ.party.in_boat).loc = global_to_local(univ.party.out_loc); + univ.party.get_boat(univ.party.in_boat).sector.x = univ.party.outdoor_corner.x + univ.party.i_w_c.x; + univ.party.get_boat(univ.party.in_boat).sector.y = univ.party.outdoor_corner.y + univ.party.i_w_c.y; } } @@ -2976,10 +2976,10 @@ bool outd_move_party(location destination,bool forced) { run_waterfalls(1); } if(univ.party.in_horse >= 0) { - univ.party.horses[univ.party.in_horse].which_town = 200; - univ.party.horses[univ.party.in_horse].loc = global_to_local(univ.party.out_loc); - univ.party.horses[univ.party.in_horse].sector.x = univ.party.outdoor_corner.x + univ.party.i_w_c.x; - univ.party.horses[univ.party.in_horse].sector.y = univ.party.outdoor_corner.y + univ.party.i_w_c.y; + univ.party.get_horse(univ.party.in_horse).which_town = 200; + univ.party.get_horse(univ.party.in_horse).loc = global_to_local(univ.party.out_loc); + univ.party.get_horse(univ.party.in_horse).sector.x = univ.party.outdoor_corner.x + univ.party.i_w_c.x; + univ.party.get_horse(univ.party.in_horse).sector.y = univ.party.outdoor_corner.y + univ.party.i_w_c.y; } @@ -3105,8 +3105,8 @@ bool town_move_party(location destination,short forced) { run_waterfalls(0); } if(univ.party.in_horse >= 0) { - univ.party.horses[univ.party.in_horse].loc = univ.party.town_loc; - univ.party.horses[univ.party.in_horse].which_town = univ.party.town_num; + univ.party.get_horse(univ.party.in_horse).loc = univ.party.town_loc; + univ.party.get_horse(univ.party.in_horse).which_town = univ.party.town_num; } center = univ.party.town_loc; return true; diff --git a/src/game/boe.graphutil.cpp b/src/game/boe.graphutil.cpp index 50dde52a..fc594577 100644 --- a/src/game/boe.graphutil.cpp +++ b/src/game/boe.graphutil.cpp @@ -285,10 +285,10 @@ void draw_outd_boats(location center) { rectangle source_rect; Texture& vehicle_gworld = *ResMgr::textures.get("vehicle"); - for(auto& boat : univ.party.boats) { + for(auto const &boat : univ.party.boats) { if(!boat.exists) continue; if(boat.which_town != 200) continue; - if(univ.party.in_boat >= 0 && univ.party.boats[univ.party.in_boat] == boat) continue; + if(univ.party.in_boat >= 0 && univ.party.get_boat(univ.party.in_boat) == boat) continue; location loc = local_to_global(boat.loc); if (is_out()) { // we must also check that the sector is ok @@ -304,7 +304,7 @@ void draw_outd_boats(location center) { for(auto& horse : univ.party.horses) { if(!horse.exists) continue; if(horse.which_town != 200) continue; - if(univ.party.in_horse >= 0 && univ.party.horses[univ.party.in_horse] == horse) continue; + if(univ.party.in_horse >= 0 && univ.party.get_horse(univ.party.in_horse) == horse) continue; location loc = local_to_global(horse.loc); if (is_out()) { // we must also check that the sector is ok @@ -324,20 +324,20 @@ void draw_town_boat(location center) { rectangle source_rect; Texture const & vehicle_gworld = *ResMgr::textures.get("vehicle"); - for(auto& boat : univ.party.boats) { + for(auto const &boat : univ.party.boats) { if(!boat.exists) continue; if(boat.which_town != univ.party.town_num) continue; - if(univ.party.in_boat >= 0 && univ.party.boats[univ.party.in_boat] == boat) continue; + if(univ.party.in_boat >= 0 && univ.party.get_boat(univ.party.in_boat) == boat) continue; if(point_onscreen(center, boat.loc) && can_see_light(center, boat.loc, sight_obscurity) < 5 && pt_in_light(center, boat.loc)) { where_draw.x = boat.loc.x - center.x + 4; where_draw.y = boat.loc.y - center.y + 4; Draw_Some_Item(vehicle_gworld, calc_rect(1,0), terrain_screen_gworld, where_draw, 1, 0); } } - for(auto& horse : univ.party.horses) { + for(auto const &horse : univ.party.horses) { if(!horse.exists) continue; if(horse.which_town != univ.party.town_num) continue; - if(univ.party.in_horse >= 0 && univ.party.horses[univ.party.in_horse] == horse) continue; + if(univ.party.in_horse >= 0 && univ.party.get_horse(univ.party.in_horse) == horse) continue; if(point_onscreen(center, horse.loc) && can_see_light(center, horse.loc, sight_obscurity) < 5 && pt_in_light(center, horse.loc)) { where_draw.x = horse.loc.x - center.x + 4; where_draw.y = horse.loc.y - center.y + 4; diff --git a/src/game/boe.party.cpp b/src/game/boe.party.cpp index 7d74e3d3..3ae3acf5 100644 --- a/src/game/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -1352,15 +1352,15 @@ void cast_town_spell(location where) { bool cast_spell_on_space(location where, eSpell spell) { short s1 = 0; - for(size_t i = 0; i < univ.town->special_locs.size(); i++) - if(where == univ.town->special_locs[i]) { - bool need_redraw = false; - // TODO: Is there a way to skip this condition without breaking compatibility? - if(univ.town->specials[univ.town->special_locs[i].spec].type == eSpecType::IF_CONTEXT) - run_special(eSpecCtx::TARGET, eSpecCtxType::TOWN, univ.town->special_locs[i].spec, where, &s1, nullptr, &need_redraw); - if(need_redraw) redraw_terrain(); - return !s1; - } + for(auto const &spec_loc : univ.town->special_locs) { + if(where != spec_loc) continue; + bool need_redraw = false; + // TODO: Is there a way to skip this condition without breaking compatibility? + if(univ.town->get_special(spec_loc.spec).type == eSpecType::IF_CONTEXT) + run_special(eSpecCtx::TARGET, eSpecCtxType::TOWN, spec_loc.spec, where, &s1, nullptr, &need_redraw); + if(need_redraw) redraw_terrain(); + return !s1; + } if(spell == eSpell::RITUAL_SANCTIFY) add_string_to_buf(" Nothing happens."); return true; diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index a5842997..08e2bb32 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -240,14 +240,14 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc, } if((mode == eSpecCtx::TOWN_MOVE || (mode == eSpecCtx::COMBAT_MOVE && which_combat_type == 1)) && can_enter && univ.town.is_special(where_check.x,where_check.y)) { - for(short i = 0; i < univ.town->special_locs.size(); i++) { - if(where_check != univ.town->special_locs[i]) continue; - spec_num = univ.town->special_locs[i].spec; + for(auto const &spec_loc : univ.town->special_locs) { + if(where_check != spec_loc) continue; + spec_num = spec_loc.spec; bool runSpecial = false; if(!is_blocked(where_check)) runSpecial = true; if(ter_special == eTerSpec::CHANGE_WHEN_STEP_ON) runSpecial = true; if(ter_special == eTerSpec::CALL_SPECIAL) runSpecial = true; - if(univ.town->specials[spec_num].type == eSpecType::CANT_ENTER) + if(univ.town->get_special(spec_num).type == eSpecType::CANT_ENTER) runSpecial = true; if(!univ.scenario.is_legacy && univ.party.in_boat >= 0 && terrain.boat_over) runSpecial = true; @@ -2105,21 +2105,15 @@ cSpecial get_node(spec_num_t cur_spec, eSpecCtxType cur_spec_type) { } return univ.scenario.scen_specials[cur_spec]; case eSpecCtxType::OUTDOOR: - if(cur_spec != minmax(0,univ.out->specials.size() - 1,cur_spec)) { + if(cur_spec != minmax(0,univ.out->specials.size() - 1,cur_spec)) showError("The scenario called an outdoor special node out of range."); - return dummy_node; - } - return univ.out->specials[cur_spec]; + return univ.out->get_special(cur_spec); case eSpecCtxType::TOWN: - if (is_out()) { + if (is_out()) showError("The scenario called a town special node but it is not in town."); - return dummy_node; - } - if(cur_spec != minmax(0,univ.town->specials.size() - 1,cur_spec)) { + else if(cur_spec != minmax(0,univ.town->specials.size() - 1,cur_spec)) showError("The scenario called a town special node out of range."); - return dummy_node; - } - return univ.town->specials[cur_spec]; + return univ.town->get_special(cur_spec); } return dummy_node; } @@ -2191,13 +2185,13 @@ void general_spec(const runtime_state& ctx) { check_mess = true; if(spec.ex1a != minmax(0, univ.party.horses.size() - 1, cur_node.ex1a)) showError("Horse out of range."); - else univ.party.horses[cur_node.ex1a].property = (spec.ex2a == 0) ? 1 : 0; + else univ.party.get_horse(cur_node.ex1a).property = (spec.ex2a == 0) ? 1 : 0; break; case eSpecType::CHANGE_BOAT_OWNER: check_mess = true; if(spec.ex1a != minmax(0,univ.party.boats.size() - 1,spec.ex1a)) showError("Boat out of range."); - else univ.party.boats[cur_node.ex1a].property = (spec.ex2a == 0) ? 1 : 0; + else univ.party.get_boat(cur_node.ex1a).property = (spec.ex2a == 0) ? 1 : 0; break; case eSpecType::SET_TOWN_VISIBILITY: check_mess = true; diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 7a162dd3..0b8b4c98 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -364,12 +364,12 @@ void start_town_mode(short which_town, short entry_dir) { univ.party.town_loc = (entry_dir < 9) ? univ.town->start_locs[entry_dir] : town_force_loc; center = univ.party.town_loc; if(univ.party.in_boat >= 0) { - univ.party.boats[univ.party.in_boat].which_town = which_town; - univ.party.boats[univ.party.in_boat].loc = univ.party.town_loc; + univ.party.get_boat(univ.party.in_boat).which_town = which_town; + univ.party.get_boat(univ.party.in_boat).loc = univ.party.town_loc; } if(univ.party.in_horse >= 0) { - univ.party.horses[univ.party.in_horse].which_town = which_town; - univ.party.horses[univ.party.in_horse].loc = univ.party.town_loc; + univ.party.get_horse(univ.party.in_horse).which_town = which_town; + univ.party.get_horse(univ.party.in_horse).loc = univ.party.town_loc; } @@ -1155,18 +1155,15 @@ void erase_out_specials() { void erase_hidden_towns(cOutdoors& sector, int quadrant_x, int quadrant_y) { for(short tile_index = 0; tile_index < sector.city_locs.size(); tile_index++) { - auto city_loc = sector.city_locs[tile_index]; - if(!univ.scenario.is_town_entrance_valid(city_loc) || - !does_location_have_special(sector, city_loc, eTerSpec::TOWN_ENTRANCE) || - !sector.is_on_map(city_loc)) { + auto const &city_loc = sector.city_locs[tile_index]; + if(!univ.scenario.is_town_entrance_valid(city_loc) || !does_location_have_special(sector, city_loc, eTerSpec::TOWN_ENTRANCE)) continue; - } - auto town_pos_x = AREA_MEDIUM * quadrant_x + sector.city_locs[tile_index].x; - auto town_pos_y = AREA_MEDIUM * quadrant_y + sector.city_locs[tile_index].y; - auto spec_pos_x = sector.city_locs[tile_index].x; - auto spec_pos_y = sector.city_locs[tile_index].y; + auto town_pos_x = AREA_MEDIUM * quadrant_x + city_loc.x; + auto town_pos_y = AREA_MEDIUM * quadrant_y + city_loc.y; + auto spec_pos_x = city_loc.x; + auto spec_pos_y = city_loc.y; auto area_index = sector.terrain[spec_pos_x][spec_pos_y]; - if(!univ.scenario.towns[sector.city_locs[tile_index].spec]->can_find) { + if(!univ.scenario.towns[city_loc.spec]->can_find) { univ.out[town_pos_x][town_pos_y] = univ.get_terrain(area_index).flag1; } else { univ.out[town_pos_x][town_pos_y] = area_index; @@ -1176,28 +1173,26 @@ void erase_hidden_towns(cOutdoors& sector, int quadrant_x, int quadrant_y) { void erase_completed_specials(cArea& sector, std::function clear_spot) { for(auto tile_index = 0; tile_index < sector.special_locs.size(); tile_index++) { - if(sector.special_locs[tile_index].spec < 0 || - sector.special_locs[tile_index].spec >= sector.specials.size()) + auto const &tile = sector.special_locs[tile_index]; + if(tile.spec < 0 || tile.spec >= sector.specials.size()) continue; - auto sn = sector.specials[sector.special_locs[tile_index].spec]; + auto sn = sector.specials[tile.spec]; if(univ.party.sd_legit(sn.sd1, sn.sd2) && PSD[sn.sd1][sn.sd2] == SDF_COMPLETE) { - auto completed_special = sector.special_locs[tile_index]; - if(!sector.is_on_map(completed_special)) { + if(!sector.is_on_map(tile)) { beep(); add_string_to_buf("Area corrupt. Problem fixed."); - print_nums(completed_special.x, completed_special.y, tile_index); + print_nums(tile.x, tile.y, tile_index); sector.special_locs[tile_index].spec = -1; } - clear_spot(completed_special); + clear_spot(tile); } } } bool does_location_have_special(cOutdoors& sector, location loc, eTerSpec special) { - auto terrain_index = sector.terrain[loc.x][loc.y]; - return univ.get_terrain(terrain_index).special == special; + return sector.is_on_map(loc) && univ.get_terrain(sector.terrain[loc.x][loc.y]).special == special; } bool is_door(location destination) { diff --git a/src/location.hpp b/src/location.hpp index 4371d6d2..f1bafcfa 100644 --- a/src/location.hpp +++ b/src/location.hpp @@ -113,6 +113,10 @@ struct info_rect_t : public rectangle { info_rect_t(const info_rect_t& other) = default; // Ditto for assignment operator info_rect_t& operator=(const info_rect_t& other) = default; + + static info_rect_t bad() { + return {-1,-1,-1,-1,"Bad Aread Desc"}; + } }; struct sign_loc_t : public location { @@ -125,6 +129,10 @@ struct sign_loc_t : public location { sign_loc_t(const sign_loc_t& other) = default; // Ditto for assignment operator sign_loc_t& operator=(const sign_loc_t& other) = default; + static sign_loc_t bad() + { + return sign_loc_t(-1,-1,"Bad Sign"); + } }; struct spec_loc_t : public location { diff --git a/src/scenario/area.cpp b/src/scenario/area.cpp index 4d9edd69..7395255c 100644 --- a/src/scenario/area.cpp +++ b/src/scenario/area.cpp @@ -7,16 +7,11 @@ #include "area.hpp" -static info_rect_t getBadAreaDesc() -{ - info_rect_t bad_area={-1,-1,-1,-1,"Bad Aread Desc"}; - return bad_area; -} info_rect_t const &cArea::get_area_desc(int num) const { if (num>=0 && num=0 && num=0 && num=0 && num=0 && num=0 && num=0 && item=0 && item=0 && id=0 && quest=0 && quest=0 && item=0 && item=0 && shop=0 && shop= 0 && loc.spec < towns_in_scenario; + return loc.spec >= 0 && loc.spec < towns.size(); } void cScenario::writeTo(std::ostream& file) const { diff --git a/src/scenario/shop.hpp b/src/scenario/shop.hpp index ba3a844d..d4423eac 100644 --- a/src/scenario/shop.hpp +++ b/src/scenario/shop.hpp @@ -97,6 +97,12 @@ public: void takeOne(size_t i); void clearItem(size_t i); void clear(); + static cShop bad() { + cShop badShop; + badShop.setName("Bad Shop"); + badShop.setFace(-3); + return badShop; + } }; std::istream& operator>>(std::istream& in, eShopType& type); diff --git a/src/scenario/special.hpp b/src/scenario/special.hpp index 2f4f0857..560e2132 100644 --- a/src/scenario/special.hpp +++ b/src/scenario/special.hpp @@ -87,6 +87,12 @@ public: cSpecial(); void import_legacy(legacy::special_node_type const & old); void writeTo(std::ostream& file, int n) const; + + static cSpecial bad() { + cSpecial bad_special; + bad_special.pic=-3; + return bad_special; + } }; enum class eSpecCtxType { diff --git a/src/scenario/terrain.hpp b/src/scenario/terrain.hpp index f22ee4dd..5e7f682f 100644 --- a/src/scenario/terrain.hpp +++ b/src/scenario/terrain.hpp @@ -54,6 +54,12 @@ public: static cPictNum get_picture_num_for_terrain(pic_num_t bigPicture); void import_legacy(legacy::terrain_type_type const &old); void writeTo(std::ostream& file) const; + static cTerrain bad() { + cTerrain badTerrain; + badTerrain.picture = -3; + badTerrain.map_pic = -3; + return badTerrain; + } }; #endif diff --git a/src/scenario/town_import.tpp b/src/scenario/town_import.tpp index 9ebbe7e5..3c550968 100644 --- a/src/scenario/town_import.tpp +++ b/src/scenario/town_import.tpp @@ -30,16 +30,12 @@ void cTown::import_legacy(T const & old, int){ the_field.type = SPECIAL_SPOT; the_road.type = SPECIAL_ROAD; // Collect a list of unused special nodes, to be used for fixing specials that could be triggered in a boat. + std::set call_special; + for(auto const &spec : specials) + call_special.insert(spec.jumpto); std::vector unused_special_slots; - for(short i = 0; i < 100; i++) { - if(specials[i].type == eSpecType::NONE && specials[i].jumpto == -1) { - // Also make sure no specials jump to it - bool is_free = true; - for(short j = 0; j < 100; j++) { - if(specials[j].jumpto == i) is_free = false; - } - if(is_free) unused_special_slots.push_back(i); - } + for(short i = 0; i < specials.size(); i++) { + if(specials[i].type == eSpecType::NONE && specials[i].jumpto == -1 && call_special.count(i)==0) unused_special_slots.push_back(i); } for(short i = 0; i < sizes::dim; i++) for(short j = 0; j < sizes::dim; j++) { diff --git a/src/scenario/vehicle.hpp b/src/scenario/vehicle.hpp index 204e30e4..f64ce0f0 100644 --- a/src/scenario/vehicle.hpp +++ b/src/scenario/vehicle.hpp @@ -32,6 +32,13 @@ public: void import_legacy(legacy::boat_record_type const &old); void writeTo(std::ostream& file) const; void readFrom(std::istream& file); + + static cVehicle bad() { + cVehicle bad_vehicle; + bad_vehicle.loc={-1,-1}; + bad_vehicle.exists=false; + return bad_vehicle; + } }; bool operator==(const cVehicle& a, const cVehicle& b); diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index 358863d4..fc48cba1 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -410,7 +410,7 @@ static bool handle_rb_action(location the_point, bool option_hit) { current_terrain->specials.pop_back(); else if(j == size_before) break; - else current_terrain->specials[j] = cSpecial(); + else current_terrain->get_special(j) = cSpecial(); } else { if(j == size_before) current_terrain->specials.emplace_back(); @@ -428,7 +428,7 @@ static bool handle_rb_action(location the_point, bool option_hit) { town->specials.pop_back(); else if(j == size_before) break; - else town->specials[j] = cSpecial(); + else town->get_special(j) = cSpecial(); } else { if(j == size_before) town->specials.emplace_back(); @@ -2159,9 +2159,9 @@ void place_edit_special(location loc) { return; } auto& specials = editing_town ? town->special_locs : current_terrain->special_locs; - for(short i = 0; i < specials.size(); i++) - if(specials[i] == loc && specials[i].spec >= 0) { - edit_spec_enc(specials[i].spec, editing_town ? 2 : 1, nullptr); + for(auto &special : specials) + if(special == loc && special.spec >= 0) { + edit_spec_enc(special.spec, editing_town ? 2 : 1, nullptr); return; } // new special @@ -2185,10 +2185,10 @@ void set_special(location spot_hit) { return; } auto& specials = editing_town ? town->special_locs : current_terrain->special_locs; - for(short x = 0; x < specials.size(); x++) - if(specials[x] == spot_hit && specials[x].spec >= 0) { - int spec = edit_special_num(editing_town ? 2 : 1,specials[x].spec); - if(spec >= 0) specials[x].spec = spec; + for(auto &special : specials) + if(special == spot_hit && special.spec >= 0) { + int spec = edit_special_num(editing_town ? 2 : 1,special.spec); + if(spec >= 0) special.spec = spec; return; } for(short x = 0; x <= specials.size(); x++) { diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index 9ed492ac..9d38e532 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -602,8 +602,8 @@ static bool commit_spec_enc(cDialog& me, std::string item_hit, node_stack_t& edi int mode = edit_stack.top().mode, node = edit_stack.top().which; switch(mode) { case 0: scenario.scen_specials[node] = edit_stack.top().node; break; - case 1: current_terrain->specials[node] = edit_stack.top().node; break; - case 2: town->specials[node] = edit_stack.top().node; break; + case 1: current_terrain->get_special(node) = edit_stack.top().node; break; + case 2: town->get_special(node) = edit_stack.top().node; break; } edit_stack.pop(); if(item_hit == "okay") { @@ -860,9 +860,9 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t& if(mode == 0) node_to_change_to = &scenario.scen_specials[store]; else if(mode == 1) - node_to_change_to = ¤t_terrain->specials[store]; + node_to_change_to = ¤t_terrain->get_special(store); else if(mode == 2) - node_to_change_to = &town->specials[store]; + node_to_change_to = &town->get_special(store); if (node_to_change_to) { if(node_to_change_to->pic < 0) node_to_change_to->pic = 0; @@ -941,7 +941,7 @@ bool edit_spec_enc(short which_node,short mode,cDialog* parent) { node_stack_t edit_stack; if(mode == 0) { - if(which_node >= scenario.scen_specials.size()) { + if(which_node<0 || which_node >= scenario.scen_specials.size()) { showError("That special node does not exist. You can create a new node by setting the field to -1 and trying again.", parent); return false; } @@ -949,7 +949,7 @@ bool edit_spec_enc(short which_node,short mode,cDialog* parent) { scenario.scen_specials[which_node].pic = 0; the_node = scenario.scen_specials[which_node]; } else if(mode == 1) { - if(which_node >= current_terrain->specials.size()) { + if(which_node<0 || which_node >= current_terrain->specials.size()) { showError("That special node does not exist. You can create a new node by setting the field to -1 and trying again.", parent); return false; } @@ -957,7 +957,7 @@ bool edit_spec_enc(short which_node,short mode,cDialog* parent) { current_terrain->specials[which_node].pic = 0; the_node = current_terrain->specials[which_node]; } else if(mode == 2) { - if(which_node >= town->specials.size()) { + if(which_node<0 || which_node >= town->specials.size()) { showError("That special node does not exist. You can create a new node by setting the field to -1 and trying again.", parent); return false; } diff --git a/src/universe/party.cpp b/src/universe/party.cpp index 9236d552..07be316c 100644 --- a/src/universe/party.cpp +++ b/src/universe/party.cpp @@ -195,6 +195,33 @@ void cParty::swap(cParty& other) { } } +cVehicle &cParty::get_boat(int id) { + if (id>=0 && id=0 && id=0 && id=0 && id> i; - if(i >= boats.size()) + if(i >= boats.size() && i<1000) boats.resize(i + 1); - boats[i].exists = true; - boats[i].readFrom(bin); + get_boat(i).exists = true; + get_boat(i).readFrom(bin); } else if(cur == "HORSE") { int i; bin >> i; - if(i >= horses.size()) + if(i >= horses.size() && i<1000) horses.resize(i + 1); - horses[i].exists = true; - horses[i].readFrom(bin); + get_horse(i).exists = true; + get_horse(i).readFrom(bin); } else if(cur == "MAGICSTORE") { int i,j; bin >> i >> j; diff --git a/src/universe/party.hpp b/src/universe/party.hpp index 4e853080..1b3b2e41 100644 --- a/src/universe/party.hpp +++ b/src/universe/party.hpp @@ -217,6 +217,11 @@ public: typedef std::vector::iterator encIter; typedef std::vector::iterator journalIter; typedef std::vector::iterator talkIter; + cVehicle &get_boat(int id); + cVehicle const &get_boat(int id) const; + cVehicle &get_horse(int id); + cVehicle const &get_horse(int id) const; + cParty(ePartyPreset party_preset = PARTY_DEFAULT); ~cParty(); // Copy-and-swap