From 88d6afce2785b3f11fd6bd1aac3a1e1b48da32e7 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sat, 3 Sep 2016 02:50:29 -0400 Subject: [PATCH] Merge all the town classes and remove the unimplemented templated towns This also adds a common superclass shared by towns and outdoor sectors, and enables towns of arbitrary sizes. --- src/BoE.xcodeproj/project.pbxproj | 16 +- src/boe.actions.cpp | 8 +- src/boe.combat.cpp | 28 +- src/boe.dlgutil.cpp | 2 +- src/boe.fileio.cpp | 4 +- src/boe.graphics.cpp | 48 +-- src/boe.graphutil.cpp | 4 +- src/boe.locutils.cpp | 18 +- src/boe.party.cpp | 4 +- src/boe.specials.cpp | 8 +- src/boe.town.cpp | 32 +- src/classes/area.hpp | 46 +++ src/classes/outdoors.cpp | 18 +- src/classes/outdoors.hpp | 12 +- src/classes/party.cpp | 6 +- src/classes/regtown.cpp | 481 ------------------------------ src/classes/regtown.hpp | 82 ----- src/classes/scenario.cpp | 6 +- src/classes/scenario.hpp | 4 +- src/classes/tmpltown.cpp | 28 -- src/classes/tmpltown.hpp | 91 ------ src/classes/town.cpp | 127 ++------ src/classes/town.hpp | 32 +- src/classes/town_import.tpp | 124 ++++++++ src/classes/universe.cpp | 127 ++++---- src/pcedit/pc.main.cpp | 2 +- src/scenedit/scen.actions.cpp | 108 +++---- src/scenedit/scen.core.cpp | 18 +- src/scenedit/scen.fileio.cpp | 30 +- src/scenedit/scen.graphics.cpp | 26 +- src/scenedit/scen.keydlgs.cpp | 34 +-- src/scenedit/scen.townout.cpp | 26 +- src/tools/fileio.hpp | 27 +- src/tools/fileio_party.cpp | 4 +- src/tools/fileio_scen.cpp | 61 ++-- src/tools/vector2d.hpp | 11 +- test/out_legacy.cpp | 4 +- test/out_read.cpp | 4 +- test/out_write.cpp | 6 +- test/town_read.cpp | 6 +- test/town_write.cpp | 8 +- 41 files changed, 566 insertions(+), 1165 deletions(-) create mode 100644 src/classes/area.hpp delete mode 100644 src/classes/regtown.cpp delete mode 100644 src/classes/regtown.hpp delete mode 100644 src/classes/tmpltown.cpp delete mode 100644 src/classes/tmpltown.hpp create mode 100644 src/classes/town_import.tpp diff --git a/src/BoE.xcodeproj/project.pbxproj b/src/BoE.xcodeproj/project.pbxproj index 3764dfc6..58be4e7b 100755 --- a/src/BoE.xcodeproj/project.pbxproj +++ b/src/BoE.xcodeproj/project.pbxproj @@ -152,7 +152,6 @@ 919CC24F1B37731800273FDA /* outdoors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E5C79D0F9F60FA00C21460 /* outdoors.cpp */; }; 919CC2501B37731D00273FDA /* party.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D05B50FA1E9E300184C18 /* party.cpp */; }; 919CC2511B37732100273FDA /* pc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D05BB0FA1EA0A00184C18 /* pc.cpp */; }; - 919CC2521B37732500273FDA /* regtown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC607F0FA26A3B00EEAE67 /* regtown.cpp */; }; 919CC2531B37732C00273FDA /* scenario.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91279C580F9D1253007B0D52 /* scenario.cpp */; }; 919CC2561B37733E00273FDA /* shop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91FDB5791A4E774E00DE5983 /* shop.cpp */; }; 919CC2571B37734000273FDA /* special.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91279CC60F9D1A02007B0D52 /* special.cpp */; }; @@ -160,7 +159,6 @@ 919CC2591B37734C00273FDA /* talking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E5C7B70F9F619D00C21460 /* talking.cpp */; }; 919CC25A1B37735100273FDA /* terrain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91279C660F9D12D6007B0D52 /* terrain.cpp */; }; 919CC25C1B37735C00273FDA /* town.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E5C7980F9F60EC00C21460 /* town.cpp */; }; - 919CC25D1B37736500273FDA /* tmpltown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC60A70FA26C1B00EEAE67 /* tmpltown.cpp */; }; 919CC25E1B37736900273FDA /* universe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC61C50FA2729900EEAE67 /* universe.cpp */; }; 919CC25F1B37736E00273FDA /* vehicle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91279C750F9D15E5007B0D52 /* vehicle.cpp */; }; 919CC2601B37737200273FDA /* estreams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E1862B1B2B2AC0006A99EA /* estreams.cpp */; }; @@ -680,10 +678,8 @@ 919DDC091900750D003E7FED /* freetype.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = freetype.framework; path = ../../../../../../Library/Frameworks/freetype.framework; sourceTree = ""; }; 91A0B15A1900F73E00EF438F /* mask.frag */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = mask.frag; sourceTree = ""; }; 91A32BD10FDB797B00C4E957 /* basicbtns.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = basicbtns.cpp; sourceTree = ""; }; - 91AC607E0FA26A3B00EEAE67 /* regtown.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = regtown.hpp; sourceTree = ""; }; - 91AC607F0FA26A3B00EEAE67 /* regtown.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = regtown.cpp; sourceTree = ""; }; - 91AC60A60FA26C1B00EEAE67 /* tmpltown.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = tmpltown.hpp; sourceTree = ""; }; - 91AC60A70FA26C1B00EEAE67 /* tmpltown.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tmpltown.cpp; sourceTree = ""; }; + 91AC607E0FA26A3B00EEAE67 /* area.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = area.hpp; sourceTree = ""; }; + 91AC607F0FA26A3B00EEAE67 /* town_import.tpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = town_import.tpp; sourceTree = ""; }; 91AC61C40FA2729900EEAE67 /* universe.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = universe.hpp; sourceTree = ""; }; 91AC61C50FA2729900EEAE67 /* universe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = universe.cpp; sourceTree = ""; }; 91AC62090FA2853700EEAE67 /* creatlist.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = creatlist.hpp; sourceTree = ""; }; @@ -1058,14 +1054,13 @@ 91E5C79D0F9F60FA00C21460 /* outdoors.cpp */, 913D05B50FA1E9E300184C18 /* party.cpp */, 913D05BB0FA1EA0A00184C18 /* pc.cpp */, - 91AC607F0FA26A3B00EEAE67 /* regtown.cpp */, + 91AC607F0FA26A3B00EEAE67 /* town_import.tpp */, 91279C580F9D1253007B0D52 /* scenario.cpp */, 91FDB5791A4E774E00DE5983 /* shop.cpp */, 91279CC60F9D1A02007B0D52 /* special.cpp */, 91597A6E1A3BEDC700BE7BF9 /* spell.cpp */, 91E5C7B70F9F619D00C21460 /* talking.cpp */, 91279C660F9D12D6007B0D52 /* terrain.cpp */, - 91AC60A70FA26C1B00EEAE67 /* tmpltown.cpp */, 91E5C7980F9F60EC00C21460 /* town.cpp */, 91AC61C50FA2729900EEAE67 /* universe.cpp */, 91279C750F9D15E5007B0D52 /* vehicle.cpp */, @@ -1076,6 +1071,7 @@ 913D03330FA0FFE800184C18 /* headers */ = { isa = PBXGroup; children = ( + 91AC607E0FA26A3B00EEAE67 /* area.hpp */, 91AC62090FA2853700EEAE67 /* creatlist.hpp */, 914698FD1A747BED00F20F5E /* creature.hpp */, 91279D3C0F9D1D6A007B0D52 /* item.hpp */, @@ -1085,7 +1081,6 @@ 91E5C79C0F9F60FA00C21460 /* outdoors.hpp */, 913D05B40FA1E9E200184C18 /* party.hpp */, 913D05BA0FA1EA0A00184C18 /* pc.hpp */, - 91AC607E0FA26A3B00EEAE67 /* regtown.hpp */, 91279C570F9D1253007B0D52 /* scenario.hpp */, 91FDB5771A4E71A900DE5983 /* shop.hpp */, 912287850FD41A2300B21642 /* simpletypes.hpp */, @@ -1093,7 +1088,6 @@ 91597A6C1A3BED2D00BE7BF9 /* spell.hpp */, 91E5C7B60F9F619D00C21460 /* talking.hpp */, 91279C650F9D12D6007B0D52 /* terrain.hpp */, - 91AC60A60FA26C1B00EEAE67 /* tmpltown.hpp */, 91E5C7970F9F60EC00C21460 /* town.hpp */, 91AC61C40FA2729900EEAE67 /* universe.hpp */, 91279C740F9D15E4007B0D52 /* vehicle.hpp */, @@ -1793,7 +1787,6 @@ 919CC24D1B37730E00273FDA /* location.cpp in Sources */, 919CC24E1B37731400273FDA /* monster.cpp in Sources */, 919CC24F1B37731800273FDA /* outdoors.cpp in Sources */, - 919CC2521B37732500273FDA /* regtown.cpp in Sources */, 919CC2531B37732C00273FDA /* scenario.cpp in Sources */, 919CC2561B37733E00273FDA /* shop.cpp in Sources */, 919CC2571B37734000273FDA /* special.cpp in Sources */, @@ -1801,7 +1794,6 @@ 919CC2591B37734C00273FDA /* talking.cpp in Sources */, 919CC25A1B37735100273FDA /* terrain.cpp in Sources */, 919CC25C1B37735C00273FDA /* town.cpp in Sources */, - 919CC25D1B37736500273FDA /* tmpltown.cpp in Sources */, 919CC25F1B37736E00273FDA /* vehicle.cpp in Sources */, 919CC2601B37737200273FDA /* estreams.cpp in Sources */, 919CC2611B37738100273FDA /* gzstream.cpp in Sources */, diff --git a/src/boe.actions.cpp b/src/boe.actions.cpp index b6343e9e..4a9b0e7a 100644 --- a/src/boe.actions.cpp +++ b/src/boe.actions.cpp @@ -1241,11 +1241,11 @@ bool handle_action(sf::Event event) { center.x--; need_redraw = true; } - if(the_point.in(border_rect[2]) && center.y < univ.town->in_town_rect.bottom && center.y < univ.town->max_dim() - 5) { + if(the_point.in(border_rect[2]) && center.y < univ.town->in_town_rect.bottom && center.y < univ.town->max_dim - 5) { center.y++; need_redraw = true; } - if(the_point.in(border_rect[3]) && center.x < univ.town->in_town_rect.right && center.x < univ.town->max_dim() - 5) { + if(the_point.in(border_rect[3]) && center.x < univ.town->in_town_rect.right && center.x < univ.town->max_dim - 5) { center.x++; need_redraw = true; } @@ -2167,8 +2167,8 @@ bool handle_scroll(sf::Event& event) { redraw_screen(REFRESH_DLOG); } else if(scrollableModes.count(overall_mode) && pos.in(world_screen)) { if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl)) - center.x = minmax(4, univ.town->max_dim() - 5, center.x - amount); - else center.y = minmax(4, univ.town->max_dim() - 5, center.y - amount); + center.x = minmax(4, univ.town->max_dim - 5, center.x - amount); + else center.y = minmax(4, univ.town->max_dim - 5, center.y - amount); redraw_screen(REFRESH_TERRAIN); } return true; diff --git a/src/boe.combat.cpp b/src/boe.combat.cpp index 7655efd7..78d03a1c 100644 --- a/src/boe.combat.cpp +++ b/src/boe.combat.cpp @@ -4013,8 +4013,8 @@ location find_fireball_loc(location where,short radius,short mode,short *m) { location check_loc,cast_loc(120,0); short cur_lev,level_max = 10; - for(check_loc.x = 1; check_loc.x < univ.town->max_dim() - 1; check_loc.x ++) - for(check_loc.y = 1; check_loc.y < univ.town->max_dim() - 1; check_loc.y ++) + for(check_loc.x = 1; check_loc.x < univ.town->max_dim - 1; check_loc.x ++) + for(check_loc.y = 1; check_loc.y < univ.town->max_dim - 1; check_loc.y ++) if(dist(where,check_loc) <= 8 && can_see(where,check_loc,sight_obscurity) < 5 && sight_obscurity(check_loc.x,check_loc.y) < 5) { cur_lev = count_levels(check_loc,radius); if(mode == 1) @@ -4119,8 +4119,8 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho // First actually make barriers, then draw them, then inflict damaging effects. - for(short i = minmax(0,univ.town->max_dim() - 1,center.x - 4); i <= minmax(0,univ.town->max_dim() - 1,center.x + 4); i++) - for(short j = minmax(0,univ.town->max_dim() - 1,center.y - 4); j <= minmax(0,univ.town->max_dim() - 1,center.y + 4); j++) { + for(short i = minmax(0,univ.town->max_dim - 1,center.x - 4); i <= minmax(0,univ.town->max_dim - 1,center.x + 4); i++) + for(short j = minmax(0,univ.town->max_dim - 1,center.y - 4); j <= minmax(0,univ.town->max_dim - 1,center.y + 4); j++) { effect = pat.pattern[i - center.x + 4][j - center.y + 4]; if(effect == FIELD_SMASH || sight_obscurity(i,j) < 5) { switch(effect) { @@ -4208,8 +4208,8 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho // Damage to pcs for(short k = 0; k < 6; k++) - for(short i = minmax(0,univ.town->max_dim() - 1,center.x - 4); i <= minmax(0,univ.town->max_dim() - 1,center.x + 4); i++) - for(short j = minmax(0,univ.town->max_dim() - 1,center.y - 4); j <= minmax(0,univ.town->max_dim() - 1,center.y + 4); j++) { + for(short i = minmax(0,univ.town->max_dim - 1,center.x - 4); i <= minmax(0,univ.town->max_dim - 1,center.x + 4); i++) + for(short j = minmax(0,univ.town->max_dim - 1,center.y - 4); j <= minmax(0,univ.town->max_dim - 1,center.y + 4); j++) { spot_hit.x = i; spot_hit.y = j; if(sight_obscurity(i,j) < 5 && univ.party[k].main_status == eMainStatus::ALIVE @@ -4285,8 +4285,8 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho if((univ.town.monst[k].active > 0) && (dist(center,univ.town.monst[k].cur_loc) <= 5)) { monster_hit = false; // First actually make barriers, then draw them, then inflict damaging effects. - for(short i = minmax(0,univ.town->max_dim() - 1,center.x - 4); i <= minmax(0,univ.town->max_dim() - 1,center.x + 4); i++) - for(short j = minmax(0,univ.town->max_dim() - 1,center.y - 4); j <= minmax(0,univ.town->max_dim() - 1,center.y + 4); j++) { + for(short i = minmax(0,univ.town->max_dim - 1,center.x - 4); i <= minmax(0,univ.town->max_dim - 1,center.x + 4); i++) + for(short j = minmax(0,univ.town->max_dim - 1,center.y - 4); j <= minmax(0,univ.town->max_dim - 1,center.y + 4); j++) { spot_hit.x = i; spot_hit.y = j; @@ -5293,8 +5293,8 @@ void process_fields() { if(univ.town.quickfire_present) { r = univ.town->in_town_rect; - for(short i = 0; i < univ.town->max_dim(); i++) - for(short j = 0; j < univ.town->max_dim(); j++) + for(short i = 0; i < univ.town->max_dim; i++) + for(short j = 0; j < univ.town->max_dim; j++) qf[i][j] = (univ.town.is_quickfire(i,j)) ? 2 : 0; for(short k = 0; k < ((is_combat()) ? 4 : 1); k++) { for(short i = r.left + 1; i < r.right ; i++) @@ -5331,8 +5331,8 @@ void process_fields() { // First fry PCs, then call to handle damage to monsters processing_fields = true; // this, in hit_space, makes damage considered to come from whole party - for(short i = 0; i < univ.town->max_dim(); i++) - for(short j = 0; j < univ.town->max_dim(); j++) { + for(short i = 0; i < univ.town->max_dim; i++) + for(short j = 0; j < univ.town->max_dim; j++) { if(univ.town.is_force_wall(i,j)) { r1 = get_ran(3,1,6); loc.x = i; loc.y = j; @@ -5402,8 +5402,8 @@ void process_fields() { monsters_going = true; // this changes who the damage is considered to come from in hit_space if(univ.town.quickfire_present) { - for(short i = 0; i < univ.town->max_dim(); i++) - for(short j = 0; j < univ.town->max_dim(); j++) + for(short i = 0; i < univ.town->max_dim; i++) + for(short j = 0; j < univ.town->max_dim; j++) if(univ.town.is_quickfire(i,j)) { loc.x = i; loc.y = j; r1 = get_ran(2,1,8); diff --git a/src/boe.dlgutil.cpp b/src/boe.dlgutil.cpp index 0bd089ac..444715a8 100644 --- a/src/boe.dlgutil.cpp +++ b/src/boe.dlgutil.cpp @@ -751,7 +751,7 @@ void handle_talk_event(location p) { beep(); return; } - if(univ.party.save_talk(univ.town->talking.people[store_personality].title, univ.town->town_name, save_talk_str1, save_talk_str2)) { + if(univ.party.save_talk(univ.town->talking.people[store_personality].title, univ.town->name, save_talk_str1, save_talk_str2)) { give_help(57,0); play_sound(0); ASB("Noted in journal."); diff --git a/src/boe.fileio.cpp b/src/boe.fileio.cpp index ea907321..8393414e 100644 --- a/src/boe.fileio.cpp +++ b/src/boe.fileio.cpp @@ -108,8 +108,8 @@ void finish_load_party(){ } // Set up field booleans - for(int j = 0; j < univ.town->max_dim(); j++) - for(int k = 0; k < univ.town->max_dim(); k++) { + for(int j = 0; j < univ.town->max_dim; j++) + for(int k = 0; k < univ.town->max_dim; k++) { if(univ.town.is_quickfire(j,k)) univ.town.quickfire_present = true; if(univ.scenario.ter_types[univ.town->terrain(j,k)].special == eTerSpec::CONVEYOR) diff --git a/src/boe.graphics.cpp b/src/boe.graphics.cpp index 639cc995..079afab8 100644 --- a/src/boe.graphics.cpp +++ b/src/boe.graphics.cpp @@ -626,23 +626,23 @@ void draw_text_bar() { bool in_area = false; if(is_out()) { - for(short i = 0; i < univ.out->info_rect.size(); i++) - if(loc.in(univ.out->info_rect[i])) { - put_text_bar(univ.out->info_rect[i].descr); + for(short i = 0; i < univ.out->area_desc.size(); i++) + if(loc.in(univ.out->area_desc[i])) { + put_text_bar(univ.out->area_desc[i].descr); in_area = true; } if(!in_area) { - put_text_bar(univ.out->out_name); + put_text_bar(univ.out->name); } } if(is_town()) { - for(short i = 0; i < univ.town->room_rect.size(); i++) - if(loc.in(univ.town->room_rect[i])) { - put_text_bar(univ.town->room_rect[i].descr); + for(short i = 0; i < univ.town->area_desc.size(); i++) + if(loc.in(univ.town->area_desc[i])) { + put_text_bar(univ.town->area_desc[i].descr); in_area = true; } if(!in_area) { - put_text_bar(univ.town->town_name); + put_text_bar(univ.town->name); } } @@ -778,8 +778,8 @@ void draw_terrain(short mode) { where_draw.y += j - 6; if(!(is_out())) light_area[i][j] = (is_town()) ? pt_in_light(view_loc,where_draw) : combat_pt_in_light(where_draw); - if(!(is_out()) && ((where_draw.x < 0) || (where_draw.x > univ.town->max_dim() - 1) - || (where_draw.y < 0) || (where_draw.y > univ.town->max_dim() - 1))) + if(!(is_out()) && ((where_draw.x < 0) || (where_draw.x > univ.town->max_dim - 1) + || (where_draw.y < 0) || (where_draw.y > univ.town->max_dim - 1))) unexplored_area[i][j] = 0; else unexplored_area[i][j] = 1 - is_explored(where_draw.x,where_draw.y); } @@ -793,18 +793,18 @@ void draw_terrain(short mode) { off_terrain = false; draw_frills = true; - if(!(is_out()) && ((where_draw.x < 0) || (where_draw.x > univ.town->max_dim() - 1) - || (where_draw.y < 0) || (where_draw.y > univ.town->max_dim() - 1))) { + if(!(is_out()) && ((where_draw.x < 0) || (where_draw.x > univ.town->max_dim - 1) + || (where_draw.y < 0) || (where_draw.y > univ.town->max_dim - 1))) { draw_frills = false; // Warning - this section changes where_draw if(where_draw.x < 0) where_draw.x = -1; - if(where_draw.x > univ.town->max_dim() - 1) - where_draw.x = univ.town->max_dim(); + if(where_draw.x > univ.town->max_dim - 1) + where_draw.x = univ.town->max_dim; if(where_draw.y < 0) where_draw.y = -1; - if(where_draw.y > univ.town->max_dim() - 1) - where_draw.y = univ.town->max_dim(); + if(where_draw.y > univ.town->max_dim - 1) + where_draw.y = univ.town->max_dim; if(can_see_light(view_loc,where_draw,sight_obscurity) < 5) can_draw = 1; else can_draw = 0; @@ -1002,9 +1002,9 @@ void place_trim(short q,short r,location where,ter_num_t ter_type) { } else { // TODO: Shouldn't we subtract one here? - if(where.x == univ.town->max_dim()) + if(where.x == univ.town->max_dim) at_right = true; - if(where.y == univ.town->max_dim()) + if(where.y == univ.town->max_dim) at_bot = true; } @@ -1268,14 +1268,14 @@ void place_road(short q,short r,location where,bool here) { rect_draw_some_item (roads_gworld, road_rects[1], terrain_screen_gworld, to_rect); } - if(((is_out()) && (where.x == 96)) || (!(is_out()) && (where.x == univ.town->max_dim() - 1)) + if(((is_out()) && (where.x == 96)) || (!(is_out()) && (where.x == univ.town->max_dim - 1)) || extend_road_terrain(where.x + 1, where.y)) { to_rect = road_dest_rects[1]; to_rect.offset(13 + q * 28,13 + r * 36); rect_draw_some_item (roads_gworld, road_rects[0], terrain_screen_gworld, to_rect); } - if(((is_out()) && (where.y == 96)) || (!(is_out()) && (where.y == univ.town->max_dim() - 1)) + if(((is_out()) && (where.y == 96)) || (!(is_out()) && (where.y == univ.town->max_dim - 1)) || extend_road_terrain(where.x, where.y + 1)) { to_rect = road_dest_rects[2]; to_rect.offset(13 + q * 28,13 + r * 36); @@ -1301,20 +1301,20 @@ void place_road(short q,short r,location where,bool here) { else if((vertTrim == eTrimType::S && trim == eTrimType::N) || (vertTrim == eTrimType::N && trim == eTrimType::S)) vert = can_build_roads_on(ref); - if(((is_out()) && (where.x < 96)) || (!(is_out()) && (where.x < univ.town->max_dim() - 1))) + if(((is_out()) && (where.x < 96)) || (!(is_out()) && (where.x < univ.town->max_dim - 1))) ter = coord_to_ter(where.x + 1,where.y); eTrimType horzTrim = univ.scenario.ter_types[ter].trim_type; - if(((is_out()) && (where.x == 96)) || (!(is_out()) && (where.x == univ.town->max_dim() - 1)) + if(((is_out()) && (where.x == 96)) || (!(is_out()) && (where.x == univ.town->max_dim - 1)) || connect_roads(ter)) horz = can_build_roads_on(ref); else if((horzTrim == eTrimType::W && trim == eTrimType::E) || (horzTrim == eTrimType::E && trim == eTrimType::W)) horz = can_build_roads_on(ref); if(vert){ - if(((is_out()) && (where.y < 96)) || (!(is_out()) && (where.y < univ.town->max_dim() - 1))) + if(((is_out()) && (where.y < 96)) || (!(is_out()) && (where.y < univ.town->max_dim - 1))) ter = coord_to_ter(where.x,where.y + 1); eTrimType vertTrim = univ.scenario.ter_types[ter].trim_type; - if(((is_out()) && (where.y == 96)) || (!(is_out()) && (where.y == univ.town->max_dim() - 1)) + if(((is_out()) && (where.y == 96)) || (!(is_out()) && (where.y == univ.town->max_dim - 1)) || connect_roads(ter)) vert = can_build_roads_on(ref); else if((vertTrim == eTrimType::S && trim == eTrimType::N) || (vertTrim == eTrimType::N && trim == eTrimType::S)) diff --git a/src/boe.graphutil.cpp b/src/boe.graphutil.cpp index 7c1dd050..7f9b80e2 100644 --- a/src/boe.graphutil.cpp +++ b/src/boe.graphutil.cpp @@ -581,9 +581,9 @@ char get_fluid_trim(location where,ter_num_t ter_type) { at_bot = true; } else { - if(where.x == univ.town->max_dim() - 1) + if(where.x == univ.town->max_dim - 1) at_right = true; - if(where.y == univ.town->max_dim() - 1) + if(where.y == univ.town->max_dim - 1) at_bot = true; } diff --git a/src/boe.locutils.cpp b/src/boe.locutils.cpp index 41a09420..f3a6d2df 100644 --- a/src/boe.locutils.cpp +++ b/src/boe.locutils.cpp @@ -133,7 +133,7 @@ location local_to_global(location local) { return global; } bool loc_off_world(location p1) { - if((p1.x < 0) || (p1.x > univ.town->max_dim()) || (p1.y < 0) || (p1.y > univ.town->max_dim())) + if((p1.x < 0) || (p1.x > univ.town->max_dim) || (p1.y < 0) || (p1.y > univ.town->max_dim)) return true; else return false; } @@ -266,8 +266,8 @@ void update_explored(location dest) { if(overall_mode > MODE_OUTDOORS) { make_explored(dest.x,dest.y); - for(look2.x = max(0,dest.x - 4); look2.x < min(univ.town->max_dim(),dest.x + 5); look2.x++) - for(look2.y = max(0,dest.y - 4); look2.y < min(univ.town->max_dim(),dest.y + 5); look2.y++) + for(look2.x = max(0,dest.x - 4); look2.x < min(univ.town->max_dim,dest.x + 5); look2.x++) + for(look2.y = max(0,dest.y - 4); look2.y < min(univ.town->max_dim,dest.y + 5); look2.y++) if(!is_explored(look2.x,look2.y)) if((can_see_light(dest, look2,sight_obscurity) < 5) && (pt_in_light(dest,look2))) make_explored(look2.x,look2.y); @@ -481,10 +481,10 @@ bool pt_in_light(location from_where,location to_where) { // Assumes, of course, if(univ.town->lighting_type == 0) return true; - if((to_where.x < 0) || (to_where.x >= univ.town->max_dim()) - || (to_where.y < 0) || (to_where.y >= univ.town->max_dim())) + if((to_where.x < 0) || (to_where.x >= univ.town->max_dim) + || (to_where.y < 0) || (to_where.y >= univ.town->max_dim)) return true; - if(univ.town->lighting(to_where.x / 8,to_where.y) & (char) (1 << to_where.x % 8)) + if(univ.town->lighting[to_where.x][to_where.y]) return true; if(dist(from_where,to_where) <= light_radius()) @@ -498,10 +498,10 @@ bool combat_pt_in_light(location to_where) { if((univ.town->lighting_type == 0) || (which_combat_type == 0)) return true; - if((to_where.x < 0) || (to_where.x >= univ.town->max_dim()) - || (to_where.y < 0) || (to_where.y >= univ.town->max_dim())) + if((to_where.x < 0) || (to_where.x >= univ.town->max_dim) + || (to_where.y < 0) || (to_where.y >= univ.town->max_dim)) return true; - if(univ.town->lighting(to_where.x / 8,to_where.y) & (char) (1 << to_where.x % 8)) + if(univ.town->lighting[to_where.x][to_where.y]) return true; rad = light_radius(); diff --git a/src/boe.party.cpp b/src/boe.party.cpp index 62f50d8d..0ca9264e 100644 --- a/src/boe.party.cpp +++ b/src/boe.party.cpp @@ -1281,8 +1281,8 @@ void cast_town_spell(location where) { case eSpell::ANTIMAGIC: add_string_to_buf(" You create an antimagic cloud."); - for(loc.x = 0; loc.x < univ.town->max_dim(); loc.x++) - for(loc.y = 0; loc.y < univ.town->max_dim(); loc.y++) + for(loc.x = 0; loc.x < univ.town->max_dim; loc.x++) + for(loc.y = 0; loc.y < univ.town->max_dim; loc.y++) if(dist(where,loc) <= 2 && can_see(where,loc,sight_obscurity) < 5 && ((abs(loc.x - where.x) < 2) || (abs(loc.y - where.y) < 2))) univ.town.set_antimagic(loc.x,loc.y,true); diff --git a/src/boe.specials.cpp b/src/boe.specials.cpp index df558269..eda373da 100644 --- a/src/boe.specials.cpp +++ b/src/boe.specials.cpp @@ -3428,8 +3428,8 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, showError("Scenario tried to check for invalid field type (1...24)"); } else { int i = 0; - for(short j = spec.ex1b; j < min(spec.ex2b, univ.town->max_dim()); j++) - for(short k = spec.ex1a; k < min(spec.ex2a, univ.town->max_dim()); k++) { + for(short j = spec.ex1b; j < min(spec.ex2b, univ.town->max_dim); j++) + for(short k = spec.ex1a; k < min(spec.ex2a, univ.town->max_dim); k++) { switch(eFieldType(spec.m1)) { // These values are not allowed case SPECIAL_EXPLORED: case SPECIAL_SPOT: case SPECIAL_ROAD: @@ -4310,7 +4310,7 @@ void townmode_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, if(x == 0 && y == 0) continue; location next(l.x+x,l.y+y); - if(next.x < 0 || next.y < 0 || next.x >= univ.town->max_dim() || next.y >= univ.town->max_dim()) + if(next.x < 0 || next.y < 0 || next.x >= univ.town->max_dim || next.y >= univ.town->max_dim) continue; if(!checked.count(next)) to_check.push(next); @@ -4620,7 +4620,7 @@ void handle_message(eSpecCtx which_mode,short cur_type,short mess1,short mess2,s get_strs(str1, str2, cur_type, mess1, mess2); where1 = is_out() ? univ.party.outdoor_corner.x + univ.party.i_w_c.x : univ.party.town_num; where2 = is_out() ? univ.party.outdoor_corner.y + univ.party.i_w_c.y : univ.party.town_num; - std::string placename = is_out() ? univ.out->out_name : univ.town->town_name; + std::string placename = is_out() ? univ.out->name : univ.town->name; cStrDlog display_strings(str1.c_str(), str2.c_str(),title,pic,pt,0); display_strings.setSound(57); display_strings.setRecordHandler(cStringRecorder(note_type).string1(mess1).string2(mess2).from(where1,where2).at(placename)); diff --git a/src/boe.town.cpp b/src/boe.town.cpp index 0a004cdd..b6c71dd3 100644 --- a/src/boe.town.cpp +++ b/src/boe.town.cpp @@ -124,8 +124,8 @@ void start_town_mode(short which_town, short entry_dir) { univ.town.belt_present = false; // Set up map, using stored map - for(short i = 0; i < univ.town->max_dim(); i++) - for(short j = 0; j < univ.town->max_dim(); j++) { + for(short i = 0; i < univ.town->max_dim; i++) + for(short j = 0; j < univ.town->max_dim; j++) { if(univ.town->maps[j][i]) make_explored(i,j); @@ -226,8 +226,8 @@ void start_town_mode(short which_town, short entry_dir) { } } - for(short j = 0; j < univ.town->max_dim(); j++) - for(short k = 0; k < univ.town->max_dim(); k++) { // now load in saved setup, + for(short j = 0; j < univ.town->max_dim; j++) + for(short k = 0; k < univ.town->max_dim; k++) { // now load in saved setup, // except that pushable things restore to orig locs // TODO: THIS IS A TEMPORARY HACK TO GET i VALUE int i = std::find_if(univ.party.creature_save.begin(), univ.party.creature_save.end(), [&pop](cPopulation& p) {return &p == &pop;}) - univ.party.creature_save.begin(); @@ -347,8 +347,8 @@ void start_town_mode(short which_town, short entry_dir) { univ.town.monst[i].active = 0; // Set up field booleans, correct for doors - for(short j = 0; j < univ.town->max_dim(); j++) - for(short k = 0; k < univ.town->max_dim(); k++) { + for(short j = 0; j < univ.town->max_dim; j++) + for(short k = 0; k < univ.town->max_dim; k++) { loc.x = j; loc.y = k; if(is_door(loc)) { univ.town.set_web(j,k,false); @@ -463,7 +463,7 @@ void start_town_mode(short which_town, short entry_dir) { univ.party.hostiles_present = 0; add_string_to_buf("Now entering:"); - add_string_to_buf(" " + univ.town->town_name); + add_string_to_buf(" " + univ.town->name); // clear entry space, and check exploration @@ -539,15 +539,15 @@ location end_town_mode(short switching_level,location destination) { // returns pop = univ.town.monst; // TODO: THIS IS A TEMPORARY HACK TO GET i VALUE int i = std::find_if(univ.party.creature_save.begin(), univ.party.creature_save.end(), [&pop](cPopulation& p) {return &p == &pop;}) - univ.party.creature_save.begin(); - for(short j = 0; j < univ.town->max_dim(); j++) - for(short k = 0; k < univ.town->max_dim(); k++) + for(short j = 0; j < univ.town->max_dim; j++) + for(short k = 0; k < univ.town->max_dim; k++) univ.party.setup[i][j][k] = (univ.town.fields[j][k] & 0xff00) >> 8; data_saved = true; } if(!data_saved) { univ.party.creature_save[univ.party.at_which_save_slot] = univ.town.monst; - for(short j = 0; j < univ.town->max_dim(); j++) - for(short k = 0; k < univ.town->max_dim(); k++) + for(short j = 0; j < univ.town->max_dim; j++) + for(short k = 0; k < univ.town->max_dim; k++) univ.party.setup[univ.party.at_which_save_slot][j][k] = (univ.town.fields[j][k] & 0xff00) >> 8; univ.party.at_which_save_slot = (univ.party.at_which_save_slot == 3) ? 0 : univ.party.at_which_save_slot + 1; } @@ -567,8 +567,8 @@ location end_town_mode(short switching_level,location destination) { // returns } // Now store map - for(short i = 0; i < univ.town->max_dim(); i++) - for(short j = 0; j < univ.town->max_dim(); j++) + for(short i = 0; i < univ.town->max_dim; i++) + for(short j = 0; j < univ.town->max_dim; j++) if(is_explored(i,j)) { univ.town->maps[j].set(i); } @@ -904,7 +904,7 @@ void create_out_combat_terrain(short ter_type,short num_walls,bool is_road) { // We take the terrain from the specified town, and nothing else. // No preset creatures, items, special nodes, etc. // Furthermore, if it's a large town, we drop the outer 8 tiles. - size_t town_size = univ.scenario.towns[arena]->max_dim(); + size_t town_size = univ.scenario.towns[arena]->max_dim; int offset = max(0,town_size - 48); rectangle town_bounds = univ.scenario.towns[arena]->in_town_rect; // Just in case the town boundary is somehow larger than the town... @@ -1233,7 +1233,7 @@ void erase_specials() { if((univ.party.sd_legit(sd1,sd2)) && (PSD[sd1][sd2] == 250)) { long spec = univ.town->special_locs[k].spec; where = univ.town->special_locs[k]; - if(spec >= 0 && (where.x > univ.town->max_dim() || where.y > univ.town->max_dim() || where.x < 0 || where.y < 0)) { + if(spec >= 0 && (where.x > univ.town->max_dim || where.y > univ.town->max_dim || where.x < 0 || where.y < 0)) { beep(); add_string_to_buf("Town corrupt. Problem fixed."); print_nums(where.x,where.y,k); @@ -1346,7 +1346,7 @@ void draw_map(bool need_refresh) { redraw_rect = view_rect; } else { - total_size = univ.town->max_dim(); + total_size = univ.town->max_dim; switch(total_size) { case 64: view_rect.left = minmax(0,24,univ.party.town_loc.x - 20); diff --git a/src/classes/area.hpp b/src/classes/area.hpp new file mode 100644 index 00000000..a1748013 --- /dev/null +++ b/src/classes/area.hpp @@ -0,0 +1,46 @@ +/* + * area.hpp + * BoE + * + * Created by Celtic Minstrel on 02/09/16. + * + */ + +#ifndef BOE_DATA_AREA_HPP +#define BOE_DATA_AREA_HPP + +#include +#include +#include + +#include "vector2d.hpp" +#include "location.hpp" +#include "special.hpp" + +enum { + AREA_TINY = 24, + AREA_SMALL = 32, + AREA_MEDIUM = 48, + AREA_LARGE = 64, + AREA_HUGE = 128, +}; + +class cArea { +public: + const size_t max_dim; + vector2d terrain; + std::vector special_locs; + std::vector sign_locs; + std::vector area_desc; + std::string name; + // Persistent data for saved games + std::vector> maps; + + explicit cArea(size_t dim) + : max_dim(dim) + , terrain(dim, dim) + , maps(dim, boost::dynamic_bitset<>(dim)) + {} +}; + +#endif diff --git a/src/classes/outdoors.cpp b/src/classes/outdoors.cpp index a977d664..f7b65c50 100644 --- a/src/classes/outdoors.cpp +++ b/src/classes/outdoors.cpp @@ -77,17 +77,17 @@ void cOutdoors::import_legacy(legacy::outdoor_record_type& old){ } city_locs.resize(8); sign_locs.resize(8); - info_rect.resize(8); + area_desc.resize(8); for(short i = 0; i < 8; i++){ city_locs[i].x = old.exit_locs[i].x; city_locs[i].y = old.exit_locs[i].y; city_locs[i].spec = old.exit_dests[i]; sign_locs[i].x = old.sign_locs[i].x; sign_locs[i].y = old.sign_locs[i].y; - info_rect[i].top = old.info_rect[i].top; - info_rect[i].left = old.info_rect[i].left; - info_rect[i].bottom = old.info_rect[i].bottom; - info_rect[i].right = old.info_rect[i].right; + area_desc[i].top = old.info_rect[i].top; + area_desc[i].left = old.info_rect[i].left; + area_desc[i].bottom = old.info_rect[i].bottom; + area_desc[i].right = old.info_rect[i].right; } for(short i = 0; i < 4; i++){ wandering[i].import_legacy(old.wandering[i]); @@ -107,13 +107,13 @@ cOutdoors::cWandering::cWandering() { std::fill(friendly.begin(), friendly.end(), 0); } -cOutdoors::cOutdoors(cScenario& scenario) : scenario(&scenario) { +cOutdoors::cOutdoors(cScenario& scenario) : cArea(AREA_MEDIUM), scenario(&scenario) { location locs[4] = {loc(8,8),loc(32,8),loc(8,32),loc(32,32)}; bg_out = bg_fight = bg_town = bg_dungeon = -1; out_sound = 0; - for(short i = 0; i < 48; i++) - for(short j = 0; j < 48; j++) { + for(short i = 0; i < max_dim; i++) + for(short j = 0; j < max_dim; j++) { terrain[i][j] = scenario.default_ground; special_spot[i][j] = false; roads[i][j] = false; @@ -122,7 +122,7 @@ cOutdoors::cOutdoors(cScenario& scenario) : scenario(&scenario) { for(short i = 0; i < wandering_locs.size(); i++) { wandering_locs[i] = locs[i]; } - out_name = "Area name"; + name = "Area name"; comment = "Comment"; } diff --git a/src/classes/outdoors.hpp b/src/classes/outdoors.hpp index bf4cc34a..a545bf85 100644 --- a/src/classes/outdoors.hpp +++ b/src/classes/outdoors.hpp @@ -17,6 +17,7 @@ #include "special.hpp" #include "simpletypes.hpp" #include "monster.hpp" +#include "area.hpp" namespace legacy { struct out_wandering_type; @@ -33,7 +34,7 @@ enum eAmbientSound { AMBIENT_CUSTOM, }; -class cOutdoors { +class cOutdoors : public cArea { cScenario* scenario; public: class cWandering { // formerly out_wandering_type @@ -60,17 +61,10 @@ public: void import_legacy(legacy::outdoor_creature_type old); }; short x,y; // Used while loading legacy scenarios. - ter_num_t terrain[48][48]; - std::vector special_locs; std::vector city_locs; - std::vector sign_locs; std::array wandering, special_enc; std::array wandering_locs; std::vector specials; - std::string out_name; - // Using std::array here so we can have .size() - // This'll make the transition smoother once it becomes a vector. - std::vector info_rect; std::string comment; std::vector spec_strs; bool special_spot[48][48]; @@ -78,8 +72,6 @@ public: eAmbientSound ambient_sound = AMBIENT_NONE; snd_num_t out_sound; int bg_out, bg_fight, bg_town, bg_dungeon; - // Persistent data for saved games - std::array, 48> maps; explicit cOutdoors(cScenario& scenario); void import_legacy(legacy::outdoor_record_type& old); diff --git a/src/classes/party.cpp b/src/classes/party.cpp index 3cdb7374..a63c6fbd 100644 --- a/src/classes/party.cpp +++ b/src/classes/party.cpp @@ -294,7 +294,7 @@ void cParty::import_legacy(legacy::setup_save_type& old){ void cParty::cConvers::import_legacy(legacy::talk_save_type old, const cScenario& scenario){ who_said = scenario.towns[old.personality / 10]->talking.people[old.personality % 10].title; - in_town = scenario.towns[old.town_num]->town_name; + in_town = scenario.towns[old.town_num]->name; int strnums[2] = {old.str1, old.str2}; std::string* strs[2] = {&the_str1, &the_str2}; for(int i = 0; i < 2; i++) { @@ -336,12 +336,12 @@ void cParty::cEncNote::import_legacy(int16_t(& old)[2], const cScenario& scenari break; case 1: the_str = scenario.outdoors[old[1] % scenario.outdoors.width()][old[1] / scenario.outdoors.width()]->spec_strs[old[0] - 1010]; - where = scenario.outdoors[old[1] % scenario.outdoors.width()][old[1] / scenario.outdoors.width()]->out_name; + where = scenario.outdoors[old[1] % scenario.outdoors.width()][old[1] / scenario.outdoors.width()]->name; type = NOTE_OUT; break; case 2: the_str = scenario.towns[old[1]]->spec_strs[old[0] - 2020]; - where = scenario.towns[old[1]]->town_name; + where = scenario.towns[old[1]]->name; type= NOTE_TOWN; break; } diff --git a/src/classes/regtown.cpp b/src/classes/regtown.cpp deleted file mode 100644 index 6b3f8783..00000000 --- a/src/classes/regtown.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/* - * regtown.cpp - * BoE - * - * Created by Celtic Minstrel on 24/04/09. - * - */ - -#include "regtown.hpp" - -#include -#include -#include -#include - -#include "scenario.hpp" -#include "strdlog.hpp" -#include "oldstructs.hpp" -#include "fileio.hpp" - -void cTinyTown::import_legacy(legacy::tiny_tr_type& old, int){ - cField the_field, the_road; - 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::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 < 32; i++) - for(short j = 0; j < 32; j++) { - ter[i][j] = old.terrain[i][j]; - light[i / 8][j] = old.lighting[i / 8][j]; - if(scenario->ter_types[ter[i][j]].i == 3000) { // marker to indicate it used to be a special spot - the_field.loc.x = i; - the_field.loc.y = j; - preset_fields.push_back(the_field); - } - if(scenario->ter_types[ter[i][j]].i == 3001) { // marker to indicate it used to be a road - the_road.loc.x = i; - the_road.loc.y = j; - preset_fields.push_back(the_road); - } - // Convert roads that crossed grass/hill boundaries - // It won't catch ones that sit exactly at the edge, though; in that case they'd need manual fixing - // For simplicity we assume the non-hill space is either a city or a grass road - // Terrain types used here: - // 80 - grass road 81 - hill road - // 38 - hill/grass 40 - hill|grass 42 - grass/hill 44 - grass|hill - // where / means "over" and | means "beside" - if(old.terrain[i][j] == 81 && i > 0 && i < 47 && j > 0 && j < 47) { - if(old.terrain[i+1][j] == 81) { - ter_num_t connect = old.terrain[i-1][j]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 44; - } else if(old.terrain[i-1][j] == 81) { - ter_num_t connect = old.terrain[i+1][j]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 40; - } else if(old.terrain[i][j+1] == 81) { - ter_num_t connect = old.terrain[i][j-1]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 42; - } else if(old.terrain[i][j-1] == 81) { - ter_num_t connect = old.terrain[i][j+1]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 38; - } - } - if(scenario->ter_types[ter[i][j]].boat_over) { - // 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++) { - if(i == special_locs[k].x && j == special_locs[k].y) { - found_spec = k; - break; - } - } - if(found_spec >= 0) { - int found_spec_id = special_locs[found_spec].spec; - cSpecial* node; - if(!unused_special_slots.empty()) { - int use_slot = unused_special_slots.back(); - unused_special_slots.pop_back(); - node = &specials[use_slot]; - special_locs[found_spec].spec = use_slot; - } else { - special_locs[found_spec].spec = specials.size(); - specials.emplace_back(); - node = &specials.back(); - } - node->type = eSpecType::IF_IN_BOAT; - node->ex1b = -1; // any boat; - node->ex1c = -1; // do nothing - node->jumpto = found_spec_id; // else jump here - } - } - } - room_rect.resize(16); - for(short i = 0; i < 16; i++) { - room_rect[i].top = old.room_rect[i].top; - room_rect[i].left = old.room_rect[i].left; - room_rect[i].bottom = old.room_rect[i].bottom; - room_rect[i].right = old.room_rect[i].right; - } - creatures.resize(30); - for(short i = 0; i < 30; i++) { - creatures[i].import_legacy(old.creatures[i]); - } -} - -void cMedTown::import_legacy(legacy::ave_tr_type& old, int){ - cField the_field, the_road; - 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::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 < 48; i++) - for(short j = 0; j < 48; j++) { - ter[i][j] = old.terrain[i][j]; - light[i / 8][j] = old.lighting[i / 8][j]; - if(scenario->ter_types[ter[i][j]].i == 3000) { // marker to indicate it used to be a special spot - the_field.loc.x = i; - the_field.loc.y = j; - preset_fields.push_back(the_field); - } - if(scenario->ter_types[ter[i][j]].i == 3001) { // marker to indicate it used to be a road - the_road.loc.x = i; - the_road.loc.y = j; - preset_fields.push_back(the_road); - } - // Convert roads that crossed grass/hill boundaries - // It won't catch ones that sit exactly at the edge, though; in that case they'd need manual fixing - // For simplicity we assume the non-hill space is either a city or a grass road - // Terrain types used here: - // 80 - grass road 81 - hill road - // 38 - hill/grass 40 - hill|grass 42 - grass/hill 44 - grass|hill - // where / means "over" and | means "beside" - if(old.terrain[i][j] == 81 && i > 0 && i < 47 && j > 0 && j < 47) { - if(old.terrain[i+1][j] == 81) { - ter_num_t connect = old.terrain[i-1][j]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 44; - } else if(old.terrain[i-1][j] == 81) { - ter_num_t connect = old.terrain[i+1][j]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 40; - } else if(old.terrain[i][j+1] == 81) { - ter_num_t connect = old.terrain[i][j-1]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 42; - } else if(old.terrain[i][j-1] == 81) { - ter_num_t connect = old.terrain[i][j+1]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 38; - } - } - if(scenario->ter_types[ter[i][j]].boat_over) { - // 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++) { - if(i == special_locs[k].x && j == special_locs[k].y) { - found_spec = k; - break; - } - } - if(found_spec >= 0) { - int found_spec_id = special_locs[found_spec].spec; - cSpecial* node; - if(!unused_special_slots.empty()) { - int use_slot = unused_special_slots.back(); - unused_special_slots.pop_back(); - node = &specials[use_slot]; - special_locs[found_spec].spec = use_slot; - } else { - special_locs[found_spec].spec = specials.size(); - specials.emplace_back(); - node = &specials.back(); - } - node->type = eSpecType::IF_IN_BOAT; - node->ex1b = -1; // any boat; - node->ex1c = -1; // do nothing - node->jumpto = found_spec_id; // else jump here - } - } - } - room_rect.resize(16); - for(short i = 0; i < 16; i++) { - room_rect[i].top = old.room_rect[i].top; - room_rect[i].left = old.room_rect[i].left; - room_rect[i].bottom = old.room_rect[i].bottom; - room_rect[i].right = old.room_rect[i].right; - } - creatures.resize(40); - for(short i = 0; i < 40; i++) { - creatures[i].import_legacy(old.creatures[i]); - } -} - -void cBigTown::import_legacy(legacy::big_tr_type& old, int){ - cField the_field, the_road; - 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::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 < 64; i++) - for(short j = 0; j < 64; j++) { - ter[i][j] = old.terrain[i][j]; - light[i / 8][j] = old.lighting[i / 8][j]; - if(scenario->ter_types[ter[i][j]].i == 3000) { // marker to indicate it used to be a special spot - the_field.loc.x = i; - the_field.loc.y = j; - preset_fields.push_back(the_field); - } - if(scenario->ter_types[ter[i][j]].i == 3001) { // marker to indicate it used to be a road - the_road.loc.x = i; - the_road.loc.y = j; - preset_fields.push_back(the_road); - } - // Convert roads that crossed grass/hill boundaries - // It won't catch ones that sit exactly at the edge, though; in that case they'd need manual fixing - // For simplicity we assume the non-hill space is either a city or a grass road - // Terrain types used here: - // 80 - grass road 81 - hill road - // 38 - hill/grass 40 - hill|grass 42 - grass/hill 44 - grass|hill - // where / means "over" and | means "beside" - if(old.terrain[i][j] == 81 && i > 0 && i < 47 && j > 0 && j < 47) { - if(old.terrain[i+1][j] == 81) { - ter_num_t connect = old.terrain[i-1][j]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 44; - } else if(old.terrain[i-1][j] == 81) { - ter_num_t connect = old.terrain[i+1][j]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 40; - } else if(old.terrain[i][j+1] == 81) { - ter_num_t connect = old.terrain[i][j-1]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 42; - } else if(old.terrain[i][j-1] == 81) { - ter_num_t connect = old.terrain[i][j+1]; - if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) - ter[i][j] = 38; - } - } - if(scenario->ter_types[ter[i][j]].boat_over) { - // 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++) { - if(i == special_locs[k].x && j == special_locs[k].y) { - found_spec = k; - break; - } - } - if(found_spec >= 0) { - int found_spec_id = special_locs[found_spec].spec; - cSpecial* node; - if(!unused_special_slots.empty()) { - int use_slot = unused_special_slots.back(); - unused_special_slots.pop_back(); - node = &specials[use_slot]; - special_locs[found_spec].spec = use_slot; - } else { - special_locs[found_spec].spec = specials.size(); - specials.emplace_back(); - node = &specials.back(); - } - node->type = eSpecType::IF_IN_BOAT; - node->ex1b = -1; // any boat; - node->ex1c = -1; // do nothing - node->jumpto = found_spec_id; // else jump here - } - } - } - room_rect.resize(16); - for(short i = 0; i < 16; i++) { - room_rect[i].top = old.room_rect[i].top; - room_rect[i].left = old.room_rect[i].left; - room_rect[i].bottom = old.room_rect[i].bottom; - room_rect[i].right = old.room_rect[i].right; - } - creatures.resize(60); - for(short i = 0; i < 60; i++) { - creatures[i].import_legacy(old.creatures[i]); - } -} - -ter_num_t& cTinyTown::terrain(size_t x, size_t y){ - return ter[x][y]; -} - -void cTinyTown::writeTerrainTo(std::ostream& file) { - writeArray(file, ter, 32, 32); -} - -void cTinyTown::readTerrainFrom(std::istream& file) { - readArray(file, ter, 32, 32); -} - -unsigned char& cTinyTown::lighting(size_t i, size_t r){ - return light[i][r]; -} - -ter_num_t& cMedTown::terrain(size_t x, size_t y){ - return ter[x][y]; -} - -void cMedTown::writeTerrainTo(std::ostream& file) { - writeArray(file, ter, 48, 48); -} - -void cMedTown::readTerrainFrom(std::istream& file) { - readArray(file, ter, 48, 48); -} - -unsigned char& cMedTown::lighting(size_t i, size_t r){ - return light[i][r]; -} - -ter_num_t& cBigTown::terrain(size_t x, size_t y){ - return ter[x][y]; -} - -void cBigTown::writeTerrainTo(std::ostream& file) { - writeArray(file, ter, 64, 64); -} - -void cBigTown::readTerrainFrom(std::istream& file) { - readArray(file, ter, 64, 64); -} - -unsigned char& cBigTown::lighting(size_t i, size_t r){ - return light[i][r]; -} - -cBigTown::cBigTown(cScenario& scenario) : cTown(scenario) { - for(size_t i = 0; i < max_dim(); i++) - for(size_t j = 0; j < max_dim(); j++) { - terrain(i,j) = scenario.default_ground; - lighting(i / 8,j) = 0; - } - init_start(); -} - -cMedTown::cMedTown(cScenario& scenario) : cTown(scenario) { - for(size_t i = 0; i < max_dim(); i++) - for(size_t j = 0; j < max_dim(); j++) { - terrain(i,j) = scenario.default_ground; - lighting(i / 8,j) = 0; - } - init_start(); -} - -cTinyTown::cTinyTown(cScenario& scenario) : cTown(scenario) { - for(size_t i = 0; i < max_dim(); i++) - for(size_t j = 0; j < max_dim(); j++) { - terrain(i,j) = scenario.default_ground; - lighting(i / 8,j) = 0; - } - init_start(); -} - -cBigTown::cBigTown(const cBigTown& other) : cTown(other) { - memcpy(ter, other.ter, sizeof(ter)); - memcpy(light, other.light, sizeof(light)); -} - -cBigTown::cBigTown(cBigTown&& other) : cTown(*other.scenario) { - swap(other); -} - -cMedTown::cMedTown(const cMedTown& other) : cTown(other) { - memcpy(ter, other.ter, sizeof(ter)); - memcpy(light, other.light, sizeof(light)); -} - -cMedTown::cMedTown(cMedTown&& other) : cTown(*other.scenario) { - swap(other); -} - -cTinyTown::cTinyTown(const cTinyTown& other) : cTown(other) { - memcpy(ter, other.ter, sizeof(ter)); - memcpy(light, other.light, sizeof(light)); -} - -cTinyTown::cTinyTown(cTinyTown&& other) : cTown(*other.scenario) { - swap(other); -} - -void cBigTown::swap(cTown& with) { - cTown::swap(with); - cBigTown& other = dynamic_cast(with); - ter_num_t temp_ter[64][64]; - memcpy(temp_ter, ter, sizeof(ter)); - memcpy(ter, other.ter, sizeof(ter)); - memcpy(other.ter, temp_ter, sizeof(ter)); - unsigned char temp_light[8][64]; - memcpy(temp_light, light, sizeof(light)); - memcpy(light, other.light, sizeof(light)); - memcpy(other.light, temp_light, sizeof(light)); -} - -void cMedTown::swap(cTown& with) { - cTown::swap(with); - cMedTown& other = dynamic_cast(with); - ter_num_t temp_ter[48][48]; - memcpy(temp_ter, ter, sizeof(ter)); - memcpy(ter, other.ter, sizeof(ter)); - memcpy(other.ter, temp_ter, sizeof(ter)); - unsigned char temp_light[6][48]; - memcpy(temp_light, light, sizeof(light)); - memcpy(light, other.light, sizeof(light)); - memcpy(other.light, temp_light, sizeof(light)); -} - -void cTinyTown::swap(cTown& with) { - cTown::swap(with); - cTinyTown& other = dynamic_cast(with); - ter_num_t temp_ter[32][32]; - memcpy(temp_ter, ter, sizeof(ter)); - memcpy(ter, other.ter, sizeof(ter)); - memcpy(other.ter, temp_ter, sizeof(ter)); - unsigned char temp_light[4][32]; - memcpy(temp_light, light, sizeof(light)); - memcpy(light, other.light, sizeof(light)); - memcpy(other.light, temp_light, sizeof(light)); -} - -cBigTown* cBigTown::clone() { - return new cBigTown(*this); -} - -cMedTown* cMedTown::clone() { - return new cMedTown(*this); -} - -cTinyTown* cTinyTown::clone() { - return new cTinyTown(*this); -} - -size_t cBigTown::max_dim() const { - return 64; -} - -size_t cMedTown::max_dim() const { - return 48; -} - -size_t cTinyTown::max_dim() const { - return 32; -} diff --git a/src/classes/regtown.hpp b/src/classes/regtown.hpp deleted file mode 100644 index a64367f2..00000000 --- a/src/classes/regtown.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * regtown.h - * BoE - * - * Created by Celtic Minstrel on 24/04/09. - * - */ - -#ifndef BOE_DATA_REGTOWN_H -#define BOE_DATA_REGTOWN_H - -#include - -#include "town.hpp" -#include "simpletypes.hpp" -#include "location.hpp" -#include "monster.hpp" - -namespace legacy { - struct big_tr_type; - struct ave_tr_type; - struct tiny_tr_type; -}; - -class cBigTown : public virtual cTown { // formerly big_tr_type - ter_num_t ter[64][64]; - unsigned char light[8][64]; -public: - void import_legacy(legacy::big_tr_type& old, int town_num); - ter_num_t& terrain(size_t x, size_t y); - unsigned char& lighting(size_t i, size_t r); - size_t max_dim() const; - - explicit cBigTown(cScenario& scenario); - void writeTerrainTo(std::ostream& file); - void readTerrainFrom(std::istream& file); - // Copy-and-swap - cBigTown* clone() override; - void swap(cTown& other) override; - cBigTown(const cBigTown& other); - cBigTown(cBigTown&& other); -}; - -class cMedTown : public virtual cTown { // formerly ave_tr_type - ter_num_t ter[48][48]; - unsigned char light[6][48]; -public: - void import_legacy(legacy::ave_tr_type& old, int town_num); - ter_num_t& terrain(size_t x, size_t y); - unsigned char& lighting(size_t i, size_t r); - size_t max_dim() const; - - explicit cMedTown(cScenario& scenario); - void writeTerrainTo(std::ostream& file); - void readTerrainFrom(std::istream& file); - // Copy-and-swap - cMedTown* clone() override; - void swap(cTown& other) override; - cMedTown(const cMedTown& other); - cMedTown(cMedTown&& other); -}; - -class cTinyTown : public virtual cTown { // formerly tiny_tr_type - ter_num_t ter[32][32]; - unsigned char light[4][32]; -public: - void import_legacy(legacy::tiny_tr_type& old, int town_num); - ter_num_t& terrain(size_t x, size_t y); - unsigned char& lighting(size_t i, size_t r); - size_t max_dim() const; - - explicit cTinyTown(cScenario& scenario); - void writeTerrainTo(std::ostream& file); - void readTerrainFrom(std::istream& file); - // Copy-and-swap - cTinyTown* clone() override; - void swap(cTown& other) override; - cTinyTown(const cTinyTown& other); - cTinyTown(cTinyTown&& other); -}; - -#endif diff --git a/src/classes/scenario.cpp b/src/classes/scenario.cpp index b9d60af3..912bad1e 100644 --- a/src/classes/scenario.cpp +++ b/src/classes/scenario.cpp @@ -132,7 +132,7 @@ cScenario::cScenario(const cScenario& other) { // Copy towns and sectors for(size_t i = 0; i < towns.size(); i++) - towns[i] = other.towns[i]->clone(); + towns[i] = new cTown(*other.towns[i]); 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]); @@ -350,8 +350,8 @@ bool cScenario::is_ter_used(ter_num_t ter) { } } for(int i = 0; i < towns.size(); i++) { - for(int x = 0; x < towns[i]->max_dim(); x++) { - for(int y = 0; y < towns[i]->max_dim(); y++) { + for(int x = 0; x < towns[i]->max_dim; x++) { + for(int y = 0; y < towns[i]->max_dim; y++) { if(towns[i]->terrain(x,y) == ter) return true; } diff --git a/src/classes/scenario.hpp b/src/classes/scenario.hpp index 3e575977..88bab8bf 100644 --- a/src/classes/scenario.hpp +++ b/src/classes/scenario.hpp @@ -99,7 +99,9 @@ public: fs::path scen_file; // transient vector2d outdoors; std::vector towns; - template void addTown() {towns.push_back(new Town(*this));} + void addTown(size_t dim) { + towns.push_back(new cTown(*this, dim)); + } void import_legacy(legacy::scenario_data_type& old); void import_legacy(legacy::scen_item_data_type& old); diff --git a/src/classes/tmpltown.cpp b/src/classes/tmpltown.cpp deleted file mode 100644 index 25ce6438..00000000 --- a/src/classes/tmpltown.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * tmpltown.cpp - * BoE - * - * Created by Celtic Minstrel on 24/04/09. - * - */ - -#include "tmpltown.hpp" - -#include -#include -#include -#include - -ter_num_t& cBigTemplTown::terrain(size_t x, size_t y){ - location pos(x,y); - return cBigTown::terrain(x,y); -} - -void cBigTemplTown::writeTerrainTo(std::ostream& /*file*/) { - // TODO: Write out the terrain somehow; -} - -void cBigTemplTown::readTerrainFrom(std::istream& /*file*/) { - // TODO: Read in the terrain somehow -} - diff --git a/src/classes/tmpltown.hpp b/src/classes/tmpltown.hpp deleted file mode 100644 index 37bc6ec2..00000000 --- a/src/classes/tmpltown.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * tmpltown.h - * BoE - * - * Created by Celtic Minstrel on 24/04/09. - * - */ - -#ifndef BOE_DATA_TMPLTOWN_H -#define BOE_DATA_TMPLTOWN_H - -#include - -#include "location.hpp" -#include "monster.hpp" -#include "simpletypes.hpp" -#include "regtown.hpp" - -class cTemplTown : public virtual cTown { -public: - class cCityBlock { // formerly city_block_type - public: - short type; - short destroy_time; - short alignment; - short key_time; - location where; - }; - class cTerRect { // formerly city_ter_rect_type - public: - rectangle rect; - ter_num_t ter_type; - bool hollow; - }; - cCityBlock blocks[15]; - cTerRect ter_rects[10]; - long day; - virtual bool is_templated() const {return true;} - virtual ~cTemplTown() {} -}; - -class cBigTemplTown : public cBigTown, public cTemplTown { - ter_num_t after[64][64]; -public: - ter_num_t& terrain(size_t x, size_t y); - void writeTerrainTo(std::ostream& file); - void readTerrainFrom(std::istream& file); - explicit cBigTemplTown(cScenario& scenario, bool init_strings = false); -}; - -class cMedTemplTown : public cMedTown, public cTemplTown { - ter_num_t after[48][48]; -public: - ter_num_t& terrain(size_t x, size_t y); - void writeTerrainTo(std::ostream& file); - void readTerrainFrom(std::istream& file); - explicit cMedTemplTown(cScenario& scenario, bool init_strings = false); -}; - -class cTinyTemplTown : public cTinyTown, public cTemplTown { - ter_num_t after[32][32]; -public: - ter_num_t& terrain(size_t x, size_t y); - void writeTerrainTo(std::ostream& file); - void readTerrainFrom(std::istream& file); - explicit cTinyTemplTown(cScenario& scenario, bool init_strings = false); -}; - -// City blocks - I want to figure out how to use these sometime. - -//struct city_block_type { -// short block_type; -// short block_destroy_time; -// char block_alignment; -// char block_key_time; -// location block_loc; -//}; -// -//struct city_ter_rect_type { -// Rect what_rect; -// unsigned char ter_type; -// unsigned char hollow; -//}; -// -//struct template_town_type { -// creature_start_type creatures[30]; -// city_block_type city_block[15]; -// city_ter_rect_type city_ter_rect[10]; -//}; - -#endif diff --git a/src/classes/town.cpp b/src/classes/town.cpp index 1631e192..bad62869 100644 --- a/src/classes/town.cpp +++ b/src/classes/town.cpp @@ -16,10 +16,7 @@ #include "scenario.hpp" #include "oldstructs.hpp" #include "mathutil.hpp" - -void cTown::import_legacy(legacy::big_tr_type&, int){} -void cTown::import_legacy(legacy::ave_tr_type&, int){} -void cTown::import_legacy(legacy::tiny_tr_type&, int){} +#include "fileio.hpp" void cTown::import_legacy(legacy::town_record_type& old){ town_chop_time = old.town_chop_time; @@ -74,7 +71,7 @@ void cTown::import_legacy(legacy::town_record_type& old){ strong_barriers = defy_scrying = defy_mapping = false; } -cTown::cTown(cScenario& scenario) : scenario(&scenario) { +cTown::cTown(cScenario& scenario, size_t dim) : cArea(dim), scenario(&scenario), lighting(dim, boost::dynamic_bitset<>(dim)) { cTown::cWandering d_wan = {0,0,0,0}; town_chop_time = -1; @@ -102,7 +99,7 @@ cTown::cTown(cScenario& scenario) : scenario(&scenario) { bg_town = bg_fight = -1; strong_barriers = defy_scrying = defy_mapping = is_hidden = has_tavern = false; - town_name = "Town name"; + name = "Town name"; comment[0] = "Comment 1"; comment[1] = "Comment 2"; comment[2] = "Comment 3"; @@ -112,90 +109,8 @@ cTown::cTown(cScenario& scenario) : scenario(&scenario) { } } -cTown::cTown(const cTown& other) - : town_chop_time(other.town_chop_time) - , town_chop_key(other.town_chop_key) - , bg_town(other.bg_town) - , bg_fight(other.bg_fight) - , wandering(other.wandering) - , wandering_locs(other.wandering_locs) - , special_locs(other.special_locs) - , sign_locs(other.sign_locs) - , lighting_type(other.lighting_type) - , start_locs(other.start_locs) - , exits(other.exits) - , in_town_rect(other.in_town_rect) - , preset_items(other.preset_items) - , creatures(other.creatures) - , max_num_monst(other.max_num_monst) - , preset_fields(other.preset_fields) - , spec_on_entry(other.spec_on_entry) - , spec_on_entry_if_dead(other.spec_on_entry_if_dead) - , spec_on_hostile(other.spec_on_hostile) - , timers(other.timers) - , specials(other.specials) - , strong_barriers(other.strong_barriers) - , defy_mapping(other.defy_mapping) - , defy_scrying(other.defy_scrying) - , is_hidden(other.is_hidden) - , has_tavern(other.has_tavern) - , difficulty(other.difficulty) - , town_name(other.town_name) - , room_rect(other.room_rect) - , comment(other.comment) - , spec_strs(other.spec_strs) - , talking(other.talking) - , maps(other.maps) - , item_taken(other.item_taken) - , can_find(other.can_find) - , m_killed(other.m_killed) -{} - -cTown::cTown(cTown&& other) { - swap(other); -} - -void cTown::swap(cTown& other) { - std::swap(town_chop_time, other.town_chop_time); - std::swap(town_chop_key, other.town_chop_key); - std::swap(bg_town, other.bg_town); - std::swap(bg_fight, other.bg_fight); - std::swap(wandering, other.wandering); - std::swap(wandering_locs, other.wandering_locs); - std::swap(special_locs, other.special_locs); - std::swap(sign_locs, other.sign_locs); - std::swap(lighting_type, other.lighting_type); - std::swap(start_locs, other.start_locs); - std::swap(exits, other.exits); - std::swap(in_town_rect, other.in_town_rect); - std::swap(preset_items, other.preset_items); - std::swap(creatures, other.creatures); - std::swap(max_num_monst, other.max_num_monst); - std::swap(preset_fields, other.preset_fields); - std::swap(spec_on_entry, other.spec_on_entry); - std::swap(spec_on_entry_if_dead, other.spec_on_entry_if_dead); - std::swap(spec_on_hostile, other.spec_on_hostile); - std::swap(timers, other.timers); - std::swap(specials, other.specials); - std::swap(strong_barriers, other.strong_barriers); - std::swap(defy_mapping, other.defy_mapping); - std::swap(defy_scrying, other.defy_scrying); - std::swap(is_hidden, other.is_hidden); - std::swap(has_tavern, other.has_tavern); - std::swap(difficulty, other.difficulty); - std::swap(town_name, other.town_name); - std::swap(room_rect, other.room_rect); - std::swap(comment, other.comment); - std::swap(spec_strs, other.spec_strs); - std::swap(talking, other.talking); - std::swap(maps, other.maps); - std::swap(item_taken, other.item_taken); - std::swap(can_find, other.can_find); - std::swap(m_killed, other.m_killed); -} - void cTown::init_start() { - short s = this->max_dim(); + short s = this->max_dim; start_locs[0].x = s / 2; start_locs[0].y = 4; start_locs[2].x = s / 2; @@ -264,29 +179,23 @@ void cTown::set_up_lights() { using namespace std::placeholders; short rad; location where,l; - bool where_lit[64][64] = {0}; auto get_obscurity = std::bind(&cTown::light_obscurity, this, _1, _2); + // First clear the lighting + lighting[0].reset(); + std::fill(lighting.begin() + 1, lighting.end(), lighting[0]); + // Find bonfires, braziers, etc. - for(short i = 0; i < this->max_dim(); i++) - for(short j = 0; j < this->max_dim(); j++) { + for(short i = 0; i < this->max_dim; i++) + for(short j = 0; j < this->max_dim; j++) { l.x = i; l.y = j; rad = scenario->ter_types[this->terrain(i,j)].light_radius; if(rad > 0) { - for(where.x = std::max(0,i - rad); where.x < min(this->max_dim(),short(i + rad + 1)); where.x++) - for(where.y = std::max(0,j - rad); where.y < min(this->max_dim(),short(j + rad + 1)); where.y++) - if(!where_lit[where.x][where.y] && dist(where,l) <= rad && can_see(l,where,get_obscurity) < 5) - where_lit[where.x][where.y] = true; - } - } - for(short i = 0; i < this->max_dim() / 8; i++) - for(short j = 0; j < this->max_dim(); j++) - this->lighting(i,j) = 0; - for(where.x = 0; where.x < this->max_dim(); where.x++) - for(where.y = 0; where.y < this->max_dim(); where.y++) { - if(where_lit[where.x][where.y]) { - this->lighting(where.x / 8,where.y) = this->lighting(where.x / 8,where.y) | (1 << (where.x % 8)); + for(where.x = std::max(0,i - rad); where.x < min(this->max_dim,short(i + rad + 1)); where.x++) + for(where.y = std::max(0,j - rad); where.y < min(this->max_dim,short(j + rad + 1)); where.y++) + if(!lighting[where.x][where.y] && dist(where,l) <= rad && can_see(l,where,get_obscurity) < 5) + lighting[where.x].set(where.y); } } } @@ -325,3 +234,11 @@ cTown::cItem::cItem(location loc, short num, ::cItem& item) : cItem() { void cTown::reattach(cScenario& scen) { scenario = &scen; } + +void cTown::writeTerrainTo(std::ostream& file) { + writeArray(file, terrain, max_dim, max_dim); +} + +void cTown::readTerrainFrom(std::istream& file) { + readArray(file, terrain, max_dim, max_dim); +} diff --git a/src/classes/town.hpp b/src/classes/town.hpp index 2ae23ce5..6f1d296b 100644 --- a/src/classes/town.hpp +++ b/src/classes/town.hpp @@ -18,6 +18,7 @@ #include "monster.hpp" #include "talking.hpp" #include "item.hpp" +#include "area.hpp" namespace legacy { struct town_record_type; @@ -32,7 +33,7 @@ namespace legacy { class cScenario; -class cTown { // formerly town_record_type +class cTown : public cArea { // formerly town_record_type protected: cScenario* scenario; public: @@ -67,9 +68,8 @@ public: int bg_town, bg_fight; std::array wandering; std::array wandering_locs; - std::vector special_locs; - std::vector sign_locs; eLighting lighting_type; + std::vector> lighting; std::array start_locs; std::array exits; rectangle in_town_rect; @@ -84,44 +84,28 @@ public: bool strong_barriers, defy_mapping, defy_scrying; bool is_hidden, has_tavern; short difficulty; - std::string town_name; // Using std::array here so we can have .size() // This'll make the transition smoother once it becomes a vector. - std::vector room_rect; std::array comment; std::vector spec_strs; cSpeech talking; // Persistent data for saved games - std::array, 64> maps; std::bitset<64> item_taken; bool can_find; long m_killed; - virtual ~cTown(){} - virtual void import_legacy(legacy::big_tr_type& old, int town_num); - virtual void import_legacy(legacy::ave_tr_type& old, int town_num); - virtual void import_legacy(legacy::tiny_tr_type& old, int town_num); - virtual ter_num_t& terrain(size_t x, size_t y) = 0; - virtual unsigned char& lighting(size_t i, size_t r) = 0; - virtual size_t max_dim() const = 0; - virtual bool is_templated() const {return false;} + template + void import_legacy(T& old, int town_num); void init_start(); void set_up_lights(); short light_obscurity(short x,short y); // Obscurity function used for calculating lighting bool is_cleaned_out(); - explicit cTown(cScenario& scenario); + explicit cTown(cScenario& scenario, size_t dim); void import_legacy(legacy::town_record_type& old); void reattach(cScenario& to); - virtual void writeTerrainTo(std::ostream& file) = 0; - virtual void readTerrainFrom(std::istream& file) = 0; - virtual cTown* clone() = 0; - // Copy-and-swap - // However, it's protected so that it can only be used by the clone implementations -protected: - virtual void swap(cTown& other); - cTown(const cTown& other); - cTown(cTown&& other); + void writeTerrainTo(std::ostream& file); + void readTerrainFrom(std::istream& file); }; std::ostream& operator<< (std::ostream& out, eLighting light); diff --git a/src/classes/town_import.tpp b/src/classes/town_import.tpp new file mode 100644 index 00000000..393c7bbc --- /dev/null +++ b/src/classes/town_import.tpp @@ -0,0 +1,124 @@ +/* + * town_import.tpp + * BoE + * + * Created by Celtic Minstrel on 02/09/16. + * + */ + +#include +#include +#include +#include + +#include "scenario.hpp" +#include "strdlog.hpp" +#include "oldstructs.hpp" +#include "fileio.hpp" + +template +struct import_helper { + static const int dim = sizeof(T().terrain) / sizeof(T().terrain[0]); + static const int num_monst = sizeof(T().creatures) / sizeof(T().creatures[0]); +}; + +template +void cTown::import_legacy(T& old, int){ + typedef import_helper sizes; + cField the_field, the_road; + 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::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 < sizes::dim; i++) + for(short j = 0; j < sizes::dim; j++) { + terrain[i][j] = old.terrain[i][j]; + lighting[i][j] = old.lighting[i / 8][j] & (1 << (i % 8)); + if(scenario->ter_types[terrain[i][j]].i == 3000) { // marker to indicate it used to be a special spot + the_field.loc.x = i; + the_field.loc.y = j; + preset_fields.push_back(the_field); + } + if(scenario->ter_types[terrain[i][j]].i == 3001) { // marker to indicate it used to be a road + the_road.loc.x = i; + the_road.loc.y = j; + preset_fields.push_back(the_road); + } + // Convert roads that crossed grass/hill boundaries + // It won't catch ones that sit exactly at the edge, though; in that case they'd need manual fixing + // For simplicity we assume the non-hill space is either a city or a grass road + // Terrain types used here: + // 80 - grass road 81 - hill road + // 38 - hill/grass 40 - hill|grass 42 - grass/hill 44 - grass|hill + // where / means "over" and | means "beside" + if(old.terrain[i][j] == 81 && i > 0 && i < 47 && j > 0 && j < 47) { + if(old.terrain[i+1][j] == 81) { + ter_num_t connect = old.terrain[i-1][j]; + if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) + terrain[i][j] = 44; + } else if(old.terrain[i-1][j] == 81) { + ter_num_t connect = old.terrain[i+1][j]; + if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) + terrain[i][j] = 40; + } else if(old.terrain[i][j+1] == 81) { + ter_num_t connect = old.terrain[i][j-1]; + if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) + terrain[i][j] = 42; + } else if(old.terrain[i][j-1] == 81) { + ter_num_t connect = old.terrain[i][j+1]; + if(connect == 80 || scenario->ter_types[connect].trim_type == eTrimType::CITY) + terrain[i][j] = 38; + } + } + if(scenario->ter_types[terrain[i][j]].boat_over) { + // 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++) { + if(i == special_locs[k].x && j == special_locs[k].y) { + found_spec = k; + break; + } + } + if(found_spec >= 0) { + int found_spec_id = special_locs[found_spec].spec; + cSpecial* node; + if(!unused_special_slots.empty()) { + int use_slot = unused_special_slots.back(); + unused_special_slots.pop_back(); + node = &specials[use_slot]; + special_locs[found_spec].spec = use_slot; + } else { + special_locs[found_spec].spec = specials.size(); + specials.emplace_back(); + node = &specials.back(); + } + node->type = eSpecType::IF_IN_BOAT; + node->ex1b = -1; // any boat; + node->ex1c = -1; // do nothing + node->jumpto = found_spec_id; // else jump here + } + } + } + area_desc.resize(16); + for(short i = 0; i < 16; i++) { + area_desc[i].top = old.room_rect[i].top; + area_desc[i].left = old.room_rect[i].left; + area_desc[i].bottom = old.room_rect[i].bottom; + area_desc[i].right = old.room_rect[i].right; + } + creatures.resize(sizes::num_monst); + for(short i = 0; i < sizes::num_monst; i++) { + creatures[i].import_legacy(old.creatures[i]); + } +} diff --git a/src/classes/universe.cpp b/src/classes/universe.cpp index ac2b39ca..4970ac86 100644 --- a/src/classes/universe.cpp +++ b/src/classes/universe.cpp @@ -14,7 +14,7 @@ #include #include -#include "regtown.hpp" +#include "town.hpp" #include "oldstructs.hpp" #include "mathutil.hpp" #include "fileio.hpp" @@ -39,21 +39,22 @@ void cCurTown::import_legacy(legacy::current_town_type& old){ } void cCurTown::import_legacy(legacy::big_tr_type& old){ - for(short i = 0; i < record()->max_dim(); i++) - for(short j = 0; j < record()->max_dim(); j++) + for(short i = 0; i < record()->max_dim; i++) + for(short j = 0; j < record()->max_dim; j++) record()->terrain(i,j) = old.terrain[i][j]; for(short i = 0; i < 16; i++){ - record()->room_rect[i].top = old.room_rect[i].top; - record()->room_rect[i].left = old.room_rect[i].left; - record()->room_rect[i].bottom = old.room_rect[i].bottom; - record()->room_rect[i].right = old.room_rect[i].right; + record()->area_desc[i].top = old.room_rect[i].top; + record()->area_desc[i].left = old.room_rect[i].left; + record()->area_desc[i].bottom = old.room_rect[i].bottom; + record()->area_desc[i].right = old.room_rect[i].right; } record()->creatures.resize(60); for(short i = 0; i < 60; i++) record()->creatures[i].import_legacy(old.creatures[i]); - for(short i = 0; i < record()->max_dim() / 8; i++) - for(short j = 0; j < record()->max_dim(); j++) - record()->lighting(i,j) = old.lighting[i][j]; + for(short i = 0; i < record()->max_dim; i++) + for(short j = 0; j < record()->max_dim; j++) { + record()->lighting[i][j] = old.lighting[i / 8][j] & (1 << (i % 8)); + } } void cCurTown::import_legacy(legacy::town_item_list& old){ @@ -181,7 +182,7 @@ bool cCurTown::prep_talk(short which) { void cCurTown::prep_arena() { if(arena != nullptr) delete arena; - arena = new cMedTown(univ.scenario); + arena = new cTown(univ.scenario, AREA_MEDIUM); } cCurTown::~cCurTown() { @@ -194,47 +195,47 @@ cTown*const cCurTown::record() const { } bool cCurTown::is_explored(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SPECIAL_EXPLORED; } bool cCurTown::is_force_wall(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & WALL_FORCE; } bool cCurTown::is_fire_wall(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & WALL_FIRE; } bool cCurTown::is_antimagic(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & FIELD_ANTIMAGIC; } bool cCurTown::is_scloud(short x, short y) const{ // stinking cloud - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & CLOUD_STINK; } bool cCurTown::is_ice_wall(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & WALL_ICE; } bool cCurTown::is_blade_wall(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & WALL_BLADES; } bool cCurTown::is_sleep_cloud(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & CLOUD_SLEEP; } bool cCurTown::is_block(short x, short y) const{ // currently unused - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & OBJECT_BLOCK; } @@ -247,7 +248,7 @@ bool cCurTown::is_road(short x, short y) const{ } bool cCurTown::is_special(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; location check(x,y); for(int i = 0; i < record()->special_locs.size(); i++) if(check == record()->special_locs[i] && record()->special_locs[i].spec >= 0) @@ -256,89 +257,89 @@ bool cCurTown::is_special(short x, short y) const{ } bool cCurTown::is_web(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & FIELD_WEB; } bool cCurTown::is_crate(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & OBJECT_CRATE; } bool cCurTown::is_barrel(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & OBJECT_BARREL; } bool cCurTown::is_fire_barr(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & BARRIER_FIRE; } bool cCurTown::is_force_barr(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & BARRIER_FORCE; } bool cCurTown::is_quickfire(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & FIELD_QUICKFIRE; } bool cCurTown::is_sm_blood(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_SMALL_BLOOD; } bool cCurTown::is_med_blood(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_MEDIUM_BLOOD; } bool cCurTown::is_lg_blood(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_LARGE_BLOOD; } bool cCurTown::is_sm_slime(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_SMALL_SLIME; } bool cCurTown::is_lg_slime(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_LARGE_SLIME; } bool cCurTown::is_ash(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_ASH; } bool cCurTown::is_bones(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_BONES; } bool cCurTown::is_rubble(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & SFX_RUBBLE; } bool cCurTown::is_force_cage(short x, short y) const{ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; return fields[x][y] & BARRIER_CAGE; } bool cCurTown::set_explored(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b) fields[x][y] |= SPECIAL_EXPLORED; else fields[x][y] &= ~SPECIAL_EXPLORED; return true; } bool cCurTown::set_force_wall(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on space, there's no room for field. if(is_impassable(x,y)) return false; @@ -355,7 +356,7 @@ bool cCurTown::set_force_wall(short x, short y, bool b){ } bool cCurTown::set_fire_wall(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on space, there's no room for field. if(is_impassable(x,y)) return false; @@ -374,7 +375,7 @@ bool cCurTown::set_fire_wall(short x, short y, bool b){ } bool cCurTown::set_antimagic(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on space, there's no room for a field. if(is_impassable(x,y)) return false; @@ -394,7 +395,7 @@ bool cCurTown::set_antimagic(short x, short y, bool b){ } bool cCurTown::set_scloud(short x, short y, bool b){ // stinking cloud - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on space, there's no room for cloud. if(is_impassable(x,y)) return false; @@ -411,7 +412,7 @@ bool cCurTown::set_scloud(short x, short y, bool b){ // stinking cloud } bool cCurTown::set_ice_wall(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on space, ther's no room for a field. if(is_impassable(x,y)) return false; @@ -430,7 +431,7 @@ bool cCurTown::set_ice_wall(short x, short y, bool b){ } bool cCurTown::set_blade_wall(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // if certain things are on space, there's no room for a field. if(is_impassable(x,y)) return false; @@ -445,7 +446,7 @@ bool cCurTown::set_blade_wall(short x, short y, bool b){ } bool cCurTown::set_sleep_cloud(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // if certain things are on space, there's no room for cloud. if(is_impassable(x,y)) return false; @@ -460,28 +461,28 @@ bool cCurTown::set_sleep_cloud(short x, short y, bool b){ } bool cCurTown::set_block(short x, short y, bool b){ // currently unused - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b) fields[x][y] |= OBJECT_BLOCK; else fields[x][y] &= ~OBJECT_BLOCK; return true; } bool cCurTown::set_spot(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b) fields[x][y] |= SPECIAL_SPOT; else fields[x][y] &= ~SPECIAL_SPOT; return true; } bool cCurTown::set_road(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b) fields[x][y] |= SPECIAL_ROAD; else fields[x][y] &= ~SPECIAL_ROAD; return true; } bool cCurTown::set_web(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on the space, there's no room for webs if(is_impassable(x,y)) return false; @@ -498,7 +499,7 @@ bool cCurTown::set_web(short x, short y, bool b){ } bool cCurTown::set_crate(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on the space, there's no room for a crate. if(is_fire_barr(x,y) || is_force_barr(x,y) || is_quickfire(x,y) || is_barrel(x,y)) return false; @@ -509,7 +510,7 @@ bool cCurTown::set_crate(short x, short y, bool b){ } bool cCurTown::set_barrel(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on the space, there's no room for a crate. if(is_fire_barr(x,y) || is_force_barr(x,y) || is_quickfire(x,y) || is_crate(x,y)) return false; @@ -520,7 +521,7 @@ bool cCurTown::set_barrel(short x, short y, bool b){ } bool cCurTown::set_fire_barr(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on the space, there's no room for a barrier. if(is_barrel(x,y) || is_force_barr(x,y) || is_quickfire(x,y) || is_crate(x,y)) return false; @@ -542,7 +543,7 @@ bool cCurTown::set_fire_barr(short x, short y, bool b){ } bool cCurTown::set_force_barr(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on the space, there's no room for a barrier. if(is_fire_barr(x,y) || is_barrel(x,y) || is_quickfire(x,y) || is_crate(x,y)) return false; @@ -564,7 +565,7 @@ bool cCurTown::set_force_barr(short x, short y, bool b){ } bool cCurTown::set_quickfire(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ // If certain things are on space, there's no room for quickfire. ter_num_t ter = record()->terrain(x,y); if(univ.scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_SIGHT) @@ -604,7 +605,7 @@ bool cCurTown::free_for_sfx(short x, short y) { } bool cCurTown::set_sm_blood(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ if(!free_for_sfx(x,y)) return false; if(is_med_blood(x,y) || is_lg_blood(x,y)) @@ -621,7 +622,7 @@ bool cCurTown::set_sm_blood(short x, short y, bool b){ } bool cCurTown::set_med_blood(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ if(!free_for_sfx(x,y)) return false; if(is_lg_blood(x,y)) @@ -639,7 +640,7 @@ bool cCurTown::set_med_blood(short x, short y, bool b){ } bool cCurTown::set_lg_blood(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ if(!free_for_sfx(x,y)) return false; set_sm_blood(x,y,false); @@ -673,7 +674,7 @@ bool cCurTown::set_sm_slime(short x, short y, bool b){ } bool cCurTown::set_lg_slime(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ if(!free_for_sfx(x,y)) return false; set_sm_blood(x,y,false); @@ -690,7 +691,7 @@ bool cCurTown::set_lg_slime(short x, short y, bool b){ } bool cCurTown::set_ash(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ if(!free_for_sfx(x,y)) return false; set_sm_blood(x,y,false); @@ -707,7 +708,7 @@ bool cCurTown::set_ash(short x, short y, bool b){ } bool cCurTown::set_bones(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ if(!free_for_sfx(x,y)) return false; set_sm_blood(x,y,false); @@ -724,7 +725,7 @@ bool cCurTown::set_bones(short x, short y, bool b){ } bool cCurTown::set_rubble(short x, short y, bool b){ - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b){ if(!free_for_sfx(x,y)) return false; set_sm_blood(x,y,false); @@ -743,7 +744,7 @@ bool cCurTown::set_rubble(short x, short y, bool b){ bool cCurTown::set_force_cage(short x, short y, bool b){ // TODO: Consider whether placing a forcecage should erase anything already present, or fail due to something already present // TODO: Also consider checking for forcecage in some of the other placement functions. - if(x > record()->max_dim() || y > record()->max_dim()) return false; + if(x > record()->max_dim || y > record()->max_dim) return false; if(b) fields[x][y] |= BARRIER_CAGE; else fields[x][y] &= ~BARRIER_CAGE; return true; @@ -811,7 +812,7 @@ void cCurTown::writeTo(std::ostream& file) const { file << '\f'; file << "FIELDS\n"; file << std::hex; - writeArray(file, fields, record()->max_dim(), record()->max_dim()); + writeArray(file, fields, record()->max_dim, record()->max_dim); file << std::dec; file << "TERRAIN\n"; record()->writeTerrainTo(file); @@ -845,7 +846,7 @@ void cCurTown::readFrom(std::istream& file){ if(cur == "FIELDS") { int num = univ.party.town_num; bin >> std::hex; - readArray(bin, fields, univ.scenario.towns[num]->max_dim(), univ.scenario.towns[num]->max_dim()); + readArray(bin, fields, univ.scenario.towns[num]->max_dim, univ.scenario.towns[num]->max_dim); bin >> std::dec; } else if(cur == "ITEM") { int i; diff --git a/src/pcedit/pc.main.cpp b/src/pcedit/pc.main.cpp index c87b69e2..d1590139 100644 --- a/src/pcedit/pc.main.cpp +++ b/src/pcedit/pc.main.cpp @@ -225,7 +225,7 @@ void handle_menu_choice(eMenu item_hit) { break; } if(univ.party.left_in != size_t(-1) && univ.party.left_in != univ.party.town_num) { - std::string need_town = univ.scenario.towns[univ.party.left_in]->town_name; + std::string need_town = univ.scenario.towns[univ.party.left_in]->name; showError("You can't reunite your party when you're in a different town than you split up in.", "Return to the following town in-game and then try again: " + need_town); break; } diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index 996a021f..61e12f74 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -609,40 +609,40 @@ static bool handle_rb_action(location the_point, bool option_hit) { right_sbar->setPosition(pos_before); break; case RB_OUT_RECT: - size_before = current_terrain->info_rect.size(); + size_before = current_terrain->area_desc.size(); if(option_hit) { if(j == size_before - 1) - current_terrain->info_rect.pop_back(); + current_terrain->area_desc.pop_back(); else if(j == size_before) break; - else current_terrain->info_rect[j] = {0, 0, 0, 0, "*"}; + else current_terrain->area_desc[j] = {0, 0, 0, 0, "*"}; } else { if(j == size_before) - current_terrain->info_rect.emplace_back(0,0,0,0,"*"); - if(!edit_text_str(j,STRS_OUT_RECT) && j == size_before && current_terrain->info_rect[j].descr == "*") - current_terrain->info_rect.pop_back(); + current_terrain->area_desc.emplace_back(0,0,0,0,"*"); + if(!edit_text_str(j,STRS_OUT_RECT) && j == size_before && current_terrain->area_desc[j].descr == "*") + current_terrain->area_desc.pop_back(); } - start_string_editing(STRS_OUT_RECT,size_before == current_terrain->info_rect.size()); - if(size_before > current_terrain->info_rect.size()) + start_string_editing(STRS_OUT_RECT,size_before == current_terrain->area_desc.size()); + if(size_before > current_terrain->area_desc.size()) pos_before--; right_sbar->setPosition(pos_before); break; case RB_TOWN_RECT: - size_before = town->room_rect.size(); + size_before = town->area_desc.size(); if(option_hit) { if(j == size_before - 1) - town->room_rect.pop_back(); + town->area_desc.pop_back(); else if(j == size_before) break; - else town->room_rect[j] = {0, 0, 0, 0, "*"}; + else town->area_desc[j] = {0, 0, 0, 0, "*"}; } else { if(j == size_before) - town->room_rect.emplace_back(0,0,0,0,"*"); - if(!edit_text_str(j,STRS_TOWN_RECT) && j == size_before && town->room_rect[j].descr == "*") - town->room_rect.pop_back(); + town->area_desc.emplace_back(0,0,0,0,"*"); + if(!edit_text_str(j,STRS_TOWN_RECT) && j == size_before && town->area_desc[j].descr == "*") + town->area_desc.pop_back(); } - start_string_editing(STRS_TOWN_RECT,size_before == town->room_rect.size()); - if(size_before > town->room_rect.size()) + start_string_editing(STRS_TOWN_RECT,size_before == town->area_desc.size()); + if(size_before > town->area_desc.size()) pos_before--; right_sbar->setPosition(pos_before); break; @@ -720,8 +720,8 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) { eScenMode old_mode = overall_mode; change_made = true; - if((spot_hit.x < 0) || (spot_hit.x > ((editing_town) ? town->max_dim() - 1 : 47)) || - (spot_hit.y < 0) || (spot_hit.y > ((editing_town) ? town->max_dim() - 1 : 47))) ; + if((spot_hit.x < 0) || (spot_hit.x > ((editing_town) ? town->max_dim - 1 : 47)) || + (spot_hit.y < 0) || (spot_hit.y > ((editing_town) ? town->max_dim - 1 : 47))) ; else switch(overall_mode) { case MODE_DRAWING: if((!mouse_button_held && terrain_matches(spot_hit.x,spot_hit.y,current_terrain_type)) || @@ -762,19 +762,19 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) { change_made = true; } else { // MODE_ROOM_RECT - auto& room_rects = editing_town ? town->room_rect : current_terrain->info_rect; - auto iter = std::find_if(room_rects.begin(), room_rects.end(), [](const info_rect_t& r) { + auto& area_descs = editing_town ? town->area_desc : current_terrain->area_desc; + auto iter = std::find_if(area_descs.begin(), area_descs.end(), [](const info_rect_t& r) { return r.right == 0; }); - if(iter != room_rects.end()) { + if(iter != area_descs.end()) { static_cast(*iter) = working_rect; iter->descr = ""; if(!edit_area_rect_str(*iter)) iter->right = 0; } else { - room_rects.emplace_back(working_rect); - if(!edit_area_rect_str(room_rects.back())) - room_rects.pop_back(); + area_descs.emplace_back(working_rect); + if(!edit_area_rect_str(area_descs.back())) + area_descs.pop_back(); } change_made = true; } @@ -1174,17 +1174,17 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) { need_redraw = true; mouse_button_held = true; } - if((the_point.in(border_rect[2])) & (cen_y < (editing_town ? town->max_dim() - 5 : 44))) { + if((the_point.in(border_rect[2])) & (cen_y < (editing_town ? town->max_dim - 5 : 44))) { cen_y++; if(ctrl_hit) - cen_y = (editing_town) ? town->max_dim() - 5 : 44; + cen_y = (editing_town) ? town->max_dim - 5 : 44; need_redraw = true; mouse_button_held = true; } - if((the_point.in(border_rect[3])) & (cen_x < (editing_town ? town->max_dim() - 5 : 44))) { + if((the_point.in(border_rect[3])) & (cen_x < (editing_town ? town->max_dim - 5 : 44))) { cen_x++; if(ctrl_hit) - cen_x = (editing_town) ? town->max_dim() - 5 : 44; + cen_x = (editing_town) ? town->max_dim - 5 : 44; need_redraw = true; mouse_button_held = true; } @@ -1597,8 +1597,8 @@ void swap_terrain() { if(!change_ter(a,b,c)) return; - for(short i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) - for(short j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { + for(short i = 0; i < ((editing_town) ? town->max_dim : 48); i++) + for(short j = 0; j < ((editing_town) ? town->max_dim : 48); j++) { ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; if((ter == a) && (get_ran(1,1,100) <= c)) { if(editing_town) @@ -1804,8 +1804,8 @@ void handle_scroll(sf::Event& event) { redraw_screen(); } else if(overall_mode < MODE_MAIN_SCREEN && pos.in(terrain_rect)) { if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl)) - cen_x = minmax(4, town->max_dim() - 5, cen_x - amount); - else cen_y = minmax(4, town->max_dim() - 5, cen_y - amount); + cen_x = minmax(4, town->max_dim - 5, cen_x - amount); + else cen_y = minmax(4, town->max_dim - 5, cen_y - amount); redraw_screen(); } } @@ -1814,8 +1814,8 @@ void change_circle_terrain(location center,short radius,ter_num_t terrain_type,s // prob is 0 - 20, 0 no, 20 always location l; - for(short i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) - for(short j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { + for(short i = 0; i < ((editing_town) ? town->max_dim : 48); i++) + for(short j = 0; j < ((editing_town) ? town->max_dim : 48); j++) { l.x = i; l.y = j; if((dist(center,l) <= radius) && (get_ran(1,1,20) <= probability)) @@ -1827,8 +1827,8 @@ void change_rect_terrain(rectangle r,ter_num_t terrain_type,short probability,bo // prob is 0 - 20, 0 no, 20 always location l; - for(short i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) - for(short j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { + for(short i = 0; i < ((editing_town) ? town->max_dim : 48); i++) + for(short j = 0; j < ((editing_town) ? town->max_dim : 48); j++) { l.x = i; l.y = j; if((i >= r.left) && (i <= r.right) && (j >= r.top) && (j <= r.bottom) @@ -1867,8 +1867,8 @@ void flood_fill_terrain(location start, ter_num_t terrain_type) { void frill_up_terrain() { ter_num_t terrain_type; - for(short i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) - for(short j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { + for(short i = 0; i < ((editing_town) ? town->max_dim : 48); i++) + for(short j = 0; j < ((editing_town) ? town->max_dim : 48); j++) { terrain_type = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; for(size_t k = 0; k < scenario.ter_types.size(); k++) { @@ -1888,8 +1888,8 @@ void frill_up_terrain() { void unfrill_terrain() { ter_num_t terrain_type; - for(short i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) - for(short j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { + for(short i = 0; i < ((editing_town) ? town->max_dim : 48); i++) + for(short j = 0; j < ((editing_town) ? town->max_dim : 48); j++) { terrain_type = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; cTerrain& ter = scenario.ter_types[terrain_type]; @@ -1942,7 +1942,7 @@ static const std::array trim_diffs = {{ void set_terrain(location l,ter_num_t terrain_type) { location l2; - if((editing_town) && ((l.x < 0) || (l.x > town->max_dim() - 1) || (l.y < 0) || (l.y > town->max_dim() - 1))) + if((editing_town) && ((l.x < 0) || (l.x > town->max_dim - 1) || (l.y < 0) || (l.y > town->max_dim - 1))) return ; if(!editing_town && ((l.x < 0) || (l.x > 47) || (l.y < 0) || (l.y > 47))) return ; @@ -2032,11 +2032,11 @@ void adjust_space(location l) { i = l.x; j = l.y; - if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) + if((editing_town) && ((i < 0) || (i > town->max_dim - 1) || (j < 0) || (j > town->max_dim - 1))) return ; if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) return ; - size_t size = editing_town ? town->max_dim() : 48; + size_t size = editing_town ? town->max_dim : 48; ter_num_t off_map = -1; ter_num_t store_ter[3][3]; @@ -2157,8 +2157,8 @@ bool place_item(location spot_hit,short which_item,bool property,bool always,sho void place_items_in_town() { location l; - for(short i = 0; i < town->max_dim(); i++) - for(short j = 0; j < town->max_dim(); j++) { + for(short i = 0; i < town->max_dim; i++) + for(short j = 0; j < town->max_dim; j++) { l.x = i; l.y = j; @@ -2325,7 +2325,7 @@ void set_up_main_screen() { set_lb(-1,LB_TEXT,LB_NO_ACTION,"",0); set_lb(-1,LB_TEXT,LB_NO_ACTION,"Town/Dungeon Options"); strb.str(""); - strb << " Town " << cur_town << ": " << town->town_name; + strb << " Town " << cur_town << ": " << town->name; set_lb(-1,LB_TEXT,LB_NO_ACTION, strb.str()); set_lb(-1,LB_TEXT,LB_LOAD_TOWN,"Load Another Town"); set_lb(-1,LB_TEXT,LB_EDIT_TOWN,"Edit Town Terrain"); @@ -2344,12 +2344,12 @@ void set_up_main_screen() { void start_town_edit() { std::ostringstream strb; small_any_drawn = false; - cen_x = town->max_dim() / 2; - cen_y = town->max_dim() / 2; + cen_x = town->max_dim / 2; + cen_y = town->max_dim / 2; reset_lb(); strb << "Editing Town " << cur_town; set_lb(0,LB_TITLE,LB_NO_ACTION,strb.str()); - set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,town->town_name); + set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,town->name); set_lb(NLS - 2,LB_TEXT,LB_RETURN,"Back to Main Menu"); set_lb(NLS - 1,LB_TEXT,LB_NO_ACTION,"(Click border to scroll view.)"); overall_mode = MODE_DRAWING; @@ -2362,8 +2362,8 @@ void start_town_edit() { set_string("Drawing mode",scenario.ter_types[current_terrain_type].name); place_location(); copied_spec = -1; - for(short i = 0; i < town->max_dim(); i++) - for(short j = 0; j < town->max_dim(); j++) + for(short i = 0; i < town->max_dim; i++) + for(short j = 0; j < town->max_dim; j++) if(town->terrain(i,j) == 0) current_ground = 0; else if(town->terrain(i,j) == 2) @@ -2379,7 +2379,7 @@ void start_out_edit() { reset_lb(); strb << "Editing outdoors (" << cur_out.x << ',' << cur_out.y << ")"; set_lb(0,LB_TITLE,LB_NO_ACTION,strb.str()); - set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,current_terrain->out_name); + set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,current_terrain->name); set_lb(NLS - 2,LB_TEXT,LB_RETURN,"Back to Main Menu"); set_lb(NLS - 1,LB_TEXT,LB_NO_ACTION,"(Click border to scroll view.)"); overall_mode = MODE_DRAWING; @@ -2593,11 +2593,11 @@ void start_string_editing(eStrMode mode,short just_redo_text) { set_rb(i,RB_TOWN_SIGN, i,str.str()); break; case 6: - str << i << " - " << current_terrain->info_rect[i].descr.substr(0,30); + str << i << " - " << current_terrain->area_desc[i].descr.substr(0,30); set_rb(i,RB_OUT_RECT, i,str.str()); break; case 7: - str << i << " - " << town->room_rect[i].descr.substr(0,30); + str << i << " - " << town->area_desc[i].descr.substr(0,30); set_rb(i,RB_TOWN_RECT, i,str.str()); break; } diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index 453790bf..8301024d 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -8,7 +8,7 @@ #include #include "scen.global.hpp" #include "scenario.hpp" -#include "regtown.hpp" +#include "town.hpp" #include "graphtool.hpp" #include "scen.graphics.hpp" #include "scen.core.hpp" @@ -2906,8 +2906,8 @@ bool build_scenario() { if(!grass) { // Go through and replace all surface terrains with similar cave terrains // Note that this assumes the default terrain set is unchanged. - for(int x = 0; x < warriors_grove->max_dim(); x++) { - for(int y = 0; y < warriors_grove->max_dim(); y++) { + for(int x = 0; x < warriors_grove->max_dim; x++) { + for(int y = 0; y < warriors_grove->max_dim; y++) { ter_num_t ter_there = warriors_grove->terrain(x,y); if(ter_there >= 36 && ter_there <= 49 && ter_there != 37) // Hills ter_there = 0; @@ -3050,16 +3050,16 @@ bool build_scenario() { } for(short i = 0; i < lg; i++) { - scenario.addTown(); - scenario.towns.back()->town_name = "Large town " + std::to_string(i + 1); + scenario.addTown(AREA_LARGE); + scenario.towns.back()->name = "Large town " + std::to_string(i + 1); } for(short i = 0; i < med; i++) { - scenario.addTown(); - scenario.towns.back()->town_name = "Medium town " + std::to_string(i + 1); + scenario.addTown(AREA_MEDIUM); + scenario.towns.back()->name = "Medium town " + std::to_string(i + 1); } for(short i = 0; i < sm; i++) { - scenario.addTown(); - scenario.towns.back()->town_name = "Small town " + std::to_string(i + 1); + scenario.addTown(AREA_SMALL); + scenario.towns.back()->name = "Small town " + std::to_string(i + 1); } cur_town = 0; town = scenario.towns[0]; diff --git a/src/scenedit/scen.fileio.cpp b/src/scenedit/scen.fileio.cpp index 9e9d9512..70f46d9c 100644 --- a/src/scenedit/scen.fileio.cpp +++ b/src/scenedit/scen.fileio.cpp @@ -616,7 +616,7 @@ void writeMonstersToXml(ticpp::Printer&& data, cScenario& scenario) { void writeOutdoorsToXml(ticpp::Printer&& data, cOutdoors& sector) { data.OpenElement("sector"); data.PushAttribute("boes", scenario.format_ed_version()); - data.PushElement("name", sector.out_name); + data.PushElement("name", sector.name); if(!sector.comment.empty()) data.PushElement("comment", sector.comment); switch(sector.ambient_sound) { @@ -640,7 +640,7 @@ void writeOutdoorsToXml(ticpp::Printer&& data, cOutdoors& sector) { data.PushText(sector.sign_locs[i].text, true); data.CloseElement("sign"); } - for(auto& area : sector.info_rect) { + for(auto& area : sector.area_desc) { if(!area.descr.empty() && area.top < area.bottom && area.left < area.right) data.PushElement("area", area); } @@ -658,8 +658,8 @@ void writeTownToXml(ticpp::Printer&& data, cTown& town) { static const char directions[] = {'n', 'w', 's', 'e'}; data.OpenElement("town"); data.PushAttribute("boes", scenario.format_ed_version()); - data.PushElement("size", town.max_dim()); - data.PushElement("name", town.town_name); + data.PushElement("size", town.max_dim); + data.PushElement("name", town.name); for(size_t i = 0; i < town.comment.size(); i++) { if(!town.comment[i].empty()) data.PushElement("comment", town.comment[i]); @@ -777,7 +777,7 @@ void writeTownToXml(ticpp::Printer&& data, cTown& town) { } data.CloseElement("creature"); } - for(auto& area : town.room_rect) { + for(auto& area : town.area_desc) { if(!area.descr.empty() && area.top < area.bottom && area.left < area.right) data.PushElement("area", area); } @@ -892,8 +892,8 @@ map_data buildOutMapData(location which, cScenario& scenario) { map_data buildTownMapData(size_t which, cScenario& scenario) { cTown& town = *scenario.towns[which]; map_data terrain; - for(size_t x = 0; x < town.max_dim(); x++) { - for(size_t y = 0; y < town.max_dim(); y++) { + for(size_t x = 0; x < town.max_dim; x++) { + for(size_t y = 0; y < town.max_dim; y++) { terrain.set(x, y, town.terrain(x,y)); } } @@ -1202,11 +1202,11 @@ void scen_text_dump(){ for(short x = 0; x < scenario.outdoors.width(); x++) { for(short y = 0; y < scenario.outdoors.height(); y++) { fout << " Section (x = " << x << ", y = " << y << "):" << endl; - fout << " Name: " << scenario.outdoors[x][y]->out_name << endl; + fout << " Name: " << scenario.outdoors[x][y]->name << endl; fout << " Comment: " << scenario.outdoors[x][y]->comment << endl; - for(short i = 0; i < scenario.outdoors[x][y]->info_rect.size(); i++) - if(scenario.outdoors[x][y]->info_rect[i].descr[0] != '*') - fout << " Area Rectangle " << i << ": " << scenario.outdoors[x][y]->info_rect[i].descr << endl; + for(short i = 0; i < scenario.outdoors[x][y]->area_desc.size(); i++) + if(scenario.outdoors[x][y]->area_desc[i].descr[0] != '*') + fout << " Area Rectangle " << i << ": " << scenario.outdoors[x][y]->area_desc[i].descr << endl; for(short i = 0; i < scenario.outdoors[x][y]->spec_strs.size(); i++) if(scenario.outdoors[x][y]->spec_strs[i][0] != '*') fout << " Message " << i << ": " << scenario.outdoors[x][y]->spec_strs[i] << endl; @@ -1219,14 +1219,14 @@ void scen_text_dump(){ fout << "Town Text:" << endl << endl; for(short j = 0; j < scenario.towns.size(); j++) { fout << " Town " << j << ':' << endl; - fout << " Name: " << scenario.towns[j]->town_name << endl; + fout << " Name: " << scenario.towns[j]->name << endl; for(short i = 0; i < 3; i++) if(scenario.towns[j]->comment[i][0] != '*') fout << " Comment: " << scenario.towns[j]->comment[i] << endl; fout << " Town Messages:" << endl; - for(short i = 0; i < scenario.towns[j]->room_rect.size(); i++) - if(scenario.towns[j]->room_rect[i].descr[0] != '*') - fout << " Area Rectangle " << i << ": " << scenario.towns[j]->room_rect[i].descr << endl; + for(short i = 0; i < scenario.towns[j]->area_desc.size(); i++) + if(scenario.towns[j]->area_desc[i].descr[0] != '*') + fout << " Area Rectangle " << i << ": " << scenario.towns[j]->area_desc[i].descr << endl; for(short i = 0; i < scenario.towns[j]->spec_strs.size(); i++) if(scenario.towns[j]->spec_strs[i][0] != '*') fout << " Message " << i << ": " << scenario.towns[j]->spec_strs[i] << endl; diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index be6e1bd1..9e30f1dc 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -903,12 +903,12 @@ void draw_terrain(){ if(editing_town) { // draw info rects - for(short i = 0; i < town->room_rect.size(); i++) - if(town->room_rect[i].left > 0) { - draw_rect.left = 22 + 28 * (town->room_rect[i].left - cen_x + 4); - draw_rect.right = 22 + 28 * (town->room_rect[i].right - cen_x + 4); - draw_rect.top = 24 + 36 * (town->room_rect[i].top - cen_y + 4); - draw_rect.bottom = 24 + 36 * (town->room_rect[i].bottom - cen_y + 4); + for(short i = 0; i < town->area_desc.size(); i++) + if(town->area_desc[i].left > 0) { + draw_rect.left = 22 + 28 * (town->area_desc[i].left - cen_x + 4); + draw_rect.right = 22 + 28 * (town->area_desc[i].right - cen_x + 4); + draw_rect.top = 24 + 36 * (town->area_desc[i].top - cen_y + 4); + draw_rect.bottom = 24 + 36 * (town->area_desc[i].bottom - cen_y + 4); draw_rect.inset(-10, -13); draw_rect.offset(TER_RECT_UL_X,TER_RECT_UL_Y); frame_rect(mainPtr, draw_rect, sf::Color::Red); @@ -924,12 +924,12 @@ void draw_terrain(){ } if(!editing_town) { // draw info rects - for(short i = 0; i < current_terrain->info_rect.size(); i++) - if(current_terrain->info_rect[i].left > 0) { - draw_rect.left = 22 + 28 * (current_terrain->info_rect[i].left - cen_x + 4); - draw_rect.right = 22 + 28 * (current_terrain->info_rect[i].right - cen_x + 4); - draw_rect.top = 24 + 36 * (current_terrain->info_rect[i].top - cen_y + 4); - draw_rect.bottom = 24 + 36 * (current_terrain->info_rect[i].bottom - cen_y + 4); + for(short i = 0; i < current_terrain->area_desc.size(); i++) + if(current_terrain->area_desc[i].left > 0) { + draw_rect.left = 22 + 28 * (current_terrain->area_desc[i].left - cen_x + 4); + draw_rect.right = 22 + 28 * (current_terrain->area_desc[i].right - cen_x + 4); + draw_rect.top = 24 + 36 * (current_terrain->area_desc[i].top - cen_y + 4); + draw_rect.bottom = 24 + 36 * (current_terrain->area_desc[i].bottom - cen_y + 4); draw_rect.inset(-10, -13); draw_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y); frame_rect(mainPtr, draw_rect, sf::Color::Red); @@ -948,7 +948,7 @@ void draw_terrain(){ // Width available: 64 4x4 tiles, 42 6x6 tiles, or 21 12x12 tiles -- 256 pixels // Height available: 81 4x4 tiles, 54 6x6 tiles, or 27 12x12 tiles -- 324 pixels short size = mini_map_scales[cur_viewing_mode - 1]; - int max_dim = (editing_town ? town->max_dim() : 48); + int max_dim = (editing_town ? town->max_dim : 48); int xMin = 0, yMin = 0, xMax = max_dim, yMax = max_dim; if(cen_x + 5 > 256 / size) { xMin = cen_x + 5 - (256 / size); diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index 92e93d38..2b0d1190 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -42,8 +42,8 @@ size_t num_strs(eStrMode str_mode) { case 3: return scenario.journal_strs.size(); case 4: return current_terrain->sign_locs.size(); case 5: return town->sign_locs.size(); - case 6: return current_terrain->info_rect.size(); - case 7: return town->room_rect.size(); + case 6: return current_terrain->area_desc.size(); + case 7: return town->area_desc.size(); } return 0; } @@ -57,8 +57,8 @@ static void ensure_str(eStrMode str_mode, size_t which) { case 3: scenario.journal_strs.resize(which + 1, "*"); break; case 4: current_terrain->sign_locs.resize(which + 1, {-1, -1, "*"}); break; case 5: town->sign_locs.resize(which + 1, {-1, -1, "*"}); break; - case 6: current_terrain->info_rect.resize(which + 1, {-1, -1, -1, -1, "*"}); break; - case 7: town->room_rect.resize(which + 1, {-1, -1, -1, -1, "*"}); break; + case 6: current_terrain->area_desc.resize(which + 1, {-1, -1, -1, -1, "*"}); break; + case 7: town->area_desc.resize(which + 1, {-1, -1, -1, -1, "*"}); break; } } } @@ -72,8 +72,8 @@ static std::string& fetch_str(eStrMode str_mode, size_t which) { case 3: return scenario.journal_strs[which]; case 4: return current_terrain->sign_locs[which].text; case 5: return town->sign_locs[which].text; - case 6: return current_terrain->info_rect[which].descr; - case 7: return town->room_rect[which].descr; + case 6: return current_terrain->area_desc[which].descr; + case 7: return town->area_desc[which].descr; } throw "Invalid string mode " + std::to_string(str_mode) + " (valid are 0-5)"; } @@ -94,16 +94,16 @@ static std::string str_info(eStrMode str_mode, size_t which) { sout << ", " << town->sign_locs[which].y << ")"; break; case 6: - sout << "(" << current_terrain->info_rect[which].left; - sout << ", " << current_terrain->info_rect[which].top; - sout << ")|(" << current_terrain->info_rect[which].right; - sout << ", " << current_terrain->info_rect[which].bottom << ")"; + sout << "(" << current_terrain->area_desc[which].left; + sout << ", " << current_terrain->area_desc[which].top; + sout << ")|(" << current_terrain->area_desc[which].right; + sout << ", " << current_terrain->area_desc[which].bottom << ")"; break; case 7: - sout << "(" << town->room_rect[which].left; - sout << ", " << town->room_rect[which].top; - sout << ")|(" << town->room_rect[which].right; - sout << ", " << town->room_rect[which].bottom << ")"; + sout << "(" << town->area_desc[which].left; + sout << ", " << town->area_desc[which].top; + sout << ")|(" << town->area_desc[which].right; + sout << ", " << town->area_desc[which].bottom << ")"; break; } return sout.str(); @@ -305,7 +305,7 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, std break; case STRT_TOWN: for(cTown* town : scenario.towns) { - strings.push_back(town->town_name); + strings.push_back(town->name); } break; case STRT_SECTOR: @@ -313,7 +313,7 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, std for(size_t j = 0; j < scenario.outdoors.height(); j++) { std::ostringstream name; name << '[' << i << ',' << j << ']'; - name << ' ' << scenario.outdoors[i][j]->out_name; + name << ' ' << scenario.outdoors[i][j]->name; strings.push_back(name.str()); } } @@ -410,7 +410,7 @@ short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent, std case STRT_TALK: for(cTown* town : scenario.towns) { for(cPersonality who : town->talking.people) { - strings.push_back(who.title + " (in " + town->town_name + ")"); + strings.push_back(who.title + " (in " + town->name + ")"); } } break; diff --git a/src/scenedit/scen.townout.cpp b/src/scenedit/scen.townout.cpp index 66c24e93..60b1e40c 100644 --- a/src/scenedit/scen.townout.cpp +++ b/src/scenedit/scen.townout.cpp @@ -5,7 +5,7 @@ #include #include "scen.global.hpp" #include "scenario.hpp" -#include "regtown.hpp" +#include "town.hpp" #include "graphtool.hpp" #include "scen.graphics.hpp" #include "scen.townout.hpp" @@ -444,7 +444,7 @@ bool change_ter(short& change_from,short& change_to,short& chance) { static bool outdoor_details_event_filter(cDialog& me, std::string, eKeyMod) { if(!me.toast(true)) return true; - current_terrain->out_name = me["name"].getText(); + current_terrain->name = me["name"].getText(); current_terrain->comment = me["comment"].getText(); current_terrain->bg_out = me["bg-out"].getTextAsNum(); current_terrain->bg_fight = me["bg-fight"].getTextAsNum(); @@ -460,7 +460,7 @@ void outdoor_details() { str_out << "X = " << cur_out.x << ", Y = " << cur_out.y; out_dlg["loc"].setText(str_out.str()); out_dlg["comment"].setText(current_terrain->comment); - out_dlg["name"].setText(current_terrain->out_name); + out_dlg["name"].setText(current_terrain->name); out_dlg["bg-out"].setTextToNum(current_terrain->bg_out); out_dlg["bg-fight"].setTextToNum(current_terrain->bg_fight); out_dlg["bg-town"].setTextToNum(current_terrain->bg_town); @@ -622,7 +622,7 @@ void edit_out_wand(short mode) { static bool save_town_details(cDialog& me, std::string, eKeyMod) { if(!me.toast(true)) return true; - town->town_name = me["name"].getText(); + town->name = me["name"].getText(); town->town_chop_time = me["chop"].getTextAsNum(); town->town_chop_key = me["key"].getTextAsNum(); town->max_num_monst = me["population"].getTextAsNum(); @@ -641,7 +641,7 @@ static bool save_town_details(cDialog& me, std::string, eKeyMod) { } static void put_town_details_in_dlog(cDialog& me) { - me["name"].setText(town->town_name); + me["name"].setText(town->name); me["chop"].setTextToNum(town->town_chop_time); me["key"].setTextToNum(town->town_chop_key); me["population"].setTextToNum(town->max_num_monst); @@ -1133,7 +1133,7 @@ static void put_out_loc_in_dlog(cDialog& me, location cur_loc, cScenario& scenar str.str(""); str << "Y = " << cur_loc.y; me["y"].setText(str.str()); - me["title"].setText(scenario.outdoors[cur_loc.x][cur_loc.y]->out_name); + me["title"].setText(scenario.outdoors[cur_loc.x][cur_loc.y]->name); } static bool pick_out_event_filter(cDialog& me, std::string item_hit, location& cur_loc, cScenario& scenario) { @@ -1199,17 +1199,17 @@ bool new_town(short which_town) { std::string size = dynamic_cast(new_dlg->getControl("size")).getSelected(); std::string preset = dynamic_cast(new_dlg->getControl("preset")).getSelected(); - if(size == "lg") scenario.towns.push_back(new cBigTown(scenario)); - else if(size == "med") scenario.towns.push_back(new cMedTown(scenario)); - else if(size == "sm") scenario.towns.push_back(new cTinyTown(scenario)); + if(size == "lg") scenario.towns.push_back(new cTown(scenario, AREA_LARGE)); + else if(size == "med") scenario.towns.push_back(new cTown(scenario, AREA_MEDIUM)); + else if(size == "sm") scenario.towns.push_back(new cTown(scenario, AREA_SMALL)); cur_town = which_town; town = scenario.towns[cur_town]; scenario.last_town_edited = cur_town; - town->town_name = new_dlg->getControl("name").getText().substr(0,30); + town->name = new_dlg->getControl("name").getText().substr(0,30); - for(short i = 0; i < town->max_dim(); i++) - for(short j = 0; j < town->max_dim(); j++) + for(short i = 0; i < town->max_dim; i++) + for(short j = 0; j < town->max_dim; j++) if(preset == "cave") { town->terrain(i,j) = 0; } else { @@ -1286,7 +1286,7 @@ static void fill_resize_outdoors(cDialog& me, int top, int left, int right, int auto txtHeight = txtBounds.height(); txtHeight = 0; for(location l : del) { - list << '(' << l.x << ", " << l.y << ") " << scenario.outdoors[l.x][l.y]->out_name << '|'; + list << '(' << l.x << ", " << l.y << ") " << scenario.outdoors[l.x][l.y]->name << '|'; txtHeight += 10; } me["delete"].setText(list.str()); diff --git a/src/tools/fileio.hpp b/src/tools/fileio.hpp index beaac579..e1c766b4 100644 --- a/src/tools/fileio.hpp +++ b/src/tools/fileio.hpp @@ -6,6 +6,9 @@ * */ +#ifndef BOE_FILEIO_HPP +#define BOE_FILEIO_HPP + #include #include #include @@ -28,9 +31,19 @@ void check_for_intel(); std::string read_maybe_quoted_string(std::istream& from); std::string maybe_quote_string(std::string which); -template -void writeArray(std::ostream& to, const T(* array)[D], int width, int height) { - using int_type = decltype(T() + 1); +template +struct array_value_type{ + using type = typename T::value_type; +}; + +template +struct array_value_type { + using type = T; +}; + +template +void writeArray(std::ostream& to, const T& array, int width, int height) { + using int_type = decltype(typename array_value_type::type() + 1); for(int y = 0; y < height; y++) { to << array[0][y]; for(int x = 1; x < width; x++) @@ -40,9 +53,9 @@ void writeArray(std::ostream& to, const T(* array)[D], int width, int height) { to << '\f'; } -template -void readArray(std::istream& from, T(* array)[D], int width, int height) { - using int_type = decltype(T() + 1); +template +void readArray(std::istream& from, T& array, int width, int height) { + using int_type = decltype(typename array_value_type::type() + 1); from >> std::ws; std::string arrayContents; getline(from, arrayContents, '\f'); @@ -88,3 +101,5 @@ public: return pos; } }; + +#endif diff --git a/src/tools/fileio_party.cpp b/src/tools/fileio_party.cpp index bb18a999..5ad97077 100644 --- a/src/tools/fileio_party.cpp +++ b/src/tools/fileio_party.cpp @@ -248,8 +248,8 @@ bool load_party_v1(fs::path file_to_load, cUniverse& real_univ, bool town_restor univ.import_legacy(o_maps); univ.town.import_legacy(sfx, misc_i); if(town_restore) // Check items in crates/barrels - for(int i = 0; i < univ.town->max_dim(); i++) { - for(int j = 0; j < univ.town->max_dim(); j++) { + for(int i = 0; i < univ.town->max_dim; i++) { + for(int j = 0; j < univ.town->max_dim; j++) { if(univ.town.is_barrel(i,j) || univ.town.is_crate(i,j)) { for(cItem item : univ.town.items) { if(item.item_loc == loc(i,j) && item.contained) diff --git a/src/tools/fileio_scen.cpp b/src/tools/fileio_scen.cpp index 57fb19a7..9c44b55f 100644 --- a/src/tools/fileio_scen.cpp +++ b/src/tools/fileio_scen.cpp @@ -15,7 +15,7 @@ #include "strdlog.hpp" #include "scenario.hpp" -#include "regtown.hpp" +#include "town.hpp" #include "map_parse.hpp" #include "special_parse.hpp" #include "graphtool.hpp" @@ -26,6 +26,10 @@ #include "porting.hpp" #include "restypes.hpp" +// Because the full template definition needs to be visible in this file +// Also, for some reason, it's not found in the include paths, so use a relative path +#include "../classes/town_import.tpp" + bool cur_scen_is_mac = true; extern cCustomGraphics spec_scen_g; extern fs::path tempDir; @@ -218,9 +222,9 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head scenario.towns.resize(scenario.format.num_towns); for(int i = 0; i < scenario.format.num_towns; i++) { switch(temp_scenario->town_size[i]) { - case 0: scenario.towns[i] = new cBigTown(scenario); break; - case 1: scenario.towns[i] = new cMedTown(scenario); break; - case 2: scenario.towns[i] = new cTinyTown(scenario); break; + case 0: scenario.towns[i] = new cTown(scenario, AREA_LARGE); break; + case 1: scenario.towns[i] = new cTown(scenario, AREA_MEDIUM); break; + case 2: scenario.towns[i] = new cTown(scenario, AREA_SMALL); break; } load_town_v1(scenario.scen_file, i, *scenario.towns[i], *temp_scenario, shops); } @@ -1478,7 +1482,7 @@ void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) { for(elem = elem.begin(data.FirstChildElement()); elem != elem.end(); elem++) { elem->GetValue(&type); if(type == "name") { - elem->GetText(&out.out_name, false); + elem->GetText(&out.name, false); found_name = true; } else if(type == "comment") { elem->GetText(&out.comment, false); @@ -1555,10 +1559,10 @@ void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) { out.sign_locs.resize(sign + 1); elem->GetText(&out.sign_locs[sign].text, false); } else if(type == "area") { - if(num_rects >= out.info_rect.size()) - out.info_rect.resize(num_rects + 1); - static_cast(out.info_rect[num_rects]) = readRectFromXml(*elem); - elem->GetText(&out.info_rect[num_rects].descr, false); + if(num_rects >= out.area_desc.size()) + out.area_desc.resize(num_rects + 1); + static_cast(out.area_desc[num_rects]) = readRectFromXml(*elem); + elem->GetText(&out.area_desc[num_rects].descr, false); num_rects++; } else if(type == "string") { int str; @@ -1588,19 +1592,16 @@ void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) { elem->GetValue(&type); reqs.erase(type); if(type == "size") { - elem->GetText(&val); - if(val == "32") { - town = new cTinyTown(scen); - } else if(val == "48") { - town = new cMedTown(scen); - } else if(val == "64") { - town = new cBigTown(scen); - } else throw xBadVal(type, xBadVal::CONTENT, val, elem->Row(), elem->Column(), fname); + size_t dim; + elem->GetText(&dim); + if(dim < 24) + throw xBadVal(type, xBadVal::CONTENT, val, elem->Row(), elem->Column(), fname); + else town = new cTown(scen, dim); found_size = true; } else if(!found_size) { throw xBadNode(type, elem->Row(), elem->Column(), fname); } else if(type == "name") { - elem->GetText(&town->town_name, false); + elem->GetText(&town->name, false); } else if(type == "comment") { if(num_cmt >= 3) throw xBadNode(type, elem->Row(), elem->Column(), fname); @@ -1771,10 +1772,10 @@ void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) { if(!reqs.empty()) throw xMissingElem("creature", *reqs.begin(), elem->Row(), elem->Column(), fname); } else if(type == "area") { - if(num_rects >= town->room_rect.size()) - town->room_rect.resize(num_rects + 1); - static_cast(town->room_rect[num_rects]) = readRectFromXml(*elem); - elem->GetText(&town->room_rect[num_rects].descr, false); + if(num_rects >= town->area_desc.size()) + town->area_desc.resize(num_rects + 1); + static_cast(town->area_desc[num_rects]) = readRectFromXml(*elem); + elem->GetText(&town->area_desc[num_rects].descr, false); num_rects++; } else throw xBadNode(type, elem->Row(), elem->Column(), fname); } @@ -1926,8 +1927,8 @@ void loadOutMapData(map_data&& data, location which, cScenario& scen) { void loadTownMapData(map_data&& data, int which, cScenario& scen) { cTown& town = *scen.towns[which]; - for(int x = 0; x < town.max_dim(); x++) { - for(int y = 0; y < town.max_dim(); y++) { + for(int x = 0; x < town.max_dim; x++) { + for(int y = 0; y < town.max_dim; y++) { town.terrain(x,y) = data.get(x,y); auto features = data.getFeatures(x,y); for(auto feat : features) { @@ -2242,14 +2243,14 @@ bool load_town_v1(fs::path scen_file, short which_town, cTown& the_town, legacy: the_town.spec_strs.resize(100); the_town.sign_locs.resize(20); - the_town.room_rect.resize(16); + the_town.area_desc.resize(16); for(short i = 0; i < 140; i++) { len = (long) (store_town.strlens[i]); fread(temp_str, len, 1, file_id); temp_str[len] = 0; - if(i == 0) the_town.town_name = temp_str; + if(i == 0) the_town.name = temp_str; else if(i >= 1 && i < 17) - the_town.room_rect[i-1].descr = temp_str; + the_town.area_desc[i-1].descr = temp_str; else if(i >= 17 && i < 20) the_town.comment[i-17] = temp_str; else if(i >= 20 && i < 120) @@ -2352,14 +2353,14 @@ bool load_outdoors_v1(fs::path scen_file, location which_out,cOutdoors& the_out, the_out.import_legacy(store_out); the_out.spec_strs.resize(90); the_out.sign_locs.resize(8); - the_out.info_rect.resize(8); + the_out.area_desc.resize(8); for(short i = 0; i < 108; i++) { len = (long) (store_out.strlens[i]); fread(temp_str, len, 1, file_id); temp_str[len] = 0; - if(i == 0) the_out.out_name = temp_str; + if(i == 0) the_out.name = temp_str; else if(i == 9) the_out.comment = temp_str; - else if(i < 9) the_out.info_rect[i-1].descr = temp_str; + else if(i < 9) the_out.area_desc[i-1].descr = temp_str; else if(i >= 10 && i < 100) the_out.spec_strs[i-10] = temp_str; else if(i >= 100 && i < 108) diff --git a/src/tools/vector2d.hpp b/src/tools/vector2d.hpp index d9108677..f31c865f 100644 --- a/src/tools/vector2d.hpp +++ b/src/tools/vector2d.hpp @@ -22,6 +22,7 @@ template> class vector2d { std::vector data; size_t w, h; public: + using value_type = Type; class row_ref { friend class vector2d; vector2d& ref; @@ -120,6 +121,12 @@ public: const_row_ref row(size_t x) const { return const_row_ref(*this, x); } + Type& operator()(size_t x, size_t y) { + return (*this)[x][y]; + } + const Type& operator()(size_t x, size_t y) const { + return (*this)[x][y]; + } size_t width() const { return w; } @@ -162,7 +169,9 @@ public: return data.empty(); } vector2d() : w(0), h(0) {} - 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); + } }; #endif diff --git a/test/out_legacy.cpp b/test/out_legacy.cpp index 5fadda16..36f14450 100644 --- a/test/out_legacy.cpp +++ b/test/out_legacy.cpp @@ -40,8 +40,8 @@ TEST_CASE("Converting legacy outdoor section data") { CHECK(sector.bg_out == -1); CHECK(sector.bg_town == -1); CHECK(sector.out_sound == 0); - REQUIRE(sector.info_rect.size() >= 1); - CHECK(sector.info_rect[0] == rect(106,110,222,180)); + REQUIRE(sector.area_desc.size() >= 1); + CHECK(sector.area_desc[0] == rect(106,110,222,180)); REQUIRE(sector.sign_locs.size() >= 1); CHECK(sector.sign_locs[0] == loc(21,25)); REQUIRE(sector.wandering_locs.size() >= 4); diff --git a/test/out_read.cpp b/test/out_read.cpp index e8ae18bc..ba9b9466 100644 --- a/test/out_read.cpp +++ b/test/out_read.cpp @@ -117,8 +117,8 @@ TEST_CASE("Loading an outdoor section definition") { CHECK(sector.wandering[0] == refEncounter); REQUIRE(sector.sign_locs.size() >= 8); CHECK(sector.sign_locs[7].text == "The best sign ever!"); - REQUIRE(sector.info_rect.size() >= 1); - CHECK(sector.info_rect[0].descr == "Some random area Amazing!"); + REQUIRE(sector.area_desc.size() >= 1); + CHECK(sector.area_desc[0].descr == "Some random area Amazing!"); REQUIRE(sector.spec_strs.size() >= 10); CHECK(sector.spec_strs[9] == "A random special string"); } diff --git a/test/out_write.cpp b/test/out_write.cpp index 510b56f8..325d5a80 100644 --- a/test/out_write.cpp +++ b/test/out_write.cpp @@ -52,15 +52,15 @@ TEST_CASE("Saving an outdoors sector") { out.comment = "Let's make a comment about comments."; out.ambient_sound = AMBIENT_DRIP; out.sign_locs.emplace_back(0,0,"Guantanamo - 14 mi."); - out.info_rect.emplace_back(0,0,1,1,"The heart of the wilderness"); + out.area_desc.emplace_back(0,0,1,1,"The heart of the wilderness"); out.spec_strs.emplace_back("Something happened!"); in_and_out("optional", out, scen); CHECK(out.comment == "Let's make a comment about comments."); CHECK(out.ambient_sound == AMBIENT_DRIP); REQUIRE(out.sign_locs.size() >= 1); CHECK(out.sign_locs[0].text == "Guantanamo - 14 mi."); - REQUIRE(out.info_rect.size() >= 1); - CHECK(out.info_rect[0].descr == "The heart of the wilderness"); + REQUIRE(out.area_desc.size() >= 1); + CHECK(out.area_desc[0].descr == "The heart of the wilderness"); REQUIRE(out.spec_strs.size() >= 1); CHECK(out.spec_strs[0] == "Something happened!"); } diff --git a/test/town_read.cpp b/test/town_read.cpp index 56c08e1a..3dffb377 100644 --- a/test/town_read.cpp +++ b/test/town_read.cpp @@ -130,7 +130,7 @@ TEST_CASE("Loading a town definition") { fin.open("files/town/minimal.xml"); doc = xmlDocFromStream(fin, "minimal.xml"); REQUIRE_NOTHROW(readTownFromXml(move(doc), town, scen)); - CHECK(town->max_dim() == 32); + CHECK(town->max_dim == 32); CHECK(town->town_name == "Test Town"); CHECK(town->in_town_rect == rect(4, 4, 28, 28)); CHECK(town->difficulty == 1); @@ -188,8 +188,8 @@ TEST_CASE("Loading a town definition") { CHECK(town->creatures[12].personality == 1); CHECK(town->creatures[12].special_on_kill == 80); CHECK(town->creatures[12].special_on_talk == 81); - REQUIRE(town->room_rect.size() >= 1); - CHECK(town->room_rect[0].descr == "This is a sample area description."); + REQUIRE(town->area_desc.size() >= 1); + CHECK(town->area_desc[0].descr == "This is a sample area description."); } delete town; diff --git a/test/town_write.cpp b/test/town_write.cpp index 30ba0999..69d4b166 100644 --- a/test/town_write.cpp +++ b/test/town_write.cpp @@ -45,7 +45,7 @@ TEST_CASE("Saving a town") { town->lighting_type = LIGHT_NONE; SECTION("With the minimal required information") { in_and_out("basic", town, scen); - CHECK(town->max_dim() == 32); + CHECK(town->max_dim == 32); CHECK(town->town_name == "Test Town"); CHECK(town->in_town_rect == rect(2,3,30,29)); CHECK(town->difficulty == 1); @@ -73,7 +73,7 @@ TEST_CASE("Saving a town") { town->wandering[0].monst = {7,8,9,10}; town->sign_locs.emplace_back(0,0,"Sign #4279816"); town->spec_strs.emplace_back("Something! With extra spaces!"); - town->room_rect.emplace_back(0,0,1,1,"Unknown Area . . ."); + town->area_desc.emplace_back(0,0,1,1,"Unknown Area . . ."); in_and_out("optional", town, scen); CHECK(town->comment[2] == "Try a comment!"); CHECK(town->spec_on_entry == 42); @@ -102,8 +102,8 @@ TEST_CASE("Saving a town") { CHECK(town->sign_locs[0].text == "Sign #4279816"); REQUIRE(town->spec_strs.size() >= 1); CHECK(town->spec_strs[0] == "Something! With extra spaces!"); - REQUIRE(town->room_rect.size() >= 1); - CHECK(town->room_rect[0].descr == "Unknown Area . . ."); + REQUIRE(town->area_desc.size() >= 1); + CHECK(town->area_desc[0].descr == "Unknown Area . . ."); } SECTION("With a preset item") { town->preset_items.emplace_back();