overboard here :) - but I figured that it could be useful to occasionally explain why I implemented something a certain way.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5767 c06c8d41-db1a-0410-9941-cceddc491573
5FMXUX2ZFIF6NQZCS54W7ZOCVSH7XR6UIMQ5FW2UZLEN4EWP5PSAC
DWSABP6YFM2CCMO7NVGGBWVCPAXOXOT5VQ6SADR4M66LHW66AP6QC
EHP6PYCIPYQ3KF4JFGBTZXEUQHN3FVAH4NUWEOWDDNKGPYVOTOJQC
JI4NDSOXGGZ7QHXXFB3ZTHAKHABXYBZXPDGLUFV5SKYEOL5FT7JQC
JEWRZ3AI42QDS32KLPVYQZIXLS3GYOOU64IR4IPPKZNF4JYUL7TAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
RC6L3CIBLJEH4GWRFD7UQNGI6PZT74FRUVOYHSAN2XCC74NZUASQC
SCWXQW5H65OXUP2MEJ2MEEAVPSRJDT3RQGKYCMKVTORS2334PQSQC
OYTCBRC7LE44EUVRZVYTOOVKQWJ6P6YE3FXTOGUTNKEMLNWPHKSQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
WXZQJUZXMYS7R6ORNB7DWE5KEUXT262GXWMRPOJYYB4I3BFGYLLAC
KC4WE63EQMVI6QBPDO3EAEPMFLAOS7H5WUAFL7JPRIE3V7CR333AC
HW7XKO7HRAUQVDVVKG5GA7PYAEL5J5GKVDPT2CKAD3FLERAY5HLAC
FS4MVTH4EEEECLEAO2FTNK5CLF2PHFYO2JZHC2YEOKYLWXRDRU6AC
JW2KRJHES33W7UTWZ6NDO4TLMK4EFU4HKZXBWR2UJOMPCCOTR4CQC
CJ6OSJQPAZOGWC56OYBALICSITGVUEQERE7LWIYJL2AXWRZE523AC
X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC
RCPQNIRPR3NQXEMVLBAQW6657UJFIP43N54UJVEZHJH22OH4UQIQC
LJK4ZQATLSB4MKZG3ARZX5V6RFGTN3NLCN6GTCUGJQKU26SOXMUAC
VXSORUQOM2VZA4CAZDC6KPAY373NQIN3UT7CXQXTRCYXO2WM62DAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
LH4OYDEWEON5QNUCM74R7MNBJDP7O4XRETY74ZMYSXUXYQV427PAC
P5TRGRH7XMQSPCZKM5IEEO34TY6WMLGHHX7BU6Y453JFRXLUR2VQC
SXUKGEXMGRRN6UO2GJW4HSVU5TSUNUHIHBMMF7CAG7QMLKZYWTKQC
EMOBSWJHHB4V6WVMZL7JCF2V3KZN454Z6NS346OKFPMBNO24EJDQC
22ORIULMB2NHLFZNJFK2AF275Q6XBKOBE4ZRMOADY64VK5FAUUSQC
Y4NA3JSN63RLATF4NNBPSR5CWF5Z7UEMWCGVX4B6NOAR47CGM4GQC
NPTVMSNYWIALN2GSKESU6NKX7XNG7QDH2TNIWUB6R6NHCLK32NFAC
DMG73XDQHY2X2PHKWIY56XKD3O4NPGZKKIO6GX3IV2LLRVXPGKYQC
32PXX2XJVV7YSLLYNAVS7RYKYRAOQ565TZMTITSEPSSXOYPB5M2AC
D7SLVLRNCYCBDYYRANHDG3JYEF25CFCSUY5FMF5KXVD5D4UZSDDAC
DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC
DLVXY6DBP65B3RGWW4PNBEBPBNHNM3LSRYD36F3XDARFY7SPSJYAC
5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC
GBUB77EAYHOFY6GQ5IY3ZSBC7FSQFZZKYNBD5QMCQFIKFLYLWHOQC
KAOE5HB3THUKVGFZRO5EZESHEB3Q34WUO5DFMLWIKOBF47LZTIYAC
KBBSDMAXAGEDFMIVL6BSPMMSOBZKWPJTFCLBGCHRLE5DGTVAACSAC
DUBEHQIQABGLXLFIVZ6WXBMFGLFKFRBOCK5LZ6ECUSRM3V2V35NAC
FLAGBNUNSIQNFDN53CDWABJRTTFWDL4PG34AI474ZKPXDEPYHOAQC
// Set the seed point
// Set the seed point.
// For each round, circumference will store all points that were discovered
// in the previous round of a given distance. We use an array of size 2,
// so we can comfortably switch between the list of points to be
// investigated this round and the slowly growing list of points to be
// inspected next round. Once we've finished with the current round, i.e.
// there are no more points to be looked at in the current array, we switch
// circ_index over to !circ_index (between 0 and 1), so the "next round"
// becomes the current one, and the old points can be overwritten with
// newer ones. Since we count the number of points for next round in
// next_iter_points, we don't even need to reset the array.
if ((you.num_gifts[GOD_NEMELEX_XOBEH] == 0
&& random2(piety_breakpoint(1)) < you.piety) ||
(random2(MAX_PIETY) <= you.piety
&& one_chance_in(3)
&& !you.attribute[ATTR_CARD_COUNTDOWN]))
if (you.num_gifts[GOD_NEMELEX_XOBEH] == 0
&& random2(piety_breakpoint(1)) < you.piety
|| random2(MAX_PIETY) <= you.piety && one_chance_in(3)
&& !you.attribute[ATTR_CARD_COUNTDOWN])
// Just because we can *see* the player, that doesn't mean
// we can actually get there. To find about that, we first
// check for transparent walls. If there are transparent
// walls in the way we'll need pathfinding, no matter what.
// (Though monsters with a los attack don't need to get any
// closer to hurt the player.)
// If no walls are detected, there could still be a river
// or a pool of lava in the way. So we check whether there
// is water or lava in LoS (boolean) and if so, try to find
// a way around it. It's possible that the player can see
// lava but it actually has no influence on the monster's
// movement (because it's lying in the opposite direction)
// but if so, we'll find that out during path finding.
// In another attempt of optimization, don't bother with
// path finding if the monster in question has no trouble
// travelling through water or flying across lava.
// Also, if no path is found (too far away, perhaps) set a
// flag, so we don't directly calculate the whole thing again
// next turn, and even extend that flag to neighbouring
// monsters of similar movement restrictions.
// Ideally, smart monsters should be able to use
// pathfinding to find the way back, and animals
// could decide to stop patrolling if the path
// was too long.
// Other than for tracking the player, there's
// currently no distinction between smart and
// stupid monsters when it comes to travelling
// back to the patrol point. This is in part due
// to the flavourness of bees finding their way
// back to the Hive (patrolling should really be
// restricted to cases like this), and for the
// other part it's not that important because
// we calculate the path once and then follow it
// home, and the player won't ever see the
// orderly fashion the bees will trudge along.
// What he will see is them swarming back to the
// Hive entrance after some time, and that is what
// matters.
// The pathfinding is an implementation of the A* algorithm. Beginning at the
// destination square we check all neighbours of a given grid, estimate the
// distance needed for any shortest path including this grid and push the
// result into a hash. We can then easily access all points with the shortest
// distance estimates and then check _their_ neighbours and so on.
// The algorithm terminates once we reach the monster position since - because
// of the sorting of grids by shortest distance in the hash - there can be no
// path between start and target that is shorter than the current one. There
// could be other paths that have the same length but that has no real impact.
// If the hash has been cleared and the start grid has not been encountered,
// then there's no path that matches the requirements fed into monster_pathfind.
// (These requirements are usually preference of habitat of a specific monster
// or a limit of the distance between start and any grid on the path.)
// zigzagging should be avoided. This means directions are looked at, in
// order: 1, 3, 5, 7, 0, 2, 4, 6. (dir = 0) is an intentional assignment.
// zigzagging can be significantly reduced.
//
// 1 0 2 This means directions are looked at, in order,
// \ | / 1, 3, 5, 7 (diagonals) followed by 0, 2, 4, 6
// 7--.--3 (orthogonals). This is achieved by the assignment
// / | \ of (dir = 0) once dir has passed 7.
// 6 5 4
//
// to reach the target.
// to reach the target. Waypoints are chosen such that from one waypoint you
// can only just see the next one. Note that grid_see_grid() is probably
// rather too conservative in these estimates.
// This is done because Crawl's path finding once a target can be seen is
// very robust and because it allows for more natural traversing if there are
// other monsters in the way.
// Only tested for shallow water since they can't enter deep water anywa.
// (The resulting path might not be optimal but it will lead to a path
// a monster of such habits is likely to prefer.)
// Only tested for shallow water since they can't enter deep water anyway.
// Petrification works in two stages. First the monster is slowed down in
// all of its actions and cannot move away (petrifying), and when that times
// out it remains properly petrified (no movement or actions). The second
// part is similar to paralysis, except that insubstantial monsters can't be
// affected and that stabbing damage is drastically reduced.
bool curare_hits_monster( const bolt &beam,
monsters *monster,
kill_category who,
int levels )
bool curare_hits_monster( const bolt &beam, monsters *monster,
kill_category who, int levels )