summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/item_use.cc1
-rw-r--r--crawl-ref/source/makefile.obj1
-rw-r--r--crawl-ref/source/monstuff.cc113
-rw-r--r--crawl-ref/source/monstuff.h12
-rw-r--r--crawl-ref/source/spells1.cc1
-rw-r--r--crawl-ref/source/spells2.cc1
-rw-r--r--crawl-ref/source/spells4.cc1
-rw-r--r--crawl-ref/source/teleport.cc130
-rw-r--r--crawl-ref/source/teleport.h10
-rw-r--r--crawl-ref/source/xom.cc1
10 files changed, 146 insertions, 125 deletions
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index eb405b395e..a4ee6dbacf 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -63,6 +63,7 @@
#include "spl-util.h"
#include "state.h"
#include "stuff.h"
+#include "teleport.h"
#include "transfor.h"
#include "traps.h"
#include "tutorial.h"
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index 0bf8af4fa2..0ecee6cd2e 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -133,6 +133,7 @@ state.o \
store.o \
stuff.o \
tags.o \
+teleport.o \
terrain.o \
transfor.o \
traps.o \
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 64e6276e68..3b1aa9e86c 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2479,119 +2479,6 @@ void slimify_monster(monsters *mon, bool hostile)
mons_make_god_gift(mon, GOD_JIYVA);
}
-// allow_adjacent: allow target to be adjacent to origin.
-// restrict_LOS: restrict target to be within PLAYER line of sight.
-bool random_near_space(const coord_def& origin, coord_def& target,
- bool allow_adjacent, bool restrict_los,
- bool forbid_dangerous, bool forbid_sanctuary)
-{
- // This might involve ray tracing (via num_feats_between()), so
- // cache results to avoid duplicating ray traces.
-#define RNS_OFFSET 6
-#define RNS_WIDTH (2*RNS_OFFSET + 1)
- FixedArray<bool, RNS_WIDTH, RNS_WIDTH> tried;
- const coord_def tried_o = coord_def(RNS_OFFSET, RNS_OFFSET);
- tried.init(false);
-
- // Is the monster on the other side of a transparent wall?
- const bool trans_wall_block = trans_wall_blocking(origin);
- const bool origin_is_player = (you.pos() == origin);
- int min_walls_between = 0;
-
- // Skip ray tracing if possible.
- if (trans_wall_block && !crawl_state.arena)
- {
- // XXX: you.pos() is invalid in the arena.
- min_walls_between = num_feats_between(origin, you.pos(),
- DNGN_CLEAR_ROCK_WALL,
- DNGN_CLEAR_PERMAROCK_WALL);
- }
-
- for (int tries = 0; tries < 150; tries++)
- {
- coord_def p = coord_def(random2(RNS_WIDTH), random2(RNS_WIDTH));
- if (tried(p))
- continue;
- else
- tried(p) = true;
-
- target = origin + (p - tried_o);
-
- // Origin is not 'near'.
- if (target == origin)
- continue;
-
- if (!in_bounds(target)
- || restrict_los && !see_cell(target)
- || grd(target) < DNGN_SHALLOW_WATER
- || actor_at(target)
- || !allow_adjacent && distance(origin, target) <= 2
- || forbid_sanctuary && is_sanctuary(target))
- {
- continue;
- }
-
- // Don't pick grids that contain a dangerous cloud.
- if (forbid_dangerous)
- {
- const int cloud = env.cgrid(target);
-
- if (cloud != EMPTY_CLOUD
- && is_damaging_cloud(env.cloud[cloud].type, true))
- {
- continue;
- }
- }
-
- if (!trans_wall_block && !origin_is_player)
- return (true);
-
- // If the monster is on a visible square which is on the other
- // side of one or more translucent walls from the player, then it
- // can only blink through translucent walls if the end point
- // is either not visible to the player, or there are at least
- // as many translucent walls between the player and the end
- // point as between the player and the start point. However,
- // monsters can still blink through translucent walls to get
- // away from the player, since in the absence of translucent
- // walls monsters can blink to places which are not in either
- // the monster's nor the player's LOS.
- if (!origin_is_player && !see_cell(target))
- return (true);
-
- // Player can't randomly pass through translucent walls.
- if (origin_is_player)
- {
- if (see_cell_no_trans(target))
- return (true);
-
- continue;
- }
-
- int walls_passed = num_feats_between(target, origin,
- DNGN_CLEAR_ROCK_WALL,
- DNGN_CLEAR_PERMAROCK_WALL,
- true, true);
- if (walls_passed == 0)
- return (true);
-
- // Player can't randomly pass through translucent walls.
- if (origin_is_player)
- continue;
-
- int walls_between = 0;
- if (!crawl_state.arena)
- walls_between = num_feats_between(target, you.pos(),
- DNGN_CLEAR_ROCK_WALL,
- DNGN_CLEAR_PERMAROCK_WALL);
-
- if (walls_between >= min_walls_between)
- return (true);
- }
-
- return (false);
-}
-
static bool _habitat_okay( const monsters *monster, dungeon_feature_type targ )
{
return (monster_habitable_grid(monster, targ));
diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h
index 1b808fed6d..40c6528587 100644
--- a/crawl-ref/source/monstuff.h
+++ b/crawl-ref/source/monstuff.h
@@ -122,18 +122,6 @@ void monster_drop_ething(monsters *monster, bool mark_item_origins = false,
* *********************************************************************** */
bool monster_blink(monsters *monster, bool quiet = false);
-
-/* ***********************************************************************
- * called from: spells1 spells4 monstuff
- * defaults are set up for player blink; monster blink should call with
- * false, false
- * *********************************************************************** */
-bool random_near_space(const coord_def& origin, coord_def& target,
- bool allow_adjacent = false, bool restrict_LOS = true,
- bool forbid_dangerous = true,
- bool forbid_sanctuary = false);
-
-
/* ***********************************************************************
* called from: beam - effects - fight - monstuff - mstuff2 - spells1 -
* spells2 - spells4
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 06225193b4..9c0feb4a40 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -43,6 +43,7 @@
#include "spl-util.h"
#include "state.h"
#include "stuff.h"
+#include "teleport.h"
#include "terrain.h"
#include "transfor.h"
#include "traps.h"
diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc
index 3a9741b49f..6d1cb1b31a 100644
--- a/crawl-ref/source/spells2.cc
+++ b/crawl-ref/source/spells2.cc
@@ -43,6 +43,7 @@
#include "spells4.h"
#include "spl-mis.h"
#include "stuff.h"
+#include "teleport.h"
#include "tiles.h"
#include "terrain.h"
#include "traps.h"
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index dd452c1fbd..08620200b8 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -46,6 +46,7 @@
#include "spl-mis.h"
#include "spl-util.h"
#include "stuff.h"
+#include "teleport.h"
#include "terrain.h"
#include "transfor.h"
#include "traps.h"
diff --git a/crawl-ref/source/teleport.cc b/crawl-ref/source/teleport.cc
new file mode 100644
index 0000000000..5db62261b2
--- /dev/null
+++ b/crawl-ref/source/teleport.cc
@@ -0,0 +1,130 @@
+/*
+ * File: teleport.cc
+ * Summary: Functions related to teleportation and blinking.
+ */
+
+#include "AppHdr.h"
+
+#include "teleport.h"
+
+#include "cloud.h"
+#include "coord.h"
+#include "los.h"
+#include "player.h"
+#include "random.h"
+#include "state.h"
+#include "terrain.h"
+#include "view.h"
+
+bool random_near_space(const coord_def& origin, coord_def& target,
+ bool allow_adjacent, bool restrict_los,
+ bool forbid_dangerous, bool forbid_sanctuary)
+{
+ // This might involve ray tracing (via num_feats_between()), so
+ // cache results to avoid duplicating ray traces.
+#define RNS_OFFSET 6
+#define RNS_WIDTH (2*RNS_OFFSET + 1)
+ FixedArray<bool, RNS_WIDTH, RNS_WIDTH> tried;
+ const coord_def tried_o = coord_def(RNS_OFFSET, RNS_OFFSET);
+ tried.init(false);
+
+ // Is the monster on the other side of a transparent wall?
+ const bool trans_wall_block = trans_wall_blocking(origin);
+ const bool origin_is_player = (you.pos() == origin);
+ int min_walls_between = 0;
+
+ // Skip ray tracing if possible.
+ if (trans_wall_block && !crawl_state.arena)
+ {
+ // XXX: you.pos() is invalid in the arena.
+ min_walls_between = num_feats_between(origin, you.pos(),
+ DNGN_CLEAR_ROCK_WALL,
+ DNGN_CLEAR_PERMAROCK_WALL);
+ }
+
+ for (int tries = 0; tries < 150; tries++)
+ {
+ coord_def p = coord_def(random2(RNS_WIDTH), random2(RNS_WIDTH));
+ if (tried(p))
+ continue;
+ else
+ tried(p) = true;
+
+ target = origin + (p - tried_o);
+
+ // Origin is not 'near'.
+ if (target == origin)
+ continue;
+
+ if (!in_bounds(target)
+ || restrict_los && !see_cell(target)
+ || grd(target) < DNGN_SHALLOW_WATER
+ || actor_at(target)
+ || !allow_adjacent && distance(origin, target) <= 2
+ || forbid_sanctuary && is_sanctuary(target))
+ {
+ continue;
+ }
+
+ // Don't pick grids that contain a dangerous cloud.
+ if (forbid_dangerous)
+ {
+ const int cloud = env.cgrid(target);
+
+ if (cloud != EMPTY_CLOUD
+ && is_damaging_cloud(env.cloud[cloud].type, true))
+ {
+ continue;
+ }
+ }
+
+ if (!trans_wall_block && !origin_is_player)
+ return (true);
+
+ // If the monster is on a visible square which is on the other
+ // side of one or more translucent walls from the player, then it
+ // can only blink through translucent walls if the end point
+ // is either not visible to the player, or there are at least
+ // as many translucent walls between the player and the end
+ // point as between the player and the start point. However,
+ // monsters can still blink through translucent walls to get
+ // away from the player, since in the absence of translucent
+ // walls monsters can blink to places which are not in either
+ // the monster's nor the player's LOS.
+ if (!origin_is_player && !see_cell(target))
+ return (true);
+
+ // Player can't randomly pass through translucent walls.
+ if (origin_is_player)
+ {
+ if (see_cell_no_trans(target))
+ return (true);
+
+ continue;
+ }
+
+ int walls_passed = num_feats_between(target, origin,
+ DNGN_CLEAR_ROCK_WALL,
+ DNGN_CLEAR_PERMAROCK_WALL,
+ true, true);
+ if (walls_passed == 0)
+ return (true);
+
+ // Player can't randomly pass through translucent walls.
+ if (origin_is_player)
+ continue;
+
+ int walls_between = 0;
+ if (!crawl_state.arena)
+ walls_between = num_feats_between(target, you.pos(),
+ DNGN_CLEAR_ROCK_WALL,
+ DNGN_CLEAR_PERMAROCK_WALL);
+
+ if (walls_between >= min_walls_between)
+ return (true);
+ }
+
+ return (false);
+}
+
+
diff --git a/crawl-ref/source/teleport.h b/crawl-ref/source/teleport.h
new file mode 100644
index 0000000000..bc762bae91
--- /dev/null
+++ b/crawl-ref/source/teleport.h
@@ -0,0 +1,10 @@
+#ifndef TELEPORT_H
+#define TELEPORT_H
+
+bool random_near_space(const coord_def& origin, coord_def& target,
+ bool allow_adjacent = false, bool restrict_LOS = true,
+ bool forbid_dangerous = true,
+ bool forbid_sanctuary = false);
+
+#endif
+
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc
index a79672a555..efcf159b6f 100644
--- a/crawl-ref/source/xom.cc
+++ b/crawl-ref/source/xom.cc
@@ -44,6 +44,7 @@
#include "stash.h"
#include "state.h"
#include "stuff.h"
+#include "teleport.h"
#include "terrain.h"
#include "transfor.h"
#include "traps.h"