git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2583 c06c8d41-db1a-0410-9941-cceddc491573
HAI4YDKI72OBDT5KMMVCO3DOU765OPWCU7GTRKTALFNSDOI4R2LAC HUHII5CFWHLFNOYQOKPQ6LUJSQ46OJHJMNISRWDJIBN4BMD4NAOAC PES2QAPAJTLHZORDXNJWKK4VWRDCGXMOVVFI2TQALCPB5JUPHCVQC I67HCZISOEMUYFEUA6VOJOO2L4TYK73IB4FSTY4CHDR7GZD6CS6QC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC XXBZEIEB6JTDFJC6V2VSDAV2KHDXZYQ245EMQBKOX3I7HTU2DMIAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC YCL3W2PFE6ILTGBFODCSXNPDIA46KVSZP2TI7HDMYAOEJT65RIEAC RSIUBEQUGNU4LO6KH4PKVROWQS33DAKSY4XFVGN7T3CEKSXABCSAC GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC YLWMDMNLJOERFAGH5RIFTRWLGCEOWAD4GIWUIXKYA7EE3EWHCVAQC SW3RLYFNRT3IJBK6LYKHKP2J2YDU7SXQWAJZX7U6S7ICYW43OMNQC Y4WR4EIOFFXHRQI2PJAZWD4MVL6A7MNBHLN4KOV6BIKGGA7FXQTQC E5DMZFW6WCFAKTKKOQPYTQXZ2CGLWMVH64LRXDUI2UIG4VYUHIVQC if (fmenv->type == MONS_PANDEMONIUM_DEMON|| fmenv->type == MONS_PLAYER_GHOST // cdl|| !fmenv->alive()|| mons_is_stationary(fmenv)|| fmenv->incapacitated()){continue;}
if (!monster_habitable_grid(fmenv, DNGN_FLOOR))return (false);
if (fmenv->speed_increment < 50)continue;
// only friendly monsters, or those actively seeking the// player, will follow up/down stairs.if (!(mons_friendly(fmenv) ||(fmenv->behaviour == BEH_SEEK && fmenv->foe == MHITYOU))){return (false);}
// only friendly monsters, or those actively seeking the// player, will follow up/down stairs.if (!(mons_friendly(fmenv) ||(fmenv->behaviour == BEH_SEEK && fmenv->foe == MHITYOU))){continue;}
// Monsters that are not directly adjacent are subject to more// stringent checks.if ((pos - you.pos()).abs() > 2){if (!mons_friendly(fmenv))return (false);
return (true);}static int follower_tag_radius2(){// If only friendlies are adjacent, we set a max radius of 6, otherwise// only adjacent friendlies may follow.coord_def p;for (p.x = you.x_pos - 1; p.x <= you.x_pos + 1; ++p.x)for (p.y = you.y_pos - 1; p.y <= you.y_pos + 1; ++p.y){if (p == you.pos())continue;if (const monsters *mon = monster_at(p)){if (!mons_friendly(mon))return (2);}
return (6 * 6);}void tag_followers(){const int radius2 = follower_tag_radius2();int n_followers = 18;std::vector<coord_def> places[2];int place_set = 0;places[place_set].push_back(you.pos());memset(travel_point_distance, 0, sizeof(travel_distance_grid_t));while (!places[place_set].empty()){for (int i = 0, size = places[place_set].size(); i < size; ++i){const coord_def &p = places[place_set][i];coord_def fp;for (fp.x = p.x - 1; fp.x <= p.x + 1; ++fp.x)for (fp.y = p.y - 1; fp.y <= p.y + 1; ++fp.y){if (fp == p || (fp - you.pos()).abs() > radius2|| !in_bounds(fp) || travel_point_distance[fp.x][fp.y]){continue;}travel_point_distance[fp.x][fp.y] = 1;if (tag_follower_at(fp)){// If we've run out of our follower allowance, bail.if (--n_followers <= 0)return;places[!place_set].push_back(fp);}}}places[place_set].clear();place_set = !place_set;
static bool grab_follower_at(const coord_def &pos){if (pos == you.pos())return (false);monsters *fmenv = monster_at(pos);if (!fmenv || !fmenv->alive())return (false);// monster has to be already tagged in order to follow:if (!testbits( fmenv->flags, MF_TAKING_STAIRS ))return (false);#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "%s is following to %s.",fmenv->name(DESC_CAP_THE, true).c_str(),level_id::current().describe().c_str());#endiffmenv->set_transit(level_id::current());fmenv->destroy_inventory();monster_cleanup(fmenv);return (true);}
if (!can_follow)
if (can_follow){memset(travel_point_distance, 0, sizeof(travel_distance_grid_t));std::vector<coord_def> places[2];int place_set = 0;places[place_set].push_back(you.pos());while (!places[place_set].empty()){for (int i = 0, size = places[place_set].size(); i < size; ++i)
// Monster can't follow us, so clear the follower flag.fmenv->flags &= ~MF_TAKING_STAIRS;continue;
const coord_def &p = places[place_set][i];coord_def fp;for (fp.x = p.x - 1; fp.x <= p.x + 1; ++fp.x)for (fp.y = p.y - 1; fp.y <= p.y + 1; ++fp.y){if (!in_bounds(fp) || travel_point_distance[fp.x][fp.y])continue;travel_point_distance[fp.x][fp.y] = 1;if (grab_follower_at(fp))places[!place_set].push_back(fp);}
#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "%s is following to %s.",fmenv->name(DESC_CAP_THE, true).c_str(),level_id::current().describe().c_str());#endiffmenv->set_transit(level_id::current());fmenv->destroy_inventory();monster_cleanup(fmenv);
places[place_set].clear();place_set = !place_set;