summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/actor.h5
-rw-r--r--crawl-ref/source/monster.h1
-rw-r--r--crawl-ref/source/player.h1
-rw-r--r--crawl-ref/source/teleport.cc44
4 files changed, 51 insertions, 0 deletions
diff --git a/crawl-ref/source/actor.h b/crawl-ref/source/actor.h
index ae0204aa6c..97e65922cb 100644
--- a/crawl-ref/source/actor.h
+++ b/crawl-ref/source/actor.h
@@ -32,6 +32,11 @@ public:
virtual void set_position(const coord_def &c);
virtual const coord_def& pos() const { return position; }
+ // Blink the actor to the destination. c should be a
+ // valid target, though the method returns false
+ // if the blink fails.
+ virtual bool blink_to(const coord_def &c, bool quiet = false) = 0;
+
virtual bool swimming() const = 0;
virtual bool submerged() const = 0;
virtual bool floundering() const = 0;
diff --git a/crawl-ref/source/monster.h b/crawl-ref/source/monster.h
index 051018c82e..dce3d7e60e 100644
--- a/crawl-ref/source/monster.h
+++ b/crawl-ref/source/monster.h
@@ -129,6 +129,7 @@ public:
void moveto(const coord_def& c);
bool move_to_pos(const coord_def &newpos);
+ bool blink_to(const coord_def& c, bool quiet = false);
kill_category kill_alignment() const;
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 55894921f0..20c8bcdeab 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -313,6 +313,7 @@ public:
void moveto(const coord_def &c);
// Move the player during an abyss shift.
void shiftto(const coord_def &c);
+ bool blink_to(const coord_def& c, bool quiet = false);
void reset_prev_move();
diff --git a/crawl-ref/source/teleport.cc b/crawl-ref/source/teleport.cc
index 30941b1d20..3d0f4d5164 100644
--- a/crawl-ref/source/teleport.cc
+++ b/crawl-ref/source/teleport.cc
@@ -13,6 +13,8 @@
#include "env.h"
#include "fprop.h"
#include "los.h"
+#include "monster.h"
+#include "mon-stuff.h"
#include "player.h"
#include "random.h"
#include "random-weight.h"
@@ -46,6 +48,48 @@ static coord_def random_close_space(actor* victim, actor* target)
return (choice ? *choice : coord_def(0, 0));
}
+bool player::blink_to(const coord_def& dest, bool quiet)
+{
+ // We rely on the non-generalized move_player_to_cell.
+ ASSERT(this == &you);
+
+ if (dest == pos())
+ return (false);
+ if (!quiet)
+ mpr("You blink.");
+ const coord_def origin = pos();
+ if (!move_player_to_grid(dest, false, true, true))
+ return (false);
+ place_cloud(CLOUD_TLOC_ENERGY, origin, 1 + random2(3), KC_YOU);
+ return (true);
+}
+
+bool monsters::blink_to(const coord_def& dest, bool quiet)
+{
+ if (dest == pos())
+ return (false);
+ if (!quiet)
+ simple_monster_message(this, " blinks!");
+
+ if (!(flags & MF_WAS_IN_VIEW))
+ seen_context = "thin air";
+
+ const coord_def oldplace = pos();
+ if (!move_to_pos(dest))
+ return (false);
+
+ // Leave a purple cloud.
+ place_cloud(CLOUD_TLOC_ENERGY, oldplace, 1 + random2(3),
+ kill_alignment());
+
+ check_redraw(oldplace);
+ apply_location_effects(oldplace);
+
+ mons_relocated(this);
+
+ return (true);
+}
+
// Blink the player closer to the monster at target.
void blink_closer(const coord_def &target)
{