vector2d: try to protect the access against bad index, to be improved...
+ details rewriting
This commit is contained in:
@@ -727,8 +727,8 @@ location find_clear_spot(location from_where,short mode) {
|
|||||||
if(!loc_off_act_area(loc) && !is_blocked(loc)
|
if(!loc_off_act_area(loc) && !is_blocked(loc)
|
||||||
&& can_see_light(from_where,loc,combat_obscurity) == 0
|
&& can_see_light(from_where,loc,combat_obscurity) == 0
|
||||||
&& (!is_combat() || univ.target_there(loc,TARG_PC) == nullptr)
|
&& (!is_combat() || univ.target_there(loc,TARG_PC) == nullptr)
|
||||||
&& (!(is_town()) || (loc != univ.party.town_loc))
|
&& (!is_town() || loc != univ.party.town_loc)
|
||||||
&& (!(univ.town.fields[loc.x][loc.y] & blocking_fields))) {
|
&& (!is_town() || !(univ.town.fields[loc.x][loc.y] & blocking_fields))) {
|
||||||
if((mode == 0) || ((mode == 1) && (adjacent(from_where,loc))))
|
if((mode == 0) || ((mode == 1) && (adjacent(from_where,loc))))
|
||||||
return loc;
|
return loc;
|
||||||
else store_loc = loc;
|
else store_loc = loc;
|
||||||
|
@@ -196,19 +196,19 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
|
|||||||
if(mode == eSpecCtx::OUT_MOVE) {
|
if(mode == eSpecCtx::OUT_MOVE) {
|
||||||
out_where = global_to_local(where_check);
|
out_where = global_to_local(where_check);
|
||||||
|
|
||||||
for(short i = 0; i < univ.out->special_locs.size(); i++)
|
for(short i = 0; i < univ.out->special_locs.size(); i++) {
|
||||||
if(out_where == univ.out->special_locs[i]) {
|
if(out_where != univ.out->special_locs[i]) continue;
|
||||||
spec_num = univ.out->special_locs[i].spec;
|
spec_num = univ.out->special_locs[i].spec;
|
||||||
// call special
|
// call special
|
||||||
run_special(mode, eSpecCtxType::OUTDOOR, spec_num, out_where, &s1, &s2);
|
run_special(mode, eSpecCtxType::OUTDOOR, spec_num, out_where, &s1, &s2);
|
||||||
if(s1 > 0)
|
if(s1 > 0)
|
||||||
can_enter = false;
|
can_enter = false;
|
||||||
else if(s2 > 0)
|
else if(s2 > 0)
|
||||||
*forced = true;
|
*forced = true;
|
||||||
erase_out_specials();
|
erase_out_specials();
|
||||||
put_pc_screen();
|
put_pc_screen();
|
||||||
put_item_screen(stat_window);
|
put_item_screen(stat_window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_combat()) {
|
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))
|
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)) {
|
&& can_enter && univ.town.is_special(where_check.x,where_check.y)) {
|
||||||
for(short i = 0; i < univ.town->special_locs.size(); i++)
|
for(short i = 0; i < univ.town->special_locs.size(); i++) {
|
||||||
if(where_check == univ.town->special_locs[i]) {
|
if(where_check != univ.town->special_locs[i]) continue;
|
||||||
spec_num = univ.town->special_locs[i].spec;
|
spec_num = univ.town->special_locs[i].spec;
|
||||||
bool runSpecial = false;
|
bool runSpecial = false;
|
||||||
if(!is_blocked(where_check)) runSpecial = true;
|
if(!is_blocked(where_check)) runSpecial = true;
|
||||||
if(ter_special == eTerSpec::CHANGE_WHEN_STEP_ON) runSpecial = true;
|
if(ter_special == eTerSpec::CHANGE_WHEN_STEP_ON) runSpecial = true;
|
||||||
if(ter_special == eTerSpec::CALL_SPECIAL) runSpecial = true;
|
if(ter_special == eTerSpec::CALL_SPECIAL) runSpecial = true;
|
||||||
if(univ.town->specials[spec_num].type == eSpecType::CANT_ENTER)
|
if(univ.town->specials[spec_num].type == eSpecType::CANT_ENTER)
|
||||||
runSpecial = true;
|
runSpecial = true;
|
||||||
if(!univ.scenario.is_legacy && univ.party.in_boat >= 0 && terrain.boat_over)
|
if(!univ.scenario.is_legacy && univ.party.in_boat >= 0 && terrain.boat_over)
|
||||||
runSpecial = true;
|
runSpecial = true;
|
||||||
if(runSpecial) {
|
if(runSpecial) {
|
||||||
give_help(54,0);
|
give_help(54,0);
|
||||||
run_special(mode, eSpecCtxType::TOWN, spec_num, where_check, &s1, &s2);
|
run_special(mode, eSpecCtxType::TOWN, spec_num, where_check, &s1, &s2);
|
||||||
if(s1 > 0)
|
if(s1 > 0)
|
||||||
can_enter = false;
|
can_enter = false;
|
||||||
else if(s2 > 0)
|
else if(s2 > 0)
|
||||||
*forced = true;
|
*forced = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
put_pc_screen();
|
put_pc_screen();
|
||||||
put_item_screen(stat_window);
|
put_item_screen(stat_window);
|
||||||
}
|
}
|
||||||
|
@@ -837,15 +837,18 @@ void create_out_combat_terrain(short ter_type,short num_walls,bool is_road) {
|
|||||||
univ.town.fields[i][j] = 0;
|
univ.town.fields[i][j] = 0;
|
||||||
if((j <= 8) || (j >= 35) || (i <= 8) || (i >= 35))
|
if((j <= 8) || (j >= 35) || (i <= 8) || (i >= 35))
|
||||||
univ.town->terrain(i,j) = 90;
|
univ.town->terrain(i,j) = 90;
|
||||||
else univ.town->terrain(i,j) = ter_base[arena];
|
else
|
||||||
}
|
univ.town->terrain(i,j) = ter_base[arena];
|
||||||
for(short i = 0; i < 48; i++)
|
if (univ.town->terrain(i,j) == 90)
|
||||||
for(short j = 0; j < 48; j++)
|
continue;
|
||||||
for(short k = 0; k < 5; k++)
|
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]))
|
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(i,j) = terrain_odds[arena][k * 2];
|
||||||
|
break;
|
||||||
univ.town->terrain(0,0) = ter_base[arena];
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
univ.town->terrain(0,0) = ter_base[arena]; // to force an exit position?
|
||||||
|
|
||||||
bool is_bridge = (arena == 3 || arena == 4);
|
bool is_bridge = (arena == 3 || arena == 4);
|
||||||
|
|
||||||
|
@@ -48,6 +48,16 @@ void cScenario::destroy_terrain() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cOutdoors *cScenario::get_bad_outdoor()
|
||||||
|
{
|
||||||
|
static std::shared_ptr<cOutdoors> badOutdoor;
|
||||||
|
if (!badOutdoor)
|
||||||
|
badOutdoor=std::make_shared<cOutdoors>(*this);
|
||||||
|
badOutdoor->reattach(*this);
|
||||||
|
badOutdoor->name="Bad Outdoor";
|
||||||
|
return badOutdoor.get();
|
||||||
|
}
|
||||||
|
|
||||||
cScenario::cScenario() {
|
cScenario::cScenario() {
|
||||||
std::string temp_str;
|
std::string temp_str;
|
||||||
|
|
||||||
@@ -68,6 +78,7 @@ cScenario::cScenario() {
|
|||||||
bg_fight = 4;
|
bg_fight = 4;
|
||||||
bg_town = 13;
|
bg_town = 13;
|
||||||
bg_dungeon = 9;
|
bg_dungeon = 9;
|
||||||
|
outdoors.set_get_default_function([this](){return get_bad_outdoor();});
|
||||||
// ASAN used but unset
|
// ASAN used but unset
|
||||||
is_legacy = false;
|
is_legacy = false;
|
||||||
for(short i = 0; i < town_mods.size(); i++) {
|
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 i = 0; i < outdoors.width(); i++)
|
||||||
for(size_t j = 0; j < outdoors.height(); j++)
|
for(size_t j = 0; j < outdoors.height(); j++)
|
||||||
outdoors[i][j] = new cOutdoors(*other.outdoors[i][j]);
|
outdoors[i][j] = new cOutdoors(*other.outdoors[i][j]);
|
||||||
|
outdoors.set_get_default_function([this](){return get_bad_outdoor();});
|
||||||
}
|
}
|
||||||
|
|
||||||
cScenario::cScenario(cScenario&& other) {
|
cScenario::cScenario(cScenario&& other) {
|
||||||
|
@@ -132,6 +132,9 @@ public:
|
|||||||
void reset_version();
|
void reset_version();
|
||||||
explicit cScenario();
|
explicit cScenario();
|
||||||
~cScenario();
|
~cScenario();
|
||||||
|
|
||||||
|
cOutdoors *get_bad_outdoor();
|
||||||
|
|
||||||
// Copy-and-swap
|
// Copy-and-swap
|
||||||
void swap(cScenario& other);
|
void swap(cScenario& other);
|
||||||
cScenario(const cScenario& other);
|
cScenario(const cScenario& other);
|
||||||
|
@@ -85,7 +85,7 @@ void cTown::import_legacy(T const & old, int){
|
|||||||
// Try to fix specials that could be triggered while in a boat
|
// 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.)
|
// (Boats never triggered specials in the old BoE, so we probably don't want them to trigger.)
|
||||||
int found_spec = -1;
|
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) {
|
if(i == special_locs[k].x && j == special_locs[k].y) {
|
||||||
found_spec = k;
|
found_spec = k;
|
||||||
break;
|
break;
|
||||||
|
@@ -26,7 +26,6 @@ void set_string(std::string string,std::string string2);
|
|||||||
bool is_special(short i,short j);
|
bool is_special(short i,short j);
|
||||||
void take_special(short i,short j);
|
void take_special(short i,short j);
|
||||||
void make_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);
|
bool is_field_type(short i,short j,eFieldType field_type);
|
||||||
void make_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);
|
void take_field_type(short i,short j,eFieldType field_type);
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
// Tried using boost::multi_array, but it kept causing weird issues, so I decided to make my own.
|
// 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)
|
// TODO: Fill out missing members (should have equivalents for most of the stuff in std::vector)
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template<typename Type, typename Alloc = std::allocator<Type>> class vector2d {
|
template<typename Type, typename Alloc = std::allocator<Type>> class vector2d {
|
||||||
@@ -21,6 +22,7 @@ template<typename Type, typename Alloc = std::allocator<Type>> class vector2d {
|
|||||||
friend class const_col_ref;
|
friend class const_col_ref;
|
||||||
std::vector<Type, Alloc> data;
|
std::vector<Type, Alloc> data;
|
||||||
size_t w, h;
|
size_t w, h;
|
||||||
|
std::function<Type()> get_default_value_function=nullptr;
|
||||||
public:
|
public:
|
||||||
using value_type = Type;
|
using value_type = Type;
|
||||||
class row_ref {
|
class row_ref {
|
||||||
@@ -30,10 +32,14 @@ public:
|
|||||||
row_ref(vector2d<Type, Alloc>& ref, size_t row) : ref(ref), y(row) {}
|
row_ref(vector2d<Type, Alloc>& ref, size_t row) : ref(ref), y(row) {}
|
||||||
public:
|
public:
|
||||||
Type& operator[](size_t x) {
|
Type& operator[](size_t x) {
|
||||||
return ref.data[ref.w * y + x];
|
if (x<ref.w)
|
||||||
|
return ref.data[ref.w * y + x];
|
||||||
|
return ref.get_bad_value();
|
||||||
}
|
}
|
||||||
const Type& operator[](size_t x) const {
|
const Type& operator[](size_t x) const {
|
||||||
return ref.data[ref.w * y + x];
|
if (x<ref.w)
|
||||||
|
return ref.data[ref.w * y + x];
|
||||||
|
return ref.get_bad_value();
|
||||||
}
|
}
|
||||||
row_ref operator=(row_ref&& other) {
|
row_ref operator=(row_ref&& other) {
|
||||||
row_ref& me = *this;
|
row_ref& me = *this;
|
||||||
@@ -60,10 +66,14 @@ public:
|
|||||||
col_ref(vector2d<Type, Alloc>& ref, size_t col) : ref(ref), x(col) {}
|
col_ref(vector2d<Type, Alloc>& ref, size_t col) : ref(ref), x(col) {}
|
||||||
public:
|
public:
|
||||||
Type& operator[](size_t y) {
|
Type& operator[](size_t y) {
|
||||||
return ref.data[ref.w * y + x];
|
if (y<ref.h)
|
||||||
|
return ref.data[ref.w * y + x];
|
||||||
|
return ref.get_bad_value();
|
||||||
}
|
}
|
||||||
const Type& operator[](size_t y) const {
|
const Type& operator[](size_t y) const {
|
||||||
return ref.data[ref.w * y + x];
|
if (y<ref.h)
|
||||||
|
return ref.data[ref.w * y + x];
|
||||||
|
return ref.get_bad_value();
|
||||||
}
|
}
|
||||||
col_ref operator=(col_ref&& other) {
|
col_ref operator=(col_ref&& other) {
|
||||||
col_ref& me = *this;
|
col_ref& me = *this;
|
||||||
@@ -90,7 +100,9 @@ public:
|
|||||||
const_row_ref(const vector2d<Type, Alloc>& ref, size_t row) : ref(ref), y(row) {}
|
const_row_ref(const vector2d<Type, Alloc>& ref, size_t row) : ref(ref), y(row) {}
|
||||||
public:
|
public:
|
||||||
const Type& operator[](size_t x) const {
|
const Type& operator[](size_t x) const {
|
||||||
return ref.data[ref.w * y + x];
|
if (x<ref.w)
|
||||||
|
return ref.data[ref.w * y + x];
|
||||||
|
return ref.get_bad_value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class const_col_ref {
|
class const_col_ref {
|
||||||
@@ -100,32 +112,50 @@ public:
|
|||||||
const_col_ref(const vector2d<Type, Alloc>& ref, size_t col) : ref(ref), x(col) {}
|
const_col_ref(const vector2d<Type, Alloc>& ref, size_t col) : ref(ref), x(col) {}
|
||||||
public:
|
public:
|
||||||
const Type& operator[](size_t y) const {
|
const Type& operator[](size_t y) const {
|
||||||
return ref.data[ref.w * y + x];
|
if (y<ref.h)
|
||||||
|
return ref.data[ref.w * y + x];
|
||||||
|
return ref.get_bad_value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
col_ref operator[](size_t x) {
|
col_ref operator[](size_t x) {
|
||||||
return col_ref(*this, x);
|
if (x<w)
|
||||||
|
return col_ref(*this, x);
|
||||||
|
return get_bad_vector()[0];
|
||||||
}
|
}
|
||||||
const_col_ref operator[](size_t x) const {
|
const_col_ref operator[](size_t x) const {
|
||||||
return const_col_ref(*this, x);
|
if (x<w)
|
||||||
|
return const_col_ref(*this, x);
|
||||||
|
return get_bad_const_vector()[0];
|
||||||
}
|
}
|
||||||
col_ref col(size_t x) {
|
col_ref col(size_t x) {
|
||||||
return col_ref(*this, x);
|
if (x<w)
|
||||||
|
return col_ref(*this, x);
|
||||||
|
return get_bad_vector()[0];
|
||||||
}
|
}
|
||||||
const_col_ref col(size_t x) const {
|
const_col_ref col(size_t x) const {
|
||||||
return const_col_ref(*this, x);
|
if (x<w)
|
||||||
|
return const_col_ref(*this, x);
|
||||||
|
return get_bad_const_vector()[0];
|
||||||
}
|
}
|
||||||
row_ref row(size_t x) {
|
row_ref row(size_t y) {
|
||||||
return row_ref(*this, x);
|
if (y<h)
|
||||||
|
return row_ref(*this, y);
|
||||||
|
return get_bad_vector().row(0);
|
||||||
}
|
}
|
||||||
const_row_ref row(size_t x) const {
|
const_row_ref row(size_t y) const {
|
||||||
return const_row_ref(*this, x);
|
if (y<h)
|
||||||
|
return const_row_ref(*this, y);
|
||||||
|
return get_bad_const_vector().row(0);
|
||||||
}
|
}
|
||||||
Type& operator()(size_t x, size_t y) {
|
Type& operator()(size_t x, size_t y) {
|
||||||
return (*this)[x][y];
|
if (x<w && y<h)
|
||||||
|
return (*this)[x][y];
|
||||||
|
return get_bad_value();
|
||||||
}
|
}
|
||||||
const Type& operator()(size_t x, size_t y) const {
|
const Type& operator()(size_t x, size_t y) const {
|
||||||
return (*this)[x][y];
|
if (x<w && y<h)
|
||||||
|
return (*this)[x][y];
|
||||||
|
return get_bad_value();
|
||||||
}
|
}
|
||||||
size_t width() const {
|
size_t width() const {
|
||||||
return w;
|
return w;
|
||||||
@@ -173,6 +203,32 @@ public:
|
|||||||
vector2d(size_t w, size_t h) : w(w), h(h) {
|
vector2d(size_t w, size_t h) : w(w), h(h) {
|
||||||
resize(w,h);
|
resize(w,h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type &get_bad_value() {
|
||||||
|
static Type badValue;
|
||||||
|
badValue=get_default_value_function ? get_default_value_function() : Type(-1);
|
||||||
|
return badValue;
|
||||||
|
}
|
||||||
|
const Type &get_bad_value() const {
|
||||||
|
static Type badValue;
|
||||||
|
badValue = get_default_value_function ? get_default_value_function() : Type(-1);
|
||||||
|
return badValue;
|
||||||
|
}
|
||||||
|
vector2d &get_bad_vector() {
|
||||||
|
static vector2d bad_vector(1,1);
|
||||||
|
bad_vector.data[0]=get_bad_value();
|
||||||
|
bad_vector.set_get_default_function(get_default_value_function);
|
||||||
|
return bad_vector;
|
||||||
|
}
|
||||||
|
vector2d const &get_bad_const_vector() const {
|
||||||
|
static vector2d bad_vector(1,1);
|
||||||
|
bad_vector.data[0]=get_bad_value();
|
||||||
|
bad_vector.set_get_default_function(get_default_value_function);
|
||||||
|
return bad_vector;
|
||||||
|
}
|
||||||
|
void set_get_default_function(std::function<Type()> const &func) {
|
||||||
|
get_default_value_function=func;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user