git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3325 c06c8d41-db1a-0410-9941-cceddc491573
32S5UVZCXZ5QWH4NDB23MHOPLVPON3VKIWH6EEY42SRPBFZUUXSQC UESUKAUHWXQBR3JCLVFKNX2CNO4RNAZIUFIT2OM2ITJSUQ4NDVTAC RBAGQ2PB7V5YAM5KSHSZR2E3MLKDSRVM5XYGI2TIXP5QMVBOQHDQC HIRKGUMNJPWKSVTR6TVBPD3MWNA63CEHCLCIPWEMGDFHVB3NPLDQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC WMHFDQKUDCUGM3R245LLVZ5NNEZSCXFDSTNMVS2O5EFUHHO7HU3AC CG4TL4AKSN4J7CMATZFJ5N7PSDCQXLS3QYX7PZ3K67KMMBT675OQC // Move monsters around to fake them walking around while player was// off-level.static void catchup_monster_moves(monsters *mon, int turns){// Summoned monsters might have disappearedif (!mon->alive())return;// Don't move non-land or stationary monsters aroundif (mons_habitat( mon ) != HT_LAND|| mons_is_stationary( mon )){return;}// Let sleeping monsters lieif (mon->behaviour == BEH_SLEEP || mons_is_paralysed(mon))return;const int range = (turns * mon->speed) / 10;const int moves = (range > 50) ? 50 : range;// const bool short_time = (range >= 5 + random2(10));const bool long_time = (range >= (500 + roll_dice( 2, 500 )));const bool ranged_attack = (mons_has_ranged_spell( mon )|| mons_has_ranged_attack( mon ));#if DEBUG_DIAGNOSTICS// probably too annoying even for DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS,"mon #%d: range %d; long %d; ""pos (%d,%d); targ %d(%d,%d); flags %ld",monster_index(mon), range, long_time, mon->x, mon->y,mon->foe, mon->target_x, mon->target_y, mon->flags );#endifif (range <= 0)return;if (long_time&& (mon->behaviour == BEH_FLEE|| mon->behaviour == BEH_CORNERED|| testbits( mon->flags, MF_BATTY )|| ranged_attack|| coinflip())){if (mon->behaviour != BEH_WANDER){mon->behaviour = BEH_WANDER;mon->foe = MHITNOT;mon->target_x = 10 + random2( GXM - 10 );mon->target_y = 10 + random2( GYM - 10 );}else{// monster will be sleeping after we move itmon->behaviour = BEH_SLEEP;}}else if (ranged_attack){// if we're doing short time movement and the monster has a// ranged attack (missile or spell), then the monster will// flee to gain distance if its "too close", else it will// just shift its position rather than charge the player. -- bwrif (grid_distance(mon->x, mon->y, mon->target_x, mon->target_y) < 3){mon->behaviour = BEH_FLEE;// if the monster is on the target square, fleeing won't workif (mon->x == mon->target_x && mon->y == mon->target_y){if (you.x_pos != mon->x || you.y_pos != mon->y){// flee from player's position if differentmon->target_x = you.x_pos;mon->target_y = you.y_pos;}else{// randomize the target so we have a direction to fleemon->target_x += (random2(3) - 1);mon->target_y += (random2(3) - 1);}}#if DEBUG_DIAGNOSTICSmpr( "backing off...", MSGCH_DIAGNOSTICS );#endif}else{shift_monster( mon, mon->x, mon->y );#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "shifted to (%d,%d)", mon->x, mon->y);#endifreturn;}}coord_def pos(mon->pos());// dirt simple movement:for (int i = 0; i < moves; i++){coord_def inc(mon->target_pos() - pos);inc = coord_def(sgn(inc.x), sgn(inc.y));if (mon->behaviour == BEH_FLEE)inc *= -1;if (pos.x + inc.x < 0 || pos.x + inc.x >= GXM)inc.x = 0;if (pos.y + inc.y < 0 || pos.y + inc.y >= GYM)inc.y = 0;if (inc.origin())break;const coord_def next(pos + inc);const dungeon_feature_type feat = grd(next);if (grid_is_solid(feat)|| mgrd(next) != NON_MONSTER|| !monster_habitable_grid(mon, feat))break;pos = next;}if (!shift_monster( mon, pos.x, pos.y ))shift_monster( mon, mon->x, mon->y );#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "moved to (%d,%d)", mon->x, mon->y );#endif}
// Summoned monsters might have disappearedif (mon->type == -1)continue;// Don't move non-land or stationary monsters aroundif (mons_habitat( mon ) != HT_LAND|| mons_is_stationary( mon )){continue;}// Let sleeping monsters lieif (mon->behaviour == BEH_SLEEP || mons_is_paralysed(mon))continue;const int range = (turns * mon->speed) / 10;const int moves = (range > 50) ? 50 : range;// const bool short_time = (range >= 5 + random2(10));const bool long_time = (range >= (500 + roll_dice( 2, 500 )));const bool ranged_attack = (mons_has_ranged_spell( mon )|| mons_has_ranged_attack( mon ));#if DEBUG_DIAGNOSTICS// probably too annoying even for DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS,"mon #%d: range %d; long %d; ""pos (%d,%d); targ %d(%d,%d); flags %ld",m, range, long_time, mon->x, mon->y,mon->foe, mon->target_x, mon->target_y, mon->flags );#endifif (range <= 0)continue;if (long_time&& (mon->behaviour == BEH_FLEE|| mon->behaviour == BEH_CORNERED|| testbits( mon->flags, MF_BATTY )|| ranged_attack|| coinflip())){if (mon->behaviour != BEH_WANDER){mon->behaviour = BEH_WANDER;mon->foe = MHITNOT;mon->target_x = 10 + random2( GXM - 10 );mon->target_y = 10 + random2( GYM - 10 );}else{// monster will be sleeping after we move itmon->behaviour = BEH_SLEEP;}}else if (ranged_attack){// if we're doing short time movement and the monster has a// ranged attack (missile or spell), then the monster will// flee to gain distance if its "too close", else it will// just shift its position rather than charge the player. -- bwrif (grid_distance(mon->x, mon->y, mon->target_x, mon->target_y) < 3){mon->behaviour = BEH_FLEE;// if the monster is on the target square, fleeing won't workif (mon->x == mon->target_x && mon->y == mon->target_y){if (you.x_pos != mon->x || you.y_pos != mon->y){// flee from player's position if differentmon->target_x = you.x_pos;mon->target_y = you.y_pos;}else{// randomize the target so we have a direction to fleemon->target_x += (random2(3) - 1);mon->target_y += (random2(3) - 1);}}#if DEBUG_DIAGNOSTICSmpr( "backing off...", MSGCH_DIAGNOSTICS );#endif}else{shift_monster( mon, mon->x, mon->y );#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "shifted to (%d,%d)", mon->x, mon->y);#endifcontinue;}}coord_def pos(mon->pos());// dirt simple movement:for (i = 0; i < moves; i++){coord_def inc(mon->target_pos() - pos);inc = coord_def(sgn(inc.x), sgn(inc.y));if (mon->behaviour == BEH_FLEE)inc *= -1;if (pos.x + inc.x < 0 || pos.x + inc.x >= GXM)inc.x = 0;if (pos.y + inc.y < 0 || pos.y + inc.y >= GYM)inc.y = 0;if (inc.origin())break;const coord_def next(pos + inc);const dungeon_feature_type feat = grd(next);if (grid_is_solid(feat)|| mgrd(next) != NON_MONSTER|| !monster_habitable_grid(mon, feat))break;pos = next;}if (!shift_monster( mon, pos.x, pos.y ))shift_monster( mon, mon->x, mon->y );#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "moved to (%d,%d)", mon->x, mon->y );#endif