many FRs on Sourceforge.
When standing at the end of a corridor, monsters of animal intelligence or higher may swarm out to semi-surround you rather than block the entrance for all monsters behind them.
Example:
####. .rgo@ ####.
will now within two turns change to
which is obviously much smarter. The same logic applies to friendly monsters who presumably form a semicircle around you to protect you.
Also, hostile monsters will even move out of the way if the next monster farther down the corridor has a ranged attack (think centaurs).
This does not yet work for diagonals (but I'm working on that one), and also does not handle monsters stepping out of a corridor to surround non-allied monsters (though this should be easy enough to add).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7445 c06c8d41-db1a-0410-9941-cceddc491573
IA6EPF5ZQE6276Q4JSUKBSXHX5ODRY5I5UK7LXH4MQEDG36P6PZAC SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC 3OFG2YD2UOHC6UA7H7LWKOWCNFFSTDOXAA6L3KC335OF5RV3YOYQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC DK362IHKSDADMUPD35NOTKM4WESQM37KG2PNOJRV2FGELDWULYPQC 247OW5JFN34ZV3GRVHRE25AXLLISUBPOX5YRGUE64BCM2V7QNEHAC PM65H4V4GNPVIJFUQW57DC3VDB7TRUUNXKVZONQKEFZSK3AXX5GQC }}static bool _allied_monster_at(monsters *mon, coord_def a, coord_def b,coord_def c){std::vector<coord_def> pos;pos.push_back(mon->pos() + a);pos.push_back(mon->pos() + b);pos.push_back(mon->pos() + c);for (unsigned int i = 0; i < pos.size(); i++){if (!in_bounds(pos[i]))continue;if (mgrd(pos[i]) == NON_MONSTER)continue;if (mons_is_stationary(&menv[mgrd(pos[i])]))return (false);if (mons_aligned(monster_index(mon), mgrd(pos[i])))return (true);}return (false);}static bool _ranged_allied_monster_in_dir(monsters *mon, coord_def p){coord_def pos = mon->pos();for (int i = 1; i <= LOS_RADIUS; i++){pos += p;if (!in_bounds(pos))break;if (mgrd(pos) == NON_MONSTER)continue;if (mons_aligned(monster_index(mon), mgrd(pos))){monsters *m = &menv[mgrd(pos)];if (mons_has_ranged_attack(m) || mons_has_ranged_spell(m))return (true);}break;
}const coord_def newpos(monster->pos() + mmov);FixedArray < bool, 3, 3 > good_move;for (int count_x = 0; count_x < 3; count_x++)for (int count_y = 0; count_y < 3; count_y++){const int targ_x = monster->pos().x + count_x - 1;const int targ_y = monster->pos().y + count_y - 1;// Bounds check - don't consider moving out of grid!if (!in_bounds(targ_x, targ_y)){good_move[count_x][count_y] = false;continue;}good_move[count_x][count_y] =_mon_can_move_to_pos(monster, coord_def(count_x-1, count_y-1));}// The monster is moving in your direction, to attack or protect you.if (newpos == you.pos() && mons_intel(monster) >= I_ANIMAL&& !mons_is_confused(monster) && !mons_is_caught(monster)&& !monster->has_ench(ENCH_BERSERK)){if (mmov.y == 0){if (!good_move[1][0] && !good_move[1][2]&& (good_move[mmov.x+1][0] || good_move[mmov.x+1][2])&& (_allied_monster_at(monster, coord_def(-mmov.x, -1),coord_def(-mmov.x, 0),coord_def(-mmov.x, 1))|| mons_intel(monster) >= I_NORMAL&& !mons_wont_attack(monster)&& _ranged_allied_monster_in_dir(monster,coord_def(-mmov.x, 0)))){if (good_move[mmov.x+1][0])mmov.y = -1;if (good_move[mmov.x+1][2] && (mmov.y == 0 || coinflip()))mmov.y = 1;}}else if (mmov.x == 0){if (!good_move[0][1] && !good_move[2][1]&& (good_move[0][mmov.y+1] || good_move[2][mmov.y+1])&& (_allied_monster_at(monster, coord_def(-1, -mmov.y),coord_def(0, -mmov.y),coord_def(1, -mmov.y))|| mons_intel(monster) >= I_NORMAL&& !mons_wont_attack(monster)&& _ranged_allied_monster_in_dir(monster,coord_def(0, -mmov.y)))){if (good_move[0][mmov.y+1])mmov.x = -1;if (good_move[2][mmov.y+1] && (mmov.x == 0 || coinflip()))mmov.x = 1;}}