From d900c7edefbb89599a199f3d2d1798287c3605d8 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Mon, 1 Dec 2014 19:50:19 -0500 Subject: [PATCH] Enumify terrain blockage and generalize the line of sight function This should probably be two separate commits, but they're tangled together and I don't want to spend the effort to disentangle them. --- osx/boe.actions.cpp | 4 +- osx/boe.combat.cpp | 14 ++-- osx/boe.fields.cpp | 9 +- osx/boe.graphics.cpp | 2 +- osx/boe.locutils.cpp | 140 ++++++-------------------------- osx/boe.locutils.h | 6 +- osx/boe.monster.cpp | 2 +- osx/boe.party.cpp | 6 +- osx/boe.specials.cpp | 2 +- osx/boe.town.cpp | 4 +- osx/classes/simpletypes.h | 14 ++++ osx/classes/terrain.cpp | 15 +++- osx/classes/terrain.h | 4 +- osx/scenedit/scen.actions.cpp | 149 ++-------------------------------- osx/scenedit/scen.actions.h | 4 +- osx/scenedit/scen.core.cpp | 24 +++--- osx/scenedit/scen.main.cpp | 2 +- osx/tools/graphtool.cpp | 45 ++++++++++ osx/tools/graphtool.h | 4 + 19 files changed, 150 insertions(+), 300 deletions(-) diff --git a/osx/boe.actions.cpp b/osx/boe.actions.cpp index 399b57a8..4a87fca1 100644 --- a/osx/boe.actions.cpp +++ b/osx/boe.actions.cpp @@ -976,7 +976,7 @@ bool handle_action(sf::Event event) }else if(overall_mode == MODE_DROP_TOWN) { if (adjacent(univ.town.p_loc,destination) == false) add_string_to_buf("Drop: must be adjacent."); - else if (get_obscurity(destination.x,destination.y) == 5) + else if(sight_obscurity(destination.x,destination.y) == 5) ASB("Drop: Space is blocked."); else drop_item(current_pc,store_drop_item,destination); } @@ -2206,7 +2206,7 @@ void increase_age()//// if (PSD[SDF_PARTY_FLIGHT] == 2) add_string_to_buf("You are starting to descend."); if (PSD[SDF_PARTY_FLIGHT] == 1) { - if (scenario.ter_types[univ.out[univ.party.p_loc.x][univ.party.p_loc.y]].blockage > 2) { + if(blocksMove(scenario.ter_types[univ.out[univ.party.p_loc.x][univ.party.p_loc.y]].blockage)) { add_string_to_buf(" You plummet to your deaths. "); slay_party(MAIN_STATUS_DEAD); print_buf(); diff --git a/osx/boe.combat.cpp b/osx/boe.combat.cpp index 838c6ce7..726c8722 100644 --- a/osx/boe.combat.cpp +++ b/osx/boe.combat.cpp @@ -868,7 +868,7 @@ void place_target(location target) add_string_to_buf(" Target out of range."); return; } - if ((get_obscurity(target.x,target.y) == 5) && (spell_being_cast != 41)) { + if(sight_obscurity(target.x,target.y) == 5 && spell_being_cast != 41) { add_string_to_buf(" Target space obstructed. "); return; } @@ -988,7 +988,7 @@ void do_combat_cast(location target)//// } else if (dist(pc_pos[current_pc],target) > ((spell_being_cast >= 100) ? priest_range[spell_being_cast - 100] : mage_range[spell_being_cast])) add_string_to_buf(" Target out of range."); - else if ((get_obscurity(target.x,target.y) == 5) && (spell_being_cast != 41)) + else if(sight_obscurity(target.x,target.y) == 5 && spell_being_cast != 41) add_string_to_buf(" Target space obstructed. "); else if (univ.town.is_antimagic(target.x,target.y)) add_string_to_buf(" Target in antimagic field."); @@ -3515,7 +3515,7 @@ location find_fireball_loc(location where,short radius,short mode,short *m) for (check_loc.x = 1; check_loc.x < univ.town->max_dim() - 1; check_loc.x ++) for (check_loc.y = 1; check_loc.y < univ.town->max_dim() - 1; check_loc.y ++) - if ((dist(where,check_loc) <= 8) && (can_see(where,check_loc,2) < 5) && (get_obscurity(check_loc.x,check_loc.y) < 5)) { + if(dist(where,check_loc) <= 8 && can_see(where,check_loc,sight_obscurity) < 5 && sight_obscurity(check_loc.x,check_loc.y) < 5) { { cur_lev = count_levels(check_loc,radius); if (mode == 1) @@ -3560,7 +3560,7 @@ short count_levels(location where,short radius) store = store + 10; } if (is_town()) - if ((vdist(where,univ.town.p_loc) <= radius) && (can_see(where,univ.town.p_loc,2) < 5)) + if(vdist(where,univ.town.p_loc) <= radius && can_see(where,univ.town.p_loc,sight_obscurity) < 5) store += 20; return store; @@ -3641,7 +3641,7 @@ void place_spell_pattern(effect_pat_type pat,location center,short type,bool pre // First actually make barriers, then draw them, then inflict damaging effects. for (i = minmax(0,univ.town->max_dim() - 1,center.x - 4); i <= minmax(0,univ.town->max_dim() - 1,center.x + 4); i++) for (j = minmax(0,univ.town->max_dim() - 1,center.y - 4); j <= minmax(0,univ.town->max_dim() - 1,center.y + 4); j++) - if (get_obscurity(i,j) < 5) { + if(sight_obscurity(i,j) < 5) { effect = pat.pattern[i - center.x + 4][j - center.y + 4]; switch (effect) { case 1: web_space(i,j); break; @@ -3673,7 +3673,7 @@ void place_spell_pattern(effect_pat_type pat,location center,short type,bool pre for (j = minmax(0,univ.town->max_dim() - 1,center.y - 4); j <= minmax(0,univ.town->max_dim() - 1,center.y + 4); j++) { spot_hit.x = i; spot_hit.y = j; - if ((get_obscurity(i,j) < 5) && (univ.party[k].main_status == 1) + if(sight_obscurity(i,j) < 5 && univ.party[k].main_status == 1 && (((is_combat()) && (pc_pos[k] == spot_hit)) || ((is_town()) && (univ.town.p_loc == spot_hit)))) { effect = pat.pattern[i - center.x + 4][j - center.y + 4]; @@ -3724,7 +3724,7 @@ void place_spell_pattern(effect_pat_type pat,location center,short type,bool pre spot_hit.x = i; spot_hit.y = j; - if ((monster_hit == false) && (get_obscurity(i,j) < 5) && (monst_on_space(spot_hit,k) > 0)) { + if(!monster_hit && sight_obscurity(i,j) < 5 && monst_on_space(spot_hit,k) > 0) { if (pat.pattern[i - center.x + 4][j - center.y + 4] > 0) monster_hit = true; diff --git a/osx/boe.fields.cpp b/osx/boe.fields.cpp index 6ca7887f..b79cfec3 100644 --- a/osx/boe.fields.cpp +++ b/osx/boe.fields.cpp @@ -192,9 +192,10 @@ void make_quickfire(short i,short j) // if ((is_force_barrier(i,j)) || (is_fire_barrier(i,j))) // return; ter = coord_to_ter(i,j); - if (scenario.ter_types[ter].blockage == 1) + if(scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_SIGHT) return; - if (scenario.ter_types[ter].blockage == 5) + // TODO: Isn't it a little odd that BLOCK_MOVE_AND_SHOOT isn't included here? + if(scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) return; // univ.town.explored[i][j] = univ.town.explored[i][j] & 1; // univ.out.misc_i[i][j] = univ.out.misc_i[i][j] & 3; @@ -388,10 +389,10 @@ void make_sfx(short i,short j, short type) { ter_num_t ter; - if (get_obscurity(i,j) > 0) + if(sight_obscurity(i,j) > 0) return; ter = coord_to_ter(i,j); - if (scenario.ter_types[ter].blockage != 0) + if(scenario.ter_types[ter].blockage != eTerObstruct::CLEAR) return; switch (type) { // case 1: case 2: diff --git a/osx/boe.graphics.cpp b/osx/boe.graphics.cpp index 80127550..a47fdfde 100644 --- a/osx/boe.graphics.cpp +++ b/osx/boe.graphics.cpp @@ -1050,7 +1050,7 @@ void draw_terrain(short mode) static ter_num_t get_ground_for_shore(ter_num_t ter){ if(scenario.ter_types[ter].block_horse) return current_ground; - else if(scenario.ter_types[ter].blockage > 2) return current_ground; + else if(blocksMove(scenario.ter_types[ter].blockage)) return current_ground; else return ter; } diff --git a/osx/boe.locutils.cpp b/osx/boe.locutils.cpp index 90ee412e..7999daf7 100644 --- a/osx/boe.locutils.cpp +++ b/osx/boe.locutils.cpp @@ -153,116 +153,19 @@ bool is_lava(short x,short y)//// else return false; } -short can_see(location p1,location p2,short mode) -//short mode; // 0 - normal 1 - counts 1 for blocked spaces or lava (used for party placement in -// town combat) -// 2 - no light check -{ - short dx,dy,count,storage = 0; - - if (is_combat()) { // Light check - if ((mode != 2) && (combat_pt_in_light(p2) == false)) { - return 6; - } - } - else if(is_town()) { - if ((mode != 2) && (pt_in_light(p1,p2) == false)) { - return 6; - } - } - - if (p1.y == p2.y) { - if (p1.x > p2.x) { - for (count = p2.x + 1; count < p1.x; count++) { - storage = storage + get_obscurity(count, p1.y); - if (((scenario.ter_types[coord_to_ter(count,p1.y)].blockage > 2) || (is_lava(count,p1.y) == true)) && (mode == 1)) - return 5; - } - } - else { - for (count = p1.x + 1; count < p2.x; count++) { - - storage = storage + get_obscurity(count, p1.y); - if (((scenario.ter_types[coord_to_ter(count,p1.y)].blockage > 2) || (is_lava(count,p1.y) == true)) && (mode == 1)) - return 5; - } - } - return storage; - } - if (p1.x == p2.x) { - if (p1.y > p2.y) { - for (count = p1.y - 1; count > p2.y; count--) { - storage = storage + get_obscurity(p1.x, count); - if (((scenario.ter_types[coord_to_ter(p1.x,count)].blockage > 2) || (is_lava(p1.x,count) == true)) && (mode == 1)) - return 5; - } - } - else { - for (count = p1.y + 1; count < p2.y; count++) { - storage = storage + get_obscurity(p1.x, count); - if (((scenario.ter_types[coord_to_ter(p1.x,count)].blockage > 2) || (is_lava(p1.x,count) == true)) && (mode == 1)) - return 5; - } - } - return storage; - } - dx = p2.x - p1.x; - dy = p2.y - p1.y; - - if (abs(dy) > abs(dx)) { - if (p2.y > p1.y) { - for (count = 1; count < dy; count++) { - storage = storage + get_obscurity(p1.x + (count * dx) / dy, p1.y + count); - if ( ((scenario.ter_types[coord_to_ter(p1.x + (count * dx) / dy,p1.y + count)].blockage > 2) || - (is_lava(p1.x + (count * dx) / dy,p1.y + count) == true)) - && (mode == 1)) - return 5; - } - } - else { - for (count = -1; count > dy; count--) { - storage = storage + get_obscurity(p1.x + (count * dx) / dy, p1.y + count); - if ( ((scenario.ter_types[coord_to_ter(p1.x + (count * dx) / dy, p1.y + count)].blockage > 2) || - (is_lava(p1.x + (count * dx) / dy, p1.y + count) == true)) - && (mode == 1)) - return 5; - } - } - return storage; - } - if (abs(dy) <= abs(dx)) { - if (p2.x > p1.x) { - for (count = 1; count < dx; count++) { - storage = storage + get_obscurity(p1.x + count, p1.y + (count * dy) / dx); - if (((scenario.ter_types[coord_to_ter(p1.x + count,p1.y + (count * dy) / dx)].blockage > 2) || - (is_lava(p1.x + count,p1.y + (count * dy) / dx) == true)) - && (mode == 1)) - return 5; - } - } - else { - for (count = -1; count > dx; count--) { - storage = storage + get_obscurity(p1.x + count, p1.y + (count * dy) / dx); - if ( ((scenario.ter_types[coord_to_ter(p1.x + count,p1.y + (count * dy) / dx)].blockage > 2) || - (is_lava(p1.x + count,p1.y + (count * dy) / dx) == true)) - && (mode == 1)) - return 5; - } - } - return storage; - } - if (storage > 5) - return 5; - else return storage; +short can_see_light(location p1, location p2, std::function get_obscurity) { + if(is_combat() && !combat_pt_in_light(p2)) return 6; + else if(is_town() && !pt_in_light(p1,p2)) return 6; + return can_see(p1, p2, get_obscurity); } -short get_obscurity(short x,short y) -{ +short sight_obscurity(short x,short y) { ter_num_t what_terrain; short store; what_terrain = coord_to_ter(x,y); + // TODO: This should not be hard-coded! if ((what_terrain >= 237) && (what_terrain <= 242)) return 1; @@ -285,6 +188,12 @@ short get_obscurity(short x,short y) return store; } +short combat_obscurity(short x, short y) { + if(blocksMove(scenario.ter_types[coord_to_ter(x,y)].blockage)) return 5; + if(is_lava(x,y)) return 5; + return sight_obscurity(x,y); +} + ter_num_t coord_to_ter(short x,short y) { ter_num_t what_terrain; @@ -329,7 +238,7 @@ void update_explored(location dest) for (look.y = shortdest.y - 4; look.y < shortdest.y + 5; look.y++) { if (univ.out.out_e[look.x][look.y] == 0) - if (can_see(shortdest, look) < 5) + if(can_see_light(shortdest, look, sight_obscurity) < 5) univ.out.out_e[look.x][look.y] = 1; } @@ -526,7 +435,7 @@ bool outd_is_blocked(location to_check) bool special_which_blocks_monst(location to_check) { - if (scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].blockage == 2) + if(scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].blockage == eTerObstruct::BLOCK_MONSTERS) return true; else return false; } @@ -539,7 +448,7 @@ bool is_special(location to_check) if (special_which_blocks_monst(to_check) == false) return false; which_ter = coord_to_ter(to_check.x,to_check.y); - if (scenario.ter_types[which_ter].blockage == 2) + if(scenario.ter_types[which_ter].blockage == eTerObstruct::BLOCK_MONSTERS) return true; else return false; } @@ -547,7 +456,7 @@ bool is_special(location to_check) bool outd_is_special(location to_check) { if (overall_mode == MODE_OUTDOORS) { - if (scenario.ter_types[univ.out[to_check.x][to_check.y]].blockage == 2) { + if(scenario.ter_types[univ.out[to_check.x][to_check.y]].blockage == eTerObstruct::BLOCK_MONSTERS) { return true; } else return false; @@ -557,20 +466,23 @@ bool outd_is_special(location to_check) bool impassable(ter_num_t terrain_to_check) { - if (scenario.ter_types[terrain_to_check].blockage > 2) + if(blocksMove(scenario.ter_types[terrain_to_check].blockage)) return true; else return false; } // TODO: What on earth is this and why does it mangle the blockage? +// NOTE: Seems to return 5 for "blocks sight", 1 for "obstructs missiles", 0 otherwise +// So it should probably be called something like "get_opacity" instead. short get_blockage(ter_num_t terrain_type) { // little kludgy in here for pits if ((terrain_type == 90) && (is_combat()) && (which_combat_type == 0)) return 5; - if ((scenario.ter_types[terrain_type].blockage == 5) || (scenario.ter_types[terrain_type].blockage == 1)) + if(scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT || + scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_SIGHT) return 5; - else if (scenario.ter_types[terrain_type].blockage > 3) + else if(scenario.ter_types[terrain_type].blockage == eTerObstruct::BLOCK_MOVE_AND_SHOOT) return 1; else { return 0; @@ -693,8 +605,8 @@ location push_loc(location from_where,location to_where) loc_to_try.x = 0; return loc_to_try; } - if ((get_obscurity((short) loc_to_try.x,(short) loc_to_try.y) > 0) || - (scenario.ter_types[univ.town->terrain(loc_to_try.x,loc_to_try.y)].blockage > 0) || + if(sight_obscurity(loc_to_try.x,loc_to_try.y) > 0 || + scenario.ter_types[univ.town->terrain(loc_to_try.x,loc_to_try.y)].blockage != eTerObstruct::CLEAR || (loc_off_act_area(loc_to_try) == true) || (monst_there(loc_to_try) < 90) || (pc_there(loc_to_try) < 6)) @@ -703,13 +615,13 @@ location push_loc(location from_where,location to_where) } -// TODO: This seems to be wrong; aren't 3 and 4 also impassable? +// TODO: This seems to be wrong; impassable implies "blocks movement", which two other blockages also do bool spot_impassable(short i,short j) { ter_num_t ter; ter = coord_to_ter(i,j); - if (scenario.ter_types[ter].blockage == 5) + if(scenario.ter_types[ter].blockage == eTerObstruct::BLOCK_MOVE_AND_SIGHT) return true; else return false; } diff --git a/osx/boe.locutils.h b/osx/boe.locutils.h index 9ef4b817..a8a12d6e 100644 --- a/osx/boe.locutils.h +++ b/osx/boe.locutils.h @@ -11,9 +11,9 @@ bool loc_off_world(location p1); bool loc_off_act_area(location p1); location get_cur_loc(); bool is_lava(short x,short y); -// TODO: Introduce enum for this mode -short can_see(location p1,location p2,short mode = 0); -short get_obscurity(short x,short y); +short sight_obscurity(short x,short y); +short can_see_light(location p1, location p2, std::function get_obscurity); +short combat_obscurity(short x,short y); ter_num_t coord_to_ter(short x,short y); bool is_container(location loc); void update_explored(location dest); diff --git a/osx/boe.monster.cpp b/osx/boe.monster.cpp index df9ed366..dfa528c2 100644 --- a/osx/boe.monster.cpp +++ b/osx/boe.monster.cpp @@ -781,7 +781,7 @@ location find_clear_spot(location from_where,short mode) r1 = get_ran(1,-2,2); loc.y = loc.y + r1; if ((loc_off_act_area(loc) == false) && (is_blocked(loc) == false) - && (can_see(from_where,loc,1) == 0) + && can_see_light(from_where,loc,combat_obscurity) == 0 && (!(is_combat()) || (pc_there(loc) == 6)) && (!(is_town()) || (loc != univ.town.p_loc)) && (!(univ.town.misc_i(loc.x,loc.y) & 248)) && // check for crate, barrel, barrier, quickfire diff --git a/osx/boe.party.cpp b/osx/boe.party.cpp index e07eb195..58aa6b51 100644 --- a/osx/boe.party.cpp +++ b/osx/boe.party.cpp @@ -1722,7 +1722,7 @@ void cast_town_spell(location where) //// update_explored(univ.town.p_loc); break; case 42: - if ((get_obscurity(where.x,where.y) == 5) || (monst_there(where) < 90)) { + if(sight_obscurity(where.x,where.y) == 5 || monst_there(where) < 90) { add_string_to_buf(" Target space obstructed."); break; } @@ -1732,7 +1732,7 @@ void cast_town_spell(location where) //// else add_string_to_buf(" Failed."); break; case 59: - if ((get_obscurity(where.x,where.y) == 5) || (monst_there(where) < 90)) { + if(sight_obscurity(where.x,where.y) == 5 || monst_there(where) < 90) { add_string_to_buf(" Target space obstructed."); break; } @@ -1752,7 +1752,7 @@ void cast_town_spell(location where) //// add_string_to_buf(" You create an antimagic cloud. "); for (loc.x = 0; loc.x < univ.town->max_dim(); loc.x++) for (loc.y = 0; loc.y < univ.town->max_dim(); loc.y++) - if ((dist(where,loc) <= 2) && (can_see(where,loc,2) < 5) && + if(dist(where,loc) <= 2 && can_see(where,loc,sight_obscurity) < 5 && ((abs(loc.x - where.x) < 2) || (abs(loc.y - where.y) < 2))) make_antimagic(loc.x,loc.y); break; diff --git a/osx/boe.specials.cpp b/osx/boe.specials.cpp index 1cf38c9e..4a0da031 100644 --- a/osx/boe.specials.cpp +++ b/osx/boe.specials.cpp @@ -294,7 +294,7 @@ bool check_special_terrain(location where_check,short mode,short which_pc,short play_sound(-1 * ter_flag2.u); } give_help(47,65); - if (scenario.ter_types[ter].blockage > 2) + if(blocksMove(scenario.ter_types[ter].blockage)) can_enter = false; break; case TER_SPEC_DAMAGING: diff --git a/osx/boe.town.cpp b/osx/boe.town.cpp index cd5c898f..23398bff 100644 --- a/osx/boe.town.cpp +++ b/osx/boe.town.cpp @@ -839,8 +839,8 @@ void place_party(short direction) check_loc.y -= y_adj; pos_locs[i] = check_loc; - if ((is_blocked(check_loc) == false) && (is_special(check_loc) == false) && (get_obscurity(check_loc.x,check_loc.y) == 0) - && (can_see(univ.town.p_loc,check_loc,1) < 1) && (loc_off_act_area(check_loc) == false)) { + if(!is_blocked(check_loc) && !is_special(check_loc) && sight_obscurity(check_loc.x,check_loc.y) == 0 + && can_see_light(univ.town.p_loc,check_loc,combat_obscurity) < 1 && !loc_off_act_area(check_loc)) { spot_ok[i] = true; how_many_ok += (i > 1) ? 1 : 0; } diff --git a/osx/classes/simpletypes.h b/osx/classes/simpletypes.h index 8547df58..07738d21 100644 --- a/osx/classes/simpletypes.h +++ b/osx/classes/simpletypes.h @@ -240,6 +240,20 @@ enum eTrimType { TRIM_CITY = 18, // the game will join roads up to this space but not draw roads on the space }; +/* terrain type blockage */ +enum class eTerObstruct { + CLEAR = 0, + BLOCK_SIGHT = 1, + BLOCK_MONSTERS = 2, + BLOCK_MOVE = 3, + BLOCK_MOVE_AND_SHOOT = 4, + BLOCK_MOVE_AND_SIGHT = 5, +}; + +inline bool blocksMove(eTerObstruct block) { + int code = (int) block; + return code > 2; +} /* items[i].type a.k.a type of weapon */ enum class eWeapType { diff --git a/osx/classes/terrain.cpp b/osx/classes/terrain.cpp index cf3b2741..897490fb 100644 --- a/osx/classes/terrain.cpp +++ b/osx/classes/terrain.cpp @@ -95,7 +95,7 @@ cTerrain& cTerrain::operator = (legacy::terrain_type_type& old){ 99,99,99,99,99,2, 99,99,99,99, 99,99,99,99, }; picture = old.picture; - blockage = old.blockage; + blockage = (eTerObstruct) old.blockage; if(picture < 260){ combat_arena = arenas[picture]; ground_type = ground[picture]; @@ -365,3 +365,16 @@ std::istream& operator >> (std::istream& in, eTerSpec& e){ else e = TER_SPEC_NONE; return in; } + +std::ostream& operator << (std::ostream& out, eTerObstruct& e){ + return out << (int) e; +} + +std::istream& operator >> (std::istream& in, eTerObstruct& e){ + int i; + in >> i; + if(i > 0 && i < 6) + e = (eTerObstruct) i; + else e = eTerObstruct::CLEAR; + return in; +} diff --git a/osx/classes/terrain.h b/osx/classes/terrain.h index 6a2d1bcf..724f3de1 100644 --- a/osx/classes/terrain.h +++ b/osx/classes/terrain.h @@ -24,7 +24,7 @@ class cTerrain { public: std::string name; pic_num_t picture; - unsigned char blockage; + eTerObstruct blockage; ter_flag_t flag1; ter_flag_t flag2; ter_flag_t flag3; // new additional flag for special properties @@ -52,5 +52,7 @@ public: std::ostream& operator << (std::ostream& out, eTerSpec& e); std::istream& operator >> (std::istream& in, eTerSpec& e); +std::ostream& operator << (std::ostream& out, eTerObstruct& e); +std::istream& operator >> (std::istream& in, eTerObstruct& e); #endif \ No newline at end of file diff --git a/osx/scenedit/scen.actions.cpp b/osx/scenedit/scen.actions.cpp index b7ab3731..4b2bcf6a 100644 --- a/osx/scenedit/scen.actions.cpp +++ b/osx/scenedit/scen.actions.cpp @@ -117,7 +117,6 @@ short special_to_paste = -1; extern std::string get_str(std::string list, short j); bool monst_on_space(location loc,short m_num); -short can_see(location p1,location p2,short mode); void init_current_terrain() { // short i,j; @@ -1467,52 +1466,6 @@ void handle_keystroke(char chr,char chr2,sf::Event event) { //void set_info_strings() { //} - - - -void modify_lists() { - /* unsigned char terrain_to_do; - char i,j, k; - short sign_count = 0, exit_count = 0, special_count = 0; - unsigned char specials[10] = {237,238,239,240,241, 242,243,244,78,78}; - unsigned char signs[6] = {110,127,142,213,214,252}; - bool is_this_type = false; - location null_point = {0,0}; - - for (i = 0; i < town->max_dim(); i++) - for (j = 0; j < town->max_dim(); j++) { - is_this_type = false; - - terrain_to_do = (unsigned char) town->terrain(i,j); - for (k = 0; k < 10; k++) - if (terrain_to_do == specials[k]) - is_this_type = true; - if ((is_this_type == true) && (special_count < 40)) { - make_special(i,j); - special_count++; - is_this_type = true; - } - - if (is_this_type == false) { - for (k = 0; k < 6; k++) - if (terrain_to_do == signs[k]) - is_this_type = true; - if ((is_this_type == true) && (sign_count < 12)) { - town.sign_locs[sign_count].x = i; - town.sign_locs[sign_count].y = j; - sign_count++; - } - } - - } - - for (i = sign_count; i < 12; i++) - town.sign_locs[i] = null_point; - */ - set_up_lights(); - -} - void set_up_lights() { short i,j,rad; location where,l; @@ -3463,7 +3416,7 @@ bool save_check(std::string which_dlog) { return true; else if(choice == "cancel") return false; - modify_lists(); + set_up_lights(); save_scenario(); return true; } @@ -3474,16 +3427,16 @@ bool is_lava(short x,short y) { else return false; } -short get_obscurity(short x,short y) { +short light_obscurity(short x,short y) { ter_num_t what_terrain; - short store; + eTerObstruct store; what_terrain = coord_to_ter(x,y); store = scenario.ter_types[what_terrain].blockage; - if ((store == 1) || (store == 5)) + if(store == eTerObstruct::BLOCK_SIGHT || store == eTerObstruct::BLOCK_MOVE_AND_SIGHT) return 5; - if (store == 4) + if(store == eTerObstruct::BLOCK_MOVE_AND_SHOOT) return 1; return 0; } @@ -3498,98 +3451,6 @@ ter_num_t coord_to_ter(short x,short y) { return what_terrain; } - -short can_see(location p1,location p2,short mode) { - //mode; // 0 - normal 1 - counts 1 for blocked spaces or lava (used for party placement in - // town combat) - // 2 - no light check - short dx,dy,count,storage = 0; - - if (p1.y == p2.y) { - if (p1.x > p2.x) { - for (count = p2.x + 1; count < p1.x; count++) { - storage = storage + get_obscurity(count, p1.y); - if (((scenario.ter_types[coord_to_ter(count,p1.y)].blockage > 2) || (is_lava(count,p1.y) == true)) && (mode == 1)) - return 5; - } - } - else { - for (count = p1.x + 1; count < p2.x; count++) { - - storage = storage + get_obscurity(count, p1.y); - if (((scenario.ter_types[coord_to_ter(count,p1.y)].blockage > 2) || (is_lava(count,p1.y) == true)) && (mode == 1)) - return 5; - } - } - return storage; - } - if (p1.x == p2.x) { - if (p1.y > p2.y) { - for (count = p1.y - 1; count > p2.y; count--) { - storage = storage + get_obscurity(p1.x, count); - if (((scenario.ter_types[coord_to_ter(p1.x,count)].blockage > 2) || (is_lava(p1.x,count) == true)) && (mode == 1)) - return 5; - } - } - else { - for (count = p1.y + 1; count < p2.y; count++) { - storage = storage + get_obscurity(p1.x, count); - if (((scenario.ter_types[coord_to_ter(p1.x,count)].blockage > 2) || (is_lava(p1.x,count) == true)) && (mode == 1)) - return 5; - } - } - return storage; - } - dx = p2.x - p1.x; - dy = p2.y - p1.y; - - if (abs(dy) > abs(dx)) { - if (p2.y > p1.y) { - for (count = 1; count < dy; count++) { - storage = storage + get_obscurity(p1.x + (count * dx) / dy, p1.y + count); - if ( ((scenario.ter_types[coord_to_ter(p1.x + (count * dx) / dy,p1.y + count)].blockage > 2) || - (is_lava(p1.x + (count * dx) / dy,p1.y + count) == true)) - && (mode == 1)) - return 5; - } - } - else { - for (count = -1; count > dy; count--) { - storage = storage + get_obscurity(p1.x + (count * dx) / dy, p1.y + count); - if ( ((scenario.ter_types[coord_to_ter(p1.x + (count * dx) / dy, p1.y + count)].blockage > 2) || - (is_lava(p1.x + (count * dx) / dy, p1.y + count) == true)) - && (mode == 1)) - return 5; - } - } - return storage; - } - if (abs(dy) <= abs(dx)) { - if (p2.x > p1.x) { - for (count = 1; count < dx; count++) { - storage = storage + get_obscurity(p1.x + count, p1.y + (count * dy) / dx); - if (((scenario.ter_types[coord_to_ter(p1.x + count,p1.y + (count * dy) / dx)].blockage > 2) || - (is_lava(p1.x + count,p1.y + (count * dy) / dx) == true)) - && (mode == 1)) - return 5; - } - } - else { - for (count = -1; count > dx; count--) { - storage = storage + get_obscurity(p1.x + count, p1.y + (count * dy) / dx); - if ( ((scenario.ter_types[coord_to_ter(p1.x + count,p1.y + (count * dy) / dx)].blockage > 2) || - (is_lava(p1.x + count,p1.y + (count * dy) / dx) == true)) - && (mode == 1)) - return 5; - } - } - return storage; - } - if (storage > 5) - return 5; - else return storage; -} - bool monst_on_space(location loc,short m_num) { if (editing_town == false) return false; diff --git a/osx/scenedit/scen.actions.h b/osx/scenedit/scen.actions.h index eecad475..66d0caf6 100644 --- a/osx/scenedit/scen.actions.h +++ b/osx/scenedit/scen.actions.h @@ -10,7 +10,6 @@ void get_town_info(); void get_sign_resource(); void set_info_strings(); cTown::cItem edit_item(cTown::cItem item); -void modify_lists(); void set_up_lights(); bool is_wall(short i,short j); bool is_correctable_wall(short i,short j); @@ -41,8 +40,7 @@ bool out_fix_water(location l); void adjust_space(location l); bool is_lava(short x,short y); ter_num_t coord_to_ter(short x,short y); -short get_obscurity(short x,short y); -short can_see(location p1,location p2,short mode); +short light_obscurity(short x,short y); bool place_item(location spot_hit,short which_item,short property,short always,short odds); void place_items_in_town(); void set_up_start_screen(); diff --git a/osx/scenedit/scen.core.cpp b/osx/scenedit/scen.core.cpp index 3e2c2b78..07a381a3 100644 --- a/osx/scenedit/scen.core.cpp +++ b/osx/scenedit/scen.core.cpp @@ -133,12 +133,12 @@ bool save_ter_info(cDialog& me, cTerrain& store_ter) { // TODO: Should somehow verify the pict number is valid std::string blockage = dynamic_cast(me["blockage"]).getSelected(); - if(blockage == "clear") store_ter.blockage = 0; - else if(blockage == "curtain") store_ter.blockage = 1; - else if(blockage == "special") store_ter.blockage = 2; - else if(blockage == "window") store_ter.blockage = 3; - else if(blockage == "obstructed") store_ter.blockage = 4; - else if(blockage == "opaque") store_ter.blockage = 5; + if(blockage == "clear") store_ter.blockage = eTerObstruct::CLEAR; + else if(blockage == "curtain") store_ter.blockage = eTerObstruct::BLOCK_SIGHT; + else if(blockage == "special") store_ter.blockage = eTerObstruct::BLOCK_MONSTERS; + else if(blockage == "window") store_ter.blockage = eTerObstruct::BLOCK_MOVE; + else if(blockage == "obstructed") store_ter.blockage = eTerObstruct::BLOCK_MOVE_AND_SHOOT; + else if(blockage == "opaque") store_ter.blockage = eTerObstruct::BLOCK_MOVE_AND_SIGHT; store_ter.special = (eTerSpec) boost::lexical_cast(dynamic_cast(me["prop"]).getSelected().substr(4)); /* i = CDGN(813,6); @@ -335,22 +335,22 @@ void fill_ter_info(cDialog& me, short ter){ { cLedGroup& led_ctrl = dynamic_cast(me["blockage"]); switch(ter_type.blockage){ - case 0: + case eTerObstruct::CLEAR: led_ctrl.setSelected("clear"); break; - case 1: + case eTerObstruct::BLOCK_SIGHT: led_ctrl.setSelected("curtain"); break; - case 2: + case eTerObstruct::BLOCK_MONSTERS: led_ctrl.setSelected("special"); break; - case 3: + case eTerObstruct::BLOCK_MOVE: led_ctrl.setSelected("window"); break; - case 4: + case eTerObstruct::BLOCK_MOVE_AND_SHOOT: led_ctrl.setSelected("obstructed"); break; - case 5: + case eTerObstruct::BLOCK_MOVE_AND_SIGHT: led_ctrl.setSelected("opaque"); break; } diff --git a/osx/scenedit/scen.main.cpp b/osx/scenedit/scen.main.cpp index aa5a0e6d..7b8ffdaf 100644 --- a/osx/scenedit/scen.main.cpp +++ b/osx/scenedit/scen.main.cpp @@ -257,7 +257,7 @@ void handle_file_menu(int item_hit) { } break; case 2: // save - modify_lists(); + set_up_lights(); save_scenario(); break; case 3: // new scen diff --git a/osx/tools/graphtool.cpp b/osx/tools/graphtool.cpp index 5ee82d6a..3410a89b 100644 --- a/osx/tools/graphtool.cpp +++ b/osx/tools/graphtool.cpp @@ -1203,3 +1203,48 @@ void tileImage(RgnHandle area, GWorldPtr img, RECT srcRect, short mode){ } } #endif + +short can_see(location p1,location p2,std::function get_obscurity) { + short storage = 0; + + if(p1.y == p2.y) { + if(p1.x > p2.x) { + for(short count = p2.x + 1; count < p1.x; count++) + storage += get_obscurity(count, p1.y); + } else { + for(short count = p1.x + 1; count < p2.x; count++) + storage += get_obscurity(count, p1.y); + } + } else if(p1.x == p2.x) { + if(p1.y > p2.y) { + for(short count = p1.y - 1; count > p2.y; count--) + storage += get_obscurity(p1.x, count); + } else { + for(short count = p1.y + 1; count < p2.y; count++) + storage += get_obscurity(p1.x, count); + } + } else { + short dx = p2.x - p1.x; + short dy = p2.y - p1.y; + + if(abs(dy) > abs(dx)) { + if(p2.y > p1.y) { + for(short count = 1; count < dy; count++) + storage += get_obscurity(p1.x + (count * dx) / dy, p1.y + count); + } else { + for(short count = -1; count > dy; count--) + storage += get_obscurity(p1.x + (count * dx) / dy, p1.y + count); + } + } + if(abs(dy) <= abs(dx)) { + if(p2.x > p1.x) { + for(short count = 1; count < dx; count++) + storage += get_obscurity(p1.x + count, p1.y + (count * dy) / dx); + } else { + for(short count = -1; count > dx; count--) + storage += get_obscurity(p1.x + count, p1.y + (count * dy) / dx); + } + } + } + return storage; +} diff --git a/osx/tools/graphtool.h b/osx/tools/graphtool.h index 267905b4..bfda2c74 100644 --- a/osx/tools/graphtool.h +++ b/osx/tools/graphtool.h @@ -10,6 +10,7 @@ #define GRAPHTOOL_H #include +#include #include #include #include "location.h" @@ -121,6 +122,9 @@ void clip_rect(sf::RenderTarget& where, RECT rect); void clip_region(sf::RenderWindow& where, Region& region); void undo_clip(sf::RenderTarget& where); +// This probably doesn't quite fit here, but it fits worse pretty much everywhere else in the common sources +short can_see(location p1,location p2,std::function get_obscurity); + #ifndef GRAPHTOOL_CPP extern m_pic_index_t m_pic_index[200]; extern RECT bg[];