diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/beam.cc | 19 | ||||
-rw-r--r-- | crawl-ref/source/direct.cc | 164 | ||||
-rw-r--r-- | crawl-ref/source/direct.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/effects.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/it_use3.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/spells1.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/spl-util.cc | 2 |
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) { |