From cabe7beff17a4a28c4ef87b2c94d5dfc698efa37 Mon Sep 17 00:00:00 2001 From: ALONSO Laurent Date: Sat, 16 Oct 2021 16:06:12 +0200 Subject: [PATCH] Scenario editor: try to simplify the code used to draw terrain texture + use cPictNum to retrieve the big terrain pictures... --- src/dialogxml/widgets/pict.hpp | 11 --- src/game/boe.locutils.cpp | 3 +- src/game/boe.specials.cpp | 3 +- src/scenario/terrain.cpp | 18 +++++ src/scenario/terrain.hpp | 5 ++ src/scenedit/scen.core.cpp | 7 +- src/scenedit/scen.graphics.cpp | 135 ++++++++++++--------------------- src/scenedit/scen.townout.cpp | 2 +- 8 files changed, 78 insertions(+), 106 deletions(-) diff --git a/src/dialogxml/widgets/pict.hpp b/src/dialogxml/widgets/pict.hpp index b31fca56..e6ad3ce9 100644 --- a/src/dialogxml/widgets/pict.hpp +++ b/src/dialogxml/widgets/pict.hpp @@ -27,17 +27,6 @@ public: , type(nType) { } - static cPictNum getPN_for_terrain(short num) - { - if(num < 960) - return cPictNum(num,PIC_TER); - else if(num < 1000) - return cPictNum(num-960,PIC_TER_ANIM); - else if(num < 2000) - return cPictNum(num-1000,PIC_CUSTOM_TER); - else - return cPictNum(num-2000,PIC_CUSTOM_TER_ANIM); - } pic_num_t num; ePicType type; diff --git a/src/game/boe.locutils.cpp b/src/game/boe.locutils.cpp index d7fdfdbc..dee4f83f 100644 --- a/src/game/boe.locutils.cpp +++ b/src/game/boe.locutils.cpp @@ -308,7 +308,8 @@ bool is_blocked(location to_check) { if (univ.scenario.is_legacy) { // checkme in combat.c this is only called when is_combat() && ter_pic==406 // (ie. ter_anim+6) due to a logical error - if (univ.scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].picture==966) + cPictNum pict=univ.scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].get_picture_num(); + if (pict.num==6 && pict.type==ePicType::PIC_TER_ANIM) return true; } else { diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index fb024661..302a77eb 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -215,7 +215,8 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc, if (univ.scenario.is_legacy) { // checkme in combat.c this is only called when is_combat() && ter_pic==406 // (ie. ter_anim+6) due to a logical error - if (univ.scenario.ter_types[coord_to_ter(where_check.x,where_check.y)].picture==966) { + cPictNum pict=univ.scenario.ter_types[coord_to_ter(where_check.x,where_check.y)].get_picture_num(); + if (pict.num==6 && pict.type==ePicType::PIC_TER_ANIM) { ASB("Move: Can't trigger this special in combat."); return true; } diff --git a/src/scenario/terrain.cpp b/src/scenario/terrain.cpp index c3f772a9..04af14ba 100644 --- a/src/scenario/terrain.cpp +++ b/src/scenario/terrain.cpp @@ -413,3 +413,21 @@ bool cTerrain::blocksMove() const { int code = (int) blockage; return code > 2; } + +cPictNum cTerrain::get_picture_num_for_terrain(pic_num_t bigPicture) +{ + /* in old source num < 400 : PIC_TER + else num < 1000 : PIC_TER_ANIM + else : PIC_CUSTOM_TER + */ + if(bigPicture < 0) + return cPictNum(-1,PIC_NONE); + if(bigPicture < 960) + return cPictNum(bigPicture,PIC_TER); + if(bigPicture < 1000) + return cPictNum(bigPicture-960,PIC_TER_ANIM); + if(bigPicture < 2000) + return cPictNum(bigPicture-1000,PIC_CUSTOM_TER); + return cPictNum(bigPicture-2000,PIC_CUSTOM_TER_ANIM); +} + diff --git a/src/scenario/terrain.hpp b/src/scenario/terrain.hpp index a6b817e2..5c3602e0 100644 --- a/src/scenario/terrain.hpp +++ b/src/scenario/terrain.hpp @@ -13,6 +13,7 @@ #include #include "pictypes.hpp" +#include "pict.hpp" #include "location.hpp" #include "terrain_abilities.hpp" @@ -46,6 +47,10 @@ public: unsigned short i; // for temporary use in porting bool blocksMove() const; + cPictNum get_picture_num() const { + return get_picture_num_for_terrain(picture); + } + static cPictNum get_picture_num_for_terrain(pic_num_t bigPicture); void import_legacy(legacy::terrain_type_type const &old); void writeTo(std::ostream& file) const; }; diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index ae87a14b..07e10c6c 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -353,9 +353,8 @@ static void fill_ter_info(cDialog& me, short ter){ cTerrain& ter_type = scenario.ter_types[ter]; { cPict& pic_ctrl = dynamic_cast(me["graphic"]); - pic_num_t pic = ter_type.picture; - pic_ctrl.setPict(cPictNum::getPN_for_terrain(pic)); - me["pict"].setTextToNum(pic); + pic_ctrl.setPict(ter_type.get_picture_num()); + me["pict"].setTextToNum(ter_type.picture); }{ cPict& pic_ctrl = dynamic_cast(me["seemap"]); pic_num_t pic = ter_type.map_pic; @@ -485,7 +484,7 @@ static bool edit_ter_obj(cDialog& me, ter_num_t which_ter) { for(int x = 0; x < 4; x++) { for(int y = 0; y < 4; y++) { std::string id = "x" + std::to_string(x) + "y" + std::to_string(y); - dynamic_cast(me[id]).setPict(cPictNum::getPN_for_terrain(obj[x][y])); + dynamic_cast(me[id]).setPict(cTerrain::get_picture_num_for_terrain(obj[x][y])); } } return true; diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index 1b0f1be8..752c78da 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -317,6 +317,35 @@ 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) +{ + source=Texture(); + switch (pict.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_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 (bool(source)) + return true; + std::cerr << "Error[get_terrain_picture]: can not find picture id=" << pict.num << "type=" << int(pict.type)<< "\n"; + return false; +} + 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); @@ -526,34 +555,14 @@ void set_up_terrain_buttons(bool reset) { rectangle draw_rect = terrain_rects[i - first]; draw_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y); switch(draw_mode){ - case DRAW_TERRAIN: + case DRAW_TERRAIN: { if(i == scenario.ter_types.size()) { rect_draw_some_item(editor_mixed, ter_plus_from, mainPtr, draw_rect); break; } - ter_from = ter_from_base; - pic = scenario.ter_types[i].picture; - if(pic >= 1000) { - Texture source_gworld; - std::tie(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000); - rect_draw_some_item(source_gworld, ter_from, mainPtr, draw_rect); - } - else if(pic < 960) { - pic = pic % 50; - ter_from.offset(28 * (pic % 10), 36 * (pic / 10)); - int which_sheet = scenario.ter_types[i].picture / 50; - rect_draw_some_item(*ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)), - ter_from, mainPtr, draw_rect); - } - else { - pic = (pic - 560) % 50; - ter_from.left = 112 * (pic / 5); - ter_from.right = ter_from.left + 28; - ter_from.top = 36 * (pic % 5); - ter_from.bottom = ter_from.top + 36; - rect_draw_some_item(*ResMgr::textures.get("teranim"), ter_from, mainPtr, draw_rect); - - } + Texture source_gworld; + if (get_terrain_picture(scenario.ter_types[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; tiny_from.offset(7 * (small_i % 30),7 * (small_i / 30)); @@ -563,6 +572,7 @@ void set_up_terrain_buttons(bool reset) { if(small_i >= 0 && small_i < 255) rect_draw_some_item(editor_mixed, tiny_from, mainPtr, tiny_to); break; + } case DRAW_MONST: pic = scenario.scen_monsters[i].picture_num; tiny_to = draw_rect; @@ -1108,36 +1118,17 @@ void force_tiny_redraw() { } void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) { - location where_draw; - rectangle source_rect; - short picture_wanted; - Texture source_gworld; - if(i < 0 || i > 8 || j < 0 || j > 8) return; - picture_wanted = scenario.ter_types[terrain_to_draw].picture; - + rectangle source_rect; + Texture source_gworld; + if (!get_terrain_picture(scenario.ter_types[terrain_to_draw].get_picture_num(), source_gworld, source_rect)) + return; + + location where_draw; where_draw.x = (char) i; where_draw.y = (char) j; - - if(picture_wanted >= 1000 && spec_scen_g) { - std::tie(source_gworld,source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); - } - else if(picture_wanted >= 960) { - source_gworld = *ResMgr::textures.get("teranim"); - picture_wanted -= 960; - source_rect.left = 112 * (picture_wanted / 5); - source_rect.right = source_rect.left + 28; - source_rect.top = 36 * (picture_wanted % 5); - source_rect.bottom = source_rect.top + 36; - } - else { - source_rect = get_template_rect(terrain_to_draw); - int which_sheet = picture_wanted / 50; - source_gworld = *ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)); - } - rectangle destrec; destrec.left = 8 + BITMAP_WIDTH * where_draw.x; destrec.right = destrec.left + BITMAP_WIDTH; @@ -1151,29 +1142,14 @@ void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) { void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short size,bool road) { rectangle dest_rect = {0,0,size,size},from_rect = {0,0,12,12}; short picture_wanted; - bool drawLargeIcon = false; Texture source_gworld; picture_wanted = scenario.ter_types[terrain_to_draw].map_pic; - if(picture_wanted == NO_PIC) { - drawLargeIcon = true; - picture_wanted = scenario.ter_types[terrain_to_draw].picture; - } dest_rect.offset(8 + TER_RECT_UL_X + size * i, 8 + TER_RECT_UL_Y + size * j); - if(drawLargeIcon) { - if(picture_wanted >= 1000) { - std::tie(source_gworld,from_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); - } else if(picture_wanted >= 960) { - source_gworld = *ResMgr::textures.get("teranim"); - from_rect = calc_rect(4 * ((picture_wanted - 960) / 5),(picture_wanted - 960) % 5); - } else { - int which_sheet = picture_wanted / 50; - source_gworld = *ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)); - picture_wanted %= 50; - from_rect = calc_rect(picture_wanted % 10, picture_wanted / 10); - } - rect_draw_some_item(source_gworld, from_rect, mainPtr, dest_rect); + if(picture_wanted == NO_PIC) { + if (get_terrain_picture(scenario.ter_types[terrain_to_draw].get_picture_num(), source_gworld, from_rect)) + rect_draw_some_item(source_gworld, from_rect, mainPtr, dest_rect); } else { if(picture_wanted >= 1000) { Texture from_gw; @@ -1276,28 +1252,11 @@ void draw_frames() { } static void place_selected_terrain(ter_num_t ter, rectangle draw_rect) { - pic_num_t picture_wanted = scenario.ter_types[ter].picture; rectangle source_rect; - if(picture_wanted >= 1000) { - Texture source_gworld; - std::tie(source_gworld,source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); - rect_draw_some_item(source_gworld, source_rect, mainPtr,draw_rect); - } - else if(picture_wanted >= 960) { - picture_wanted -= 960; - source_rect.left = 112 * (picture_wanted / 5); - source_rect.right = source_rect.left + 28; - source_rect.top = 36 * (picture_wanted % 5); - source_rect.bottom = source_rect.top + 36; - rect_draw_some_item(*ResMgr::textures.get("teranim"),source_rect,mainPtr,draw_rect); - } - else { - source_rect = get_template_rect(ter); - int which_sheet = picture_wanted / 50; - auto const & terrain_gworld = *ResMgr::textures.get("ter" + std::to_string(1 + which_sheet)); - rect_draw_some_item(terrain_gworld,source_rect, - mainPtr,draw_rect); - } + Texture source_gworld; + if (get_terrain_picture(scenario.ter_types[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); rectangle tiny_to = draw_rect; tiny_to.top = tiny_to.bottom - 7; diff --git a/src/scenedit/scen.townout.cpp b/src/scenedit/scen.townout.cpp index 1d06fb1a..5773195c 100644 --- a/src/scenedit/scen.townout.cpp +++ b/src/scenedit/scen.townout.cpp @@ -368,7 +368,7 @@ void edit_sign(sign_loc_t& which_sign,short num,short picture) { cDialog sign_dlg("edit-sign"); sign_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, &sign_dlg, false)); sign_dlg["okay"].attachClickHandler(std::bind(edit_sign_event_filter, _1, std::ref(which_sign))); - dynamic_cast(sign_dlg["pic"]).setPict(cPictNum::getPN_for_terrain(picture)); + dynamic_cast(sign_dlg["pic"]).setPict(cTerrain::get_picture_num_for_terrain(picture)); // checkme: does this really need to be some terrain? sign_dlg["num"].setTextToNum(num); sign_dlg["text"].setText(which_sign.text);