diff --git a/src/dialogxml/widgets/pict.cpp b/src/dialogxml/widgets/pict.cpp index 1a195bbb..27934f6a 100644 --- a/src/dialogxml/widgets/pict.cpp +++ b/src/dialogxml/widgets/pict.cpp @@ -689,6 +689,62 @@ void cPict::draw(){ drawFrame(2, frameStyle); } +bool cPict::get_terrain_picture(cPictNum pict, Texture &source, rectangle &from_rect, int anim) +try { + source=Texture(); + ePicType type=pict.type; + if (pict.num<0) + type=ePicType::PIC_NONE; + switch (type) { + case ePicType::PIC_TER: { + source = *ResMgr::textures.get("ter" + std::to_string(1 + pict.num / 50)); + int picture_wanted = pict.num%50; + from_rect = calc_rect(picture_wanted % 10, picture_wanted / 10); + break; + } + case ePicType::PIC_TER_ANIM: + source = *ResMgr::textures.get("teranim"); + from_rect = calc_rect(4*(pict.num/5)+(anim%4),pict.num%5); + break; + case ePicType::PIC_TER_MAP: + source=*ResMgr::textures.get("termap"); + if (pict.num<960) { + from_rect.left = 12*(pict.num%20); + from_rect.top = 12*(pict.num/20); + } + else { + from_rect.left = 12*20; + from_rect.top = 12*(pict.num-960); + } + from_rect.right = from_rect.left+12; + from_rect.bottom = from_rect.top+12; + break; + case ePicType::PIC_CUSTOM_TER: + if (!spec_scen_g) + break; + std::tie(source,from_rect) = spec_scen_g.find_graphic(pict.num); + break; + case ePicType::PIC_CUSTOM_TER_ANIM: + if (!spec_scen_g) + break; + std::tie(source,from_rect) = spec_scen_g.find_graphic(pict.num+(anim%4)); + break; + default: + break; + } + if (!source) + throw "can not find image"; + return true; +} +catch (...) { + if (pict.num==-1) // ok no picture + return false; + std::cerr << "Error[get_terrain_picture]: can not find picture id=" << pict.num << ", type=" << int(pict.type)<< "\n"; + source = *ResMgr::textures.get("errors"); + from_rect={0,0,40,40}; + return true; +} + void cPict::drawPresetTer(short num, rectangle to_rect){ auto from_gw = getSheet(SHEET_TER, num / 50); if(!from_gw) return; diff --git a/src/dialogxml/widgets/pict.hpp b/src/dialogxml/widgets/pict.hpp index e6ad3ce9..a6e92231 100644 --- a/src/dialogxml/widgets/pict.hpp +++ b/src/dialogxml/widgets/pict.hpp @@ -82,6 +82,7 @@ public: static void advanceAnim(); virtual ~cPict(); void draw(); + static bool get_terrain_picture(cPictNum pict, Texture &source, rectangle &from_rect, int anim=0); /// A utility function to draw an icon into an arbitrary window. /// @param win The window to draw in. /// @param dest The bounding rect to draw in (ignored for drawing the actual, but used for background fill and framing) diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index de8b7443..a7d1b56c 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -341,7 +341,7 @@ static void handle_toggle_active(bool& need_reprint) { static void handle_rest(bool& need_redraw, bool& need_reprint) { sf::Event dummy_evt; int i = 0; - ter_num_t ter = univ.out[univ.party.out_loc.x][univ.party.out_loc.y]; + ter_num_t const ter = univ.out[univ.party.out_loc.x][univ.party.out_loc.y]; if(univ.party.in_boat >= 0) add_string_to_buf("Rest: Not in boat."); else if(someone_poisoned()) @@ -350,7 +350,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(univ.scenario.ter_types[ter].special == eTerSpec::DAMAGING || univ.scenario.ter_types[ter].special == eTerSpec::DANGEROUS) + else if(univ.get_terrain(ter).special == eTerSpec::DAMAGING || univ.get_terrain(ter).special == eTerSpec::DANGEROUS) add_string_to_buf("Rest: It's dangerous here."); else if(flying()) add_string_to_buf("Rest: Not while flying."); @@ -536,8 +536,8 @@ static void handle_move(location destination, bool& did_something, bool& need_re menu_activate(); } else need_redraw = true; - ter_num_t storage = univ.out[univ.party.out_loc.x][univ.party.out_loc.y]; - if(univ.scenario.ter_types[storage].special == eTerSpec::TOWN_ENTRANCE) { + ter_num_t const storage = univ.out[univ.party.out_loc.x][univ.party.out_loc.y]; + if(univ.get_terrain(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; @@ -2350,7 +2350,7 @@ void increase_age() { if(univ.party.status[ePartyStatus::FLIGHT] == 2) add_string_to_buf("You are starting to descend."); if(univ.party.status[ePartyStatus::FLIGHT] == 1) { - if(univ.scenario.ter_types[univ.out[univ.party.out_loc.x][univ.party.out_loc.y]].blocksMove()) { + if(univ.get_terrain(univ.out[univ.party.out_loc.x][univ.party.out_loc.y]).blocksMove()) { add_string_to_buf(" You plummet to your deaths."); slay_party(eMainStatus::DEAD); print_buf(); @@ -2551,20 +2551,20 @@ void handle_hunting() { return; if(univ.out.is_road(univ.party.out_loc.x, univ.party.out_loc.y)) return; - ter_num_t ter = univ.out[univ.party.out_loc.x][univ.party.out_loc.y]; + ter_num_t const ter = univ.out[univ.party.out_loc.x][univ.party.out_loc.y]; if(!wilderness_lore_present(ter)) return; eTrait trait = eTrait::PACIFIST; - if(univ.scenario.ter_types[ter].special == eTerSpec::WILDERNESS_CAVE) + if(univ.get_terrain(ter).special == eTerSpec::WILDERNESS_CAVE) trait = eTrait::CAVE_LORE; - else if(univ.scenario.ter_types[ter].special == eTerSpec::WILDERNESS_SURFACE) + else if(univ.get_terrain(ter).special == eTerSpec::WILDERNESS_SURFACE) trait = eTrait::WOODSMAN; if(trait == eTrait::PACIFIST) return; for(cPlayer& pc : univ.party) if(pc.is_alive() && pc.traits[trait] && get_ran(1,0,12) == 5) { - univ.party.food += get_ran(univ.scenario.ter_types[ter].flag1,1,6); + univ.party.food += get_ran(univ.get_terrain(ter).flag1,1,6); add_string_to_buf(pc.name + " hunts."); put_pc_screen(); } @@ -2723,13 +2723,13 @@ 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){ - eTerSpec spec = univ.scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].special; + eTerSpec spec = univ.get_terrain(univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])).special; to_dir[i] = spec == eTerSpec::WATERFALL_CAVE || spec == eTerSpec::WATERFALL_SURFACE; - if(univ.scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].flag1 != i) to_dir[i] = false; + if(univ.get_terrain(univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])).flag1 != i) to_dir[i] = false; }else{ - eTerSpec spec = univ.scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].special; + eTerSpec spec = univ.get_terrain(univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]).special; to_dir[i] = spec == eTerSpec::WATERFALL_CAVE || spec == eTerSpec::WATERFALL_SURFACE; - if(univ.scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].flag1 != i) to_dir[i] = false; + if(univ.get_terrain(univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]).flag1 != i) to_dir[i] = false; } } short count = 0; @@ -2778,7 +2778,7 @@ static void run_waterfalls(short mode){ // mode 0 - town, 1 - outdoors if(wilderness_lore_present(coord_to_ter(x - dir_x_dif[dir], y - dir_y_dif[dir]) > 0) && get_ran(1,0,1) == 0) add_string_to_buf(" (No supplies lost.)"); else { - cTerrain& ter = univ.scenario.ter_types[coord_to_ter(x, y)]; + cTerrain const & ter = univ.get_terrain(coord_to_ter(x, y)); int lost = univ.party.food * ter.flag2 / 100; if(lost >= ter.flag3) { lost = ter.flag3; @@ -2872,9 +2872,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 - && (!univ.scenario.ter_types[ter].boat_over + && (!univ.get_terrain(ter).boat_over || ((real_dest.x != univ.party.out_loc.x) && (real_dest.y != univ.party.out_loc.y))) - && univ.scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) { + && univ.get_terrain(ter).special != eTerSpec::TOWN_ENTRANCE) { add_string_to_buf("You leave the boat."); univ.party.in_boat = -1; } @@ -2882,8 +2882,8 @@ bool outd_move_party(location destination,bool forced) { || (!forced && out_boat_there(destination))) return false; else if(!outd_is_blocked(real_dest) - && univ.scenario.ter_types[ter].boat_over - && univ.scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) { + && univ.get_terrain(ter).boat_over + && univ.get_terrain(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",{"under","land"}).show() == "under") @@ -2893,7 +2893,7 @@ bool outd_move_party(location destination,bool forced) { univ.party.in_boat = -1; } } - else if(univ.scenario.ter_types[ter].boat_over) + else if(univ.get_terrain(ter).boat_over) forced = true; } @@ -2915,7 +2915,7 @@ bool outd_move_party(location destination,bool forced) { univ.party.loc_in_sec = global_to_local(univ.party.out_loc); if((store_corner.x != univ.party.outdoor_corner.x) || (store_corner.y != univ.party.outdoor_corner.y) || - (store_iwc.x != univ.party.i_w_c.x) || (store_iwc.y != univ.party.i_w_c.y)) + (store_iwc.x != univ.party.i_w_c.x) || (store_iwc.y != univ.party.i_w_c.y)) // OSNOLA: really need ? minimap::add_pending_redraw(); return true; @@ -2937,27 +2937,27 @@ bool outd_move_party(location destination,bool forced) { univ.party.loc_in_sec = global_to_local(univ.party.out_loc); if((store_corner.x != univ.party.outdoor_corner.x) || (store_corner.y != univ.party.outdoor_corner.y) || - (store_iwc.x != univ.party.i_w_c.x) || (store_iwc.y != univ.party.i_w_c.y)) + (store_iwc.x != univ.party.i_w_c.x) || (store_iwc.y != univ.party.i_w_c.y)) // OSNOLA minimap::add_pending_redraw(); return true; } else if(!outd_is_blocked(real_dest) || forced // Check if can fly over - || (flying() && univ.scenario.ter_types[ter].fly_over)) { + || (flying() && univ.get_terrain(ter).fly_over)) { if(univ.party.in_horse >= 0) { - if(univ.scenario.ter_types[ter].special == eTerSpec::DAMAGING || univ.scenario.ter_types[ter].special == eTerSpec::DANGEROUS) { + if(univ.get_terrain(ter).special == eTerSpec::DAMAGING || univ.get_terrain(ter).special == eTerSpec::DANGEROUS) { ASB("Your horses quite sensibly refuse."); return false; } - if(univ.scenario.ter_types[ter].block_horse) { + if(univ.get_terrain(ter).block_horse) { ASB("You can't take horses there!"); return false; } } // TODO: But I though you automatically landed when entering? - if(flying() && univ.scenario.ter_types[ter].special == eTerSpec::TOWN_ENTRANCE) { + if(flying() && univ.get_terrain(ter).special == eTerSpec::TOWN_ENTRANCE) { add_string_to_buf("Moved: You have to land first."); return false; } @@ -2983,7 +2983,7 @@ bool outd_move_party(location destination,bool forced) { } if((store_corner.x != univ.party.outdoor_corner.x) || (store_corner.y != univ.party.outdoor_corner.y) || - (store_iwc.x != univ.party.i_w_c.x) || (store_iwc.y != univ.party.i_w_c.y)) + (store_iwc.x != univ.party.i_w_c.x) || (store_iwc.y != univ.party.i_w_c.y)) // OSNOLA minimap::add_pending_redraw(); return true; @@ -3019,7 +3019,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 - && (!univ.scenario.ter_types[ter].boat_over + && (!univ.get_terrain(ter).boat_over || ((destination.x != univ.party.town_loc.x) && (destination.y != univ.party.town_loc.y)))) { add_string_to_buf("You leave the boat."); univ.party.in_boat = -1; @@ -3027,7 +3027,7 @@ bool town_move_party(location destination,short forced) { else if((destination.x != univ.party.town_loc.x) && (destination.y != univ.party.town_loc.y)) return false; // Crossing bridge: land or go through - else if(!is_blocked(destination) && univ.scenario.ter_types[ter].boat_over && univ.scenario.ter_types[ter].special == eTerSpec::BRIDGE) { + else if(!is_blocked(destination) && univ.get_terrain(ter).boat_over && univ.get_terrain(ter).special == eTerSpec::BRIDGE) { if(cChoiceDlog("boat-bridge",{"under","land"}).show() == "under") forced = true; else if(!is_blocked(destination)) { @@ -3041,7 +3041,7 @@ bool town_move_party(location destination,short forced) { return false; } // water or lava - else if(univ.scenario.ter_types[ter].boat_over) + else if(univ.get_terrain(ter).boat_over) forced = true; } @@ -3079,11 +3079,11 @@ bool town_move_party(location destination,short forced) { } else if(!is_blocked(destination) || forced) { if(univ.party.in_horse >= 0) { - if(univ.scenario.ter_types[ter].special == eTerSpec::DAMAGING || univ.scenario.ter_types[ter].special == eTerSpec::DANGEROUS) { + if(univ.get_terrain(ter).special == eTerSpec::DAMAGING || univ.get_terrain(ter).special == eTerSpec::DANGEROUS) { ASB("Your horses quite sensibly refuse."); return false; } - if(univ.scenario.ter_types[ter].block_horse) { + if(univ.get_terrain(ter).block_horse) { ASB("You can't take horses there!"); return false; } @@ -3165,10 +3165,7 @@ short count_walls(location loc) { // TODO: Generalize this function } bool is_sign(ter_num_t ter) { - - if(univ.scenario.ter_types[ter].special == eTerSpec::IS_A_SIGN) - return true; - return false; + return univ.scenario.get_terrain(ter).special == eTerSpec::IS_A_SIGN; } bool check_for_interrupt(){ diff --git a/src/game/boe.graphics.cpp b/src/game/boe.graphics.cpp index 787201f5..651ce381 100644 --- a/src/game/boe.graphics.cpp +++ b/src/game/boe.graphics.cpp @@ -685,10 +685,7 @@ void refresh_text_bar() { // this is used for determinign whether to round off walkway corners // right now, trying a restrictive rule (just cave floor and grass, mainly) bool is_nature(short x, short y, unsigned short ground_t) { - ter_num_t ter_type; - - ter_type = coord_to_ter((short) x,(short) y); - return ground_t == univ.scenario.ter_types[ter_type].ground_type; + return ground_t == univ.get_terrain(coord_to_ter((short) x,(short) y)).ground_type; } std::vector forcecage_locs; @@ -818,12 +815,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 = univ.scenario.ter_types[spec_terrain].trim_type; + eTrimType trim = univ.get_terrain(spec_terrain).trim_type; // Finally, draw this terrain spot if(trim == eTrimType::WALKWAY){ int trim = -1; - unsigned short ground_t = univ.scenario.ter_types[spec_terrain].trim_ter; + unsigned short ground_t = univ.get_terrain(spec_terrain).trim_ter; ter_num_t ground_ter = univ.scenario.get_ter_from_ground(ground_t); if(!loc_off_act_area(where_draw)) { if(is_nature(where_draw.x - 1,where_draw.y,ground_t)){ // check left @@ -949,9 +946,10 @@ void draw_terrain(short mode) { static ter_num_t get_ground_for_shore(ter_num_t ter){ - if(univ.scenario.ter_types[ter].block_horse) return current_ground; - else if(univ.scenario.ter_types[ter].blocksMove()) return current_ground; - else return ter; + if(univ.get_terrain(ter).block_horse || univ.get_terrain(ter).blocksMove()) + return current_ground; + else + return ter; } void place_trim(short q,short r,location where,ter_num_t ter_type) { @@ -1121,9 +1119,6 @@ void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter) { {0,0,36,28}, }; static std::unique_ptr trim_masks[12], walkway_masks[9]; - rectangle from_rect = {0,0,36,28},to_rect; - Texture from_gworld; - sf::Texture* mask; static bool inited = false; if(!inited){ inited = true; @@ -1142,38 +1137,33 @@ void draw_trim(short q,short r,short which_trim,ter_num_t ground_ter) { for(short i = 0; i < 8 ; i++) walkway_rects[i].offset((i%4)*28,(i/4)*36); walkway_rects[8].offset(196,0); } - sf::Color test_color = {0,0,0}, store_color; - if(!get_bool_pref("DrawTerrainShoreFrills", true)) return; - unsigned short pic = univ.scenario.ter_types[ground_ter].picture; - if(pic < 960){ - int which_sheet = pic / 50; - from_gworld = *ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)); - pic %= 50; - from_rect.offset(28 * (pic % 10), 36 * (pic / 10)); - }else if(pic < 1000){ - from_gworld = *ResMgr::textures.get("teranim"); - pic -= 960; - from_rect.offset(112 * (pic / 5),36 * (pic % 5)); - }else{ - pic %= 1000; - std::tie(from_gworld,from_rect) = spec_scen_g.find_graphic(pic); + rectangle from_rect; + Texture from_gworld; + rectangle to_rect = coord_to_rect(q,r); + if (!cPict::get_terrain_picture(univ.get_terrain(ground_ter).get_picture_num(), from_gworld, from_rect)) { + fill_rect(terrain_screen_gworld, to_rect, sf::Color::Yellow); + return; // CHECKME better to draw a bad image to indicate that there is a problem here } - if(which_trim < 50) { + + sf::Texture* mask=nullptr; + if(which_trim>=0 && which_trim < 12) { if(!trim_masks[which_trim]) init_trim_mask(trim_masks[which_trim], trim_rects[which_trim]); mask = trim_masks[which_trim].get(); - } else { + } else if (which_trim>=50 && which_trim<59){ int which = which_trim - 50; if(!walkway_masks[which]) init_trim_mask(walkway_masks[which], walkway_rects[which]); mask = walkway_masks[which].get(); } - to_rect = coord_to_rect(q,r); - rect_draw_some_item(from_gworld, from_rect, *mask, terrain_screen_gworld, to_rect); + if (mask) + rect_draw_some_item(from_gworld, from_rect, *mask, terrain_screen_gworld, to_rect); + else + rect_draw_some_item(from_gworld, from_rect, terrain_screen_gworld, to_rect); } @@ -1182,10 +1172,11 @@ static bool extend_road_terrain(int x, int y) { return true; if(is_town() && univ.town.is_road(x,y)) return true; - ter_num_t ter = coord_to_ter(x,y); - 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; + ter_num_t const ter = coord_to_ter(x,y); + cTerrain const &terrain=univ.get_terrain(ter); + eTrimType trim = terrain.trim_type; + eTerSpec spec = terrain.special; + ter_num_t flag = terrain.flag1; if(trim == eTrimType::CITY || trim == eTrimType::WALKWAY) return true; if(spec == eTerSpec::BRIDGE) @@ -1194,7 +1185,7 @@ static bool extend_road_terrain(int x, int y) { 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 && univ.scenario.ter_types[flag].special == eTerSpec::CHANGE_WHEN_STEP_ON && univ.scenario.ter_types[flag].flag1 == ter) + if(spec == eTerSpec::CHANGE_WHEN_USED && univ.get_terrain(flag).special == eTerSpec::CHANGE_WHEN_STEP_ON && univ.get_terrain(flag).flag1 == ter) return true; // open door (I think) TODO: Verify this works if(spec == eTerSpec::LOCKABLE) return true; // open portcullis (most likely) @@ -1203,14 +1194,13 @@ static bool extend_road_terrain(int x, int y) { static bool can_build_roads_on(ter_num_t ter) { if(impassable(ter)) return false; - if(univ.scenario.ter_types[ter].special == eTerSpec::BRIDGE) return false; + if(univ.get_terrain(ter).special == eTerSpec::BRIDGE) return false; return true; } static bool connect_roads(ter_num_t ter){ - if (ter>=univ.scenario.ter_types.size()) return false; - eTrimType trim = univ.scenario.ter_types[ter].trim_type; - eTerSpec spec = univ.scenario.ter_types[ter].special; + eTrimType trim = univ.get_terrain(ter).trim_type; + eTerSpec spec = univ.get_terrain(ter).special; if(trim == eTrimType::CITY) return true; if(spec == eTerSpec::TOWN_ENTRANCE && trim != eTrimType::NONE) @@ -1274,10 +1264,10 @@ void place_road(short q,short r,location where,bool here) { ter_num_t ter = coord_to_ter(where.x, where.y); ter_num_t ref = coord_to_ter(where.x,where.y); bool horz = false, vert = false; - eTrimType trim = univ.scenario.ter_types[ref].trim_type; + eTrimType trim = univ.get_terrain(ref).trim_type; if(where.y > 0) ter = coord_to_ter(where.x,where.y - 1); - eTrimType vertTrim = univ.scenario.ter_types[ter].trim_type; + eTrimType vertTrim = univ.get_terrain(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)) @@ -1285,7 +1275,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 = termax_dim - 1)) || connect_roads(ter)) horz = can_build_roads_on(ref); @@ -1295,7 +1285,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 = termax_dim - 1)) || connect_roads(ter)) vert = can_build_roads_on(ref); @@ -1307,7 +1297,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 = univ.scenario.ter_types[ter].trim_type; + eTrimType horzTrim = univ.get_terrain(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/src/game/boe.graphutil.cpp b/src/game/boe.graphutil.cpp index 63332320..4f9c5da4 100644 --- a/src/game/boe.graphutil.cpp +++ b/src/game/boe.graphutil.cpp @@ -59,48 +59,23 @@ bool gave_no_g_error = false; // if terrain_to_draw is -1, do black // if terrain_to_draw >= 10000, force to draw graphic which is terrain_to_draw - 10000 void draw_one_terrain_spot (short i,short j,short terrain_to_draw) { - rectangle where_draw; - rectangle source_rect; - Texture source_gworld; - location l; - - l.x = i; l.y = j; + location l={i,j}; if(supressing_some_spaces && (l != ok_space[0]) && (l != ok_space[1]) && (l != ok_space[2]) && (l != ok_space[3])) return; - where_draw = calc_rect(i,j); + rectangle where_draw = calc_rect(i,j); where_draw.offset(13,13); if(terrain_to_draw == -1) { fill_rect(terrain_screen_gworld, where_draw, sf::Color::Black); return; } - - if(terrain_to_draw >= 10000) { // force using a specific graphic - terrain_to_draw -= 10000; - int which_sheet = terrain_to_draw / 50; - source_gworld = *ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)); - terrain_to_draw %= 50; - source_rect = calc_rect(terrain_to_draw % 10, terrain_to_draw / 10); + + rectangle source_rect; + Texture source_gworld; + if (!cPict::get_terrain_picture(univ.get_terrain(terrain_to_draw).get_picture_num(), source_gworld, source_rect, anim_ticks % 4)) { + fill_rect(terrain_screen_gworld, where_draw, sf::Color::Yellow); + return; // CHECKME better to draw an error image to indicate that there is a problem here } - else if(univ.scenario.ter_types[terrain_to_draw].picture >= 2000) { // custom - std::tie(source_gworld,source_rect) = spec_scen_g.find_graphic(univ.scenario.ter_types[terrain_to_draw].picture - 2000 + (anim_ticks % 4)); - } - else if(univ.scenario.ter_types[terrain_to_draw].picture >= 1000) { // custom - std::tie(source_gworld,source_rect) = spec_scen_g.find_graphic(univ.scenario.ter_types[terrain_to_draw].picture - 1000); - } - else if(univ.scenario.ter_types[terrain_to_draw].picture >= 960) { // animated - source_gworld = *ResMgr::textures.get("teranim"); - 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); - } - else { - terrain_to_draw = univ.scenario.ter_types[terrain_to_draw].picture; - int which_sheet = terrain_to_draw / 50; - source_gworld = *ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)); - terrain_to_draw %= 50; - source_rect = calc_rect(terrain_to_draw % 10, terrain_to_draw / 10); - } - rect_draw_some_item(source_gworld, source_rect, terrain_screen_gworld, where_draw); } @@ -172,10 +147,10 @@ void draw_monsters() { ter = univ.town->terrain(monst.cur_loc.x,monst.cur_loc.y); // in bed? if(store_loc.x >= 0 && store_loc.x < 9 && store_loc.y >= 0 && store_loc.y < 9 && - (univ.scenario.ter_types[ter].special == eTerSpec::BED) && isHumanoid(monst.m_type) + (univ.get_terrain(ter).special == eTerSpec::BED) && isHumanoid(monst.m_type) && (monst.active == 1 || monst.target == 6) && width == 1 && height == 1) - draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1); + draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.get_terrain(ter).flag1); else if(monst.picture_num >= 1000) { bool isParty = monst.picture_num >= 10000; pic_num_t need_pic = (monst.picture_num % 1000) + k; @@ -476,8 +451,8 @@ void draw_party_symbol(location center) { else if(is_town() || is_combat()) ter = univ.town->terrain(univ.party.town_loc.x,univ.party.town_loc.y); // now wedge in bed graphic - 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); + if(is_town() && univ.scenario.get_terrain(ter).special == eTerSpec::BED) + draw_one_terrain_spot((short) target.x,(short) target.y,10000 + univ.get_terrain(ter).flag1); else Draw_Some_Item(from_gw, source_rect, terrain_screen_gworld, target, 1, 0); } else if(univ.party.in_boat >= 0) { @@ -507,51 +482,26 @@ rectangle get_monster_template_rect (pic_num_t picture_wanted,short mode,short w // Is this a fluid that gets shore plopped down on it? bool is_fluid(ter_num_t ter_type) { -// if(((ter_type >= 71) && (ter_type <= 76)) || (ter_type == 90)) -// return true; -// return false; - return univ.scenario.ter_types[ter_type].trim_type == eTrimType::FRILLS; + // odd game true 71-76, 90 + return univ.get_terrain(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(univ.scenario.ter_types[ter_type].trim_type == eTrimType::WATERFALL) - return false; -// if(ter_type == 77) -// return false; -// if(ter_type == 90) -// return false; -/* if(ter_type == 240) - return false; - if((ter_type >= 117) && (ter_type <= 131)) - return false; - if((ter_type >= 193) && (ter_type <= 207)) - return false; */ - return true; + // odd game false 77,90,240,117-131,193-207 + return univ.get_terrain(ter_type).trim_type != eTrimType::WATERFALL; } // These two functions used to determine wall round-cornering bool is_wall(ter_num_t ter_type) { - return univ.scenario.ter_types[ter_type].trim_type == eTrimType::WALL; -// short pic; -// -// pic = scenario.ter_types[ter_type].picture; -// -// if((pic >= 88) && (pic <= 120)) -// return true; -// -// return false; + return univ.get_terrain(ter_type).trim_type == eTrimType::WALL; } bool is_ground(ter_num_t ter_type) { - if(univ.scenario.ter_types[ter_type].trim_type == eTrimType::WALL) - return false; - if(univ.scenario.ter_types[ter_type].block_horse) - return false; -// if(scenario.ter_types[ter_type].trim_type == eTrimType::WALKWAY) -// return false; - return true; + cTerrain const &terrain=univ.get_terrain(ter_type); + // test also for WALKWAY ? + return terrain.trim_type != eTrimType::WALL && !terrain.block_horse; } char get_fluid_trim(location where,ter_num_t ter_type) { diff --git a/src/game/boe.minimap.cpp b/src/game/boe.minimap.cpp index 8d6b253f..9f8bf006 100644 --- a/src/game/boe.minimap.cpp +++ b/src/game/boe.minimap.cpp @@ -212,7 +212,6 @@ void draw(bool need_refresh) { else out_mode = false; // TODO: It could be possible to draw the entire map here and then only refresh if a spot actually changes terrain type - auto const & small_ter_gworld = *ResMgr::textures.get("termap"); for(where.x = redraw_rect.left; where.x < redraw_rect.right; where.x++) for(where.y = redraw_rect.top; where.y < redraw_rect.bottom; where.y++) { draw_rect = orig_draw_rect; @@ -228,54 +227,17 @@ void draw(bool need_refresh) { expl = univ.out.out_e[where.x + 48 * univ.party.i_w_c.x][where.y + 48 * univ.party.i_w_c.y]; else expl = is_explored(where.x,where.y); - if(expl != 0) { - pic = univ.scenario.ter_types[what_ter].map_pic; - bool drawLargeIcon = false; - if(pic == NO_PIC) { - pic = univ.scenario.ter_types[what_ter].picture; - drawLargeIcon = true; - } - if(pic >= 1000) { - if(spec_scen_g) { - //print_nums(0,99,pic); - Texture src_gw; - if(drawLargeIcon) { - pic = pic % 1000; - std::tie(src_gw,custom_from) = spec_scen_g.find_graphic(pic); - rect_draw_some_item(src_gw,custom_from,gworld,draw_rect); - } else { - std::tie(src_gw,custom_from) = spec_scen_g.find_graphic(pic % 1000); - custom_from.right = custom_from.left + 12; - custom_from.bottom = custom_from.top + 12; - pic /= 1000; pic--; - custom_from.offset((pic / 3) * 12, (pic % 3) * 12); - rect_draw_some_item(src_gw,custom_from, gworld, draw_rect); - } - } - } else if(drawLargeIcon) { - if(pic >= 960) { - custom_from = calc_rect(4 * ((pic - 960) / 5),(pic - 960) % 5); - rect_draw_some_item(*ResMgr::textures.get("teranim"), custom_from, gworld, draw_rect); - } else { - int which_sheet = pic / 50; - auto const &src_gw = *ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)); - pic %= 50; - custom_from = calc_rect(pic % 10, pic / 10); - rect_draw_some_item(src_gw, custom_from, gworld, draw_rect); - } - } else { - 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 * (univ.scenario.ter_types[what_ter].picture - 960)); - rect_draw_some_item(small_ter_gworld,ter_temp_from,gworld,draw_rect); - } + if(expl == 0) + continue; + Texture src_gw; + if (!cPict::get_terrain_picture(univ.get_terrain(what_ter).get_map_picture_num(), src_gw,custom_from)) + fill_rect(gworld, draw_rect, sf::Color::Yellow); // FIXME: show an error here + else + rect_draw_some_item(src_gw, custom_from, gworld, draw_rect); - if(is_out() ? univ.out->roads[where.x][where.y] : univ.town.is_road(where.x,where.y)) { - draw_rect.inset(1,1); - rect_draw_some_item(*ResMgr::textures.get("trim"),{8,112,12,116},gworld,draw_rect); - } + if(is_out() ? univ.out->roads[where.x][where.y] : univ.town.is_road(where.x,where.y)) { + draw_rect.inset(1,1); + rect_draw_some_item(*ResMgr::textures.get("trim"),{8,112,12,116},gworld,draw_rect); } } diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index 7a015d6a..41bd9459 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -318,58 +318,6 @@ static std::vector get_small_icons(location at, ter_num_t t_to_draw) { return icons; } -static bool get_terrain_picture(cPictNum pict, Texture &source, rectangle &from_rect) -try { - source=Texture(); - ePicType type=pict.type; - if (pict.num<0) - type=ePicType::PIC_NONE; - switch (type) { - case ePicType::PIC_TER: { - source = *ResMgr::textures.get("ter" + std::to_string(1 + pict.num / 50)); - int picture_wanted = pict.num%50; - from_rect = calc_rect(picture_wanted % 10, picture_wanted / 10); - break; - } - case ePicType::PIC_TER_ANIM: - source = *ResMgr::textures.get("teranim"); - from_rect = calc_rect(4 * (pict.num / 5),pict.num % 5); - break; - case ePicType::PIC_TER_MAP: - source=*ResMgr::textures.get("termap"); - if (pict.num<960) { - from_rect.left = 12*(pict.num%20); - from_rect.top = 12*(pict.num/20); - } - else { - from_rect.left = 12*20; - from_rect.top = 12*(pict.num-960); - } - from_rect.right = from_rect.left+12; - from_rect.bottom = from_rect.top+12; - break; - case ePicType::PIC_CUSTOM_TER: - case ePicType::PIC_CUSTOM_TER_ANIM: // checkme - if (!spec_scen_g) - break; - std::tie(source,from_rect) = spec_scen_g.find_graphic(pict.num); - break; - default: - break; - } - if (!source) - throw "can not find image"; - return true; -} -catch (...) { - if (pict.num==-1) // ok no picture - return false; - std::cerr << "Error[get_terrain_picture]: can not find picture id=" << pict.num << ", type=" << int(pict.type)<< "\n"; - source = *ResMgr::textures.get("errors"); - from_rect={0,0,40,40}; - return true; -} - void Set_up_win() { terrain_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y); terrain_buttons_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y); @@ -585,7 +533,7 @@ void set_up_terrain_buttons(bool reset) { break; } Texture source_gworld; - if (get_terrain_picture(scenario.get_terrain(i).get_picture_num(), source_gworld, ter_from)) + if (cPict::get_terrain_picture(scenario.get_terrain(i).get_picture_num(), source_gworld, ter_from)) rect_draw_some_item(source_gworld,ter_from, mainPtr, draw_rect); small_i = get_small_icon(i); tiny_from = base_small_button_from; @@ -1147,7 +1095,7 @@ void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) { rectangle source_rect; Texture source_gworld; - if (!get_terrain_picture(scenario.get_terrain(terrain_to_draw).get_picture_num(), source_gworld, source_rect)) + if (!cPict::cPict::get_terrain_picture(scenario.get_terrain(terrain_to_draw).get_picture_num(), source_gworld, source_rect)) return; location where_draw; @@ -1168,7 +1116,7 @@ void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short Texture source_gworld; rectangle dest_rect = {0,0,size,size}; dest_rect.offset(8 + TER_RECT_UL_X + size * i, 8 + TER_RECT_UL_Y + size * j); - if (get_terrain_picture(scenario.get_terrain(terrain_to_draw).get_map_picture_num(), source_gworld, from_rect)) + if (cPict::get_terrain_picture(scenario.get_terrain(terrain_to_draw).get_map_picture_num(), source_gworld, from_rect)) rect_draw_some_item(source_gworld, from_rect, mainPtr, dest_rect); if(road) { rectangle road_rect = dest_rect; @@ -1253,7 +1201,7 @@ void draw_frames() { static void place_selected_terrain(ter_num_t ter, rectangle draw_rect) { rectangle source_rect; Texture source_gworld; - if (get_terrain_picture(scenario.get_terrain(ter).get_picture_num(), source_gworld, source_rect)) + if (cPict::get_terrain_picture(scenario.get_terrain(ter).get_picture_num(), source_gworld, source_rect)) rect_draw_some_item(source_gworld,source_rect, mainPtr,draw_rect); short small_i = get_small_icon(ter);