summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-26 20:21:02 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-26 20:21:02 +0000
commit3cfe89ce027c008e6fe651b79171afa5da78cd85 (patch)
tree2144e4b9ebf175f54ed9afb3f604d61bcaba0514 /crawl-ref/source
parent3df2c03fc7434ef10dc8608617425c0969d18916 (diff)
downloadcrawl-ref-3cfe89ce027c008e6fe651b79171afa5da78cd85.tar.gz
crawl-ref-3cfe89ce027c008e6fe651b79171afa5da78cd85.zip
Fix "suicidal travelling" towards monsters you can see through glass.
Fix =sustenance not being treated as useless for Mummies. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7982 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/dat/database/FAQ.txt2
-rw-r--r--crawl-ref/source/dat/mini.des2
-rw-r--r--crawl-ref/source/database.cc2
-rw-r--r--crawl-ref/source/enum.h3
-rw-r--r--crawl-ref/source/itemname.cc4
-rw-r--r--crawl-ref/source/misc.cc41
-rw-r--r--crawl-ref/source/monplace.cc43
-rw-r--r--crawl-ref/source/monplace.h10
-rw-r--r--crawl-ref/source/monstuff.cc46
-rw-r--r--crawl-ref/source/transfor.cc1
10 files changed, 106 insertions, 48 deletions
diff --git a/crawl-ref/source/dat/database/FAQ.txt b/crawl-ref/source/dat/database/FAQ.txt
index 762586f4d2..b769fb9355 100644
--- a/crawl-ref/source/dat/database/FAQ.txt
+++ b/crawl-ref/source/dat/database/FAQ.txt
@@ -143,7 +143,7 @@ The game keeps crashing. / I think I found a bug. What do I do?
%%%%
A:bug
-Please submit a bug report on Sourceforge, and give as much information as you can. (What were you doing at the time? What did you expect to happen, what happened instead? etc.) Sometimes a screenshot can be helpful. For crashes, or monsters/items/levels behaving oddly, we probably need a save file. To be on the safe side, attach the entire zipped save of the character on question. If there are error messages, please write them down.
+Please submit a bug report on Sourceforge, and give as much information as you can. (What were you doing at the time? What did you expect to happen, what happened instead? etc.) Sometimes a screenshot can be helpful. For crashes, or monsters/items/levels behaving oddly, we probably need a save file. To be on the safe side, attach the entire zipped save of the character in question. If there are error messages, please write them down.
If you don't log in to Sourceforge or leave an email address at least check the thread from time to time in case we have some more questions. Thanks in advance!
%%%%
Q:ideas
diff --git a/crawl-ref/source/dat/mini.des b/crawl-ref/source/dat/mini.des
index 75c20c1980..0fd746e1e5 100644
--- a/crawl-ref/source/dat/mini.des
+++ b/crawl-ref/source/dat/mini.des
@@ -45,7 +45,7 @@ ENDMAP
###########################################################################
# Small areas with translucent rock (glass) columns which you can duck
# behind, but still see the monster you're ducking from (and they can
-# still see you
+# still see you)
NAME: glass_columns_a
DEPTH: D, Elf, Crypt
WEIGHT: 5
diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc
index 488ece7d42..1dbdacd279 100644
--- a/crawl-ref/source/database.cc
+++ b/crawl-ref/source/database.cc
@@ -719,14 +719,12 @@ std::vector<std::string> getAllFAQKeys()
std::string getFAQ_Question(const std::string &key)
{
-// mprf("Question key: %s", key.c_str());
return _query_database(FAQDB.get(), key, false, true);
}
std::string getFAQ_Answer(const std::string &question)
{
std::string key = "a" + question.substr(1, question.length()-1);
-// mprf("Answer key: %s", key.c_str());
return _query_database(FAQDB.get(), key, false, true);
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index d18eea0572..ee45a5efac 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -3056,7 +3056,8 @@ enum montravel_target_type
MTRAV_PATROL, // Travelling to reach the patrol point.
MTRAV_SIREN, // Sirens travelling towards deep water.
MTRAV_WALL, // Earthworms travelling towards a wall.
- MTRAV_UNREACHABLE // Not travelling because target is unreachable.
+ MTRAV_UNREACHABLE, // Not travelling because target is unreachable.
+ MTRAV_KNOWN_UNREACHABLE // As above, and the player knows this.
};
#ifndef USE_TILE
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index 0f74bd14cb..bd5149d314 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -2471,8 +2471,8 @@ bool is_useless_item(const item_def &item, bool temp)
case RING_REGENERATION:
case RING_SUSTENANCE:
return (you.is_undead
- && (!temp || you.species == SP_VAMPIRE
- && you.hunger_state == HS_STARVING));
+ && (you.species != SP_VAMPIRE
+ || temp && you.hunger_state == HS_STARVING));
case RING_SEE_INVISIBLE:
return (player_mutation_level(MUT_ACUTE_VISION));
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index cdd0b3157f..0c3ae915f3 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -55,6 +55,7 @@
#include "makeitem.h"
#include "mapmark.h"
#include "message.h"
+#include "monplace.h"
#include "mon-util.h"
#include "monstuff.h"
#include "ouch.h"
@@ -2580,6 +2581,41 @@ bool go_berserk(bool intentional)
return (true);
}
+// Returns true if the monster has a path to the player, or it has to be
+// assumed that this is the case.
+static bool _mons_has_path_to_player(const monsters *mon)
+{
+ int m = monster_index(mon);
+
+ // Don't consider sleeping monsters safe, in case the player would
+ // rather retreat and try another path for maximum stabbing chances.
+ if (mons_is_sleeping(mon))
+ return (true);
+
+ // If the monster is awake and knows a path towards the player
+ // (even though the player cannot know this) treat it as unsafe.
+ if (mon->travel_target == MTRAV_PLAYER)
+ return (true);
+
+ if (mon->travel_target == MTRAV_KNOWN_UNREACHABLE)
+ return (false);
+
+ // Try to find a path from monster to player, using the map as it's
+ // known to the player and assuming unknown terrain to be traversable.
+ monster_pathfind mp;
+ const int range = mons_tracking_range(mon);
+ if (range > 0)
+ mp.set_range(range);
+
+ if (mp.init_pathfind(&menv[m], you.pos(), true, false, true))
+ return (true);
+
+ // Now we know the monster cannot possibly reach the player.
+ menv[m].travel_target = MTRAV_KNOWN_UNREACHABLE;
+
+ return (false);
+}
+
bool mons_is_safe(const monsters *mon, bool want_move,
bool consider_user_options)
{
@@ -2593,6 +2629,7 @@ bool mons_is_safe(const monsters *mon, bool want_move,
#endif
// Only seen through glass walls?
|| !see_grid_no_trans(mon->pos())
+ && !_mons_has_path_to_player(mon)
&& !mons_has_ranged_spell(mon)
&& !mons_has_los_ability(mon->type));
@@ -2682,7 +2719,7 @@ std::vector<monsters*> get_nearby_monsters(bool want_move,
std::vector<monsters*> mons;
// Sweep every visible square within range.
- for ( radius_iterator ri(you.pos(), range); ri; ++ri )
+ for (radius_iterator ri(you.pos(), range); ri; ++ri)
{
const unsigned short targ_monst = env.mgrid(*ri);
if (targ_monst != NON_MONSTER)
@@ -2753,9 +2790,7 @@ bool i_feel_safe(bool announce, bool want_move, bool just_monsters, int range)
tutorial_first_monster(m);
}
else if (announce && visible.size() > 1)
- {
mprf(MSGCH_WARN, "Not with these monsters around!");
- }
return (false);
}
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 5e21057810..d7772d368a 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -2472,6 +2472,41 @@ monster_type summon_any_dragon(dragon_class_type dct)
// (These requirements are usually preference of habitat of a specific monster
// or a limit of the distance between start and any grid on the path.)
+int mons_tracking_range(const monsters *mon)
+{
+
+ int range = 0;
+ switch (mons_intel(mon))
+ {
+ case I_PLANT:
+ range = 2;
+ break;
+ case I_INSECT:
+ range = 4;
+ break;
+ case I_ANIMAL:
+ range = 5;
+ break;
+ case I_NORMAL:
+ range = LOS_RADIUS;
+ break;
+ default:
+ // Highly intelligent monsters can find their way
+ // anywhere. (range == 0 means no restriction.)
+ break;
+ }
+
+ if (range)
+ {
+ if (mons_is_native_in_branch(mon))
+ range += 3;
+ else if (mons_class_flag(mon->type, M_BLOOD_SCENT))
+ range++;
+ }
+
+ return (range);
+}
+
//#define DEBUG_PATHFIND
monster_pathfind::monster_pathfind()
: mons(), target(), range(0), min_length(0), max_length(0), dist(), prev()
@@ -2491,7 +2526,7 @@ void monster_pathfind::set_range(int r)
// The main method in the monster_pathfind class.
// Returns true if a path was found, else false.
bool monster_pathfind::init_pathfind(monsters *mon, coord_def dest, bool diag,
- bool msg)
+ bool msg, bool pass_unmapped)
{
mons = mon;
@@ -2499,7 +2534,8 @@ bool monster_pathfind::init_pathfind(monsters *mon, coord_def dest, bool diag,
start = dest;
target = mon->pos();
pos = start;
- allow_diagonals = diag;
+ allow_diagonals = diag;
+ traverse_unmapped = pass_unmapped;
// Easy enough. :P
if (start == target)
@@ -2786,6 +2822,9 @@ std::vector<coord_def> monster_pathfind::calc_waypoints()
bool monster_pathfind::traversable(const coord_def p)
{
+ if (traverse_unmapped && grd(p) == DNGN_UNSEEN)
+ return (true);
+
if (mons)
return mons_traversable(p);
diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h
index 24be04f149..300803fe2f 100644
--- a/crawl-ref/source/monplace.h
+++ b/crawl-ref/source/monplace.h
@@ -352,6 +352,8 @@ void get_vault_mon_list(std::vector<mons_spec> &list);
* *********************************************************************** */
void setup_vault_mon_list();
+int mons_tracking_range(const monsters *mon);
+
class monster_pathfind
{
public:
@@ -361,7 +363,8 @@ public:
// public methods
void set_range(int r);
bool init_pathfind(monsters *mon, coord_def dest,
- bool diag = true, bool msg = false);
+ bool diag = true, bool msg = false,
+ bool pass_unmapped = false);
bool init_pathfind(coord_def src, coord_def dest,
bool diag = true, bool msg = false);
bool start_pathfind(bool msg = false);
@@ -390,6 +393,11 @@ protected:
// If false, do not move diagonally along the path.
bool allow_diagonals;
+ // If true, unmapped terrain is treated as traversable no matter the
+ // monster involved.
+ // (Used for player estimates of whether a monster can travel somewhere.)
+ bool traverse_unmapped;
+
// Maximum range to search between start and target. None, if zero.
int range;
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index e410ab54e0..16f2c8f570 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -1612,7 +1612,7 @@ static bool _jelly_divide(monsters *parent)
int num_spots = 0;
// First, find a suitable spot for the child {dlb}:
- for ( adjacent_iterator ai(parent->pos()); ai; ++ai )
+ for (adjacent_iterator ai(parent->pos()); ai; ++ai)
{
if (mgrd(*ai) == NON_MONSTER
&& parent->can_pass_through(*ai)
@@ -2673,7 +2673,7 @@ static void _find_all_level_exits(std::vector<level_exit> &e)
for (rectangle_iterator ri(1); ri; ++ri)
{
if (!in_bounds(*ri))
- continue;
+ continue;
const dungeon_feature_type gridc = grd(*ri);
@@ -2769,6 +2769,12 @@ static void _set_no_path_found(monsters *mon)
_mark_neighbours_target_unreachable(mon);
}
+static bool _target_is_unreachable(monsters *mon)
+{
+ return (mon->travel_target == MTRAV_UNREACHABLE
+ || mon->travel_target == MTRAV_KNOWN_UNREACHABLE);
+}
+
// The monster is trying to get to the player (MHITYOU).
// Check whether there's an unobstructed path to the player (in sight!),
// either by using an existing travel_path or calculating a new one.
@@ -2850,7 +2856,7 @@ static bool _try_pathfind(monsters *mon, const dungeon_feature_type can_move,
// Even if the target has been to "unreachable" (the monster already tried,
// and failed, to find a path) there's a chance of trying again.
- if (mon->travel_target != MTRAV_UNREACHABLE || one_chance_in(12))
+ if (!_target_is_unreachable(mon) || one_chance_in(12))
{
#ifdef DEBUG_PATHFIND
mprf("%s: Player out of reach! What now?",
@@ -2892,37 +2898,7 @@ static bool _try_pathfind(monsters *mon, const dungeon_feature_type can_move,
#ifdef DEBUG_PATHFIND
mprf("Need to calculate a path... (dist = %d)", dist);
#endif
- const bool native = mons_is_native_in_branch(mon);
-
- int range = 0;
- switch (mons_intel(mon))
- {
- case I_PLANT:
- range = 2;
- break;
- case I_INSECT:
- range = 4;
- break;
- case I_ANIMAL:
- range = 5;
- break;
- case I_NORMAL:
- range = LOS_RADIUS;
- break;
- default:
- // Highly intelligent monsters can find their way
- // anywhere. (range == 0 means no restriction.)
- break;
- }
-
- if (range)
- {
- if (native)
- range += 3;
- else if (mons_class_flag(mon->type, M_BLOOD_SCENT))
- range++;
- }
-
+ const int range = mons_tracking_range(mon);
if (range > 0 && dist > range)
{
mon->travel_target = MTRAV_UNREACHABLE;
@@ -8333,7 +8309,7 @@ bool shift_monster( monsters *mon, coord_def p )
if (p.origin())
p = mon->pos();
- for ( adjacent_iterator ai(p); ai; ++ai )
+ for (adjacent_iterator ai(p); ai; ++ai)
{
// Don't drop on anything but vanilla floor right now.
if (grd(*ai) != DNGN_FLOOR)
diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc
index ce6a49d507..f891c90804 100644
--- a/crawl-ref/source/transfor.cc
+++ b/crawl-ref/source/transfor.cc
@@ -62,6 +62,7 @@ static void _init_equipment_removal(std::set<equipment_type> &rem_stuff,
break;
case TRAN_LICH:
+ // Liches may wear anything.
rem_stuff.clear();
break;