summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-11 12:38:33 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-11 12:38:33 +0000
commit5a10cfbf8b5800a362608ebfd534e643cc5cbbcd (patch)
tree4d1cadca24ee81a50ddb06475421cf0409f61db3
parente3c86b100dc45f37ef5e0d4759b867a5c0b22a22 (diff)
downloadcrawl-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.cc33
-rw-r--r--crawl-ref/source/mon-data.h2
-rw-r--r--crawl-ref/source/mon-util.cc2
-rw-r--r--crawl-ref/source/monstuff.cc69
-rw-r--r--crawl-ref/source/view.cc6
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