From b11e934162f1006ec65c18f0963f93f3fc3c5059 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Mon, 2 Feb 2015 11:35:18 -0500 Subject: [PATCH] Rewrite automatic trim placement to use the generalized attributes of the terrain spaces --- src/boe.graphics.cpp | 15 +- src/boe.graphics.h | 3 - src/classes/scenario.cpp | 24 + src/classes/scenario.h | 4 + src/classes/terrain.cpp | 14 +- src/classes/terrain.h | 2 +- src/scenedit/scen.actions.cpp | 1151 ++++----------------------------- src/scenedit/scen.actions.h | 18 - 8 files changed, 156 insertions(+), 1075 deletions(-) diff --git a/src/boe.graphics.cpp b/src/boe.graphics.cpp index eb81184d..045c6fce 100644 --- a/src/boe.graphics.cpp +++ b/src/boe.graphics.cpp @@ -761,17 +761,6 @@ bool is_nature(short x, short y, unsigned short ground_t) { return ground_t == univ.scenario.ter_types[ter_type].ground_type; } -ter_num_t get_ground_from_ter(ter_num_t ter){ - return get_ter_from_ground(univ.scenario.ter_types[ter].ground_type); -} - -ter_num_t get_ter_from_ground(unsigned char ground){ - for(int i = 0; i < 256; i++) - if(univ.scenario.ter_types[i].ground_type == ground) - return i; - return 0; -} - std::vector forcecage_locs; //mode ... if 1, don't place on screen after redoing @@ -904,7 +893,7 @@ void draw_terrain(short mode) { if(trim == eTrimType::WALKWAY){ int trim = -1; unsigned short ground_t = univ.scenario.ter_types[spec_terrain].trim_ter; - ter_num_t ground_ter = get_ter_from_ground(ground_t); + ter_num_t ground_ter = univ.scenario.get_ter_from_ground(ground_t); if(!loc_off_act_area(where_draw)) { if(is_nature(where_draw.x - 1,where_draw.y,ground_t)){ // check left if(is_nature(where_draw.x,where_draw.y - 1,ground_t)){ // check up @@ -941,7 +930,7 @@ void draw_terrain(short mode) { }else if(spec_terrain == 65535) { draw_one_terrain_spot(q,r,-1); }else{ - current_ground = get_ground_from_ter(spec_terrain); + current_ground = univ.scenario.get_ground_from_ter(spec_terrain); draw_one_terrain_spot(q,r,spec_terrain); } } diff --git a/src/boe.graphics.h b/src/boe.graphics.h index a20aa14a..ec239555 100644 --- a/src/boe.graphics.h +++ b/src/boe.graphics.h @@ -58,9 +58,6 @@ void put_dialog_graphic(short graphic_num,short spec_g,rectangle draw_rect); void draw_startup_stats(); void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter); -ter_num_t get_ground_from_ter(ter_num_t ter); -ter_num_t get_ter_from_ground(unsigned char ground); - void draw_startup_anim(bool advance); #endif diff --git a/src/classes/scenario.cpp b/src/classes/scenario.cpp index 3241b1e5..fbec19d0 100644 --- a/src/classes/scenario.cpp +++ b/src/classes/scenario.cpp @@ -191,3 +191,27 @@ std::string cScenario::format_ed_version() { std::string cScenario::format_scen_version() { return format_version(format.ver); } + +ter_num_t cScenario::get_ground_from_ter(ter_num_t ter){ + return get_ter_from_ground(ter_types[ter].ground_type); +} + +ter_num_t cScenario::get_ter_from_ground(unsigned short ground){ + for(int i = 0; i < ter_types.size(); i++) + if(ter_types[i].ground_type == ground) + return i; + return 0; +} + +ter_num_t cScenario::get_trim_terrain(unsigned short ground, unsigned short trim_g, eTrimType trim) { + for(int i = 0; i < ter_types.size(); i++) { + if(ter_types[i].ground_type != ground) + continue; + if(ter_types[i].trim_ter != trim_g) + continue; + if(ter_types[i].trim_type != trim) + continue; + return i; + } + return 90; +} diff --git a/src/classes/scenario.h b/src/classes/scenario.h index ad79cf62..e9abcdd2 100644 --- a/src/classes/scenario.h +++ b/src/classes/scenario.h @@ -108,6 +108,10 @@ public: std::string format_scen_version(); std::string format_ed_version(); + ter_num_t get_ground_from_ter(ter_num_t ter); + ter_num_t get_ter_from_ground(unsigned short ground); + ter_num_t get_trim_terrain(unsigned short ground, unsigned short trim_g, eTrimType trim); + cScenario& operator=(cScenario&& other); cScenario(cScenario&) = delete; explicit cScenario(bool init_strings = false); diff --git a/src/classes/terrain.cpp b/src/classes/terrain.cpp index 05ff0b6a..0740745d 100644 --- a/src/classes/terrain.cpp +++ b/src/classes/terrain.cpp @@ -68,22 +68,22 @@ void cTerrain::append(legacy::terrain_type_type& old){ 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10,11, 12,13,0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,0, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,0, - 0, 8, 0, 4, 6, 0, 2, 0, 0, 0, 0, 0, 0, 0, 14,0, 0, 0, 0, 0, + 0,18, 0,18,18, 0,18, 0, 0, 0, 0, 0, 0, 0, 14,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 18,18,18, 18,18,6, 4, 2, 8, 18,18,0, 0, + 0, 0, 0, 0, 0, 0, 0, 18,18,18, 18,18,18,18,18,18,18,18,0, 0, 18,18,15,15,15,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,16,0, 16,16, 16,16,16,16,16,16,0, 0, 0, 0, 0, 0, 18,0, 0, 0, 18,18,18,18, - 2, 4, 6, 8, 18,18,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 18,18,18,18,18,18,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,14,14,14,14,17,18,0, 0, 0, 0, 0, 0, 0, }; static const short trim_ters[274] = { - 99,99,99,99,99,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99,99, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 99,99,1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 99,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 99, + 99,99,99,99,99,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 99, 99,1, 99,1, 1, 99,1, 99,99,99, 99,99,99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99,99,99, @@ -115,7 +115,7 @@ void cTerrain::append(legacy::terrain_type_type& old){ trim_type = eTrimType::NONE; trim_ter = 0; } - if(trim_ter == 99) trim_ter = 0; + if(trim_ter == 99) trim_ter = -1; flag1 = old.flag1; flag2 = old.flag2; switch(old.special){ diff --git a/src/classes/terrain.h b/src/classes/terrain.h index a681cb07..38966c85 100644 --- a/src/classes/terrain.h +++ b/src/classes/terrain.h @@ -38,7 +38,7 @@ public: unsigned int obj_num = 0; // ditto (formerly res1) unsigned int ground_type; // ditto (formerly res2) eTrimType trim_type; // ditto, mostly (formerly res3) - unsigned short trim_ter; // ditto + long trim_ter; // ditto unsigned short combat_arena; location obj_pos; // editor use only location obj_size; // editor use only diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index 56defef3..eb5532ea 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -1478,157 +1478,6 @@ void handle_keystroke(sf::Event event) { mouse_button_held = false; } -bool is_wall(short i,short j) { - ter_num_t ter; - bool answer = false; - short pic; - - ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; - pic = scenario.ter_types[ter].picture; - - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) - return true; - if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) - return true; - if((ter < 22) && (ter > 4)) - return true; - if((pic >= 5) && (pic <= 17)) - return true; - if((pic >= 88) && (pic <= 120)) - return true; - if((pic >= 240) && (pic <= 243)) - return true; - if(pic == 405) - return true; -// for(k = 0; k < 3 ; k++) -// if(town->terrain(i,j) == walls[k]) -// answer = true; - return answer; - -} - -bool is_correctable_wall(short i,short j) { - ter_num_t ter,walls[13] = {5,6,8,9,11,12, - 14,15,17,18,19,20,21}; - bool answer = false; - short k; - - ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) - return false; - if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) - return false; - for(k = 0; k < 13 ; k++) - if(ter == walls[k]) - answer = true; - return answer; - -} - -bool is_mountain(short i,short j) { - bool answer = false; - short pic; - ter_num_t ter; - - ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; - pic = scenario.ter_types[ter].picture; - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) - return true; - if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) - return true; - if((ter >= 22) && (ter <= 35)) - answer = true; - if((pic >= 18) && - (pic <= 31) ) return true; - if(pic == 192) return true; - if(pic == 193) return true; - if(pic == 195) return true; - if(pic == 194) return true; - return answer; - -} -bool is_hill(short i,short j) { - bool answer = false; - short pic; - ter_num_t ter; - - ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; - pic = scenario.ter_types[ter].picture; - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) - return true; - if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) - return true; - if((ter >= 36) && (ter <= 49)) - answer = true; - - if(((pic >= 32) && - (pic <= 45)) - || (pic == 204) - || (pic == 212) - ) - answer = true; - return answer; - -} -bool is_hill_or_mountain(short i,short j) { - if(is_hill(i,j)) - return true; - if(is_mountain(i,j)) - return true; - return false; -} -bool is_erasable_water(short i,short j) { - bool answer = false; - short pic; - ter_num_t ter; - - ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; - pic = scenario.ter_types[ter].picture; - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) - return false; - if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) - return false; - if((ter >= 50) && - (ter <= 62)) - answer = true; - - return answer; -} -bool is_water(short i,short j) { - bool answer = false; - short pic; - ter_num_t ter; - - ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; - pic = scenario.ter_types[ter].picture; - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) - return true; - if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) - return true; - if((pic >= 46) && - (pic <= 66)) - answer = true; - - return answer; -} -bool is_correctable_water(short i,short j) { - bool answer = false; - short pic; - ter_num_t ter; - - ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; - pic = scenario.ter_types[ter].picture; - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) - return false; - if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) - return false; - if((ter >= 50) && - (ter <= 62)) - answer = true; - - return answer; -} - void shy_change_circle_terrain(location center,short radius,ter_num_t terrain_type,short probability) { // prob is 0 - 20, 0 no, 20 always location l; @@ -1761,6 +1610,9 @@ bool terrain_matches(unsigned char x, unsigned char y, ter_num_t ter){ return false; } +static const std::array trim_diffs = {{ + loc(0,0), loc(-1,0), loc(1,0), loc(0,-1), loc(0,1) +}}; void set_terrain(location l,ter_num_t terrain_type) { short i,j,which_sign = -1; @@ -1796,64 +1648,36 @@ void set_terrain(location l,ter_num_t terrain_type) { } } -// if(terrain_type == 85) { -// l2.x++; -// if(editing_town) -// town->terrain(l2.x,l2.y) = 86; -// else current_terrain.terrain[l2.x][l2.y] = 86; -// } -// if(terrain_type == 86) { -// l2.x--; -// if(editing_town) -// town->terrain(l2.x,l2.y) = 85; -// else current_terrain.terrain[l2.x][l2.y] = 85; -// } -// if(terrain_type == 88) { -// l2.x++; -// if(editing_town) -// town->terrain(l2.x,l2.y) = 89; -// else current_terrain.terrain[l2.x][l2.y] = 89; -// } -// if(terrain_type == 89) { -// l2.x--; -// if(editing_town) -// town->terrain(l2.x,l2.y) = 88; -// else current_terrain.terrain[l2.x][l2.y] = 88; -// } + // First make sure surrounding spaces have the correct ground types. + // This should handle the case of placing hills around mountains. + unsigned int main_ground = scenario.ter_types[terrain_type].ground_type; + long trim_ground = scenario.ter_types[terrain_type].trim_ter; + for(int x = -1; x <= 1; x++) { + for(int y = -1; y <= 1; y++) { + location l3(l.x+x,l.y+y); + ter_num_t ter_there = editing_town ? town->terrain(l3.x,l3.y) : current_terrain->terrain[l3.x][l3.y]; + unsigned int ground_there = scenario.ter_types[ter_there].ground_type; + if(ground_there != main_ground && ground_there != trim_ground) { + ter_num_t new_ter = scenario.get_ter_from_ground(trim_ground); + cTerrain& ter_type = scenario.ter_types[new_ter]; + // We need to be very cautious here. + // Only make the change if the terrain already there is the archetype for the ground type + // that is the trim terrain of the terrain we're trying to place. + // Otherwise it might overwrite important things, like buildings or forests. + if(ter_there != scenario.get_ter_from_ground(ter_type.trim_ter)) + continue; + if(editing_town) + town->terrain(l3.x,l3.y) = new_ter; + else current_terrain->terrain[l3.x][l3.y] = new_ter; + } + } + } - // Correcting mountains? - if(is_mountain(l.x,l.y)) - for(i = l.x - 1; i < l.x + 2; i++) - for(j = l.y - 1; j < l.y + 2; j++) { - if((i < 0) || (i > ((editing_town) ? town->max_dim() - 1 : 47)) - || (j < 0) || (j > ((editing_town) ? town->max_dim() - 1 : 47))) - ; - else { - l2.x = i; - l2.y = j; - ter = editing_town ? town->terrain(l2.x,l2.y) : current_terrain->terrain[l2.x][l2.y]; - if((!is_mountain(l2.x,l2.y)) && (ter < 5)) { - if(editing_town) - town->terrain(l2.x,l2.y) = 36; - else current_terrain->terrain[l2.x][l2.y] = 36; - } - } - } - - adjust_space(l); - l.x--; - adjust_space(l); - - l.x += 2; - adjust_space(l); - - l.x--; - l.y--; - adjust_space(l); - - l.y+= 2; - adjust_space(l); - l.y--; + // Adjusting terrains with trim + for(location d : trim_diffs) { + location l3(l.x+d.x, l.y+d.y); + adjust_space(l3); + } if(scenario.ter_types[terrain_type].special == eTerSpec::IS_A_SIGN && editing_town) { for(i = 0; i < town->sign_locs.size(); i++) @@ -1922,800 +1746,6 @@ void set_terrain(location l,ter_num_t terrain_type) { } } -bool fix_rubble(location l) { - ter_num_t terrain_type; - - if((l.x < 0) || (l.y > town->max_dim() - 1) || (l.y < 0) || (l.y > town->max_dim() - 1)) - return false; - terrain_type = town->terrain(l.x,l.y); - if((terrain_type == 85) && (town->terrain(l.x + 1,l.y) != 86)) { - town->terrain(l.x,l.y) = 0; - return true; - } - if((terrain_type == 86) && (town->terrain(l.x - 1,l.y) != 85)) { - town->terrain(l.x,l.y) = 0; - return true; - } - if((terrain_type == 88) && (town->terrain(l.x + 1,l.y) != 89)) { - town->terrain(l.x,l.y) = 2; - return true; - } - if((terrain_type == 89) && (town->terrain(l.x - 1,l.y) != 88)) { - town->terrain(l.x,l.y) = 2; - return true; - } - return false; -} - -bool fix_cave(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > town->max_dim() - 1) || (l.y < 0) || (l.y > town->max_dim() - 1)) - return false; - i = l.x; - j = l.y; - store_ter = town->terrain(l.x,l.y); - - if(is_correctable_wall(i,j)) { - /*if(((l.x == 0) || (l.x == town->max_dim() - 1)) && ((l.y == 0) || (l.y == town->max_dim() - 1))) - ter_to_fix = 2; - else if((l.x == 0) || (l.x == town->max_dim() - 1)) { - if(is_wall(i,j-1)) { - if(is_wall(i,j+1)) { - ter_to_fix = 2; - } - else ter_to_fix = 3; - } - else ter_to_fix = 9; - } - else if((l.y == 0) || (l.y == town->max_dim() - 1)) { - if(is_wall(i - 1,j)) { - if(is_wall(i + 1,j)) { - ter_to_fix = 2; - } - else ter_to_fix = 6; - } - else ter_to_fix = 12; - - } - else { // not edge - */ - if(!is_wall(i-1,j)) { - if(!is_wall(i,j-1)) { - ter_to_fix = 11; - } - else { - if(!is_wall(i,j+1)) - ter_to_fix = 14; - else ter_to_fix = 12; - } - - - - } - - else { // wall(i-1,j) - if(!is_wall(i+1,j)) { - if(!is_wall(i, j-1)) - ter_to_fix = 8; - else if(!is_wall(i,j+1)) - ter_to_fix = 5; - else ter_to_fix = 6; - - } - - else { //wall(i+1,j) - - if(!is_wall(i, j-1)) - ter_to_fix = 9; - else if(!is_wall(i,j+1)) - ter_to_fix = 3; - else if(!is_wall(i-1,j-1)) - ter_to_fix = 16; - else if(!is_wall(i-1,j+1)) - ter_to_fix = 15; - else if(!is_wall(i+1,j-1)) - ter_to_fix = 17; - else if(!is_wall(i+1,j+1)) - ter_to_fix = 18; - else ter_to_fix = 2; - - - - } - - } - //} - ter_to_fix += 3; - town->terrain(i,j) = ter_to_fix; - } - - if(store_ter == town->terrain(l.x,l.y)) - return false; - else return true; - -} - - -bool fix_mountain(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > town->max_dim() - 1) || (l.y < 0) || (l.y > town->max_dim() - 1)) - return false; - i = l.x; - j = l.y; - store_ter = town->terrain(l.x,l.y); - - if((store_ter >= 22) && - (store_ter <= 35) && (store_ter != 23)) { - if(((l.x == 0) || (l.x == town->max_dim() - 1)) && ((l.y == 0) || (l.y == town->max_dim() - 1))) - ter_to_fix = 22; - else if((l.x == 0) || (l.x == town->max_dim() - 1)) { - if(is_mountain(i,j-1)) { - if(is_mountain(i,j+1)) { - ter_to_fix = 22; - } - else ter_to_fix = 24; - } - else ter_to_fix = 28; - } - else if((l.y == 0) || (l.y == town->max_dim() - 1)) { - if(is_mountain(i - 1,j)) { - if(is_mountain(i + 1,j)) { - ter_to_fix = 22; - } - else ter_to_fix = 26; - } - else ter_to_fix = 30; - - } - else { // not edge - - if(!is_mountain(i-1,j)) { - if(!is_mountain(i,j-1)) { - ter_to_fix = 29; - } - else { - if(!is_mountain(i,j+1)) - ter_to_fix = 31; - else ter_to_fix = 30; - } - - - - } - - else { // wall(i-1,j) - if(!is_mountain(i+1,j)) { - if(!is_mountain(i, j-1)) - ter_to_fix = 27; - else if(!is_mountain(i,j+1)) - ter_to_fix = 25; - else ter_to_fix = 26; - - } - - else { //wall(i+1,j) - - if(!is_mountain(i, j-1)) - ter_to_fix = 28; - else if(!is_mountain(i,j+1)) - ter_to_fix = 24; - else if(!is_mountain(i-1,j-1)) - ter_to_fix = 33; - else if(!is_mountain(i-1,j+1)) - ter_to_fix = 32; - else if(!is_mountain(i+1,j-1)) - ter_to_fix = 34; - else if(!is_mountain(i+1,j+1)) - ter_to_fix = 35; - else ter_to_fix = 22; - - - - } - - } - } - town->terrain(i,j) = ter_to_fix; - } - - if(store_ter == town->terrain(l.x,l.y)) - return false; - else return true; - -} - -bool fix_hill(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > town->max_dim() - 1) || (l.y < 0) || (l.y > town->max_dim() - 1)) - return false; - i = l.x; - j = l.y; - store_ter = town->terrain(l.x,l.y); - - if((town->terrain(l.x,l.y) >= 36) && - (town->terrain(l.x,l.y) <= 49) ) { - if(((l.x == 0) || (l.x == town->max_dim() - 1)) && ((l.y == 0) || (l.y == town->max_dim() - 1))) - ter_to_fix = 22; - else if((l.x == 0) || (l.x == town->max_dim() - 1)) { - if(is_hill_or_mountain(i,j-1)) { - if(is_hill_or_mountain(i,j+1)) { - ter_to_fix = 22; - } - else ter_to_fix = 24; - } - else ter_to_fix = 28; - } - else if((l.y == 0) || (l.y == town->max_dim() - 1)) { - if(is_hill_or_mountain(i - 1,j)) { - if(is_hill_or_mountain(i + 1,j)) { - ter_to_fix = 22; - } - else ter_to_fix = 26; - } - else ter_to_fix = 30; - - } - else { // not edge - - if(!is_hill_or_mountain(i-1,j)) { - if(!is_hill_or_mountain(i,j-1)) { - ter_to_fix = 29; - } - else { - if(!is_hill_or_mountain(i,j+1)) - ter_to_fix = 31; - else ter_to_fix = 30; - } - - - - } - - else { // wall(i-1,j) - if(!is_hill_or_mountain(i+1,j)) { - if(!is_hill_or_mountain(i, j-1)) - ter_to_fix = 27; - else if(!is_hill_or_mountain(i,j+1)) - ter_to_fix = 25; - else ter_to_fix = 26; - - } - - else { //wall(i+1,j) - - if(!is_hill_or_mountain(i, j-1)) - ter_to_fix = 28; - else if(!is_hill_or_mountain(i,j+1)) - ter_to_fix = 24; - else if(!is_hill_or_mountain(i-1,j-1)) - ter_to_fix = 33; - else if(!is_hill_or_mountain(i-1,j+1)) - ter_to_fix = 32; - else if(!is_hill_or_mountain(i+1,j-1)) - ter_to_fix = 34; - else if(!is_hill_or_mountain(i+1,j+1)) - ter_to_fix = 35; - else ter_to_fix = 22; - - - - } - - } - } - ter_to_fix += 14; - //if((ter_to_fix == 36) && (get_ran(1,0,15) == 5)) - // ter_to_fix++; - if((town->terrain(i,j) != 37) || (ter_to_fix != 36)) - town->terrain(i,j) = ter_to_fix; - } - - if(store_ter == town->terrain(l.x,l.y)) - return false; - else return true; - -} - -bool fix_water(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > town->max_dim() - 1) || (l.y < 0) || (l.y > town->max_dim() - 1)) - return false; - i = l.x; - j = l.y; - store_ter = town->terrain(l.x,l.y); - - if(is_correctable_water(l.x,l.y)) { - if(((l.x == 0) || (l.x == town->max_dim() - 1)) && ((l.y == 0) || (l.y == town->max_dim() - 1))) - ter_to_fix = 22; - else if((l.x == 0) || (l.x == town->max_dim() - 1)) { - if(is_water(i,j-1)) { - if(is_water(i,j+1)) { - ter_to_fix = 22; - } - else ter_to_fix = 24; - } - else ter_to_fix = 28; - } - else if((l.y == 0) || (l.y == town->max_dim() - 1)) { - if(is_water(i - 1,j)) { - if(is_water(i + 1,j)) { - ter_to_fix = 22; - } - else ter_to_fix = 26; - } - else ter_to_fix = 30; - - } - else { // not edge - - if(!is_water(i-1,j)) { - if(!is_water(i,j-1)) { - ter_to_fix = 29; - } - else { - if(!is_water(i,j+1)) - ter_to_fix = 31; - else ter_to_fix = 30; - } - - - - } - - else { // wall(i-1,j) - if(!is_water(i+1,j)) { - if(!is_water(i, j-1)) - ter_to_fix = 27; - else if(!is_water(i,j+1)) - ter_to_fix = 25; - else ter_to_fix = 26; - - } - - else { //wall(i+1,j) - - if(!is_water(i, j-1)) - ter_to_fix = 28; - else if(!is_water(i,j+1)) - ter_to_fix = 24; - else if(!is_water(i-1,j-1)) - ter_to_fix = 33; - else if(!is_water(i-1,j+1)) - ter_to_fix = 32; - else if(!is_water(i+1,j-1)) - ter_to_fix = 34; - else if(!is_water(i+1,j+1)) - ter_to_fix = 35; - else ter_to_fix = 22; - - - - } - - } - } - ter_to_fix += 27; - if(ter_to_fix == 49) - ter_to_fix++; - town->terrain(i,j) = ter_to_fix; - } - - if(store_ter == town->terrain(l.x,l.y)) - return false; - else return true; - -} - -// begin out -bool out_fix_rubble(location l) { - ter_num_t terrain_type; - - if((l.x < 0) || (l.y > 47) || (l.y < 0) || (l.y > 47)) - return false; - terrain_type = current_terrain->terrain[l.x][l.y]; - if((terrain_type == 85) && (current_terrain->terrain[l.x + 1][l.y] != 86)) { - current_terrain->terrain[l.x][l.y] = 0; - return true; - } - if((terrain_type == 86) && (current_terrain->terrain[l.x - 1][l.y] != 85)) { - current_terrain->terrain[l.x][l.y] = 0; - return true; - } - if((terrain_type == 88) && (current_terrain->terrain[l.x + 1][l.y] != 89)) { - current_terrain->terrain[l.x][l.y] = 2; - return true; - } - if((terrain_type == 89) && (current_terrain->terrain[l.x - 1][l.y] != 88)) { - current_terrain->terrain[l.x][l.y] = 2; - return true; - } - return false; -} - -bool out_fix_cave(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > 47) || (l.y < 0) || (l.y > 47)) - return false; - i = l.x; - j = l.y; - store_ter = current_terrain->terrain[l.x][l.y]; - - if(is_correctable_wall(i,j)) { - if(((l.x == 0) || (l.x == 47)) && ((l.y == 0) || (l.y == 47))) - ter_to_fix = 2; - else if((l.x == 0) || (l.x == 47)) { - if(is_wall(i,j-1)) { - if(is_wall(i,j+1)) { - ter_to_fix = 2; - } - else ter_to_fix = 3; - } - else ter_to_fix = 9; - } - else if((l.y == 0) || (l.y == 47)) { - if(is_wall(i - 1,j)) { - if(is_wall(i + 1,j)) { - ter_to_fix = 2; - } - else ter_to_fix = 6; - } - else ter_to_fix = 12; - - } - else { // not edge - - if(!is_wall(i-1,j)) { - if(!is_wall(i,j-1)) { - ter_to_fix = 11; - } - else { - if(!is_wall(i,j+1)) - ter_to_fix = 14; - else ter_to_fix = 12; - } - - - - } - - else { // wall(i-1,j) - if(!is_wall(i+1,j)) { - if(!is_wall(i, j-1)) - ter_to_fix = 8; - else if(!is_wall(i,j+1)) - ter_to_fix = 5; - else ter_to_fix = 6; - - } - - else { //wall(i+1,j) - - if(!is_wall(i, j-1)) - ter_to_fix = 9; - else if(!is_wall(i,j+1)) - ter_to_fix = 3; - else if(!is_wall(i-1,j-1)) - ter_to_fix = 16; - else if(!is_wall(i-1,j+1)) - ter_to_fix = 15; - else if(!is_wall(i+1,j-1)) - ter_to_fix = 17; - else if(!is_wall(i+1,j+1)) - ter_to_fix = 18; - else ter_to_fix = 2; - - - - } - - } - } - ter_to_fix += 3; - current_terrain->terrain[i][j] = ter_to_fix; - } - - if(store_ter == current_terrain->terrain[l.x][l.y]) - return false; - else return true; - -} - - -bool out_fix_mountain(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > 47) || (l.y < 0) || (l.y > 47)) - return false; - i = l.x; - j = l.y; - store_ter = current_terrain->terrain[l.x][l.y]; - - if((store_ter >= 22) && - (store_ter <= 35) && (store_ter != 23)) { - if(((l.x == 0) || (l.x == 47)) && ((l.y == 0) || (l.y == 47))) - ter_to_fix = 22; - else if((l.x == 0) || (l.x == 47)) { - if(is_mountain(i,j-1)) { - if(is_mountain(i,j+1)) { - ter_to_fix = 22; - } - else ter_to_fix = 24; - } - else ter_to_fix = 28; - } - else if((l.y == 0) || (l.y == 47)) { - if(is_mountain(i - 1,j)) { - if(is_mountain(i + 1,j)) { - ter_to_fix = 22; - } - else ter_to_fix = 26; - } - else ter_to_fix = 30; - - } - else { // not edge - - if(!is_mountain(i-1,j)) { - if(!is_mountain(i,j-1)) { - ter_to_fix = 29; - } - else { - if(!is_mountain(i,j+1)) - ter_to_fix = 31; - else ter_to_fix = 30; - } - - - - } - - else { // wall(i-1,j) - if(!is_mountain(i+1,j)) { - if(!is_mountain(i, j-1)) - ter_to_fix = 27; - else if(!is_mountain(i,j+1)) - ter_to_fix = 25; - else ter_to_fix = 26; - - } - - else { //wall(i+1,j) - - if(!is_mountain(i, j-1)) - ter_to_fix = 28; - else if(!is_mountain(i,j+1)) - ter_to_fix = 24; - else if(!is_mountain(i-1,j-1)) - ter_to_fix = 33; - else if(!is_mountain(i-1,j+1)) - ter_to_fix = 32; - else if(!is_mountain(i+1,j-1)) - ter_to_fix = 34; - else if(!is_mountain(i+1,j+1)) - ter_to_fix = 35; - else ter_to_fix = 22; - - - - } - - } - } - current_terrain->terrain[i][j] = ter_to_fix; - } - - if(store_ter == current_terrain->terrain[l.x][l.y]) - return false; - else return true; - -} - -bool out_fix_hill(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > 47) || (l.y < 0) || (l.y > 47)) - return false; - i = l.x; - j = l.y; - store_ter = current_terrain->terrain[l.x][l.y]; - - if((current_terrain->terrain[l.x][l.y] >= 36) && - (current_terrain->terrain[l.x][l.y] <= 49) ) { - if(((l.x == 0) || (l.x == 47)) && ((l.y == 0) || (l.y == 47))) - ter_to_fix = 22; - else if((l.x == 0) || (l.x == 47)) { - if(is_hill_or_mountain(i,j-1)) { - if(is_hill_or_mountain(i,j+1)) { - ter_to_fix = 22; - } - else ter_to_fix = 24; - } - else ter_to_fix = 28; - } - else if((l.y == 0) || (l.y == 47)) { - if(is_hill_or_mountain(i - 1,j)) { - if(is_hill_or_mountain(i + 1,j)) { - ter_to_fix = 22; - } - else ter_to_fix = 26; - } - else ter_to_fix = 30; - - } - else { // not edge - - if(!is_hill_or_mountain(i-1,j)) { - if(!is_hill_or_mountain(i,j-1)) { - ter_to_fix = 29; - } - else { - if(!is_hill_or_mountain(i,j+1)) - ter_to_fix = 31; - else ter_to_fix = 30; - } - - - - } - - else { // wall(i-1,j) - if(!is_hill_or_mountain(i+1,j)) { - if(!is_hill_or_mountain(i, j-1)) - ter_to_fix = 27; - else if(!is_hill_or_mountain(i,j+1)) - ter_to_fix = 25; - else ter_to_fix = 26; - - } - - else { //wall(i+1,j) - - if(!is_hill_or_mountain(i, j-1)) - ter_to_fix = 28; - else if(!is_hill_or_mountain(i,j+1)) - ter_to_fix = 24; - else if(!is_hill_or_mountain(i-1,j-1)) - ter_to_fix = 33; - else if(!is_hill_or_mountain(i-1,j+1)) - ter_to_fix = 32; - else if(!is_hill_or_mountain(i+1,j-1)) - ter_to_fix = 34; - else if(!is_hill_or_mountain(i+1,j+1)) - ter_to_fix = 35; - else ter_to_fix = 22; - - - - } - - } - } - ter_to_fix += 14; - //if((ter_to_fix == 36) && (get_ran(1,0,15) == 5)) - // ter_to_fix++; - if((current_terrain->terrain[i][j] != 37) || (ter_to_fix != 36)) - current_terrain->terrain[i][j] = ter_to_fix; - } - - if(store_ter == current_terrain->terrain[l.x][l.y]) - return false; - else return true; - -} - -bool out_fix_water(location l) { - ter_num_t ter_to_fix; - ter_num_t store_ter; - short i,j; - - if((l.x < 0) || (l.y > 47) || (l.y < 0) || (l.y > 47)) - return false; - i = l.x; - j = l.y; - store_ter = current_terrain->terrain[l.x][l.y]; - - if(is_correctable_water(l.x,l.y)) { - if(((l.x == 0) || (l.x == 47)) && ((l.y == 0) || (l.y == 47))) - ter_to_fix = 22; - else if((l.x == 0) || (l.x == 47)) { - if(is_water(i,j-1)) { - if(is_water(i,j+1)) { - ter_to_fix = 22; - } - else ter_to_fix = 24; - } - else ter_to_fix = 28; - } - else if((l.y == 0) || (l.y == 47)) { - if(is_water(i - 1,j)) { - if(is_water(i + 1,j)) { - ter_to_fix = 22; - } - else ter_to_fix = 26; - } - else ter_to_fix = 30; - - } - else { // not edge - - if(!is_water(i-1,j)) { - if(!is_water(i,j-1)) { - ter_to_fix = 29; - } - else { - if(!is_water(i,j+1)) - ter_to_fix = 31; - else ter_to_fix = 30; - } - - - - } - - else { // wall(i-1,j) - if(!is_water(i+1,j)) { - if(!is_water(i, j-1)) - ter_to_fix = 27; - else if(!is_water(i,j+1)) - ter_to_fix = 25; - else ter_to_fix = 26; - - } - - else { //wall(i+1,j) - - if(!is_water(i, j-1)) - ter_to_fix = 28; - else if(!is_water(i,j+1)) - ter_to_fix = 24; - else if(!is_water(i-1,j-1)) - ter_to_fix = 33; - else if(!is_water(i-1,j+1)) - ter_to_fix = 32; - else if(!is_water(i+1,j-1)) - ter_to_fix = 34; - else if(!is_water(i+1,j+1)) - ter_to_fix = 35; - else ter_to_fix = 22; - - - - } - - } - } - ter_to_fix += 27; - if(ter_to_fix == 49) - ter_to_fix++; - current_terrain->terrain[i][j] = ter_to_fix; - } - - if(store_ter == current_terrain->terrain[l.x][l.y]) - return false; - else return true; - -} -// end out - void adjust_space(location l) { bool needed_change = false; location l2; @@ -2727,43 +1757,98 @@ void adjust_space(location l) { return ; if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) return ; + size_t size = editing_town ? town->max_dim() : 48; + ter_num_t off_map = -1; - if(editing_town) { - if(fix_rubble(l)) - needed_change = true; - if(fix_cave(l)) - needed_change = true; - if(fix_mountain(l)) - needed_change = true; - if(fix_hill(l)) - needed_change = true; - if(fix_water(l)) - needed_change = true; + ter_num_t store_ter[3][3]; + long store_ter2[3][3]; + unsigned int store_ground[3][3]; + eTrimType store_trim[3][3]; + for(int dx = -1; dx <= 1; dx++) { + for(int dy = -1; dy <= 1; dy++) { + int x = i + dx, y = j + dy; + if(x < 0 || x >= size || y < 0 || y >= size) { + store_ter[dx+1][dy+1] = off_map; + continue; + } + store_ter[dx+1][dy+1] = editing_town ? town->terrain(x,y) : current_terrain->terrain[x][y]; + cTerrain& ter_type = scenario.ter_types[store_ter[dx+1][dy+1]]; + store_ter2[dx+1][dy+1] = ter_type.trim_ter; + store_ground[dx+1][dy+1] = ter_type.ground_type; + store_trim[dx+1][dy+1] = ter_type.trim_type; + } } - if(!editing_town) { - if(out_fix_rubble(l)) - needed_change = true; - if(out_fix_cave(l)) - needed_change = true; - if(out_fix_mountain(l)) - needed_change = true; - if(out_fix_hill(l)) - needed_change = true; - if(out_fix_water(l)) + + // Correctable spaces are recognizable by having a trim terrain... + if(store_ter2[1][1] < 0) return; + // ...as well as a particular subset of trim types. + if(store_trim[1][1] >= eTrimType::FRILLS || store_trim[1][1] == eTrimType::WALL) + return; + + bool have_wall = scenario.ter_types[store_ter[1][1]].blockage >= eTerObstruct::BLOCK_MOVE; + + unsigned int main_ground = store_ground[1][1]; + long trim_ground = store_ter2[1][1]; + + auto is_same_ter = [&](int x,int y) -> bool { + if(store_ground[x][y] == main_ground) + return true; + if(store_ter2[x][y] == main_ground) + return true; + if(store_ter[x][y] == off_map) + return true; + if(!have_wall) + return false; + if(store_trim[x][y] == eTrimType::WATERFALL) + return true; + if(store_trim[x][y] == eTrimType::WALL) + return true; + return false; + }; + + // Then go through and figure out what the trim type of the centre should be. + eTrimType need_trim = eTrimType::NONE; + if(!is_same_ter(0,1)) { + if(!is_same_ter(1,0)) { + need_trim = eTrimType::NW; + } else if(!is_same_ter(1,2)) { + need_trim = eTrimType::SW; + } else need_trim = eTrimType::W; + } else if(!is_same_ter(2,1)) { + if(!is_same_ter(1,0)) { + need_trim = eTrimType::NE; + } else if(!is_same_ter(1,2)) { + need_trim = eTrimType::SE; + } else need_trim = eTrimType::E; + } else if(!is_same_ter(1,0)) + need_trim = eTrimType::N; + else if(!is_same_ter(1,2)) + need_trim = eTrimType::S; + else if(!is_same_ter(0,0)) + need_trim = eTrimType::SE_INNER; + else if(!is_same_ter(0,2)) + need_trim = eTrimType::NE_INNER; + else if(!is_same_ter(2,0)) + need_trim = eTrimType::SW_INNER; + else if(!is_same_ter(2,2)) + need_trim = eTrimType::NW_INNER; + + if(store_trim[1][1] != need_trim) { + ter_num_t replace = scenario.get_trim_terrain(main_ground, trim_ground, need_trim); + if(replace != 90) { // If we got 90 back, the required trim doesn't exist. needed_change = true; + if(editing_town) + town->terrain(i,j) = replace; + else current_terrain->terrain[i][j] = replace; + } } if(needed_change) { - l2 = l; - l2.x--; - adjust_space(l2); - l2.x += 2; - adjust_space(l2); - l2.x--; - l2.y--; - adjust_space(l2); - l2.y += 2; - adjust_space(l2); + for(location d : trim_diffs) { + if(d.x == 0 && d.y == 0) continue; + location l2(l.x+d.x, l.y+d.y); + adjust_space(l2); + } } } diff --git a/src/scenedit/scen.actions.h b/src/scenedit/scen.actions.h index a5561c3e..5969f257 100644 --- a/src/scenedit/scen.actions.h +++ b/src/scenedit/scen.actions.h @@ -10,29 +10,12 @@ void get_town_info(); void get_sign_resource(); void set_info_strings(); cTown::cItem edit_item(cTown::cItem item); -bool is_wall(short i,short j); -bool is_correctable_wall(short i,short j); -bool is_mountain(short i,short j); -bool is_hill(short i,short j); -bool is_hill_or_mountain(short i,short j); -bool is_water(short i,short j); -bool is_correctable_water(short i,short j); void shy_change_circle_terrain(location center,short radius,ter_num_t terrain_type,short probability); void change_circle_terrain(location center,short radius,ter_num_t terrain_type,short probability); void change_rect_terrain(rectangle r,ter_num_t terrain_type,short probability,bool hollow); void frill_up_terrain(); void unfrill_terrain(); void set_terrain(location l,ter_num_t terrain_type); -bool fix_rubble(location l); -bool fix_cave(location l); -bool fix_mountain(location l); -bool fix_hill(location l); -bool fix_water(location l); -bool out_fix_rubble(location l); -bool out_fix_cave(location l); -bool out_fix_mountain(location l); -bool out_fix_hill(location l); -bool out_fix_water(location l); void adjust_space(location l); bool is_lava(short x,short y); ter_num_t coord_to_ter(short x,short y); @@ -51,7 +34,6 @@ void start_string_editing(short mode,short just_redo_text); void start_special_editing(short mode,short just_redo_text); void town_entry(location spot_hit); void start_dialogue_editing(short restoring); -bool is_erasable_water(short i,short j); void update_mouse_spot(location the_point); bool monst_on_space(location loc,short m_num);