diff options
27 files changed, 102 insertions, 78 deletions
diff --git a/crawl-ref/source/actor-los.cc b/crawl-ref/source/actor-los.cc new file mode 100644 index 0000000000..85e66fd8ab --- /dev/null +++ b/crawl-ref/source/actor-los.cc @@ -0,0 +1,49 @@ +#include "AppHdr.h" + +#include "actor.h" +#include "player.h" +#include "monster.h" +#include "state.h" + +bool actor::observable() const +{ + return (crawl_state.arena || this == &you || you.can_see(this)); +} + +bool actor::see_cell(const coord_def &p) const +{ + return (los.see_cell(p)); +} + +void actor::update_los() +{ + los.update(); +} + +bool actor::can_see(const actor *target) const +{ + return (target->visible_to(this) && see_cell(target->pos())); +} + +bool player::see_cell_no_trans(const coord_def &p) const +{ + return (los_no_trans.see_cell(p)); +} + +const los_def& actor::get_los_no_trans() +{ + return (los_no_trans); +} + +const los_def& monsters::get_los_no_trans() +{ + los_no_trans.update(); + return (los_no_trans); +} + +void player::update_los() +{ + los_no_trans.update(); + actor::update_los(); +} + diff --git a/crawl-ref/source/actor.cc b/crawl-ref/source/actor.cc index 705a492221..90ff956d44 100644 --- a/crawl-ref/source/actor.cc +++ b/crawl-ref/source/actor.cc @@ -8,28 +8,13 @@ #include "stuff.h" #include "traps.h" -actor::~actor() -{ -} - -bool actor::observable() const +actor::actor() + : los_no_trans(los_def(coord_def(0,0), opacity_no_trans())) { - return (crawl_state.arena || this == &you || you.can_see(this)); } -bool actor::see_cell(const coord_def &p) const -{ - return (los.see_cell(p)); -} - -void actor::update_los() -{ - los.update(); -} - -bool actor::can_see(const actor *target) const +actor::~actor() { - return (target->visible_to(this) && see_cell(target->pos())); } bool actor::has_equipped(equipment_type eq, int sub_type) const @@ -129,4 +114,5 @@ void actor::set_position(const coord_def &c) { position = c; los.set_center(c); + los_no_trans.set_center(c); } diff --git a/crawl-ref/source/actor.h b/crawl-ref/source/actor.h index be566ce97a..b93046d727 100644 --- a/crawl-ref/source/actor.h +++ b/crawl-ref/source/actor.h @@ -6,6 +6,7 @@ class actor { public: + actor(); virtual ~actor(); virtual monster_type id() const = 0; @@ -113,6 +114,9 @@ public: virtual void update_los(); + // Could be const for player, but monsters updates it on the fly. + virtual const los_def& get_los_no_trans(); + // Can the actor actually see the target? virtual bool can_see(const actor *target) const; @@ -235,6 +239,7 @@ public: protected: los_def los; + los_def los_no_trans; // only being updated for player }; #endif diff --git a/crawl-ref/source/coordit.cc b/crawl-ref/source/coordit.cc index 10677e2212..c0c79414c0 100644 --- a/crawl-ref/source/coordit.cc +++ b/crawl-ref/source/coordit.cc @@ -70,10 +70,10 @@ rectangle_iterator rectangle_iterator::operator++( int dummy ) radius_iterator::radius_iterator(const coord_def& _center, int _radius, bool _roguelike_metric, bool _require_los, bool _exclude_center, - const env_show_grid* _losgrid) + const los_def* _los) : center(_center), radius(_radius), roguelike_metric(_roguelike_metric), require_los(_require_los), exclude_center(_exclude_center), - losgrid(_losgrid), iter_done(false) + los(_los), iter_done(false) { reset(); } @@ -129,9 +129,9 @@ bool radius_iterator::on_valid_square() const return (false); if (require_los) { - if (!losgrid && !you.see_cell(location)) + if (!los && !you.see_cell(location)) return (false); - if (losgrid && !see_cell(*losgrid, center, location)) + if (los && !los->see_cell(location)) return (false); } if (exclude_center && location == center) diff --git a/crawl-ref/source/coordit.h b/crawl-ref/source/coordit.h index 4599eea66d..60fbf1a669 100644 --- a/crawl-ref/source/coordit.h +++ b/crawl-ref/source/coordit.h @@ -17,15 +17,16 @@ private: coord_def current, topleft, bottomright; }; +class los_def; class radius_iterator : public std::iterator<std::forward_iterator_tag, coord_def> { public: - radius_iterator( const coord_def& center, int radius, - bool roguelike_metric = true, - bool require_los = true, - bool exclude_center = false, - const env_show_grid* losgrid = NULL ); + radius_iterator(const coord_def& center, int radius, + bool roguelike_metric = true, + bool require_los = true, + bool exclude_center = false, + const los_def* los = NULL); bool done() const; void reset(); operator bool() const { return !done(); } @@ -41,7 +42,7 @@ private: coord_def location, center; int radius; bool roguelike_metric, require_los, exclude_center; - const env_show_grid* losgrid; + const los_def* los; bool iter_done; }; diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index d27201f8b4..47cdd1542e 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -2048,7 +2048,7 @@ static bool _find_monster( const coord_def& where, int mode, bool need_path, return (false); // Monster in LOS but only via glass walls, so no direct path. - if (need_path && !see_cell_no_trans(where)) + if (need_path && !you.see_cell_no_trans(where)) return (false); if (!_mons_is_valid_target(mon, mode, range)) diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 1c1f87e35c..c88216ee35 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -4347,7 +4347,7 @@ int place_ring(std::vector<coord_def> &ring_points, // Collect lists of points that are within LOS (under the given env map), // unoccupied, and not solid (walls/statues). void collect_radius_points(std::vector<std::vector<coord_def> > &radius_points, - const coord_def &origin, const env_show_grid &losgrid) + const coord_def &origin, const los_def &los) { radius_points.clear(); @@ -4404,7 +4404,7 @@ void collect_radius_points(std::vector<std::vector<coord_def> > &radius_points, coord_dist temp(*i, current.second); // If the grid is out of LOS, skip it. - if (!see_cell(losgrid, origin, temp.first)) + if (!los.see_cell(temp.first)) continue; coord_def local = temp.first - origin; @@ -4437,10 +4437,9 @@ static int _mushroom_ring(item_def &corpse, int & seen_count, std::vector<std::vector<coord_def> > radius_points; - env_show_grid losgrid; - losight(losgrid, corpse.pos, opc_solid); + los_def los(corpse.pos, opc_solid); - collect_radius_points(radius_points, corpse.pos, losgrid); + collect_radius_points(radius_points, corpse.pos, los); // So what we have done so far is collect the set of points at each radius // reachable from the origin with (somewhat constrained) 8 connectivity, diff --git a/crawl-ref/source/effects.h b/crawl-ref/source/effects.h index dd23f6ba67..fd1886dd36 100644 --- a/crawl-ref/source/effects.h +++ b/crawl-ref/source/effects.h @@ -52,7 +52,7 @@ int place_ring(std::vector<coord_def>& ring_points, // Collect lists of points that are within LOS (under the given losgrid), // unoccupied, and not solid (walls/statues). void collect_radius_points(std::vector<std::vector<coord_def> > &radius_points, - const coord_def &origin, const env_show_grid &losgrid); + const coord_def &origin, const los_def &los); void random_uselessness(int scroll_slot = -1); diff --git a/crawl-ref/source/env.h b/crawl-ref/source/env.h index 85bb53ad6b..c110be03eb 100644 --- a/crawl-ref/source/env.h +++ b/crawl-ref/source/env.h @@ -29,10 +29,6 @@ public: // Objects that are in LOS, used for drawing. show_def show; - // What would be visible, if all of the translucent wall were - // made opaque. - env_show_grid no_trans_show; - #ifdef USE_TILE // indexed by grid coords FixedArray<tile_fg_store, GXM, GYM> tile_bk_fg; diff --git a/crawl-ref/source/godwrath.cc b/crawl-ref/source/godwrath.cc index 088d5083de..8e3c769bed 100644 --- a/crawl-ref/source/godwrath.cc +++ b/crawl-ref/source/godwrath.cc @@ -1030,7 +1030,8 @@ static bool _feawn_retribution() // We are going to spawn some oklobs but first we need to find // out a little about the situation. std::vector<std::vector<coord_def> > radius_points; - collect_radius_points(radius_points,you.pos(),env.no_trans_show); + collect_radius_points(radius_points, you.pos(), + you.get_los_no_trans()); unsigned free_thresh = 30; diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index 54a8acba67..55ee0ec7c8 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -223,7 +223,7 @@ static bool _reaching_weapon_attack(const item_def& wpn) mpr("Your weapon cannot reach that far!"); return (false); } - else if (!see_cell_no_trans(beam.target) + else if (!you.see_cell_no_trans(beam.target) && grd(middle) <= DNGN_MAX_NONREACH) { // Might also be a granite statue/orcish idol which you diff --git a/crawl-ref/source/l_you.cc b/crawl-ref/source/l_you.cc index 70d165ee0d..cd9a6ab3fa 100644 --- a/crawl-ref/source/l_you.cc +++ b/crawl-ref/source/l_you.cc @@ -228,7 +228,7 @@ LUARET2(you_pos, number, you.pos().x, you.pos().y) LUARET1(you_see_cell, boolean, you.see_cell(coord_def(luaL_checkint(ls, 1), luaL_checkint(ls, 2)))) LUARET1(you_see_cell_no_trans, boolean, - see_cell_no_trans(coord_def(luaL_checkint(ls, 1), luaL_checkint(ls, 2)))) + you.see_cell_no_trans(coord_def(luaL_checkint(ls, 1), luaL_checkint(ls, 2)))) LUAFN(you_moveto) { diff --git a/crawl-ref/source/los.cc b/crawl-ref/source/los.cc index c3d06066f5..909ed97922 100644 --- a/crawl-ref/source/los.cc +++ b/crawl-ref/source/los.cc @@ -929,12 +929,7 @@ void losight_permissive(env_show_grid &sh, const coord_def& center) void calc_show_los() { if (!crawl_state.arena && !crawl_state.arena_suspended) - { you.update_los(); - // What would be visible, if all of the translucent walls were - // made opaque. - losight(env.no_trans_show, you.pos(), opc_no_trans); - } } bool see_cell(const env_show_grid &show, @@ -963,15 +958,8 @@ bool observe_cell(const coord_def &p) || you.see_cell(p)); } -// Answers the question: "Would a cell be within character's line of sight, -// even if all translucent/clear walls were made opaque?" -bool see_cell_no_trans(const coord_def &p) -{ - return see_cell(env.no_trans_show, you.pos(), p); -} - // Is the cell visible, but a translucent wall is in the way? bool trans_wall_blocking(const coord_def &p) { - return you.see_cell(p) && !see_cell_no_trans(p); + return (you.see_cell(p) && !you.see_cell_no_trans(p)); } diff --git a/crawl-ref/source/los.h b/crawl-ref/source/los.h index fd24d16cf1..642f90deab 100644 --- a/crawl-ref/source/los.h +++ b/crawl-ref/source/los.h @@ -50,7 +50,6 @@ bool see_cell(const env_show_grid &show, const coord_def &c, const coord_def &pos ); bool observe_cell(const coord_def &p); -bool see_cell_no_trans( const coord_def &p ); bool trans_wall_blocking( const coord_def &p ); #endif diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index a7d3f4dd6f..eee65cc43f 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -3,6 +3,7 @@ abl-show.o \ abyss.o \ acr.o \ actor.o \ +actor-los.o \ arena.o \ artefact.o \ attitude-change.o \ diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 39271c1592..f209c8153f 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -1256,7 +1256,7 @@ void search_around(bool only_adjacent) for (radius_iterator ri(you.pos(), max_dist); ri; ++ri ) { // Must have LOS, with no translucent walls in the way. - if (see_cell_no_trans(*ri)) + if (you.see_cell_no_trans(*ri)) { // Maybe we want distance() instead of feat_distance()? int dist = grid_distance(*ri, you.pos()); @@ -2776,12 +2776,12 @@ bool mons_is_safe(const monsters *mon, bool want_move, // Only seen through glass walls or within water? // Assuming that there are no water-only/lava-only // monsters capable of throwing or zapping wands. - || (!see_cell_no_trans(mon->pos()) + || (!you.see_cell_no_trans(mon->pos()) || mons_class_habitat(mon->type) == HT_WATER || mons_class_habitat(mon->type) == HT_LAVA) && !_mons_has_path_to_player(mon) && !mons_has_los_attack(mon) - && (!see_cell_no_trans(mon->pos()) + && (!you.see_cell_no_trans(mon->pos()) || !mons_has_ranged_ability(mon))); #ifdef CLUA_BINDINGS diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc index 62301ab0bd..ca5c4cd2dc 100644 --- a/crawl-ref/source/mon-act.cc +++ b/crawl-ref/source/mon-act.cc @@ -759,7 +759,7 @@ static bool _handle_reaching(monsters *monster) // This check isn't redundant -- player may be invisible. if (monster->target == you.pos() && grid_distance(monster->pos(), you.pos()) == 2 - && (see_cell_no_trans(monster->pos()) + && (you.see_cell_no_trans(monster->pos()) || grd(middle) > DNGN_MAX_NONREACH)) { ret = true; diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index ceeb613caf..fea055da96 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -2729,7 +2729,7 @@ bool empty_surrounds(const coord_def& where, dungeon_feature_type spc_wanted, continue; // Players won't summon out of LOS, or past transparent walls. - if (!see_cell_no_trans(*ri) && playerSummon) + if (!you.see_cell_no_trans(*ri) && playerSummon) continue; success = diff --git a/crawl-ref/source/monster.h b/crawl-ref/source/monster.h index b811059b73..68bf582a16 100644 --- a/crawl-ref/source/monster.h +++ b/crawl-ref/source/monster.h @@ -322,6 +322,8 @@ public: bool mon_see_cell(const coord_def& pos, bool reach = false) const; bool near_foe() const; + const los_def& get_los_no_trans(); + bool is_icy() const; bool is_fiery() const; bool paralysed() const; diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index e779582a0a..b6dd64644b 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -295,9 +295,8 @@ public: std::vector<int> beholders; protected: - FixedVector<PlaceInfo, NUM_BRANCHES> branch_info; - FixedVector<PlaceInfo, NUM_LEVEL_AREA_TYPES - 1> non_branch_info; - + FixedVector<PlaceInfo, NUM_BRANCHES> branch_info; + FixedVector<PlaceInfo, NUM_LEVEL_AREA_TYPES - 1> non_branch_info; public: player(); @@ -325,6 +324,10 @@ public: bool can_see_invisible() const; bool can_see_invisible(bool unid) const; bool visible_to(const actor *looker) const; + + bool see_cell_no_trans(const coord_def &c) const; + void update_los(); + bool is_icy() const; bool is_fiery() const; diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 548e7491ad..4cb64dcd99 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -131,7 +131,7 @@ int blink(int pow, bool high_level_controlled_blink, bool wizard_blink) mesclr(); mpr("You can't blink into the sea!"); } - else if (see_cell_no_trans(beam.target)) + else if (you.see_cell_no_trans(beam.target)) { // Grid in los, no problem. break; @@ -455,7 +455,7 @@ void cast_chain_lightning(int pow, const actor *caster) else if (!see_source && see_targ) mpr("The lightning arc suddenly appears!"); - if (!see_cell_no_trans( target )) + if (!you.see_cell_no_trans( target )) { // It's no longer in the caster's LOS and influence. pow = pow / 2 + 1; diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 040e7a9e09..e157ca688f 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -224,7 +224,7 @@ void corpse_rot() { for (radius_iterator ri(you.pos(), 6); ri; ++ri) { - if (see_cell_no_trans(*ri) && !is_sanctuary(*ri) + if (you.see_cell_no_trans(*ri) && !is_sanctuary(*ri) && env.cgrid(*ri) == EMPTY_CLOUD) { for (stack_iterator si(*ri); si; ++si) diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index a15b02fd32..35365fd302 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -1062,17 +1062,11 @@ int animate_dead(actor *caster, int pow, beh_type beha, unsigned short hitting, { UNUSED(pow); - // Use an alternate LOS grid, based on the caster's LOS. - env_show_grid losgrid; - if (caster->atype() != ACT_PLAYER) - losight(losgrid, caster->pos(), opc_no_trans); - int number_raised = 0; int number_seen = 0; radius_iterator ri(caster->pos(), 6, true, true, false, - caster->atype() == ACT_PLAYER ? &env.no_trans_show - : &losgrid); + &caster->get_los_no_trans()); // Sweep all squares in LOS. for (; ri; ++ri) diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index fd0dd6ab07..c560435d5e 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -2007,7 +2007,7 @@ static int _quadrant_blink(coord_def where, int pow, int, actor *) if (distance(base, target) > 10 || distance(you.pos(), target) < 8) continue; - if (!see_cell_no_trans(target)) + if (!you.see_cell_no_trans(target)) continue; found = true; diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index f62b74fa37..c7df5d907b 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -643,7 +643,7 @@ static int _get_dist_to_nearest_monster() continue; // Can we see (and reach) the grid? - if (!see_cell_no_trans(*ri)) + if (!you.see_cell_no_trans(*ri)) continue; const monsters *mon = monster_at(*ri); diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc index c84dbeb525..a11341c80c 100644 --- a/crawl-ref/source/spl-util.cc +++ b/crawl-ref/source/spl-util.cc @@ -486,7 +486,7 @@ int apply_area_visible(cell_func cf, int power, int rv = 0; for (radius_iterator ri(you.pos(), LOS_RADIUS); ri; ++ri) - if (pass_through_trans || see_cell_no_trans(*ri)) + if (pass_through_trans || you.see_cell_no_trans(*ri)) rv += cf(*ri, power, 0, agent); return (rv); diff --git a/crawl-ref/source/teleport.cc b/crawl-ref/source/teleport.cc index ba60707388..83fa11fe67 100644 --- a/crawl-ref/source/teleport.cc +++ b/crawl-ref/source/teleport.cc @@ -100,7 +100,7 @@ bool random_near_space(const coord_def& origin, coord_def& target, // Player can't randomly pass through translucent walls. if (origin_is_player) { - if (see_cell_no_trans(target)) + if (you.see_cell_no_trans(target)) return (true); continue; |