pick_random_monster() to try something else, rather than by culling them after they're placed.
By default the arena prevents zero xp monsters from being randomly placed. To allow them to be placed use the spec tag "allow_zero_xp".
Removed the arena spec tag "alert", since it's no longer needed.
Added the arena spec tag "cycle_random", which if set causes pick_random_monster() to cycle through all the monsters valid for the level_id chosen as the arena's place. Produces a greater variety of monsters when using test spawners.
If arena mode is dumping message to the output file then prefix error messages with "ERROR: " and diagnostic messages with "DIAG: "
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8165 c06c8d41-db1a-0410-9941-cceddc491573
R32CQ6FQJTQLB35P3HENIDCBDT3UWXBBCDAAUWHUQO6G6NKEDPKQC
55PFDYPVE6JVGDYPCFUE4XS2523PVSV4CSIFRW6A2GGX4I6VWRWQC
WGM77XP66ZEIRWAOKAJDICJ4ZBEUKGAEY6MZQQJ2LUWG5PCG722QC
KFF5D5WMDV2B5CZRI2WAVBH7NZZ2JA2RVY2L3O2TMHETD47VN4DAC
JIEXJFA2CK46JWK2YXA73S6QMCTPVV7JYVW63CHHHN33IBFSCEQQC
MB3ZKRP3CSLCJJSXQ44QTAME4M4OOAQLNQ2K3D3AFQV5FO6H3EPQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC
MSMWAL6JZAWNGZXCNXPATUMAU6TVXBWWFY666P7UBSZ5LPYJYUCQC
PKXXBHS3LWLPZI2QVRX22MSQ4R2626IXRSNHFFYHXYTLJJQU54LQC
WDEFQ6YABDQIGJXW5KT3OGR3EO6FZHXZELIRVIXQ4XDYTVOV5V6AC
UZ6N6HOUPGVSPC5NQROEEDWMEGJA5XUWUY2AKH5QG65AZ25PVXDAC
74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC
ONOH6OOENDDCK5H25C6RLLVAOCO4T6PG2GTURIDXFK7FFXGIYASQC
JQKRFPNPLYBHUWMVQLPX5UB5RRP5PKY6NQ5LRHJRIOY6IKN2AH6AC
PKENI7REL6MQ5KKGSBIOVMPJKITY6OLQRXHVD4Z6PU7HMS23XM7AC
ESHSNJO7LNU6GCDNEBRZAXZYVJK63CUGSXO5FO2Q6ZVGJGJ5NXOQC
OKAC6U6XUKANH3325B5UYUYBF3IST74DEMK573ZPUNTSLIT52TSAC
bool allow_summons = true;
bool no_immobile = false;
bool do_alert = false;
bool allow_summons = true;
bool allow_zero_xp = false;
bool allow_immobile = true;
}
}
void alert_faction(bool friendly)
{
int alerter = 0;
for (int i = 0; i < MAX_MONSTERS; i++)
{
const monsters *mon = &menv[i];
if (!mon->alive())
continue;
if (mons_friendly(mon) != friendly)
{
alerter = i;
break;
}
}
// Move player aside so that behaviour_event() default src_pos
// isn't the same as the player's position, in order to avoid an
// assertion.
you.position = coord_def(-1, -1);
for (int i = 0; i < MAX_MONSTERS; i++)
{
monsters *mon = &menv[i];
if (!mon->alive())
continue;
if (mons_friendly(mon) == friendly)
behaviour_event(mon, ME_ALERT, alerter);
allow_summons = !strip_tag(spec, "no_summons");
do_alert = strip_tag(spec, "alert");
no_immobile = strip_tag(spec, "no_immobile");
allow_summons = !strip_tag(spec, "no_summons");
allow_immobile = !strip_tag(spec, "no_immobile");
allow_zero_xp = strip_tag(spec, "allow_zero_xp");
cycle_random = strip_tag(spec, "cycle_random");
if (!mon->alive())
continue;
if (mons_is_stationary(mon) && mon->is_summoned())
monster_die(mon, KILL_DISMISSED, NON_MONSTER, true, true);
if (chan == MSGCH_ERROR)
msg = "ERROR: " + msg;
else if (chan == MSGCH_DIAGNOSTICS)
msg = "DIAG: " + msg;
fprintf(file, "%s\n", msg.c_str());
}
}
/////////////////////////////////////////////////////////////////////////////
// Various arena callbacks
monster_type arena_pick_random_monster(const level_id &place, int power,
int &lev_mons)
{
if (!arena::cycle_random)
return (RANDOM_MONSTER);
for (int tries = 0; tries <= NUM_MONSTERS; tries++)
{
arena::cycle_random_pos++;
if (arena::cycle_random_pos >= NUM_MONSTERS)
arena::cycle_random_pos = 0;
const monster_type type = (monster_type) arena::cycle_random_pos;
if (mons_rarity(type, place) == 0)
continue;
if (arena_veto_random_monster(type))
continue;
return (type);
end(1, false, "No random monsters for place '%s'",
arena::place.describe().c_str());
return (NUM_MONSTERS);
}
bool arena_veto_random_monster(monster_type type)
{
if (!arena::allow_immobile && mons_class_is_stationary(type))
return (true);
if (!arena::allow_zero_xp && mons_class_flag(type, M_NO_EXP_GAIN))
return (true);
return (false);