diff --git a/src/game/boe.monster.cpp b/src/game/boe.monster.cpp index 9e74b555..ecd88b0d 100644 --- a/src/game/boe.monster.cpp +++ b/src/game/boe.monster.cpp @@ -727,8 +727,8 @@ location find_clear_spot(location from_where,short mode) { if(!loc_off_act_area(loc) && !is_blocked(loc) && can_see_light(from_where,loc,combat_obscurity) == 0 && (!is_combat() || univ.target_there(loc,TARG_PC) == nullptr) - && (!(is_town()) || (loc != univ.party.town_loc)) - && (!(univ.town.fields[loc.x][loc.y] & blocking_fields))) { + && (!is_town() || loc != univ.party.town_loc) + && (!is_town() || !(univ.town.fields[loc.x][loc.y] & blocking_fields))) { if((mode == 0) || ((mode == 1) && (adjacent(from_where,loc)))) return loc; else store_loc = loc; diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index ceb2cdf5..a5842997 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -196,19 +196,19 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc, if(mode == eSpecCtx::OUT_MOVE) { out_where = global_to_local(where_check); - for(short i = 0; i < univ.out->special_locs.size(); i++) - if(out_where == univ.out->special_locs[i]) { - spec_num = univ.out->special_locs[i].spec; - // call special - run_special(mode, eSpecCtxType::OUTDOOR, spec_num, out_where, &s1, &s2); - if(s1 > 0) - can_enter = false; - else if(s2 > 0) - *forced = true; - erase_out_specials(); - put_pc_screen(); - put_item_screen(stat_window); - } + for(short i = 0; i < univ.out->special_locs.size(); i++) { + if(out_where != univ.out->special_locs[i]) continue; + spec_num = univ.out->special_locs[i].spec; + // call special + run_special(mode, eSpecCtxType::OUTDOOR, spec_num, out_where, &s1, &s2); + if(s1 > 0) + can_enter = false; + else if(s2 > 0) + *forced = true; + erase_out_specials(); + put_pc_screen(); + put_item_screen(stat_window); + } } if (is_combat()) { @@ -240,26 +240,26 @@ 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]) { - spec_num = univ.town->special_locs[i].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) - runSpecial = true; - if(!univ.scenario.is_legacy && univ.party.in_boat >= 0 && terrain.boat_over) - runSpecial = true; - if(runSpecial) { - give_help(54,0); - run_special(mode, eSpecCtxType::TOWN, spec_num, where_check, &s1, &s2); - if(s1 > 0) - can_enter = false; - else if(s2 > 0) - *forced = true; - } + 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; + 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) + runSpecial = true; + if(!univ.scenario.is_legacy && univ.party.in_boat >= 0 && terrain.boat_over) + runSpecial = true; + if(runSpecial) { + give_help(54,0); + run_special(mode, eSpecCtxType::TOWN, spec_num, where_check, &s1, &s2); + if(s1 > 0) + can_enter = false; + else if(s2 > 0) + *forced = true; } + } put_pc_screen(); put_item_screen(stat_window); } diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 6db6ddbe..7a162dd3 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -837,15 +837,18 @@ void create_out_combat_terrain(short ter_type,short num_walls,bool is_road) { univ.town.fields[i][j] = 0; if((j <= 8) || (j >= 35) || (i <= 8) || (i >= 35)) univ.town->terrain(i,j) = 90; - else univ.town->terrain(i,j) = ter_base[arena]; - } - for(short i = 0; i < 48; i++) - for(short j = 0; j < 48; j++) - for(short k = 0; k < 5; k++) - if((univ.town->terrain(i,j) != 90) && (get_ran(1,1,1000) < terrain_odds[arena][k * 2 + 1])) + else + univ.town->terrain(i,j) = ter_base[arena]; + if (univ.town->terrain(i,j) == 90) + continue; + for(short k = 0; k < 5; k++) { + if(get_ran(1,1,1000) < terrain_odds[arena][k * 2 + 1]) { univ.town->terrain(i,j) = terrain_odds[arena][k * 2]; - - univ.town->terrain(0,0) = ter_base[arena]; + break; + } + } + } + univ.town->terrain(0,0) = ter_base[arena]; // to force an exit position? bool is_bridge = (arena == 3 || arena == 4); diff --git a/src/scenario/scenario.cpp b/src/scenario/scenario.cpp index aed8e51c..a6f09745e 100644 --- a/src/scenario/scenario.cpp +++ b/src/scenario/scenario.cpp @@ -48,6 +48,16 @@ void cScenario::destroy_terrain() { } } +cOutdoors *cScenario::get_bad_outdoor() +{ + static std::shared_ptr badOutdoor; + if (!badOutdoor) + badOutdoor=std::make_shared(*this); + badOutdoor->reattach(*this); + badOutdoor->name="Bad Outdoor"; + return badOutdoor.get(); +} + cScenario::cScenario() { std::string temp_str; @@ -68,6 +78,7 @@ cScenario::cScenario() { bg_fight = 4; bg_town = 13; bg_dungeon = 9; + outdoors.set_get_default_function([this](){return get_bad_outdoor();}); // ASAN used but unset is_legacy = false; for(short i = 0; i < town_mods.size(); i++) { @@ -143,6 +154,7 @@ cScenario::cScenario(const cScenario& other) for(size_t i = 0; i < outdoors.width(); i++) for(size_t j = 0; j < outdoors.height(); j++) outdoors[i][j] = new cOutdoors(*other.outdoors[i][j]); + outdoors.set_get_default_function([this](){return get_bad_outdoor();}); } cScenario::cScenario(cScenario&& other) { diff --git a/src/scenario/scenario.hpp b/src/scenario/scenario.hpp index a35e23f5..a3d28239 100644 --- a/src/scenario/scenario.hpp +++ b/src/scenario/scenario.hpp @@ -132,6 +132,9 @@ public: void reset_version(); explicit cScenario(); ~cScenario(); + + cOutdoors *get_bad_outdoor(); + // Copy-and-swap void swap(cScenario& other); cScenario(const cScenario& other); diff --git a/src/scenario/town_import.tpp b/src/scenario/town_import.tpp index d5673e12..9ebbe7e5 100644 --- a/src/scenario/town_import.tpp +++ b/src/scenario/town_import.tpp @@ -85,7 +85,7 @@ void cTown::import_legacy(T const & old, int){ // Try to fix specials that could be triggered while in a boat // (Boats never triggered specials in the old BoE, so we probably don't want them to trigger.) int found_spec = -1; - for(int k = 0; k < 50; k++) { + for(int k = 0; k < special_locs.size(); k++) { if(i == special_locs[k].x && j == special_locs[k].y) { found_spec = k; break; diff --git a/src/scenedit/scen.graphics.hpp b/src/scenedit/scen.graphics.hpp index b5345480..eac83c27 100644 --- a/src/scenedit/scen.graphics.hpp +++ b/src/scenedit/scen.graphics.hpp @@ -26,7 +26,6 @@ void set_string(std::string string,std::string string2); bool is_special(short i,short j); void take_special(short i,short j); void make_special(short i,short j); -void sort_specials(); bool is_field_type(short i,short j,eFieldType field_type); void make_field_type(short i,short j,eFieldType field_type); void take_field_type(short i,short j,eFieldType field_type); diff --git a/src/tools/vector2d.hpp b/src/tools/vector2d.hpp index 6cc4f96f..88326ec3 100644 --- a/src/tools/vector2d.hpp +++ b/src/tools/vector2d.hpp @@ -12,6 +12,7 @@ // Tried using boost::multi_array, but it kept causing weird issues, so I decided to make my own. // TODO: Fill out missing members (should have equivalents for most of the stuff in std::vector) +#include #include template> class vector2d { @@ -21,6 +22,7 @@ template> class vector2d { friend class const_col_ref; std::vector data; size_t w, h; + std::function get_default_value_function=nullptr; public: using value_type = Type; class row_ref { @@ -30,10 +32,14 @@ public: row_ref(vector2d& ref, size_t row) : ref(ref), y(row) {} public: Type& operator[](size_t x) { - return ref.data[ref.w * y + x]; + if (x& ref, size_t col) : ref(ref), x(col) {} public: Type& operator[](size_t y) { - return ref.data[ref.w * y + x]; + if (y& ref, size_t row) : ref(ref), y(row) {} public: const Type& operator[](size_t x) const { - return ref.data[ref.w * y + x]; + if (x& ref, size_t col) : ref(ref), x(col) {} public: const Type& operator[](size_t y) const { - return ref.data[ref.w * y + x]; + if (y const &func) { + get_default_value_function=func; + } }; #endif