diff options
author | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-06-11 12:38:33 +0000 |
---|---|---|
committer | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-06-11 12:38:33 +0000 |
commit | 5a10cfbf8b5800a362608ebfd534e643cc5cbbcd (patch) | |
tree | 4d1cadca24ee81a50ddb06475421cf0409f61db3 | |
parent | e3c86b100dc45f37ef5e0d4759b867a5c0b22a22 (diff) | |
download | crawl-ref-5a10cfbf8b5800a362608ebfd534e643cc5cbbcd.tar.gz crawl-ref-5a10cfbf8b5800a362608ebfd534e643cc5cbbcd.zip |
Increase efficiency for pathfinding around glass structures by lowering
the chance to "try again" if the last time we were unsuccessful. Also,
if a monster tries to find a path to the player (not directly reachable)
and fails, mark all surrounding monsters of the same species within a
radius of 2 as having been unsuccessful. This includes monsters that are
currently out of los of the player or that are targetting a different
monster. Once they target the player, there'll either be a direct path
which they can use, or there won't, in which case there's a low chance of
using path finding; otherwise they'll simply advance the traditional way
as close as they can get.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5733 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/source/delay.cc | 33 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 69 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 6 |
5 files changed, 94 insertions, 18 deletions
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index c571d2985a..35a19bdd62 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -767,14 +767,16 @@ void handle_delay( void ) } else { - // Only give the rotting message if the corpse wasn't - // previously rotten. (special < 100 is the rottenness check) - if (food_is_rotten(mitm[delay.parm1]) && delay.parm2 >= 100) + if (food_is_rotten(mitm[delay.parm1])) { - mpr("The corpse rots.", MSGCH_ROTTEN_MEAT); + // Only give the rotting message if the corpse wasn't + // previously rotten. (special < 100 is the rottenness check). + if (delay.parm2 >= 100) + mpr("The corpse rots.", MSGCH_ROTTEN_MEAT); + if (delay.type == DELAY_OFFER_CORPSE) { - // don't attempt to offer a rotten corpse + // Don't attempt to offer a rotten corpse. _pop_delay(); // Chain onto the next delay. @@ -782,7 +784,7 @@ void handle_delay( void ) return; } - delay.parm2 = 99; // don't give the message twice + delay.parm2 = 99; // Don't give the message twice. if (you.is_undead != US_UNDEAD && player_mutation_level(MUT_SAPROVOROUS) < 3) @@ -798,7 +800,7 @@ void handle_delay( void ) } } - // mark work done on the corpse in case we stop -- bwr + // Mark work done on the corpse in case we stop. -- bwr mitm[ delay.parm1 ].plus2++; } } @@ -1176,8 +1178,21 @@ static void _finish_delay(const delay_queue_item &delay) return; } - offer_corpse(delay.parm1); - StashTrack.update_stash(); // Don't stash-track this corpse anymore. + if (food_is_rotten(mitm[delay.parm1])) + { + simple_god_message(coinflip() ? " refuses to accept that" + " mouldy sacrifice!" + : " demands fresh blood!", + you.religion); + _pop_delay(); + // Chain onto the next delay. + handle_delay(); + } + else + { + offer_corpse(delay.parm1); + StashTrack.update_stash(); // Don't stash-track this corpse anymore. + } break; } case DELAY_DROP_ITEM: diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index 37b4d7bcfe..3ae9fd9c5c 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -3060,7 +3060,7 @@ // mimics { - // gold mimics are the only mimics that actually use their name -- bwr + // Gold mimics are the only mimics that actually use their name. -- bwr MONS_GOLD_MIMIC, '$', YELLOW, "pile of gold coins", M_NO_SKELETON | M_STATIONARY, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 68ccf0d090..4fb4d510ab 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -703,7 +703,7 @@ bool mons_see_invis(const monsters *mon) bool mon_can_see_monster( const monsters *mon, const monsters *targ ) { if (!mon->mon_see_grid(targ->x, targ->y)) - return false; + return (false); return (mons_monster_visible(mon, targ)); } diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index fbc9538e1d..c1431bea59 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -2322,6 +2322,63 @@ static bool _choose_random_patrol_target_grid(monsters *mon) } //#define DEBUG_PATHFIND + +// If a monster can see but not directly reach the player, and then fails to +// find a path to get him, mark all surrounding (in a radius of 2) monsters +// of the same species as also being unable to find a path, so we won't need +// to calculate again. +// Should there be a direct path to the player for a monster thus marked, it +// will still be able to come nearer (and the mark will be cleared). +static void _mark_species_members_player_unreachable(monsters *mon) +{ + // Highly intelligent monsters are capable of pathfinding and don't + // need their neighbour's advice. + if (mons_intel(mon->type) > I_NORMAL) + return; + + // We won't be able to find pack members of human unique monsters. + if (mons_is_unique(mon->type) && mons_species(mon->type) == MONS_HUMAN) + return; + + int x, y; + monsters *m; + for (int i = -2; i <= 2; i++) + for (int j = -2; j <= 2; j++) + { + if (i == 0 && j == 0) + continue; + + x = mon->x + i; + y = mon->y + j; + + if (!in_bounds(x,y)) + continue; + + if (mgrd[x][y] == NON_MONSTER) + continue; + + // Don't alert monsters out of sight (e.g. on the other side of + // a wall). + if (!mon->mon_see_grid(x, y)) + continue; + + m = &menv[mgrd[x][y]]; + + // Only mark target for monsters of same species. + // Restrict to same _type_ for humans (by far the most + // versatile species). + if (mon->type != m->type + && (mon->type == MONS_HUMAN + || mons_species(mon->type) != mons_species(m->type))) + { + continue; + } + + if (m->travel_target == MTRAV_NONE) + m->travel_target = MTRAV_UNREACHABLE; + } +} + //--------------------------------------------------------------- // // handle_behaviour @@ -2630,15 +2687,17 @@ static void _handle_behaviour(monsters *mon) { if (proxPlayer && !trans_wall_block) { - if (travelling && mon->travel_target != MTRAV_PATROL) + if (mon->travel_target != MTRAV_PATROL + && mon->travel_target != MTRAV_NONE) { - mon->travel_path.clear(); + if (travelling) + mon->travel_path.clear(); mon->travel_target = MTRAV_NONE; } } else if (proxPlayer && trans_wall_block && (mon->travel_target != MTRAV_UNREACHABLE - || one_chance_in(8))) + || one_chance_in(12))) { #ifdef DEBUG_PATHFIND mprf("%s: Player out of reach! What now?", @@ -2656,7 +2715,7 @@ static void _handle_behaviour(monsters *mon) && !trans_wall_blocking(targ.x, targ.y)) { #ifdef DEBUG_PATHFIND - mpr("Target still valid..."); + mpr("Target still valid?"); #endif // Current target still valid? if (mon->x == mon->travel_path[0].x @@ -2739,6 +2798,7 @@ static void _handle_behaviour(monsters *mon) monster_pathfind mp; if (range > 0) mp.set_range(range); + if (mp.start_pathfind(mon, coord_def(you.x_pos, you.y_pos))) { @@ -2757,6 +2817,7 @@ static void _handle_behaviour(monsters *mon) mpr("No path found!"); #endif mon->travel_target = MTRAV_UNREACHABLE; + _mark_species_members_player_unreachable(mon); } } else diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index a8f5eda595..905fe0e967 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -793,8 +793,8 @@ static void _good_god_follower_attitude_change(monsters *monster) if (you.is_undead || you.species == SP_DEMONSPAWN) return; - // for followers of good gods, decide whether holy beings will be - // good neutral towards you + // For followers of good gods, decide whether holy beings will be + // good neutral towards you. if (is_good_god(you.religion) && monster->foe == MHITYOU && mons_is_holy(monster) @@ -830,7 +830,7 @@ void beogh_follower_convert(monsters *monster, bool orc_hit) if (you.species != SP_HILL_ORC) return; - // for followers of Beogh, decide whether orcs will join you + // For followers of Beogh, decide whether orcs will join you. if (you.religion == GOD_BEOGH && monster->foe == MHITYOU && mons_species(monster->type) == MONS_ORC |