player through the walls. Don't use pathfinding to target other monsters, only the player! Monsters of different intelligence have different limits on the distance they may travel to circumvent an obstacle, i.e. zombies will only use a range of 2, whereas highly intelligent monsters can expertly find their way through (transparent) labyrinths, though there's a chance they'll forget their target if they don't see it, so for very long and winding paths it's likely they don't ever arrive.
Will probably affect performance, though I did test on entire levels turned transparent with Vitrification and things seemed to run more or less smoothly.
Ideally, monsters should also be able to move around other obstacles that don't affect visibility (such as water, lava, or statues) but that is currently not possible.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5700 c06c8d41-db1a-0410-9941-cceddc491573
LH4OYDEWEON5QNUCM74R7MNBJDP7O4XRETY74ZMYSXUXYQV427PAC 3OFG2YD2UOHC6UA7H7LWKOWCNFFSTDOXAA6L3KC335OF5RV3YOYQC EMOBSWJHHB4V6WVMZL7JCF2V3KZN454Z6NS346OKFPMBNO24EJDQC Q5YUZONIIPGRWOIQNL6DHRGLKF4V3K5XSZCBH2SL7DP4WPLDNOSQC AM7QPHDAWNXHLUEVUHVRHG2RO2DOIEFFU4GV3DCIROW6O5HW7H4AC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC P5TRGRH7XMQSPCZKM5IEEO34TY6WMLGHHX7BU6Y453JFRXLUR2VQC PSCYVKJ7DGXAL3V5U4O6AJTRV6Q3N3SHQWAZ73VIPRTE4W64F2XAC PFEJ4LMDNEKLMGRCMWQ7EIRVU4JMYGICI4G7X4WVWOROVXQCBZ7QC LFBNFE3PZBXTR2ROPKYPARUWLJAYWAKGTS7VBWADZWVVSJ5CLX6AC LTX72QGIPNUGWQN5ULPOMFCOPZTK7472DQY4AYX5WM3WHSUVXI5QC 22ORIULMB2NHLFZNJFK2AF275Q6XBKOBE4ZRMOADY64VK5FAUUSQC Y4NA3JSN63RLATF4NNBPSR5CWF5Z7UEMWCGVX4B6NOAR47CGM4GQC 7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC WQLOHSNCA3VOMDJF6IINJYKSYVYZEBPJJWBB33QSNE4RP5HEXPMAC 4GYZYBY7FFORRNPIEFTV4ZM2C7Z6D2KTQOM537ZCC2YBXT2TNSHAC RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC TDAVD56MGLFSMJLPLSYLEVW7MBRMT7V5BNII4TRWVDIHH47CD2OAC TAG_MINOR_PIETY = 2, // Added piety_hysteresisTAG_MINOR_QUIVER = 3, // Added quiverTAG_MINOR_MAPMARK = 4, // Added sizes to map markersTAG_MINOR_MONNAM = 5, // Monsters get individual namesTAG_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
TAG_MINOR_PIETY = 2, // Added piety_hysteresisTAG_MINOR_QUIVER = 3, // Added quiverTAG_MINOR_MAPMARK = 4, // Added sizes to map markersTAG_MINOR_MONNAM = 5, // Monsters get individual namesTAG_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_TRTARGET = 10, // Added travel target.TAG_MINOR_VERSION = 10 // Current version
if (proxPlayer && !trans_wall_block){if (travelling && mon->travel_target != MTRAV_PATROL){mon->travel_path.clear();mon->travel_target = MTRAV_NONE;}}else if (proxPlayer && trans_wall_block&& (mon->travel_target != MTRAV_UNREACHABLE|| one_chance_in(8))){#ifdef DEBUG_PATHFINDmprf("%s: Player out of reach! What now?",mon->name(DESC_PLAIN).c_str());#endif// If we're already on our way, do nothing.if (travelling && mon->travel_target == MTRAV_PLAYER){#ifdef DEBUG_PATHFINDmpr("Already travelling...");#endifint len = mon->travel_path.size();coord_def targ = mon->travel_path[len - 1];if (grid_see_grid(targ.x, targ.y, you.x_pos, you.y_pos)&& !trans_wall_blocking(targ.x, targ.y)){#ifdef DEBUG_PATHFINDmpr("Target still valid...");#endif// Current target still valid?if (mon->x == mon->travel_path[0].x&& mon->y == mon->travel_path[0].y){// Get next waypoint.mon->travel_path.erase(mon->travel_path.begin() );if (!mon->travel_path.empty()){mon->target_x = mon->travel_path[0].x;mon->target_y = mon->travel_path[0].y;break;}}else if (grid_see_grid(mon->x, mon->y,mon->travel_path[0].x,mon->travel_path[0].y,can_move)){mon->target_x = mon->travel_path[0].x;mon->target_y = mon->travel_path[0].y;break;}}}// Use pathfinding to find a (new) path to the player.const int dist = grid_distance(mon->x, mon->y,you.x_pos, you.y_pos);#ifdef DEBUG_PATHFINDmprf("Need to calculate a path... (dist = %d)", dist);#endifconst bool native =mons_is_native_in_branch(mon, you.where_are_you);int range = 0;switch (mons_intel(mon->type)){case I_PLANT:range = 2;break;case I_INSECT:range = 3;break;case I_ANIMAL:range = 5;break;case I_NORMAL:range = 10;break;default:// Highly intelligent monsters can find their way// anywhere.range = 0;break;}if (range && native)range += 3;if (range > 0 && dist > range){mon->travel_target = MTRAV_UNREACHABLE;#ifdef DEBUG_PATHFINDmprf("Distance too great, don't attempt pathfinding! (%s)",mon->name(DESC_PLAIN).c_str());#endif}else{#ifdef DEBUG_PATHFINDmprf("Need a path for %s from (%d, %d) to (%d, %d), ""max. dist = %d",mon->name(DESC_PLAIN).c_str(), mon->x, mon->y,you.x_pos, you.y_pos, range);#endifmonster_pathfind mp;if (range > 0)mp.set_range(range);if (mp.start_pathfind(mon, coord_def(you.x_pos,you.y_pos))){mon->travel_path = mp.calc_waypoints();if (!mon->travel_path.empty()){// Okay then, we found a path. Let's use it!mon->target_x = mon->travel_path[0].x;mon->target_y = mon->travel_path[0].y;mon->travel_target = MTRAV_PLAYER;break;}else{#ifdef DEBUG_PATHFINDmpr("No path found!");#endifmon->travel_target = MTRAV_UNREACHABLE;}}else{#ifdef DEBUG_PATHFINDmpr("No path found!");#endifmon->travel_target = MTRAV_UNREACHABLE;}}}