From f9bb873c8b6192688281a1d738c46d19352c8d51 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Fri, 29 May 2009 03:21:19 +0000 Subject: FR 2797173: * When hovering the cursor/cross-hair over a visible monster which has a blocked line of fire, describe the monster as having a blocked line of fire. * If a player tracer beam is fired at a visble monster or square which has a blocked line of fire, warn the player about it and allow the player to cancel. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9845 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 35 +++++++++++++++++++++++++++++++++++ crawl-ref/source/directn.cc | 17 ++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 5f86991643..78cd63f25e 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1792,6 +1792,41 @@ void bolt::hit_wall() const dungeon_feature_type feat = grd(pos()); ASSERT( grid_is_solid(feat) ); + if (is_tracer && YOU_KILL(thrower) && flavour != BEAM_DIGGING + && flavour <= BEAM_LAST_REAL && pos() != target && pos() != source + && !affects_nothing && bounces == 0 && reflections == 0 + && see_grid(target) && !grid_is_solid(grd(target))) + { + // Okay, with all those tests passed, this is probably an instance + // of the player manually targetting something whose line of fire + // is blocked, even though its line of sight isn't blocked. Give + // a warning about this fact. + std::string prompt = "Your line of fire to "; + const monsters* mon = monster_at(target); + + if (mon && you.can_see(mon)) + prompt += mon->name(DESC_NOCAP_THE); + else + { + prompt += "the targeted " + + feature_description(target, false, DESC_PLAIN, false); + } + + prompt += " is blocked by " + + feature_description(pos(), false, DESC_NOCAP_A, false); + + prompt += ". Continue anyway?"; + + if (!yesno(prompt.c_str(), false, 'n')) + { + beam_cancelled = true; + finish_beam(); + return; + } + + // Well, we warned them. + } + if (affects_wall(feat)) affect_wall(); else if (is_bouncy(feat) && !in_explosion_phase) diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 5f6aa57fc9..7959b19807 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -958,7 +958,8 @@ bool _dist_ok(const dist& moves, int range, targ_mode_type mode, return (true); } -static bool _blocked_ray(const coord_def &where) +static bool _blocked_ray(const coord_def &where, + dungeon_feature_type* feat = NULL) { ray_def ray; find_ray(you.pos(), where, true, ray, 0, true); @@ -967,7 +968,11 @@ static bool _blocked_ray(const coord_def &where) while (ray.pos() != where) { if (grd(ray.pos()) <= DNGN_MINMOVE) + { + if (feat != NULL) + *feat = grd(ray.pos()); return (true); + } ray.advance_through(where); } return (false); @@ -3114,6 +3119,16 @@ static std::string _get_monster_desc(const monsters *mon) else if (mons_enslaved_soul(mon)) text += pronoun + " is a disembodied soul.\n"; + dungeon_feature_type blocking_feat; + if (_blocked_ray(mon->pos(), &blocking_feat)) + { + text += "Your line of fire to " + lowercase_string(pronoun) + + " is blocked by " + + feature_description(blocking_feat, NUM_TRAPS, false, + DESC_NOCAP_A) + + "\n"; + } + text += _mon_enchantments_string(mon); return text; } -- cgit v1.2.3-54-g00ecf