summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc2
-rw-r--r--crawl-ref/source/beam.cc19
-rw-r--r--crawl-ref/source/direct.cc164
-rw-r--r--crawl-ref/source/direct.h6
-rw-r--r--crawl-ref/source/effects.cc4
-rw-r--r--crawl-ref/source/it_use3.cc2
-rw-r--r--crawl-ref/source/item_use.cc2
-rw-r--r--crawl-ref/source/spells1.cc4
-rw-r--r--crawl-ref/source/spl-util.cc2
9 files changed, 140 insertions, 65 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index c928a43982..534c6117c5 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -2180,7 +2180,7 @@ void process_command( command_type cmd )
MSGCH_PROMPT);
struct dist lmove; // will be initialized by direction()
- direction(lmove, DIR_TARGET, TARG_ANY, true);
+ direction(lmove, DIR_TARGET, TARG_ANY, -1, true);
if (lmove.isValid && lmove.isTarget && !lmove.isCancel)
start_travel( lmove.tx, lmove.ty );
break;
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index bc76bf2e5d..a9d8abf02c 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2347,10 +2347,25 @@ bool check_line_of_sight( int sx, int sy, int tx, int ty )
*/
void mimic_alert(monsters *mimic)
{
+ bool should_id = !testbits(mimic->flags, MF_KNOWN_MIMIC)
+ && player_monster_visible(mimic) && mons_near(mimic);
+
+ // If we got here, we at least got a resists message, if not
+ // a full wounds printing. Thus, might as well id the mimic.
if (mimic->has_ench(ENCH_TP))
+ {
+ if (should_id)
+ mimic->flags |= MF_KNOWN_MIMIC;
+
return;
-
- monster_teleport( mimic, !one_chance_in(3) );
+ }
+
+ const bool instant_tele = !one_chance_in(3);
+ monster_teleport( mimic, instant_tele );
+
+ // at least for this short while, we know it's a mimic
+ if (!instant_tele && should_id)
+ mimic->flags |= MF_KNOWN_MIMIC;
} // end mimic_alert()
static bool _isBouncy(bolt &beam, unsigned char gridtype)
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index b7921d6a3f..55c807cfc6 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -85,21 +85,21 @@ enum LOSSelect
static void describe_feature(int mx, int my, bool oos);
static void describe_cell(int mx, int my);
-static bool find_object( int x, int y, int mode );
-static bool find_monster( int x, int y, int mode );
-static bool find_feature( int x, int y, int mode );
+static bool find_object( int x, int y, int mode, int range );
+static bool find_monster( int x, int y, int mode, int range );
+static bool find_feature( int x, int y, int mode, int range );
static char find_square_wrapper( int tx, int ty,
FixedVector<char, 2> &mfp, char direction,
- bool (*targ)(int, int, int),
- int mode = TARG_ANY,
+ bool (*targ)(int, int, int, int),
+ int mode = TARG_ANY, int range = -1,
bool wrap = false,
int los = LOS_ANY);
static char find_square( int xps, int yps,
FixedVector<char, 2> &mfp, int direction,
- bool (*targ)(int, int, int),
- int mode = TARG_ANY,
+ bool (*targ)(int, int, int, int),
+ int mode = TARG_ANY, int range = -1,
bool wrap = false,
int los = LOS_ANY);
@@ -121,7 +121,8 @@ void direction_choose_compass( dist& moves, targeting_behaviour *beh)
beh->compass = true;
- do {
+ do
+ {
const command_type key_command = beh->get_command();
if (key_command == CMD_TARGET_SELECT)
@@ -142,7 +143,8 @@ void direction_choose_compass( dist& moves, targeting_behaviour *beh)
moves.isCancel = true;
moves.isValid = false;
}
- } while ( !moves.isCancel && moves.dx == 0 && moves.dy == 0 );
+ }
+ while ( !moves.isCancel && moves.dx == 0 && moves.dy == 0 );
return;
}
@@ -244,6 +246,15 @@ static void draw_ray_glyph(const coord_def &pos, int colour,
#endif
}
+static bool _is_target_in_range(int x, int y, int range)
+{
+ // range doesn't matter
+ if (range == -1)
+ return true;
+
+ return (grid_distance(you.x_pos, you.y_pos, x, y) <= range);
+}
+
// We handle targeting for repeating commands and re-doing the
// previous command differently (i.e., not just letting the keys
// stuffed into the macro buffer replay as-is) because if the player
@@ -251,7 +262,7 @@ static void draw_ray_glyph(const coord_def &pos, int colour,
// moved between repititions, then simply replaying the keys in the
// buffer will target an empty square.
static void direction_again(dist& moves, targeting_type restricts,
- targ_mode_type mode, bool just_looking,
+ targ_mode_type mode, int range, bool just_looking,
const char *prompt, targeting_behaviour *beh)
{
moves.isValid = false;
@@ -325,7 +336,16 @@ static void direction_again(dist& moves, targeting_type restricts,
"square.");
return;
}
+ else if (!_is_target_in_range(you.prev_grd_targ.x, you.prev_grd_targ.y,
+ range))
+ {
+ moves.isCancel = true;
+ crawl_state.cancel_cmd_repeat("Your previous target is now out of "
+ "range.");
+ return;
+ }
+
moves.tx = you.prev_grd_targ.x;
moves.ty = you.prev_grd_targ.y;
@@ -348,8 +368,8 @@ static void direction_again(dist& moves, targeting_type restricts,
{
const monsters *montarget = &menv[you.prev_targ];
- if (!mons_near(montarget) ||
- !player_monster_visible( montarget ))
+ if (!mons_near(montarget)
+ || !player_monster_visible( montarget ))
{
moves.isCancel = true;
@@ -357,6 +377,15 @@ static void direction_again(dist& moves, targeting_type restricts,
return;
}
+ else if (!_is_target_in_range(you.prev_grd_targ.x, you.prev_grd_targ.y,
+ range))
+ {
+ moves.isCancel = true;
+
+ crawl_state.cancel_cmd_repeat("Your previous target is now out of "
+ "range.");
+ return;
+ }
moves.tx = montarget->x;
moves.ty = montarget->y;
@@ -394,7 +423,7 @@ static void direction_again(dist& moves, targeting_type restricts,
//
//---------------------------------------------------------------
void direction(dist& moves, targeting_type restricts,
- targ_mode_type mode, bool just_looking,
+ targ_mode_type mode, int range, bool just_looking,
bool needs_path, const char *prompt,
targeting_behaviour *beh)
{
@@ -406,7 +435,7 @@ void direction(dist& moves, targeting_type restricts,
if (crawl_state.is_replaying_keys() && restricts != DIR_DIR)
{
- direction_again(moves, restricts, mode, just_looking,
+ direction_again(moves, restricts, mode, range, just_looking,
prompt, beh);
return;
}
@@ -449,7 +478,9 @@ void direction(dist& moves, targeting_type restricts,
if ( you.prev_targ != MHITNOT && you.prev_targ != MHITYOU )
{
const monsters *montarget = &menv[you.prev_targ];
- if (mons_near(montarget) && player_monster_visible(montarget))
+ if ( mons_near(montarget) && player_monster_visible(montarget)
+ && !mons_friendly(montarget) // not made friendly since then
+ && _is_target_in_range(montarget->x, montarget->y, range) )
{
found_autotarget = true;
moves.tx = montarget->x;
@@ -661,7 +692,7 @@ void direction(dist& moves, targeting_type restricts,
{
const int thing_to_find = targeting_cmd_to_feature(key_command);
if (find_square_wrapper(moves.tx, moves.ty, objfind_pos, 1,
- find_feature, thing_to_find, true,
+ find_feature, thing_to_find, range, true,
Options.target_los_first ?
LOS_FLIPVH : LOS_ANY))
{
@@ -749,7 +780,7 @@ void direction(dist& moves, targeting_type restricts,
case CMD_TARGET_OBJ_CYCLE_FORWARD:
dir = (key_command == CMD_TARGET_OBJ_CYCLE_BACK) ? -1 : 1;
if (find_square_wrapper( moves.tx, moves.ty, objfind_pos, dir,
- find_object, 0, true,
+ find_object, 0, range, true,
Options.target_los_first
? (dir == 1? LOS_FLIPVH : LOS_FLIPHV)
: LOS_ANY))
@@ -768,7 +799,8 @@ void direction(dist& moves, targeting_type restricts,
case CMD_TARGET_CYCLE_BACK:
dir = (key_command == CMD_TARGET_CYCLE_BACK) ? -1 : 1;
if (find_square_wrapper( moves.tx, moves.ty, monsfind_pos, dir,
- find_monster, mode, Options.target_wrap ))
+ find_monster, mode, range,
+ Options.target_wrap))
{
moves.tx = monsfind_pos[0];
moves.ty = monsfind_pos[1];
@@ -1081,27 +1113,45 @@ bool in_los(int x, int y)
return (in_vlos(grid2view(coord_def(x, y))));
}
-static bool find_monster( int x, int y, int mode )
+static bool find_monster( int x, int y, int mode, int range = -1)
{
- const int targ_mon = mgrd[ x ][ y ];
if ((mode == TARG_FRIEND || mode == TARG_ANY)
- && x == you.x_pos && y == you.y_pos)
+ && x == you.x_pos && y == you.y_pos)
+ {
return (true);
+ }
- return (targ_mon != NON_MONSTER
- && in_los(x, y)
- && player_monster_visible( &(menv[targ_mon]) )
- && !mons_is_mimic( menv[targ_mon].type )
- && (mode == TARG_ANY
- || (mode == TARG_FRIEND && mons_friendly( &menv[targ_mon] ))
- || (mode == TARG_ENEMY
- && !mons_friendly( &menv[targ_mon] )
- &&
- (Options.target_zero_exp ||
- !mons_class_flag( menv[targ_mon].type, M_NO_EXP_GAIN )) )));
+ // don't target out of range
+ if (!_is_target_in_range(x, y, range))
+ return (false);
+
+ const int targ_mon = mgrd[ x ][ y ];
+
+ // Is target a (known) monster?
+ if (targ_mon == NON_MONSTER || !in_los(x,y)
+ || !player_monster_visible( &(menv[targ_mon]) )
+ || mons_is_mimic(menv[targ_mon].type)
+ && !(menv[targ_mon].flags & MF_KNOWN_MIMIC))
+ {
+ return (false);
+ }
+
+ // Now compare target modes.
+ if (mode == TARG_ANY)
+ return true;
+
+ if (mode == TARG_FRIEND)
+ return (mons_friendly(&menv[targ_mon] ));
+
+ if (mode != TARG_ENEMY)
+ return false;
+
+ return ( !mons_friendly( &menv[targ_mon] )
+ && (Options.target_zero_exp
+ || !mons_class_flag( menv[targ_mon].type, M_NO_EXP_GAIN )) );
}
-static bool find_feature( int x, int y, int mode )
+static bool find_feature( int x, int y, int mode, int /* range */)
{
// The stair need not be in LOS if the square is mapped.
if (!in_los(x, y) && (!Options.target_oos || !is_terrain_seen(x, y)))
@@ -1110,14 +1160,25 @@ static bool find_feature( int x, int y, int mode )
return is_feature(mode, x, y);
}
-static bool find_object(int x, int y, int mode)
+static bool find_object(int x, int y, int mode, int /* range */)
{
+ // First, check for mimics.
+ bool is_mimic = false;
+ const int mons = mgrd[ x ][ y ];
+ if (mons != NON_MONSTER
+ && player_monster_visible( &(menv[mons]) )
+ && mons_is_mimic(menv[mons].type)
+ && !(menv[mons].flags & MF_KNOWN_MIMIC))
+ {
+ is_mimic = true;
+ }
+
const int item = igrd[x][y];
- // The square need not be in LOS if the stash tracker knows this item.
- return (item != NON_ITEM
- && (in_los(x, y)
- || (Options.target_oos && is_terrain_seen(x, y)
- && is_stash(x, y))));
+ if (item == NON_ITEM && !is_mimic)
+ return false;
+
+ return (in_los(x, y) || Options.target_oos && is_terrain_seen(x, y)
+ && (is_stash(x, y) || is_mimic));
}
static int next_los(int dir, int los, bool wrap)
@@ -1192,8 +1253,8 @@ bool in_los_bounds(int x, int y)
//---------------------------------------------------------------
static char find_square( int xps, int yps,
FixedVector<char, 2> &mfp, int direction,
- bool (*find_targ)( int x, int y, int mode ),
- int mode, bool wrap, int los )
+ bool (*find_targ)( int x, int y, int mode, int range ),
+ int mode, int range, bool wrap, int los )
{
// the day will come when [unsigned] chars will be consigned to
// the fires of Gehenna. Not quite yet, though.
@@ -1257,19 +1318,19 @@ static char find_square( int xps, int yps,
{
if (direction == 1 && temp_xps == minx && temp_yps == maxy)
{
- if (find_targ(you.x_pos, you.y_pos, mode))
+ if (find_targ(you.x_pos, you.y_pos, mode, range))
{
mfp[0] = ctrx;
mfp[1] = ctry;
return (1);
}
return find_square(ctrx, ctry, mfp, direction, find_targ, mode,
- false, next_los(direction, los, wrap));
+ range, false, next_los(direction, los, wrap));
}
if (direction == -1 && temp_xps == ctrx && temp_yps == ctry)
{
return find_square(minx, maxy, mfp, direction, find_targ, mode,
- false, next_los(direction, los, wrap));
+ range, false, next_los(direction, los, wrap));
}
if (direction == 1)
@@ -1397,7 +1458,7 @@ static char find_square( int xps, int yps,
if ((onlyVis || onlyHidden) && onlyVis != in_los(targ_x, targ_y))
continue;
- if (find_targ(targ_x, targ_y, mode))
+ if (find_targ(targ_x, targ_y, mode, range))
{
mfp[0] = temp_xps;
mfp[1] = temp_yps;
@@ -1406,9 +1467,9 @@ static char find_square( int xps, int yps,
}
return (direction == 1?
- find_square(ctrx, ctry, mfp, direction, find_targ, mode, false,
+ find_square(ctrx, ctry, mfp, direction, find_targ, mode, range, false,
next_los(direction, los, wrap))
- : find_square(minx, maxy, mfp, direction, find_targ, mode, false,
+ : find_square(minx, maxy, mfp, direction, find_targ, mode, range, false,
next_los(direction, los, wrap)));
}
@@ -1417,11 +1478,12 @@ static char find_square( int xps, int yps,
// (mfp) are in grid coordinates rather than view coordinates.
static char find_square_wrapper( int tx, int ty,
FixedVector<char, 2> &mfp, char direction,
- bool (*find_targ)( int x, int y, int mode ),
- int mode, bool wrap, int los )
+ bool (*find_targ)( int x, int y, int mode,
+ int range ),
+ int mode, int range, bool wrap, int los )
{
- const char r = find_square(grid2viewX(tx), grid2viewY(ty),
- mfp, direction, find_targ, mode, wrap, los);
+ const char r = find_square(grid2viewX(tx), grid2viewY(ty), mfp,
+ direction, find_targ, mode, range, wrap, los);
mfp[0] = view2gridX(mfp[0]);
mfp[1] = view2gridY(mfp[1]);
return r;
diff --git a/crawl-ref/source/direct.h b/crawl-ref/source/direct.h
index a7b8382691..702d2ffd97 100644
--- a/crawl-ref/source/direct.h
+++ b/crawl-ref/source/direct.h
@@ -147,9 +147,9 @@ struct dist
};
void direction( dist &moves, targeting_type restricts = DIR_NONE,
- targ_mode_type mode = TARG_ANY, bool just_looking = false,
- bool needs_path = true, const char *prompt = NULL,
- targeting_behaviour *mod = NULL );
+ targ_mode_type mode = TARG_ANY, int range = -1,
+ bool just_looking = false, bool needs_path = true,
+ const char *prompt = NULL, targeting_behaviour *mod = NULL );
bool in_los_bounds(int x, int y);
bool in_viewport_bounds(int x, int y);
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index 0913e3a9ba..5921bece0f 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -1915,7 +1915,7 @@ void yell(bool force)
}
mpr("Gang up on whom?", MSGCH_PROMPT);
- direction( targ, DIR_TARGET, TARG_ENEMY, false, false );
+ direction( targ, DIR_TARGET, TARG_ENEMY, -1, false, false );
if (targ.isCancel)
{
@@ -2024,7 +2024,6 @@ bool vitrify_area(int radius)
const int clear_plus = DNGN_CLEAR_ROCK_WALL - DNGN_ROCK_WALL;
bool something_happened = false;
for ( int x = X_BOUND_1; x <= X_BOUND_2; ++x )
- {
for ( int y = Y_BOUND_1; y <= Y_BOUND_2; ++y )
{
if ( distance(x,y,you.x_pos,you.y_pos) < radius2 )
@@ -2041,7 +2040,6 @@ bool vitrify_area(int radius)
}
}
}
- }
return (something_happened);
}
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 6f7da402d3..3ce951dc19 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -257,7 +257,7 @@ static bool reaching_weapon_attack(const item_def& wpn)
mpr("Attack whom?", MSGCH_PROMPT);
- direction(beam, DIR_TARGET, TARG_ENEMY);
+ direction(beam, DIR_TARGET, TARG_ENEMY, 2);
if (!beam.isValid)
return false;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 1fbbb65bea..ca1cf7a46f 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -1511,7 +1511,7 @@ static bool _fire_choose_item_and_target(int& item, dist& target)
beh.message_ammo_prompt();
message_current_target(); // XXX: this stuff should be done by direction()
- direction( target, DIR_NONE, TARG_ENEMY, false, true, NULL, &beh );
+ direction( target, DIR_NONE, TARG_ENEMY, -1, false, true, NULL, &beh );
if (beh.item == ENDOFPACK)
{
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 01c06d2fd7..e9e2e21617 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -102,7 +102,7 @@ int blink(int pow, bool high_level_controlled_blink, bool wizard_blink)
// query for location {dlb}:
for (;;)
{
- direction(beam, DIR_TARGET, TARG_ANY, false, false,
+ direction(beam, DIR_TARGET, TARG_ANY, -1, false, false,
"Blink to where?");
if (!beam.isValid || coord_def(beam.tx, beam.ty) == you.pos())
@@ -489,7 +489,7 @@ bool conjure_flame(int pow)
done_first_message = true;
}
- direction( spelld, DIR_TARGET, TARG_ENEMY, false, false );
+ direction( spelld, DIR_TARGET, TARG_ENEMY, -1, false, false );
if (!spelld.isValid)
{
diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc
index 1a35365798..2aec6deff0 100644
--- a/crawl-ref/source/spl-util.cc
+++ b/crawl-ref/source/spl-util.cc
@@ -756,7 +756,7 @@ bool spell_direction( dist &spelld, bolt &pbolt,
if (restrict != DIR_DIR)
message_current_target();
- direction( spelld, restrict, mode, false, needs_path, prompt );
+ direction( spelld, restrict, mode, -1, false, needs_path, prompt );
if (!spelld.isValid)
{