Scenerio Editor: try to allow to edit scenario with bogus terrain type or

bogus terrain picture nums.
This commit is contained in:
ALONSO Laurent
2021-10-18 10:05:52 +02:00
committed by Celtic Minstrel
parent e4d220799e
commit 1b7dcaab1f
10 changed files with 129 additions and 101 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -211,6 +211,26 @@ cScenario::cItemStorage::cItemStorage() : ter_type(-1), property(0) {
item_odds[i] = 0;
}
cTerrain const &cScenario::get_terrain(ter_num_t ter) const
{
if (ter<ter_types.size())
return ter_types[ter];
static cTerrain badTerrain;
badTerrain.picture = -3;
badTerrain.map_pic = -3;
return badTerrain;
}
cTerrain &cScenario::get_terrain(ter_num_t ter)
{
if (ter<ter_types.size())
return ter_types[ter];
static cTerrain badTerrain;
badTerrain.picture = -3;
badTerrain.map_pic = -3;
return badTerrain;
}
void cScenario::import_legacy(legacy::scenario_data_type const &old){
is_legacy = true;
difficulty = old.difficulty;

View File

@@ -49,6 +49,8 @@ public:
cItemStorage& operator = (legacy::item_storage_shortcut_type const &old);
};
void destroy_terrain();
cTerrain const &get_terrain(ter_num_t ter) const;
cTerrain &get_terrain(ter_num_t ter);
public:
unsigned short difficulty,intro_pic,default_ground;
int bg_out, bg_fight, bg_town, bg_dungeon;

View File

@@ -421,7 +421,7 @@ cPictNum cTerrain::get_picture_num_for_terrain(pic_num_t bigPicture)
else : PIC_CUSTOM_TER
*/
if(bigPicture < 0)
return cPictNum(-1,PIC_NONE);
return cPictNum(bigPicture,PIC_NONE);
if(bigPicture < 960)
return cPictNum(bigPicture,PIC_TER);
if(bigPicture < 1000)

View File

