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