From 4b96f579b7e2631d65f5a48fe1bccbcc3599e7d9 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Mon, 22 Dec 2014 00:20:37 -0500 Subject: [PATCH] Embark on an epic journey to make both the game and the two editors load the entire scenario into memory. Some other tweaks and fixes got pulled in along the way. Details: - Improved const-correctness - The scenario is now part of the universe, so now there's no global scenario object in the game or the PC editor. (Of course, the scenario editor has no universe, so it still has a global scenario object.) - Towns and outdoors now store a reference to the scenario; the party, current town, and current outdoors store a reference to the universe. Altogether this means that the data module has no need for global scenario or universe objects. - The fileio routines now take a scenario or universe reference as a parameter, so they don't need the global scenario or universe objects either. - cCurOut now has an arrow operator for accessing the current outdoor section, instead of a 2x2 subset of the outdoors; this replaces using i_w_c to index the 2x2 subset. (And it's much less verbose!) - cCurTown no longer stores a pointer to the town record, since it can simply access it through the universe instance which it stores a reference to. - Tweaked how the monster roster menu works (it now caches up to 60 monsters) - The operator= functions that convert from legacy to new scenario/save format are now ordinary functions rather than operators. - The bizarre use of assigning a cCreature to itself to populate certain fields has been nuked. - When at the corner of an outdoor sector, the scenario editor now shows the cornermost terrain in the diagonally adjacent sector. - There was a missing check to prevent horses entering dangerous terrain (eg, swamp) while in town. - Fix cancelling load party dialog causing a party to appear --- osx/BoE.xcodeproj/project.pbxproj | 2 + osx/boe.actions.cpp | 136 ++++---- osx/boe.appleevents.mm | 4 +- osx/boe.combat.cpp | 3 +- osx/boe.dlgutil.cpp | 17 +- osx/boe.fileio.cpp | 104 +++---- osx/boe.fileio.h | 2 - osx/boe.graphics.cpp | 57 ++-- osx/boe.graphutil.cpp | 76 ++--- osx/boe.infodlg.cpp | 64 ++-- osx/boe.itemdata.cpp | 5 +- osx/boe.items.cpp | 5 +- osx/boe.locutils.cpp | 31 +- osx/boe.main.cpp | 20 +- osx/boe.menus.mac.mm | 6 +- osx/boe.monster.cpp | 46 ++- osx/boe.newgraph.cpp | 3 +- osx/boe.party.cpp | 203 +++--------- osx/boe.party.h | 2 - osx/boe.specials.cpp | 135 ++++---- osx/boe.text.cpp | 9 +- osx/boe.town.cpp | 116 ++++--- osx/boe.townspec.cpp | 3 +- osx/classes.h | 6 - osx/classes/creatlist.cpp | 38 ++- osx/classes/creatlist.h | 5 +- osx/classes/item.cpp | 11 +- osx/classes/item.h | 10 +- osx/classes/monster.cpp | 74 +---- osx/classes/monster.h | 21 +- osx/classes/outdoors.cpp | 52 ++-- osx/classes/outdoors.h | 15 +- osx/classes/party.cpp | 63 +++- osx/classes/party.h | 9 +- osx/classes/pc.cpp | 19 +- osx/classes/pc.h | 6 +- osx/classes/regtown.cpp | 111 ++----- osx/classes/regtown.h | 24 +- osx/classes/scenario.cpp | 102 +++++- osx/classes/scenario.h | 17 +- osx/classes/special.cpp | 3 +- osx/classes/special.h | 4 +- osx/classes/talking.cpp | 3 +- osx/classes/talking.h | 4 +- osx/classes/terrain.cpp | 3 +- osx/classes/terrain.h | 4 +- osx/classes/tmpltown.cpp | 6 +- osx/classes/tmpltown.h | 21 +- osx/classes/town.cpp | 54 +++- osx/classes/town.h | 15 +- osx/classes/universe.cpp | 237 ++++++-------- osx/classes/universe.h | 25 +- osx/classes/vehicle.cpp | 8 +- osx/classes/vehicle.h | 6 +- osx/pcedit/pc.fileio.cpp | 7 +- osx/pcedit/pc.fileio.h | 1 - osx/pcedit/pc.main.cpp | 16 +- osx/pcedit/pc.menus.mac.mm | 8 +- osx/scenedit/scen.actions.cpp | 228 +++++++------- osx/scenedit/scen.core.cpp | 123 +------- osx/scenedit/scen.core.h | 1 - osx/scenedit/scen.fileio.cpp | 99 ++---- osx/scenedit/scen.fileio.h | 4 - osx/scenedit/scen.graphics.cpp | 52 ++-- osx/scenedit/scen.keydlgs.cpp | 70 ++--- osx/scenedit/scen.main.cpp | 23 +- osx/scenedit/scen.townout.cpp | 107 +------ osx/scenedit/scen.townout.h | 3 +- osx/tools/fileio.cpp | 498 ++++++------------------------ osx/tools/fileio.h | 18 +- osx/tools/vector2d.hpp | 70 +++++ 71 files changed, 1383 insertions(+), 1970 deletions(-) create mode 100644 osx/tools/vector2d.hpp diff --git a/osx/BoE.xcodeproj/project.pbxproj b/osx/BoE.xcodeproj/project.pbxproj index c6e1b4e7..50da8b18 100644 --- a/osx/BoE.xcodeproj/project.pbxproj +++ b/osx/BoE.xcodeproj/project.pbxproj @@ -668,6 +668,7 @@ 915E09081A316D89008BDF00 /* map_parse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = map_parse.cpp; sourceTree = ""; }; 9179A45E1A42986200FEF872 /* graphics.exd */ = {isa = PBXFileReference; lastKnownFileType = folder; path = graphics.exd; sourceTree = ""; }; 9179A45F1A42988200FEF872 /* sounds.exa */ = {isa = PBXFileReference; lastKnownFileType = folder; path = sounds.exa; sourceTree = ""; }; + 9179A4621A47D4E200FEF872 /* vector2d.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = vector2d.hpp; sourceTree = ""; }; 917B573F100B956C0096C978 /* undo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = undo.h; sourceTree = ""; }; 918D59A718EA513900735B66 /* dialog.keys.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dialog.keys.h; sourceTree = ""; }; 919145FB18E3A32F005CF3A4 /* boe.appleevents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = boe.appleevents.mm; sourceTree = ""; }; @@ -1011,6 +1012,7 @@ 91EC480E18FBAA8700BB1E86 /* prefs.hpp */, 91B3F10E0F9779D000BF5B67 /* soundtool.h */, 91BFA3D91902ADD5001686E4 /* tarball.hpp */, + 9179A4621A47D4E200FEF872 /* vector2d.hpp */, 91F06E8F1A2EBEE70038E902 /* special_parse.hpp */, 917B573F100B956C0096C978 /* undo.h */, 919145FE18E63B41005CF3A4 /* winutil.h */, diff --git a/osx/boe.actions.cpp b/osx/boe.actions.cpp index f0b35ee1..a04d0cae 100644 --- a/osx/boe.actions.cpp +++ b/osx/boe.actions.cpp @@ -101,7 +101,6 @@ extern eSpell store_mage, store_priest; //extern town_item_list t_i; // shouldn't be here //extern unsigned char misc_i[64][64]; extern short spec_item_array[60]; -extern cScenario scenario; extern cUniverse univ; //extern piles_of_stuff_dumping_type *data_store; extern std::vector talk_words; @@ -345,7 +344,7 @@ static void handle_rest(bool& need_redraw, bool& need_reprint) { add_string_to_buf("Rest: Not enough food. "); else if(nearest_monster() <= 3) add_string_to_buf("Rest: Monster too close. "); - else if(scenario.ter_types[ter].special == eTerSpec::DAMAGING || scenario.ter_types[ter].special == eTerSpec::DANGEROUS) + else if(univ.scenario.ter_types[ter].special == eTerSpec::DAMAGING || univ.scenario.ter_types[ter].special == eTerSpec::DANGEROUS) add_string_to_buf("Rest: It's dangerous here."); else if(flying()) add_string_to_buf("Rest: Not while flying. "); @@ -453,9 +452,9 @@ static void handle_look(location destination, bool& need_redraw, bool& need_repr } } else if(overall_mode == MODE_LOOK_OUTDOORS) { for(int k = 0; k < 8; k++) { - if(destination == univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].sign_locs[k]) { + if(destination == univ.out->sign_locs[k]) { need_reprint = true; - if(adjacent(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].sign_locs[k],univ.party.loc_in_sec)) + if(adjacent(univ.out->sign_locs[k],univ.party.loc_in_sec)) do_sign(200 + get_outdoor_num(),k,ter_looked_at); else add_string_to_buf(" Too far away to read sign. "); } @@ -506,7 +505,7 @@ static void handle_move(location destination, bool& did_something, bool& need_re } else need_redraw = true; ter_num_t storage = univ.out[univ.party.p_loc.x][univ.party.p_loc.y]; - if(scenario.ter_types[storage].special == eTerSpec::TOWN_ENTRANCE) { + if(univ.scenario.ter_types[storage].special == eTerSpec::TOWN_ENTRANCE) { short find_direction_from; if(univ.party.direction == 0) find_direction_from = 2; else if(univ.party.direction == 4) find_direction_from = 0; @@ -514,10 +513,10 @@ static void handle_move(location destination, bool& did_something, bool& need_re else find_direction_from = 1; for(int i = 0; i < 8; i++) - if(univ.party.loc_in_sec == univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].exit_locs[i]) { - short which_t = univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].exit_dests[i]; + if(univ.party.loc_in_sec == univ.out->exit_locs[i]) { + short which_t = univ.out->exit_dests[i]; if(which_t >= 0) - start_town_mode(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].exit_dests[i], find_direction_from); + start_town_mode(univ.out->exit_dests[i], find_direction_from); if(is_town()) { need_redraw = false; i = 8; @@ -547,7 +546,7 @@ static void handle_talk(location destination, bool& did_something, bool& need_re if(!univ.town.monst[i].summoned) small_talk = -univ.town.monst[i].personality; std::string str = "No response."; - if(small_talk > 1000) str = scenario.spec_strs[small_talk - 1000]; + if(small_talk > 1000) str = univ.scenario.spec_strs[small_talk - 1000]; // TODO: Come up with a set of pre-cooked responses. add_string_to_buf("Talk: " + str, 4); } else { @@ -902,7 +901,7 @@ static void handle_victory() {reload_startup(); if(cChoiceDlog("congrats-save.xml",{"cancel","save"}).show() == "save"){ // TODO: Wait, this shouldn't be a "save as" action, should it? It should save without asking for a location. fs::path file = nav_put_party(); - if(!file.empty()) save_party(file); + if(!file.empty()) save_party(file, univ); } } @@ -1051,7 +1050,7 @@ bool handle_action(sf::Event event) { case 5: if(overall_mode == MODE_OUTDOORS) { - save_party(univ.file); + save_party(univ.file, univ); need_redraw = true; current_switch = 6; break; @@ -1922,11 +1921,11 @@ bool handle_keystroke(sf::Event& event){ add_string_to_buf(" Not while on horse. "); break; } - force_town_enter(scenario.which_town_start,scenario.where_start); - start_town_mode(scenario.which_town_start,9); - position_party(scenario.out_sec_start.x,scenario.out_sec_start.y, - scenario.out_start.x,scenario.out_start.y); - center = univ.town.p_loc = scenario.where_start; + force_town_enter(univ.scenario.which_town_start,univ.scenario.where_start); + start_town_mode(univ.scenario.which_town_start,9); + position_party(univ.scenario.out_sec_start.x,univ.scenario.out_sec_start.y, + univ.scenario.out_start.x,univ.scenario.out_start.y); + center = univ.town.p_loc = univ.scenario.where_start; redraw_screen(REFRESH_ALL); add_string_to_buf("Debug: You return to the start."); print_buf(); @@ -1952,9 +1951,9 @@ bool handle_keystroke(sf::Event& event){ case 'T': if(!in_scen_debug) break; short find_direction_from; - sout << "Enter Town Number (between 0 and " << scenario.num_towns - 1 << ')'; - i = get_num_response(0, scenario.num_towns - 1, "Enter Town Number"); - if(i >= 0 && i < scenario.num_towns ){ + sout << "Enter Town Number (between 0 and " << univ.scenario.num_towns - 1 << ')'; + i = get_num_response(0, univ.scenario.num_towns - 1, "Enter Town Number"); + if(i >= 0 && i < univ.scenario.num_towns) { if(univ.party.direction == 0) find_direction_from = 2; else if(univ.party.direction == 4) find_direction_from = 0; else if(univ.party.direction < 4) find_direction_from = 3; @@ -2137,9 +2136,9 @@ bool handle_keystroke(sf::Event& event){ void do_load() { fs::path file_to_load = nav_get_party(); - if(!file_to_load.empty()) - if(!load_party(file_to_load)) - return; + if(file_to_load.empty()) return; + if(!load_party(file_to_load, univ)) + return; finish_load_party(); if(overall_mode != MODE_STARTUP) post_load(); @@ -2187,7 +2186,7 @@ void do_save(short mode) { if(mode == 1) file = nav_put_party(file); if(!file.empty()) { univ.file = file; - save_party(univ.file); + save_party(univ.file, univ); } @@ -2296,7 +2295,7 @@ void increase_age() { if(PSD[SDF_PARTY_FLIGHT] == 2) add_string_to_buf("You are starting to descend."); if(PSD[SDF_PARTY_FLIGHT] == 1) { - if(blocksMove(scenario.ter_types[univ.out[univ.party.p_loc.x][univ.party.p_loc.y]].blockage)) { + if(blocksMove(univ.scenario.ter_types[univ.out[univ.party.p_loc.x][univ.party.p_loc.y]].blockage)) { add_string_to_buf(" You plummet to your deaths. "); slay_party(eMainStatus::DEAD); print_buf(); @@ -2507,7 +2506,7 @@ void handle_hunting() { // TODO: Resupport this! ter = univ.out[univ.party.p_loc.x][univ.party.p_loc.y]; - pic = scenario.ter_types[ter].picture; + pic = univ.scenario.ter_types[ter].picture; for(i = 0; i < 6; i++) if(univ.party[i].main_status == eMainStatus::ALIVE && univ.party[i].traits[eTrait::CAVE_LORE] && get_ran(1,0,12) == 5 && (((pic >= 0) && (pic <= 1)) || ((pic >= 70) && (pic <= 76))) ) { @@ -2584,7 +2583,7 @@ void handle_death() { } else if(choice == "load") { fs::path file_to_load = nav_get_party(); - if(!file_to_load.empty()) load_party(file_to_load); + if(!file_to_load.empty()) load_party(file_to_load, univ); if(!party_toast()) { if(overall_mode != MODE_STARTUP) post_load(), finish_load_party(); @@ -2610,19 +2609,32 @@ void start_new_game() { return; //which = choice - 1; + // Destroy the universe + univ.~cUniverse(); + + long party_type = 'dflt'; // display_intro(); - if(kb::isKeyPressed(kb::LSystem) || kb::isKeyPressed(kb::RSystem)) init_party(2); // if command key held down, create debug party - else if(kb::isKeyPressed(kb::LControl) || kb::isKeyPressed(kb::RControl)) init_party(2); - else init_party(0); + // If system key held down, create debug party +#ifdef __APPLE__ + if(kb::isKeyPressed(kb::LSystem) || kb::isKeyPressed(kb::RSystem)) +#else + if(kb::isKeyPressed(kb::LControl) || kb::isKeyPressed(kb::RControl)) +#endif + party_type = 'dbug'; + + // And now, reconstruct the universe. + new(&univ) cUniverse(party_type); + + // Default is save maps + PSD[SDF_NO_MAPS] = 0; + save_maps = true; + + // The original code called build_outdoors here, but they're not even in a scenario, so I removed it. + // It was probably a relic of Exile III. + // (It also refreshed stores... with uninitialized items.) - //while(!creation_done) { edit_party(); - /* if((i > 0) || !in_startup_mode) - creation_done = true; - if((i == 0) && !in_startup_mode) - return; - } */ // if no PCs left, forget it for(i = 0 ; i < 6; i++) @@ -2656,7 +2668,7 @@ void start_new_game() { univ.party[i].cur_sp = univ.party[i].max_sp; } fs::path file = nav_put_party(); - if(!file.empty()) save_party(file); + if(!file.empty()) save_party(file, univ); party_in_memory = true; party_in_memory = true; @@ -2691,12 +2703,12 @@ static eDirection find_waterfall(short x, short y, short mode){ bool to_dir[8]; for(eDirection i = DIR_N; i < DIR_HERE; i++){ if(mode == 0){ - to_dir[i] = scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].special == eTerSpec::WATERFALL; + to_dir[i] = univ.scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].special == eTerSpec::WATERFALL; //printf("%i\n",scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].flag1); - if(scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].flag1.u != i) to_dir[i] = false; + if(univ.scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].flag1.u != i) to_dir[i] = false; }else{ - to_dir[i] = scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].special == eTerSpec::WATERFALL; - if(scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].flag1.u != i) to_dir[i] = false; + to_dir[i] = univ.scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].special == eTerSpec::WATERFALL; + if(univ.scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].flag1.u != i) to_dir[i] = false; } } short count = 0; @@ -2802,12 +2814,12 @@ bool outd_move_party(location destination,bool forced) { // Check if party moves into new sector if((destination.x < 6) && (univ.party.outdoor_corner.x > 0)) shift_universe_left(); - if((destination.x > 90) && (univ.party.outdoor_corner.x < scenario.out_width - 1)) + if(destination.x > 90 && univ.party.outdoor_corner.x < univ.scenario.out_width - 1) shift_universe_right(); if((destination.y < 6) && (univ.party.outdoor_corner.y > 0)) { shift_universe_up(); } - else if((destination.y > 90) && (univ.party.outdoor_corner.y < scenario.out_height - 1)) + else if(destination.y > 90 && univ.party.outdoor_corner.y < univ.scenario.out_height - 1) shift_universe_down(); // Now stop from going off the world's edge real_dest.x = univ.party.p_loc.x + real_dest.x; @@ -2816,8 +2828,8 @@ bool outd_move_party(location destination,bool forced) { ASB("You've reached the world's edge."); return false; } - if(((real_dest.x > 94 /*92*/) && (univ.party.outdoor_corner.x >= scenario.out_width - 2)) || - ((real_dest.x > 46 /*44*/) && (univ.party.outdoor_corner.x >= scenario.out_width - 1))) { + if((real_dest.x > 94 /*92*/ && univ.party.outdoor_corner.x >= univ.scenario.out_width - 2) || + (real_dest.x > 46 /*44*/ && univ.party.outdoor_corner.x >= univ.scenario.out_width - 1)) { ASB("You've reached the world's edge."); return false; } @@ -2825,8 +2837,8 @@ bool outd_move_party(location destination,bool forced) { ASB("You've reached the world's edge."); return false; } - else if(((real_dest.y > 94 /*92*/) && (univ.party.outdoor_corner.y >= scenario.out_height - 2)) || - ((real_dest.y > 46 /*44*/) && (univ.party.outdoor_corner.y >= scenario.out_height - 1))) { + else if((real_dest.y > 94 /*92*/ && univ.party.outdoor_corner.y >= univ.scenario.out_height - 2) || + (real_dest.y > 46 /*44*/ && univ.party.outdoor_corner.y >= univ.scenario.out_height - 1)) { ASB("You've reached the world's edge."); return false; } @@ -2846,9 +2858,9 @@ bool outd_move_party(location destination,bool forced) { if(univ.party.in_boat >= 0) { if(!outd_is_blocked(real_dest) //&& !outd_is_special(real_dest) // not in towns - && (!scenario.ter_types[ter].boat_over + && (!univ.scenario.ter_types[ter].boat_over || ((real_dest.x != univ.party.p_loc.x) && (real_dest.y != univ.party.p_loc.y))) - && scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) { + && univ.scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) { add_string_to_buf("You leave the boat."); univ.party.in_boat = -1; } @@ -2856,8 +2868,8 @@ bool outd_move_party(location destination,bool forced) { || (!forced && (out_boat_there(destination) < 30))) return false; else if(!outd_is_blocked(real_dest) - && scenario.ter_types[ter].boat_over - && scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) { + && univ.scenario.ter_types[ter].boat_over + && univ.scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) { // TODO: It kinda looks like there should be a check for eTerSpec::BRIDGE here? // Note: Maybe not though, since this is where boating over lava was once hard-coded...? if(cChoiceDlog("boat-bridge.xml",{"under","land"}).show() == "under") @@ -2867,7 +2879,7 @@ bool outd_move_party(location destination,bool forced) { univ.party.in_boat = -1; } } - else if(scenario.ter_types[ter].boat_over) + else if(univ.scenario.ter_types[ter].boat_over) forced = true; } @@ -2917,13 +2929,13 @@ bool outd_move_party(location destination,bool forced) { } else if(!outd_is_blocked(real_dest) || forced // Check if can fly over - || (flying() && scenario.ter_types[ter].fly_over)) { + || (flying() && univ.scenario.ter_types[ter].fly_over)) { if(univ.party.in_horse >= 0) { - if(scenario.ter_types[ter].special == eTerSpec::DAMAGING || scenario.ter_types[ter].special == eTerSpec::DANGEROUS) { + if(univ.scenario.ter_types[ter].special == eTerSpec::DAMAGING || univ.scenario.ter_types[ter].special == eTerSpec::DANGEROUS) { ASB("Your horses quite sensibly refuse."); return false; } - if(scenario.ter_types[ter].block_horse) { + if(univ.scenario.ter_types[ter].block_horse) { ASB("You can't take horses there!"); return false; } @@ -2931,7 +2943,7 @@ bool outd_move_party(location destination,bool forced) { univ.party.direction = set_direction(univ.party.p_loc, destination); // TODO: But I though you automatically landed when entering? - if(flying() && scenario.ter_types[ter].special == eTerSpec::TOWN_ENTRANCE) { + if(flying() && univ.scenario.ter_types[ter].special == eTerSpec::TOWN_ENTRANCE) { add_string_to_buf("Moved: You have to land first. "); return false; } @@ -3012,7 +3024,7 @@ bool town_move_party(location destination,short forced) { if(univ.party.in_boat >= 0) { if((!is_blocked(destination)) && (!is_special(destination)) // If to bridge, exit if heading diagonal, keep going if heading horiz or vert - && ( (!scenario.ter_types[ter].boat_over) + && (!univ.scenario.ter_types[ter].boat_over || ((destination.x != univ.town.p_loc.x) && (destination.y != univ.town.p_loc.y)))) { add_string_to_buf("You leave the boat. "); univ.party.in_boat = -1; @@ -3020,7 +3032,7 @@ bool town_move_party(location destination,short forced) { else if((destination.x != univ.town.p_loc.x) && (destination.y != univ.town.p_loc.y)) return false; // Crossing bridge: land or go through - else if(!is_blocked(destination) && scenario.ter_types[ter].boat_over && scenario.ter_types[ter].special == eTerSpec::BRIDGE) { + else if(!is_blocked(destination) && univ.scenario.ter_types[ter].boat_over && univ.scenario.ter_types[ter].special == eTerSpec::BRIDGE) { if(cChoiceDlog("boat-bridge.xml",{"under","land"}).show() == "under") forced = true; else if(!is_blocked(destination)) { @@ -3034,7 +3046,7 @@ bool town_move_party(location destination,short forced) { return false; } // water or lava - else if(scenario.ter_types[ter].boat_over) + else if(univ.scenario.ter_types[ter].boat_over) forced = true; } @@ -3071,11 +3083,11 @@ bool town_move_party(location destination,short forced) { } else if(!is_blocked(destination) || forced) { if(univ.party.in_horse >= 0) { - if(scenario.ter_types[ter].special == eTerSpec::DAMAGING) { + if(univ.scenario.ter_types[ter].special == eTerSpec::DAMAGING || univ.scenario.ter_types[ter].special == eTerSpec::DANGEROUS) { ASB("Your horses quite sensibly refuse."); return false; } - if(scenario.ter_types[ter].block_horse) { + if(univ.scenario.ter_types[ter].block_horse) { ASB("You can't take horses there!"); return false; } @@ -3142,7 +3154,7 @@ void setup_outdoors(location where) { } short get_outdoor_num() { - return (scenario.out_width * (univ.party.outdoor_corner.y + univ.party.i_w_c.y) + univ.party.outdoor_corner.x + univ.party.i_w_c.x); + return (univ.scenario.out_width * (univ.party.outdoor_corner.y + univ.party.i_w_c.y) + univ.party.outdoor_corner.x + univ.party.i_w_c.x); } short count_walls(location loc) { // TODO: Generalize this function @@ -3166,7 +3178,7 @@ short count_walls(location loc) { // TODO: Generalize this function bool is_sign(ter_num_t ter) { - if(scenario.ter_types[ter].special == eTerSpec::IS_A_SIGN) + if(univ.scenario.ter_types[ter].special == eTerSpec::IS_A_SIGN) return true; return false; } diff --git a/osx/boe.appleevents.mm b/osx/boe.appleevents.mm index 395f8f32..563da848 100644 --- a/osx/boe.appleevents.mm +++ b/osx/boe.appleevents.mm @@ -76,7 +76,7 @@ void set_up_apple_events() { std::copy(msg.get(), msg.get() + len, std::inserter(fileName, fileName.begin())); ae_loading = true; - load_party(fileName); + load_party(fileName, univ); finish_load_party(); ae_loading = false; @@ -99,7 +99,7 @@ void set_up_apple_events() { std::string choice = cChoiceDlog("quit-confirm-save.xml", {"save", "quit", "cancel"}).show(); if(choice == "cancel") return; // TODO: Need to make sure the quit is actually cancelled here if(choice == "save") - save_party(univ.file); + save_party(univ.file, univ); } else { std::string choice = cChoiceDlog("quit-confirm-nosave.xml", {"quit", "cancel"}).show(); if(choice == "cancel") return; // TODO: Need to make sure the quit is actually cancelled here diff --git a/osx/boe.combat.cpp b/osx/boe.combat.cpp index b8255937..e51cae24 100644 --- a/osx/boe.combat.cpp +++ b/osx/boe.combat.cpp @@ -53,7 +53,6 @@ extern bool fast_bang; extern short store_current_pc; //extern location monster_targs[60]; extern short combat_posing_monster , current_working_monster ; // 0-5 PC 100 + x - monster x -extern cScenario scenario; extern short spell_caster, missile_firer,current_monst_tactic; char create_line[60]; eSpell spell_being_cast; @@ -4270,7 +4269,7 @@ bool combat_cast_mage_spell() { store_sum_monst = pick_trapped_monst(); if(store_sum_monst == 0) return false; - get_monst = scenario.scen_monsters[store_sum_monst]; + get_monst = univ.scenario.scen_monsters[store_sum_monst]; if(store_sp < get_monst.level) { add_string_to_buf("Cast: Not enough spell points. "); return false; diff --git a/osx/boe.dlgutil.cpp b/osx/boe.dlgutil.cpp index d6bdfbd4..b478e249 100644 --- a/osx/boe.dlgutil.cpp +++ b/osx/boe.dlgutil.cpp @@ -55,7 +55,6 @@ extern bool map_visible; extern sf::RenderWindow mini_map; //extern town_item_list t_i; extern bool game_run_before,skip_boom_delay; -extern cScenario scenario; extern cUniverse univ; //extern piles_of_stuff_dumping_type *data_store; //extern talking_record_type talking; @@ -538,11 +537,8 @@ void start_talk_mode(short m_num,short personality,m_num_t monst_type,short stor // This would be the place to show the text box, if I add it. - // first make sure relevant talk strs are loaded in - load_town_talk(personality / 10); - - // load all possible responses - store_responses(); + // Set the current town for talk strings + univ.town.prep_talk(personality / 10); // Dredge up critter's name title_string = std::string(univ.town.cur_talk().people[personality % 10].title) + ":"; @@ -981,10 +977,6 @@ void handle_talk_event(location p) { place_talk_str(save_talk_str1,save_talk_str2,0,dummy_rect); } -void store_responses() { - -} - //town_num; // Will be 0 - 200 for town, 200 - 290 for outdoors //short sign_type; // terrain type void do_sign(short town_num, short which_sign, short sign_type) { @@ -999,12 +991,11 @@ void do_sign(short town_num, short which_sign, short sign_type) { cPict& pict = dynamic_cast(sign->getControl("ter")); store_sign_mode = sign_type; - pict.setPict(scenario.ter_types[sign_type].picture); + pict.setPict(univ.scenario.ter_types[sign_type].picture); if(town_num >= 200) { town_num -= 200; - //load_outdoor_str(loc(town_num % scenario.out_width, town_num / scenario.out_width),which_sign + 100,(char *) sign_text); - sign_text = univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].sign_strs[which_sign]; + sign_text = univ.out->sign_strs[which_sign]; } else { sign_text = univ.town->sign_strs[which_sign]; diff --git a/osx/boe.fileio.cpp b/osx/boe.fileio.cpp index 5228379e..a0136f97 100644 --- a/osx/boe.fileio.cpp +++ b/osx/boe.fileio.cpp @@ -38,7 +38,6 @@ extern bool map_visible; extern sf::RenderWindow mini_map; extern short which_combat_type; extern short cur_town_talk_loaded; -extern cScenario scenario; extern cUniverse univ; cScenarioList scen_headers; extern bool mac_is_intel; @@ -94,7 +93,7 @@ void finish_load_party(){ path = progDir/"Blades of Exile Scenarios"; path /= univ.party.scen_name; std::cout<<"Searching for scenario at:\n"<max_monst(); i++){ univ.town.monst[i].targ_loc.x = 0; univ.town.monst[i].targ_loc.y = 0; @@ -146,7 +136,7 @@ void finish_load_party(){ for(int k = 0; k < univ.town->max_dim(); k++) { if(univ.town.is_quickfire(j,k)) univ.town.quickfire_present = true; - if(scenario.ter_types[univ.town->terrain(j,k)].special == eTerSpec::CONVEYOR) + if(univ.scenario.ter_types[univ.town->terrain(j,k)].special == eTerSpec::CONVEYOR) univ.town.belt_present = true; } center = univ.town.p_loc; @@ -250,10 +240,6 @@ void shift_universe_left() { univ.party.outdoor_corner.x--; univ.party.i_w_c.x++; univ.party.p_loc.x += 48; - univ.out.outdoors[1][0] = univ.out.outdoors[0][0]; - univ.out.outdoors[1][1] = univ.out.outdoors[0][1]; -// outdoor_text[1][0] = outdoor_text[0][0]; -// outdoor_text[1][1] = outdoor_text[0][1]; for(i = 48; i < 96; i++) for(j = 0; j < 96; j++) @@ -270,8 +256,6 @@ void shift_universe_left() { univ.party.out_c[i].m_loc.x += 48; } - load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y),univ.out.outdoors[0][0]); - load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1),univ.out.outdoors[0][1]); build_outdoors(); restore_cursor(); @@ -285,10 +269,6 @@ void shift_universe_right() { univ.party.outdoor_corner.x++; univ.party.i_w_c.x--; univ.party.p_loc.x -= 48; - univ.out.outdoors[0][0] = univ.out.outdoors[1][0]; - univ.out.outdoors[0][1] = univ.out.outdoors[1][1]; -// outdoor_text[0][0] = outdoor_text[1][0]; -// outdoor_text[0][1] = outdoor_text[1][1]; for(i = 0; i < 48; i++) for(j = 0; j < 96; j++) univ.out.out_e[i][j] = univ.out.out_e[i + 48][j]; @@ -303,8 +283,6 @@ void shift_universe_right() { if(univ.party.out_c[i].exists) univ.party.out_c[i].m_loc.x -= 48; } - load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y),univ.out.outdoors[1][0]); - load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1),univ.out.outdoors[1][1]); build_outdoors(); restore_cursor(); @@ -318,11 +296,7 @@ void shift_universe_up() { univ.party.outdoor_corner.y--; univ.party.i_w_c.y++; univ.party.p_loc.y += 48; - univ.out.outdoors[0][1] = univ.out.outdoors[0][0]; - univ.out.outdoors[1][1] = univ.out.outdoors[1][0]; -// outdoor_text[0][1] = outdoor_text[0][0]; -// outdoor_text[1][1] = outdoor_text[1][0]; for(i = 0; i < 96; i++) for(j = 48; j < 96; j++) univ.out.out_e[i][j] = univ.out.out_e[i][j - 48]; @@ -336,8 +310,6 @@ void shift_universe_up() { if(univ.party.out_c[i].exists) univ.party.out_c[i].m_loc.y += 48; } - load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y),univ.out.outdoors[0][0]); - load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y),univ.out.outdoors[1][0]); build_outdoors(); restore_cursor(); @@ -353,11 +325,7 @@ void shift_universe_down() { univ.party.outdoor_corner.y++; univ.party.i_w_c.y--; univ.party.p_loc.y = univ.party.p_loc.y - 48; - univ.out.outdoors[0][0] = univ.out.outdoors[0][1]; - univ.out.outdoors[1][0] = univ.out.outdoors[1][1]; -// outdoor_text[0][0] = outdoor_text[0][1]; -// outdoor_text[1][0] = outdoor_text[1][1]; for(i = 0; i < 96; i++) for(j = 0; j < 48; j++) univ.out.out_e[i][j] = univ.out.out_e[i][j + 48]; @@ -371,8 +339,6 @@ void shift_universe_down() { if(univ.party.out_c[i].exists) univ.party.out_c[i].m_loc.y = univ.party.out_c[i].m_loc.y - 48; } - load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1),univ.out.outdoors[0][1]); - load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1),univ.out.outdoors[1][1]); build_outdoors(); restore_cursor(); @@ -384,7 +350,7 @@ void position_party(short out_x,short out_y,short pc_pos_x,short pc_pos_y) { short i,j; if((pc_pos_x != minmax(0,47,pc_pos_x)) || (pc_pos_y != minmax(0,47,pc_pos_y)) || - (out_x != minmax(0,scenario.out_width - 1,out_x)) || (out_y != minmax(0,scenario.out_height - 1,out_y))) { + (out_x != minmax(0,univ.scenario.out_width - 1,out_x)) || (out_y != minmax(0,univ.scenario.out_height - 1,out_y))) { giveError("The scenario has tried to place you in an out of bounds outdoor location."); return; } @@ -397,10 +363,6 @@ void position_party(short out_x,short out_y,short pc_pos_x,short pc_pos_y) { if((univ.party.outdoor_corner.x != out_x) || (univ.party.outdoor_corner.y != out_y)) { univ.party.outdoor_corner.x = out_x; univ.party.outdoor_corner.y = out_y; - load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1),univ.out.outdoors[1][1]); - load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1),univ.out.outdoors[0][1]); - load_outdoors(loc(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y),univ.out.outdoors[1][0]); - load_outdoors(loc(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y),univ.out.outdoors[0][0]); } univ.party.i_w_c.x = (univ.party.p_loc.x > 47) ? 1 : 0; univ.party.i_w_c.y = (univ.party.p_loc.y > 47) ? 1 : 0; @@ -414,13 +376,16 @@ void position_party(short out_x,short out_y,short pc_pos_x,short pc_pos_y) { void build_outdoors() { - short i,j; + short i,j,x = univ.party.outdoor_corner.x,y=univ.party.outdoor_corner.y; for(i = 0; i < 48; i++) for(j = 0; j < 48; j++) { - univ.out[i][j] = univ.out.outdoors[0][0].terrain[i][j]; - univ.out[48 + i][j] = univ.out.outdoors[1][0].terrain[i][j]; - univ.out[i][48 + j] = univ.out.outdoors[0][1].terrain[i][j]; - univ.out[48 + i][48 + j] = univ.out.outdoors[1][1].terrain[i][j]; + univ.out[i][j] = univ.scenario.outdoors[x][y]->terrain[i][j]; + if(x + 1 < univ.scenario.out_width) + univ.out[48 + i][j] = univ.scenario.outdoors[x+1][y]->terrain[i][j]; + if(y + 1 < univ.scenario.out_height) + univ.out[i][48 + j] = univ.scenario.outdoors[x][y+1]->terrain[i][j]; + if(x + 1 < univ.scenario.out_width && y + 1 < univ.scenario.out_height) + univ.out[48 + i][48 + j] = univ.scenario.outdoors[x+1][y+1]->terrain[i][j]; } fix_boats(); @@ -441,7 +406,7 @@ void build_outdoors() { short onm(char x_sector,char y_sector) { short i; - i = y_sector * scenario.out_width + x_sector; + i = y_sector * univ.scenario.out_width + x_sector; return i; } @@ -455,26 +420,26 @@ void save_outdoor_maps() { for(j = 0; j < 48; j++) { if(univ.out.out_e[i][j] > 0) univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y)][i / 8][j] = - univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y)][i / 8][j] | - (char) (s_pow(2,i % 8)); - if(univ.party.outdoor_corner.x + 1 < scenario.out_width) { + univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y)][i / 8][j] | + (char) (s_pow(2,i % 8)); + if(univ.party.outdoor_corner.x + 1 < univ.scenario.out_width) { if(univ.out.out_e[i + 48][j] > 0) univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y)][i / 8][j] = - univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y)][i / 8][j] | - (char) (s_pow(2,i % 8)); + univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y)][i / 8][j] | + (char) (s_pow(2,i % 8)); } - if(univ.party.outdoor_corner.y + 1 < scenario.out_height) { + if(univ.party.outdoor_corner.y + 1 < univ.scenario.out_height) { if(univ.out.out_e[i][j + 48] > 0) univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1)][i / 8][j] = - univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1)][i / 8][j] | - (char) (s_pow(2,i % 8)); + univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1)][i / 8][j] | + (char) (s_pow(2,i % 8)); } - if((univ.party.outdoor_corner.y + 1 < scenario.out_height) && - (univ.party.outdoor_corner.x + 1 < scenario.out_width)) { + if((univ.party.outdoor_corner.y + 1 < univ.scenario.out_height) && + (univ.party.outdoor_corner.x + 1 < univ.scenario.out_width)) { if(univ.out.out_e[i + 48][j + 48] > 0) univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1)][i / 8][j] = - univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1)][i / 8][j] | - (char) (s_pow(2,i % 8)); + univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1)][i / 8][j] | + (char) (s_pow(2,i % 8)); } } } @@ -488,20 +453,20 @@ void add_outdoor_maps() { // This takes the existing outdoor map info and supple ((univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y)][i / 8][j] & (char) (s_pow(2,i % 8))) != 0)) univ.out.out_e[i][j] = 1; - if(univ.party.outdoor_corner.x + 1 < scenario.out_width) { + if(univ.party.outdoor_corner.x + 1 < univ.scenario.out_width) { if((univ.out.out_e[i + 48][j] == 0) && ((univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y)][i / 8][j] & (char) (s_pow(2,i % 8))) != 0)) univ.out.out_e[i + 48][j] = 1; } - if(univ.party.outdoor_corner.y + 1 < scenario.out_height) { + if(univ.party.outdoor_corner.y + 1 < univ.scenario.out_height) { if((univ.out.out_e[i][j + 48] == 0) && ((univ.out_maps[onm(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y + 1)][i / 8][j] & (char) (s_pow(2,i % 8))) != 0)) univ.out.out_e[i][j + 48] = 1; } - if((univ.party.outdoor_corner.y + 1 < scenario.out_height) && - (univ.party.outdoor_corner.x + 1 < scenario.out_width)) { + if((univ.party.outdoor_corner.y + 1 < univ.scenario.out_height) && + (univ.party.outdoor_corner.x + 1 < univ.scenario.out_width)) { if((univ.out.out_e[i + 48][j + 48] == 0) && ((univ.out_maps[onm(univ.party.outdoor_corner.x + 1,univ.party.outdoor_corner.y + 1)][i / 8][j] & (char) (s_pow(2,i % 8))) != 0)) @@ -631,12 +596,13 @@ bool load_scenario_header(fs::path file/*,short header_entry*/){ // So file is OK, so load in string data and close it. fclose(file_id); - load_scenario(file); + cScenario temp_scenario; + load_scenario(file, temp_scenario); scen_header_str_type scen_strs; - scen_strs.name = scenario.scen_name; - scen_strs.who1 = scenario.who_wrote[0]; - scen_strs.who2 = scenario.who_wrote[1]; + scen_strs.name = temp_scenario.scen_name; + scen_strs.who1 = temp_scenario.who_wrote[0]; + scen_strs.who2 = temp_scenario.who_wrote[1]; std::string curScenarioName(file.filename().string()); scen_strs.file = curScenarioName; diff --git a/osx/boe.fileio.h b/osx/boe.fileio.h index 8504e5e4..b6a76ae2 100644 --- a/osx/boe.fileio.h +++ b/osx/boe.fileio.h @@ -51,8 +51,6 @@ bool load_scenario_header(fs::path filename/*,short header_entry*/); //short get_buf_ptr(short flag); //bool check_p (short pword); -__declspec(deprecated) void init_town(); - //void port_talk_nodes(); //void port_town(); //void port_t_d(); diff --git a/osx/boe.graphics.cpp b/osx/boe.graphics.cpp index f7a6188d..509a2dc9 100644 --- a/osx/boe.graphics.cpp +++ b/osx/boe.graphics.cpp @@ -55,7 +55,6 @@ extern long register_flag; extern long ed_flag,ed_key; extern bool fast_bang; extern tessel_ref_t bg[]; -extern cScenario scenario; extern cUniverse univ; extern cCustomGraphics spec_scen_g; extern sf::RenderWindow mini_map; @@ -681,17 +680,17 @@ void draw_text_bar(short mode) { remember_tiny_text = 500; if(is_out()) { for(i = 0; i < 8; i++) - if(loc.in(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].info_rect[i])) { + if(loc.in(univ.out->info_rect[i])) { if((remember_tiny_text == i) && (mode == 0)) return; else { - put_text_bar(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].rect_names[i]); + put_text_bar(univ.out->rect_names[i]); remember_tiny_text = i; return; } } // TODO: I'm pretty sure this brace location is correct, but must verify it if(remember_tiny_text != 50 + univ.party.i_w_c.x + univ.party.i_w_c.y) { - put_text_bar(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].out_name); + put_text_bar(univ.out->out_name); remember_tiny_text = 50 + univ.party.i_w_c.x + univ.party.i_w_c.y; } } @@ -778,16 +777,16 @@ bool is_nature(char x, char y, unsigned char ground_t) { ter_num_t ter_type; ter_type = coord_to_ter((short) x,(short) y); - return ground_t == scenario.ter_types[ter_type].ground_type; + return ground_t == univ.scenario.ter_types[ter_type].ground_type; } ter_num_t get_ground_from_ter(ter_num_t ter){ - return get_ter_from_ground(scenario.ter_types[ter].ground_type); + return get_ter_from_ground(univ.scenario.ter_types[ter].ground_type); } ter_num_t get_ter_from_ground(unsigned char ground){ for(int i = 0; i < 256; i++) - if(scenario.ter_types[i].ground_type == ground) + if(univ.scenario.ter_types[i].ground_type == ground) return i; return 0; } @@ -918,12 +917,12 @@ void draw_terrain(short mode) { if((can_draw != 0) && (overall_mode != MODE_RESTING)) { // if can see, not a pit, and not resting if(is_combat()) anim_ticks = 0; - eTrimType trim = scenario.ter_types[spec_terrain].trim_type; + eTrimType trim = univ.scenario.ter_types[spec_terrain].trim_type; // Finally, draw this terrain spot if(trim == eTrimType::WALKWAY){ int trim = -1; - unsigned char ground_t = scenario.ter_types[spec_terrain].trim_ter; + unsigned char ground_t = univ.scenario.ter_types[spec_terrain].trim_ter; ter_num_t ground_ter = get_ter_from_ground(ground_t); if(!loc_off_act_area(where_draw)) { if(is_nature(where_draw.x - 1,where_draw.y,ground_t)){ // check left @@ -1037,8 +1036,8 @@ void draw_terrain(short mode) { static ter_num_t get_ground_for_shore(ter_num_t ter){ - if(scenario.ter_types[ter].block_horse) return current_ground; - else if(blocksMove(scenario.ter_types[ter].blockage)) return current_ground; + if(univ.scenario.ter_types[ter].block_horse) return current_ground; + else if(blocksMove(univ.scenario.ter_types[ter].blockage)) return current_ground; else return ter; } @@ -1231,7 +1230,7 @@ void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter) { // // if((which_trim == 3) && (current_ground == 2)) // trim corner walls with grass instead of cave floor // OffsetRect(&from_rect,0,36); - unsigned short pic = scenario.ter_types[ground_ter].picture; + unsigned short pic = univ.scenario.ter_types[ground_ter].picture; if(pic < 960){ from_gworld = &terrain_gworld[pic / 50]; pic %= 50; @@ -1272,9 +1271,9 @@ void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter) { bool extend_road_terrain(ter_num_t ter) { - eTrimType trim = scenario.ter_types[ter].trim_type; - eTerSpec spec = scenario.ter_types[ter].special; - ter_num_t flag = scenario.ter_types[ter].flag1.u; + eTrimType trim = univ.scenario.ter_types[ter].trim_type; + eTerSpec spec = univ.scenario.ter_types[ter].special; + ter_num_t flag = univ.scenario.ter_types[ter].flag1.u; if(trim == eTrimType::ROAD || trim == eTrimType::CITY || trim == eTrimType::WALKWAY) return true; if(spec == eTerSpec::BRIDGE) @@ -1283,7 +1282,7 @@ bool extend_road_terrain(ter_num_t ter) { return true; // cave entrance, most likely if(spec == eTerSpec::UNLOCKABLE || spec == eTerSpec::CHANGE_WHEN_STEP_ON) return true; // closed door, possibly locked; or closed portcullis - if(spec == eTerSpec::CHANGE_WHEN_USED && scenario.ter_types[flag].special == eTerSpec::CHANGE_WHEN_STEP_ON && scenario.ter_types[flag].flag1.u == ter) + if(spec == eTerSpec::CHANGE_WHEN_USED && univ.scenario.ter_types[flag].special == eTerSpec::CHANGE_WHEN_STEP_ON && univ.scenario.ter_types[flag].flag1.u == ter) return true; // open door (I think) TODO: Verify this works if(spec == eTerSpec::LOCKABLE) return true; // open portcullis (most likely) @@ -1292,19 +1291,19 @@ bool extend_road_terrain(ter_num_t ter) { static bool can_build_roads_on(ter_num_t ter) { if(impassable(ter)) return false; - if(scenario.ter_types[ter].special == eTerSpec::BRIDGE) return false; + if(univ.scenario.ter_types[ter].special == eTerSpec::BRIDGE) return false; return true; } static bool superextend_road_terrain(int x, int y) { // Connect road to trim? ter_num_t ter = coord_to_ter(x,y); - eTrimType trim = scenario.ter_types[ter].trim_type; + eTrimType trim = univ.scenario.ter_types[ter].trim_type; if(trim == eTrimType::N || trim == eTrimType::S) { ter_num_t up = coord_to_ter(x,y-1); ter_num_t down = coord_to_ter(x,y+1); - eTrimType trimUp = scenario.ter_types[up].trim_type; - eTrimType trimDn = scenario.ter_types[down].trim_type; + eTrimType trimUp = univ.scenario.ter_types[up].trim_type; + eTrimType trimDn = univ.scenario.ter_types[down].trim_type; if((trimUp == eTrimType::ROAD || trimUp == eTrimType::CITY) && (trimDn == eTrimType::ROAD || trimDn == eTrimType::CITY)) return can_build_roads_on(ter); if((trimUp == eTrimType::ROAD || trimUp == eTrimType::CITY) && trim == eTrimType::N && trimDn == eTrimType::S) @@ -1314,8 +1313,8 @@ static bool superextend_road_terrain(int x, int y) { } else if(trim == eTrimType::E || trim == eTrimType::W) { ter_num_t left = coord_to_ter(x-1,y); ter_num_t right = coord_to_ter(x+1,y); - eTrimType trimLeft = scenario.ter_types[left].trim_type; - eTrimType trimRight = scenario.ter_types[right].trim_type; + eTrimType trimLeft = univ.scenario.ter_types[left].trim_type; + eTrimType trimRight = univ.scenario.ter_types[right].trim_type; if((trimLeft == eTrimType::ROAD || trimLeft == eTrimType::CITY) && (trimRight == eTrimType::ROAD || trimRight == eTrimType::CITY)) return can_build_roads_on(ter); if((trimLeft == eTrimType::ROAD || trimLeft == eTrimType::CITY) && trim == eTrimType::W && trimRight == eTrimType::E) @@ -1327,8 +1326,8 @@ static bool superextend_road_terrain(int x, int y) { } static bool connect_roads(ter_num_t ter){ - eTrimType trim = scenario.ter_types[ter].trim_type; - eTerSpec spec = scenario.ter_types[ter].special; + eTrimType trim = univ.scenario.ter_types[ter].trim_type; + eTerSpec spec = univ.scenario.ter_types[ter].special; if(trim == eTrimType::ROAD || trim == eTrimType::CITY) return true; if(spec == eTerSpec::TOWN_ENTRANCE && trim != eTrimType::NONE) @@ -1399,11 +1398,11 @@ void place_road(short q,short r,location where, bool here) { }else{ ter_num_t ref = coord_to_ter(where.x,where.y); bool horz = false, vert = false; - eTrimType trim = scenario.ter_types[ref].trim_type; + eTrimType trim = univ.scenario.ter_types[ref].trim_type; if(where.y > 0) ter = coord_to_ter(where.x,where.y - 1); // TODO: ter could be uninitialized here! - eTrimType vertTrim = scenario.ter_types[ter].trim_type; + eTrimType vertTrim = univ.scenario.ter_types[ter].trim_type; if((where.y == 0) || connect_roads(ter)) vert = can_build_roads_on(ref); else if((vertTrim == eTrimType::S && trim == eTrimType::N) || (vertTrim == eTrimType::N && trim == eTrimType::S)) @@ -1411,7 +1410,7 @@ void place_road(short q,short r,location where, bool here) { 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 = scenario.ter_types[ter].trim_type; + eTrimType horzTrim = univ.scenario.ter_types[ter].trim_type; if(((is_out()) && (where.x == 96)) || (!(is_out()) && (where.x == univ.town->max_dim() - 1)) || connect_roads(ter)) horz = can_build_roads_on(ref); @@ -1421,7 +1420,7 @@ void place_road(short q,short r,location where, bool here) { if(vert){ 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 = scenario.ter_types[ter].trim_type; + eTrimType vertTrim = univ.scenario.ter_types[ter].trim_type; if(((is_out()) && (where.y == 96)) || (!(is_out()) && (where.y == univ.town->max_dim() - 1)) || connect_roads(ter)) vert = can_build_roads_on(ref); @@ -1433,7 +1432,7 @@ void place_road(short q,short r,location where, bool here) { if(horz){ if(where.x > 0) ter = coord_to_ter(where.x - 1,where.y); - eTrimType horzTrim = scenario.ter_types[ter].trim_type; + eTrimType horzTrim = univ.scenario.ter_types[ter].trim_type; if((where.x == 0) || connect_roads(ter)) horz = can_build_roads_on(ref); else if((horzTrim == eTrimType::W && trim == eTrimType::E) || (horzTrim == eTrimType::E && trim == eTrimType::W)) diff --git a/osx/boe.graphutil.cpp b/osx/boe.graphutil.cpp index 8b7e234f..d3ed6e4f 100644 --- a/osx/boe.graphutil.cpp +++ b/osx/boe.graphutil.cpp @@ -71,7 +71,6 @@ extern short monster_index[21]; extern bool supressing_some_spaces; extern location ok_space[4]; extern bool can_draw_pcs; -extern cScenario scenario; extern cCustomGraphics spec_scen_g; // TODO: The duplication of rectangle here shouldn't be necessary... @@ -114,26 +113,26 @@ void draw_one_terrain_spot (short i,short j,short terrain_to_draw) { source_rect = calc_rect(terrain_to_draw % 10, terrain_to_draw / 10); anim_type = -1; } - else if(scenario.ter_types[terrain_to_draw].picture >= 2000) { // custom - graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(scenario.ter_types[terrain_to_draw].picture - 2000 + (anim_ticks % 4)); + else if(univ.scenario.ter_types[terrain_to_draw].picture >= 2000) { // custom + graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(univ.scenario.ter_types[terrain_to_draw].picture - 2000 + (anim_ticks % 4)); anim_type = 0; terrain_there[i][j] = -1; } - else if(scenario.ter_types[terrain_to_draw].picture >= 1000) { // custom - graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(scenario.ter_types[terrain_to_draw].picture - 1000); + else if(univ.scenario.ter_types[terrain_to_draw].picture >= 1000) { // custom + graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(univ.scenario.ter_types[terrain_to_draw].picture - 1000); terrain_there[i][j] = -1; } - else if(scenario.ter_types[terrain_to_draw].picture >= 960) { // animated + else if(univ.scenario.ter_types[terrain_to_draw].picture >= 960) { // animated source_gworld = &anim_gworld; - terrain_to_draw = scenario.ter_types[terrain_to_draw].picture; + terrain_to_draw = univ.scenario.ter_types[terrain_to_draw].picture; source_rect = calc_rect(4 * ((terrain_to_draw - 960) / 5) + (anim_ticks % 4),(terrain_to_draw - 960) % 5); terrain_there[i][j] = -1; anim_type = 0; } else { - if(terrain_there[i][j] == scenario.ter_types[terrain_to_draw].picture) return; - terrain_there[i][j] = scenario.ter_types[terrain_to_draw].picture; - terrain_to_draw = scenario.ter_types[terrain_to_draw].picture; + if(terrain_there[i][j] == univ.scenario.ter_types[terrain_to_draw].picture) return; + terrain_there[i][j] = univ.scenario.ter_types[terrain_to_draw].picture; + terrain_to_draw = univ.scenario.ter_types[terrain_to_draw].picture; source_gworld = &terrain_gworld[terrain_to_draw / 50]; terrain_there[i][j] = terrain_to_draw; terrain_to_draw %= 50; @@ -197,7 +196,8 @@ void draw_monsters() { // TODO: Windows special-cases the bear and drake, whose graphics are split between two columns/sheets. Is this necessary? // It really doesn't look necessary to me, since each quadrant of the graphic is fetched separately. // Technically what they do is always pass 0 as the final argument to get_monster_template_rect, instead of passing k; they also hardcode the sheet to look on (4 for drake, 5 for bear). - pic_num_t this_monst = univ.party.out_c[i].what_monst.get(j,true,&cMonster::picture_num); + m_num_t m_num = univ.party.out_c[i].what_monst.monst[j]; + pic_num_t this_monst = univ.scenario.scen_monsters[m_num].picture_num; source_rect = get_monster_template_rect(this_monst,(univ.party.out_c[i].direction < 4) ? 0 : 1,k); to_rect = monst_rects[(width - 1) * 2 + height - 1][k]; to_rect.offset(13 + 28 * where_draw.x,13 + 36 * where_draw.y); @@ -229,11 +229,11 @@ void draw_monsters() { ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y); // in bed? if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) && - scenario.ter_types[ter].special == eTerSpec::BED && + univ.scenario.ter_types[ter].special == eTerSpec::BED && isHumanoid(univ.town.monst[i].m_type) && ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) && (width == 1) && (height == 1)) //// - draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + scenario.ter_types[ter].flag1.u); + draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u); else Draw_Some_Item(*src_gw, source_rect, terrain_screen_gworld, store_loc, 1, 0); } if(univ.town.monst[i].picture_num < 1000) { @@ -243,11 +243,11 @@ void draw_monsters() { ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y); // in bed? if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) && - (scenario.ter_types[ter].special == eTerSpec::BED) && + (univ.scenario.ter_types[ter].special == eTerSpec::BED) && isHumanoid(univ.town.monst[i].m_type) && ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) && (width == 1) && (height == 1)) //// - draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + scenario.ter_types[ter].flag1.u); + draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u); else Draw_Some_Item(monst_gworld[m_pic_index[this_monst].i/20], source_rect, terrain_screen_gworld, store_loc, 1, 0); } } @@ -273,11 +273,11 @@ void draw_monsters() { + ((combat_posing_monster == i + 100) ? (2 * width * height) : 0)); ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y); if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) && - scenario.ter_types[ter].special == eTerSpec::BED && + univ.scenario.ter_types[ter].special == eTerSpec::BED && isHumanoid(univ.town.monst[i].m_type) && ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) && (width == 1) && (height == 1)) - draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + scenario.ter_types[ter].flag1.u); //// + draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u); else Draw_Some_Item(*src_gw, source_rect, terrain_screen_gworld, store_loc, 1, 0); } if(univ.town.monst[i].picture_num < 1000) { @@ -287,11 +287,11 @@ void draw_monsters() { ,k); ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y); if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) && - scenario.ter_types[ter].special == eTerSpec::BED && + univ.scenario.ter_types[ter].special == eTerSpec::BED && isHumanoid(univ.town.monst[i].m_type) && ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) && (width == 1) && (height == 1)) - draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + scenario.ter_types[ter].flag1.u); //// + draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u); else Draw_Some_Item(monst_gworld[m_pic_index[this_monst].i/20], source_rect, terrain_screen_gworld, store_loc, 1, 0); } } @@ -302,18 +302,18 @@ void draw_monsters() { void play_see_monster_str(unsigned short m, location monst_loc) { short str1, str2, pic, snd, spec; ePicType type; - str1 = scenario.scen_monsters[m].see_str1; - str2 = scenario.scen_monsters[m].see_str2; - pic = scenario.scen_monsters[m].picture_num; + str1 = univ.scenario.scen_monsters[m].see_str1; + str2 = univ.scenario.scen_monsters[m].see_str2; + pic = univ.scenario.scen_monsters[m].picture_num; type = get_monst_pictype(m); - snd = scenario.scen_monsters[m].see_sound; - spec = scenario.scen_monsters[m].see_spec; + snd = univ.scenario.scen_monsters[m].see_sound; + spec = univ.scenario.scen_monsters[m].see_spec; // First display strings, if any - if(str1 || str2) { - short where1 = is_out() ? univ.party.i_w_c.x : univ.town.num; - short where2 = is_out() ? univ.party.i_w_c.y : univ.town.num; - std::string placename = is_out() ? univ.out.outdoors[where1][where2].out_name : univ.town->town_name; - cStrDlog display_strings(str1 ? scenario.monst_strs[str1] : "", str2 ? scenario.monst_strs[str2] : "", "", pic, type, NULL); + if((str1 >= 0 && str1 < 100) || (str2 >= 0 && str2 < 100)) { + short where1 = is_out() ? univ.party.outdoor_corner.x + univ.party.i_w_c.x : univ.town.num; + short where2 = is_out() ? univ.party.outdoor_corner.y + univ.party.i_w_c.y : univ.town.num; + std::string placename = is_out() ? univ.out->out_name : univ.town->town_name; + cStrDlog display_strings(str1 ? univ.scenario.monst_strs[str1] : "", str2 ? univ.scenario.monst_strs[str2] : "", "", pic, type, NULL); display_strings.setSound(snd); display_strings.setRecordHandler(cStringRecorder(NOTE_MONST).string1(str1).string2(str2).from(where1,where2).at(placename)); display_strings.show(); @@ -475,7 +475,7 @@ void draw_fields(location where){ location where_draw(4 + where.x - center.x, 4 + where.y - center.y); if(is_out()){ where = global_to_local(where); - if(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_spot[where.x][where.y]) + if(univ.out->special_spot[where.x][where.y]) Draw_Some_Item(fields_gworld,calc_rect(4,0),terrain_screen_gworld,where_draw,1,0); return; } @@ -552,8 +552,8 @@ void draw_party_symbol(location center) { source_rect.offset(28,0); ter_num_t ter = is_out() ? univ.out[univ.party.p_loc.x][univ.party.p_loc.y] : univ.town->terrain(univ.town.p_loc.x,univ.town.p_loc.y); // now wedge in bed graphic - if(is_town() && scenario.ter_types[ter].special == eTerSpec::BED) - draw_one_terrain_spot((short) target.x,(short) target.y,10000 + scenario.ter_types[ter].flag1.u); + if(is_town() && univ.scenario.ter_types[ter].special == eTerSpec::BED) + draw_one_terrain_spot((short) target.x,(short) target.y,10000 + univ.scenario.ter_types[ter].flag1.u); else Draw_Some_Item(pc_gworld, source_rect, terrain_screen_gworld, target, 1, 0); } else if(univ.party.in_boat >= 0) { @@ -629,14 +629,14 @@ bool is_fluid(ter_num_t ter_type) { // if(((ter_type >= 71) && (ter_type <= 76)) || (ter_type == 90)) // return true; // return false; - return scenario.ter_types[ter_type].trim_type == eTrimType::FRILLS; + return univ.scenario.ter_types[ter_type].trim_type == eTrimType::FRILLS; } // Is this a beach that gets shore plopped down next to it? bool is_shore(ter_num_t ter_type) { if(is_fluid(ter_type)) return false; - if(scenario.ter_types[ter_type].trim_type == eTrimType::WATERFALL) + if(univ.scenario.ter_types[ter_type].trim_type == eTrimType::WATERFALL) return false; // if(ter_type == 77) // return false; @@ -653,7 +653,7 @@ bool is_shore(ter_num_t ter_type) { // These two functions used to determine wall round-cornering bool is_wall(ter_num_t ter_type) { - return scenario.ter_types[ter_type].trim_type == eTrimType::WALL; + return univ.scenario.ter_types[ter_type].trim_type == eTrimType::WALL; // short pic; // // pic = scenario.ter_types[ter_type].picture; @@ -664,9 +664,9 @@ bool is_wall(ter_num_t ter_type) { // return false; } bool is_ground(ter_num_t ter_type) { - if(scenario.ter_types[ter_type].trim_type == eTrimType::WALL) + if(univ.scenario.ter_types[ter_type].trim_type == eTrimType::WALL) return false; - if(scenario.ter_types[ter_type].block_horse) + if(univ.scenario.ter_types[ter_type].block_horse) return false; // if(scenario.ter_types[ter_type].trim_type == eTrimType::WALKWAY) // return false; @@ -758,7 +758,7 @@ void check_if_monst_seen(unsigned short m_num, location at) { play_see_monster_str(m_num, at); } // Make the monster vocalize if applicable - snd_num_t sound = scenario.scen_monsters[m_num].ambient_sound; + snd_num_t sound = univ.scenario.scen_monsters[m_num].ambient_sound; if(get_ran(1,1,100) < 10) play_sound(-sound); } diff --git a/osx/boe.infodlg.cpp b/osx/boe.infodlg.cpp index 343dfdda..801e2943 100644 --- a/osx/boe.infodlg.cpp +++ b/osx/boe.infodlg.cpp @@ -53,7 +53,6 @@ location source_locs[6] = {loc(2,9),loc(0,6),loc(3,6),loc(3,4),loc(6,2),loc(0,0) //extern current_town_type univ.town; extern location dest_locs[40] ; extern char *alch_names[]; -extern cScenario scenario; extern cUniverse univ; // Displaying string vars @@ -434,32 +433,31 @@ static void put_monst_info(cDialog& me, const cCreature& store_m) { static bool display_monst_event_filter(cDialog& me, std::string item_hit, cCreature& store_m) { - short i,dummy = 0; + // This is a bit hacky; keep a cPopulation here to handle the full roster; it's treated like a rotating buffer. + static cPopulation roster; + short i; - if(item_hit == "done") { - me.toast(true); - } else if(item_hit == "left") { + if(item_hit == "left") { if(position == 0) { - for(i = 255; on_monst_menu[i] < 0 && i > 0; i--) - dummy++; + for(i = 255; on_monst_menu[i] < 0 && i > 0; i--); position = i; } else position--; if(on_monst_menu[position] < 0) position = 0; - store_m.number = on_monst_menu[position]; - store_m = store_m; // to fill in fields that wouldn't otherwise be filled in; replaces return_monster_template - put_monst_info(me, store_m); } else if(item_hit == "right") { position++; if(on_monst_menu[position] < 0) position = 0; - store_m.number = on_monst_menu[position]; - store_m = store_m; // no, this is not redundant - // TODO: It may not be redudndant, but it looks pretty stupid; change it - put_monst_info(me, store_m); + } else if(item_hit != "none") + return true; // Means an immunity LED was hit + + if(roster[position % 60].number != on_monst_menu[position]) { + cMonster& monst = univ.scenario.scen_monsters[on_monst_menu[position]]; + roster.assign(position % 60, cCreature(on_monst_menu[position]), monst, PSD[SDF_EASY_MODE], univ.difficulty_adjust()); } + put_monst_info(me, store_m); return true; } @@ -470,26 +468,23 @@ void display_monst(short array_pos,cCreature *which_m,short mode) { position = array_pos; full_roster = false; cCreature store_m; - if(mode == 1) { - full_roster = true; - store_m = cCreature(); - store_m.number = on_monst_menu[array_pos]; - store_m = store_m; // yes, this DOES do something - } - else { - store_m = *which_m; - } + if(mode == 1) full_roster = true; + else store_m = *which_m; make_cursor_sword(); cDialog monstInfo("monster-info.xml"); auto event_filter = std::bind(display_monst_event_filter, _1, _2,std::ref(store_m)); - monstInfo.attachClickHandlers(event_filter, {"done", "left", "right"}); + monstInfo["done"].attachClickHandler(std::bind(&cDialog::toast, &monstInfo, true)); + monstInfo.attachClickHandlers(event_filter, {"left", "right"}); // Also add the click handler to the LEDs to suppress normal LED behaviour monstInfo.attachClickHandlers(event_filter, {"immune1", "immune2", "immune3", "immune4"}); monstInfo.attachClickHandlers(event_filter, {"immune5", "immune6", "immune7", "immune8"}); - if(!full_roster) { + if(full_roster) { + // This is a bit hacky - call event handler with dummy ID to ensure the monster details are correctly populated. + display_monst_event_filter(monstInfo, "none", store_m); + } else { monstInfo["left"].hide(); monstInfo["right"].hide(); } @@ -893,8 +888,9 @@ void journal() { journal.run(); } + void add_to_journal(short event) { - if(univ.party.add_to_journal(scenario.journal_strs[event], calc_day())) + if(univ.party.add_to_journal(univ.scenario.journal_strs[event], calc_day())) ASB("Something was added to your journal."); } @@ -931,8 +927,8 @@ void give_help(short help1, short help2, cDialog& parent) { } void put_spec_item_info (short which_i) { - cStrDlog display_strings(scenario.special_items[which_i].descr,"", - scenario.special_items[which_i].name,scenario.intro_pic,PIC_SCEN); + cStrDlog display_strings(univ.scenario.special_items[which_i].descr,"", + univ.scenario.special_items[which_i].name,univ.scenario.intro_pic,PIC_SCEN); display_strings.setSound(57); display_strings.show(); //item_name = get_str(6,1 + which_i * 2); @@ -946,20 +942,20 @@ void cStringRecorder::operator()(cDialog& me) { std::string str1, str2; switch(type) { case NOTE_SCEN: - str1 = scenario.spec_strs[label1]; - str2 = scenario.spec_strs[label2]; + str1 = univ.scenario.spec_strs[label1]; + str2 = univ.scenario.spec_strs[label2]; break; case NOTE_TOWN: str1 = univ.town->spec_strs[label1]; str2 = univ.town->spec_strs[label2]; break; case NOTE_OUT: - str1 = univ.out.outdoors[label1b][label2b].spec_strs[label1]; - str2 = univ.out.outdoors[label1b][label2b].spec_strs[label2]; + str1 = univ.scenario.outdoors[label1b][label2b]->spec_strs[label1]; + str2 = univ.scenario.outdoors[label1b][label2b]->spec_strs[label2]; break; case NOTE_MONST: - str1 = scenario.monst_strs[label1]; - str2 = scenario.monst_strs[label2]; + str1 = univ.scenario.monst_strs[label1]; + str2 = univ.scenario.monst_strs[label2]; break; } if(univ.party.record(type, str1, location)) diff --git a/osx/boe.itemdata.cpp b/osx/boe.itemdata.cpp index 83259691..cca5fd76 100644 --- a/osx/boe.itemdata.cpp +++ b/osx/boe.itemdata.cpp @@ -10,13 +10,12 @@ #include "boe.itemdata.h" #include "mathutil.h" //extern piles_of_stuff_dumping_type *data_store; -extern cScenario scenario; - //item_record_type convert_item (short_item_record_type s_item); short loot_min[5] = {0,0,5,50,400}; short loot_max[5] = {3,8,40,800,4000}; +extern cUniverse univ; //// whole file //item_record_type return_dummy_item() @@ -36,7 +35,7 @@ cItemRec get_stored_item(short which) { return s_item; } - s_item = scenario.scen_items[which]; + s_item = univ.scenario.scen_items[which]; return s_item; } diff --git a/osx/boe.items.cpp b/osx/boe.items.cpp index 88b14371..414d4e75 100644 --- a/osx/boe.items.cpp +++ b/osx/boe.items.cpp @@ -45,7 +45,6 @@ extern bool map_visible,diff_depth_ok; extern sf::RenderWindow mini_map; //extern short town_size[3]; extern sf::Texture pc_gworld; -extern cScenario scenario; extern cUniverse univ; const std::multiset equippable = { @@ -836,7 +835,7 @@ void set_town_attitude(short lo,short hi,short att) { univ.town.monst[i].mobility = 1; // If a "guard", give a power boost - if(scenario.scen_monsters[num].spec_skill == 37) { + if(univ.scenario.scen_monsters[num].spec_skill == 37) { univ.town.monst[i].active = 2; univ.town.monst[i].health *= 3; univ.town.monst[i].status[eStatus::HASTE_SLOW] = 8; @@ -1212,7 +1211,7 @@ void place_glands(location where,m_num_t m_type) { cItemRec store_i; cMonster monst; - monst = scenario.scen_monsters[m_type]; + monst = univ.scenario.scen_monsters[m_type]; if((monst.corpse_item >= 0) && (monst.corpse_item < 400) && (get_ran(1,1,100) < monst.corpse_item_chance)) { store_i = get_stored_item(monst.corpse_item); diff --git a/osx/boe.locutils.cpp b/osx/boe.locutils.cpp index 3f48c26e..ed3eaf39 100644 --- a/osx/boe.locutils.cpp +++ b/osx/boe.locutils.cpp @@ -22,7 +22,6 @@ extern eGameMode overall_mode; //extern cOutdoors outdoors[2][2]; //extern unsigned char out[96][96], out_e[96][96]; extern location center; -extern cScenario scenario; extern cUniverse univ; location light_locs[40]; @@ -172,7 +171,7 @@ bool is_lava(short x,short y) { ter_num_t ter; ter = coord_to_ter(x,y); - if(scenario.ter_types[ter].picture == 404) + if(univ.scenario.ter_types[ter].picture == 964) return true; else return false; } @@ -214,7 +213,7 @@ short sight_obscurity(short x,short y) { } short combat_obscurity(short x, short y) { - if(blocksMove(scenario.ter_types[coord_to_ter(x,y)].blockage)) return 5; + if(blocksMove(univ.scenario.ter_types[coord_to_ter(x,y)].blockage)) return 5; if(is_lava(x,y)) return 5; return sight_obscurity(x,y); } @@ -238,7 +237,7 @@ bool is_container(location loc) { if((univ.town.is_barrel(loc.x,loc.y)) || (univ.town.is_crate(loc.x,loc.y))) return true; ter = coord_to_ter(loc.x,loc.y); - if(scenario.ter_types[ter].special == eTerSpec::IS_A_CONTAINER) + if(univ.scenario.ter_types[ter].special == eTerSpec::IS_A_CONTAINER) return true; return false; } @@ -300,7 +299,7 @@ bool is_blocked(location to_check) { if((is_town()) || (is_combat())) { ter = univ.town->terrain(to_check.x,to_check.y); - gr = scenario.ter_types[ter].picture; + gr = univ.scenario.ter_types[ter].picture; //// // Terrain blocking? @@ -311,7 +310,7 @@ bool is_blocked(location to_check) { // Keep away from marked specials during combat if((is_combat()) && univ.town.is_spot(to_check.x, to_check.y)) return true; - if((is_combat()) && (scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].trim_type == eTrimType::CITY)) + if((is_combat()) && (univ.scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].trim_type == eTrimType::CITY)) return true; // TODO: Maybe replace eTrimType::CITY with a blockage == clear/special && is_special() check // Note: The purpose of the above check is to avoid portals. @@ -457,14 +456,14 @@ bool is_special(location to_check) { ter_num_t which_ter; which_ter = coord_to_ter(to_check.x,to_check.y); - if(scenario.ter_types[which_ter].blockage == eTerObstruct::BLOCK_MONSTERS) + if(univ.scenario.ter_types[which_ter].blockage == eTerObstruct::BLOCK_MONSTERS) return true; else return false; } bool outd_is_special(location to_check) { if(overall_mode == MODE_OUTDOORS) { - if(scenario.ter_types[univ.out[to_check.x][to_check.y]].blockage == eTerObstruct::BLOCK_MONSTERS) { + if(univ.scenario.ter_types[univ.out[to_check.x][to_check.y]].blockage == eTerObstruct::BLOCK_MONSTERS) { return true; } else return false; @@ -473,7 +472,7 @@ bool outd_is_special(location to_check) { } bool impassable(ter_num_t terrain_to_check) { - if(blocksMove(scenario.ter_types[terrain_to_check].blockage)) + if(blocksMove(univ.scenario.ter_types[terrain_to_check].blockage)) return true; else return false; } @@ -485,10 +484,10 @@ short get_blockage(ter_num_t terrain_type) { // little kludgy in here for pits if((terrain_type == 90) && (is_combat()) && (which_combat_type == 0)) return 5; - if(scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT || - scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_SIGHT) + if(univ.scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT || + univ.scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_SIGHT) return 5; - else if(scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_MOVE_AND_SHOOT) + else if(univ.scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_MOVE_AND_SHOOT) return 1; else { return 0; @@ -606,7 +605,7 @@ location push_loc(location from_where,location to_where) { return loc_to_try; } if(sight_obscurity(loc_to_try.x,loc_to_try.y) > 0 || - scenario.ter_types[univ.town->terrain(loc_to_try.x,loc_to_try.y)].blockage != eTerObstruct::CLEAR || + univ.scenario.ter_types[univ.town->terrain(loc_to_try.x,loc_to_try.y)].blockage != eTerObstruct::CLEAR || (loc_off_act_area(loc_to_try)) || (monst_there(loc_to_try) < 90) || (pc_there(loc_to_try) < 6)) @@ -620,7 +619,7 @@ bool spot_impassable(short i,short j) { ter_num_t ter; ter = coord_to_ter(i,j); - if(scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) + if(univ.scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) return true; else return false; } @@ -641,11 +640,11 @@ void alter_space(short i,short j,ter_num_t ter) { if(is_out()) { l = local_to_global(l); univ.out[l.x][l.y] = ter; - univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].terrain[i][j] = ter; + univ.out->terrain[i][j] = ter; } else { univ.town->terrain(i,j) = ter; - if(scenario.ter_types[univ.town->terrain(i,j)].special == eTerSpec::CONVEYOR) + if(univ.scenario.ter_types[univ.town->terrain(i,j)].special == eTerSpec::CONVEYOR) univ.town.belt_present = true; } } diff --git a/osx/boe.main.cpp b/osx/boe.main.cpp index 3f0c1b7b..71754de9 100644 --- a/osx/boe.main.cpp +++ b/osx/boe.main.cpp @@ -48,7 +48,6 @@ rectangle item_sbar_rect = {146,546,253,562}; bool bgm_on = false,bgm_init = false; //short dialog_answer; location store_anim_ul; -cScenario scenario; cUniverse univ; //piles_of_stuff_dumping_type *data_store; //talking_record_type talking; @@ -334,7 +333,7 @@ void Handle_One_Event() { if(choice == "save") { fs::path file = nav_put_party(); if(!file.empty()) break; - save_party(file); + save_party(file, univ); } } All_Done = true; @@ -350,7 +349,7 @@ void Handle_One_Event() { if(choice == "cancel") break; if(choice == "save") - save_party(univ.file); + save_party(univ.file, univ); } All_Done = true; // TODO: Handle closing of mini-map @@ -428,7 +427,6 @@ void Mouse_Pressed() { void close_program() { // TODO: Ultimately we would like to have cleanup happen automatically, negating the need for this function //end_music(); - if(univ.town.loaded()) univ.town.unload(); } void handle_apple_menu(int item_hit) { @@ -486,7 +484,7 @@ void handle_file_menu(int item_hit) { if(choice == "save") { fs::path file = nav_put_party(); if(!file.empty()) break; - save_party(file); + save_party(file, univ); } } All_Done = true; @@ -502,7 +500,7 @@ void handle_file_menu(int item_hit) { if(choice == "cancel") break; if(choice == "save") - save_party(univ.file); + save_party(univ.file, univ); } All_Done = true; break; @@ -559,7 +557,7 @@ void handle_options_menu(int item_hit) { ASB("Add PC: You already have 6 PCs."); print_buf(); } - if(univ.town.num == scenario.which_town_start) { + if(univ.town.num == univ.scenario.which_town_start) { give_help(56,0); create_pc(6,NULL); } @@ -744,9 +742,9 @@ void move_sound(ter_num_t ter,short step){ short pic,snd; eTerSpec spec; - pic = scenario.ter_types[ter].picture; - spec = scenario.ter_types[ter].special; - snd = scenario.ter_types[ter].step_sound; + pic = univ.scenario.ter_types[ter].picture; + spec = univ.scenario.ter_types[ter].special; + snd = univ.scenario.ter_types[ter].step_sound; //if on swamp don't play squish sound : BoE legacy behavior, can be removed safely if(snd == 4 && !flying() && univ.party.in_boat == 0){ @@ -762,7 +760,7 @@ void move_sound(ter_num_t ter,short step){ else if(!monsters_going && (overall_mode < MODE_COMBAT) && (univ.party.in_horse >= 0)) {//// is on horse ? play_sound(85); //so play horse sound } - else switch(scenario.ter_types[ter].step_sound){ + else switch(univ.scenario.ter_types[ter].step_sound){ case 1: play_sound(55); //squish break; diff --git a/osx/boe.menus.mac.mm b/osx/boe.menus.mac.mm index cdc8bc59..48927e8f 100644 --- a/osx/boe.menus.mac.mm +++ b/osx/boe.menus.mac.mm @@ -11,7 +11,6 @@ #include #include #include "universe.h" -#include "scenario.h" #include "boe.party.h" #include "boe.infodlg.h" #include "boe.consts.h" @@ -22,7 +21,6 @@ extern short on_monst_menu[256]; extern bool party_in_memory; extern short current_pc; extern cUniverse univ; -extern cScenario scenario; extern eGameMode overall_mode; #ifndef __APPLE__ @@ -90,11 +88,11 @@ void adjust_monst_menu() { } for(i = 0; i < 256; i++) { if(on_monst_menu[i] >= 0) { - std::string monst_name = scenario.scen_monsters[on_monst_menu[i]].m_name; + std::string monst_name = univ.scenario.scen_monsters[on_monst_menu[i]].m_name; NSString* str = [NSString stringWithUTF8String: monst_name.c_str()]; NSMenuItem* newItem = [monst_menu addItemWithTitle: str action: @selector(monstMenu:) keyEquivalent: @""]; [newItem setTarget: targ]; - [newItem setRepresentedObject: [MonsterWrapper withMonster: scenario.scen_monsters[on_monst_menu[i]]]]; + [newItem setRepresentedObject: [MonsterWrapper withMonster: univ.scenario.scen_monsters[on_monst_menu[i]]]]; } } } diff --git a/osx/boe.monster.cpp b/osx/boe.monster.cpp index 7527f997..ea957b04 100644 --- a/osx/boe.monster.cpp +++ b/osx/boe.monster.cpp @@ -33,8 +33,6 @@ extern short hit_chance[21]; extern location center; extern short boom_gr[8],futzing; extern bool processing_fields,monsters_going; -//extern town_item_list univ.town; -extern cScenario scenario; extern cUniverse univ; @@ -89,7 +87,7 @@ short out_enc_lev_tot(short which) { for(i = 0; i < 7; i++) if(univ.party.out_c[which].what_monst.monst[i] != 0) - count += scenario.scen_monsters[univ.party.out_c[which].what_monst.monst[i]].level * num[i]; + count += univ.scenario.scen_monsters[univ.party.out_c[which].what_monst.monst[i]].level * num[i]; return count; } @@ -99,14 +97,12 @@ void create_wand_monst() { r1 = get_ran(1,0,3); if(overall_mode == MODE_OUTDOORS) { - if(!univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering[r1].isNull()) { + if(!univ.out->wandering[r1].isNull()) { r2 = get_ran(1,0,3); - while((point_onscreen(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering_locs[r2], - global_to_local(univ.party.p_loc))) && (num_tries++ < 100)) + while(point_onscreen(univ.out->wandering_locs[r2], global_to_local(univ.party.p_loc)) && num_tries++ < 100) r2 = get_ran(1,0,3); - if(!is_blocked(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering_locs[r2])) - place_outd_wand_monst(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering_locs[r2], - univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].wandering[r1],0); + if(!is_blocked(univ.out->wandering_locs[r2])) + place_outd_wand_monst(univ.out->wandering_locs[r2], univ.out->wandering[r1],0); } } else if(!univ.town->wandering[r1].isNull() && univ.town.countMonsters() <= 50 && univ.party.m_killed[univ.town.num] < univ.town->max_num_monst) { @@ -180,12 +176,12 @@ location get_monst_head(short m_num) { } short get_monst_picnum(m_num_t monst) { - return scenario.scen_monsters[monst].picture_num; + return univ.scenario.scen_monsters[monst].picture_num; } ePicType get_monst_pictype(m_num_t monst) { ePicType type = PIC_MONST; - short n = scenario.scen_monsters[monst].picture_num; + short n = univ.scenario.scen_monsters[monst].picture_num; if(n >= 1000){ type += PIC_CUSTOM; switch(n / 1000){ @@ -209,8 +205,8 @@ ePicType get_monst_pictype(m_num_t monst) { void get_monst_dims(m_num_t monst,short *width, short *height) { - *width = scenario.scen_monsters[monst].x_width; - *height = scenario.scen_monsters[monst].y_width; + *width = univ.scenario.scen_monsters[monst].x_width; + *height = univ.scenario.scen_monsters[monst].y_width; } // Used to set up monsters for outdoor wandering encounters. @@ -220,7 +216,7 @@ void set_up_monst(short mode,m_num_t m_num) { for(which = 0; which < univ.town->max_monst(); which++) if(univ.town.monst[which].active == 0) { - univ.town.monst[which] = cCreature(m_num); + univ.town.monst.assign(which, cCreature(m_num), univ.scenario.scen_monsters[m_num], PSD[SDF_EASY_MODE], univ.difficulty_adjust()); univ.town.monst[which].active = 2; univ.town.monst[which].summoned = 0; univ.town.monst[which].attitude = mode + 1; @@ -920,8 +916,8 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon ter = univ.town->terrain(where_check.x,where_check.y); //// which_m = &univ.town.monst[which_monst]; - ter_abil = scenario.ter_types[ter].special; - ter_flag = scenario.ter_types[ter].flag3.u; + ter_abil = univ.scenario.ter_types[ter].special; + ter_flag = univ.scenario.ter_types[ter].flag3.u; if(mode > 0 && ter_abil == eTerSpec::CONVEYOR) { if( @@ -1025,7 +1021,7 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon } } if(monster_placid(which_monst) && // monsters don't hop into bed when things are calm - scenario.ter_types[ter].special == eTerSpec::BED) + univ.scenario.ter_types[ter].special == eTerSpec::BED) can_enter = false; if(mode == 1 && univ.town.is_spot(where_check.x, where_check.y)) can_enter = false; @@ -1042,10 +1038,10 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon case eTerSpec::CHANGE_WHEN_STEP_ON: can_enter = false; if(!(monster_placid(which_monst))) { - univ.town->terrain(where_check.x,where_check.y) = scenario.ter_types[ter].flag1.u; + univ.town->terrain(where_check.x,where_check.y) = univ.scenario.ter_types[ter].flag1.u; do_look = true; if(point_onscreen(center,where_check)) - play_sound(scenario.ter_types[ter].flag2.u); + play_sound(univ.scenario.ter_types[ter].flag2.u); } break; @@ -1271,10 +1267,9 @@ short place_monster(m_num_t which,location where) { } if(i < univ.town->max_monst()) { - univ.town.monst[i].number = which; - univ.town.monst[i] = cCreature(); - static_cast(univ.town.monst[i]) = scenario.scen_monsters[which]; - univ.town.monst[i].attitude = scenario.scen_monsters[which].default_attitude; + univ.town.monst.assign(i, cCreature(which), univ.scenario.scen_monsters[which], PSD[SDF_EASY_MODE], univ.difficulty_adjust()); + static_cast(univ.town.monst[i]) = univ.scenario.scen_monsters[which]; + univ.town.monst[i].attitude = univ.scenario.scen_monsters[which].default_attitude; if(univ.town.monst[i].attitude % 2 == 0) univ.town.monst[i].attitude = 1; univ.town.monst[i].mobility = 1; @@ -1351,7 +1346,8 @@ void activate_monsters(short code,short /*attitude*/) { return; for(i = 0; i < univ.town->max_monst(); i++) if(univ.town.monst[i].spec_enc_code == code) { - univ.town.monst[i] = univ.town->creatures(i); + cCreature& monst = univ.town->creatures(i); + univ.town.monst.assign(i, monst, univ.scenario.scen_monsters[monst.number], PSD[SDF_EASY_MODE], univ.difficulty_adjust()); univ.town.monst[i].spec_enc_code = 0; univ.town.monst[i].active = 2; // TODO: Can thes be commented out? \/ //univ.town.monst[i].attitude = univ.town->creatures(i).start_attitude; @@ -1385,7 +1381,7 @@ m_num_t get_summon_monster(short summon_class) { for(i = 0; i < 200; i++) { j = get_ran(1,0,255); - if(scenario.scen_monsters[j].summon_type == summon_class) { + if(univ.scenario.scen_monsters[j].summon_type == summon_class) { return j; } } diff --git a/osx/boe.newgraph.cpp b/osx/boe.newgraph.cpp index a70795c2..03082361 100644 --- a/osx/boe.newgraph.cpp +++ b/osx/boe.newgraph.cpp @@ -71,7 +71,6 @@ extern char unexplored_area[13][13]; extern tessel_ref_t bw_pats[6]; extern short combat_posing_monster , current_working_monster ; // 0-5 PC 100 + x - monster x extern short store_talk_face_pic; -extern cScenario scenario; extern cUniverse univ; //extern talking_record_type talking; @@ -928,7 +927,7 @@ static void place_talk_face() { face_rect.offset(talk_area_rect.topLeft()); face_rect.offset(ul); mainPtr.setActive(); - short face_to_draw = scenario.scen_monsters[store_monst_type].default_facial_pic; + short face_to_draw = univ.scenario.scen_monsters[store_monst_type].default_facial_pic; if(store_talk_face_pic >= 0) face_to_draw = store_talk_face_pic; if(store_talk_face_pic >= 1000) { diff --git a/osx/boe.party.cpp b/osx/boe.party.cpp index 588a1f3e..2e9b5691 100644 --- a/osx/boe.party.cpp +++ b/osx/boe.party.cpp @@ -90,7 +90,6 @@ extern short current_ground; extern short monst_marked_damage[60]; extern location golem_m_locs[16]; //extern town_item_list t_i; -extern cScenario scenario; extern cUniverse univ; //extern piles_of_stuff_dumping_type *data_store; extern sf::Texture pc_gworld; @@ -111,132 +110,6 @@ short store_graphic_pc_num ; short store_graphic_mode ; short store_pc_graphic; -//mode; // 0 - prefab 1 - regular 2 - debug -// Note: mode 1 is never used -void init_party(short mode) { - // TODO: Remove in favour of cParty constructor. - short i,j,k,l; - - cVehicle null_boat;// = {{0,0},{0,0},{0,0},200,false}; - cVehicle null_horse;// = {{0,0},{0,0},{0,0},200,false}; - - univ.party.age = 0; - univ.party.gold = 200; - univ.party.food = 100; - for(i = 0; i < 310; i++) - for(j = 0; j < 10; j++) - PSD[i][j] = 0; - univ.party.light_level = 0; - univ.party.outdoor_corner.x = 7; - univ.party.outdoor_corner.y = 8; - univ.party.i_w_c.x = 1; - univ.party.i_w_c.y = 1; - univ.party.loc_in_sec.x = 36; - univ.party.loc_in_sec.y = 36; - univ.party.p_loc.x = 84; - univ.party.p_loc.y = 84; - for(i = 0; i < 30; i++) - univ.party.boats[i] = null_boat; - for(i = 0; i < 30; i++) - univ.party.horses[i] = null_horse; - univ.party.in_boat = -1; - univ.party.in_horse = -1; - for(i = 0; i < 4; i++) - univ.party.creature_save[i].which_town = 200; - for(i = 0; i < 10; i++) - univ.party.out_c[i].exists = false; - for(i = 0; i < 5; i++) - for(j = 0; j < 10; j++) - univ.party.magic_store_items[i][j].variety = eItemType::NO_ITEM; - for(i = 0; i < 4; i++) - univ.party.imprisoned_monst[i] = 0; - for(i = 0; i < 256; i++) - univ.party.m_seen[i] = univ.party.m_noted[i] = 0; -// for(i = 0; i < 50; i++) -// univ.party.journal_str[i] = -1; -// for(i = 0; i < 140; i++) -// for(j = 0; j < 2; j++) -// univ.party.special_notes_str[i][j] = 0; -// for(i = 0; i < 120; i++) -// univ.party.talk_save[i].personality = -1; - univ.party.journal.clear(); - univ.party.special_notes.clear(); - univ.party.talk_save.clear(); - - univ.party.total_m_killed = 0; - univ.party.total_dam_done = 0; - univ.party.total_xp_gained = 0; - univ.party.total_dam_taken = 0; - univ.party.direction = 0; - univ.party.at_which_save_slot = 0; - for(i = 0; i < 20; i++) - univ.party.alchemy[i] = 0; - for(i = 0; i < 200; i++) - univ.party.can_find_town[i] = 0; - for(i = 0; i < 20; i++) - univ.party.key_times[i] = 30000; - univ.party.party_event_timers.clear(); - for(i = 0; i < 50; i++) - univ.party.spec_items[i] = 0; - for(i = 0; i < 200; i++) - univ.party.m_killed[i] = 0; - univ.party.scen_name = ""; - - for(i = 0; i < 200; i++) - for(j = 0; j < 8; j++) - univ.party.item_taken[i][j] = 0; - - // Zero out campaign flags and pointers - univ.party.campaign_flags.clear(); - univ.party.pointers.clear(); - - - refresh_store_items(); - - for(i = 0; i < 6; i++) { - switch(mode){ - case 0: - univ.party[i] = cPlayer('dflt',i); - break; - case 1: - univ.party[i] = cPlayer(); - break; - case 2: - univ.party[i] = cPlayer('dbug',i); - break; - } - } - - for(i = 0; i < 96; i++) - for(j = 0; j < 96; j++) - univ.out.out_e[i][j] = 0; - - - for(i = 0; i < 3;i++) - for(j = 0; j < NUM_TOWN_ITEMS; j++) { - univ.party.stored_items[i][j] = cItemRec(); - } - - for(i = 0; i < 200; i++) - for(j = 0; j < 8; j++) - for(k = 0; k < 64; k++) - univ.town_maps[i][j][k] = 0; - - for(i = 0; i < 100; i++) - for(k = 0; k < 6; k++) - for(l = 0; l < 48; l++) - univ.out_maps[i][k][l] = 0; - - // Default is save maps - PSD[SDF_NO_MAPS] = 0; - save_maps = true; - - - // NOT DEBUG - build_outdoors(); - -} - // This is only called after a scenario is loaded and the party is put into it. // Until that time, the party scen vals are uninited // Then, it inits the party properly for starting the scenario based @@ -253,28 +126,28 @@ void init_party_scen_data() { PSD[i][j] = 0; PSD[SDF_NO_INSTANT_HELP] = store_help; univ.party.light_level = 0; - univ.party.outdoor_corner.x = scenario.out_sec_start.x; - univ.party.outdoor_corner.y = scenario.out_sec_start.y; + univ.party.outdoor_corner.x = univ.scenario.out_sec_start.x; + univ.party.outdoor_corner.y = univ.scenario.out_sec_start.y; univ.party.i_w_c.x = 0; univ.party.i_w_c.y = 0; - univ.party.loc_in_sec.x = scenario.out_start.x; - univ.party.loc_in_sec.y = scenario.out_start.y; - univ.party.p_loc.x = scenario.out_start.x; - univ.party.p_loc.y = scenario.out_start.y; + univ.party.loc_in_sec.x = univ.scenario.out_start.x; + univ.party.loc_in_sec.y = univ.scenario.out_start.y; + univ.party.p_loc.x = univ.scenario.out_start.x; + univ.party.p_loc.y = univ.scenario.out_start.y; for(i = 0; i < 30; i++) - univ.party.boats[i] = scenario.boats[i]; + univ.party.boats[i] = univ.scenario.boats[i]; for(i = 0; i < 30; i++) - univ.party.horses[i] = scenario.horses[i]; + univ.party.horses[i] = univ.scenario.horses[i]; for(i = 0; i < 30; i++) { - if((scenario.boats[i].which_town >= 0) && (scenario.boats[i].loc.x >= 0)) { + if(univ.scenario.boats[i].which_town >= 0 && univ.scenario.boats[i].loc.x >= 0) { if(!univ.party.boats[i].exists) { - univ.party.boats[i] = scenario.boats[i]; + univ.party.boats[i] = univ.scenario.boats[i]; univ.party.boats[i].exists = true; } } - if((scenario.horses[i].which_town >= 0) && (scenario.horses[i].loc.x >= 0)) { + if(univ.scenario.horses[i].which_town >= 0 && univ.scenario.horses[i].loc.x >= 0) { if(!univ.party.horses[i].exists) { - univ.party.horses[i] = scenario.horses[i]; + univ.party.horses[i] = univ.scenario.horses[i]; univ.party.horses[i].exists = true; } } @@ -306,12 +179,12 @@ void init_party_scen_data() { univ.party.direction = 0; univ.party.at_which_save_slot = 0; for(i = 0; i < 200; i++) - univ.party.can_find_town[i] = 1 - scenario.town_hidden[i]; + univ.party.can_find_town[i] = !univ.scenario.town_hidden[i]; for(i = 0; i < 20; i++) univ.party.key_times[i] = 30000; univ.party.party_event_timers.clear(); for(i = 0; i < 50; i++) - univ.party.spec_items[i] = (scenario.special_items[i].flags >= 10) ? 1 : 0; + univ.party.spec_items[i] = (univ.scenario.special_items[i].flags >= 10) ? 1 : 0; for(i = 0; i < 200; i++) univ.party.m_killed[i] = 0; @@ -403,7 +276,7 @@ void put_party_in_scen(std::string scen_name) { path = progDir/"Blades of Exile Scenarios"; path /= scen_name; std::cout<<"Searching for scenario at:\n"<= 10) ? 1 : 0; + univ.party.spec_items[i] = (univ.scenario.special_items[i].flags >= 10) ? 1 : 0; // Compatibility flags - if(scenario.format.prog_make_ver[0] < 2){ + if(univ.scenario.format.prog_make_ver[0] < 2){ PSD[SDF_RESURRECT_NO_BALM] = 1; PSD[SDF_NO_BOAT_SPECIALS] = 1; PSD[SDF_TIMERS_DURING_REST] = 0; @@ -1370,11 +1239,11 @@ void do_priest_spell(short pc_num,eSpell spell_num) { } univ.party[pc_num].cur_sp -= (*spell_num).cost; add_string_to_buf(" You are moved... "); - force_town_enter(scenario.which_town_start,scenario.where_start); - start_town_mode(scenario.which_town_start,9); - position_party(scenario.out_sec_start.x,scenario.out_sec_start.y, - scenario.out_start.x,scenario.out_start.y); - center = univ.town.p_loc = scenario.where_start; + force_town_enter(univ.scenario.which_town_start,univ.scenario.where_start); + start_town_mode(univ.scenario.which_town_start,9); + position_party(univ.scenario.out_sec_start.x,univ.scenario.out_sec_start.y, + univ.scenario.out_start.x,univ.scenario.out_start.y); + center = univ.town.p_loc = univ.scenario.where_start; // overall_mode = MODE_OUTDOORS; // center = univ.party.p_loc; // update_explored(univ.party.p_loc); @@ -1718,17 +1587,17 @@ void cast_town_spell(location where) { case eSpell::UNLOCK: // TODO: Is the unlock spell supposed to have a max range? - if(scenario.ter_types[ter].special == eTerSpec::UNLOCKABLE){ - if(scenario.ter_types[ter].flag2.u == 10) + if(univ.scenario.ter_types[ter].special == eTerSpec::UNLOCKABLE){ + if(univ.scenario.ter_types[ter].flag2.u == 10) r1 = 10000; else{ r1 = get_ran(1,1,100) - 5 * stat_adj(who_cast,eSkill::INTELLIGENCE) + 5 * univ.town.difficulty; - r1 += scenario.ter_types[ter].flag2.u * 7; + r1 += univ.scenario.ter_types[ter].flag2.u * 7; } if(r1 < (135 - combat_percent[min(19,univ.party[who_cast].level)])) { add_string_to_buf(" Door unlocked. "); play_sound(9); - univ.town->terrain(where.x,where.y) = scenario.ter_types[ter].flag1.u; + univ.town->terrain(where.x,where.y) = univ.scenario.ter_types[ter].flag1.u; } else { play_sound(41); @@ -1789,9 +1658,9 @@ void crumble_wall(location where) { // TODO: Add something like this to the spre if(loc_off_act_area(where)) return; ter = univ.town->terrain(where.x,where.y); - if(scenario.ter_types[ter].special == eTerSpec::CRUMBLING && scenario.ter_types[ter].flag3.u < 2) { + if(univ.scenario.ter_types[ter].special == eTerSpec::CRUMBLING && univ.scenario.ter_types[ter].flag3.u < 2) { play_sound(60); - univ.town->terrain(where.x,where.y) = scenario.ter_types[ter].flag1.u; + univ.town->terrain(where.x,where.y) = univ.scenario.ter_types[ter].flag1.u; add_string_to_buf(" Barrier crumbles."); } @@ -2702,7 +2571,7 @@ m_num_t pick_trapped_monst() { else { sp = get_m_name(univ.party.imprisoned_monst[i]); soulCrystal->getControl("slot" + n).setText(sp); - get_monst = scenario.scen_monsters[univ.party.imprisoned_monst[i]]; + get_monst = univ.scenario.scen_monsters[univ.party.imprisoned_monst[i]]; soulCrystal->getControl("lvl" + n).setTextToNum(get_monst.level); } } diff --git a/osx/boe.party.h b/osx/boe.party.h index 80ce732e..b51a8db4 100644 --- a/osx/boe.party.h +++ b/osx/boe.party.h @@ -3,8 +3,6 @@ #define BOE_GAME_PARTY_H class cDialog; -__declspec(deprecated) void init_party(short mode); -__declspec(deprecated) void init_party_scen_data(); void make_boats(); bool create_pc(short spot,cDialog* parent_num); bool take_sp(short pc_num,short amt); diff --git a/osx/boe.specials.cpp b/osx/boe.specials.cpp index 05144930..859321ed 100644 --- a/osx/boe.specials.cpp +++ b/osx/boe.specials.cpp @@ -49,7 +49,6 @@ extern eSpell spell_being_cast, town_spell; extern sf::RenderWindow mini_map; extern bool fast_bang,end_scenario; //extern short town_size[3]; -extern cScenario scenario; extern cUniverse univ; extern std::queue special_queue; //extern piles_of_stuff_dumping_type *data_store; @@ -166,11 +165,11 @@ bool check_special_terrain(location where_check,eSpecCtx mode,short which_pc,sho printf("Note: Improper mode passed to check_special_terrain: %d\n", (int)mode); return false; } - ter_special = scenario.ter_types[ter].special; - ter_flag1 = scenario.ter_types[ter].flag1; - ter_flag2 = scenario.ter_types[ter].flag2; - ter_flag3 = scenario.ter_types[ter].flag3; - ter_pic = scenario.ter_types[ter].picture; + ter_special = univ.scenario.ter_types[ter].special; + ter_flag1 = univ.scenario.ter_types[ter].flag1; + ter_flag2 = univ.scenario.ter_types[ter].flag2; + ter_flag3 = univ.scenario.ter_types[ter].flag3; + ter_pic = univ.scenario.ter_types[ter].picture; // TODO: Why not support conveyors outdoors, too? if(mode != eSpecCtx::OUT_MOVE && ter_special == eTerSpec::CONVEYOR) { @@ -188,13 +187,13 @@ bool check_special_terrain(location where_check,eSpecCtx mode,short which_pc,sho out_where = global_to_local(where_check); for(i = 0; i < 18; i++) - if(out_where == univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_locs[i]) { - *spec_num = univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_id[i]; + if(out_where == univ.out->special_locs[i]) { + *spec_num = univ.out->special_id[i]; if((*spec_num >= 0) && - univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].specials[*spec_num].type == eSpecType::SECRET_PASSAGE) + univ.out->specials[*spec_num].type == eSpecType::SECRET_PASSAGE) *forced = true; // call special - run_special(mode,1,univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_id[i],out_where,&s1,&s2,&s3); + run_special(mode,1,univ.out->special_id[i],out_where,&s1,&s2,&s3); if(s1 > 0) can_enter = false; erase_out_specials(); @@ -204,7 +203,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,short which_pc,sho } if((is_combat()) && (univ.town.is_spot(where_check.x, where_check.y) || - (scenario.ter_types[coord_to_ter(where_check.x, where_check.y)].trim_type == eTrimType::CITY))) { + (univ.scenario.ter_types[coord_to_ter(where_check.x, where_check.y)].trim_type == eTrimType::CITY))) { ASB("Move: Can't trigger this special in combat."); return false; // TODO: Maybe replace eTrimType::CITY check with a blockage == clear/special && is_special() check? } @@ -229,7 +228,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,short which_pc,sho if(!is_blocked(where_check)) runSpecial = true; if(ter_special == eTerSpec::CHANGE_WHEN_STEP_ON) runSpecial = true; if(ter_special == eTerSpec::CALL_SPECIAL) runSpecial = true; - if(!PSD[SDF_NO_BOAT_SPECIALS] && univ.party.in_boat >= 0 && scenario.ter_types[ter].boat_over) + if(!PSD[SDF_NO_BOAT_SPECIALS] && univ.party.in_boat >= 0 && univ.scenario.ter_types[ter].boat_over) runSpecial = true; if(runSpecial) { give_help(54,0); @@ -314,7 +313,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,short which_pc,sho play_sound(-1 * ter_flag2.u); } give_help(47,65); - if(blocksMove(scenario.ter_types[ter].blockage)) + if(blocksMove(univ.scenario.ter_types[ter].blockage)) can_enter = false; break; case eTerSpec::DAMAGING: @@ -595,7 +594,7 @@ void use_spec_item(short item) { short i,j,k; location null_loc; - run_special(eSpecCtx::USE_SPEC_ITEM,0,scenario.special_items[item].special,univ.party.p_loc,&i,&j,&k); + run_special(eSpecCtx::USE_SPEC_ITEM,0,univ.scenario.special_items[item].special,univ.party.p_loc,&i,&j,&k); } @@ -1234,24 +1233,24 @@ bool use_space(location where) { univ.town.set_block((short) to_loc.x,(short) to_loc.y,true); } - if(scenario.ter_types[ter].special == eTerSpec::CHANGE_WHEN_USED) { + if(univ.scenario.ter_types[ter].special == eTerSpec::CHANGE_WHEN_USED) { if(where == from_loc) { add_string_to_buf(" Not while on space."); return false; } add_string_to_buf(" OK."); - alter_space(where.x,where.y,scenario.ter_types[ter].flag1.u); - play_sound(scenario.ter_types[ter].flag2.u); + alter_space(where.x,where.y,univ.scenario.ter_types[ter].flag1.u); + play_sound(univ.scenario.ter_types[ter].flag2.u); return true; - } else if(scenario.ter_types[ter].special == eTerSpec::CALL_SPECIAL_WHEN_USED) { + } else if(univ.scenario.ter_types[ter].special == eTerSpec::CALL_SPECIAL_WHEN_USED) { short spec_type = 0; - if(scenario.ter_types[ter].flag2.u == 3){ + if(univ.scenario.ter_types[ter].flag2.u == 3){ if((is_town() || (is_combat() && which_combat_type == 1))) spec_type = 2; else spec_type = 1; - }else if(scenario.ter_types[ter].flag2.u == 1 && (is_town() || (is_combat() && which_combat_type == 1))) + }else if(univ.scenario.ter_types[ter].flag2.u == 1 && (is_town() || (is_combat() && which_combat_type == 1))) spec_type = 2; - else if(scenario.ter_types[ter].flag2.u == 2 && (is_out() || (is_combat() && which_combat_type == 1))) + else if(univ.scenario.ter_types[ter].flag2.u == 2 && (is_out() || (is_combat() && which_combat_type == 1))) spec_type = 1; - run_special(eSpecCtx::USE_SPACE,spec_type,scenario.ter_types[ter].flag1.u,where,&i,&i,&i); + run_special(eSpecCtx::USE_SPACE,spec_type,univ.scenario.ter_types[ter].flag1.u,where,&i,&i,&i); return true; } add_string_to_buf(" Nothing to use."); @@ -1295,8 +1294,8 @@ bool adj_town_look(location where) { } if(is_container(where) && item_there && can_open) { get_item(where,6,true); - }else if(scenario.ter_types[terrain].special == eTerSpec::CHANGE_WHEN_USED || - scenario.ter_types[terrain].special == eTerSpec::CALL_SPECIAL_WHEN_USED) { + }else if(univ.scenario.ter_types[terrain].special == eTerSpec::CHANGE_WHEN_USED || + univ.scenario.ter_types[terrain].special == eTerSpec::CALL_SPECIAL_WHEN_USED) { add_string_to_buf(" (Use this space to do something"); add_string_to_buf(" with it.)"); }else{ @@ -1318,10 +1317,10 @@ void PSOE(short which_special,unsigned char *stuff_done_val,short where_put) { else *stuff_done_val = 20; } for(i = 0; i < 18; i++) - if(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_id[i] == where_put) { + if(univ.out->special_id[i] == where_put) { for(j = 0; j < 7; j++) - if(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_enc[which_special].monst[j] > 0) { - graphic_num = 400 + get_monst_picnum(univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_enc[which_special].monst[j]); + if(univ.out->special_enc[which_special].monst[j] > 0) { + graphic_num = get_monst_picnum(univ.out->special_enc[which_special].monst[j]); j = 7; } //display_strings( str1a, str1b, str2a, str2b, @@ -1417,7 +1416,7 @@ void fade_party() { void change_level(short town_num,short x,short y) { location l(x,y); - if((town_num < 0) || (town_num >= scenario.num_towns)) { + if((town_num < 0) || (town_num >= univ.scenario.num_towns)) { giveError("The scenario special encounter tried to put you into a town that doesn't exist."); return; } @@ -1740,7 +1739,7 @@ void push_things() { if(univ.town.monst[i].active > 0) { l = univ.town.monst[i].cur_loc; ter = univ.town->terrain(l.x,l.y); - switch(scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions + switch(univ.scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions case DIR_N: l.y--; break; case DIR_E: l.x++; break; case DIR_S: l.y++; break; @@ -1757,7 +1756,7 @@ void push_things() { if(univ.town.items[i].variety != eItemType::NO_ITEM) { l = univ.town.items[i].item_loc; ter = univ.town->terrain(l.x,l.y); - switch(scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions + switch(univ.scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions case DIR_N: l.y--; break; case DIR_E: l.x++; break; case DIR_S: l.y++; break; @@ -1774,7 +1773,7 @@ void push_things() { if(is_town()) { ter = univ.town->terrain(univ.town.p_loc.x,univ.town.p_loc.y); l = univ.town.p_loc; - switch(scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions + switch(univ.scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions case DIR_N: l.y--; break; case DIR_E: l.x++; break; case DIR_S: l.y++; break; @@ -1782,7 +1781,7 @@ void push_things() { } if(l != univ.town.p_loc) { ASB("You get pushed."); - if(scenario.ter_types[ter].special == eTerSpec::CONVEYOR) + if(univ.scenario.ter_types[ter].special == eTerSpec::CONVEYOR) draw_terrain(0); center = l; univ.town.p_loc = l; @@ -1813,7 +1812,7 @@ void push_things() { if(univ.party[i].main_status == eMainStatus::ALIVE) { ter = univ.town->terrain(univ.party[i].combat_pos.x,univ.party[i].combat_pos.y); l = univ.party[i].combat_pos; - switch(scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions + switch(univ.scenario.ter_types[ter].flag1.u) { // TODO: Implement the other 4 possible directions case DIR_N: l.y--; break; case DIR_E: l.x++; break; case DIR_S: l.y++; break; @@ -1822,7 +1821,7 @@ void push_things() { if(l != univ.party[i].combat_pos) { ASB("Someone gets pushed."); ter = univ.town->terrain(l.x,l.y); - if(scenario.ter_types[ter].special == eTerSpec::CONVEYOR) + if(univ.scenario.ter_types[ter].special == eTerSpec::CONVEYOR) draw_terrain(0); univ.party[i].combat_pos = l; update_explored(l); @@ -1879,14 +1878,14 @@ void special_increase_age(long length, bool queue) { } univ.party.age = current_age; for(i = 0; i < 20; i++) - if(scenario.scenario_timer_times[i] > 0) { - short time = scenario.scenario_timer_times[i]; + if(univ.scenario.scenario_timer_times[i] > 0) { + short time = univ.scenario.scenario_timer_times[i]; for(unsigned long j = age_before; j <= current_age; j++) if(j % time == 0) { if(queue) { univ.party.age = j; - queue_special(eSpecCtx::SCEN_TIMER, 0, scenario.scenario_timer_specs[i], null_loc); - } else run_special(eSpecCtx::SCEN_TIMER,0,scenario.scenario_timer_specs[i],null_loc,&s1,&s2,&s3); + queue_special(eSpecCtx::SCEN_TIMER, 0, univ.scenario.scenario_timer_specs[i], null_loc); + } else run_special(eSpecCtx::SCEN_TIMER,0,univ.scenario.scenario_timer_specs[i],null_loc,&s1,&s2,&s3); } stat_area = true; if(s3 > 0) @@ -2064,21 +2063,21 @@ void run_special(eSpecCtx which_mode,short which_type,short start_spec,location cSpecial get_node(short cur_spec,short cur_spec_type) { cSpecial dummy_node; - dummy_node = scenario.scen_specials[0]; + dummy_node = univ.scenario.scen_specials[0]; dummy_node.type = eSpecType::ERROR; if(cur_spec_type == 0) { if(cur_spec != minmax(0,255,cur_spec)) { giveError("The scenario called a scenario special node out of range."); return dummy_node; } - return scenario.scen_specials[cur_spec]; + return univ.scenario.scen_specials[cur_spec]; } if(cur_spec_type == 1) { if(cur_spec != minmax(0,59,cur_spec)) { giveError("The scenario called an outdoor special node out of range."); return dummy_node; } - return univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].specials[cur_spec]; + return univ.out->specials[cur_spec]; } if(cur_spec_type == 2) { if(cur_spec != minmax(0,99,cur_spec)) { @@ -2161,7 +2160,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, break; case eSpecType::SET_TOWN_VISIBILITY: check_mess = true; - if(spec.ex1a != minmax(0,scenario.num_towns - 1,spec.ex1a)) + if(spec.ex1a != minmax(0,univ.scenario.num_towns - 1,spec.ex1a)) giveError("Town out of range."); else univ.party.can_find_town[spec.ex1a] = spec.ex2a; *redraw = true; @@ -2485,8 +2484,7 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, } else { l = global_to_local(univ.party.p_loc); - place_outd_wand_monst(l, - univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_enc[spec.ex1a],true); + place_outd_wand_monst(l, univ.out->special_enc[spec.ex1a],true); } break; case eSpecType::ONCE_TOWN_ENCOUNTER: @@ -3346,9 +3344,9 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, void set_terrain(location l, ter_num_t terrain_type) { ter_num_t former = univ.town->terrain(l.x,l.y); univ.town->terrain(l.x,l.y) = terrain_type; - if(scenario.ter_types[terrain_type].special == eTerSpec::CONVEYOR) + if(univ.scenario.ter_types[terrain_type].special == eTerSpec::CONVEYOR) belt_present = true; - if(scenario.ter_types[former].light_radius != scenario.ter_types[terrain_type].light_radius) + if(univ.scenario.ter_types[former].light_radius != univ.scenario.ter_types[terrain_type].light_radius) univ.town->set_up_lights(); } @@ -3398,7 +3396,7 @@ void townmode_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, break; case eSpecType::TOWN_TRANS_TER: ter = coord_to_ter(spec.ex1a,spec.ex1b); - set_terrain(l,scenario.ter_types[ter].trans_to_what); + set_terrain(l,univ.scenario.ter_types[ter].trans_to_what); *redraw = 1; draw_map(true); break; @@ -3432,14 +3430,14 @@ void townmode_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, break; case eSpecType::TOWN_LOCK_SPACE: ter = coord_to_ter(spec.ex1a,spec.ex1b); - if(scenario.ter_types[ter].special == eTerSpec::LOCKABLE) - set_terrain(l,scenario.ter_types[ter].flag1.u); + if(univ.scenario.ter_types[ter].special == eTerSpec::LOCKABLE) + set_terrain(l,univ.scenario.ter_types[ter].flag1.u); *redraw = 1; break; case eSpecType::TOWN_UNLOCK_SPACE: ter = coord_to_ter(spec.ex1a,spec.ex1b); - if(scenario.ter_types[ter].special == eTerSpec::UNLOCKABLE) - set_terrain(l,scenario.ter_types[ter].flag1.u); + if(univ.scenario.ter_types[ter].special == eTerSpec::UNLOCKABLE) + set_terrain(l,univ.scenario.ter_types[ter].flag1.u); *redraw = 1; break; case eSpecType::TOWN_SFX_BURST: // TODO: Add a "random offset" mode @@ -3553,7 +3551,7 @@ void townmode_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, if(i == 1) {*next_spec = -1;} else { ter = coord_to_ter(store_special_loc.x,store_special_loc.y); - set_terrain(store_special_loc,scenario.ter_types[ter].trans_to_what); + set_terrain(store_special_loc,univ.scenario.ter_types[ter].trans_to_what); *next_spec = spec.ex1b; } } @@ -3860,22 +3858,22 @@ void rect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, break; case eSpecType::RECT_TRANS_TER: ter = coord_to_ter(i,j); - set_terrain(l,scenario.ter_types[ter].trans_to_what); + set_terrain(l,univ.scenario.ter_types[ter].trans_to_what); *redraw = true; draw_map(true); break; case eSpecType::RECT_LOCK: ter = coord_to_ter(i,j); - if(scenario.ter_types[ter].special == eTerSpec::LOCKABLE){ - set_terrain(l,scenario.ter_types[ter].flag1.u); + if(univ.scenario.ter_types[ter].special == eTerSpec::LOCKABLE){ + set_terrain(l,univ.scenario.ter_types[ter].flag1.u); *redraw = true; draw_map(true); } break; case eSpecType::RECT_UNLOCK: ter = coord_to_ter(i,j); - if(scenario.ter_types[ter].special == eTerSpec::UNLOCKABLE){ - set_terrain(l,scenario.ter_types[ter].flag1.u); + if(univ.scenario.ter_types[ter].special == eTerSpec::UNLOCKABLE){ + set_terrain(l,univ.scenario.ter_types[ter].flag1.u); *redraw = true; draw_map(true); break; @@ -3906,7 +3904,7 @@ void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, *redraw = 1; break; case eSpecType::OUT_CHANGE_TER: - univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].terrain[spec.ex1a][spec.ex1b] = spec.ex2a; + univ.out->terrain[spec.ex1a][spec.ex1b] = spec.ex2a; l.x = spec.ex1a; l.y = spec.ex1b; l = local_to_global(l); @@ -3921,8 +3919,7 @@ void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, } else { l = global_to_local(univ.party.p_loc); - place_outd_wand_monst(l, - univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].special_enc[spec.ex1a],true); + place_outd_wand_monst(l, univ.out->special_enc[spec.ex1a],true); check_mess = true; } break; @@ -3987,10 +3984,10 @@ void handle_message(eSpecCtx which_mode,short cur_type,short mess1,short mess2,s return; } get_strs(str1, str2, cur_type, mess1, mess2); - where1 = is_out() ? univ.party.i_w_c.x : univ.town.num; - where2 = is_out() ? univ.party.i_w_c.y : univ.town.num; - std::string placename = is_out() ? univ.out.outdoors[where1][where2].out_name : univ.town->town_name; - cStrDlog display_strings(str1.c_str(), str2.c_str(),"",scenario.intro_pic,PIC_SCEN,0); + where1 = is_out() ? univ.party.outdoor_corner.x + univ.party.i_w_c.x : univ.town.num; + where2 = is_out() ? univ.party.outdoor_corner.y + univ.party.i_w_c.y : univ.town.num; + std::string placename = is_out() ? univ.out->out_name : univ.town->town_name; + cStrDlog display_strings(str1.c_str(), str2.c_str(),"",univ.scenario.intro_pic,PIC_SCEN,0); display_strings.setSound(57); display_strings.setRecordHandler(cStringRecorder(note_type).string1(mess1).string2(mess2).from(where1,where2).at(placename)); display_strings.show(); @@ -4007,17 +4004,17 @@ void get_strs(std::string& str1,std::string& str2,short cur_type,short which_str switch(cur_type) { case 0: if(which_str1 >= 0) - str1 = scenario.spec_strs[which_str1]; + str1 = univ.scenario.spec_strs[which_str1]; if(which_str2 >= 0) - str2 = scenario.spec_strs[which_str2]; + str2 = univ.scenario.spec_strs[which_str2]; break; case 1: if(which_str1 >= 0) //load_outdoor_str(loc(univ.party.outdoor_corner.x + univ.party.i_w_c.x,univ.party.outdoor_corner.y + univ.party.i_w_c.y),which_str1,(char *) str1); - str1 = univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].spec_strs[which_str1]; + str1 = univ.out->spec_strs[which_str1]; if(which_str2 >= 0) //load_outdoor_str(loc(univ.party.outdoor_corner.x + univ.party.i_w_c.x,univ.party.outdoor_corner.y + univ.party.i_w_c.y),which_str2,(char *) str2); - str2 = univ.out.outdoors[univ.party.i_w_c.x][univ.party.i_w_c.y].spec_strs[which_str2]; + str2 = univ.out->spec_strs[which_str2]; break; case 2: if(which_str1 >= 0) @@ -4035,7 +4032,7 @@ void set_campaign_flag(short sdf_a, short sdf_b, short cpf_a, short cpf_b, short // get_send = true: Retrieve value from Campaign Flag and put in SDF try { if(str >= 0) { - std::string cp_id = scenario.spec_strs[str]; + std::string cp_id = univ.scenario.spec_strs[str]; if(get_send) univ.party.stuff_done[sdf_a][sdf_b] = univ.party.cpn_flag(cpf_a, cpf_b, cp_id); else diff --git a/osx/boe.text.cpp b/osx/boe.text.cpp index 1387ecf8..1972a8e7 100644 --- a/osx/boe.text.cpp +++ b/osx/boe.text.cpp @@ -57,7 +57,6 @@ extern short dest_personalities[40]; extern location source_locs[6]; extern location dest_locs[40] ; //extern piles_of_stuff_dumping_type *data_store; -extern cScenario scenario; extern sf::Texture tiny_obj_gworld,invenbtn_gworld,status_gworld; extern cCustomGraphics spec_scen_g; @@ -258,10 +257,10 @@ void put_item_screen(short screen_num,short suppress_buttons) { i_num = i + item_offset; if(spec_item_array[i_num] >= 0) { // 2nd condition above is quite kludgy, in case it gets here with array all 0's - win_draw_string(item_stats_gworld,item_buttons[i][0],scenario.special_items[spec_item_array[i_num]].name,eTextMode::WRAP,style); + win_draw_string(item_stats_gworld,item_buttons[i][0],univ.scenario.special_items[spec_item_array[i_num]].name,eTextMode::WRAP,style); place_item_button(3,i,4,0); - if((scenario.special_items[spec_item_array[i_num]].flags % 10 == 1) + if((univ.scenario.special_items[spec_item_array[i_num]].flags % 10 == 1) && (!(is_combat()))) place_item_button(0,i,3,0); } @@ -951,7 +950,7 @@ std::string get_m_name(m_num_t num) { //// //strcpy((char *) str,(char *) scenario.scen_monsters[num].m_name); - return scenario.scen_monsters[num].m_name; + return univ.scenario.scen_monsters[num].m_name; } std::string get_ter_name(ter_num_t num) { std::string store_name = "Pit"; @@ -960,7 +959,7 @@ std::string get_ter_name(ter_num_t num) { if((num == 90) && ((is_out()) || (is_town()) || ((is_combat()) && (which_combat_type == 1)))); //sprintf((char *) store_name,"Pit"); else { - store_name = scenario.ter_types[num].name; + store_name = univ.scenario.ter_types[num].name; } return store_name; } diff --git a/osx/boe.town.cpp b/osx/boe.town.cpp index 2503a190..ef791c9b 100644 --- a/osx/boe.town.cpp +++ b/osx/boe.town.cpp @@ -60,7 +60,6 @@ extern sf::RenderWindow mini_map; extern location hor_vert_place[14]; extern location diag_place[14]; extern location golem_m_locs[16]; -extern cScenario scenario; extern cUniverse univ; //extern piles_of_stuff_dumping_type *data_store; extern sf::Texture anim_gworld; @@ -138,19 +137,19 @@ void start_town_mode(short which_town, short entry_dir) { former_town = town_number = which_town; - if((town_number < 0) || (town_number >= scenario.num_towns)) { + if(town_number < 0 || town_number >= univ.scenario.num_towns) { giveError("The scenario tried to put you into a town that doesn't exist.", - "Requested town: " + std::to_string(town_number) + "|Max town: " + std::to_string(scenario.num_towns)); + "Requested town: " + std::to_string(town_number) + "|Max town: " + std::to_string(univ.scenario.num_towns)); return; } // Now adjust town number as necessary. for(i = 0; i < 10; i++) - if((scenario.town_to_add_to[i] >= 0) && (scenario.town_to_add_to[i] < 200) && - (town_number == scenario.town_to_add_to[i]) && - (sd_legit(scenario.flag_to_add_to_town[i][0],scenario.flag_to_add_to_town[i][1]))) { + if(univ.scenario.town_to_add_to[i] >= 0 && univ.scenario.town_to_add_to[i] < 200 && + town_number == univ.scenario.town_to_add_to[i] && + sd_legit(univ.scenario.flag_to_add_to_town[i][0],univ.scenario.flag_to_add_to_town[i][1])) { former_town = town_number; - town_number += PSD[scenario.flag_to_add_to_town[i][0]][scenario.flag_to_add_to_town[i][1]]; + town_number += PSD[univ.scenario.flag_to_add_to_town[i][0]][univ.scenario.flag_to_add_to_town[i][1]]; // Now update horses & boats for(i = 0; i < 30; i++) if((univ.party.horses[i].exists) && (univ.party.horses[i].which_town == former_town)) @@ -162,20 +161,15 @@ void start_town_mode(short which_town, short entry_dir) { - if((town_number < 0) || (town_number >= scenario.num_towns)) { + if(town_number < 0 || town_number >= univ.scenario.num_towns) { giveError("The scenario tried to put you into a town that doesn't exist.", - "Requested town: " + std::to_string(former_town) + "|Adjusted town: " + std::to_string(town_number) + "|Max town: " + std::to_string(scenario.num_towns)); + "Requested town: " + std::to_string(former_town) + "|Adjusted town: " + std::to_string(town_number) + "|Max town: " + std::to_string(univ.scenario.num_towns)); return; } overall_mode = MODE_TOWN; - - load_town(town_number,univ.town.record); - univ.town.num = town_number; - load_town_talk(town_number); - init_town(); // if(play_town_sound) { if(univ.town->lighting_type > 0) @@ -199,7 +193,7 @@ void start_town_mode(short which_town, short entry_dir) { current_ground = 0; else if(univ.town->terrain(i,j) == 2) current_ground = 2; - if(scenario.ter_types[univ.town->terrain(i,j)].special == eTerSpec::CONVEYOR) + if(univ.scenario.ter_types[univ.town->terrain(i,j)].special == eTerSpec::CONVEYOR) univ.town.belt_present = true; } @@ -295,7 +289,8 @@ void start_town_mode(short which_town, short entry_dir) { } else { // First set up the values. - univ.town.monst[i] = univ.town->creatures(i); + cCreature& preset = univ.town->creatures(i); + univ.town.monst.assign(i, preset, univ.scenario.scen_monsters[preset.number], PSD[SDF_EASY_MODE], univ.difficulty_adjust()); univ.town.monst[i].target = 6; univ.town.monst[i].active = 1; // TODO: Can those two \/ be commented out? //univ.town.monst[i].attitude = univ.town->creatures(i).start_attitude; @@ -423,7 +418,7 @@ void start_town_mode(short which_town, short entry_dir) { univ.town.items[i] = cItemRec(); for(j = 0; j < 3; j++) - if(scenario.store_item_towns[j] == town_number) { + if(univ.scenario.store_item_towns[j] == town_number) { for(i = 0; i < NUM_TOWN_ITEMS; i++) univ.town.items[i] = univ.party.stored_items[j][i]; } @@ -534,15 +529,15 @@ void start_town_mode(short which_town, short entry_dir) { //// check horses for(i = 0; i < 30; i++) { - if((scenario.boats[i].which_town >= 0) && (scenario.boats[i].loc.x >= 0)) { + if(univ.scenario.boats[i].which_town >= 0 && univ.scenario.boats[i].loc.x >= 0) { if(!univ.party.boats[i].exists) { - univ.party.boats[i] = scenario.boats[i]; + univ.party.boats[i] = univ.scenario.boats[i]; univ.party.boats[i].exists = true; } } - if((scenario.horses[i].which_town >= 0) && (scenario.horses[i].loc.x >= 0)) { + if(univ.scenario.horses[i].which_town >= 0 && univ.scenario.horses[i].loc.x >= 0) { if(!univ.party.horses[i].exists) { - univ.party.horses[i] = scenario.horses[i]; + univ.party.horses[i] = univ.scenario.horses[i]; univ.party.horses[i].exists = true; } } @@ -584,13 +579,13 @@ location end_town_mode(short switching_level,location destination) { // returns // Store items, if necessary for(j = 0; j < 3; j++) - if(scenario.store_item_towns[j] == univ.town.num) { + if(univ.scenario.store_item_towns[j] == univ.town.num) { for(i = 0; i < NUM_TOWN_ITEMS; i++) if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].is_special == 0 && - ((univ.town.items[i].item_loc.x >= scenario.store_item_rects[j].left) && - (univ.town.items[i].item_loc.x <= scenario.store_item_rects[j].right) && - (univ.town.items[i].item_loc.y >= scenario.store_item_rects[j].top) && - (univ.town.items[i].item_loc.y <= scenario.store_item_rects[j].bottom)) ) { + univ.town.items[i].item_loc.x >= univ.scenario.store_item_rects[j].left && + univ.town.items[i].item_loc.x <= univ.scenario.store_item_rects[j].right && + univ.town.items[i].item_loc.y >= univ.scenario.store_item_rects[j].top && + univ.town.items[i].item_loc.y <= univ.scenario.store_item_rects[j].bottom) { univ.party.stored_items[j][i] = univ.town.items[i]; } else univ.party.stored_items[j][i].variety = eItemType::NO_ITEM; @@ -906,7 +901,7 @@ void create_out_combat_terrain(short type,short num_walls,short /*spec_code*/) { // if(ter_type > 260) // ter_type = 1; // else ter_type = general_types[ter_type]; - ter_type = scenario.ter_types[type].combat_arena; + ter_type = univ.scenario.ter_types[type].combat_arena; if(ter_type >= 1000) ter_type = 1; // TODO: load town ter_type - 1000 as the combat arena // TODO: Also implement the roads and crops arenas @@ -1122,11 +1117,11 @@ void pick_lock(location where,short pc_num) { if(pc_has_abil_equip(pc_num,eItemAbil::THIEVING) < 24) r1 = r1 - 12; - if(scenario.ter_types[terrain].special != eTerSpec::UNLOCKABLE) { + if(univ.scenario.ter_types[terrain].special != eTerSpec::UNLOCKABLE) { add_string_to_buf(" Wrong terrain type. "); return; } - unlock_adjust = scenario.ter_types[terrain].flag2.u; + unlock_adjust = univ.scenario.ter_types[terrain].flag2.u; if((unlock_adjust >= 5) || (r1 > (unlock_adjust * 15 + 30))) { add_string_to_buf(" Didn't work. "); if(will_break) { @@ -1138,7 +1133,7 @@ void pick_lock(location where,short pc_num) { else { add_string_to_buf(" Door unlocked. "); play_sound(9); - univ.town->terrain(where.x,where.y) = scenario.ter_types[terrain].flag1.u; + univ.town->terrain(where.x,where.y) = univ.scenario.ter_types[terrain].flag1.u; } } @@ -1149,20 +1144,20 @@ void bash_door(location where,short pc_num) { terrain = univ.town->terrain(where.x,where.y); r1 = get_ran(1,1,100) - 15 * stat_adj(pc_num,eSkill::STRENGTH) + univ.town.difficulty * 4; - if(scenario.ter_types[terrain].special != eTerSpec::UNLOCKABLE) { + if(univ.scenario.ter_types[terrain].special != eTerSpec::UNLOCKABLE) { add_string_to_buf(" Wrong terrain type. "); return; } - unlock_adjust = scenario.ter_types[terrain].flag2.u; - if((unlock_adjust >= 5) || (r1 > (unlock_adjust * 15 + 40)) || (scenario.ter_types[terrain].flag3.u != 1)) { + unlock_adjust = univ.scenario.ter_types[terrain].flag2.u; + if(unlock_adjust >= 5 || r1 > (unlock_adjust * 15 + 40) || univ.scenario.ter_types[terrain].flag3.u != 1) { add_string_to_buf(" Didn't work. "); damage_pc(pc_num,get_ran(1,1,4),DAMAGE_UNBLOCKABLE,eRace::UNKNOWN,0); } else { add_string_to_buf(" Lock breaks. "); play_sound(9); - univ.town->terrain(where.x,where.y) = scenario.ter_types[terrain].flag1.u; + univ.town->terrain(where.x,where.y) = univ.scenario.ter_types[terrain].flag1.u; } } @@ -1218,35 +1213,36 @@ void erase_out_specials() { for(short i = 0; i < 2; i++) for(short j = 0; j < 2; j++) if(quadrant_legal(i,j)) { + cOutdoors& sector = *univ.scenario.outdoors[univ.party.outdoor_corner.x + i][univ.party.outdoor_corner.y + j]; for(short k = 0; k < 18; k++) { - if(i < 8 && univ.out.outdoors[i][j].exit_dests[k] >= 0 && - (univ.out.outdoors[i][j].exit_locs[k].x == minmax(0,47,univ.out.outdoors[i][j].exit_locs[k].x)) && - (univ.out.outdoors[i][j].exit_locs[k].y == minmax(0,47,univ.out.outdoors[i][j].exit_locs[k].y))) { - if(univ.party.can_find_town[univ.out.outdoors[i][j].exit_dests[k]] == 0) { - univ.out[48 * i + univ.out.outdoors[i][j].exit_locs[k].x][48 * j + univ.out.outdoors[i][j].exit_locs[k].y] = - scenario.ter_types[univ.out.outdoors[i][j].terrain[univ.out.outdoors[i][j].exit_locs[k].x][univ.out.outdoors[i][j].exit_locs[k].y]].flag1.u; + if(i < 8 && sector.exit_dests[k] >= 0 && + (sector.exit_locs[k].x == minmax(0,47,sector.exit_locs[k].x)) && + (sector.exit_locs[k].y == minmax(0,47,sector.exit_locs[k].y))) { + if(univ.party.can_find_town[sector.exit_dests[k]] == 0) { + univ.out[48 * i + sector.exit_locs[k].x][48 * j + sector.exit_locs[k].y] = + univ.scenario.ter_types[sector.terrain[sector.exit_locs[k].x][sector.exit_locs[k].y]].flag1.u; } - else if(univ.party.can_find_town[univ.out.outdoors[i][j].exit_dests[k]] > 0) { - univ.out[48 * i + univ.out.outdoors[i][j].exit_locs[k].x][48 * j + univ.out.outdoors[i][j].exit_locs[k].y] = - univ.out.outdoors[i][j].terrain[univ.out.outdoors[i][j].exit_locs[k].x][univ.out.outdoors[i][j].exit_locs[k].y]; + else if(univ.party.can_find_town[sector.exit_dests[k]] > 0) { + univ.out[48 * i + sector.exit_locs[k].x][48 * j + sector.exit_locs[k].y] = + sector.terrain[sector.exit_locs[k].x][sector.exit_locs[k].y]; } } - if(univ.out.outdoors[i][j].special_id[k] < 0) continue; // TODO: Is this needed? Seems to be important, so why was it commented out? - out_num = scenario.out_width * (univ.party.outdoor_corner.y + j) + univ.party.outdoor_corner.x + i; + if(sector.special_id[k] < 0) continue; // TODO: Is this needed? Seems to be important, so why was it commented out? + out_num = univ.scenario.out_width * (univ.party.outdoor_corner.y + j) + univ.party.outdoor_corner.x + i; - sn = univ.out.outdoors[i][j].specials[univ.out.outdoors[i][j].special_id[k]]; + sn = sector.specials[sector.special_id[k]]; sd1 = sn.sd1; sd2 = sn.sd2; if((sd_legit(sd1,sd2)) && (PSD[sd1][sd2] == 250)) { - where = univ.out.outdoors[i][j].special_locs[k]; + where = sector.special_locs[k]; if((where.x > 48) || (where.y > 48) || (where.x < 0) || (where.y < 0)) { beep(); add_string_to_buf("Outdoor section corrupt. Problem fixed."); - univ.out.outdoors[i][j].special_id[k] = -1; // TODO: Again, was there a reason for commenting this out? + sector.special_id[k] = -1; // TODO: Again, was there a reason for commenting this out? } - univ.out.outdoors[i][j].special_spot[where.x][where.y] = false; + sector.special_spot[where.x][where.y] = false; } } } @@ -1294,7 +1290,7 @@ void draw_map(bool need_refresh) { short total_size = 48; // if full redraw, use this to figure out everything rectangle area_to_put_on_map_rect; rectangle custom_from; - short town_type = scenario.town_size[univ.town.num]; + short town_type = univ.scenario.town_size[univ.town.num]; draw_surroundings = true; @@ -1408,10 +1404,10 @@ void draw_map(bool need_refresh) { else expl = is_explored(where.x,where.y); if(expl != 0) { - pic = scenario.ter_types[what_ter].map_pic; + pic = univ.scenario.ter_types[what_ter].map_pic; bool drawLargeIcon = false; if(pic == NO_PIC) { - pic = scenario.ter_types[what_ter].picture; + pic = univ.scenario.ter_types[what_ter].picture; drawLargeIcon = true; } if(pic >= 1000) { @@ -1443,11 +1439,11 @@ void draw_map(bool need_refresh) { } } else switch(pic >= 960 ? anim_map_pats[pic - 960] : map_pats[pic]) { case 0: case 10: case 11: - if(scenario.ter_types[what_ter].picture < 960) - ter_temp_from.offset(12 * (scenario.ter_types[what_ter].picture % 20), - 12 * (scenario.ter_types[what_ter].picture / 20)); + if(univ.scenario.ter_types[what_ter].picture < 960) + ter_temp_from.offset(12 * (univ.scenario.ter_types[what_ter].picture % 20), + 12 * (univ.scenario.ter_types[what_ter].picture / 20)); else ter_temp_from.offset(12 * 20, - 12 * (scenario.ter_types[what_ter].picture - 960)); + 12 * (univ.scenario.ter_types[what_ter].picture - 960)); rect_draw_some_item(small_ter_gworld,ter_temp_from,map_gworld,draw_rect); break; @@ -1545,8 +1541,8 @@ void draw_map(bool need_refresh) { bool is_door(location destination) { - if(scenario.ter_types[univ.town->terrain(destination.x,destination.y)].special == eTerSpec::UNLOCKABLE || - scenario.ter_types[univ.town->terrain(destination.x,destination.y)].special == eTerSpec::CHANGE_WHEN_STEP_ON) + if(univ.scenario.ter_types[univ.town->terrain(destination.x,destination.y)].special == eTerSpec::UNLOCKABLE || + univ.scenario.ter_types[univ.town->terrain(destination.x,destination.y)].special == eTerSpec::CHANGE_WHEN_STEP_ON) return true; return false; } @@ -1568,9 +1564,9 @@ void check_done() { } bool quadrant_legal(short i, short j) { - if(univ.party.outdoor_corner.x + i >= scenario.out_width) + if(univ.party.outdoor_corner.x + i >= univ.scenario.out_width) return false; - if(univ.party.outdoor_corner.y + j >= scenario.out_height) + if(univ.party.outdoor_corner.y + j >= univ.scenario.out_height) return false; if(univ.party.outdoor_corner.x + i < 0) return false; diff --git a/osx/boe.townspec.cpp b/osx/boe.townspec.cpp index 90d7a493..4af34576 100644 --- a/osx/boe.townspec.cpp +++ b/osx/boe.townspec.cpp @@ -30,7 +30,6 @@ extern location center; //extern town_item_list t_i; //extern big_tr_type t_d; extern sf::RenderWindow mainPtr; -extern cScenario scenario; extern cUniverse univ; char answer[256]; @@ -223,6 +222,6 @@ short handle_lever(location w) { } void switch_lever(location w) { - alter_space(w.x,w.y,scenario.ter_types[univ.town->terrain(w.x,w.y)].trans_to_what); + alter_space(w.x,w.y,univ.scenario.ter_types[univ.town->terrain(w.x,w.y)].trans_to_what); } diff --git a/osx/classes.h b/osx/classes.h index 317811af..17628ff9 100644 --- a/osx/classes.h +++ b/osx/classes.h @@ -27,9 +27,3 @@ #include "creatlist.h" #include "party.h" #include "universe.h" - -extern cScenario scenario; -template type cOutdoors::cWandering::get(m_num_t who,bool hostile,type cMonster::* what){ - if(hostile) return scenario.scen_monsters[monst[who]].*what; - return scenario.scen_monsters[friendly[who]].*what; -} diff --git a/osx/classes/creatlist.cpp b/osx/classes/creatlist.cpp index 551f9d08..0f5a94bc 100644 --- a/osx/classes/creatlist.cpp +++ b/osx/classes/creatlist.cpp @@ -14,14 +14,46 @@ #include "classes.h" #include "oldstructs.h" -cPopulation& cPopulation::operator = (legacy::creature_list_type old){ +void cPopulation::append(legacy::creature_list_type old){ for(int i = 0; i < 60; i++) - dudes[i] = old.dudes[i]; + dudes[i].append(old.dudes[i]); which_town = old.which_town; friendly = old.friendly; - return *this; +} + +const cCreature& cPopulation::operator[](size_t n) const { + return dudes[n]; } cCreature& cPopulation::operator[](size_t n){ return dudes[n]; } + +// This function takes a preset cCreature from a scenario town record and prepares it for use in-game. +// It's needed because in the town record, many fields are ignored, including all the superclass fields. +// replaces return_monster_template() from boe.monsters.cpp +void cPopulation::assign(size_t n, const cCreature& other, const cMonster& base, bool easy, int difficulty_adjust){ + // First do a basic assign + dudes[n] = other; + // And make sure the superclass fields are correctly populated + static_cast(dudes[n]) = base; + // Now set up extra stuff + dudes[n].active = 1; // TODO: Is this right? + if(dudes[n].spec_skill == 11) dudes[n].picture_num = 0; + dudes[n].m_health /= easy ? 2 : 1; + dudes[n].m_health *= difficulty_adjust; + dudes[n].health = dudes[n].m_health; + dudes[n].ap = 0; + if(dudes[n].mu > 0 || dudes[n].cl > 0) + dudes[n].max_mp = dudes[n].mp = 12 * dudes[n].level; + else dudes[n].max_mp = dudes[n].mp = 0; + dudes[n].m_morale = 10 * dudes[n].level; + if(dudes[n].level >= 20) + dudes[n].m_morale += 10 * (dudes[n].level - 20); + dudes[n].morale = dudes[n].m_morale; + dudes[n].direction = 0; + dudes[n].status.clear(); + dudes[n].attitude = dudes[n].start_attitude; // TODO: Is this right? + dudes[n].cur_loc = dudes[n].start_loc; + dudes[n].target = 6; // No target +} diff --git a/osx/classes/creatlist.h b/osx/classes/creatlist.h index f5fce089..8ebe52b5 100644 --- a/osx/classes/creatlist.h +++ b/osx/classes/creatlist.h @@ -34,8 +34,11 @@ public: short which_town; short friendly; - cPopulation& operator= (legacy::creature_list_type old); + void append(legacy::creature_list_type old); + void assign(size_t n, const cCreature& other, const cMonster& base, bool easy, int difficulty_adjust); cCreature& operator[](size_t n); + const cCreature& operator[](size_t n) const; + cPopulation() : which_town(200) {} }; #endif \ No newline at end of file diff --git a/osx/classes/item.cpp b/osx/classes/item.cpp index 438e6830..b65090b2 100644 --- a/osx/classes/item.cpp +++ b/osx/classes/item.cpp @@ -294,7 +294,7 @@ cItemRec::cItemRec(long preset){ } } -cItemRec& cItemRec::operator = (legacy::item_record_type& old){ +void cItemRec::append(legacy::item_record_type& old){ variety = (eItemType) old.variety; item_level = old.item_level; awkward = old.awkward; @@ -334,10 +334,9 @@ cItemRec& cItemRec::operator = (legacy::item_record_type& old){ unsellable = old.item_properties & 16; reserved1 = old.reserved1; reserved2 = old.reserved2; - return *this; } -void cItemRec::writeTo(std::ostream& file, std::string prefix){ +void cItemRec::writeTo(std::ostream& file, std::string prefix) const { file << prefix << "VARIETY " << variety << '\n'; file << prefix << "LEVEL " << item_level << '\n'; file << prefix << "AWKWARD " << awkward << '\n'; @@ -410,15 +409,15 @@ void cItemRec::readFrom(std::istream& sin){ } } -std::ostream& operator << (std::ostream& out, eSkill& e){ +std::ostream& operator << (std::ostream& out, eSkill e){ return out << (int) e; } -std::ostream& operator << (std::ostream& out, eItemType& e){ +std::ostream& operator << (std::ostream& out, eItemType e){ return out << (int) e; } -std::ostream& operator << (std::ostream& out, eItemAbil& e){ +std::ostream& operator << (std::ostream& out, eItemAbil e){ return out << (int) e; } diff --git a/osx/classes/item.h b/osx/classes/item.h index 118962b6..ff515956 100644 --- a/osx/classes/item.h +++ b/osx/classes/item.h @@ -72,16 +72,16 @@ public: cItemRec(); cItemRec(long preset); - cItemRec& operator = (legacy::item_record_type& old); - void writeTo(std::ostream& file, std::string prefix = ""); + void append(legacy::item_record_type& old); + void writeTo(std::ostream& file, std::string prefix = "") const; void readFrom(std::istream& sin); }; -std::ostream& operator << (std::ostream& out, eItemType& e); -std::ostream& operator << (std::ostream& out, eItemAbil& e); +std::ostream& operator << (std::ostream& out, eItemType e); +std::ostream& operator << (std::ostream& out, eItemAbil e); std::istream& operator >> (std::istream& in, eItemType& e); std::istream& operator >> (std::istream& in, eItemAbil& e); -std::ostream& operator << (std::ostream& out, eSkill& e); +std::ostream& operator << (std::ostream& out, eSkill e); std::istream& operator >> (std::istream& in, eSkill& e); class cSpecItem { diff --git a/osx/classes/monster.cpp b/osx/classes/monster.cpp index c0b83b83..f268ff22 100644 --- a/osx/classes/monster.cpp +++ b/osx/classes/monster.cpp @@ -14,7 +14,7 @@ #include "classes.h" #include "oldstructs.h" -cMonster& cMonster::operator = (legacy::monster_record_type& old){ +void cMonster::append(legacy::monster_record_type& old){ level = old.level; //m_name = old.m_name; m_health = old.m_health; @@ -48,11 +48,12 @@ cMonster& cMonster::operator = (legacy::monster_record_type& old){ picture_num = old.picture_num; if(picture_num == 122) picture_num = 119; see_spec = -1; - return *this; } cMonster::cMonster(){ // TODO: Fill in + see_str1 = -1; + see_str2 = -1; see_spec = -1; } @@ -73,7 +74,7 @@ cCreature::cCreature(int num) : cCreature() { number = num; } -cCreature& cCreature::operator = (legacy::creature_start_type old){ +void cCreature::append(legacy::creature_start_type old){ number = old.number; start_attitude = old.start_attitude; start_loc.x = old.start_loc.x; @@ -90,16 +91,15 @@ cCreature& cCreature::operator = (legacy::creature_start_type old){ personality = old.personality; special_on_kill = old.special_on_kill; facial_pic = old.facial_pic; - return *this; } -cCreature& cCreature::operator = (legacy::creature_data_type old){ +void cCreature::append(legacy::creature_data_type old){ active = old.active; attitude = old.attitude; number = old.number; cur_loc.x = old.m_loc.x; cur_loc.y = old.m_loc.y; - *this = old.m_d; + cMonster::append(old.m_d); mobility = old.mobile; summoned = old.summoned; number = old.monst_start.number; @@ -127,7 +127,6 @@ cCreature& cCreature::operator = (legacy::creature_data_type old){ for(int i = 0; i < 15; i++) status[(eStatus) i] = old.m_d.status[i]; direction = old.m_d.direction; - return *this; } cMonster::cAttack::operator int() const { @@ -145,7 +144,7 @@ std::ostream& operator<<(std::ostream& out, const cMonster::cAttack& att) { return out; } -std::ostream& operator << (std::ostream& out, eStatus& e){ +std::ostream& operator << (std::ostream& out, eStatus e){ return out << (int) e; } @@ -159,7 +158,7 @@ std::istream& operator >> (std::istream& in, eStatus& e){ return in; } -std::ostream& operator << (std::ostream& out, eRace& e){ +std::ostream& operator << (std::ostream& out, eRace e){ return out << (int) e; } @@ -172,47 +171,6 @@ std::istream& operator >> (std::istream& in, eRace& e){ return in; } -extern cUniverse univ; -extern cScenario scenario; -// TODO: Any setup where "x = x" does something is probably a bad idea... -cCreature& cCreature::operator = (const cCreature& other){ // replaces return_monster_template() from boe.monsters.cpp - id = other.id; - number = other.number; - start_attitude = other.start_attitude; - start_loc = other.start_loc; - mobility = other.mobility; - time_flag = other.time_flag; - extra1 = other.extra1; - extra2 = other.extra2; - spec1 = other.spec1; - spec2 = other.spec2; - spec_enc_code = other.spec_enc_code; - time_code = other.time_code; - monster_time = other.monster_time; - personality = other.personality; - special_on_kill = other.special_on_kill; - facial_pic = other.facial_pic; - *this = scenario.scen_monsters[number]; - active = 1; // TODO: Is this right? - if(spec_skill == 11) picture_num = 0; - m_health /= (univ.party.stuff_done[306][7]) ? 2 : 1; - m_health *= univ.difficulty_adjust(); - health = m_health; - ap = 0; - if((mu > 0 || cl > 0)) - max_mp = mp = 12 * level; - else max_mp = mp = 0; - m_morale = 10 * level; - if(level >= 20) m_morale += 10 * (level - 20); - morale = m_morale; - direction = 0; - status.clear(); - attitude = start_attitude; // TODO: Is this right? - cur_loc = start_loc; - target = 6; // No target - return *this; -} - cMonster::cAbility::operator std::string(){ std::ostringstream sout; short i = 0; @@ -360,7 +318,8 @@ cMonster::cAbility::operator std::string(){ sout << "Steals gold when hits"; break; case MONST_SUMMON_ONE: - sout << "Summons " << scenario.scen_monsters[extra1].m_name << "s (" << extra2 <<"% chance)"; + // TODO: Store the name of the summoned monster in the class so it can be used here. +// sout << "Summons " << univ.scenario.scen_monsters[extra1].m_name << "s (" << extra2 <<"% chance)"; break; case MONST_SUMMON_TYPE: sout << "Summons "; @@ -499,7 +458,7 @@ bool cMonster::hasAbil(eMonstAbil what, unsigned char* x1, unsigned char* x2){ return false; } -void cMonster::writeTo(std::ostream& /*file*/) { +void cMonster::writeTo(std::ostream& /*file*/) const { // TODO: Implement this (low priority since only used for exported summons) } @@ -507,7 +466,7 @@ void cMonster::readFrom(std::istream& /*file*/) { // TODO: Implement this (low priority since only used for exported summons) } -void cCreature::writeTo(std::ostream& file) { +void cCreature::writeTo(std::ostream& file) const { file << "MONSTER " << number << '\n'; file << "ATTITUDE " << attitude << '\n'; file << "STARTATT " << unsigned(start_attitude) << '\n'; @@ -529,8 +488,8 @@ void cCreature::writeTo(std::ostream& file) { file << "TARGLOC " << targ_loc.x << ' ' << targ_loc.y << '\n'; for(int i = 0; i < 15; i++) { eStatus stat = (eStatus) i; - if(status[stat] != 0) - file << "STATUS " << i << ' ' << status[stat] << '\n'; + if(status.at(stat) != 0) + file << "STATUS " << i << ' ' << status.at(stat) << '\n'; } file << "CURHP " << health << '\n'; file << "CURSP " << mp << '\n'; @@ -545,10 +504,9 @@ void cCreature::readFrom(std::istream& file) { printf("Parsing line in town.txt: %s\n", cur.c_str()); std::istringstream line(cur); line >> cur; - if(cur == "MONSTER") { + if(cur == "MONSTER") line >> number; - *this = cCreature(number); - } else if(cur == "ATTITUDE") + else if(cur == "ATTITUDE") line >> attitude; else if(cur == "STARTATT") { unsigned int i; diff --git a/osx/classes/monster.h b/osx/classes/monster.h index 3786ad48..204a6686 100644 --- a/osx/classes/monster.h +++ b/osx/classes/monster.h @@ -23,6 +23,9 @@ namespace legacy { struct creature_start_type; }; +class cScenario; +class cUniverse; + /* Attack Types */ #define MONSTER_ATTACK_SWINGS 0 @@ -140,9 +143,9 @@ public: std::string getAbil1Name(); std::string getAbil2Name(); bool hasAbil(eMonstAbil what, unsigned char* x1 = NULL, unsigned char* x2 = NULL); - cMonster& operator = (legacy::monster_record_type& old); + void append(legacy::monster_record_type& old); cMonster(); - void writeTo(std::ostream& file); + void writeTo(std::ostream& file) const; void readFrom(std::istream& file); }; @@ -175,19 +178,17 @@ public: cCreature(); cCreature(int num); - cCreature& operator = (legacy::creature_data_type old); - cCreature& operator = (legacy::creature_start_type old); - cCreature& operator = (const cCreature& other); - //cCreature& operator = (const cMonster& other); - void writeTo(std::ostream& file); + void append(legacy::creature_data_type old); + void append(legacy::creature_start_type old); + void writeTo(std::ostream& file) const; void readFrom(std::istream& file); }; -std::ostream& operator << (std::ostream& out, eStatus& e); +std::ostream& operator << (std::ostream& out, eStatus e); std::istream& operator >> (std::istream& in, eStatus& e); -std::ostream& operator << (std::ostream& out, eRace& e); +std::ostream& operator << (std::ostream& out, eRace e); std::istream& operator >> (std::istream& in, eRace& e); -std::ostream& operator << (std::ostream& out, eMonstAbil& e); +std::ostream& operator << (std::ostream& out, eMonstAbil e); std::istream& operator >> (std::istream& in, eMonstAbil& e); std::ostream& operator<<(std::ostream& out, const cMonster::cAttack& att); #endif \ No newline at end of file diff --git a/osx/classes/outdoors.cpp b/osx/classes/outdoors.cpp index e98857f9..f9d69e5c 100644 --- a/osx/classes/outdoors.cpp +++ b/osx/classes/outdoors.cpp @@ -15,9 +15,7 @@ #include "classes.h" #include "oldstructs.h" -extern cScenario scenario; - -cOutdoors& cOutdoors::operator = (legacy::outdoor_record_type& old){ +void cOutdoors::append(legacy::outdoor_record_type& old, const cScenario& scenario){ int i,j; // 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; @@ -130,23 +128,25 @@ cOutdoors& cOutdoors::operator = (legacy::outdoor_record_type& old){ // special_enc[i].end_spec1 = old.special_enc[i].end_spec1; // wandering[i].end_spec2 = old.wandering[i].end_spec2; // special_enc[i].end_spec2 = old.special_enc[i].end_spec2; - wandering[i] = old.wandering[i]; - special_enc[i] = old.special_enc[i]; + wandering[i].append(old.wandering[i]); + special_enc[i].append(old.special_enc[i]); wandering_locs[i].x = old.wandering_locs[i].x; wandering_locs[i].y = old.wandering_locs[i].y; } for(i = 0; i < 180; i++) strlens[i] = old.strlens[i]; for(i = 0; i < 60; i++) - specials[i] = old.specials[i]; - return *this; + specials[i].append(old.specials[i]); } -cOutdoors::cOutdoors(){ +cOutdoors::cWandering::cWandering() { + spec_on_meet = spec_on_win = spec_on_flee = -1; + end_spec1 = end_spec2 = -1; +} + +cOutdoors::cOutdoors(cScenario& scenario, bool init_strings) : scenario(scenario) { short i,j; - location d_loc(100,0); - cOutdoors::cWandering d_monst = {{0,0,0,0,0,0,0},{0,0,0},-1,-1,-1,0,-1,-1}; - rectangle d_rect; + location d_loc(100,0);; location locs[4] = {loc(8,8),loc(32,8),loc(8,32),loc(32,32)}; for(i = 0; i < 48; i++) @@ -156,27 +156,31 @@ cOutdoors::cOutdoors(){ for(i = 0; i < 18; i++) { special_locs[i] = d_loc; - special_id[i] = 0; } for(i = 0; i < 8; i++) { exit_locs[i] = d_loc; - exit_dests[i] = 0; sign_locs[i] = d_loc; sign_locs[i].x = 100; - info_rect[i] = d_rect; } for(i = 0; i < 4; i++) { - wandering[i] = d_monst; wandering_locs[i] = locs[i]; - special_enc[i] = d_monst; } - for(i = 0; i < 60; i++) { - specials[i] = cSpecial(); + if(!init_strings) return; + std::string temp_str; + for(i = 0; i < 120; i++) { + temp_str = get_str("outdoor-default",i + 1); + if(i == 0) out_name = temp_str; + else if(i == 9) comment = temp_str; + else if(i < 9) rect_names[i-1] = temp_str; + else if(i >= 10 && i < 100) + spec_strs[i-10] = temp_str; + else if(i >= 100 && i < 108) + sign_strs[i-100] = temp_str; + strlens[i] = temp_str.length(); } - } -cOutdoors::cWandering& cOutdoors::cWandering::operator = (legacy::out_wandering_type old){ +void cOutdoors::cWandering::append(legacy::out_wandering_type old){ for(int i = 0; i < 7; i++) monst[i] = old.monst[i]; for(int j = 0; j < 3; j++) @@ -187,21 +191,19 @@ cOutdoors::cWandering& cOutdoors::cWandering::operator = (legacy::out_wandering_ cant_flee = old.cant_flee; end_spec1 = old.end_spec1; end_spec2 = old.end_spec2; - return *this; } -cOutdoors::cCreature& cOutdoors::cCreature::operator = (legacy::outdoor_creature_type old){ +void cOutdoors::cCreature::append(legacy::outdoor_creature_type old){ exists = old.exists; direction = old.direction; - what_monst = old.what_monst; + what_monst.append(old.what_monst); which_sector.x = old.which_sector.x; which_sector.y = old.which_sector.y; m_loc.x = old.m_loc.x; m_loc.y = old.m_loc.y; - return *this; } -void cOutdoors::cWandering::writeTo(std::ostream& file, std::string prefix){ +void cOutdoors::cWandering::writeTo(std::ostream& file, std::string prefix) const { for(int i = 0; i < 7; i++) file << prefix << "HOSTILE " << i << ' ' << monst[i] << '\n'; for(int i = 0; i < 3; i++) diff --git a/osx/classes/outdoors.h b/osx/classes/outdoors.h index 69d5eba2..e11a6027 100644 --- a/osx/classes/outdoors.h +++ b/osx/classes/outdoors.h @@ -24,7 +24,10 @@ namespace legacy { struct outdoor_creature_type; }; +class cScenario; + class cOutdoors { + cScenario& scenario; public: class cWandering { // formerly out_wandering_type public: @@ -34,10 +37,10 @@ public: short end_spec1,end_spec2; bool isNull(); - cWandering& operator = (legacy::out_wandering_type old); - void writeTo(std::ostream& file, std::string prefix = ""); + void append(legacy::out_wandering_type old); + void writeTo(std::ostream& file, std::string prefix = "") const; void readFrom(std::istream& sin); - template type get(m_num_t who,bool hostile,type cMonster::* what); + cWandering(); }; class cCreature { // formerly outdoor_creature_type public: @@ -46,7 +49,7 @@ public: cWandering what_monst; location which_sector,m_loc,home_sector; // home_sector is the sector it was spawned in - cCreature& operator = (legacy::outdoor_creature_type old); + void append(legacy::outdoor_creature_type old); }; short x,y; // Used while loading legacy scenarios. ter_num_t terrain[48][48]; @@ -70,8 +73,8 @@ public: std::array sign_strs; bool special_spot[48][48]; - cOutdoors(); - cOutdoors& operator = (legacy::outdoor_record_type& old); + explicit cOutdoors(cScenario& scenario, bool init_strings = false); + void append(legacy::outdoor_record_type& old, const cScenario& scenario); }; #endif \ No newline at end of file diff --git a/osx/classes/party.cpp b/osx/classes/party.cpp index 7d76757e..b16a44d7 100644 --- a/osx/classes/party.cpp +++ b/osx/classes/party.cpp @@ -17,7 +17,32 @@ #include "oldstructs.h" #include "fileio.h" -cParty& cParty::operator = (legacy::party_record_type& old){ +cParty::cParty(cUniverse& univ, long party_preset) : univ(univ) { + gold = 200; + food = 100; + // Note: These starting position values were in the original code and so are included here. + // However, I suspect they're relics of Exile III that are soon overwritten. + outdoor_corner.x = 7; + outdoor_corner.y = 8; + i_w_c.x = 1; + i_w_c.y = 1; + loc_in_sec.x = 36; + loc_in_sec.y = 36; + p_loc.x = 84; + p_loc.y = 84; + in_boat = -1; + in_horse = -1; + for(int i = 0; i < 5; i++) + for(int j = 0; j < 10; j++) + magic_store_items[i][j].variety = eItemType::NO_ITEM; + // Original code set all key times 30000. I felt this was more appropriate. + std::fill(key_times, key_times + 20, std::numeric_limits::max()); + + for(int i = 0; i < 6; i++) + adven[i] = cPlayer(party_preset, i); +} + +void cParty::append(legacy::party_record_type& old){ int i,j; age = old.age; gold = old.gold; @@ -39,8 +64,8 @@ cParty& cParty::operator = (legacy::party_record_type& old){ loc_in_sec.y = old.loc_in_sec.y; party_event_timers.reserve(30); for(i = 0; i < 30; i++){ - boats[i] = old.boats[i]; - horses[i] = old.horses[i]; + boats[i].append(old.boats[i]); + horses[i].append(old.horses[i]); cTimer t; t.time = old.party_event_timers[i]; t.global_or_town = old.global_or_town[i]; @@ -51,15 +76,15 @@ cParty& cParty::operator = (legacy::party_record_type& old){ // party_event_timers[i].node_to_call = old.node_to_call[i]; } for(i = 0; i < 4; i++){ - creature_save[i] = old.creature_save[i]; + creature_save[i].append(old.creature_save[i]); imprisoned_monst[i] = old.imprisoned_monst[i]; } in_boat = old.in_boat; in_horse = old.in_horse; for(i = 0; i < 10; i++){ - out_c[i] = old.out_c[i]; + out_c[i].append(old.out_c[i]); for(j = 0; j < 5; j++) - magic_store_items[j][i] = old.magic_store_items[j][i]; + magic_store_items[j][i].append(old.magic_store_items[j][i]); } for(i = 0; i < 256; i++) m_noted[i] = old.m_seen[i]; @@ -106,12 +131,11 @@ cParty& cParty::operator = (legacy::party_record_type& old){ total_xp_gained = old.total_xp_gained; total_dam_taken = old.total_dam_taken; scen_name = old.scen_name; - return *this; } void cParty::append(legacy::stored_items_list_type& old,short which_list){ for(int i = 0; i < 115; i++) - stored_items[which_list][i] = old.items[i]; + stored_items[which_list][i].append(old.items[i]); } void cParty::append(legacy::setup_save_type& old){ @@ -133,7 +157,7 @@ cParty::cConvers& cParty::cConvers::operator = (legacy::talk_save_type old){ void cParty::add_pc(legacy::pc_record_type old){ for(int i = 0; i < 6; i++) if(adven[i].main_status == eMainStatus::ABSENT){ - adven[i] = old; + adven[i].append(old); break; } } @@ -203,7 +227,7 @@ bool cParty::start_timer(short time, short node, short type){ return(true); } -void cParty::writeTo(std::ostream& file){ +void cParty::writeTo(std::ostream& file) const { file << "CREATEVERSION" << OBOE_CURRENT_VERSION << '\n'; file << "AGE " << age << '\n'; file << "GOLD " << gold << '\n'; @@ -337,28 +361,28 @@ void cParty::writeTo(std::ostream& file){ if(summons.size() > 0) { file << '\f'; file << "SUMMON" << '\n'; - for(cMonster& monst : summons) { + for(const cMonster& monst : summons) { monst.writeTo(file); file << '\f'; } } if(journal.size() > 0) { file << '\f'; - for(cJournal& entry : journal) { + for(const cJournal& entry : journal) { file << "JOURNAL " << entry.day << ' ' << maybe_quote_string(entry.in_scen) << '\n' << entry.the_str << '\n'; file << '\f'; } } if(special_notes.size() > 0) { file << '\f'; - for(cEncNote& note : special_notes) { + for(const cEncNote& note : special_notes) { file << "ENCNOTE " << note.type << ' ' << maybe_quote_string(note.where) << '\n' << note.the_str << '\n'; file << '\f'; } } if(talk_save.size() > 0) { file << '\f'; - for(cConvers& note : talk_save) { + for(const cConvers& note : talk_save) { file << "TALKNOTE"; file << "WHO " << maybe_quote_string(note.who_said) << '\n'; file << "WHERE " << maybe_quote_string(note.in_town) << ' ' << maybe_quote_string(note.in_scen) << '\n'; @@ -586,6 +610,13 @@ cPlayer& cParty::operator[](unsigned short n){ return adven[n]; } +const cPlayer& cParty::operator[](unsigned short n) const{ + if(n > 6) throw std::out_of_range("Attempt to access a player that doesn't exist."); + else if(n == 6) + return adven[0]; // TODO: PC #6 should never be accessed, but bounds checking is rarely done, so this is a quick fix. + return adven[n]; +} + // Note that the pointer functions take the pointer with its negative sign stripped off! void cParty::set_ptr(unsigned short p, unsigned short sdfx, unsigned short sdfy){ // This function is not used for setting the reserved pointers @@ -614,8 +645,8 @@ unsigned char cParty::get_ptr(unsigned short p){ } unsigned char& cParty::cpn_flag(unsigned int x, unsigned int y, std::string id) { - if(id.empty()) id = scenario.campaign_id; - if(id.empty()) id = scenario.scen_name; + if(id.empty()) id = univ.scenario.campaign_id; + if(id.empty()) id = univ.scenario.scen_name; if(x >= 25 || y >= 25) throw std::range_error("Attempted to access a campaign flag out of range (0..25)"); return campaign_flags[id].idx[x][y]; } diff --git a/osx/classes/party.h b/osx/classes/party.h index f348c6f8..21dac590 100644 --- a/osx/classes/party.h +++ b/osx/classes/party.h @@ -34,6 +34,8 @@ struct campaign_flag_type{ unsigned char idx[25][25]; }; +class cUniverse; + class cParty { public: class cConvers { // conversation; formerly talk_save_type @@ -99,6 +101,7 @@ public: long long total_m_killed, total_dam_done, total_xp_gained, total_dam_taken; std::string scen_name; private: + cUniverse& univ; cPlayer adven[6]; public: unsigned short setup[4][64][64]; // formerly setup_save_type @@ -120,7 +123,7 @@ public: unsigned char& cpn_flag(unsigned int x, unsigned int y, std::string id = ""); - cParty& operator = (legacy::party_record_type& old); + void append(legacy::party_record_type& old); void append(legacy::big_tr_type& old); void append(legacy::stored_items_list_type& old,short which_list); void append(legacy::setup_save_type& old); @@ -133,7 +136,8 @@ public: bool record(eEncNoteType type, const std::string& what, const std::string& where); bool start_timer(short time, short node, short type); cPlayer& operator[](unsigned short n); - void writeTo(std::ostream& file); + const cPlayer& operator[](unsigned short n) const; + void writeTo(std::ostream& file) const; void readFrom(std::istream& file); std::string start_split(short a, short b, snd_num_t noise, short who); @@ -148,6 +152,7 @@ public: typedef std::vector::iterator journalIter; typedef std::vector::iterator talkIter; typedef std::vector::iterator timerIter; + cParty(cUniverse& univ, long party_preset = 'dflt'); // TODO: Remove this in favour of cParty constructor friend void init_party(short); }; diff --git a/osx/classes/pc.cpp b/osx/classes/pc.cpp index e8a74f36..9fe053ed 100644 --- a/osx/classes/pc.cpp +++ b/osx/classes/pc.cpp @@ -15,7 +15,7 @@ #include "classes.h" #include "oldstructs.h" -cPlayer& cPlayer::operator = (legacy::pc_record_type old){ +void cPlayer::append(legacy::pc_record_type old){ int i; main_status = (eMainStatus) old.main_status; name = old.name; @@ -38,7 +38,7 @@ cPlayer& cPlayer::operator = (legacy::pc_record_type old){ traits[trait] = old.traits[i]; } for(i = 0; i < 24; i++){ - items[i] = old.items[i]; + items[i].append(old.items[i]); equip[i] = old.equip[i]; } for(i = 0; i < 62; i++){ @@ -50,7 +50,6 @@ cPlayer& cPlayer::operator = (legacy::pc_record_type old){ race = (eRace) old.race; //exp_adj = old.exp_adj; direction = old.direction; - return *this; } short cPlayer::get_tnl(){ @@ -282,15 +281,15 @@ void operator -= (eMainStatus& stat, eMainStatus othr){ stat = (eMainStatus) (-10 + (int)othr); } -void cPlayer::writeTo(std::ostream& file){ +void cPlayer::writeTo(std::ostream& file) const { file << "STATUS -1 " << main_status << '\n'; file << "NAME " << name << '\n'; file << "SKILL 19 " << max_health << '\n'; file << "SKILL 20 " << max_sp << '\n'; for(int i = 0; i < 19; i++) { eSkill skill = eSkill(i); - if(skills[skill] > 0) - file << "SKILL " << i << ' ' << skills[skill] << '\n'; + if(skills.at(skill) > 0) + file << "SKILL " << i << ' ' << skills.at(skill) << '\n'; } file << "HEALTH " << cur_health << '\n'; file << "MANA " << cur_sp << '\n'; @@ -299,8 +298,8 @@ void cPlayer::writeTo(std::ostream& file){ file << "LEVEL " << level << '\n'; for(int i = 0; i < 15; i++) { eStatus stat = (eStatus) i; - if(status[stat] != 0) - file << "STATUS " << i << ' ' << status[stat] << '\n'; + if(status.at(stat) != 0) + file << "STATUS " << i << ' ' << status.at(stat) << '\n'; } for(int i = 0; i < 24; i++) if(equip[i]) @@ -313,7 +312,7 @@ void cPlayer::writeTo(std::ostream& file){ file << "PRIEST " << i << '\n'; for(int i = 0; i < 62; i++) { eTrait trait = eTrait(i); - if(traits[trait]) + if(traits.at(trait)) file << "TRAIT " << i << '\n'; } file << "ICON " << which_graphic << '\n'; @@ -419,7 +418,7 @@ void cPlayer::readFrom(std::istream& file){ } } -std::ostream& operator << (std::ostream& out, eMainStatus& e){ +std::ostream& operator << (std::ostream& out, eMainStatus e){ return out << (int) e; } diff --git a/osx/classes/pc.h b/osx/classes/pc.h index 2aa389a7..bf163c8f 100644 --- a/osx/classes/pc.h +++ b/osx/classes/pc.h @@ -50,17 +50,17 @@ public: location combat_pos; short marked_damage, dir, parry, last_attacked; - cPlayer& operator = (legacy::pc_record_type old); + void append(legacy::pc_record_type old); cPlayer(); cPlayer(long key,short slot); short get_tnl(); - void writeTo(std::ostream& file); + void writeTo(std::ostream& file) const; void readFrom(std::istream& file); }; void operator += (eMainStatus& stat, eMainStatus othr); void operator -= (eMainStatus& stat, eMainStatus othr); -std::ostream& operator << (std::ostream& out, eMainStatus& e); +std::ostream& operator << (std::ostream& out, eMainStatus e); std::istream& operator >> (std::istream& in, eMainStatus& e); #endif \ No newline at end of file diff --git a/osx/classes/regtown.cpp b/osx/classes/regtown.cpp index a9d0780f..abd85e82 100644 --- a/osx/classes/regtown.cpp +++ b/osx/classes/regtown.cpp @@ -16,8 +16,6 @@ #include "oldstructs.h" #include "fileio.h" -extern cScenario scenario; - void cTinyTown::append(legacy::tiny_tr_type& old, int town_num){ int i,j; cField the_field; @@ -78,23 +76,7 @@ void cTinyTown::append(legacy::tiny_tr_type& old, int town_num){ _room_rect[i].right = old.room_rect[i].right; } for(i = 0; i < 30; i++) { -// _creatures[i].number = old.creatures[i].number; -// _creatures[i].start_attitude = old.creatures[i].start_attitude; -// _creatures[i].start_loc.x = old.creatures[i].start_loc.x; -// _creatures[i].start_loc.y = old.creatures[i].start_loc.y; -// _creatures[i].mobile = old.creatures[i].mobile; -// _creatures[i].time_flag = old.creatures[i].time_flag; -// _creatures[i].extra1 = old.creatures[i].extra1; -// _creatures[i].extra2 = old.creatures[i].extra2; -// _creatures[i].spec1 = old.creatures[i].spec1; -// _creatures[i].spec2 = old.creatures[i].spec2; -// _creatures[i].spec_enc_code = old.creatures[i].spec_enc_code; -// _creatures[i].time_code = old.creatures[i].time_code; -// _creatures[i].monster_time = old.creatures[i].monster_time; -// _creatures[i].personality = old.creatures[i].personality; -// _creatures[i].special_on_kill = old.creatures[i].special_on_kill; -// _creatures[i].facial_pic = old.creatures[i].facial_pic; - _creatures[i] = old.creatures[i]; + _creatures[i].append(old.creatures[i]); } } @@ -158,27 +140,11 @@ void cMedTown::append(legacy::ave_tr_type& old, int town_num){ _room_rect[i].right = old.room_rect[i].right; } for(i = 0; i < 40; i++) { -// _creatures[i].number = old.creatures[i].number; -// _creatures[i].start_attitude = old.creatures[i].start_attitude; -// _creatures[i].start_loc.x = old.creatures[i].start_loc.x; -// _creatures[i].start_loc.y = old.creatures[i].start_loc.y; -// _creatures[i].mobile = old.creatures[i].mobile; -// _creatures[i].time_flag = old.creatures[i].time_flag; -// _creatures[i].extra1 = old.creatures[i].extra1; -// _creatures[i].extra2 = old.creatures[i].extra2; -// _creatures[i].spec1 = old.creatures[i].spec1; -// _creatures[i].spec2 = old.creatures[i].spec2; -// _creatures[i].spec_enc_code = old.creatures[i].spec_enc_code; -// _creatures[i].time_code = old.creatures[i].time_code; -// _creatures[i].monster_time = old.creatures[i].monster_time; -// _creatures[i].personality = old.creatures[i].personality; -// _creatures[i].special_on_kill = old.creatures[i].special_on_kill; -// _creatures[i].facial_pic = old.creatures[i].facial_pic; - _creatures[i] = old.creatures[i]; + _creatures[i].append(old.creatures[i]); } } -void cBigTown::append(legacy::big_tr_type& old, int town_num){ +void cBigTown::append(legacy::big_tr_type& old, int town_numo){ int i,j; cField the_field; the_field.type = 2; @@ -225,7 +191,7 @@ void cBigTown::append(legacy::big_tr_type& old, int town_num){ spec_id[found_spec] = use_slot; } else { std::stringstream sout; - sout << "In town " << town_num << " at (" << i << ',' << j << "); special node ID " << spec_id[found_spec]; + sout << "In town " << town_numo << " at (" << i << ',' << j << "); special node ID " << spec_id[found_spec]; giveError("Warning: A special node was found that could be triggered from in a boat, which is probably not what the designer intended. An attempt to fix this has failed because there were not enough unused special nodes.", sout.str()); } } @@ -238,23 +204,7 @@ void cBigTown::append(legacy::big_tr_type& old, int town_num){ _room_rect[i].right = old.room_rect[i].right; } for(i = 0; i < 60; i++) { -// _creatures[i].number = old.creatures[i].number; -// _creatures[i].start_attitude = old.creatures[i].start_attitude; -// _creatures[i].start_loc.x = old.creatures[i].start_loc.x; -// _creatures[i].start_loc.y = old.creatures[i].start_loc.y; -// _creatures[i].mobile = old.creatures[i].mobile; -// _creatures[i].time_flag = old.creatures[i].time_flag; -// _creatures[i].extra1 = old.creatures[i].extra1; -// _creatures[i].extra2 = old.creatures[i].extra2; -// _creatures[i].spec1 = old.creatures[i].spec1; -// _creatures[i].spec2 = old.creatures[i].spec2; -// _creatures[i].spec_enc_code = old.creatures[i].spec_enc_code; -// _creatures[i].time_code = old.creatures[i].time_code; -// _creatures[i].monster_time = old.creatures[i].monster_time; -// _creatures[i].personality = old.creatures[i].personality; -// _creatures[i].special_on_kill = old.creatures[i].special_on_kill; -// _creatures[i].facial_pic = old.creatures[i].facial_pic; - _creatures[i] = old.creatures[i]; + _creatures[i].append(old.creatures[i]); } } @@ -330,9 +280,8 @@ unsigned char& cBigTown::lighting(size_t i, size_t r){ return _lighting[i][r]; } -cBigTown::cBigTown(){ +cBigTown::cBigTown(cScenario& scenario, bool init_strings) : cTown(scenario, init_strings) { int i; - cCreature dummy_creature;// = {0,0,loc(),0,0,0,0,0,0,0}; rectangle d_rect = {0,0,0,0}; for(i = 0; i < 16; i++) { _room_rect[i].top = d_rect.top; @@ -340,14 +289,15 @@ cBigTown::cBigTown(){ _room_rect[i].bottom = d_rect.bottom; _room_rect[i].right = d_rect.right; } - for(i = 0; i < 60; i++) { - _creatures[i] = dummy_creature; - } + for(i = 0; i < max_dim(); i++) + for(int j = 0; j < max_dim(); j++) { + terrain(i,j) = scenario.default_ground * 2; + lighting(i / 8,j) = 0; + } } -cMedTown::cMedTown(){ +cMedTown::cMedTown(cScenario& scenario, bool init_strings) : cTown(scenario, init_strings) { int i; - cCreature dummy_creature;// = {0,0,loc(),0,0,0,0,0,0,0}; rectangle d_rect = {0,0,0,0}; for(i = 0; i < 16; i++) { _room_rect[i].top = d_rect.top; @@ -355,14 +305,15 @@ cMedTown::cMedTown(){ _room_rect[i].bottom = d_rect.bottom; _room_rect[i].right = d_rect.right; } - for(i = 0; i < 40; i++) { - _creatures[i] = dummy_creature; - } + for(i = 0; i < max_dim(); i++) + for(int j = 0; j < max_dim(); j++) { + terrain(i,j) = scenario.default_ground * 2; + lighting(i / 8,j) = 0; + } } -cTinyTown::cTinyTown(){ +cTinyTown::cTinyTown(cScenario& scenario, bool init_strings) : cTown(scenario, init_strings) { int i; - cCreature dummy_creature;// = {0,0,loc(),0,0,0,0,0,0,0}; rectangle d_rect = {0,0,0,0}; for(i = 0; i < 16; i++) { _room_rect[i].top = d_rect.top; @@ -370,43 +321,45 @@ cTinyTown::cTinyTown(){ _room_rect[i].bottom = d_rect.bottom; _room_rect[i].right = d_rect.right; } - for(i = 0; i < 30; i++) { - _creatures[i] = dummy_creature; - } + for(i = 0; i < max_dim(); i++) + for(int j = 0; j < max_dim(); j++) { + terrain(i,j) = scenario.default_ground * 2; + lighting(i / 8,j) = 0; + } } -short cBigTown::max_dim(){ +short cBigTown::max_dim() const { return 64; } -short cMedTown::max_dim(){ +short cMedTown::max_dim() const { return 48; } -short cTinyTown::max_dim(){ +short cTinyTown::max_dim() const { return 32; } -short cBigTown::max_monst(){ +short cBigTown::max_monst() const { return 60; } -short cMedTown::max_monst(){ +short cMedTown::max_monst() const { return 40; } -short cTinyTown::max_monst(){ +short cTinyTown::max_monst() const { return 30; } -short cBigTown::max_items(){ +short cBigTown::max_items() const { return 64; } -short cMedTown::max_items(){ +short cMedTown::max_items() const { return 64; } -short cTinyTown::max_items(){ +short cTinyTown::max_items() const { return 64; } diff --git a/osx/classes/regtown.h b/osx/classes/regtown.h index f220af25..429cfe84 100644 --- a/osx/classes/regtown.h +++ b/osx/classes/regtown.h @@ -34,11 +34,11 @@ public: rectangle& room_rect(size_t i); cCreature& creatures(size_t i); unsigned char& lighting(size_t i, size_t r); - short max_dim(); - short max_monst(); - short max_items(); + short max_dim() const; + short max_monst() const; + short max_items() const; - cBigTown(); + explicit cBigTown(cScenario& scenario, bool init_strings = false); void writeTerrainTo(std::ostream& file); void readTerrainFrom(std::istream& file); }; @@ -55,11 +55,11 @@ public: rectangle& room_rect(size_t i); cCreature& creatures(size_t i); unsigned char& lighting(size_t i, size_t r); - short max_dim(); - short max_monst(); - short max_items(); + short max_dim() const; + short max_monst() const; + short max_items() const; - cMedTown(); + explicit cMedTown(cScenario& scenario, bool init_strings = false); void writeTerrainTo(std::ostream& file); void readTerrainFrom(std::istream& file); }; @@ -76,11 +76,11 @@ public: rectangle& room_rect(size_t i); cCreature& creatures(size_t i); unsigned char& lighting(size_t i, size_t r); - short max_dim(); - short max_monst(); - short max_items(); + short max_dim() const; + short max_monst() const; + short max_items() const; - cTinyTown(); + explicit cTinyTown(cScenario& scenario, bool init_strings = false); void writeTerrainTo(std::ostream& file); void readTerrainFrom(std::istream& file); }; diff --git a/osx/classes/scenario.cpp b/osx/classes/scenario.cpp index 69af0f07..4dca5374 100644 --- a/osx/classes/scenario.cpp +++ b/osx/classes/scenario.cpp @@ -14,6 +14,93 @@ #include "classes.h" #include "oldstructs.h" +cScenario::~cScenario() { + destroy_terrain(); +} + +void cScenario::destroy_terrain() { + // Nuke towns + if(!towns.empty()) { + for(size_t i = 0; i < towns.size(); i++) { + if(towns[i] != nullptr) delete towns[i]; + towns[i] = nullptr; + } + } + if(!outdoors.empty()){ + for(size_t i = 0; i < outdoors.width(); i++) { + for(size_t j = 0; j < outdoors.height(); j++) { + if(outdoors[i][j] != nullptr) delete outdoors[i][j]; + outdoors[i][j] = nullptr; + } + } + } +} + +cScenario& cScenario::operator=(cScenario&& other) { + // If self-assignment, do nothing. + if(this == &other) return *this; + // First, free any held pointers. + destroy_terrain(); + // Resize the outdoors to ensure the assigned outdoors fits + outdoors.resize(other.outdoors.width(), other.outdoors.height()); + // Then forward to the default assignment operator. + // Use const_cast to ensure the right overload is selected. + return *this = const_cast(other); +} + +cScenario::cScenario(bool init_strings) { + short i; + std::string temp_str; + + format.ver[0] = 1; + format.min_run_ver = 1; + format.prog_make_ver[0] = 1; + num_towns = 1; + out_width = 1; + out_height = 1; + default_ground = 1; + for(i = 0; i < 200; i++) { + town_size[i] = 1; + } + where_start.x = 24; + where_start.y = 24; + out_start = where_start; + for(i = 0; i < 10; i++) { + town_to_add_to[i] = -1; + } + for(i = 0; i < 3; i++) { + store_item_towns[i] = -1; + } + for(i = 0; i < 50; i++) { + special_items[i].special = -1; + } + for(i = 0; i < 20; i++) { + scenario_timer_specs[i] = -1; + } + for(i = 0; i < 400; i++) { + scen_items[i] = cItemRec(); + } + if(!init_strings) return; + for(i = 0; i < 270; i++) { + temp_str = get_str("scen-default",i + 1); + if(i == 0) scen_name = temp_str; + else if(i == 1 || i == 2) + who_wrote[i-1] = temp_str; + else if(i == 3) + contact_info = temp_str; + else if(i >= 4 && i < 10) + intro_strs[i-4] = temp_str; + else if(i >= 10 && i < 60) + journal_strs[i-10] = temp_str; + else if(i >= 60 && i < 160) { + if(i % 2 == 0) special_items[(i-60)/2].name = temp_str; + else special_items[(i-60)/2].descr = temp_str; + } else if(i >= 260) continue; // These were never ever used, for some reason. + else spec_strs[i-160] = temp_str; + scen_str_len[i] = temp_str.length(); + } +} + cScenario::cItemStorage::cItemStorage() : ter_type(-1), property(0) { for(int i = 0; i < 10; i++) item_num[i] = -1; @@ -23,7 +110,7 @@ cScenario::cItemStorage::cItemStorage() : ter_type(-1), property(0) { //{-1,{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{0,0,0,0,0,0,0,0,0,0},0} -cScenario& cScenario::operator = (legacy::scenario_data_type& old){ +void cScenario::append(legacy::scenario_data_type& old){ is_legacy = true; int i,j; // for(i = 0; i < 3; i++) format.ver[i] = old.ver[i]; @@ -77,18 +164,18 @@ cScenario& cScenario::operator = (legacy::scenario_data_type& old){ // TODO: Is this used anywhere? uses_custom_graphics = old.uses_custom_graphics; flag_f = old.flag_f; - for(i = 0; i < 256; i++) scen_monsters[i] = old.scen_monsters[i]; - for(i = 0; i < 30; i++) boats[i] = old.scen_boats[i]; - for(i = 0; i < 30; i++) horses[i] = old.scen_horses[i]; + for(i = 0; i < 256; i++) scen_monsters[i].append(old.scen_monsters[i]); + for(i = 0; i < 30; i++) boats[i].append(old.scen_boats[i]); + for(i = 0; i < 30; i++) horses[i].append(old.scen_horses[i]); flag_g = old.flag_g; for(i = 0; i < 256; i++){ ter_types[i].i = i; - ter_types[i] = old.ter_types[i]; + ter_types[i].append(old.ter_types[i]); } for(i = 0; i < 20; i++) scenario_timer_times[i] = old.scenario_timer_times[i]; for(i = 0; i < 20; i++) scenario_timer_specs[i] = old.scenario_timer_specs[i]; flag_h = old.flag_h; - for(i = 0; i < 256; i++) scen_specials[i] = old.scen_specials[i]; + for(i = 0; i < 256; i++) scen_specials[i].append(old.scen_specials[i]); for(i = 0; i < 10; i++) storage_shortcuts[i] = old.storage_shortcuts[i]; flag_d = old.flag_d; for(i = 0; i < 300; i++) scen_str_len[i] = old.scen_str_len[i]; @@ -97,7 +184,6 @@ cScenario& cScenario::operator = (legacy::scenario_data_type& old){ last_out_edited.y = old.last_out_edited.y; last_town_edited = old.last_town_edited; adjust_diff = true; - return *this; } cScenario::cItemStorage& cScenario::cItemStorage::operator = (legacy::item_storage_shortcut_type& old){ @@ -111,7 +197,7 @@ cScenario::cItemStorage& cScenario::cItemStorage::operator = (legacy::item_stora void cScenario::append(legacy::scen_item_data_type& old){ short i; for(i = 0; i < 400; i++) - scen_items[i] = old.scen_items[i]; + scen_items[i].append(old.scen_items[i]); for(i = 0; i < 256; i++) scen_monsters[i].m_name = old.monst_names[i]; for(i = 0; i < 256; i++) diff --git a/osx/classes/scenario.h b/osx/classes/scenario.h index 52a4ff55..f4357ce6 100644 --- a/osx/classes/scenario.h +++ b/osx/classes/scenario.h @@ -19,6 +19,7 @@ #include "special.h" #include "outdoors.h" #include "town.h" +#include "vector2d.hpp" namespace fs = boost::filesystem; // TODO: Centralize this namespace alias? @@ -44,6 +45,8 @@ public: cItemStorage(); cItemStorage& operator = (legacy::item_storage_shortcut_type& old); }; + cScenario& operator=(const cScenario& other) = default; + void destroy_terrain(); public: //unsigned char flag1, flag2, flag3, flag4; unsigned char num_towns; @@ -104,12 +107,18 @@ public: char : 7; bool is_legacy; fs::path scen_file; // transient - cOutdoors* outdoors; - cTown* towns; + vector2d outdoors; + std::vector towns; + template void addTown() {towns.push_back(new Town(*this, true));} - cScenario& operator = (legacy::scenario_data_type& old); + void append(legacy::scenario_data_type& old); void append(legacy::scen_item_data_type& old); - void writeTo(std::ostream& file); + void writeTo(std::ostream& file) const; + + cScenario& operator=(cScenario&& other); + cScenario(cScenario&) = delete; + explicit cScenario(bool init_strings = false); + ~cScenario(); }; // OBoE Current Version diff --git a/osx/classes/special.cpp b/osx/classes/special.cpp index 2c96af7a..7f15088a 100644 --- a/osx/classes/special.cpp +++ b/osx/classes/special.cpp @@ -30,7 +30,7 @@ cSpecial::cSpecial(){ jumpto = -1; } -cSpecial& cSpecial::operator = (legacy::special_node_type& old){ +void cSpecial::append(legacy::special_node_type& old){ type = (eSpecType)old.type; sd1 = old.sd1; sd2 = old.sd2; @@ -117,7 +117,6 @@ cSpecial& cSpecial::operator = (legacy::special_node_type& old){ type = eSpecType::TOWN_SET_ATTITUDE; break; } - return *this; } std::ostream& operator << (std::ostream& out, eSpecType& e) { diff --git a/osx/classes/special.h b/osx/classes/special.h index 1d98291d..5b9e7c76 100644 --- a/osx/classes/special.h +++ b/osx/classes/special.h @@ -34,8 +34,8 @@ public: short jumpto; cSpecial(); - cSpecial& operator = (legacy::special_node_type& old); - void writeTo(std::ostream& file); + void append(legacy::special_node_type& old); + void writeTo(std::ostream& file) const; }; struct pending_special_type { diff --git a/osx/classes/talking.cpp b/osx/classes/talking.cpp index 1e6249a6..45f9073b 100644 --- a/osx/classes/talking.cpp +++ b/osx/classes/talking.cpp @@ -14,7 +14,7 @@ #include "classes.h" #include "oldstructs.h" -cSpeech& cSpeech::operator = (legacy::talking_record_type& old){ +void cSpeech::append(legacy::talking_record_type& old){ int i,j; for(i = 0; i < 200; i++) strlens[i] = old.strlens[i]; @@ -33,5 +33,4 @@ cSpeech& cSpeech::operator = (legacy::talking_record_type& old){ break; } } - return *this; } diff --git a/osx/classes/talking.h b/osx/classes/talking.h index 123710d3..3d69a175 100644 --- a/osx/classes/talking.h +++ b/osx/classes/talking.h @@ -35,8 +35,8 @@ public: cPersonality people[10]; cNode talk_nodes[60]; - cSpeech& operator = (legacy::talking_record_type& old); - void writeTo(std::ostream& file); + void append(legacy::talking_record_type& old); + void writeTo(std::ostream& file) const; }; #endif \ No newline at end of file diff --git a/osx/classes/terrain.cpp b/osx/classes/terrain.cpp index 77d4fbab..453c5acd 100644 --- a/osx/classes/terrain.cpp +++ b/osx/classes/terrain.cpp @@ -15,7 +15,7 @@ #include "oldstructs.h" #include "boe.consts.h" // TODO: Put these constants in a global file -cTerrain& cTerrain::operator = (legacy::terrain_type_type& old){ +void cTerrain::append(legacy::terrain_type_type& old){ static const short arenas[274] = { 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, // 0 - grassy field 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, // 1 - ordinary cave @@ -353,7 +353,6 @@ cTerrain& cTerrain::operator = (legacy::terrain_type_type& old){ }; if(picture < 1000) map_pic = picture; else map_pic = NO_PIC; - return *this; } std::ostream& operator << (std::ostream& out, eTerSpec& e){ diff --git a/osx/classes/terrain.h b/osx/classes/terrain.h index 724f3de1..a6b727bd 100644 --- a/osx/classes/terrain.h +++ b/osx/classes/terrain.h @@ -46,8 +46,8 @@ public: pic_num_t map_pic; unsigned short i; // for temporary use in porting - cTerrain& operator = (legacy::terrain_type_type& old); - void writeTo(std::ostream& file); + void append(legacy::terrain_type_type& old); + void writeTo(std::ostream& file) const; }; std::ostream& operator << (std::ostream& out, eTerSpec& e); diff --git a/osx/classes/tmpltown.cpp b/osx/classes/tmpltown.cpp index 90ea199d..7236da28 100644 --- a/osx/classes/tmpltown.cpp +++ b/osx/classes/tmpltown.cpp @@ -37,14 +37,14 @@ unsigned char& cBigTemplTown::lighting(size_t i, size_t r){ return _lighting[i][r]; } -short cBigTemplTown::max_dim(){ +short cBigTemplTown::max_dim() const { return 0; // not sure what they are yet. } -short cBigTemplTown::max_monst(){ +short cBigTemplTown::max_monst() const { return 30; } -short cBigTemplTown::max_items(){ +short cBigTemplTown::max_items() const { return 64; } diff --git a/osx/classes/tmpltown.h b/osx/classes/tmpltown.h index 5a60cdbd..eda8e957 100644 --- a/osx/classes/tmpltown.h +++ b/osx/classes/tmpltown.h @@ -47,11 +47,12 @@ public: rectangle& room_rect(size_t i); cCreature& creatures(size_t i); unsigned char& lighting(size_t i, size_t r); - short max_dim(); - short max_monst(); - short max_items(); + short max_dim() const; + short max_monst() const; + short max_items() const; void writeTerrainTo(std::ostream& file); void readTerrainFrom(std::istream& file); + explicit cBigTemplTown(cScenario& scenario, bool init_strings = false); }; class cMedTemplTown : public cMedTown, cTemplTown { @@ -65,11 +66,12 @@ public: rectangle& room_rect(size_t i); cCreature& creatures(size_t i); unsigned char& lighting(size_t i, size_t r); - short max_dim(); - short max_monst(); - short max_items(); + short max_dim() const; + short max_monst() const; + short max_items() const; void writeTerrainTo(std::ostream& file); void readTerrainFrom(std::istream& file); + explicit cMedTemplTown(cScenario& scenario, bool init_strings = false); }; class cTinyTemplTown : public cTinyTown, cTemplTown { @@ -83,11 +85,12 @@ public: rectangle& room_rect(size_t i); cCreature& creatures(size_t i); unsigned char& lighting(size_t i, size_t r); - short max_dim(); - short max_monst(); - short max_items(); + short max_dim() const; + short max_monst() const; + short max_items() const; 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. diff --git a/osx/classes/town.cpp b/osx/classes/town.cpp index 9d3d2940..6afdaa0c 100644 --- a/osx/classes/town.cpp +++ b/osx/classes/town.cpp @@ -14,11 +14,11 @@ #include "classes.h" #include "oldstructs.h" -void cTown::append(legacy::big_tr_type&, int town_num){} -void cTown::append(legacy::ave_tr_type&, int town_num){} -void cTown::append(legacy::tiny_tr_type&, int town_num){} +void cTown::append(legacy::big_tr_type&, int){} +void cTown::append(legacy::ave_tr_type&, int){} +void cTown::append(legacy::tiny_tr_type&, int){} -cTown& cTown::operator = (legacy::town_record_type& old){ +void cTown::append(legacy::town_record_type& old){ int i; town_chop_time = old.town_chop_time; town_chop_key = old.town_chop_key; @@ -74,16 +74,13 @@ cTown& cTown::operator = (legacy::town_record_type& old){ for(i = 0; i < 180; i++) strlens[i] = old.strlens[i]; for(i = 0; i < 100; i++) - specials[i] = old.specials[i]; + specials[i].append(old.specials[i]); difficulty = old.difficulty; strong_barriers = defy_scrying = defy_mapping = false; - return *this; } -cTown::cTown(){} - short max_dim[3] = {64,48,32}; -cTown::cTown(short){ +cTown::cTown(cScenario& scenario, bool init_strings) : scenario(scenario) { short i,s; location d_loc(100,0); cTown::cWandering d_wan = {0,0,0,0}; @@ -139,6 +136,45 @@ cTown::cTown(short){ } difficulty = 0; strong_barriers = defy_scrying = defy_mapping = false; + for(i = 0; i < 60; i++) { + talking.talk_nodes[i].personality = -1; + talking.talk_nodes[i].type = 0; + talking.talk_nodes[i].extras[0] = 0; + talking.talk_nodes[i].extras[1] = 0; + talking.talk_nodes[i].extras[2] = 0; + talking.talk_nodes[i].extras[3] = -1; + talking.talk_nodes[i].str1 = ""; + talking.talk_nodes[i].str2 = ""; + for(int j = 0; j < 4; j++) { + talking.talk_nodes[i].link1[j] = 'x'; + talking.talk_nodes[i].link2[j] = 'x'; + } + } + if(!init_strings) return; + std::string temp_str; + for(i = 0; i < 180; i++) { + temp_str = get_str("town-default",i + 1); + if(i == 0) town_name = temp_str; + else if(i >= 1 && i < 17) + rect_names[i-1] = temp_str; + else if(i >= 17 && i < 20) + comment[i-17] = temp_str; + else if(i >= 20 && i < 120) + spec_strs[i-20] = temp_str; + else if(i >= 120 && i < 140) + sign_strs[i-120] = temp_str; + strlens[i] = temp_str.length(); + } + + for(i = 0; i < 200; i++) + talking.strlens[i] = 0; + for(i = 0; i < 10; i++) { + talking.people[i].title = "Unused"; + talking.people[i].look = ""; + talking.people[i].name = ""; + talking.people[i].job = ""; + talking.people[i].dunno = ""; + } } cTown::cWandering& cTown::cWandering::operator = (legacy::wandering_type old){ diff --git a/osx/classes/town.h b/osx/classes/town.h index 75eda278..33a41dfe 100644 --- a/osx/classes/town.h +++ b/osx/classes/town.h @@ -36,7 +36,11 @@ enum eLighting { LIGHT_NONE = 3, }; +class cScenario; + class cTown { // formerly town_record_type +protected: + cScenario& scenario; public: // class cCreature { // formerly creature_start_type // public: @@ -120,15 +124,14 @@ public: virtual rectangle& room_rect(size_t i) = 0; virtual cCreature& creatures(size_t i) = 0; virtual unsigned char& lighting(size_t i, size_t r) = 0; - virtual short max_dim() = 0; - virtual short max_monst() = 0; - virtual short max_items() = 0; + virtual short max_dim() const = 0; + virtual short max_monst() const = 0; + virtual short max_items() const = 0; void set_up_lights(); short light_obscurity(short x,short y); // Obscurity function used for calculating lighting - cTown(); - cTown(short size); - cTown& operator = (legacy::town_record_type& old); + explicit cTown(cScenario& scenario, bool init_strings = false); + void append(legacy::town_record_type& old); virtual void writeTerrainTo(std::ostream& file) = 0; virtual void readTerrainFrom(std::istream& file) = 0; }; diff --git a/osx/classes/universe.cpp b/osx/classes/universe.cpp index b3066e67..1a6e5719 100644 --- a/osx/classes/universe.cpp +++ b/osx/classes/universe.cpp @@ -22,56 +22,42 @@ void cCurOut::append(legacy::out_info_type& old){ expl[i][j] = old.expl[i][j]; } -void cCurTown::append(legacy::current_town_type& old,short which_size){ +void cCurTown::append(legacy::current_town_type& old){ num = old.town_num; difficulty = old.difficulty; - if(record != NULL) delete record; - switch(which_size){ - case 0: - record = new cBigTown; - break; - case 1: - record = new cMedTown; - break; - case 2: - record = new cTinyTown; - break; - } - *record = old.town; + record()->append(old.town); for(int i = 0; i < 64; i++) for(int j = 0; j < 64; j++) fields[i][j] = old.explored[i][j]; hostile = old.hostile; - monst = old.monst; + monst.append(old.monst); in_boat = old.in_boat; p_loc.x = old.p_loc.x; p_loc.y = old.p_loc.y; - curTalk = &record->talking; - talkNeedsDeleting = false; cur_talk_loaded = num; } void cCurTown::append(legacy::big_tr_type& old){ int i,j; - for(i = 0; i < record->max_dim(); i++) - for(j = 0; j < record->max_dim(); j++) - record->terrain(i,j) = old.terrain[i][j]; + for(i = 0; i < record()->max_dim(); i++) + for(j = 0; j < record()->max_dim(); j++) + record()->terrain(i,j) = old.terrain[i][j]; for(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()->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; } - for(i = 0; i < record->max_monst(); i++) - record->creatures(i) = old.creatures[i]; - for(i = 0; i < record->max_dim() / 8; i++) - for(j = 0; j < record->max_dim(); j++) - record->lighting(i,j) = old.lighting[i][j]; + for(i = 0; i < record()->max_monst(); i++) + record()->creatures(i).append(old.creatures[i]); + for(i = 0; i < record()->max_dim() / 8; i++) + for(j = 0; j < record()->max_dim(); j++) + record()->lighting(i,j) = old.lighting[i][j]; } void cCurTown::append(legacy::town_item_list& old){ for(int i = 0; i < 115; i++) - items[i] = old.items[i]; + items[i].append(old.items[i]); } void cUniverse::append(legacy::stored_town_maps_type& old){ @@ -102,91 +88,77 @@ void cCurTown::append(unsigned char(& old_sfx)[64][64], unsigned char(& old_misc } cTown* cCurTown::operator -> (){ - return record; -} - -bool cCurTown::loaded() const{ - return record != NULL; -} - -void cCurTown::unload(){ - delete record; - record = NULL; + return record(); } cSpeech& cCurTown::cur_talk() { // Make sure we actually have a valid speech stored - if(curTalk == NULL) prep_talk(num); - return *curTalk; + return univ.scenario.towns[cur_talk_loaded]->talking; } bool cCurTown::prep_talk(short which) { if(which == cur_talk_loaded) return true; - if(talkNeedsDeleting && curTalk != NULL) delete curTalk; cur_talk_loaded = which; - if(which == num) { - curTalk = &record->talking; - talkNeedsDeleting = false; - return true; - } else { - curTalk = new cSpeech; - talkNeedsDeleting = true; - return false; - } + return true; } void cCurTown::prep_arena() { - if(loaded()) delete record; - record = new cMedTown(); + if(arena != nullptr) delete arena; + arena = new cMedTown(univ.scenario, false); } cCurTown::~cCurTown() { - if(talkNeedsDeleting && curTalk != NULL) delete curTalk; + if(arena != nullptr) delete arena; +} + +cTown*const cCurTown::record() const { + if(num == 200) return arena; + return univ.scenario.towns[num]; } bool cCurTown::is_explored(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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; } @@ -195,97 +167,97 @@ bool cCurTown::is_spot(char x, char y) const{ } bool cCurTown::is_special(char x, char y) const{ - if(x > record->max_dim() || y > record->max_dim()) return false; + if(x > record()->max_dim() || y > record()->max_dim()) return false; for(int i = 0; i < 50; i++) - if(x == record->special_locs[i].x && y == record->special_locs[i].y) + if(x == record()->special_locs[i].x && y == record()->special_locs[i].y) return true; return false; } bool cCurTown::is_web(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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(char x, char 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; @@ -302,7 +274,7 @@ bool cCurTown::set_force_wall(char x, char y, bool b){ } bool cCurTown::set_fire_wall(char x, char 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; @@ -321,7 +293,7 @@ bool cCurTown::set_fire_wall(char x, char y, bool b){ } bool cCurTown::set_antimagic(char x, char 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; @@ -341,7 +313,7 @@ bool cCurTown::set_antimagic(char x, char y, bool b){ } bool cCurTown::set_scloud(char x, char 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; @@ -358,7 +330,7 @@ bool cCurTown::set_scloud(char x, char y, bool b){ // stinking cloud } bool cCurTown::set_ice_wall(char x, char 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; @@ -377,7 +349,7 @@ bool cCurTown::set_ice_wall(char x, char y, bool b){ } bool cCurTown::set_blade_wall(char x, char 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; @@ -392,7 +364,7 @@ bool cCurTown::set_blade_wall(char x, char y, bool b){ } bool cCurTown::set_sleep_cloud(char x, char 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; @@ -407,21 +379,21 @@ bool cCurTown::set_sleep_cloud(char x, char y, bool b){ } bool cCurTown::set_block(char x, char 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(char x, char 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_web(char x, char 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; @@ -438,7 +410,7 @@ bool cCurTown::set_web(char x, char y, bool b){ } bool cCurTown::set_crate(char x, char 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; @@ -449,7 +421,7 @@ bool cCurTown::set_crate(char x, char y, bool b){ } bool cCurTown::set_barrel(char x, char 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; @@ -460,7 +432,7 @@ bool cCurTown::set_barrel(char x, char y, bool b){ } bool cCurTown::set_fire_barr(char x, char 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; @@ -482,7 +454,7 @@ bool cCurTown::set_fire_barr(char x, char y, bool b){ } bool cCurTown::set_force_barr(char x, char 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; @@ -504,13 +476,13 @@ bool cCurTown::set_force_barr(char x, char y, bool b){ } bool cCurTown::set_quickfire(char x, char 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(scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_SIGHT) + ter_num_t ter = record()->terrain(x,y); + if(univ.scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_SIGHT) return false; // TODO: Isn't it a little odd that BLOCK_MOVE_AND_SHOOT isn't included here? - if(scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) + if(univ.scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) return false; if(is_antimagic(x,y) && get_ran(1,0,1) == 0) return false; @@ -537,14 +509,14 @@ bool cCurTown::set_quickfire(char x, char y, bool b){ bool cCurTown::free_for_sfx(short x, short y) { ter_num_t ter; - ter = record->terrain(x,y); - if(scenario.ter_types[ter].blockage != eTerObstruct::CLEAR) + ter = record()->terrain(x,y); + if(univ.scenario.ter_types[ter].blockage != eTerObstruct::CLEAR) return false; return true; } bool cCurTown::set_sm_blood(char x, char 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)) @@ -561,7 +533,7 @@ bool cCurTown::set_sm_blood(char x, char y, bool b){ } bool cCurTown::set_med_blood(char x, char 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)) @@ -579,7 +551,7 @@ bool cCurTown::set_med_blood(char x, char y, bool b){ } bool cCurTown::set_lg_blood(char x, char 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); @@ -613,7 +585,7 @@ bool cCurTown::set_sm_slime(char x, char y, bool b){ } bool cCurTown::set_lg_slime(char x, char 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); @@ -630,7 +602,7 @@ bool cCurTown::set_lg_slime(char x, char y, bool b){ } bool cCurTown::set_ash(char x, char 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); @@ -647,7 +619,7 @@ bool cCurTown::set_ash(char x, char y, bool b){ } bool cCurTown::set_bones(char x, char 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); @@ -664,7 +636,7 @@ bool cCurTown::set_bones(char x, char y, bool b){ } bool cCurTown::set_rubble(char x, char 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); @@ -683,7 +655,7 @@ bool cCurTown::set_rubble(char x, char y, bool b){ bool cCurTown::set_force_cage(char x, char 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; @@ -722,8 +694,8 @@ bool cCurTown::set_force_cage(char x, char y, bool b){ bool cCurTown::is_impassable(short i,short j) { ter_num_t ter; - ter = record->terrain(i,j); - if(scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) + ter = record()->terrain(i,j); + if(univ.scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) return true; else return false; } @@ -736,7 +708,7 @@ ter_num_t& cCurOut::operator [] (location loc) { return out[loc.x][loc.y]; } -void cCurOut::writeTo(std::ostream& file){ +void cCurOut::writeTo(std::ostream& file) const { writeArray(file, expl, 96, 96); writeArray(file, out, 96, 96); writeArray(file, out_e, 96, 96); @@ -757,7 +729,7 @@ void cCurOut::readFrom(std::istream& file) { readArray(file, out_e, 96, 96); } -void cCurTown::writeTo(std::ostream& file){ +void cCurTown::writeTo(std::ostream& file) const { file << "TOWN " << num << '\n'; file << "DIFFICULTY " << difficulty << '\n'; if(hostile) file << "HOSTILE" << '\n'; @@ -781,8 +753,8 @@ void cCurTown::writeTo(std::ostream& file){ file << '\f'; file << "FIELDS\n"; writeArray(file, fields, 64, 46); - file << "SIZE " << record->max_dim() << "\n"; - record->writeTerrainTo(file); + file << "SIZE " << record()->max_dim() << "\n"; + record()->writeTerrainTo(file); // TODO: Do we need to save special_spot? } @@ -826,33 +798,30 @@ void cCurTown::readFrom(std::istream& file){ } else if(cur == "SIZE") { int dim; bin >> dim; - if(record != NULL) delete record; - switch(dim){ - case 32: - record = new cTinyTown; - break; - case 48: - record = new cMedTown; - break; - case 64: - record = new cBigTown; - break; - } - record->readTerrainFrom(bin); + univ.scenario.towns[num]->readTerrainFrom(bin); } bin.clear(); } } -cCurTown::cCurTown(){ - record = NULL; +cCurTown::cCurTown(cUniverse& univ) : univ(univ) { + arena = nullptr; num = 200; for(int i = 0; i < 64; i++) for(int j = 0; j < 64; j++) fields[i][j] = 0L; } -extern cScenario scenario; -short cUniverse::difficulty_adjust() { + +cCurOut::cCurOut(cUniverse& univ) : univ(univ) {} + +cOutdoors* cCurOut::operator->() { + short x = univ.party.outdoor_corner.x + univ.party.i_w_c.x, y = univ.party.outdoor_corner.y + univ.party.i_w_c.y; + return univ.scenario.outdoors[x][y]; +} + +cUniverse::cUniverse(long party_type) : party(*this, party_type), out(*this), town(*this) {} + +short cUniverse::difficulty_adjust() const { short party_level = 0; short adj = 1; @@ -874,7 +843,7 @@ short cUniverse::difficulty_adjust() { short cCurTown::countMonsters(){ short to_ret = 0; - for(short i = 0; i < record->max_monst(); i++) + for(short i = 0; i < record()->max_monst(); i++) if(monst[i].active > 0) to_ret++; return to_ret; diff --git a/osx/classes/universe.h b/osx/classes/universe.h index 8547af58..7dd77fcd 100644 --- a/osx/classes/universe.h +++ b/osx/classes/universe.h @@ -17,6 +17,7 @@ #include "town.h" #include "talking.h" #include "simpletypes.h" +#include "scenario.h" namespace fs = boost::filesystem; // TODO: Centralize this namespace alias? @@ -30,13 +31,13 @@ namespace legacy { }; class cCurTown { - cSpeech* curTalk = NULL; - bool talkNeedsDeleting = false; short cur_talk_loaded = -1; bool free_for_sfx(short x, short y); + cUniverse& univ; + cTown* arena; + cTown*const record() const; public: bool quickfire_present = false, belt_present = false; - cTown* record; // formerly current_town_type short num; // 200 if outdoors (my addition) short difficulty; @@ -51,15 +52,13 @@ public: //ter_num_t template_terrain[64][64]; unsigned long fields[64][64]; - void append(legacy::current_town_type& old,short which_size); + void append(legacy::current_town_type& old); void append(legacy::town_item_list& old); void append(unsigned char(& old_sfx)[64][64], unsigned char(& old_misc_i)[64][64]); void append(legacy::big_tr_type& old); cTown* operator -> (); - cCurTown(); - bool loaded() const; - void unload(); + explicit cCurTown(cUniverse& univ); short countMonsters(); cSpeech& cur_talk(); // Get the currently loaded speech bool prep_talk(short which); // Prepare for loading specified speech, returning true if already loaded @@ -119,25 +118,27 @@ public: bool set_force_cage(char x, char y, bool b); // bool set_trim(char x, char y, char t, bool b); bool is_impassable(short x, short y); - void writeTo(std::ostream& file); + void writeTo(std::ostream& file) const; void readFrom(std::istream& file); ~cCurTown(); }; class cCurOut { + cUniverse& univ; public: char expl[96][96]; // formerly out_info_type ter_num_t out[96][96]; unsigned char out_e[96][96]; - cOutdoors outdoors[2][2]; void append(legacy::out_info_type& old); ter_num_t(& operator [] (size_t i))[96]; ter_num_t& operator [] (location loc); - void writeTo(std::ostream& file); + void writeTo(std::ostream& file) const; void readFrom(std::istream& file); + cOutdoors* operator->(); + explicit cCurOut(cUniverse& univ); }; enum eAmbientSound { @@ -149,6 +150,7 @@ enum eAmbientSound { class cUniverse{ public: + cScenario scenario; cParty party; cCurTown town; char town_maps[200][8][64]; // formerly stored_town_maps_type @@ -159,7 +161,8 @@ public: void append(legacy::stored_town_maps_type& old); void append(legacy::stored_outdoor_maps_type& old); - short difficulty_adjust(); + short difficulty_adjust() const; + explicit cUniverse(long party_type = 'dflt'); }; #endif \ No newline at end of file diff --git a/osx/classes/vehicle.cpp b/osx/classes/vehicle.cpp index c948e456..9d9b98e8 100644 --- a/osx/classes/vehicle.cpp +++ b/osx/classes/vehicle.cpp @@ -27,7 +27,7 @@ cVehicle::cVehicle() : sector.x = 0; sector.y = 0; } -cVehicle& cVehicle::operator = (legacy::horse_record_type& old){ +void cVehicle::append(legacy::horse_record_type& old){ which_town = old.which_town; exists = old.exists; property = old.property; @@ -37,10 +37,9 @@ cVehicle& cVehicle::operator = (legacy::horse_record_type& old){ loc_in_sec.y = old.horse_loc_in_sec.y; sector.x = old.horse_sector.x; sector.y = old.horse_sector.y; - return *this; } -cVehicle& cVehicle::operator = (legacy::boat_record_type& old){ +void cVehicle::append(legacy::boat_record_type& old){ which_town = old.which_town; exists = old.exists; property = old.property; @@ -50,10 +49,9 @@ cVehicle& cVehicle::operator = (legacy::boat_record_type& old){ loc_in_sec.y = old.boat_loc_in_sec.y; sector.x = old.boat_sector.x; sector.y = old.boat_sector.y; - return *this; } -void cVehicle::writeTo(std::ostream& file) { +void cVehicle::writeTo(std::ostream& file) const { file << "LOCATION " << loc.x << ' ' << loc.y << '\n'; file << "LOCINSECTOR " << loc_in_sec.x << ' ' << loc_in_sec.y << '\n'; file << "SECTOR " << sector.x << ' ' << sector.y << '\n'; diff --git a/osx/classes/vehicle.h b/osx/classes/vehicle.h index 42cd091f..73c72e6d 100644 --- a/osx/classes/vehicle.h +++ b/osx/classes/vehicle.h @@ -29,9 +29,9 @@ public: bool property; cVehicle(); - cVehicle& operator = (legacy::horse_record_type& old); - cVehicle& operator = (legacy::boat_record_type& old); - void writeTo(std::ostream& file); + void append(legacy::horse_record_type& old); + void append(legacy::boat_record_type& old); + void writeTo(std::ostream& file) const; void readFrom(std::istream& file); }; diff --git a/osx/pcedit/pc.fileio.cpp b/osx/pcedit/pc.fileio.cpp index 050d9507..4e73ff22 100644 --- a/osx/pcedit/pc.fileio.cpp +++ b/osx/pcedit/pc.fileio.cpp @@ -84,10 +84,5 @@ short init_data(short flag) { void load_base_item_defs(){ fs::path basePath = progDir/"Scenario Editor"/"Blades of Exile Base"/"bladbase.exs"; - scen_items_loaded = load_scenario(basePath, true); -} - -bool load_scen_item_defs(std::string scen_name){ - fs::path scenPath = progDir/"Blades of Exile Scenarios"/scen_name; - return load_scenario(scenPath, true); + scen_items_loaded = load_scenario(basePath, univ.scenario); } diff --git a/osx/pcedit/pc.fileio.h b/osx/pcedit/pc.fileio.h index 73c4483e..9189b157 100644 --- a/osx/pcedit/pc.fileio.h +++ b/osx/pcedit/pc.fileio.h @@ -9,4 +9,3 @@ short init_data(short flag); //void save_prefs(); void remove_party_from_scen(); void load_base_item_defs(); -bool load_scen_item_defs(std::string scen_name); diff --git a/osx/pcedit/pc.main.cpp b/osx/pcedit/pc.main.cpp index 5e832955..93c97313 100644 --- a/osx/pcedit/pc.main.cpp +++ b/osx/pcedit/pc.main.cpp @@ -93,8 +93,6 @@ extern fs::path progDir; short specials_res_id; char start_name[256]; -cScenario scenario; - // // Main body of program Exile // @@ -216,22 +214,20 @@ void handle_file_menu(int item_hit) { switch(item_hit) { case 1://save - save_party(file_in_mem); + save_party(file_in_mem, univ); break; case 2://save as file = nav_put_party(); - if(!file.empty()) save_party(file); + if(!file.empty()) save_party(file, univ); break; case 3://open if(verify_restore_quit(true)){ file = nav_get_party(); if(!file.empty()) { - if(load_party(file)) { + if(load_party(file, univ)) { file_in_mem = file; party_in_scen = !univ.party.scen_name.empty(); - if(party_in_scen && load_scen_item_defs(univ.party.scen_name)) - scen_items_loaded = true; - else load_base_item_defs(); + if(!party_in_scen) load_base_item_defs(); update_item_menu(); } } @@ -459,7 +455,7 @@ void handle_item_menu(int item_hit) { display_strings(5,7); return; } - store_i = scenario.scen_items[item_hit]; + store_i = univ.scenario.scen_items[item_hit]; store_i.ident = true; give_to_pc(current_active_pc,store_i,false); } @@ -482,7 +478,7 @@ bool verify_restore_quit(bool mode) { return false; if(choice == "quit") return true; - save_party(file_in_mem); + save_party(file_in_mem, univ); return true; } diff --git a/osx/pcedit/pc.menus.mac.mm b/osx/pcedit/pc.menus.mac.mm index 4d0d52a5..f0dac2ba 100644 --- a/osx/pcedit/pc.menus.mac.mm +++ b/osx/pcedit/pc.menus.mac.mm @@ -9,7 +9,7 @@ #include "pc.menus.h" #include #include "item.h" -#include "scenario.h" +#include "universe.h" #ifndef __APPLE__ #error pc.menus.mm is Mac-specific code; try compiling pc.menus.win.cpp instead @@ -23,7 +23,7 @@ extern void handle_extra_menu(int item_hit); extern void handle_edit_menu(int item_hit); extern void handle_item_menu(int item_hit); -extern cScenario scenario; +extern cUniverse univ; extern fs::path file_in_mem; extern bool scen_items_loaded; MenuHandle menu_bar_handle; @@ -90,7 +90,7 @@ void menu_activate() { void update_item_menu() { id targ = [[file_menu itemAtIndex: 0] target]; - cItemRec(& item_list)[400] = scenario.scen_items; + cItemRec(& item_list)[400] = univ.scenario.scen_items; for(int j = 0; j < 4; j++){ [items_menu[j] removeAllItems]; if(!scen_items_loaded) { @@ -154,7 +154,7 @@ void update_item_menu() { } -(cItemRec&) item { - return scenario.scen_items[self->itemID]; + return univ.scenario.scen_items[self->itemID]; } @end diff --git a/osx/scenedit/scen.actions.cpp b/osx/scenedit/scen.actions.cpp index ac100d2c..0996d3ea 100644 --- a/osx/scenedit/scen.actions.cpp +++ b/osx/scenedit/scen.actions.cpp @@ -71,7 +71,7 @@ extern ter_num_t template_terrain[64][64]; extern cItemRec item_list[400]; extern cScenario scenario; extern std::shared_ptr right_sbar; -extern cOutdoors current_terrain; +extern cOutdoors* current_terrain; extern location cur_out; extern sf::RenderWindow mainPtr; //extern piles_of_stuff_dumping_type *data_store; @@ -106,7 +106,6 @@ short town_buttons[6][10] = { cCreature last_placed_monst; -cSpecial null_spec_node;// = {0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; cSpeech::cNode null_talk_node = {0,0,{120,120,120,120},{120,120,120,120},{0,0,0,0}}; rectangle working_rect; @@ -184,13 +183,11 @@ bool handle_action(location the_point,sf::Event /*event*/) { case 4: // edit fs::path file_to_load = nav_get_scenario(); - if(!file_to_load.empty() && load_scenario(file_to_load)) { - if(load_town(scenario.last_town_edited,town)) - cur_town = scenario.last_town_edited; - if(load_outdoors(scenario.last_out_edited,current_terrain)){ - cur_out = scenario.last_out_edited; - augment_terrain(cur_out); - } + if(!file_to_load.empty() && load_scenario(file_to_load, scenario)) { + cur_town = scenario.last_town_edited; + town = scenario.towns[cur_town]; + cur_out = scenario.last_out_edited; + current_terrain = scenario.outdoors[cur_out.x][cur_out.y]; overall_mode = MODE_MAIN_SCREEN; set_up_main_screen(); update_item_menu(); @@ -240,11 +237,9 @@ bool handle_action(location the_point,sf::Event /*event*/) { } spot_hit = pick_out(cur_out); if(spot_hit != cur_out) { - if(load_outdoors(spot_hit,current_terrain)){ - augment_terrain(spot_hit); - cur_out = spot_hit; - set_up_main_screen(); - } + cur_out = spot_hit; + current_terrain = scenario.outdoors[cur_out.x][cur_out.y]; + set_up_main_screen(); } break; case 12: // edit outdoors @@ -258,8 +253,9 @@ bool handle_action(location the_point,sf::Event /*event*/) { break; } x = pick_town_num("select-town-edit.xml",cur_town); - if(x >= 0 && load_town(x,town)){ + if(x >= 0){ cur_town = x; + town = scenario.towns[cur_town]; set_up_main_screen(); } break; @@ -319,7 +315,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { break; case 4: if(option_hit) { - scenario.scen_specials[j] = null_spec_node; + scenario.scen_specials[j] = cSpecial(); } else edit_spec_enc(j,0,nullptr); //get_str(s2,22,scenario.scen_specials[j].type + 1); @@ -329,7 +325,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { break; case 5: if(option_hit) { - current_terrain.specials[j] = null_spec_node; + current_terrain->specials[j] = cSpecial(); } else edit_spec_enc(j,1,nullptr); //get_str(s2,22,current_terrain.specials[j].type + 1); @@ -339,7 +335,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { break; case 6: if(option_hit) { - town->specials[j] = null_spec_node; + town->specials[j] = cSpecial(); } else edit_spec_enc(j,2,nullptr); //get_str(s2,22,town.specials[j].type + 1); @@ -361,7 +357,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { case 8: if(option_hit) { s2 = get_str("outdoor-default", j + 11); - current_terrain.spec_strs[j] = s2; + current_terrain->spec_strs[j] = s2; } else edit_text_str(j,1); //sprintf((char *) str,"%d - %-30.30s",j,(char *) data_store->out_strs[j]); @@ -403,7 +399,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { case 14: if(option_hit) { s2 = get_str("outdoor-default", j + 101); - current_terrain.spec_strs[j] = s2; + current_terrain->spec_strs[j] = s2; } else edit_text_str(j,4); start_string_editing(4,1); @@ -515,11 +511,11 @@ bool handle_action(location the_point,sf::Event /*event*/) { } else { for(x = 0; x < 8; x++) - if(current_terrain.info_rect[x].right == 0) { - current_terrain.info_rect[x] = working_rect; - current_terrain.rect_names[x] = ""; + if(current_terrain->info_rect[x].right == 0) { + current_terrain->info_rect[x] = working_rect; + current_terrain->rect_names[x] = ""; if(!edit_area_rect_str(x,0)) - current_terrain.info_rect[x].right = 0; + current_terrain->info_rect[x].right = 0; x = 500; } @@ -534,8 +530,8 @@ bool handle_action(location the_point,sf::Event /*event*/) { if(mouse_button_held) break; if(!editing_town) { - current_terrain.wandering_locs[mode_count - 1].x = spot_hit.x; - current_terrain.wandering_locs[mode_count - 1].y = spot_hit.y; + current_terrain->wandering_locs[mode_count - 1].x = spot_hit.x; + current_terrain->wandering_locs[mode_count - 1].y = spot_hit.y; } if(editing_town) { town->wandering_locs[mode_count - 1].x = spot_hit.x; @@ -721,7 +717,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { break; case MODE_TOGGLE_SPECIAL_DOT: if(!editing_town){ - current_terrain.special_spot[spot_hit.x][spot_hit.y] = !current_terrain.special_spot[spot_hit.x][spot_hit.y]; + current_terrain->special_spot[spot_hit.x][spot_hit.y] = !current_terrain->special_spot[spot_hit.x][spot_hit.y]; overall_mode = MODE_DRAWING; break; } @@ -748,7 +744,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { case MODE_EYEDROPPER: if(editing_town) set_new_terrain(town->terrain(spot_hit.x,spot_hit.y)); - else set_new_terrain(current_terrain.terrain[spot_hit.x][spot_hit.y]); + else set_new_terrain(current_terrain->terrain[spot_hit.x][spot_hit.y]); set_cursor(wand_curs); overall_mode = MODE_DRAWING; break; @@ -782,8 +778,8 @@ bool handle_action(location the_point,sf::Event /*event*/) { } if(!editing_town) { for(x = 0; x < 8; x++) - if((current_terrain.sign_locs[x].x == spot_hit.x) && (current_terrain.sign_locs[x].y == spot_hit.y)) { - edit_sign(x,scenario.ter_types[current_terrain.terrain[spot_hit.x][spot_hit.y]].picture); + if((current_terrain->sign_locs[x].x == spot_hit.x) && (current_terrain->sign_locs[x].y == spot_hit.y)) { + edit_sign(x,scenario.ter_types[current_terrain->terrain[spot_hit.x][spot_hit.y]].picture); x = 30; } if(x == 8) { @@ -817,8 +813,8 @@ bool handle_action(location the_point,sf::Event /*event*/) { } if(!editing_town) { for(x = 0; x < 18; x++) - if((current_terrain.special_locs[x].x == spot_hit.x) && (current_terrain.special_locs[x].y == spot_hit.y)) { - copied_spec = current_terrain.special_id[x]; + if((current_terrain->special_locs[x].x == spot_hit.x) && (current_terrain->special_locs[x].y == spot_hit.y)) { + copied_spec = current_terrain->special_id[x]; x = 500; } } @@ -846,9 +842,9 @@ bool handle_action(location the_point,sf::Event /*event*/) { break; } for(x = 0; x < 18; x++) - if(current_terrain.special_locs[x].x == 100) { - current_terrain.special_locs[x] = spot_hit; - current_terrain.special_id[x] = copied_spec ; + if(current_terrain->special_locs[x].x == 100) { + current_terrain->special_locs[x] = spot_hit; + current_terrain->special_id[x] = copied_spec; x = 500; } } @@ -869,8 +865,8 @@ bool handle_action(location the_point,sf::Event /*event*/) { } if(!editing_town) { for(x = 0; x < 18; x++) - if((current_terrain.special_locs[x].x == spot_hit.x) && (current_terrain.special_locs[x].y == spot_hit.y)) { - current_terrain.special_locs[x].x = 100; + if((current_terrain->special_locs[x].x == spot_hit.x) && (current_terrain->special_locs[x].y == spot_hit.y)) { + current_terrain->special_locs[x].x = 100; x = 500; } } @@ -1298,11 +1294,11 @@ void swap_terrain() { for(i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) for(j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][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) town->terrain(i,j) = b; - else current_terrain.terrain[i][j] = b; + else current_terrain->terrain[i][j] = b; } } @@ -1507,7 +1503,7 @@ bool is_wall(short i,short j) { bool answer = false; short pic; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; pic = scenario.ter_types[ter].picture; if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) @@ -1537,7 +1533,7 @@ bool is_correctable_wall(short i,short j) { bool answer = false; short k; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) return false; if(!editing_town && ((i < 0) || (i > 47) || (j < 0) || (j > 47))) @@ -1554,7 +1550,7 @@ bool is_mountain(short i,short j) { short pic; ter_num_t ter; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; pic = scenario.ter_types[ter].picture; if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) return true; @@ -1576,7 +1572,7 @@ bool is_hill(short i,short j) { short pic; ter_num_t ter; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; pic = scenario.ter_types[ter].picture; if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) return true; @@ -1606,7 +1602,7 @@ bool is_erasable_water(short i,short j) { short pic; ter_num_t ter; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; pic = scenario.ter_types[ter].picture; if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) return false; @@ -1623,7 +1619,7 @@ bool is_water(short i,short j) { short pic; ter_num_t ter; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; pic = scenario.ter_types[ter].picture; if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) return true; @@ -1640,7 +1636,7 @@ bool is_correctable_water(short i,short j) { short pic; ter_num_t ter; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; pic = scenario.ter_types[ter].picture; if((editing_town) && ((i < 0) || (i > town->max_dim() - 1) || (j < 0) || (j > town->max_dim() - 1))) return false; @@ -1663,7 +1659,7 @@ void shy_change_circle_terrain(location center,short radius,ter_num_t terrain_ty for(j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { l.x = i; l.y = j; - ter = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + ter = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; if((dist(center,l) <= radius) && (get_ran(1,1,20) <= probability) && (ter < 5)) set_terrain(l,terrain_type); @@ -1727,7 +1723,7 @@ void frill_up_terrain() { for(i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) for(j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { - terrain_type = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + terrain_type = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; if((terrain_type == 2) && (get_ran(1,1,20) < 3)) terrain_type = 3; @@ -1739,7 +1735,7 @@ void frill_up_terrain() { terrain_type = 37; if(editing_town) town->terrain(i,j) = terrain_type; - else current_terrain.terrain[i][j] = terrain_type; + else current_terrain->terrain[i][j] = terrain_type; } draw_terrain(); } @@ -1750,7 +1746,7 @@ void unfrill_terrain() { for(i = 0; i < ((editing_town) ? town->max_dim() : 48); i++) for(j = 0; j < ((editing_town) ? town->max_dim() : 48); j++) { - terrain_type = (editing_town) ? town->terrain(i,j) : current_terrain.terrain[i][j]; + terrain_type = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j]; if(terrain_type == 3) terrain_type = 2; if(terrain_type == 4) @@ -1761,7 +1757,7 @@ void unfrill_terrain() { terrain_type = 36; if(editing_town) town->terrain(i,j) = terrain_type; - else current_terrain.terrain[i][j] = terrain_type; + else current_terrain->terrain[i][j] = terrain_type; } draw_terrain(); } @@ -1786,7 +1782,7 @@ ter_num_t get_ground_from_ter(ter_num_t ter){ bool terrain_matches(unsigned char x, unsigned char y, ter_num_t ter){ ter_num_t ter2; - if(editing_town) ter2 = town->terrain(x,y); else ter2 = current_terrain.terrain[x][y]; + if(editing_town) ter2 = town->terrain(x,y); else ter2 = current_terrain->terrain[x][y]; if(ter2 == ter) return true; if(scenario.ter_types[ter2].ground_type != scenario.ter_types[ter].ground_type) return false; @@ -1823,7 +1819,7 @@ void set_terrain(location l,ter_num_t terrain_type) { if(editing_town) town->terrain(i,j) = terrain_type; - else current_terrain.terrain[i][j] = terrain_type; + else current_terrain->terrain[i][j] = terrain_type; l2 = l; // Large objects (eg rubble) @@ -1837,7 +1833,7 @@ void set_terrain(location l,ter_num_t terrain_type) { for(j = 0; j < obj_dim.y; j++){ if(editing_town) town->terrain(l2.x + i,l2.y + j) = find_object_part(q,i,j,terrain_type); - else current_terrain.terrain[l2.x + i][l2.y + j] = find_object_part(q,i,j,terrain_type); + else current_terrain->terrain[l2.x + i][l2.y + j] = find_object_part(q,i,j,terrain_type); } } @@ -1876,11 +1872,11 @@ void set_terrain(location l,ter_num_t terrain_type) { else { l2.x = i; l2.y = j; - ter = (editing_town) ? town->terrain(l2.x,l2.y) : current_terrain.terrain[l2.x][l2.y]; + ter = editing_town ? town->terrain(l2.x,l2.y) : current_terrain->terrain[l2.x][l2.y]; if((!is_mountain(l2.x,l2.y)) && (ter < 5)) { if(editing_town) town->terrain(l2.x,l2.y) = 36; - else current_terrain.terrain[l2.x][l2.y] = 36; + else current_terrain->terrain[l2.x][l2.y] = 36; } } } @@ -1938,26 +1934,26 @@ void set_terrain(location l,ter_num_t terrain_type) { } for(i = 0; i < 8; i++) if(which_sign < 0) { - if((current_terrain.sign_locs[i].x == l.x) && (current_terrain.sign_locs[i].y == l.y)) + if((current_terrain->sign_locs[i].x == l.x) && (current_terrain->sign_locs[i].y == l.y)) which_sign = i; } for(i = 0; i < 8; i++) if(which_sign < 0) { - if(current_terrain.sign_locs[i].x == 100) + if(current_terrain->sign_locs[i].x == 100) which_sign = i; else { - ter = current_terrain.terrain[current_terrain.sign_locs[i].x][current_terrain.sign_locs[i].y]; + ter = current_terrain->terrain[current_terrain->sign_locs[i].x][current_terrain->sign_locs[i].y]; if(scenario.ter_types[ter].special != eTerSpec::IS_A_SIGN) which_sign = i; } } if(which_sign >= 0) { - current_terrain.sign_locs[which_sign] = l; + current_terrain->sign_locs[which_sign] = l; edit_sign(which_sign,scenario.ter_types[terrain_type].picture); sign_error_received = false; } else { - current_terrain.terrain[l.x][l.y] = current_ground; + current_terrain->terrain[l.x][l.y] = current_ground; if(!sign_error_received) { giveError("Towns can have at most 15 signs. Outdoor sections can have at most 8. When the party looks at this sign, they will get no message."); sign_error_received = true; @@ -2369,21 +2365,21 @@ bool out_fix_rubble(location l) { if((l.x < 0) || (l.y > 47) || (l.y < 0) || (l.y > 47)) return false; - terrain_type = current_terrain.terrain[l.x][l.y]; - if((terrain_type == 85) && (current_terrain.terrain[l.x + 1][l.y] != 86)) { - current_terrain.terrain[l.x][l.y] = 0; + terrain_type = current_terrain->terrain[l.x][l.y]; + if((terrain_type == 85) && (current_terrain->terrain[l.x + 1][l.y] != 86)) { + current_terrain->terrain[l.x][l.y] = 0; return true; } - if((terrain_type == 86) && (current_terrain.terrain[l.x - 1][l.y] != 85)) { - current_terrain.terrain[l.x][l.y] = 0; + if((terrain_type == 86) && (current_terrain->terrain[l.x - 1][l.y] != 85)) { + current_terrain->terrain[l.x][l.y] = 0; return true; } - if((terrain_type == 88) && (current_terrain.terrain[l.x + 1][l.y] != 89)) { - current_terrain.terrain[l.x][l.y] = 2; + if((terrain_type == 88) && (current_terrain->terrain[l.x + 1][l.y] != 89)) { + current_terrain->terrain[l.x][l.y] = 2; return true; } - if((terrain_type == 89) && (current_terrain.terrain[l.x - 1][l.y] != 88)) { - current_terrain.terrain[l.x][l.y] = 2; + if((terrain_type == 89) && (current_terrain->terrain[l.x - 1][l.y] != 88)) { + current_terrain->terrain[l.x][l.y] = 2; return true; } return false; @@ -2398,7 +2394,7 @@ bool out_fix_cave(location l) { return false; i = l.x; j = l.y; - store_ter = current_terrain.terrain[l.x][l.y]; + store_ter = current_terrain->terrain[l.x][l.y]; if(is_correctable_wall(i,j)) { if(((l.x == 0) || (l.x == 47)) && ((l.y == 0) || (l.y == 47))) @@ -2471,10 +2467,10 @@ bool out_fix_cave(location l) { } } ter_to_fix += 3; - current_terrain.terrain[i][j] = ter_to_fix; + current_terrain->terrain[i][j] = ter_to_fix; } - if(store_ter == current_terrain.terrain[l.x][l.y]) + if(store_ter == current_terrain->terrain[l.x][l.y]) return false; else return true; @@ -2490,7 +2486,7 @@ bool out_fix_mountain(location l) { return false; i = l.x; j = l.y; - store_ter = current_terrain.terrain[l.x][l.y]; + store_ter = current_terrain->terrain[l.x][l.y]; if((store_ter >= 22) && (store_ter <= 35) && (store_ter != 23)) { @@ -2563,10 +2559,10 @@ bool out_fix_mountain(location l) { } } - current_terrain.terrain[i][j] = ter_to_fix; + current_terrain->terrain[i][j] = ter_to_fix; } - if(store_ter == current_terrain.terrain[l.x][l.y]) + if(store_ter == current_terrain->terrain[l.x][l.y]) return false; else return true; @@ -2581,10 +2577,10 @@ bool out_fix_hill(location l) { return false; i = l.x; j = l.y; - store_ter = current_terrain.terrain[l.x][l.y]; + store_ter = current_terrain->terrain[l.x][l.y]; - if((current_terrain.terrain[l.x][l.y] >= 36) && - (current_terrain.terrain[l.x][l.y] <= 49) ) { + if((current_terrain->terrain[l.x][l.y] >= 36) && + (current_terrain->terrain[l.x][l.y] <= 49) ) { if(((l.x == 0) || (l.x == 47)) && ((l.y == 0) || (l.y == 47))) ter_to_fix = 22; else if((l.x == 0) || (l.x == 47)) { @@ -2657,11 +2653,11 @@ bool out_fix_hill(location l) { ter_to_fix += 14; //if((ter_to_fix == 36) && (get_ran(1,0,15) == 5)) // ter_to_fix++; - if((current_terrain.terrain[i][j] != 37) || (ter_to_fix != 36)) - current_terrain.terrain[i][j] = ter_to_fix; + if((current_terrain->terrain[i][j] != 37) || (ter_to_fix != 36)) + current_terrain->terrain[i][j] = ter_to_fix; } - if(store_ter == current_terrain.terrain[l.x][l.y]) + if(store_ter == current_terrain->terrain[l.x][l.y]) return false; else return true; @@ -2676,7 +2672,7 @@ bool out_fix_water(location l) { return false; i = l.x; j = l.y; - store_ter = current_terrain.terrain[l.x][l.y]; + store_ter = current_terrain->terrain[l.x][l.y]; if(is_correctable_water(l.x,l.y)) { if(((l.x == 0) || (l.x == 47)) && ((l.y == 0) || (l.y == 47))) @@ -2751,10 +2747,10 @@ bool out_fix_water(location l) { ter_to_fix += 27; if(ter_to_fix == 49) ter_to_fix++; - current_terrain.terrain[i][j] = ter_to_fix; + current_terrain->terrain[i][j] = ter_to_fix; } - if(store_ter == current_terrain.terrain[l.x][l.y]) + if(store_ter == current_terrain->terrain[l.x][l.y]) return false; else return true; @@ -2905,8 +2901,8 @@ void place_edit_special(location loc) { return; } for(i = 0; i < 18; i++) - if((current_terrain.special_locs[i].x == loc.x) && (current_terrain.special_locs[i].y == loc.y)) { - edit_spec_enc(current_terrain.special_id[i],1,nullptr); + if((current_terrain->special_locs[i].x == loc.x) && (current_terrain->special_locs[i].y == loc.y)) { + edit_spec_enc(current_terrain->special_id[i],1,nullptr); i = 500; } if(i < 500) { // new special @@ -2916,13 +2912,13 @@ void place_edit_special(location loc) { return; } for(i = 0; i < 18; i++) - if(current_terrain.special_locs[i].x == 100) { - current_terrain.special_locs[i] = loc; - current_terrain.special_id[i] = spec; + if(current_terrain->special_locs[i].x == 100) { + current_terrain->special_locs[i] = loc; + current_terrain->special_id[i] = spec; edit_spec_enc(spec,1,nullptr); - if(current_terrain.specials[spec].pic < 0) - current_terrain.special_locs[i].x = 100; + if(current_terrain->specials[spec].pic < 0) + current_terrain->special_locs[i].x = 100; i = 500; } if(i < 500) { @@ -2964,18 +2960,18 @@ void set_special(location spot_hit) { return; } for(x = 0; x < 18; x++) - if((current_terrain.special_locs[x].x == spot_hit.x) && (current_terrain.special_locs[x].y == spot_hit.y)) { - y = edit_special_num(1,current_terrain.special_id[x]); - if(y >= 0) current_terrain.special_id[x] = y; + if((current_terrain->special_locs[x].x == spot_hit.x) && (current_terrain->special_locs[x].y == spot_hit.y)) { + y = edit_special_num(1,current_terrain->special_id[x]); + if(y >= 0) current_terrain->special_id[x] = y; x = 500; } if(x < 500) { for(x = 0; x < 18; x++) - if(current_terrain.special_locs[x].x == 100) { - y = edit_special_num(1,current_terrain.special_id[x]); + if(current_terrain->special_locs[x].x == 100) { + y = edit_special_num(1,current_terrain->special_id[x]); if(y >= 0) { - current_terrain.special_locs[x] = spot_hit; - current_terrain.special_id[x] = y; + current_terrain->special_locs[x] = spot_hit; + current_terrain->special_id[x] = y; } x = 500; } @@ -2990,31 +2986,31 @@ void town_entry(location spot_hit) { short x,y; ter_num_t ter; - ter = current_terrain.terrain[spot_hit.x][spot_hit.y]; + ter = current_terrain->terrain[spot_hit.x][spot_hit.y]; if(scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) { giveError("This space isn't a town entrance. Town entrances are marked by a small brown castle icon."); return; } // clean up old town entrys for(x = 0; x < 8; x++) - if(current_terrain.exit_locs[x].x < 100) { - ter = current_terrain.terrain[current_terrain.exit_locs[x].x][current_terrain.exit_locs[x].y]; + if(current_terrain->exit_locs[x].x < 100) { + ter = current_terrain->terrain[current_terrain->exit_locs[x].x][current_terrain->exit_locs[x].y]; if(scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) - current_terrain.exit_locs[x].x = 100; + current_terrain->exit_locs[x].x = 100; } y = -2; for(x = 0; x < 8; x++) - if((current_terrain.exit_locs[x].x == spot_hit.x) && (current_terrain.exit_locs[x].y == spot_hit.y)) { - y = pick_town_num("select-town-enter.xml",current_terrain.exit_dests[x]); - if(y >= 0) current_terrain.exit_dests[x] = y; + if((current_terrain->exit_locs[x].x == spot_hit.x) && (current_terrain->exit_locs[x].y == spot_hit.y)) { + y = pick_town_num("select-town-enter.xml",current_terrain->exit_dests[x]); + if(y >= 0) current_terrain->exit_dests[x] = y; } if(y == -2) { for(x = 0; x < 8; x++) - if(current_terrain.exit_locs[x].x == 100) { + if(current_terrain->exit_locs[x].x == 100) { y = pick_town_num("select-town-enter.xml",0); if(y >= 0) { - current_terrain.exit_dests[x] = y; - current_terrain.exit_locs[x] = spot_hit; + current_terrain->exit_dests[x] = y; + current_terrain->exit_locs[x] = spot_hit; } x = 500; } @@ -3117,7 +3113,7 @@ void start_out_edit() { reset_lb(); sprintf(message,"Editing outdoors (%d,%d)",cur_out.x,cur_out.y); set_lb(0,2,message,0); - set_lb(NLS - 3,1,current_terrain.out_name.c_str(),0); + set_lb(NLS - 3,1,current_terrain->out_name.c_str(),0); set_lb(NLS - 2,1,"(Click border to scroll view.)",0); set_lb(NLS - 1,11,"Back to Main Menu",0); overall_mode = MODE_DRAWING; @@ -3132,9 +3128,9 @@ void start_out_edit() { copied_spec = -1; for(i = 0; i < 48; i++) for(j = 0; j < 48; j++) - if(current_terrain.terrain[i][j] == 0) + if(current_terrain->terrain[i][j] == 0) current_ground = 0; - else if(current_terrain.terrain[i][j] == 2) + else if(current_terrain->terrain[i][j] == 2) current_ground = 2; } @@ -3264,7 +3260,7 @@ void start_string_editing(short mode,short just_redo_text) { set_rb(i,7000 + i,(char *) str,0); break; case 1: - sprintf((char *) str,"%d - %-30.30s",i,current_terrain.spec_strs[i].c_str()); + sprintf((char *) str,"%d - %-30.30s",i,current_terrain->spec_strs[i].c_str()); set_rb(i,8000 + i,(char *) str,0); break; case 2: @@ -3276,7 +3272,7 @@ void start_string_editing(short mode,short just_redo_text) { set_rb(i,11000 + i,str,0); break; case 4: // TODO: This is currently inaccessible - add menu option? - sprintf((char *) str,"%d - %-30.30s",i,current_terrain.sign_strs[i].c_str()); + sprintf((char *) str,"%d - %-30.30s",i,current_terrain->sign_strs[i].c_str()); set_rb(i,14000 + i,str,0); break; case 5: // TODO: This is currently inaccessible - add menu option? @@ -3323,7 +3319,7 @@ void start_special_editing(short mode,short just_redo_text) { set_rb(i,4000 + i,(char *) str,0); break; case 1: - s2 = get_str("special-node-names",int(current_terrain.specials[i].type) + 1); + s2 = get_str("special-node-names",int(current_terrain->specials[i].type) + 1); sprintf((char *) str,"%d - %-30.30s",i,s2.c_str()); set_rb(i,5000 + i,(char *) str,0); break; @@ -3408,7 +3404,7 @@ ter_num_t coord_to_ter(short x,short y) { if(editing_town) what_terrain = town->terrain(x,y); - else what_terrain = current_terrain.terrain[x][y]; + else what_terrain = current_terrain->terrain[x][y]; return what_terrain; } diff --git a/osx/scenedit/scen.core.cpp b/osx/scenedit/scen.core.cpp index ed1c0b7e..e6f8752f 100644 --- a/osx/scenedit/scen.core.cpp +++ b/osx/scenedit/scen.core.cpp @@ -23,6 +23,7 @@ extern short cen_x, cen_y,/* overall_mode,*/cur_town; extern bool mouse_button_held; extern short cur_viewing_mode; extern cTown* town; +extern cOutdoors* current_terrain; extern short max_dim[3]; extern short mode_count,to_create; extern ter_num_t template_terrain[64][64]; @@ -33,107 +34,6 @@ extern cSpeech null_talk_node; extern location cur_out; extern short start_volume, start_dir; -void init_scenario() { - short i; - rectangle dummy_rect; - std::string temp_str; - cVehicle null_boat;// = {{0,0},{0,0},{0,0},-1,false,false}; - cVehicle null_horse;// = {{0,0},{0,0},{0,0},-1,false,false}; - cScenario::cItemStorage null_item_s;// ={-1,{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{0,0,0,0,0,0,0,0,0,0},0}; - - scenario.format.ver[0] = 1; - scenario.format.ver[1] = 0; - scenario.format.ver[2] = 0; - scenario.format.min_run_ver = 1; - scenario.format.prog_make_ver[0] = 1; - scenario.format.prog_make_ver[1] = 0; - scenario.format.prog_make_ver[2] = 0; - scenario.num_towns = 1; - scenario.out_width = 1; - scenario.out_height = 1; - scenario.difficulty = 0; - scenario.intro_pic = 0; - scenario.default_ground = 1; - for(i = 0; i < 200; i++) { - scenario.town_size[i] = 1; - scenario.town_hidden[i] = 0; - scenario.town_data_size[i][0] = 0; - scenario.town_data_size[i][1] = 0; - scenario.town_data_size[i][2] = 0; - scenario.town_data_size[i][3] = 0; - scenario.town_data_size[i][4] = 0; - } - scenario.intro_mess_len = 0; - scenario.where_start.x = 24; - scenario.where_start.y = 24; - scenario.out_sec_start.x = 0; - scenario.out_sec_start.y = 0; - scenario.out_start = scenario.where_start; - scenario.which_town_start = 0; - for(i = 0; i < 10; i++) { - scenario.town_to_add_to[i] = -1; - scenario.flag_to_add_to_town[i][0] = 0; - scenario.flag_to_add_to_town[i][1] = 0; - } - for(i = 0; i < 100; i++) { - scenario.out_data_size[i][0] = 0; - scenario.out_data_size[i][1] = 0; - } - for(i = 0; i < 3; i++) { - scenario.store_item_rects[i] = dummy_rect; - scenario.store_item_towns[i] = -1; - } - for(i = 0; i < 50; i++) { - scenario.special_items[i].flags = 0; - scenario.special_items[i].special = -1; - } - scenario.rating = 0; - scenario.uses_custom_graphics = 0; - for(i = 0; i < 256; i++) { - scenario.scen_monsters[i] = cMonster(); - } - for(i = 0; i < 30; i++) { - scenario.boats[i] = null_boat; - scenario.horses[i] = null_horse; - } - for(i = 0; i < 256; i++) { - scenario.ter_types[i] = cTerrain(); - - scenario.scen_specials[i] = null_spec_node; - } - for(i = 0; i < 20; i++) { - scenario.scenario_timer_times[i] = 0; - scenario.scenario_timer_specs[i] = -1; - } - for(i = 0; i < 10; i++) { - scenario.storage_shortcuts[i] = null_item_s; - } - scenario.last_out_edited.x = 0; - scenario.last_out_edited.y = 0; - scenario.last_town_edited = 0; - for(i = 0; i < 400; i++) { - scenario.scen_items[i] = cItemRec(); - } - for(i = 0; i < 270; i++) { - temp_str = get_str("scen-default",i + 1); - if(i == 0) scenario.scen_name = temp_str; - else if(i == 1 || i == 2) - scenario.who_wrote[i-1] = temp_str; - else if(i == 3) - scenario.contact_info = temp_str; - else if(i >= 4 && i < 10) - scenario.intro_strs[i-4] = temp_str; - else if(i >= 10 && i < 60) - scenario.journal_strs[i-10] = temp_str; - else if(i >= 60 && i < 160) { - if(i % 2 == 0) scenario.special_items[(i-60)/2].name = temp_str; - else scenario.special_items[(i-60)/2].descr = temp_str; - } else if(i >= 260) continue; // These were never ever used, for some reason. - else scenario.spec_strs[i-160] = temp_str; - scenario.scen_str_len[i] = temp_str.length(); - } -} - static bool save_ter_info(cDialog& me, cTerrain& store_ter) { store_ter.picture = me["pict"].getTextAsNum(); @@ -1670,12 +1570,10 @@ bool build_scenario() { filename += ".boes"; if(!edit_make_scen_2(width, height, large, med, small, default_town)) return false; - town = new cMedTown; - init_out(); - init_scenario(); + scenario = cScenario(true); scenario.scen_name = title; if(!default_town) { - init_town(1); + scenario.addTown(); if(!grass) for(i = 0; i < 48; i++) for(j = 0; j < 48; j++) @@ -1690,13 +1588,11 @@ bool build_scenario() { make_new_scenario(filename,width,height,default_town,grass); - // now make sure correct outdoors is in memory, because we're going to be saving scenarios - // for a while overall_mode = MODE_MAIN_SCREEN; + cur_out.x = 0; cur_out.y = 0; - // TODO: Not quite sure if this is actually necessary; if so, need to check what to pass as 2nd param -// load_outdoors(cur_out,0); + current_terrain = scenario.outdoors[0][0]; // TODO: Append i+1 to each town name for(i = 0; i < large; i++) { @@ -1705,7 +1601,7 @@ bool build_scenario() { scenario.town_size[which_town] = 0; scenario.town_hidden[which_town] = 0; cur_town = which_town; - init_town(0); + scenario.addTown(); town->town_name = "Large town"; save_scenario(); } @@ -1715,7 +1611,7 @@ bool build_scenario() { scenario.town_size[which_town] = 1; scenario.town_hidden[which_town] = 0; cur_town = which_town; - init_town(1); + scenario.addTown(); town->town_name = "Medium town"; save_scenario(); } @@ -1725,13 +1621,12 @@ bool build_scenario() { scenario.town_size[which_town] = 2; scenario.town_hidden[which_town] = 0; cur_town = which_town; - init_town(2); + scenario.addTown(); town->town_name = "Small town"; save_scenario(); } - if(load_town(0, town)) cur_town = 0; cur_town = 0; - augment_terrain(cur_out); + town = scenario.towns[0]; update_item_menu(); return false; } diff --git a/osx/scenedit/scen.core.h b/osx/scenedit/scen.core.h index 87db1e6c..13fa6e43 100644 --- a/osx/scenedit/scen.core.h +++ b/osx/scenedit/scen.core.h @@ -1,7 +1,6 @@ class cDialog; -__declspec(deprecated) void init_scenario(); short edit_ter_type(ter_num_t which_ter); short edit_monst_type(short which_monst); cMonster edit_monst_abil(cMonster starting_record,short parent_num); diff --git a/osx/scenedit/scen.fileio.cpp b/osx/scenedit/scen.fileio.cpp index c2887365..4f825ae9 100644 --- a/osx/scenedit/scen.fileio.cpp +++ b/osx/scenedit/scen.fileio.cpp @@ -24,8 +24,7 @@ extern short cur_town;//overall_mode,given_password,user_given_password; extern location cur_out; //extern piles_of_stuff_dumping_type *data_store; //extern cSpeech talking; -extern cOutdoors current_terrain; -extern ter_num_t borders[4][50]; +extern cOutdoors* current_terrain; extern bool change_made; extern cCustomGraphics spec_scen_g; extern bool mac_is_intel; @@ -348,39 +347,6 @@ void save_scenario() { giveError("Sorry, scenario saving is currently disabled."); } -void augment_terrain(location to_create) { - location to_load; - short i,j; - - for(i = 0 ; i < 4; i++) - for(j = 0 ; j < 50; j++) - borders[i][j] = 90; - - to_load = to_create; - if(to_create.y > 0) { - to_load.y--; - load_outdoors(to_load, 1, borders); - } - to_load = to_create; - if(to_create.y < scenario.out_height - 1) { - to_load.y++; - load_outdoors(to_load, 3, borders); - } - - to_load = to_create; - if(to_create.x < scenario.out_width - 1) { - to_load.x++; - load_outdoors(to_load, 2, borders); - } - to_load = to_create; - if(to_create.x > 0) { - to_load.x--; - load_outdoors(to_load, 4, borders); - } -} - - - void create_basic_scenario() { // short i,j,k,num_outdoors; // FSSpec to_load,new_file,dummy_file; @@ -1065,61 +1031,56 @@ void scen_text_dump(){ for(out_sec.x = 0; out_sec.x < scenario.out_width ; out_sec.x++) { for(out_sec.y = 0; out_sec.y < scenario.out_height ; out_sec.y++) { fout << " Section (x = " << (short)out_sec.x << ", y = " << (short)out_sec.y << "):" << endl; - load_outdoors(out_sec,current_terrain); - fout << " Name: " << current_terrain.out_name; - fout << " Comment: " << current_terrain.comment; + fout << " Name: " << scenario.outdoors[out_sec.x][out_sec.y]->out_name; + fout << " Comment: " << scenario.outdoors[out_sec.x][out_sec.y]->comment; for(i = 0; i < 8; i++) - if(current_terrain.rect_names[i][0] != '*') - fout << " Area Rectangle " << i << ": " << current_terrain.rect_names[i] << endl; + if(scenario.outdoors[out_sec.x][out_sec.y]->rect_names[i][0] != '*') + fout << " Area Rectangle " << i << ": " << scenario.outdoors[out_sec.x][out_sec.y]->rect_names[i] << endl; for(i = 0; i < 90; i++) - if(current_terrain.spec_strs[i][0] != '*') - fout << " Message " << i << ": " << current_terrain.spec_strs[i] << endl; + if(scenario.outdoors[out_sec.x][out_sec.y]->spec_strs[i][0] != '*') + fout << " Message " << i << ": " << scenario.outdoors[out_sec.x][out_sec.y]->spec_strs[i] << endl; for(i = 0; i < 8; i++) - if(current_terrain.sign_strs[i][0] != '*') - fout << " Sign " << i << ": " << current_terrain.sign_strs[i] << endl; + if(scenario.outdoors[out_sec.x][out_sec.y]->sign_strs[i][0] != '*') + fout << " Sign " << i << ": " << scenario.outdoors[out_sec.x][out_sec.y]->sign_strs[i] << endl; fout << endl; } } - load_outdoors(cur_out,current_terrain); - augment_terrain(cur_out); fout << "Town Text:" << endl << endl; for(short j = 0; j < scenario.num_towns; j++) { fout << " Town " << j << ':' << endl; fout << " Town Messages:" << endl; - load_town(j,town); - fout << " Name: " << town->town_name << endl; + fout << " Name: " << scenario.towns[i]->town_name << endl; for(i = 0; i < 16; i++) - if(town->rect_names[i][0] != '*') - fout << " Area Rectangle " << i << ": " << town->rect_names[i] << endl; - fout << " Name: " << town->town_name << endl; + if(scenario.towns[i]->rect_names[i][0] != '*') + fout << " Area Rectangle " << i << ": " << scenario.towns[i]->rect_names[i] << endl; + fout << " Name: " << scenario.towns[i]->town_name << endl; for(i = 0; i < 3; i++) - if(town->comment[i][0] != '*') - fout << " Comment " << i << ": " << town->comment[i] << endl; - fout << " Name: " << town->town_name << endl; + if(scenario.towns[i]->comment[i][0] != '*') + fout << " Comment " << i << ": " << scenario.towns[i]->comment[i] << endl; + fout << " Name: " << scenario.towns[i]->town_name << endl; for(i = 0; i < 100; i++) - if(town->spec_strs[i][0] != '*') - fout << " Message " << i << ": " << town->spec_strs[i] << endl; - fout << " Name: " << town->town_name << endl; + if(scenario.towns[i]->spec_strs[i][0] != '*') + fout << " Message " << i << ": " << scenario.towns[i]->spec_strs[i] << endl; + fout << " Name: " << scenario.towns[i]->town_name << endl; for(i = 0; i < 20; i++) - if(town->sign_strs[i][0] != '*') - fout << " Sign " << i << ": " << town->sign_strs[i] << endl; + if(scenario.towns[i]->sign_strs[i][0] != '*') + fout << " Sign " << i << ": " << scenario.towns[i]->sign_strs[i] << endl; fout << endl << " Town Dialogue:" << endl; for(i = 0; i < 10; i++) { - fout << " Personality " << j + i << " (" << town->talking.people[i].title << "): " << endl; - fout << " look: " << town->talking.people[i].look << endl; - fout << " name: " << town->talking.people[i].name << endl; - fout << " job: " << town->talking.people[i].job << endl; - fout << " confused: " << town->talking.people[i].dunno << endl; + fout << " Personality " << j + i << " (" << scenario.towns[i]->talking.people[i].title << "): " << endl; + fout << " look: " << scenario.towns[i]->talking.people[i].look << endl; + fout << " name: " << scenario.towns[i]->talking.people[i].name << endl; + fout << " job: " << scenario.towns[i]->talking.people[i].job << endl; + fout << " confused: " << scenario.towns[i]->talking.people[i].dunno << endl; } for(i = 0; i < 60; i++) { - if(town->talking.talk_nodes[i].str1.length() > 0) - fout << " Node " << i << "a: " << town->talking.talk_nodes[i].str1 << endl; - if(town->talking.talk_nodes[i].str2.length() > 0) - fout << " Node " << i << "b: " << town->talking.talk_nodes[i].str2 << endl; + if(scenario.towns[i]->talking.talk_nodes[i].str1.length() > 0) + fout << " Node " << i << "a: " << scenario.towns[i]->talking.talk_nodes[i].str1 << endl; + if(scenario.towns[i]->talking.talk_nodes[i].str2.length() > 0) + fout << " Node " << i << "b: " << scenario.towns[i]->talking.talk_nodes[i].str2 << endl; } fout << endl; } fout.close(); - load_town(cur_town,town); } diff --git a/osx/scenedit/scen.fileio.h b/osx/scenedit/scen.fileio.h index 740ce57d..e3c99f27 100644 --- a/osx/scenedit/scen.fileio.h +++ b/osx/scenedit/scen.fileio.h @@ -1,9 +1,5 @@ void save_scenario(); -//void load_scenario(); -void augment_terrain(location to_create); -//void load_outdoors(location which_out,short mode); -//void load_town(short which_town); void import_town(short which_town,fs::path temp_file_to_load); void create_basic_scenario(); void make_new_scenario(std::string file_name,short out_width,short out_height,bool making_warriors_grove, diff --git a/osx/scenedit/scen.graphics.cpp b/osx/scenedit/scen.graphics.cpp index f3008dd0..caf7c6ae 100644 --- a/osx/scenedit/scen.graphics.cpp +++ b/osx/scenedit/scen.graphics.cpp @@ -31,7 +31,7 @@ short find_index_spot(); bool is_s_d(); void sort_specials(); -extern cOutdoors current_terrain; +extern cOutdoors* current_terrain; extern sf::RenderWindow mainPtr; extern cTown* current_town; extern short cen_x, cen_y,current_terrain_type,cur_town; @@ -52,7 +52,6 @@ extern rectangle left_button[NLS]; extern rectangle right_buttons[NRSONPAGE]; extern rectangle right_scrollbar_rect; extern rectangle right_area_rect; -extern ter_num_t borders[4][50]; extern std::shared_ptr right_sbar; extern bool left_buttons_active,right_buttons_active; @@ -621,15 +620,26 @@ void draw_terrain(){ t_to_draw = town->terrain(cen_x + q - 4,cen_y + r - 4); } else { - if(cen_x + q - 4 == -1) - t_to_draw = borders[3][cen_y + r - 4]; - else if(cen_x + q - 4 == 48) - t_to_draw = borders[1][cen_y + r - 4]; - else if(cen_y + r - 4 == -1) - t_to_draw = borders[0][cen_x + q - 4]; - else if(cen_y + r - 4 == 48) - t_to_draw = borders[2][cen_x + q - 4]; - else t_to_draw = current_terrain.terrain[cen_x + q - 4][cen_y + r - 4]; + short ter_x = cen_x + q - 4, ter_y = cen_y + r - 4; + if(ter_x == -1 && ter_y == -1 && cur_out.x > 0 && cur_out.y > 0) + t_to_draw = scenario.outdoors[cur_out.x - 1][cur_out.y - 1]->terrain[47][47]; + else if(ter_x == -1 && ter_y == 48 && cur_out.x > 0 && cur_out.y < scenario.out_height - 1) + t_to_draw = scenario.outdoors[cur_out.x - 1][cur_out.y + 1]->terrain[47][0]; + else if(ter_x == 48 && ter_y == -1 && cur_out.x < scenario.out_width - 1 && cur_out.y > 0) + t_to_draw = scenario.outdoors[cur_out.x + 1][cur_out.y - 1]->terrain[0][47]; + else if(ter_x == 48 && ter_y == 48 && cur_out.x < scenario.out_width - 1 && cur_out.y < scenario.out_height - 1) + t_to_draw = scenario.outdoors[cur_out.x + 1][cur_out.y + 1]->terrain[0][0]; + else if(ter_x == -1 && ter_y >= 0 && ter_y < 48 && cur_out.x > 0) + t_to_draw = scenario.outdoors[cur_out.x - 1][cur_out.y]->terrain[47][ter_y]; + else if(ter_y == -1 && ter_x >= 0 && ter_x < 48 && cur_out.y > 0) + t_to_draw = scenario.outdoors[cur_out.x][cur_out.y - 1]->terrain[ter_x][47]; + else if(ter_x == 48 && ter_y >= 0 && ter_y < 48 && cur_out.x < scenario.out_width - 1) + t_to_draw = scenario.outdoors[cur_out.x + 1][cur_out.y]->terrain[0][ter_y]; + else if(ter_y == 48 && ter_x >= 0 && ter_x < 48 && cur_out.y < scenario.out_height - 1) + t_to_draw = scenario.outdoors[cur_out.x][cur_out.y + 1]->terrain[ter_x][0]; + else if(ter_x == -1 || ter_x == 48 || ter_y == -1 || ter_y == 48) + t_to_draw = 90; + else t_to_draw = current_terrain->terrain[ter_x][ter_y]; } draw_one_terrain_spot(q,r,t_to_draw); @@ -687,8 +697,8 @@ void draw_terrain(){ //} if(!editing_town) { for(i = 0; i < 4; i++) - if((cen_x + q - 4 == current_terrain.wandering_locs[i].x) && - (cen_y + r - 4 == current_terrain.wandering_locs[i].y)) { + if((cen_x + q - 4 == current_terrain->wandering_locs[i].x) && + (cen_y + r - 4 == current_terrain->wandering_locs[i].y)) { tiny_from = base_small_button_from; tiny_from.offset(7 * (2),7 * (1)); rect_draw_some_item(editor_mixed,tiny_from,ter_draw_gworld,tiny_to); @@ -799,11 +809,11 @@ void draw_terrain(){ if(!editing_town) { // draw info rects for(i = 0; i < 8; 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); + 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); frame_rect(ter_draw_gworld, draw_rect, sf::Color::Red); } } @@ -832,7 +842,7 @@ void draw_terrain(){ printf("Drawing map for x = %d...%d and y = %d...%d\n", xMin, xMax, yMin, yMax); for(q = xMin; q < xMax; q++) for(r = yMin; r < yMax; r++) { - t_to_draw = editing_town ? town->terrain(q,r) : current_terrain.terrain[q][r]; + t_to_draw = editing_town ? town->terrain(q,r) : current_terrain->terrain[q][r]; draw_one_tiny_terrain_spot(q-xMin,r-yMin,t_to_draw,size); small_what_drawn[q][r] = t_to_draw; } @@ -1274,7 +1284,7 @@ bool is_special(short i,short j) { return true; if(!editing_town) for(k = 0; k < 18; k++) - if((current_terrain.special_locs[k].x == i) && (current_terrain.special_locs[k].y == j)) + if((current_terrain->special_locs[k].x == i) && (current_terrain->special_locs[k].y == j)) return true; return false; @@ -1292,7 +1302,7 @@ void sort_specials() { bool is_spot(short i,short j){ if(editing_town) return is_field_type(i,j,2); - else return current_terrain.special_spot[i][j]; + else return current_terrain->special_spot[i][j]; return false; } diff --git a/osx/scenedit/scen.keydlgs.cpp b/osx/scenedit/scen.keydlgs.cpp index adb53e91..639d7826 100644 --- a/osx/scenedit/scen.keydlgs.cpp +++ b/osx/scenedit/scen.keydlgs.cpp @@ -23,7 +23,7 @@ extern cScenario scenario; extern cSpecial null_spec_node; extern cSpeech null_talk_node; //extern piles_of_stuff_dumping_type *data_store; -extern cOutdoors current_terrain; +extern cOutdoors* current_terrain; extern cCustomGraphics spec_scen_g; std::stack last_node; @@ -37,10 +37,10 @@ std::vector lgdlog_pics = {0,72}; size_t num_strs(short str_mode) { switch(str_mode) { case 0: return scenario.spec_strs.size(); - case 1: return current_terrain.spec_strs.size(); + case 1: return current_terrain->spec_strs.size(); case 2: return town->spec_strs.size(); case 3: return scenario.journal_strs.size(); - case 4: return current_terrain.sign_strs.size(); + case 4: return current_terrain->sign_strs.size(); case 5: return town->sign_strs.size(); } return 0; @@ -190,13 +190,13 @@ static bool edit_text_event_filter(cDialog& me, std::string item_hit, short& whi if(str_mode == 0) scenario.spec_strs[which_str] = newVal; if(str_mode == 1) - current_terrain.spec_strs[which_str] = newVal; + current_terrain->spec_strs[which_str] = newVal; if(str_mode == 2) town->spec_strs[which_str] = newVal; if(str_mode == 3) scenario.journal_strs[which_str] = newVal; if(str_mode == 4) - current_terrain.sign_strs[which_str] = newVal; + current_terrain->sign_strs[which_str] = newVal; if(str_mode == 5) town->sign_strs[which_str] = newVal; if(item_hit == "okay") me.toast(true); @@ -211,13 +211,13 @@ static bool edit_text_event_filter(cDialog& me, std::string item_hit, short& whi if(str_mode == 0) me["text"].setText(scenario.spec_strs[which_str]); if(str_mode == 1) - me["text"].setText(current_terrain.spec_strs[which_str]); + me["text"].setText(current_terrain->spec_strs[which_str]); if(str_mode == 2) me["text"].setText(town->spec_strs[which_str]); if(str_mode == 3) me["text"].setText(scenario.journal_strs[which_str]); if(str_mode == 4) - me["text"].setText(current_terrain.sign_strs[which_str]); + me["text"].setText(current_terrain->sign_strs[which_str]); if(str_mode == 5) me["text"].setText(town->sign_strs[which_str]); return true; @@ -234,13 +234,13 @@ void edit_text_str(short which_str,short mode) { if(mode == 0) dlog["text"].setText(scenario.spec_strs[which_str]); if(mode == 1) - dlog["text"].setText(current_terrain.spec_strs[which_str]); + dlog["text"].setText(current_terrain->spec_strs[which_str]); if(mode == 2) dlog["text"].setText(town->spec_strs[which_str]); if(mode == 3) dlog["text"].setText(scenario.journal_strs[which_str]); if(mode == 4) - dlog["text"].setText(current_terrain.sign_strs[which_str]); + dlog["text"].setText(current_terrain->sign_strs[which_str]); if(mode == 5) dlog["text"].setText(town->sign_strs[which_str]); @@ -253,7 +253,7 @@ static bool edit_area_rect_event_filter(cDialog& me, std::string item_hit, short me.toast(true); std::string str = me["area"].getText().substr(0,29); if(str_mode == 0) - current_terrain.rect_names[which_str]; + current_terrain->rect_names[which_str]; else town->rect_names[which_str]; } else if(item_hit == "cancel") { me.setResult(false); @@ -270,7 +270,7 @@ bool edit_area_rect_str(short which_str,short mode) { dlog.attachClickHandlers(std::bind(edit_area_rect_event_filter, _1, _2, which_str, mode), {"okay", "cancel"}); if(mode == 0) - dlog["area"].setText(current_terrain.rect_names[which_str]); + dlog["area"].setText(current_terrain->rect_names[which_str]); else dlog["area"].setText(town->rect_names[which_str]); dlog.run(); @@ -304,7 +304,7 @@ static bool save_spec_enc(cDialog& me, short which_mode, short which_node) { if(which_mode == 0) scenario.scen_specials[which_node] = store_spec_node; if(which_mode == 1) - current_terrain.specials[which_node] = store_spec_node; + current_terrain->specials[which_node] = store_spec_node; if(which_mode == 2) town->specials[which_node] = store_spec_node; return true; @@ -697,7 +697,7 @@ static bool edit_spec_enc_event_filter(cDialog& me, std::string item_hit, short& if(which_mode == 0) store_spec_node = scenario.scen_specials[which_node]; if(which_mode == 1) - store_spec_node = current_terrain.specials[which_node]; + store_spec_node = current_terrain->specials[which_node]; if(which_mode == 2) store_spec_node = town->specials[which_node]; if(store_spec_node.pic < 0) @@ -718,7 +718,7 @@ bool edit_spec_enc(short which_node,short mode,cDialog* parent) { if(mode == 0) store_spec_node = scenario.scen_specials[which_node]; if(mode == 1) - store_spec_node = current_terrain.specials[which_node]; + store_spec_node = current_terrain->specials[which_node]; if(mode == 2) store_spec_node = town->specials[which_node]; if(store_spec_node.pic < 0) @@ -746,7 +746,7 @@ short get_fresh_spec(short which_mode) { if(which_mode == 0) store_node = scenario.scen_specials[i]; if(which_mode == 1) - store_node = current_terrain.specials[i]; + store_node = current_terrain->specials[i]; if(which_mode == 2) store_node = town->specials[i]; if(store_node.type == eSpecType::NONE && store_node.jumpto == -1 && store_node.pic == -1) @@ -775,7 +775,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short } break; case 1: - if(current_terrain.spec_strs[i][0] == '*') { + if(current_terrain->spec_strs[i][0] == '*') { *str1 = i; i = 500; } @@ -793,7 +793,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short } break; case 4: - if(current_terrain.sign_strs[i][0] == '*') { + if(current_terrain->sign_strs[i][0] == '*') { *str1 = i; i = 500; } @@ -817,7 +817,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short scenario.spec_strs[*str1] = str; break; case 1: - current_terrain.spec_strs[*str1] = str; + current_terrain->spec_strs[*str1] = str; break; case 2: town->spec_strs[*str1] = str; @@ -826,7 +826,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short scenario.journal_strs[*str1] = str; break; case 4: - current_terrain.sign_strs[*str1] = str; + current_terrain->sign_strs[*str1] = str; break; case 5: town->sign_strs[*str1] = str; @@ -847,7 +847,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short } break; case 1: - if(current_terrain.spec_strs[i][0] == '*') { + if(current_terrain->spec_strs[i][0] == '*') { *str2 = i; i = 500; } @@ -865,7 +865,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short } break; case 4: - if(current_terrain.sign_strs[i][0] == '*') { + if(current_terrain->sign_strs[i][0] == '*') { *str2 = i; i = 500; } @@ -890,7 +890,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short scenario.spec_strs[*str2] = str; break; case 1: - current_terrain.spec_strs[*str2] = str; + current_terrain->spec_strs[*str2] = str; break; case 2: town->spec_strs[*str2] = str; @@ -899,7 +899,7 @@ static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short scenario.journal_strs[*str2] = str; break; case 4: - current_terrain.sign_strs[*str2] = str; + current_terrain->sign_strs[*str2] = str; break; case 5: town->sign_strs[*str2] = str; @@ -926,13 +926,13 @@ void edit_spec_text(short mode,short *str1,short *str2,cDialog* parent) { if(mode == 0) edit["str1"].setText(scenario.spec_strs[*str1]); if(mode == 1) - edit["str1"].setText(current_terrain.spec_strs[*str1]); + edit["str1"].setText(current_terrain->spec_strs[*str1]); if(mode == 2) edit["str1"].setText(town->spec_strs[*str1]); if(mode == 3) edit["str1"].setText(scenario.journal_strs[*str1]); if(mode == 4) - edit["str1"].setText(current_terrain.sign_strs[*str1]); + edit["str1"].setText(current_terrain->sign_strs[*str1]); if(mode == 5) edit["str1"].setText(town->sign_strs[*str1]); } @@ -942,13 +942,13 @@ void edit_spec_text(short mode,short *str1,short *str2,cDialog* parent) { if(mode == 0) edit["str2"].setText(scenario.spec_strs[*str2]); if(mode == 1) - edit["str2"].setText(current_terrain.spec_strs[*str2]); + edit["str2"].setText(current_terrain->spec_strs[*str2]); if(mode == 2) edit["str2"].setText(town->spec_strs[*str2]); if(mode == 3) edit["str2"].setText(scenario.journal_strs[*str2]); if(mode == 4) - edit["str2"].setText(current_terrain.sign_strs[*str2]); + edit["str2"].setText(current_terrain->sign_strs[*str2]); if(mode == 5) edit["str2"].setText(town->sign_strs[*str2]); } @@ -969,7 +969,7 @@ static bool edit_dialog_text_event_filter(cDialog& me, std::string item_hit, sho scenario.spec_strs[*str1 + i] = str; break; case 1: - current_terrain.spec_strs[*str1 + i] = str; + current_terrain->spec_strs[*str1 + i] = str; break; case 2: town->spec_strs[*str1 + i] = str; @@ -978,7 +978,7 @@ static bool edit_dialog_text_event_filter(cDialog& me, std::string item_hit, sho scenario.journal_strs[*str1 + i] = str; break; case 4: - current_terrain.sign_strs[*str1 + i] = str; + current_terrain->sign_strs[*str1 + i] = str; break; case 5: town->sign_strs[*str1 + i] = str; @@ -1008,7 +1008,7 @@ void edit_dialog_text(short mode,short *str1,cDialog* parent) { j = 500; break; case 1: - if(current_terrain.spec_strs[j][0] != '*') + if(current_terrain->spec_strs[j][0] != '*') j = 500; break; case 2: @@ -1020,7 +1020,7 @@ void edit_dialog_text(short mode,short *str1,cDialog* parent) { j = 500; break; case 4: - if(current_terrain.sign_strs[j][0] != '*') + if(current_terrain->sign_strs[j][0] != '*') j = 500; break; case 5: @@ -1040,7 +1040,7 @@ void edit_dialog_text(short mode,short *str1,cDialog* parent) { scenario.spec_strs[i] = ""; break; case 1: - current_terrain.spec_strs[i] = ""; + current_terrain->spec_strs[i] = ""; break; case 2: town->spec_strs[i] = ""; @@ -1049,7 +1049,7 @@ void edit_dialog_text(short mode,short *str1,cDialog* parent) { scenario.journal_strs[i] = ""; break; case 4: - current_terrain.sign_strs[i] = ""; + current_terrain->sign_strs[i] = ""; break; case 5: town->sign_strs[i] = ""; @@ -1072,13 +1072,13 @@ void edit_dialog_text(short mode,short *str1,cDialog* parent) { if(mode == 0) edit[id].setText(scenario.spec_strs[*str1 + i]); if(mode == 1) - edit[id].setText(current_terrain.spec_strs[*str1 + i]); + edit[id].setText(current_terrain->spec_strs[*str1 + i]); if(mode == 2) edit[id].setText(town->spec_strs[*str1 + i]); if(mode == 0) edit[id].setText(scenario.journal_strs[*str1 + i]); if(mode == 1) - edit[id].setText(current_terrain.sign_strs[*str1 + i]); + edit[id].setText(current_terrain->sign_strs[*str1 + i]); if(mode == 2) edit[id].setText(town->sign_strs[*str1 + i]); } diff --git a/osx/scenedit/scen.main.cpp b/osx/scenedit/scen.main.cpp index a2146369..833fe318 100644 --- a/osx/scenedit/scen.main.cpp +++ b/osx/scenedit/scen.main.cpp @@ -21,8 +21,6 @@ #include "dlogutil.h" #include "scen.menus.h" -cUniverse univ; // not needed; just to silence the compiler - /* Globals */ bool All_Done = false; // delete play_sounds sf::Event event; @@ -35,15 +33,12 @@ short cen_x, cen_y; eScenMode overall_mode = MODE_INTRO_SCREEN; std::shared_ptr right_sbar; short mode_count = 0; -cOutdoors current_terrain; +cOutdoors* current_terrain; //cSpeech talking; //short given_password; //short user_given_password = -1; short pixel_depth,old_depth = 8; -ter_num_t border1 = 90, border2 = 90; // kludgy thing ... leave right here, before borders -ter_num_t borders[4][50]; - bool change_made = false; // Numbers of current areas being edited @@ -106,9 +101,6 @@ int main(int, char* argv[]) { run_startup_g(); init_lb(); init_rb(); - init_town(1); - init_out(); - init_scenario(); make_cursor_sword(); @@ -238,13 +230,11 @@ void handle_file_menu(int item_hit) { switch(item_hit) { case 1: // open file_to_load = nav_get_scenario(); - if(!file_to_load.empty() && load_scenario(file_to_load)) { - if(load_town(scenario.last_town_edited,town)) - cur_town = scenario.last_town_edited; - if(load_outdoors(scenario.last_out_edited,current_terrain)){ - cur_out = scenario.last_out_edited; - augment_terrain(cur_out); - } + if(!file_to_load.empty() && load_scenario(file_to_load, scenario)) { + cur_town = scenario.last_town_edited; + town = scenario.towns[cur_town]; + cur_out = scenario.last_out_edited; + current_terrain = scenario.outdoors[cur_out.x][cur_out.y]; overall_mode = MODE_MAIN_SCREEN; change_made = false; update_item_menu(); @@ -560,7 +550,6 @@ void Mouse_Pressed() { } void close_program() { - if(town != NULL) delete town; } // TODO: Remove this function and replace it with beep() or play_sound() everywhere. diff --git a/osx/scenedit/scen.townout.cpp b/osx/scenedit/scen.townout.cpp index 47a70ef4..ff3293c7 100644 --- a/osx/scenedit/scen.townout.cpp +++ b/osx/scenedit/scen.townout.cpp @@ -26,8 +26,7 @@ extern cScenario scenario; extern cSpecial null_spec_node; extern cSpeech::cNode null_talk_node; //extern piles_of_stuff_dumping_type *data_store; -extern cOutdoors current_terrain; -extern ter_num_t borders[4][50]; +extern cOutdoors* current_terrain; extern location cur_out; //extern cSpeech talking; @@ -44,78 +43,6 @@ short store_which_talk_node,last_talk_node[60]; cSpeech::cNode store_talk_node; location store_cur_loc; -void init_town(short size) { - short i,j; - std::string temp_str; - if(size == 0) town = new cBigTown; - else if(size == 1) town = new cMedTown; - else if(size == 2) town = new cTinyTown; - else return; - for(i = 0; i < 180; i++) { - temp_str = get_str("town-default",i + 1); - if(i == 0) town->town_name = temp_str; - else if(i >= 1 && i < 17) - town->rect_names[i-1] = temp_str; - else if(i >= 17 && i < 20) - town->comment[i-17] = temp_str; - else if(i >= 20 && i < 120) - town->spec_strs[i-20] = temp_str; - else if(i >= 120 && i < 140) - town->sign_strs[i-120] = temp_str; - town->strlens[i] = temp_str.length(); - } - for(i = 0; i < town->max_dim(); i++) - for(j = 0; j < town->max_dim(); j++) { - town->terrain(i,j) = scenario.default_ground * 2; - town->lighting(i / 8,j) = 0; - } - - for(i = 0; i < 200; i++) - town->talking.strlens[i] = 0; - for(i = 0; i < 10; i++) { - town->talking.people[i].title = "Unused"; - town->talking.people[i].look = ""; - town->talking.people[i].name = ""; - town->talking.people[i].job = ""; - town->talking.people[i].dunno = ""; - } - for(i = 0; i < 60; i++) { - town->talking.talk_nodes[i].personality = -1; - town->talking.talk_nodes[i].type = 0; - town->talking.talk_nodes[i].extras[0] = 0; - town->talking.talk_nodes[i].extras[1] = 0; - town->talking.talk_nodes[i].extras[2] = 0; - town->talking.talk_nodes[i].extras[3] = -1; - town->talking.talk_nodes[i].str1 = ""; - town->talking.talk_nodes[i].str2 = ""; - for(j = 0; j < 4; j++) { - town->talking.talk_nodes[i].link1[j] = 'x'; - town->talking.talk_nodes[i].link2[j] = 'x'; - } - } -} - -void init_out() { - short i,j; - std::string temp_str; - - for(i = 0; i < 4; i++) - for(j = 0; j < 50; j++) - borders[i][j] = 90; - - for(i = 0; i < 120; i++) { - temp_str = get_str("outdoor-default",i + 1); - if(i == 0) current_terrain.out_name = temp_str; - else if(i == 9) current_terrain.comment = temp_str; - else if(i < 9) current_terrain.rect_names[i-1] = temp_str; - else if(i >= 10 && i < 100) - current_terrain.spec_strs[i-10] = temp_str; - else if(i >= 100 && i < 108) - current_terrain.sign_strs[i-100] = temp_str; - current_terrain.strlens[i] = temp_str.length(); - } -} - static void put_placed_monst_in_dlog(cDialog& me) { me["num"].setTextToNum(store_which_placed_monst); me["type"].setText(scenario.scen_monsters[store_placed_monst.number].m_name); @@ -328,7 +255,7 @@ static bool edit_sign_event_filter(cDialog& me, short which_sign) { if(!me.toast(true)) return true; if(editing_town) town->sign_strs[which_sign] = me["text"].getText(); - else current_terrain.sign_strs[which_sign] = me["text"].getText(); + else current_terrain->sign_strs[which_sign] = me["text"].getText(); #if 0 // TODO: Apparently there used to be left/right buttons on this dialog. if(item_hit == 3) store_which_sign--; @@ -357,7 +284,7 @@ void edit_sign(short which_sign,short picture) { sign_dlg["num"].setTextToNum(which_sign); if(!editing_town) - sign_dlg["text"].setText(current_terrain.sign_strs[which_sign]); + sign_dlg["text"].setText(current_terrain->sign_strs[which_sign]); else sign_dlg["text"].setText(town->sign_strs[which_sign]); sign_dlg.run(); @@ -373,9 +300,9 @@ static bool save_roomdescs(cDialog& me, bool isTown, bool str_do_delete[]) { if(str_do_delete[i]) town->room_rect(i).right = 0; } else { - current_terrain.rect_names[i] = me[id].getText().substr(0,30); + current_terrain->rect_names[i] = me[id].getText().substr(0,30); if(str_do_delete[i]) - current_terrain.info_rect[i].right = 0; + current_terrain->info_rect[i].right = 0; } } return true; @@ -388,7 +315,7 @@ static void put_roomdescs_in_dlog(cDialog& me, bool isTown, bool str_do_delete[] std::ostringstream str; bool active = true; if(isTown && town->room_rect(i).right == 0) active = false; - if(!isTown && current_terrain.info_rect[i].right == 0) active = false; + if(!isTown && current_terrain->info_rect[i].right == 0) active = false; if(str_do_delete[i]) active = false; if(!active) { str << "Not yet placed."; @@ -397,8 +324,8 @@ static void put_roomdescs_in_dlog(cDialog& me, bool isTown, bool str_do_delete[] me["desc" + id].setText(town->rect_names[i]); str << "X = " << town->room_rect(i).left << ", Y = " << town->room_rect(i).top; } else { - me["desc" + id].setText(current_terrain.rect_names[i]); - str << "X = " << current_terrain.info_rect[i].left << ", Y = " << current_terrain.info_rect[i].top; + me["desc" + id].setText(current_terrain->rect_names[i]); + str << "X = " << current_terrain->info_rect[i].left << ", Y = " << current_terrain->info_rect[i].top; } me["rect" + id].setText(str.str()); } @@ -488,8 +415,8 @@ 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.comment = me["comment"].getText(); + current_terrain->out_name = me["name"].getText(); + current_terrain->comment = me["comment"].getText(); return true; } @@ -500,8 +427,8 @@ void outdoor_details() { out_dlg["okay"].attachClickHandler(outdoor_details_event_filter); snprintf(temp_str,256,"X = %d, Y = %d",cur_out.x,cur_out.y); out_dlg["loc"].setText(temp_str); - out_dlg["comment"].setText(current_terrain.comment); - out_dlg["name"].setText(current_terrain.out_name); + out_dlg["comment"].setText(current_terrain->comment); + out_dlg["name"].setText(current_terrain->out_name); out_dlg.run(); } @@ -548,10 +475,10 @@ static void save_out_wand(cDialog& me, short store_which_out_wand, cOutdoors::cW switch(mode) { case 0: - current_terrain.wandering[store_which_out_wand] = store_out_wand; + current_terrain->wandering[store_which_out_wand] = store_out_wand; break; case 1: - current_terrain.special_enc[store_which_out_wand] = store_out_wand; + current_terrain->special_enc[store_which_out_wand] = store_out_wand; break; } } @@ -564,13 +491,13 @@ static bool edit_out_wand_event_filter(cDialog& me, std::string item_hit, short& me.untoast(); store_which_out_wand--; if(store_which_out_wand < 0) store_which_out_wand = 3; - store_out_wand = (mode == 0) ? current_terrain.wandering[store_which_out_wand] : current_terrain.special_enc[store_which_out_wand]; + store_out_wand = (mode == 0) ? current_terrain->wandering[store_which_out_wand] : current_terrain->special_enc[store_which_out_wand]; put_out_wand_in_dlog(me, store_which_out_wand, store_out_wand); } else if(item_hit == "right") { me.untoast(); store_which_out_wand++; if(store_which_out_wand > 3) store_which_out_wand = 0; - store_out_wand = (mode == 0) ? current_terrain.wandering[store_which_out_wand] : current_terrain.special_enc[store_which_out_wand]; + store_out_wand = (mode == 0) ? current_terrain->wandering[store_which_out_wand] : current_terrain->special_enc[store_which_out_wand]; put_out_wand_in_dlog(me, store_which_out_wand, store_out_wand); } return true; @@ -616,7 +543,7 @@ void edit_out_wand(short mode) { using namespace std::placeholders; short which_out_wand = 0; - cOutdoors::cWandering store_out_wand = (mode == 0) ? current_terrain.wandering[0] : current_terrain.special_enc[0]; + cOutdoors::cWandering store_out_wand = (mode == 0) ? current_terrain->wandering[0] : current_terrain->special_enc[0]; cDialog wand_dlg("edit-outdoor-encounter.xml"); wand_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, &wand_dlg, false)); diff --git a/osx/scenedit/scen.townout.h b/osx/scenedit/scen.townout.h index a9f22406..5e6f6888 100644 --- a/osx/scenedit/scen.townout.h +++ b/osx/scenedit/scen.townout.h @@ -1,5 +1,4 @@ -__declspec(deprecated) void init_town(short size); -__declspec(deprecated) void init_out(); + void edit_placed_monst(short which_m); cCreature edit_placed_monst_adv(cCreature monst_record, class cDialog& parent); void edit_sign(short which_sign,short picture); diff --git a/osx/tools/fileio.cpp b/osx/tools/fileio.cpp index d4d779d7..a367e7e4 100644 --- a/osx/tools/fileio.cpp +++ b/osx/tools/fileio.cpp @@ -24,14 +24,25 @@ #include "tarball.hpp" bool cur_scen_is_mac = true, mac_is_intel; -extern cScenario scenario; extern sf::Texture items_gworld,tiny_obj_gworld,fields_gworld,roads_gworld,boom_gworld,missiles_gworld; extern sf::Texture dlogpics_gworld,monst_gworld[],terrain_gworld[],anim_gworld,talkfaces_gworld,pc_gworld; extern sf::Texture status_gworld, vehicle_gworld, small_ter_gworld; extern cCustomGraphics spec_scen_g; -extern cUniverse univ; fs::path progDir, tempDir; +void load_spec_graphics(fs::path scen_file); +// Load old scenarios (town talk is handled by the town loading function) +static bool load_scenario_v1(fs::path file_to_load, cScenario& scenario); +static bool load_outdoors_v1(fs::path scen_file, location which_out,cOutdoors& the_out, cScenario& scenario); +static bool load_town_v1(fs::path scen_file, short which_town, cTown& the_town, legacy::scenario_data_type& scenario); +// Load new scenarios +static bool load_outdoors(fs::path out_base, location which_out, cOutdoors& the_out); +static bool load_town(fs::path town_base, short which_town, cTown*& the_town); +static bool load_town_talk(fs::path town_base, short which_town, cSpeech& the_talk); +// Load saved games +static bool load_party_v1(fs::path file_to_load, cUniverse& univ, bool town_restore, bool in_scen, bool maps_there, bool must_port); +static bool load_party_v2(fs::path file_to_load, cUniverse& univ, bool town_restore, bool in_scen, bool maps_there); + #include void init_directories(const char* exec_path) { @@ -73,7 +84,13 @@ void check_for_intel() { mac_is_intel = endian.c; } -bool load_scenario(fs::path file_to_load, bool skip_strings){ +bool load_scenario(fs::path file_to_load, cScenario& scenario) { + scenario = cScenario(); + // TODO: Implement checking to determine whether it's old or new + return load_scenario_v1(file_to_load, scenario); +} + +bool load_scenario_v1(fs::path file_to_load, cScenario& scenario){ short i,n; bool file_ok = false; long len; @@ -129,10 +146,9 @@ bool load_scenario(fs::path file_to_load, bool skip_strings){ return false; } port_item_list(item_data); - scenario = *temp_scenario; + scenario.append(*temp_scenario); scenario.append(*item_data); - if(!skip_strings) { // TODO: Consider skipping the fread and assignment when len is 0 for(i = 0; i < 270; i++) { len = (long) (temp_scenario->scen_str_len[i]); @@ -153,20 +169,40 @@ bool load_scenario(fs::path file_to_load, bool skip_strings){ } else if(i >= 260) continue; // These were never ever used, for some reason. else scenario.spec_strs[i-160] = temp_str; } - } fclose(file_id); scenario.ter_types[23].fly_over = false; - delete temp_scenario; - delete item_data; scenario.scen_file = file_to_load; - load_spec_graphics(); + load_spec_graphics(scenario.scen_file); + + // Now load all the outdoor sectors + scenario.outdoors.resize(scenario.out_width, scenario.out_height); + for(int x = 0; x < scenario.out_width; x++) { + for(int y = 0; y < scenario.out_height; y++) { + scenario.outdoors[x][y] = new cOutdoors(scenario); + load_outdoors_v1(scenario.scen_file, loc(x,y), *scenario.outdoors[x][y], scenario); + } + } + + // Then load all the towns + scenario.towns.resize(scenario.num_towns); + for(int i = 0; i < scenario.num_towns; i++) { + switch(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; + } + load_town_v1(scenario.scen_file, i, *scenario.towns[i], *temp_scenario); + } + + delete temp_scenario; + delete item_data; return true; } -static long get_town_offset(short which_town){ +static long get_town_offset(short which_town, legacy::scenario_data_type& scenario){ int i,j; long len_to_jump,store; @@ -187,7 +223,7 @@ static long get_town_offset(short which_town){ return len_to_jump; } -static bool load_town_v1(short which_town, cTown*& the_town) { +bool load_town_v1(fs::path scen_file, short which_town, cTown& the_town, legacy::scenario_data_type& scenario) { short i,n; long len,len_to_jump = 0; char temp_str[256]; @@ -197,20 +233,13 @@ static bool load_town_v1(short which_town, cTown*& the_town) { legacy::ave_tr_type ave_t; legacy::tiny_tr_type tiny_t; - if(which_town != minmax(0,scenario.num_towns - 1,which_town)) { - // This should never be reached from the scenario editor, - // because it does its own range checking before calling load_town. - giveError("The scenario tried to place you into a non-existant town."); - return false; - } - - FILE* file_id = fopen(scenario.scen_file.c_str(), "rb"); + FILE* file_id = fopen(scen_file.c_str(), "rb"); if(file_id == NULL) { oopsError(14, 0, 0); return false; } - len_to_jump = get_town_offset(which_town); + len_to_jump = get_town_offset(which_town, scenario); n = fseek(file_id, len_to_jump, SEEK_SET); if(n != 0) { fclose(file_id); @@ -227,33 +256,29 @@ static bool load_town_v1(short which_town, cTown*& the_town) { } port_town(&store_town); - if(the_town != NULL) delete the_town; switch(scenario.town_size[which_town]) { case 0: len = sizeof(legacy::big_tr_type); n = fread(&t_d, len, 1, file_id); port_t_d(&t_d); - the_town = new cBigTown; - *the_town = store_town; - the_town->append(t_d, which_town); + the_town.append(store_town); + the_town.append(t_d, which_town); break; case 1: len = sizeof(legacy::ave_tr_type); n = fread(&ave_t, len, 1, file_id); port_ave_t(&ave_t); - the_town = new cMedTown; - *the_town = store_town; - the_town->append(ave_t, which_town); + the_town.append(store_town); + the_town.append(ave_t, which_town); break; case 2: len = sizeof(legacy::tiny_tr_type); n = fread(&tiny_t, len, 1, file_id); port_tiny_t(&tiny_t); - the_town = new cTinyTown; - *the_town = store_town; - the_town->append(tiny_t, which_town); + the_town.append(store_town); + the_town.append(tiny_t, which_town); break; } @@ -261,15 +286,15 @@ static bool load_town_v1(short which_town, cTown*& the_town) { len = (long) (store_town.strlens[i]); n = 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.town_name = temp_str; else if(i >= 1 && i < 17) - the_town->rect_names[i-1] = temp_str; + the_town.rect_names[i-1] = temp_str; else if(i >= 17 && i < 20) - the_town->comment[i-17] = temp_str; + the_town.comment[i-17] = temp_str; else if(i >= 20 && i < 120) - the_town->spec_strs[i-20] = temp_str; + the_town.spec_strs[i-20] = temp_str; else if(i >= 120 && i < 140) - the_town->sign_strs[i-120] = temp_str; + the_town.sign_strs[i-120] = temp_str; } len = sizeof(legacy::talking_record_type); @@ -280,26 +305,26 @@ static bool load_town_v1(short which_town, cTown*& the_town) { return false; } port_talk_nodes(&store_talk); - the_town->talking = store_talk; + the_town.talking.append(store_talk); for(i = 0; i < 170; i++) { - len = (long) (the_town->talking.strlens[i]); + len = (long) (the_town.talking.strlens[i]); n = fread(temp_str, len, 1, file_id); temp_str[len] = 0; if(i >= 0 && i < 10) - the_town->talking.people[i].title = temp_str; + the_town.talking.people[i].title = temp_str; else if(i >= 10 && i < 20) - the_town->talking.people[i-10].look = temp_str; + the_town.talking.people[i-10].look = temp_str; else if(i >= 20 && i < 30) - the_town->talking.people[i-20].name = temp_str; + the_town.talking.people[i-20].name = temp_str; else if(i >= 30 && i < 40) - the_town->talking.people[i-30].job = temp_str; + the_town.talking.people[i-30].job = temp_str; else if(i >= 160) - the_town->talking.people[i-160].dunno = temp_str; + the_town.talking.people[i-160].dunno = temp_str; else { if(i % 2 == 0) - the_town->talking.talk_nodes[(i-40)/2].str1 = temp_str; - else the_town->talking.talk_nodes[(i-40)/2].str2 = temp_str; + the_town.talking.talk_nodes[(i-40)/2].str1 = temp_str; + else the_town.talking.talk_nodes[(i-40)/2].str2 = temp_str; } } @@ -311,9 +336,9 @@ static bool load_town_v1(short which_town, cTown*& the_town) { return true; } -bool load_town(short which_town, cTown*& the_town) { - if(scenario.is_legacy) return load_town_v1(which_town, the_town); - fs::path town_base = scenario.scen_file/"towns"; +bool load_town(fs::path town_base, short which_town, cTown*& the_town) { + // TODO: This stuff goes in load_scenario() now +// fs::path town_base = scenario.scen_file/"towns"; std::string base_fname = "t" + std::to_string(which_town), fname; // TODO: Implement all this. // First load the main town data. @@ -326,239 +351,17 @@ bool load_town(short which_town, cTown*& the_town) { // Load the town's special encounter strings fname = base_fname + ".txt"; // And finally, load the town's dialogue nodes. - load_town_talk(which_town); + load_town_talk(town_base, which_town, the_town->talking); return false; } -static bool load_town_talk_v1(short which_town) { - if(univ.town.prep_talk(which_town)) return true; - char temp_str[256]; - - short i,n; - long len,len_to_jump = 0; - legacy::town_record_type store_town; - legacy::talking_record_type store_talk; - - if(which_town != minmax(0,scenario.num_towns - 1,which_town)) { - // This should never be reached from the scenario editor, - // because it does its own range checking before calling load_town. - giveError("The scenario tried to place you into a non-existant town."); - return false; - } - - FILE* file_id = fopen(scenario.scen_file.c_str(), "rb"); - if(file_id == NULL) { - oopsError(19, 0, 0); - return false; - } - - len_to_jump = get_town_offset(which_town); - n = fseek(file_id, len_to_jump, SEEK_SET); - if(n != 0) { - fclose(file_id); - oopsError(20, 0, 0); - return false; - } - - len = sizeof(legacy::town_record_type); - n = fread(&store_town, len, 1, file_id); - if(n < 1) { - fclose(file_id); - oopsError(21, 0, 0); - return false; - } - port_town(&store_town); - - switch(scenario.town_size[which_town]) { - case 0: - len = sizeof(legacy::big_tr_type); - break; - case 1: - len = sizeof(legacy::ave_tr_type); - break; - case 2: - len = sizeof(legacy::tiny_tr_type); - break; - } - - n = fseek(file_id, len, SEEK_CUR); - for(i = 0; i < 140; i++) { - len = (long) (store_town.strlens[i]); - fseek(file_id, len, SEEK_CUR); - } - - len = sizeof(legacy::talking_record_type); - n = fread(&store_talk, len, 1, file_id); - if(n < 1) { - fclose(file_id); - oopsError(22, 0, 0); - return false; - } - port_talk_nodes(&store_talk); - cSpeech& the_talk = univ.town.cur_talk(); - the_talk = store_talk; - - for(i = 0; i < 170; i++) { - len = (long) (the_talk.strlens[i]); - n = fread(temp_str, len, 1, file_id); - temp_str[len] = 0; - if(i >= 0 && i < 10) - the_talk.people[i].title = temp_str; - else if(i >= 10 && i < 20) - the_talk.people[i-10].look = temp_str; - else if(i >= 20 && i < 30) - the_talk.people[i-20].name = temp_str; - else if(i >= 30 && i < 40) - the_talk.people[i-30].job = temp_str; - else if(i >= 160) - the_talk.people[i-160].dunno = temp_str; - else { - if(i % 2 == 0) the_talk.talk_nodes[(i-40)/2].str1 = temp_str; - else the_talk.talk_nodes[(i-40)/2].str2 = temp_str; - } - } - - n = fclose(file_id); - if(n != 0) { - oopsError(23, 0, 0); - } - - return true; -} - -bool load_town_talk(short which_town) { - if(scenario.is_legacy) return load_town_talk_v1(which_town); - fs::path town_base = scenario.scen_file/"towns"; +bool load_town_talk(fs::path town_base, short which_town, cSpeech& the_talk) { // TODO: Implement this. std::string fname = "t" + std::to_string(which_town) + "talk.xml"; return false; } -bool load_town_str(short which_town, short which_str, char* str){ - short i,n; - long len,len_to_jump = 0; - legacy::town_record_type store_town; - - FILE* file_id = fopen(scenario.scen_file.c_str(), "rb"); - if(file_id == NULL) { - oopsError(24, 0, 0); - return false; - } - - len_to_jump = get_town_offset(which_town); - n = fseek(file_id, len_to_jump, SEEK_SET); - if(n < 1) { - fclose(file_id); - oopsError(25, 0, 0); - return false; - } - - len = sizeof(legacy::town_record_type); - - n = fread(&store_town, len, 1, file_id); - if(len < 1) { - fclose(file_id); - oopsError(26, 0, 0); - return false; - } - port_town(&store_town); - - switch(scenario.town_size[which_town]) { - case 0: - len = sizeof(legacy::big_tr_type); - break; - case 1: - len = sizeof(legacy::ave_tr_type); - break; - case 2: - len = sizeof(legacy::tiny_tr_type); - break; - } - - n = fseek(file_id, len, SEEK_CUR); - for(i = 0; i < 140; i++) { - len = (long) (univ.town->strlens[i]); - if(i == which_str){ - n = fread(str, len, 1, file_id); - str[len] = 0; - } - else fseek(file_id, len, SEEK_CUR); - } - - n = fclose(file_id); - if(n != 0) { - oopsError(27, 0, 0); - } - - return true; -} - -bool load_town_str(short which_town, cTown*& t){ - short i,n; - long len,len_to_jump = 0; - char temp_str[256]; - legacy::town_record_type store_town; - - FILE* file_id = fopen(scenario.scen_file.c_str(), "rb"); - if(file_id == NULL) { - oopsError(28, 0, 0); - return false; - } - - len_to_jump = get_town_offset(which_town); - n = fseek(file_id, len_to_jump, SEEK_SET); - if(n != 0) { - fclose(file_id); - oopsError(29, 0, 0); - return false; - } - - len = sizeof(legacy::town_record_type); - n = fread(&store_town, len, 1, file_id); - if(n < 1) { - fclose(file_id); - oopsError(30, 0, 0); - return false; - } - port_town(&store_town); - - switch(scenario.town_size[which_town]) { - case 0: - len = sizeof(legacy::big_tr_type); - break; - case 1: - len = sizeof(legacy::ave_tr_type); - break; - case 2: - len = sizeof(legacy::tiny_tr_type); - break; - } - - n = fseek(file_id, len, SEEK_CUR); - for(i = 0; i < 140; i++) { - len = (long) (t->strlens[i]); - n = fread(temp_str, len, 1, file_id); - temp_str[len] = 0; - if(i == 0) t->town_name = temp_str; - else if(i >= 1 && i < 17) - t->rect_names[i-1] = temp_str; - else if(i >= 17 && i < 20) - t->comment[i-17] = temp_str; - else if(i >= 20 && i < 120) - t->spec_strs[i-20] = temp_str; - else if(i >= 120 && i < 140) - t->sign_strs[i-120] = temp_str; - } - - n = fclose(file_id); - if(n != 0) { - oopsError(31, 0, 0); - } - - return true; -} - -static long get_outdoors_offset(location& which_out){ +static long get_outdoors_offset(location& which_out, cScenario& scenario){ int i,j,out_sec_num; long len_to_jump,store; out_sec_num = scenario.out_width * which_out.y + which_out.x; @@ -578,25 +381,19 @@ static long get_outdoors_offset(location& which_out){ } //mode -> 0 - primary load 1 - add to top 2 - right 3 - bottom 4 - left -static bool load_outdoors_v1(location which_out,cOutdoors& the_out){ +bool load_outdoors_v1(fs::path scen_file, location which_out,cOutdoors& the_out, cScenario& scenario){ short i,n; long len,len_to_jump; char temp_str[256]; legacy::outdoor_record_type store_out; - if((which_out.x != minmax(0,scenario.out_width - 1,which_out.x)) || - (which_out.y != minmax(0,scenario.out_height - 1,which_out.y))) { - the_out = cOutdoors(); - return true; - } - - FILE* file_id = fopen(scenario.scen_file.c_str(), "rb"); + FILE* file_id = fopen(scen_file.c_str(), "rb"); if(file_id == NULL) { oopsError(32, 0, 0); return false; } - len_to_jump = get_outdoors_offset(which_out); + len_to_jump = get_outdoors_offset(which_out, scenario); n = fseek(file_id, len_to_jump, SEEK_SET); if(n != 0) { fclose(file_id); @@ -615,7 +412,7 @@ static bool load_outdoors_v1(location which_out,cOutdoors& the_out){ the_out.x = which_out.x; the_out.y = which_out.y; port_out(&store_out); - the_out = store_out; + the_out.append(store_out, scenario); for(i = 0; i < 108; i++) { len = (long) (store_out.strlens[i]); n = fread(temp_str, len, 1, file_id); @@ -636,16 +433,16 @@ static bool load_outdoors_v1(location which_out,cOutdoors& the_out){ return true; } -bool load_outdoors(location which_out,cOutdoors& the_out) { - if(scenario.is_legacy) return load_outdoors_v1(which_out, the_out); - fs::path town_base = scenario.scen_file/"outdoors"; +bool load_outdoors(fs::path out_base, location which_out,cOutdoors& the_out) { + // TODO: This bit goes in load_scenario() now +// fs::path town_base = scenario.scen_file/"outdoors"; std::string base_fname = "tut" + std::to_string(which_out.x) + "~" + std::to_string(which_out.y), fname; // TODO: Implement all this. // First load the main sector data. fname = base_fname + ".xml"; // Next, load in the sector map. fname = base_fname + ".map"; - map_data map = load_map(town_base/fname); + map_data map = load_map(out_base/fname); // Then load the sector's special nodes. fname = base_fname + ".spec"; // Load the sector's special encounter strings @@ -653,111 +450,14 @@ bool load_outdoors(location which_out,cOutdoors& the_out) { return false; } -bool load_outdoors(location which_out, short mode, ter_num_t borders[4][50]){ - short j,n; - long len,len_to_jump; - legacy::outdoor_record_type store_out; - - FILE* file_id = fopen(scenario.scen_file.c_str(), "rb"); - if(file_id == NULL) { - oopsError(36, 0, 0); - return false; - } - - len_to_jump = get_outdoors_offset(which_out); - - n = fseek(file_id, len_to_jump, SEEK_SET); - if(n != 0) { - fclose(file_id); - oopsError(37, 0, 0); - return false; - } - - len = sizeof(legacy::outdoor_record_type); - n = fread(&store_out, len, 1, file_id); - if(n < 1) { - fclose(file_id); - oopsError(38, 0, 0); - return false; - } - - switch(mode) { - case 1: - for(j = 0; j < 48; j++) { - borders[0][j] = store_out.terrain[j][47]; - } - break; - case 2: - for(j = 0; j < 48; j++) { - borders[1][j] = store_out.terrain[0][j]; - } - break; - case 3: - for(j = 0; j < 48; j++) { - borders[2][j] = store_out.terrain[j][0]; - } - break; - case 4: - for(j = 0; j < 48; j++) { - borders[3][j] = store_out.terrain[47][j]; - } - break; - } - - n = fclose(file_id); - if(n != 0) { - oopsError(39, 0, 0); - } - return true; -} - -bool load_outdoor_str(location which_out, short which_str, char* str){ - short i,n; - long len,len_to_jump; - char temp_str[256]; - legacy::outdoor_record_type store_out; - - FILE* file_id = fopen(scenario.scen_file.c_str(), "rb"); - if(file_id == NULL) { - oopsError(40, 0, 0); - return false; - } - - len_to_jump = get_outdoors_offset(which_out); - n = fseek(file_id, len_to_jump, SEEK_SET); - if(n != 0) { - fclose(file_id); - oopsError(41, 0, 0); - return false; - } - - // TODO: len was never assigned at all, is this the correct value? - len = sizeof(store_out); - n = fread(&store_out, len, 1, file_id); - for(i = 0; i < 120; i++) { - len = (long) (store_out.strlens[i]); - if(i == which_str) { - n = fread(str, len, 1, file_id); - str[len] = 0; - } - else fseek(file_id, len, SEEK_CUR); - } - - n = fclose(file_id); - if(n != 0) { - oopsError(42, 0, 0); - } - return true; -} - #ifdef __APPLE__ bool tryLoadPictFromResourceFile(fs::path& gpath, sf::Image& graphics_store); #endif -void load_spec_graphics() { +void load_spec_graphics(fs::path scen_file) { static const char*const noGraphics = "The game will still work without the custom graphics, but some things will not look right."; short i; - fs::path path(scenario.scen_file); + fs::path path(scen_file); printf("Loading scenario graphics... (%s)\n",path.c_str()); // Tried path.replace_extension, but that only deleted the extension, so I have to do it manually std::string filename = path.stem().string(); @@ -792,6 +492,7 @@ void load_spec_graphics() { } }//else{} + // TODO: This should really reload ALL textures... // Now load regular graphics items_gworld.loadFromImage(*ResMgr::get("objects")); tiny_obj_gworld.loadFromImage(*ResMgr::get("tinyobj")); @@ -820,10 +521,7 @@ void load_spec_graphics() { // TODO: Scenario icons ... } - -bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool maps_there, bool must_port); -bool load_party_v2(fs::path file_to_load, bool town_restore, bool in_scen, bool maps_there); -bool load_party(fs::path file_to_load){ +bool load_party(fs::path file_to_load, cUniverse& univ){ bool town_restore = false; bool maps_there = false; bool in_scen = false; @@ -930,11 +628,11 @@ bool load_party(fs::path file_to_load){ fclose(file_id); switch(format){ case old_mac: - return load_party_v1(file_to_load, town_restore, in_scen, maps_there, mac_is_intel); + return load_party_v1(file_to_load, univ, town_restore, in_scen, maps_there, mac_is_intel); case old_win: - return load_party_v1(file_to_load, town_restore, in_scen, maps_there, !mac_is_intel); + return load_party_v1(file_to_load, univ, town_restore, in_scen, maps_there, !mac_is_intel); case new_oboe: - return load_party_v2(file_to_load, town_restore, in_scen, maps_there); + return load_party_v2(file_to_load, univ, town_restore, in_scen, maps_there); case unknown: cChoiceDlog("not-save-game.xml").show(); return false; @@ -943,7 +641,7 @@ bool load_party(fs::path file_to_load){ return true; } -bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool maps_there, bool must_port){ +bool load_party_v1(fs::path file_to_load, cUniverse& univ, bool town_restore, bool in_scen, bool maps_there, bool must_port){ std::ifstream fin(file_to_load.c_str(), std::ios_base::binary); fin.seekg(3*sizeof(short),std::ios_base::beg); // skip the header, which is 6 bytes in the old format @@ -992,8 +690,6 @@ bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool len = (long) sizeof(legacy::out_info_type); fin.read((char*)&store_out_info, len); - if(univ.town.loaded()) univ.town.unload(); - // LOAD TOWN if(town_restore) { len = (long) sizeof(legacy::current_town_type); @@ -1035,7 +731,7 @@ bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool // TODO: Need to convert after loading the scenario in order to look up saved strings. // However, for that to work, the entire scenario (all towns and sections) would need to be in memory. - univ.party = store_party; + univ.party.append(store_party); univ.party.append(store_setup); univ.party.void_pcs(); for(int i = 0; i < 6; i++) @@ -1043,7 +739,7 @@ bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool if(in_scen){ univ.out.append(store_out_info); if(town_restore){ - univ.town.append(store_c_town,scenario.town_size[univ.town.num]); + univ.town.append(store_c_town); univ.town.append(t_d); univ.town.append(t_i); } @@ -1057,7 +753,7 @@ bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool fs::path path; path = progDir/"Blades of Exile Scenarios"/univ.party.scen_name; - if(!load_scenario(path)) + if(!load_scenario(path, univ.scenario)) return false; univ.file = path; }else{ @@ -1066,7 +762,7 @@ bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool // Compatibility flags // TODO: Pretty sure I did this elsewhere, so probably don't need it here - if(in_scen && scenario.format.prog_make_ver[0] < 2){ + if(in_scen && univ.scenario.format.prog_make_ver[0] < 2){ univ.party.stuff_done[305][8] = 1; } else { univ.party.stuff_done[305][8] = 0; @@ -1075,7 +771,7 @@ bool load_party_v1(fs::path file_to_load, bool town_restore, bool in_scen, bool return true; } -bool load_party_v2(fs::path file_to_load, bool town_restore, bool in_scen, bool maps_there){ +bool load_party_v2(fs::path file_to_load, cUniverse& univ, bool town_restore, bool in_scen, bool maps_there){ if(!fs::exists(tempDir)) fs::create_directories(tempDir); fs::path tempPath = tempDir/"loadtemp.exg"; @@ -1176,7 +872,7 @@ bool load_party_v2(fs::path file_to_load, bool town_restore, bool in_scen, bool } //mode; // 0 - normal 1 - save as -bool save_party(fs::path dest_file) { +bool save_party(fs::path dest_file, const cUniverse& univ) { if(!fs::exists(tempDir)) fs::create_directories(tempDir); bool in_scen = univ.party.scen_name != ""; diff --git a/osx/tools/fileio.h b/osx/tools/fileio.h index 53b9f309..959d05c0 100644 --- a/osx/tools/fileio.h +++ b/osx/tools/fileio.h @@ -11,23 +11,15 @@ #include #include -#include "town.h" -#include "outdoors.h" +class cScenario; +class cUniverse; namespace fs = boost::filesystem; // TODO: Centralize this alias! -bool load_scenario(fs::path file_to_load, bool skip_strings = false); -bool load_town(short which_town, cTown*& the_town); -bool load_town_talk(short which_town); -bool load_town_str(short which_town, short which_str, char* str); -bool load_town_str(short which_town, cTown*& the_town); -bool load_outdoors(location which_out,cOutdoors& the_out); -bool load_outdoors(location which_out, short mode, ter_num_t borders[4][50]); -bool load_outdoor_str(location which_out, short which_str, char* str); -void load_spec_graphics(); +bool load_scenario(fs::path file_to_load, cScenario& scenario); -bool load_party(fs::path file_to_load); -bool save_party(fs::path dest_file); +bool load_party(fs::path file_to_load, cUniverse& univ); +bool save_party(fs::path dest_file, const cUniverse& univ); void init_directories(const char* exec_path); void check_for_intel(); diff --git a/osx/tools/vector2d.hpp b/osx/tools/vector2d.hpp new file mode 100644 index 00000000..25101914 --- /dev/null +++ b/osx/tools/vector2d.hpp @@ -0,0 +1,70 @@ +// +// vector_2d.hpp +// BoE +// +// Created by Celtic Minstrel on 14-12-21. +// +// + +#ifndef BoE_VECTOR_2D_HPP +#define BoE_VECTOR_2D_HPP + +// Tried using boost::multi_array, but it kept causing weird issues, so I decided to make my own. +// TODO: Fill out missing members (should have equivalents for most of the stuff in std::vector) +// TODO: Add row-wise access using the included row_ref, and support for row/column assignment +// (These would be very useful for implementing a resize outdoors function in the scenario editor.) + +#include + +template> class vector2d { + friend class row_ref; + friend class col_ref; + std::vector data; + size_t w, h; +public: + class row_ref { + friend class vector2d; + vector2d& ref; + size_t y; + row_ref(vector2d& ref, size_t row) : ref(ref), y(row) {} + public: + Type& operator[](size_t x) { + return ref.data[ref.w * y + x]; + } + }; + class col_ref { + friend class vector2d; + vector2d& ref; + size_t x; + col_ref(vector2d& ref, size_t col) : ref(ref), x(col) {} + public: + Type& operator[](size_t y) { + return ref.data[ref.w * y + x]; + } + }; + col_ref operator[](size_t x) { + return col_ref(*this, x); + } +// const col_ref operator[](size_t x) const { +// return col_ref(*this, x); +// } + size_t width() { + return w; + } + size_t height() { + return h; + } + size_t size() { + return data.size(); + } + void resize(size_t width, size_t height) { + w = width; h = height; + data.resize(w * h); + } + bool empty() { + return data.empty(); + } + vector2d() : w(0), h(0) {} +}; + +#endif