Scenario editor: try to simplify the code used to draw terrain texture +

use cPictNum to retrieve the big terrain pictures...
This commit is contained in:
ALONSO Laurent
2021-10-16 16:06:12 +02:00
committed by Celtic Minstrel
parent 7e189847ee
commit cabe7beff1
8 changed files with 78 additions and 106 deletions

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -13,6 +13,7 @@
#include <iosfwd>
#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;
};

View File

@@ -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<cPict&>(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<cPict&>(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<cPict&>(me[id]).setPict(cPictNum::getPN_for_terrain(obj[x][y]));
dynamic_cast<cPict&>(me[id]).setPict(cTerrain::get_picture_num_for_terrain(obj[x][y]));
}
}
return true;

View File

@@ -317,6 +317,35 @@ static std::vector<short> 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;

View File

@@ -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<cPict&>(sign_dlg["pic"]).setPict(cPictNum::getPN_for_terrain(picture));
dynamic_cast<cPict&>(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);