BEH_LEAVE replaces BEH_INVESTIGATE, which wasn't being used.
Notes:
Since leaving the level is similar to fleeing in some ways, monsters leaving the level share some behaviors with fleeing monsters: they are less likely to shoot; they are more likely to use scrolls of blinking or teleportation; and leaving eyeballs won't paralyze you or drain your MP.
Leaving the level is also similar to lurking in some ways, so it won't be interrupted by noticing something, just as with lurking.
Getting far enough away from a monster will make it leave the level (i.e., die with KILL_DISMISSED and MF_HARD_RESET, so it takes its stuff with it), as will getting it into a grid it can submerge in, at which time it will submerge and leave the level. Neither of these apply to monsters that can't move, of course, except for mimics, since they can teleport.
Incomplete things (sorry for the mess):
I still haven't figured out how to make a monster target a dungeon feature (in this case, the nearest level exit, the nearest teleportation or shaft trap, or the nearest submersible grid), so, currently, a pacified monster will just go to where its last target was and stand there until/unless one of the aforementioned level exit scenarios occurs.
Pacified monsters can still cast summoning spells. Whatever they summon
is neutral, just as they are, but such summons can still get in the way.
(Try pacifying an orc high priest, for example.) Maybe summoning should
be disabled or have its chance lowered for neutral monsters in general,
unless something's in their way?
Speaking of targeting, the leaving-by-submerging scenario should occur only if there's no other way to reach the target: all ways off the level are blocked, the monster's habitat is water and it's not amphibious, the monster's habitat is lava, or (possibly) the monster's habitat is rock.
There should be a message if the monster leaves the level, but what about the ones that do so out of the player's LOS?
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5924 c06c8d41-db1a-0410-9941-cceddc491573
VEVPRVWGRHRKBBUTO64ELK3NPZANUQI3ZZ7F23YXJQLKIORUW3HQC
3CY6KJWHQUZFZGO2C7VVCO32RRHUIMQQQJAE2MUXFF45F7ECRLJQC
CMGEKP57BEOQXLDZJCFDQJ3R47REQOG45GI6OV4AWOZTZ2CH7JPQC
JPBP7PZSMLAI3DCMQZ3RB5EBDFAXJLZJE5MMUHADIJE5VYEMD5KQC
UJTB5VR2BSQSN2QRTLZPM2MDNHQ6KKRCPOBESWSM24N2PTWPRRHQC
KZ2HPEQZ5JPJO7GYJTMMQSTJLUETPHG4WEX2X3GWAMYSDYYLK7AQC
3HGELZU7NELOQ635HZO6IJIYLBSNCJ5VPH46IE22KA3OSLEFK7AQC
W6JMQP26KNVIZOJTITBWR447OX63DUKBIQE442Q7QYLUUKJVBELAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
D7SLVLRNCYCBDYYRANHDG3JYEF25CFCSUY5FMF5KXVD5D4UZSDDAC
QBDE22XS3EO2TD7K6MOEMOUDISHZAGKCVW23Y62NXII7HNEKCJ6QC
AV3TMWHWB3XBXQCT34UPMZBSIIKVXIGWQPNEFU4CZSBS3ZOF2CUQC
P5TRGRH7XMQSPCZKM5IEEO34TY6WMLGHHX7BU6Y453JFRXLUR2VQC
SXUKGEXMGRRN6UO2GJW4HSVU5TSUNUHIHBMMF7CAG7QMLKZYWTKQC
YPD42V7VOQFGAVLLOSQAQ4SD77L5L3LZHPLFVZIAOHBNDKPO3O4QC
WQIEW3O4MANA2KKYRUWEZP44KHVJ4RRHEZTDXSF4EDELX66LO26QC
VQD5BW56OTUNPILMCASXZ6YZ3OQGXKQ7CSNDMNZUX72AQZXKOE3QC
3RNRFLMD2X4RUFTDVITLXAP377YB6F6YMQLL3DAXSUZDZBTWSLRQC
IBCGW7GAP7MBB4EQ5Q6B6GAOUIYG3O7NLU2LCK37E7ZSDMTAAYZQC
PKHOZG6TIUP2NZZIP6CW5OIPZ3O6PCGWXXW5MH4I6P2WVM24HZEQC
FLDIOEND63BONSOAIZ7WYAVNQLJ35O3VFY3PTVRWWYOJL4JXREHAC
OPNCHI4UGN7WBIYPAXVV2C4N22ZSWROA435FJCY5UZVXKWRYQ42QC
F6AE3G4DNTPXKCQXKQDLVCOU5PUMU22R53J3HGM7KH7753HUTKBAC
LOEVXFCKSHE3TCQSUSHOIHHVDJT3RFLE6U3VDI6JXAQTQI5KCJ4AC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
if (old_behaviour == BEH_LURK && !mons_is_lurking(mon))
{
switch(event)
{
case ME_EVAL:
case ME_DISTURB:
case ME_ALERT:
// Lurking monsters won't stop lurking just because they
// noticed something.
mon->behaviour = BEH_LURK;
break;
const bool wasLurking =
(old_behaviour == BEH_LURK && !mons_is_lurking(mon));
const bool wasLeaving =
(old_behaviour == BEH_LEAVE && !mons_is_leaving(mon));
default:
if (mon->has_ench(ENCH_SUBMERGED)
&& !mon->del_ench(ENCH_SUBMERGED))
{
// Lurking monsters that can't unsubmerge keep lurking.
mon->behaviour = BEH_LURK;
}
break;
}
if ((wasLurking || wasLeaving)
&& (event == ME_DISTURB || event == ME_ALERT || event == ME_EVAL))
{
// Lurking monsters or monsters leaving the level won't stop
// doing so just because they noticed something.
mon->behaviour = old_behaviour;
case BEH_LEAVE:
// If the monster can't move at all (or even teleport, as a
// mimic would), it obviously can't leave, so get out.
if (mons_is_truly_stationary(mon))
break;
// If the monster can submerge where it is, make it do so
// and leave the level.
if (monster_can_submerge(mon, grd(mon->pos())))
{
mon->add_ench(ENCH_SUBMERGED);
_make_mons_leave_level(mon);
return;
}
// Greatly lowered chances if the monster is fleeing.
if (mons_is_fleeing(monster) && !one_chance_in(8))
// Greatly lowered chances if the monster is fleeing or leaving the
// level.
if ((mons_is_fleeing(monster) || mons_is_leaving(monster))
&& !one_chance_in(8))
{