Fixed patrol definitions in maps not actually working.
Tested both by teleporting the minotaur in a labyrinth. About 50 turns later it arrived back in its lair. :)
Since the minotaur proved to have a high magic resistance, it had plenty of time to loot the stash at the labyrinth entrance once I'd woken it before I finally managed to teleport it away (in wizmode you can force monsters not noticing you).
This resulted in "A minotaur, wielding the demon trident "Suyn Oma", and wearing a heavily runed ring mail." o_O
It had also picked up a scroll and a wand. Ouch… (but cool!)
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5536 c06c8d41-db1a-0410-9941-cceddc491573
EMOBSWJHHB4V6WVMZL7JCF2V3KZN454Z6NS346OKFPMBNO24EJDQC
5O2SHPEXAOCAWI7URLQ674UP2ZUSNUJ3NYY5KQGWBJI26TZFMXLAC
22ORIULMB2NHLFZNJFK2AF275Q6XBKOBE4ZRMOADY64VK5FAUUSQC
DMG73XDQHY2X2PHKWIY56XKD3O4NPGZKKIO6GX3IV2LLRVXPGKYQC
YF2GZWXNV6NVFFEBEOYS67JQJQK2IUS5BZMGJW3XQPYIJYHQJCEQC
AM7QPHDAWNXHLUEVUHVRHG2RO2DOIEFFU4GV3DCIROW6O5HW7H4AC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
JGKYRZ34S3I23PMJX6IUBR7EHEFD6I4XXEGXNT7GKT2M2VIRBSMQC
GPEJOT73KMACP33IPAKFR5ROGHCOIP22VXZMQNYTGLEA2OSZUM2AC
WQLOHSNCA3VOMDJF6IINJYKSYVYZEBPJJWBB33QSNE4RP5HEXPMAC
P5TRGRH7XMQSPCZKM5IEEO34TY6WMLGHHX7BU6Y453JFRXLUR2VQC
7KWDC7XFNMBLSUO2HISIROBINZBX5T67LJEEXTAORXW2YZ7VWFGAC
PSCYVKJ7DGXAL3V5U4O6AJTRV6Q3N3SHQWAZ73VIPRTE4W64F2XAC
NLQNXH3SVJ52CWXEV35FSSZP32VHC4QFGN3HINF4KO5GZHZMOBKQC
F7QFSXE22UPQTBLYJLY26HJ3QPHFNBJMUOFJRV35R5YCHSGKTBYQC
X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
LFBNFE3PZBXTR2ROPKYPARUWLJAYWAKGTS7VBWADZWVVSJ5CLX6AC
LTX72QGIPNUGWQN5ULPOMFCOPZTK7472DQY4AYX5WM3WHSUVXI5QC
Y4NA3JSN63RLATF4NNBPSR5CWF5Z7UEMWCGVX4B6NOAR47CGM4GQC
7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC
QS3ZRS3E6KL3YJHPKYEWCWJYRBJSXD5OOYF6Y25HZVECGPJRDB5QC
ASLW3Z5PAVZSWJEMMMVZT226P44EKSAD47QS72JIFJESAI3RPN3AC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
53K44NBML2QHWLZNXU5HBY2MOIXRK7ZGFQYAWZFO663TCOJKVHZAC
H3552BCIAVBLKAYKE4DHFLBLFW5RGRMYBMRRYHYEB5IPIJRUVU5QC
32B6H524I6YHMCVYFWZPHP32R4BURWJHMFGLYAEWADGI45B27ZUQC
ZRJSOM6JBS4EBKBNK4UZZ74KNMLDP7N6EWMDH2NF5GSBXXPEW3SQC
VU634ZCADYXGKUDW2HMWXQBGKECM6E6SXTSCW5SCWMZBX3PM3V3QC
ZWYVZW5QFM5I2F6BLMNDDTV7FROJUHOO3O2BCBG7WSCKMKXUEMTQC
PT2CGTJ35VAS2NPZP6C4WVYFLPXBFBVGH4BYETSLQLOWI3WM6SHAC
TAG_MINOR_PIETY = 2, // Added piety_hysteresis
TAG_MINOR_QUIVER = 3, // Added quiver
TAG_MINOR_MAPMARK = 4, // Added sizes to map markers
TAG_MINOR_MONNAM = 5, // Monsters get individual names
TAG_MINOR_MONBASE = 6, // Zombie base monster gets its own field.
TAG_MINOR_FPICKUP = 7, // Added pickup option for allied monsters.
TAG_MINOR_MPATROL = 8, // Added monster patrol points.
TAG_MINOR_VERSION = 8 // Current version
TAG_MINOR_PIETY = 2, // Added piety_hysteresis
TAG_MINOR_QUIVER = 3, // Added quiver
TAG_MINOR_MAPMARK = 4, // Added sizes to map markers
TAG_MINOR_MONNAM = 5, // Monsters get individual names
TAG_MINOR_MONBASE = 6, // Zombie base monster gets its own field.
TAG_MINOR_FPICKUP = 7, // Added pickup option for allied monsters.
TAG_MINOR_MPATROL = 8, // Added monster patrol points.
TAG_MINOR_PATHFIND = 9, // Added monster pathfinding.
TAG_MINOR_VERSION = 9 // Current version
if (patrolling)
bool need_target = true;
if (travelling)
{
#ifdef DEBUG_PATHFIND
mprf("Monster %s reached target (%d, %d)",
mon->name(DESC_PLAIN).c_str(),
mon->target_x, mon->target_y);
#endif
need_target = false;
if (mon->x == mon->travel_path[0].x
&& mon->y == mon->travel_path[0].y)
{
// Hey, we reached our first waypoint!
mon->travel_path.erase( mon->travel_path.begin() );
if (mon->travel_path.empty())
need_target = true;
mon->target_x = mon->travel_path[0].x;
mon->target_y = mon->travel_path[0].y;
#ifdef DEBUG_PATHFIND
mprf("Next waypoint: (%d, %d)",
mon->target_x, mon->target_y);
#endif
}
else
{
// Apparently we got sidetracked a bit.
// Check the waypoints vector backwards and pick the
// first waypoint we can see.
// XXX: Note that this might still not be the best
// thing to do since another path might be even
// *closer* to our actual target now.
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;
int erase = -1; // Erase how many waypoints?
for (unsigned int i = mon->travel_path.size() - 1;
i >= 0; i--)
{
if (grid_see_grid(mon->x, mon->y,
mon->travel_path[i].x,
mon->travel_path[i].y, can_move))
{
mon->target_x = mon->travel_path[i].x;
mon->target_y = mon->travel_path[i].y;
erase = i;
break;
}
}
if (erase != -1)
{
// Erase all waypoints that came earlier:
// we don't need them anymore.
while (0 < erase--)
{
mon->travel_path.erase(
mon->travel_path.begin() );
}
}
else
{
// We can't reach our old path from our current
// position, so calculate a new path instead.
monster_pathfind mp;
if (mp.start_pathfind(mon, mon->patrol_point, true))
{
mon->travel_path = mp.calc_waypoints();
if (!mon->travel_path.empty())
{
mon->target_x = mon->travel_path[0].x;
mon->target_y = mon->travel_path[0].y;
}
}
else
{
mon->travel_path.clear();
need_target = true;
}
}
}
}
if (need_target && patrolling)
mon->target_x = mon->patrol_point.x;
mon->target_y = mon->patrol_point.y;
monster_pathfind mp;
if (mp.start_pathfind(mon, mon->patrol_point, true))
{
mon->travel_path = mp.calc_waypoints();
if (!mon->travel_path.empty())
{
mon->target_x = mon->travel_path[0].x;
mon->target_y = mon->travel_path[0].y;
}
}
else
{
// Stop patrolling.
mon->patrol_point = coord_def(0, 0);
}
target_x(0), target_y(0), patrol_point(0, 0), inv(NON_ITEM), spells(),
attitude(ATT_HOSTILE), behaviour(BEH_WANDER), foe(MHITYOU),
enchantments(), flags(0L), experience(0), number(0), colour(BLACK),
foe_memory(0), shield_blocks(0), god(GOD_NO_GOD), ghost(),
target_x(0), target_y(0), patrol_point(0, 0),
inv(NON_ITEM), spells(), attitude(ATT_HOSTILE), behaviour(BEH_WANDER),
foe(MHITYOU), enchantments(), flags(0L), experience(0), number(0),
colour(BLACK), foe_memory(0), shield_blocks(0), god(GOD_NO_GOD), ghost(),
int max_cluster = 7 + random2(9);
// startprob is used to initialize the chance for neighbours being
// spattered, which will be decreased by 1 per recursion round.
// We then use one_chance_in(chance) to determine whether to spatter a
// given grid or not. Thus, startprob = 1 means that initially all
// surrounding grids will be spattered (3x3), and the _higher_ startprob
// the _lower_ the overall chance for spattering and the _smaller_ the
// bloodshed area.
const int max_cluster = 7 + random2(9);
// Lower chances for large bloodshed areas if we have many clusters,
// but increase chances if we have few.
// Chances for startprob are [1..3] for 7-9 clusters,
// ... [1..4] for 10-12 clusters, and
// ... [2..5] for 13-15 clusters.
int min_prob = 1;
int max_prob = 4;
if (max_cluster < 10)
max_prob--;
else if (max_cluster > 12)
min_prob++;