@@ -794,7 +794,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
break;
case 0:
overall_mode = MODE_DRAWING;
set_string("Drawing mode",scenario.ter_types[current_terrain_type].name);
set_string("Drawing mode",scenario.get_terrain(current_terrain_type).name);
break;
}
break;
@@ -983,7 +983,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
{
auto& signs = editing_town ? town->sign_locs : current_terrain->sign_locs;
auto iter = std::find(signs.begin(), signs.end(), spot_hit);
short picture = scenario.ter_types[editing_town ? town->terrain(spot_hit.x,spot_hit.y) : current_terrain->terrain[spot_hit.x][spot_hit.y]].picture;
short picture = scenario.get_terrain(editing_town ? town->terrain(spot_hit.x,spot_hit.y) : current_terrain->terrain[spot_hit.x][spot_hit.y]).picture;
if(iter != signs.end()) {
edit_sign(*iter, iter - signs.begin(), picture);
} else {
@@ -1145,7 +1145,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
break; // Nothing to do here, of course.
}
if((overall_mode == MODE_DRAWING) && (old_mode != MODE_DRAWING))
set_string("Drawing mode",scenario.ter_types[current_terrain_type].name);
set_string("Drawing mode",scenario.get_terrain(current_terrain_type).name);
draw_terrain();
return true;
}
@@ -1228,10 +1228,10 @@ static bool handle_terpal_action(location cur_point, bool option_hit) {
else if(i == size_before) {
scenario.ter_types.resize(size_before + 16);
for(; i < scenario.ter_types.size(); i++)
scenario.ter_types[i].name = "New Terrain";
scenario.get_terrain(i).name = "New Terrain";
} else {
scenario.ter_types[i] = cTerrain();
scenario.ter_types[i].name = "Unused Terrain";
scenario.get_terrain(i) = cTerrain();
scenario.get_terrain(i).name = "Unused Terrain";
}
} else {
if(i == size_before) {
@@ -1262,27 +1262,28 @@ static bool handle_toolpal_action(location cur_point2) {
rectangle temp_rect = palette_buttons[i][j];
temp_rect.offset(RIGHT_AREA_UL_X + 5, RIGHT_AREA_UL_Y + terrain_rects[255].bottom + 5);
flash_rect(temp_rect);
auto const &ter_type=scenario.get_terrain(current_terrain_type);
switch(cur_palette_buttons[j][i]) {
case PAL_ARROW_UP: case PAL_ARROW_DOWN: // These two might never be used.
case PAL_BLANK: break;
case PAL_PENCIL:
set_string("Drawing mode",scenario.ter_types[current_terrain_type].name);
set_string("Drawing mode",ter_type.name);
overall_mode = MODE_DRAWING;
break;
case PAL_BRUSH_LG:
set_string("Paintbrush (large)",scenario.ter_types[current_terrain_type].name);
set_string("Paintbrush (large)",ter_type.name);
overall_mode = MODE_LARGE_PAINTBRUSH;
break;
case PAL_BRUSH_SM:
set_string("Paintbrush (small)",scenario.ter_types[current_terrain_type].name);
set_string("Paintbrush (small)",ter_type.name);
overall_mode = MODE_SMALL_PAINTBRUSH;
break;
case PAL_SPRAY_LG:
set_string("Spraycan (large)",scenario.ter_types[current_terrain_type].name);
set_string("Spraycan (large)",ter_type.name);
overall_mode = MODE_LARGE_SPRAYCAN;
break;
case PAL_SPRAY_SM:
set_string("Spraycan (small)",scenario.ter_types[current_terrain_type].name);
set_string("Spraycan (small)",ter_type.name);
overall_mode = MODE_SMALL_SPRAYCAN;
break;
case PAL_DROPPER:
@@ -1300,7 +1301,7 @@ static bool handle_toolpal_action(location cur_point2) {
break;
case PAL_BUCKET:
overall_mode = MODE_FLOOD_FILL;
set_string("Flood fill", scenario.ter_types[current_terrain_type].name);
set_string("Flood fill", ter_type.name);
break;
case PAL_ZOOM: // switch view
cur_viewing_mode = (cur_viewing_mode + 1) % 4;
@@ -1602,15 +1603,15 @@ void set_new_terrain(ter_num_t selected_terrain) {
if(selected_terrain >= scenario.ter_types.size()) return;
current_terrain_type = selected_terrain;
current_ground = scenario.get_ground_from_ter(selected_terrain);
cTerrain& ter = scenario.ter_types[current_terrain_type];
cTerrain& gter = scenario.ter_types[current_ground];
cTerrain const & ter = scenario.get_terrain(current_terrain_type);
cTerrain const &gter = scenario.get_terrain(current_ground);
if(gter.blockage >= eTerObstruct::BLOCK_MOVE || ter.trim_type == eTrimType::WALKWAY || /*current_ground == current_terrain_type ||*/
(ter.trim_type >= eTrimType::S && ter.trim_type <= eTrimType::NW_INNER)) {
long trim = scenario.ter_types[current_ground].trim_ter;
long trim = gter.trim_ter;
if(trim < 0) current_ground = 0;
else current_ground = scenario.get_ter_from_ground(trim);
}
set_string(current_string[0],scenario.ter_types[current_terrain_type].name);
set_string(current_string[0],ter.name);
}
void handle_keystroke(sf::Event event) {
@@ -1870,7 +1871,7 @@ void unfrill_terrain() {
for(short i = 0; i < ((editing_town) ? town->max_dim : 48); i++)
for(short j = 0; j < ((editing_town) ? town->max_dim : 48); j++) {
terrain_type = editing_town ? town->terrain(i,j) : current_terrain->terrain[i][j];
cTerrain& ter = scenario.ter_types[terrain_type];
cTerrain const &ter = scenario.get_terrain(terrain_type);
if(ter.frill_for >= 0)
terrain_type = ter.frill_for;
@@ -1896,21 +1897,19 @@ 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(ter2 == ter) return true;
if(scenario.ter_types[ter2].ground_type != scenario.ter_types[ter].ground_type)
auto const &ter_type=scenario.get_terrain(ter);
auto const &ter_type2=scenario.get_terrain(ter2);
if(ter_type2.ground_type != ter_type.ground_type)
return false;
if(scenario.ter_types[ter].trim_type == eTrimType::NONE &&
scenario.ter_types[ter2].trim_type >= eTrimType::S &&
scenario.ter_types[ter2].trim_type <= eTrimType::NW_INNER)
if(ter_type.trim_type == eTrimType::NONE && ter_type2.trim_type >= eTrimType::S &&
ter_type2.trim_type <= eTrimType::NW_INNER)
return ter == scenario.get_ground_from_ter(ter);
if(scenario.ter_types[ter2].trim_type == eTrimType::NONE &&
scenario.ter_types[ter].trim_type >= eTrimType::S &&
scenario.ter_types[ter].trim_type <= eTrimType::NW_INNER)
if(ter_type2.trim_type == eTrimType::NONE && ter_type.trim_type >= eTrimType::S &&
ter_type.trim_type <= eTrimType::NW_INNER)
return ter2 == scenario.get_ground_from_ter(ter2);
if(scenario.ter_types[ter2].trim_type >= eTrimType::S &&
scenario.ter_types[ter2].trim_type <= eTrimType::NW_INNER &&
scenario.ter_types[ter].trim_type >= eTrimType::S &&
scenario.ter_types[ter].trim_type <= eTrimType::NW_INNER)
return scenario.ter_types[ter].trim_type != scenario.ter_types[ter2].trim_type;
if(ter_type2.trim_type >= eTrimType::S && ter_type2.trim_type <= eTrimType::NW_INNER &&
ter_type.trim_type >= eTrimType::S && ter_type.trim_type <= eTrimType::NW_INNER)
return ter_type.trim_type != ter_type2.trim_type;
return false;
}
@@ -1932,10 +1931,11 @@ void set_terrain(location l,ter_num_t terrain_type) {
l2 = l;
// Large objects (eg rubble)
if(scenario.ter_types[terrain_type].obj_num > 0){
int q = scenario.ter_types[terrain_type].obj_num;
location obj_loc = scenario.ter_types[terrain_type].obj_pos;
location obj_dim = scenario.ter_types[terrain_type].obj_size;
auto const &ter_type=scenario.get_terrain(terrain_type);
if(ter_type.obj_num > 0){
int q = ter_type.obj_num;
location obj_loc = ter_type.obj_pos;
location obj_dim = ter_type.obj_size;
while(obj_loc.x > 0) l2.x-- , obj_loc.x--;
while(obj_loc.y > 0) l2.y-- , obj_loc.y--;
for(short i = 0; i < obj_dim.x; i++)
@@ -1948,17 +1948,18 @@ void set_terrain(location l,ter_num_t terrain_type) {
// First make sure surrounding spaces have the correct ground types.
// This should handle the case of placing hills around mountains.
unsigned int main_ground = scenario.ter_types[terrain_type].ground_type;
long trim_ground = scenario.ter_types[terrain_type].trim_ter;
auto const &terrain_ground=scenario.get_terrain(terrain_type);
unsigned int main_ground = terrain_ground.ground_type;
long trim_ground = terrain_ground.trim_ter;
for(int x = -1; x <= 1; x++) {
for(int y = -1; y <= 1; y++) {
location l3(l.x+x,l.y+y);
ter_num_t ter_there = editing_town ? town->terrain(l3.x,l3.y) : current_terrain->terrain[l3.x][l3.y];
unsigned int ground_there = scenario.ter_types[ter_there].ground_type;
unsigned int ground_there = scenario.get_terrain(ter_there).ground_type;
if(ground_there != main_ground && ground_there != trim_ground) {
ter_num_t new_ter = scenario.get_ter_from_ground(trim_ground);
if(new_ter > scenario.ter_types.size()) continue;
cTerrain& ter_type = scenario.ter_types[new_ter];
cTerrain const & ter_type = scenario.get_terrain(new_ter);
// We need to be very cautious here.
// Only make the change if the terrain already there is the archetype for the ground type
// that is the trim terrain of the terrain we're trying to place.
@@ -1978,7 +1979,7 @@ void set_terrain(location l,ter_num_t terrain_type) {
adjust_space(l3);
}
if(scenario.ter_types[terrain_type].special == eTerSpec::IS_A_SIGN) {
if(terrain_ground.special == eTerSpec::IS_A_SIGN) {
if(!editing_town && (l.x == 0 || l.x == 47 || l.y == 0 || l.y == 47)) {
cChoiceDlog("not-at-edge").show();
mouse_button_held = false;
@@ -1990,7 +1991,7 @@ void set_terrain(location l,ter_num_t terrain_type) {
iter = std::find_if(signs.begin(), signs.end(), [](const sign_loc_t& sign) {
if(sign.x == 100) return true;
ter_num_t ter = editing_town ? town->terrain(sign.x,sign.y) : current_terrain->terrain[sign.x][sign.y];
return scenario.ter_types[ter].special != eTerSpec::IS_A_SIGN;
return scenario.get_terrain(ter).special != eTerSpec::IS_A_SIGN;
});
if(iter == signs.end()) {
signs.emplace_back();
@@ -1999,7 +2000,7 @@ void set_terrain(location l,ter_num_t terrain_type) {
}
static_cast<location&>(*iter) = l;
ter_num_t terrain_type = editing_town ? town->terrain(iter->x,iter->y) : current_terrain->terrain[iter->x][iter->y];
edit_sign(*iter, iter - signs.begin(), scenario.ter_types[terrain_type].picture);
edit_sign(*iter, iter - signs.begin(), scenario.get_terrain(terrain_type).picture);
mouse_button_held = false;
}
}
@@ -2030,7 +2031,7 @@ void adjust_space(location l) {
continue;
}
store_ter[dx+1][dy+1] = editing_town ? town->terrain(x,y) : current_terrain->terrain[x][y];
cTerrain& ter_type = scenario.ter_types[store_ter[dx+1][dy+1]];
cTerrain const &ter_type = scenario.get_terrain(store_ter[dx+1][dy+1]);
store_ter2[dx+1][dy+1] = ter_type.trim_ter;
store_ground[dx+1][dy+1] = ter_type.ground_type;
store_trim[dx+1][dy+1] = ter_type.trim_type;
@@ -2043,7 +2044,7 @@ void adjust_space(location l) {
if(store_trim[1][1] >= eTrimType::FRILLS || store_trim[1][1] == eTrimType::WALL)
return;
bool have_wall = scenario.ter_types[store_ter[1][1]].blockage >= eTerObstruct::BLOCK_MOVE;
bool have_wall = scenario.get_terrain(store_ter[1][1]).blockage >= eTerObstruct::BLOCK_MOVE;
unsigned int main_ground = store_ground[1][1];
long trim_ground = store_ter2[1][1];
@@ -2206,7 +2207,7 @@ void set_special(location spot_hit) {
void town_entry(location spot_hit) {
ter_num_t ter = current_terrain->terrain[spot_hit.x][spot_hit.y];
if(scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE) {
if(scenario.get_terrain(ter).special != eTerSpec::TOWN_ENTRANCE) {
showError("This space isn't a town entrance. Town entrances are marked by a small brown castle icon.");
return;
}
@@ -2214,7 +2215,7 @@ void town_entry(location spot_hit) {
for(short x = 0; x < current_terrain->city_locs.size(); x++)
if(current_terrain->city_locs[x].spec >= 0) {
ter = current_terrain->terrain[current_terrain->city_locs[x].x][current_terrain->city_locs[x].y];
if(scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE)
if(scenario.get_terrain(ter).special != eTerSpec::TOWN_ENTRANCE)
current_terrain->city_locs[x].spec = -1;
}
auto iter = std::find(current_terrain->city_locs.begin(), current_terrain->city_locs.end(), spot_hit);
@@ -2336,7 +2337,7 @@ void start_town_edit() {
shut_down_menus(2);
right_sbar->hide();
pal_sbar->show();
set_string("Drawing mode",scenario.ter_types[current_terrain_type].name);
set_string("Drawing mode",scenario.get_terrain(current_terrain_type).name);
place_location();
copied_spec = -1;
for(short i = 0; i < town->max_dim; i++)
@@ -2367,7 +2368,7 @@ void start_out_edit() {
pal_sbar->show();
shut_down_menus(4);
shut_down_menus(1);
set_string("Drawing mode",scenario.ter_types[current_terrain_type].name);
set_string("Drawing mode",scenario.get_terrain(current_terrain_type).name);
place_location();
copied_spec = -1;
for(short i = 0; i < 48; i++)

View File

@@ -349,38 +349,34 @@ static bool fill_ter_flag_info(cDialog& me, std::string id, bool losing){
return true;
}
// REMOVEME when setPict will not do fatal error
bool check_picture_num(cPictNum const &pic, bool noneIsOk)
try {
if (noneIsOk && pic.num==-1)
return true;
if (pic.num<0)
return false;
if (pic.type==ePicType::PIC_TER)
// REMOVEME when setPict will not do fatal error
*ResMgr::textures.get("ter" + std::to_string(1 + pic.num / 50));
return true;
}
catch(...) {
return false;
}
static void fill_ter_info(cDialog& me, short ter){
cTerrain& ter_type = scenario.ter_types[ter];
cTerrain const & ter_type = scenario.get_terrain(ter);
{
cPict& pic_ctrl = dynamic_cast<cPict&>(me["graphic"]);
bool bad=false;
if (ter_type.get_picture_num().type==ePicType::PIC_TER) {
// REMOVEME when setPict will not do fatal error
try {
*ResMgr::textures.get("ter" + std::to_string(1 + ter_type.get_picture_num().num / 50));
}
catch(...) {
bad=true;
}
}
if (!bad)
if (check_picture_num(ter_type.get_picture_num(), false)) // REMOVEME
pic_ctrl.setPict(ter_type.get_picture_num());
else
pic_ctrl.setPict(cPictNum(1999,ePicType::PIC_CUSTOM_TER));
me["pict"].setTextToNum(ter_type.picture);
}{
cPict& pic_ctrl = dynamic_cast<cPict&>(me["seemap"]);
bool bad=false;
if (ter_type.get_map_picture_num().type==ePicType::PIC_TER) {
// REMOVEME when setPict will not do fatal error
try {
*ResMgr::textures.get("ter" + std::to_string(1 + ter_type.get_map_picture_num().num / 50));
}
catch(...) {
bad=true;
}
}
if (!bad) // FIXME the picture size is bad if we revert to the main picture
if (check_picture_num(ter_type.get_map_picture_num(), false)) // REMOVEME
pic_ctrl.setPict(ter_type.get_map_picture_num());
else
pic_ctrl.setPict(cPictNum(1999,ePicType::PIC_CUSTOM_TER));
@@ -453,7 +449,7 @@ static void fill_ter_info(cDialog& me, short ter){
}
static bool finish_editing_ter(cDialog& me, std::string id, ter_num_t& which) {
if(!save_ter_info(me, scenario.ter_types[which])) return true;
if(!save_ter_info(me, scenario.get_terrain(which))) return true;
if(!me.toast(true)) return true;
if(id == "left") {
@@ -473,7 +469,7 @@ static bool finish_editing_ter(cDialog& me, std::string id, ter_num_t& which) {
}
static bool edit_ter_obj(cDialog& me, ter_num_t which_ter) {
cTerrain& ter = scenario.ter_types[which_ter];
cTerrain& ter = scenario.get_terrain(which_ter);
const pic_num_t pic = ter.picture;
cDialog obj_dlg("edit-ter-obj", &me);
obj_dlg.attachFocusHandlers([&pic](cDialog& me, std::string fld, bool losing) -> bool {
@@ -507,7 +503,10 @@ 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);
if (check_picture_num(cTerrain::get_picture_num_for_terrain(obj[x][y]), true))
dynamic_cast<cPict&>(me[id]).setPict(cTerrain::get_picture_num_for_terrain(obj[x][y]));
else
dynamic_cast<cPict&>(me[id]).setPict(cPictNum(1999,ePicType::PIC_CUSTOM_TER));
}
}
return true;

View File

@@ -22,6 +22,7 @@ void edit_scenario_events();
bool build_scenario();
bool edit_vehicle(class cVehicle& what, int num, bool is_boat);
bool check_picture_num(cPictNum const &pic, bool noneIsOk);
bool check_range_msg(cDialog& me,std::string id,bool losing,long min_val,long max_val,std::string fld_name,std::string xtra);
bool check_range(cDialog& me,std::string id,bool losing,long min_val,long max_val,std::string fld_name);
bool pick_string(std::string from_file, cDialog& parent, std::string result_fld, std::string str_fld);

View File

@@ -88,15 +88,16 @@ extern bool small_any_drawn;
static short get_small_icon(ter_num_t ter){
short icon = -1;
switch(scenario.ter_types[ter].special){
auto const &ter_type=scenario.get_terrain(ter);
switch(ter_type.special){
case eTerSpec::NONE:
icon = scenario.ter_types[ter].flag1;
icon = ter_type.flag1;
break;
case eTerSpec::CHANGE_WHEN_STEP_ON:
icon = 87;
break;
case eTerSpec::DAMAGING:
switch(eDamageType(scenario.ter_types[ter].flag3)) {
switch(eDamageType(ter_type.flag3)) {
case eDamageType::WEAPON:
icon = 16;
break;
@@ -136,50 +137,50 @@ static short get_small_icon(ter_num_t ter){
break;
case eTerSpec::DANGEROUS:
icon = 12;
switch((eStatus)scenario.ter_types[ter].flag3){
switch((eStatus)ter_type.flag3){
case eStatus::POISONED_WEAPON: // TODO: Do something here
break;
case eStatus::BLESS_CURSE:
icon = scenario.ter_types[ter].flag1 > 0 ? 4 : 5;
icon = ter_type.flag1 > 0 ? 4 : 5;
break;
case eStatus::POISON:
if(scenario.ter_types[ter].flag1 > 0)
if(ter_type.flag1 > 0)
icon = 1;
break;
case eStatus::HASTE_SLOW:
icon = scenario.ter_types[ter].flag1 > 0 ? 6 : 7;
icon = ter_type.flag1 > 0 ? 6 : 7;
break;
case eStatus::INVULNERABLE: // TODO: Do something here
break;
case eStatus::MAGIC_RESISTANCE: // TODO: Do something here
break;
case eStatus::WEBS:
if(scenario.ter_types[ter].flag1 > 0)
if(ter_type.flag1 > 0)
icon = 52;
break;
case eStatus::DISEASE:
if(scenario.ter_types[ter].flag1 > 0)
if(ter_type.flag1 > 0)
icon = 0;
break;
case eStatus::INVISIBLE: // TODO: Do something here
break;
case eStatus::DUMB:
icon = scenario.ter_types[ter].flag1 > 0 ? 8 : 9;
icon = ter_type.flag1 > 0 ? 8 : 9;
break;
case eStatus::MARTYRS_SHIELD: // TODO: Do something here
break;
case eStatus::ASLEEP:
if(scenario.ter_types[ter].flag1 > 0)
if(ter_type.flag1 > 0)
icon = 3;
break;
case eStatus::PARALYZED: // TODO: Do something here
break;
case eStatus::ACID:
if(scenario.ter_types[ter].flag1 > 0)
if(ter_type.flag1 > 0)
icon = 2;
break;
case eStatus::FORCECAGE:
if(scenario.ter_types[ter].flag1 > 0)
if(ter_type.flag1 > 0)
icon = 43;
break;
case eStatus::MAIN: case eStatus::CHARM:
@@ -194,8 +195,8 @@ static short get_small_icon(ter_num_t ter){
icon = 94;
break;
case eTerSpec::UNLOCKABLE:
if(scenario.ter_types[ter].flag2 >= 5)
icon = (scenario.ter_types[ter].flag2 == 10) ? 96 : 95;
if(ter_type.flag2 >= 5)
icon = (ter_type.flag2 == 10) ? 96 : 95;
else icon = 94;
break;
case eTerSpec::IS_A_SIGN:
@@ -203,7 +204,7 @@ static short get_small_icon(ter_num_t ter){
break;
case eTerSpec::CALL_SPECIAL:
case eTerSpec::CALL_SPECIAL_WHEN_USED:
icon = scenario.ter_types[ter].flag3;
icon = ter_type.flag3;
break;
case eTerSpec::IS_A_CONTAINER:
icon = 93;
@@ -213,7 +214,7 @@ static short get_small_icon(ter_num_t ter){
icon = 91;
break;
case eTerSpec::CONVEYOR:
switch(scenario.ter_types[ter].flag1){
switch(ter_type.flag1){
case DIR_N:
icon = 78;
break;
@@ -292,7 +293,7 @@ static std::vector<short> get_small_icons(location at, ter_num_t t_to_draw) {
else icons.push_back(88);
}
if(editing_town) {
if(scenario.ter_types[t_to_draw].light_radius > 0)
if(scenario.get_terrain(t_to_draw).light_radius > 0)
icons.push_back(83);
for(size_t i = 0; i < town->start_locs.size(); i++)
if(at == town->start_locs[i]) {
@@ -363,7 +364,7 @@ try {
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";
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;
@@ -584,7 +585,7 @@ void set_up_terrain_buttons(bool reset) {
break;
}
Texture source_gworld;
if (get_terrain_picture(scenario.ter_types[i].get_picture_num(), source_gworld, ter_from))
if (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;
@@ -927,7 +928,7 @@ void draw_terrain(){
}
}
} else if(overall_mode == MODE_DRAWING) {
cTerrain& ter = scenario.ter_types[current_terrain_type];
cTerrain& ter = scenario.get_terrain(current_terrain_type);
if(ter.obj_num > 0) {
// TODO: Don't do this if auto-completion of large terrain objects is disabled
for(int x = 0; x < ter.obj_size.x; x++) {
@@ -1146,7 +1147,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.ter_types[terrain_to_draw].get_picture_num(), source_gworld, source_rect))
if (!get_terrain_picture(scenario.get_terrain(terrain_to_draw).get_picture_num(), source_gworld, source_rect))
return;
location where_draw;
@@ -1167,7 +1168,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.ter_types[terrain_to_draw].get_map_picture_num(), source_gworld, from_rect))
if (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;
@@ -1206,7 +1207,7 @@ rectangle get_template_rect (unsigned short type_wanted) {
rectangle store_rect;
short picture_wanted;
picture_wanted = scenario.ter_types[type_wanted].picture;
picture_wanted = scenario.get_terrain(type_wanted).picture;
if(picture_wanted >= 1000)
picture_wanted = 0;
picture_wanted = picture_wanted % 50;
@@ -1252,7 +1253,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.ter_types[ter].get_picture_num(), source_gworld, source_rect))
if (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);
@@ -1289,7 +1290,7 @@ void place_location() {
int first = pal_sbar->getPosition() * 16;
switch(draw_mode) {
case DRAW_TERRAIN:
if(first + i < scenario.ter_types.size())
if(first+i >= 0 && first + i < scenario.ter_types.size())
sout << "Terrain: " << scenario.ter_types[first + i].name;
break;
case DRAW_ITEM:
@@ -1578,7 +1579,7 @@ void take_field_type(short i,short j,eFieldType field_type) {
bool container_there(location l) {
if(!editing_town)
return false;
if(scenario.ter_types[town->terrain(l.x,l.y)].special == eTerSpec::IS_A_CONTAINER)
if(scenario.get_terrain(town->terrain(l.x,l.y)).special == eTerSpec::IS_A_CONTAINER)
return true;
if(is_field_type(l.x,l.y, OBJECT_BARREL))
return true;

View File

@@ -368,7 +368,11 @@ 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)));
if (check_picture_num(cTerrain::get_picture_num_for_terrain(picture), false)) // REMOVEME
dynamic_cast<cPict&>(sign_dlg["pic"]).setPict(cTerrain::get_picture_num_for_terrain(picture)); // checkme: does this really need to be some terrain?
else
dynamic_cast<cPict&>(sign_dlg["pic"]).setPict(cPictNum(1999,ePicType::PIC_CUSTOM_TER));
sign_dlg["num"].setTextToNum(num);
sign_dlg["text"].setText(which_sign.text);