widgets/pict.hpp: add a class cPictNum to store a picture number and its type,

game[legacy]: only prevent walking on portail in combat mode
Scenario Editor: begin to use cPictNum to avoid crashing when displaying some
  terrain animations, to be continued...
This commit is contained in:
ALONSO Laurent
2021-10-16 12:43:23 +02:00
committed by Celtic Minstrel
parent fdb2b0e0d8
commit 7e189847ee
5 changed files with 56 additions and 27 deletions

View File

@@ -20,6 +20,29 @@
#include "pictypes.hpp" #include "pictypes.hpp"
#include "texture.hpp" #include "texture.hpp"
class cPictNum {
public:
explicit cPictNum(pic_num_t nNum=-1, ePicType nType=ePicType::PIC_NONE)
: num(nNum)
, 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;
};
/// A simple icon. /// A simple icon.
/// This control can also be made clickable. /// This control can also be made clickable.
class cPict : public cControl { class cPict : public cControl {
@@ -44,6 +67,7 @@ public:
/// and applies the custom modifier. (If type is PIC_TER_MAP, it does not take the remainder by 1000.) /// and applies the custom modifier. (If type is PIC_TER_MAP, it does not take the remainder by 1000.)
/// - If num is 10000 or greater and type is PIC_TER_MAP, it automatically subtracts 10000 and applies the party modifier. /// - If num is 10000 or greater and type is PIC_TER_MAP, it automatically subtracts 10000 and applies the party modifier.
void setPict(pic_num_t num, ePicType type); void setPict(pic_num_t num, ePicType type);
void setPict(cPictNum const &num) { setPict(num.num, num.type); }
/// Set the pict's icon. /// Set the pict's icon.
/// @param num The new icon index. /// @param num The new icon index.
void setPict(pic_num_t num); void setPict(pic_num_t num);

View File

@@ -304,13 +304,19 @@ bool is_blocked(location to_check) {
return true; return true;
} }
// checkme in combat.c this is only called when is_combat() && ter_pic==406 if (is_combat()) {
// due to a logical error if (univ.scenario.is_legacy) {
if(is_combat() && !univ.scenario.is_legacy && univ.town.is_spot(to_check.x, to_check.y)) // checkme in combat.c this is only called when is_combat() && ter_pic==406
return true; // (ie. ter_anim+6) due to a logical error
if(is_combat() && univ.scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].trim_type == eTrimType::CITY) if (univ.scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].picture==966)
return true; // TODO: Maybe replace eTrimType::CITY with a blockage == clear/special && is_special() check return true;
// Note: The purpose of the above check is to avoid portals. }
else {
if(univ.town.is_spot(to_check.x, to_check.y) || 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.
}
}
// Party there? // Party there?
if(is_town()) if(is_town())

View File

@@ -211,11 +211,22 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
} }
} }
// checkme in combat.c this is only called when is_combat() && ter_pic==406 if (is_combat()) {
// due to a logical error if (univ.scenario.is_legacy) {
if(is_combat() && ((!univ.scenario.is_legacy && univ.town.is_spot(where_check.x, where_check.y)) || terrain.trim_type == eTrimType::CITY)) { // checkme in combat.c this is only called when is_combat() && ter_pic==406
ASB("Move: Can't trigger this special in combat."); // (ie. ter_anim+6) due to a logical error
return false; // TODO: Maybe replace eTrimType::CITY check with a blockage == clear/special && is_special() check? if (univ.scenario.ter_types[coord_to_ter(where_check.x,where_check.y)].picture==966) {
ASB("Move: Can't trigger this special in combat.");
return true;
}
}
else {
if(univ.town.is_spot(where_check.x, where_check.y) || 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 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.
}
}
} }
if(mode != eSpecCtx::OUT_MOVE && univ.town.is_force_barr(where_check.x,where_check.y)) { if(mode != eSpecCtx::OUT_MOVE && univ.town.is_force_barr(where_check.x,where_check.y)) {

View File

@@ -354,14 +354,7 @@ static void fill_ter_info(cDialog& me, short ter){
{ {
cPict& pic_ctrl = dynamic_cast<cPict&>(me["graphic"]); cPict& pic_ctrl = dynamic_cast<cPict&>(me["graphic"]);
pic_num_t pic = ter_type.picture; pic_num_t pic = ter_type.picture;
if(pic < 960) pic_ctrl.setPict(cPictNum::getPN_for_terrain(pic));
pic_ctrl.setPict(pic, PIC_TER);
else if(pic < 1000)
pic_ctrl.setPict(pic - 960, PIC_TER_ANIM);
else if(pic < 2000)
pic_ctrl.setPict(pic % 1000, PIC_CUSTOM_TER);
else
pic_ctrl.setPict(pic % 2000, PIC_CUSTOM_TER_ANIM);
me["pict"].setTextToNum(pic); me["pict"].setTextToNum(pic);
}{ }{
cPict& pic_ctrl = dynamic_cast<cPict&>(me["seemap"]); cPict& pic_ctrl = dynamic_cast<cPict&>(me["seemap"]);
@@ -492,7 +485,7 @@ static bool edit_ter_obj(cDialog& me, ter_num_t which_ter) {
for(int x = 0; x < 4; x++) { for(int x = 0; x < 4; x++) {
for(int y = 0; y < 4; y++) { for(int y = 0; y < 4; y++) {
std::string id = "x" + std::to_string(x) + "y" + std::to_string(y); std::string id = "x" + std::to_string(x) + "y" + std::to_string(y);
dynamic_cast<cPict&>(me[id]).setPict(obj[x][y]); dynamic_cast<cPict&>(me[id]).setPict(cPictNum::getPN_for_terrain(obj[x][y]));
} }
} }
return true; return true;

View File

@@ -368,12 +368,7 @@ void edit_sign(sign_loc_t& which_sign,short num,short picture) {
cDialog sign_dlg("edit-sign"); cDialog sign_dlg("edit-sign");
sign_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, &sign_dlg, false)); 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))); sign_dlg["okay"].attachClickHandler(std::bind(edit_sign_event_filter, _1, std::ref(which_sign)));
cPict& icon = dynamic_cast<cPict&>(sign_dlg["pic"]); dynamic_cast<cPict&>(sign_dlg["pic"]).setPict(cPictNum::getPN_for_terrain(picture));
if(picture >= 960 && picture < 1000)
icon.setPict(picture, PIC_TER_ANIM);
else if(picture >= 2000)
icon.setPict(picture - 2000, PIC_CUSTOM_TER_ANIM);
else icon.setPict(picture, PIC_TER); // automatically adjusts for custom graphics
sign_dlg["num"].setTextToNum(num); sign_dlg["num"].setTextToNum(num);
sign_dlg["text"].setText(which_sign.text); sign_dlg["text"].setText(which_sign.text);