or lava. I've added some more checks to avoid hampering performance too much, but of course there's still space for improvement.
Once per turn check whether the player can see water and/or lava, and only if this is the case run the additional checks (monster habitat, grid_see_grid) when a monster tries to move. Smart monsters that have a ranged attack won't use pathfinding either since they can directly fire at the player. (This is identical to their pre-pathfinding behaviour.)
Also fix butterflies really not interrupting resting. (Setting it to 0 doesn't work for some reason.)
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5737 c06c8d41-db1a-0410-9941-cceddc491573
EHP6PYCIPYQ3KF4JFGBTZXEUQHN3FVAH4NUWEOWDDNKGPYVOTOJQC
TMH66BDPTYSCUYFICAYUKLBQNHA7J3Q7DHKW33ZWKWG7YGE5DM4AC
32PXX2XJVV7YSLLYNAVS7RYKYRAOQ565TZMTITSEPSSXOYPB5M2AC
SXUKGEXMGRRN6UO2GJW4HSVU5TSUNUHIHBMMF7CAG7QMLKZYWTKQC
GHP3H4FU6XZTSZ7IWNOT5Z34GJL3BFRMARHPXXW5MJUQ4SOZ7ATQC
2O3C3MTT2ZBYIFGPJ4MF5R4AXBYUHOEN62KAUWFWF6JWHIIVLRNQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
ZJLJGSB2XSBQU42OFQMXL3EG4CXAQGOYAU6YTV2SAWZEJIPFH2CAC
NVSFIV2ZKP44XHCSCXG6OZVGL67OIFINC34J2EMKTA4KULCERUEAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC
PR2XIEELO6UJWT3EXDHWCJZGIZCCF3D6KF6LC67R6RWWAVNWEHWAC
LH4OYDEWEON5QNUCM74R7MNBJDP7O4XRETY74ZMYSXUXYQV427PAC
P5TRGRH7XMQSPCZKM5IEEO34TY6WMLGHHX7BU6Y453JFRXLUR2VQC
DK362IHKSDADMUPD35NOTKM4WESQM37KG2PNOJRV2FGELDWULYPQC
PM65H4V4GNPVIJFUQW57DC3VDB7TRUUNXKVZONQKEFZSK3AXX5GQC
XIDD2TZUOXG6DAMK7OQU5MUKVIEHQWJIJL5BVOTCVY33EPWJNX4QC
LFBNFE3PZBXTR2ROPKYPARUWLJAYWAKGTS7VBWADZWVVSJ5CLX6AC
IJNXE4Z7S7X3NG26GFV6UNZVEQ6HPXAKSCNPJEKU5DUQUDYJ34KAC
IAQLRRSOXHIU4XQNOFK5F6IUXCMMXSHDDETNYWFPV7YNWPIRIUOQC
KAOE5HB3THUKVGFZRO5EZESHEB3Q34WUO5DFMLWIKOBF47LZTIYAC
RBAGQ2PB7V5YAM5KSHSZR2E3MLKDSRVM5XYGI2TIXP5QMVBOQHDQC
ZNGET7722J4PJXQM7IISUIIUFGB6D7WBD4IXR4QQENHERHXOG7KQC
LTX72QGIPNUGWQN5ULPOMFCOPZTK7472DQY4AYX5WM3WHSUVXI5QC
FSD7GIK3YLZXWLEH37BU6KV3IUCFGXPQL6IZ7H65YWNRBEKDBX5AC
3HGELZU7NELOQ635HZO6IJIYLBSNCJ5VPH46IE22KA3OSLEFK7AQC
JESCEQPAFC23D6BUZMBOB4M54XT3GQZJYT7NCJ556LEUCHRER3SQC
WUWTYSQ2Z7HI637WNO2J55LW6WLPBDF2ILH622T47ICW3AN7OWMQC
OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC
NNG27Y5ZQAZX6UD7F7M4F6KEZBEDFXPEEC3LFUSX4ESKT7K6UJQAC
WMHFDQKUDCUGM3R245LLVZ5NNEZSCXFDSTNMVS2O5EFUHHO7HU3AC
CG4TL4AKSN4J7CMATZFJ5N7PSDCQXLS3QYX7PZ3K67KMMBT675OQC
SQDS2YBPOYDDDCW3GGARBZ2HQIUHCQKL7SSHKFQWDENOL5YNNVNQC
DMG73XDQHY2X2PHKWIY56XKD3O4NPGZKKIO6GX3IV2LLRVXPGKYQC
R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC
BD5ZPI4AQYR4SHYGKH4FJ6XNNCGSSEXESF2HMD5WN4GJAJXAMGGAC
BR4UJTJEP76VHWKMNCRIQAIBHH4XWRNTXYQU4POSNLMSND65MMHAC
547JREUJXTZNYVGHNNAET5F5O5JYYGNTDQB6ABZNT7YX5EY64OHAC
SSQP7MS6LZYY73QEF66EYNNQJJSB6TVLLWXLWL7JJAYBLXCEY2XAC
CAHE52HL2ZGRJPBYZ3DS4BVKUD2XC7N3SG25TGG7JGHGJDST4P3QC
3QVLDVR6DWYKU26UGOXBTVGA4FUNB3BI56EORGT4C2RHNQOVV5WQC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
TRZAZJJA5VQBJ65SO5H5DNSILIZEJHIZCBYEBHEATCT6ZSMWIFKQC
4TPFZIL52CS4HPO5LQMKS3PHTE2X2C547ULEFXKM4UIQQ64FUBGAC
3YBQGKQ22WFXA5RXDSKLFWMABLJ6KHBVWEIA3WIDHWM25OECNTYAC
JM7UAK777RAVDAVLQLEOBRTGNW2B47S5G55XITJXO243IUNZHVYQC
UEI5JAVCMN7Y2SACTEZPZSNFJWOJTC55G24Q6LKQCT4XNDH5ZQIAC
QRD2M37AMG76CPGCALZQ3N2PZ3OZ3MFETMVAEHBJJVVH2BCPVGUAC
OFH2B2UZBK43QLFQBZ54FOCFLFNE54BZVDNCEUGDTBCUGNVZULIQC
FZKMVCODMWQEVVBBQHTTXFBRO4LZEYLB646ZPVUMLHH6EER7FAOAC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
VIHJ3Z75JN7BXWNOPWV3CWQZEA7K5DK36EKHCYMZC7SOSJYH2XHQC
P25D567E2UEAQHNI7LAZPNY7KAI3J4OE77YKLWOIEEALC5RREJHAC
SGR2P5BGJIJHVSSQYQHWS4ORLVHQBZTDES3D4BFC6SVAQXSKENNQC
43ZTEB57FU7KE5EVMYWZONNVJBZCGF3JEAJZIY25LC4LGE65PG5QC
BIZDHHK5LIO57S5AKHEPJFLWV5DAFKZIKYBGOUNGICSWTX7DCXKAC
YL67KHG3TAZXJCWGRZPVASD6RS2SQ3V5KMIUK4E6PV43V2NBOLEAC
TDAVD56MGLFSMJLPLSYLEVW7MBRMT7V5BNII4TRWVDIHH47CD2OAC
// will still be able to come nearer (and the mark will be cleared).
static void _mark_species_members_player_unreachable(monsters *mon)
// will still be able to come nearer (and the mark will then be cleared).
static void _mark_neighbours_player_unreachable(monsters *mon)
// Highly intelligent monsters are capable of pathfinding and don't
// need their neighbour's advice.
if (mons_intel(mon->type) > I_NORMAL)
// Highly intelligent monsters are perfectly capable of pathfinding
// and don't need their neighbour's advice.
const int intel = mons_intel(mon->type);
if (intel > I_NORMAL)
// We won't be able to find pack members of human unique monsters.
if (mons_is_unique(mon->type) && mons_species(mon->type) == MONS_HUMAN)
return;
bool flies = mons_flies(mon);
bool amphibious = mons_amphibious(mon);
habitat_type habit = mons_habitat(mon);
// Only mark target for monsters of same species.
// Restrict to same _type_ for humans (by far the most
// versatile species).
if (mon->type != m->type
&& (mon->type == MONS_HUMAN
|| mons_species(mon->type) != mons_species(m->type)))
{
// Don't restrict smarter monsters as they might find a path
// a dumber monster wouldn't.
if (mons_intel(m->type) > intel)
dungeon_feature_type can_move;
if (mons_amphibious(mons_is_zombified(mon) ?
mon->base_monster : mon->type))
{
can_move = DNGN_DEEP_WATER;
}
else
can_move = DNGN_SHALLOW_WATER;
const dungeon_feature_type can_move =
(mons_amphibious(mon)) ? DNGN_DEEP_WATER : DNGN_SHALLOW_WATER;
if (proxPlayer && !trans_wall_block)
bool potentially_blocking = trans_wall_block;
// Smart monsters that can fire through walls won't use
// pathfinding.
if (potentially_blocking && mons_intel(mon->type) >= I_NORMAL
&& mons_has_los_ability(mon->type))
{
potentially_blocking = false;
}
else
{
// Flying monsters don't see water/lava as obstacle.
// Also don't use pathfinding if the monster can shoot
// across the blocking terrain, and is smart enough to
// realize that.
if (!potentially_blocking && !mons_flies(mon)
&& (mons_intel(mon->type) < I_NORMAL
|| !mons_has_ranged_spell(mon)
&& !mons_has_ranged_attack(mon)))
{
const habitat_type habit = mons_habitat(mon);
if (you.lava_in_sight && habit != HT_LAVA
|| you.water_in_sight && habit != HT_WATER
&& !mons_amphibious(mon))
{
potentially_blocking = true;
}
}
}
if (!potentially_blocking
|| grid_see_grid(mon->x, mon->y, you.x_pos, you.y_pos,
can_move))
skill_type sage_bonus_skill; // if Sage is in effect, which skill it affects
int sage_bonus_degree; // how much bonus XP to give in that skill
skill_type sage_bonus_skill; // If Sage is in effect, which skill it affects.
int sage_bonus_degree; // How much bonus XP to give in that skill.
}
static void _check_lava_water_in_sight()
{
// Check the player's vision for lava or deep water,
// to avoid unnecessary pathfinding later.
you.lava_in_sight = you.water_in_sight = false;
coord_def gp;
for (gp.y = (you.y_pos - 8); (gp.y <= you.y_pos + 8); gp.y++)
for (gp.x = (you.x_pos - 8); (gp.x <= you.x_pos + 8); gp.x++)
{
if (!in_bounds(gp))
continue;
const coord_def ep = gp - you.pos() + coord_def(9, 9);
if (env.show(ep))
{
dungeon_feature_type feat = grd[gp.x][gp.y];
if (feat == DNGN_LAVA)
you.lava_in_sight = true;
else if (feat == DNGN_DEEP_WATER)
you.water_in_sight = true;
if (you.lava_in_sight && you.water_in_sight)
break;
}
}