summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/teleport.cc
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-11-13 23:34:54 +0100
committerRobert Vollmert <rvollmert@gmx.net>2009-11-14 00:45:06 +0100
commited044f5b883fb2cea4abf3e2bb8d6278a1483ebe (patch)
treee5d13738ce8a6746dcb9e51bfba139a834f3b3a1 /crawl-ref/source/teleport.cc
parent5c15e6abda97c19829d5b2b348b422f3857b42f7 (diff)
downloadcrawl-ref-ed044f5b883fb2cea4abf3e2bb8d6278a1483ebe.tar.gz
crawl-ref-ed044f5b883fb2cea4abf3e2bb8d6278a1483ebe.zip
Implement function to blink an actor closer to another actor.
Diffstat (limited to 'crawl-ref/source/teleport.cc')
-rw-r--r--crawl-ref/source/teleport.cc41
1 files changed, 41 insertions, 0 deletions
diff --git a/crawl-ref/source/teleport.cc b/crawl-ref/source/teleport.cc
index fe0c2f4b7f..e5f6258911 100644
--- a/crawl-ref/source/teleport.cc
+++ b/crawl-ref/source/teleport.cc
@@ -9,14 +9,55 @@
#include "cloud.h"
#include "coord.h"
+#include "coordit.h"
#include "env.h"
#include "fprop.h"
#include "los.h"
#include "player.h"
#include "random.h"
+#include "random-weight.h"
#include "state.h"
#include "terrain.h"
+typedef std::pair<coord_def, int> coord_weight;
+
+// Try to find a "safe" place for the victim close to the target.
+static coord_def random_close_space(actor* victim, actor* target)
+{
+ std::vector<std::pair<coord_def, int> > dests;
+ const coord_def tpos = target->pos();
+
+ // XXX: should use actor::see_cell_no_trans.
+ const los_def* vlos = &victim->get_los_no_trans();
+ const los_def* tlos = &target->get_los_no_trans();
+ for (radius_iterator ri(vlos, true); ri; ++ri)
+ {
+ if (!tlos->see_cell(*ri) || !victim->is_habitable(*ri))
+ continue;
+ int weight = (LOS_RADIUS+1)*(LOS_RADIUS+1) - (tpos - *ri).abs();
+ if (weight < 0)
+ weight = 1;
+ dests.push_back(coord_weight(*ri, weight));
+ }
+ coord_def* choice = random_choose_weighted(dests);
+ return (choice ? *choice : coord_def(0, 0));
+}
+
+void blink_closer(const coord_def &target)
+{
+ actor* caster = actor_at(target);
+ if (!caster)
+ return;
+ coord_def dest = random_close_space(&you, caster);
+ if (dest.origin())
+ return;
+ mpr("You blink.");
+ coord_def origin = you.pos();
+ bool success = move_player_to_grid(dest, false, true, true);
+ if (success)
+ place_cloud(CLOUD_TLOC_ENERGY, origin, 1 + random2(3), KC_YOU);
+}
+
bool random_near_space(const coord_def& origin, coord_def& target,
bool allow_adjacent, bool restrict_los,
bool forbid_dangerous, bool forbid_sanctuary)