New command on 'F' (one of the few free keys, not documented yet).
What it does: List all monsters in sight, sorted first by attitude (hostile, neutral, friendly), then by monster type (number currently, but we could use any other measure instead).
My four current wiz-mode testing games produced the following output: a) You can see three orcs, and two neutral orcs. b) You can see a friendly orc, and a friendly elf. c) There are no monsters in sight! d) You can see a red devil, a hairy devil, an iron devil, a lemure, three ufetubi, a midge, a neutral deep elf summoner, and a friendly rat.
Also:
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3844 c06c8d41-db1a-0410-9941-cceddc491573
XX62GOJVDP352L4BH7MELNYXHMZNA6VAGF7B6RWWOSULX7VJR5YAC
ARORC5GJNHLAPL2MJ3PUYIAR55ETDDAPXYSYH4OBMXHADNWSGYPAC
7FUHFAXXCAL5TZ3MGUVMWH44637Z7WYJOM5Y5P6K6YPO22TNLDJQC
ACDPN464TK2LKLHSDN3YVRHAPF7WLSLLU3UHIYEXKFDEZPEU3XSQC
UWMN4HLG6YA2YFQEVIVMDISD6APKEPIZXMMPMNUYCBQDSAUYSXPQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
CH7JECYYH35H4TRHRNRTRJCQTQLZ2WRH62TKV72SUIU2RTK5OH7AC
GL6SGPBZQPJBVGPOASYVCTAFXS7RNARR6Y5WZMIO5YCTB7ZJY4KAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
5CNYJQGEILRX2TAYBWMVECJ6D4OPV2CD6YPDIERS2SR77Z4LTZPAC
3YK4G4IQBXW63HPGU5WRTV6L2FCMKAK4DOTCHFK2FNSB5B3Y3PVQC
547JREUJXTZNYVGHNNAET5F5O5JYYGNTDQB6ABZNT7YX5EY64OHAC
AVCMVFA3MKCXHO6H44UK5KJNIHTGQV7UA7GYXM26VI6TXXU5ZN6QC
}
static bool _mons_hostile( const monsters *mon)
{
return (!mons_friendly(mon) && !mons_neutral(mon));
}
static const char* _get_monster_name(const monsters *mon, bool list_a = false)
{
std::string desc = "";
bool adj = false;
if (mons_friendly(mon))
{
desc += "friendly ";
adj = true;
}
else if (mons_neutral(mon))
{
desc += "neutral ";
adj = true;
}
if (adj && list_a)
{
desc = "a " + desc;
list_a = false;
}
desc += mons_type_name(mon->type, (list_a ? DESC_NOCAP_A : DESC_PLAIN));
return desc.c_str();
}
// Returns true if the first monster is more aggressive (in terms of
// hostile/neutral/friendly) than the second or, if both monsters share the
// same attitude, if the first monster has a lower type.
// If monster type and attitude are the same, return false.
static bool _compare_monsters_attitude( const monsters *m1, const monsters *m2 )
{
if (_mons_hostile(m1) && !_mons_hostile(m2))
return (true);
if (mons_neutral(m1))
{
if (mons_friendly(m2))
return (true);
if (_mons_hostile(m2))
return (false);
}
if (mons_friendly(m1) && !mons_friendly(m2))
return (false);
// If we get here then monsters have the same attitude.
// FIX ME: replace with difficulty comparison
return (m1->type < m2->type);
}
static void _list_monsters()
{
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;
std::vector<const monsters*> mons;
// monster check
for ( int y = ystart; y < yend; ++y )
for ( int x = xstart; x < xend; ++x )
if ( see_grid(x,y) )
{
const unsigned short targ_monst = mgrd[x][y];
if ( targ_monst != NON_MONSTER )
{
const monsters *mon = &menv[targ_monst];
if ( player_monster_visible(mon)
&& !mons_is_submerged(mon)
&& !mons_is_mimic(mon->type))
{
mons.push_back(mon);
}
}
}
if (mons.empty())
{
mpr("There are no monsters in sight!");
return;
}
else if (mons.size() == 1)
{
mprf("You can see %s.",
mons_type_name(mons[0]->type, DESC_NOCAP_A).c_str());
return;
}
std::sort( mons.begin(), mons.end(), _compare_monsters_attitude );
std::vector<std::string> describe;
int count = 0;
int size = mons.size();
for (int i = 0; i < size; ++i)
{
if (i > 0 && _compare_monsters_attitude(mons[i-1], mons[i]))
{
if (count == 1)
describe.push_back(_get_monster_name(mons[i-1], true));
else
{
describe.push_back(number_in_words(count) + " "
+ pluralise(_get_monster_name(mons[i-1])));
}
count = 0;
}
count++;
}
// handle last monster
if (_compare_monsters_attitude(mons[size-2], mons[size-1]))
describe.push_back(_get_monster_name(mons[size-1], true));
else
{
describe.push_back(number_in_words(count) + " "
+ pluralise(_get_monster_name(mons[size-1])));
}
std::string msg = "You can see ";
msg += comma_separated_line(describe.begin(), describe.end(),
", and ", ", ");
msg += ".";
mpr(msg.c_str());
case CONTROL('M'): return CMD_NO_CMD;
case CONTROL('I'): return CMD_NO_CMD; // Backspace on most systems
case CONTROL('M'): return CMD_NO_CMD; // Enter on most systems