summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-17 21:28:56 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-17 21:28:56 +0000
commit12de33d2d95164e30a8a2ac960ad28b2a69383e3 (patch)
tree4b238a712c0c7f329eed44cc23832f6998c7b2ca
parent46c7199d6ae8c006a78799a1c59dacf4e2d77c8f (diff)
downloadcrawl-ref-12de33d2d95164e30a8a2ac960ad28b2a69383e3.tar.gz
crawl-ref-12de33d2d95164e30a8a2ac960ad28b2a69383e3.zip
Another modification of autotargetting submerged monsters, based off
BR 1935715. * Targeting a square with a known submerged monster ("strange disturbance" description) always enforces '!' rather than '.' * Submerged monsters only get targetted if there are no other more viable targets (dangerous monsters, really) in sight. The latter uses a heavily modified i_feel_safe() that now draws on get_playervisible_monsters(), which got numerous new parameters to cover all possibilities. :p git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4314 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/direct.cc78
-rw-r--r--crawl-ref/source/fight.cc10
-rw-r--r--crawl-ref/source/invent.cc1
-rw-r--r--crawl-ref/source/misc.cc150
-rw-r--r--crawl-ref/source/misc.h9
-rw-r--r--crawl-ref/source/skills2.cc10
6 files changed, 135 insertions, 123 deletions
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index 31bf2c580d..c822c03304 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -247,6 +247,19 @@ static void draw_ray_glyph(const coord_def &pos, int colour,
#endif
}
+// Unseen monsters in shallow water show a "strange disturbance".
+// (Unless flying!)
+static bool _mon_submerged_in_water(const monsters *mon)
+{
+ if (!mon)
+ return false;
+
+ return (grd[mon->x][mon->y] == DNGN_SHALLOW_WATER
+ && see_grid(mon->x, mon->y)
+ && !player_monster_visible(mon)
+ && !mons_flies(mon));
+}
+
static bool _is_target_in_range(int x, int y, int range)
{
// range doesn't matter
@@ -564,11 +577,11 @@ void direction(dist& moves, targeting_type restricts,
key_command = shift_direction(key_command);
}
- if (target_unshifted &&
- (key_command == CMD_TARGET_CYCLE_FORWARD
- || key_command == CMD_TARGET_CYCLE_BACK
- || key_command == CMD_TARGET_OBJ_CYCLE_FORWARD
- || key_command == CMD_TARGET_OBJ_CYCLE_BACK))
+ if (target_unshifted
+ && (key_command == CMD_TARGET_CYCLE_FORWARD
+ || key_command == CMD_TARGET_CYCLE_BACK
+ || key_command == CMD_TARGET_OBJ_CYCLE_FORWARD
+ || key_command == CMD_TARGET_OBJ_CYCLE_BACK))
{
target_unshifted = false;
}
@@ -710,8 +723,8 @@ void direction(dist& moves, targeting_type restricts,
mode = static_cast<targ_mode_type>((mode + 1) % TARG_NUM_MODES);
mprf( "Targeting mode is now: %s",
(mode == TARG_ANY) ? "any" :
- (mode == TARG_ENEMY) ? "enemies" :
- "friends" );
+ (mode == TARG_ENEMY) ? "enemies"
+ : "friends" );
break;
case CMD_TARGET_PREV_TARGET:
@@ -758,7 +771,13 @@ void direction(dist& moves, targeting_type restricts,
moves.isEndpoint = true;
// intentional fall-through
case CMD_TARGET_SELECT: // finalize current choice
- moves.isValid = true;
+ if (!moves.isEndpoint
+ && mgrd[moves.tx][moves.ty] != NON_MONSTER
+ && _mon_submerged_in_water(&menv[mgrd[moves.tx][moves.ty]]))
+ {
+ moves.isEndpoint = true;
+ }
+ moves.isValid = true;
moves.isTarget = true;
loop_done = true;
@@ -919,8 +938,8 @@ void direction(dist& moves, targeting_type restricts,
MSGCH_EXAMINE_FILTER);
}
// Ask for confirmation if we're quitting for some odd reason
- else if ( moves.isValid || moves.isCancel ||
- yesno("Are you sure you want to fizzle?", false, 'n') )
+ else if ( moves.isValid || moves.isCancel
+ || yesno("Are you sure you want to fizzle?", false, 'n') )
{
// Finalize whatever is inside the loop
// (moves-internal finalizations can be done later)
@@ -966,17 +985,18 @@ void direction(dist& moves, targeting_type restricts,
#ifdef USE_TILE
// tiles always need a beam redraw if show_beam is true (and if valid...)
- if (show_beam && find_ray(you.x_pos, you.y_pos, moves.tx, moves.ty,
- true, ray, 0, true) || need_beam_redraw )
+ if ( need_beam_redraw
+ || show_beam && find_ray(you.x_pos, you.y_pos, moves.tx, moves.ty,
+ true, ray, 0, true) )
{
#else
if ( need_beam_redraw )
{
viewwindow(true, false);
#endif
- if ( show_beam &&
- in_vlos(grid2viewX(moves.tx), grid2viewY(moves.ty)) &&
- moves.target() != you.pos() )
+ if ( show_beam
+ && in_vlos(grid2viewX(moves.tx), grid2viewY(moves.ty))
+ && moves.target() != you.pos() )
{
// Draw the new ray with magenta '*'s, not including
// your square or the target square.
@@ -996,7 +1016,7 @@ void direction(dist& moves, targeting_type restricts,
textcolor(LIGHTGREY);
#ifdef USE_TILE
draw_ray_glyph(moves.target(), MAGENTA, '*',
- MAGENTA | COLFLAG_REVERSE);
+ MAGENTA | COLFLAG_REVERSE);
}
viewwindow(true, false);
#else
@@ -1131,23 +1151,27 @@ static bool find_monster( int x, int y, int mode, int range = -1)
if (targ_mon == NON_MONSTER || !in_los(x,y))
return (false);
- // Unseen monsters in shallow water show a "strange disturbance"
- // (unless flying!)
- if (!player_monster_visible(&menv[targ_mon]))
- {
- // since you can't see the monster, assume it's not a friend
- return (mode != TARG_FRIEND
- && grd[x][y] == DNGN_SHALLOW_WATER
- && !mons_flies(&menv[targ_mon]));
- }
+ monsters *mon = &menv[targ_mon];
// Unknown mimics don't count as monsters, either.
- if (mons_is_mimic(menv[targ_mon].type)
- && !(menv[targ_mon].flags & MF_KNOWN_MIMIC))
+ if (mons_is_mimic(mon->type)
+ && !(mon->flags & MF_KNOWN_MIMIC))
{
return (false);
}
+ // Don't usually target unseen monsters...
+ if (!player_monster_visible(mon))
+ {
+ // ... unless it creates a "disturbance in the water".
+ // Since you can't see the monster, assume it's not a friend.
+ // Also don't target submerged monsters if there are other targets
+ // in sight. (This might be too restrictive.)
+ return (mode != TARG_FRIEND
+ && _mon_submerged_in_water(mon)
+ && i_feel_safe(false, false, true, range));
+ }
+
// Now compare target modes.
if (mode == TARG_ANY)
return true;
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 80e10471de..ddbaad4aa2 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -348,13 +348,13 @@ void melee_attack::init_attack()
if (defender)
defender_shield = defender->shield();
- water_attack = is_water_attack(attacker, defender);
- attacker_visible = attacker->visible();
+ water_attack = is_water_attack(attacker, defender);
+ attacker_visible = attacker->visible();
attacker_invisible = !attacker_visible && see_grid(attacker->pos());
- defender_visible = defender && defender->visible();
+ defender_visible = defender && defender->visible();
defender_invisible = !defender_visible && defender
- && see_grid(defender->pos());
- needs_message = attacker_visible || defender_visible;
+ && see_grid(defender->pos());
+ needs_message = attacker_visible || defender_visible;
if (defender && defender->submerged())
unarmed_ok = false;
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index 01e5bd5543..f232e5374c 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -537,6 +537,7 @@ const menu_sort_condition *InvMenu::find_menu_sort_condition() const
for (int i = 0, size = Options.sort_menus.size(); i < size; ++i)
if (Options.sort_menus[i].matches(type))
return &Options.sort_menus[i];
+
return (NULL);
}
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index bb1cba82f7..5f210c6ca7 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -2537,10 +2537,10 @@ bool mons_is_safe(const struct monsters *mon, bool want_move)
|| mons_class_flag(mon->type, M_NO_EXP_GAIN);
#ifdef CLUA_BINDINGS
- bool moving = ((!you.delay_queue.empty() &&
- is_run_delay(you.delay_queue.front().type) &&
- you.delay_queue.front().type != DELAY_REST) ||
- you.running < RMODE_NOT_RUNNING || want_move);
+ bool moving = ((!you.delay_queue.empty()
+ && is_run_delay(you.delay_queue.front().type)
+ && you.delay_queue.front().type != DELAY_REST)
+ || you.running < RMODE_NOT_RUNNING || want_move);
int dist = grid_distance(you.x_pos, you.y_pos,
mon->x, mon->y);
@@ -2559,113 +2559,97 @@ bool mons_is_safe(const struct monsters *mon, bool want_move)
// Return all monsters in LOS that the player is able to see
// and recognize as being a monster.
-void get_playervisible_monsters(std::vector<monsters*>& mons)
+void get_playervisible_monsters(std::vector<monsters*> &mons, bool want_move,
+ bool just_check, bool dangerous, int range)
{
- const int ystart = MAX(0, you.y_pos - LOS_RADIUS);
- const int yend = MIN(GYM, you.y_pos + LOS_RADIUS);
- const int xstart = MAX(0, you.x_pos - LOS_RADIUS);
- const int xend = MIN(GXM, you.x_pos + LOS_RADIUS);
+ if (range == -1)
+ range = LOS_RADIUS;
+
+ const int ystart = MAX(0, you.y_pos - range);
+ const int yend = MIN(GYM, you.y_pos + range);
+ const int xstart = MAX(0, you.x_pos - range);
+ const int xend = MIN(GXM, you.x_pos + range);
// monster check
for ( int y = ystart; y < yend; ++y )
- for ( int x = xstart; x < xend; ++x )
- {
- const unsigned short targ_monst = env.mgrid[x][y];
- if ( targ_monst != NON_MONSTER )
+ for ( int x = xstart; x < xend; ++x )
{
- if ( see_grid(x,y) )
+ const unsigned short targ_monst = env.mgrid[x][y];
+ if ( targ_monst != NON_MONSTER )
{
- monsters *mon = &env.mons[targ_monst];
- if ( player_monster_visible(mon) &&
- !mons_is_submerged(mon) &&
- (!mons_is_mimic(mon->type) || mons_is_known_mimic(mon))
- )
+ if ( see_grid(x,y) )
{
- mons.push_back(mon);
+ monsters *mon = &env.mons[targ_monst];
+ if ( player_monster_visible(mon)
+ && !mons_is_submerged(mon)
+ && (!mons_is_mimic(mon->type)
+ || mons_is_known_mimic(mon))
+ && (!dangerous || !mons_is_safe(mon, want_move)))
+ {
+ mons.push_back(mon);
+ if (just_check)
+ {
+ // one monster found, that's enough
+ return;
+ }
+ }
}
}
}
- }
}
-bool i_feel_safe(bool announce, bool want_move)
+bool i_feel_safe(bool announce, bool want_move, bool just_monsters, int range)
{
- int ystart = you.y_pos - 9, xstart = you.x_pos - 9;
- int yend = you.y_pos + 9, xend = you.x_pos + 9;
- if ( xstart < 0 ) xstart = 0;
- if ( ystart < 0 ) ystart = 0;
- if ( xend >= GXM ) xend = GXM;
- if ( yend >= GYM ) yend = GYM;
-
- if (in_bounds(you.x_pos, you.y_pos)
- && env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD)
- {
- const cloud_type type =
- env.cloud[ env.cgrid[you.x_pos][you.y_pos] ].type;
- if (is_damaging_cloud(type, false))
- {
- if (announce)
- mprf(MSGCH_WARN, "You're standing in a cloud of %s!",
- cloud_name(type).c_str());
- return (false);
- }
- }
-
- // no monster will attack you inside a sanctuary,
- // so presence of monsters won't matter
- if (is_sanctuary(you.x_pos, you.y_pos))
- return (true);
-
- std::vector<const monsters *> mons;
-
- // monster check
- // XXX: refactor this to make use of get_playervisible_monsters()
- for ( int y = ystart; y < yend; ++y )
+ if (!just_monsters)
{
- for ( int x = xstart; x < xend; ++x )
+ if (in_bounds(you.x_pos, you.y_pos)
+ && env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD)
{
- // if you can see an unfriendly monster, then you feel unsafe
- if ( see_grid(x,y) )
+ const cloud_type type =
+ env.cloud[ env.cgrid[you.x_pos][you.y_pos] ].type;
+ if (is_damaging_cloud(type, false))
{
- const unsigned short targ_monst = mgrd[x][y];
- if ( targ_monst != NON_MONSTER )
+ if (announce)
{
- const monsters *mon = &menv[targ_monst];
- if ( player_monster_visible(mon) &&
- !mons_is_submerged(mon) &&
- !mons_is_mimic(mon->type) &&
- !mons_is_safe(mon, want_move))
- {
- if (announce)
- mons.push_back(mon);
- else
- {
- tutorial_first_monster(*mon);
- return false;
- }
- }
+ mprf(MSGCH_WARN, "You're standing in a cloud of %s!",
+ cloud_name(type).c_str());
}
+ return (false);
}
}
+
+ // no monster will attack you inside a sanctuary,
+ // so presence of monsters won't matter
+ if (is_sanctuary(you.x_pos, you.y_pos))
+ return (true);
}
- if (announce)
+ // monster check
+ std::vector<monsters*> visible;
+ get_playervisible_monsters(visible, !announce, want_move, true, range);
+
+ // No monsters found.
+ if (visible.empty())
+ return true;
+
+ // Announce the presence of monsters (Eidolos).
+ if (visible.size() == 1)
{
- // Announce the presence of monsters (Eidolos).
- if (mons.size() == 1)
+ const monsters &m = *visible[0];
+ if (announce)
{
- const monsters &m = *mons[0];
mprf(MSGCH_WARN, "Not with %s in view!",
- m.name(DESC_NOCAP_A).c_str());
- }
- else if (mons.size() > 1)
- {
- mprf(MSGCH_WARN, "Not with these monsters around!");
+ m.name(DESC_NOCAP_A).c_str());
}
- return (mons.empty());
+ else
+ tutorial_first_monster(m);
+ }
+ else if (announce && visible.size() > 1)
+ {
+ mprf(MSGCH_WARN, "Not with these monsters around!");
}
- return true;
+ return (false);
}
static const char *shop_types[] = {
diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h
index 9e71adead8..2223757511 100644
--- a/crawl-ref/source/misc.h
+++ b/crawl-ref/source/misc.h
@@ -113,7 +113,12 @@ void curare_hits_player(int agent, int degree);
bool mons_is_safe(const monsters *mon, bool want_move = false);
-bool i_feel_safe(bool announce = false, bool want_move = false);
+void get_playervisible_monsters(std::vector<monsters*>& mons,
+ bool just_check = false, bool want_move = false,
+ bool dangerous = false, int range = -1);
+
+bool i_feel_safe(bool announce = false, bool want_move = false,
+ bool just_monsters = false, int range = -1);
void setup_environment_effects();
@@ -137,6 +142,4 @@ bool interrupt_cmd_repeat( activity_interrupt_type ai,
void reveal_secret_door(int x, int y);
-void get_playervisible_monsters(std::vector<monsters*>& mons);
-
#endif
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index 01a120a906..550164c3ee 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -1698,13 +1698,13 @@ static const skill_type skill_display_order[] =
static const int ndisplayed_skills =
sizeof(skill_display_order) / sizeof(*skill_display_order);
-static bool player_knows_aptitudes()
+static bool _player_knows_aptitudes()
{
return !player_genus(GENPC_DRACONIAN) || you.max_level >= 7;
}
-static void display_skill_table(bool show_aptitudes)
+static void _display_skill_table(bool show_aptitudes)
{
menu_letter lcount = 'a';
const int num_lines = get_number_of_lines();
@@ -1847,7 +1847,7 @@ static void display_skill_table(bool show_aptitudes)
textcolor(LIGHTGREY);
cprintf("Press the letter of a skill to choose "
"whether you want to practise it.");
- if (player_knows_aptitudes())
+ if (_player_knows_aptitudes())
{
cgotoxy(1, bottom_line);
formatted_string::parse_string("Press '!' to toggle between "
@@ -1864,10 +1864,10 @@ void show_skills()
clrscr();
while (true)
{
- display_skill_table(show_aptitudes);
+ _display_skill_table(show_aptitudes);
const int keyin = getch();
- if (keyin == '!' && player_knows_aptitudes())
+ if (keyin == '!' && _player_knows_aptitudes())
{
show_aptitudes = !show_aptitudes;
continue;