00001
00002
00003
00004
00005
00006 #ifndef TRAVEL_H
00007 #define TRAVEL_H
00008
00009 #include "externs.h"
00010 #include "exclude.h"
00011 #include "map_knowledge.h"
00012
00013
00014 #include "travel_defs.h"
00015
00016 #include <stdio.h>
00017 #include <string>
00018 #include <vector>
00019 #include <map>
00020
00021 class reader;
00022 class writer;
00023
00024 enum run_check_type
00025 {
00026 RCHECK_LEFT,
00027 RCHECK_FRONT,
00028 RCHECK_RIGHT,
00029 };
00030
00031 enum run_dir_type
00032 {
00033 RDIR_UP = 0,
00034 RDIR_UP_RIGHT,
00035 RDIR_RIGHT,
00036 RDIR_DOWN_RIGHT,
00037 RDIR_DOWN,
00038 RDIR_DOWN_LEFT,
00039 RDIR_LEFT,
00040 RDIR_UP_LEFT,
00041 RDIR_REST,
00042 };
00043
00044 enum run_mode_type
00045 {
00046 RMODE_INTERLEVEL = -4,
00047 RMODE_EXPLORE_GREEDY = -3,
00048 RMODE_EXPLORE = -2,
00049 RMODE_TRAVEL = -1,
00050 RMODE_NOT_RUNNING = 0,
00051 RMODE_CONTINUE,
00052 RMODE_START,
00053 RMODE_REST_DURATION = 100,
00054 };
00055
00056
00057
00058
00059 void initialise_travel();
00060 void init_travel_terrain_check(bool check_race_equip = true);
00061 void stop_running(void);
00062 void travel_init_load_level();
00063 void travel_init_new_level();
00064
00065 uint8_t is_waypoint(const coord_def &p);
00066 command_type direction_to_command(int x, int y);
00067 bool is_resting(void);
00068 void explore_pickup_event(int did_pickup, int tried_pickup);
00069 bool feat_is_traversable(dungeon_feature_type feat);
00070 bool is_unknown_stair(const coord_def &p);
00071
00072 void find_travel_pos(const coord_def& youpos, int *move_x, int *move_y,
00073 std::vector<coord_def>* coords = NULL);
00074
00075 bool is_travelsafe_square(const coord_def& c, bool ignore_hostile = false);
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 void start_explore(bool grab_items = false);
00086 void do_explore_cmd();
00087
00088 struct level_pos;
00089 class level_id;
00090 struct travel_target;
00091
00092 level_id find_up_level(level_id curr, bool up_branch = false);
00093 level_id find_down_level(level_id curr);
00094
00095 void start_translevel_travel_prompt();
00096 void start_translevel_travel(const travel_target &pos);
00097
00098 void start_travel(const coord_def& p);
00099
00100 command_type travel();
00101
00102 int travel_direction(uint8_t branch, int subdungeondepth);
00103
00104 void prevent_travel_to(const std::string &dungeon_feature_name);
00105
00106
00107 void arrange_features(std::vector<coord_def> &features);
00108 int level_distance(level_id first, level_id second);
00109 level_id find_deepest_explored(level_id curr);
00110
00111 bool can_travel_to(const level_id &lid);
00112 bool can_travel_interlevel();
00113 bool prompt_stop_explore(int es_why);
00114
00115 bool travel_kill_monster(const monster* mons);
00116
00117 enum translevel_prompt_flags
00118 {
00119 TPF_NO_FLAGS = 0,
00120
00121 TPF_ALLOW_WAYPOINTS = 0x1,
00122 TPF_ALLOW_UPDOWN = 0x2,
00123 TPF_REMEMBER_TARGET = 0x4,
00124 TPF_SHOW_ALL_BRANCHES = 0x8,
00125
00126 TPF_DEFAULT_OPTIONS = TPF_ALLOW_WAYPOINTS | TPF_ALLOW_UPDOWN
00127 | TPF_REMEMBER_TARGET,
00128 };
00129
00130 travel_target prompt_translevel_target(int prompt_flags,
00131 std::string& dest_name);
00132
00133
00134
00135
00136 const int PD_TRAP = -42;
00137
00138
00139 const int PD_EXCLUDED = -20099;
00140
00141
00142 const int PD_EXCLUDED_RADIUS = -20100;
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 extern travel_distance_grid_t travel_point_distance;
00153
00154 enum explore_stop_type
00155 {
00156 ES_NONE = 0x0000,
00157
00158
00159 ES_ITEM = 0x0001,
00160
00161
00162
00163 ES_GREEDY_PICKUP = 0x0002,
00164
00165
00166 ES_GREEDY_PICKUP_GOLD = 0x0004,
00167
00168
00169
00170
00171
00172 ES_GREEDY_PICKUP_SMART = 0x0008,
00173
00174
00175 ES_GREEDY_PICKUP_THROWN = 0x0010,
00176 ES_GREEDY_PICKUP_MASK = (ES_GREEDY_PICKUP
00177 | ES_GREEDY_PICKUP_GOLD
00178 | ES_GREEDY_PICKUP_SMART
00179 | ES_GREEDY_PICKUP_THROWN),
00180
00181
00182 ES_GREEDY_ITEM = 0x0020,
00183
00184
00185
00186
00187 ES_GREEDY_VISITED_ITEM_STACK = 0x0040,
00188
00189
00190
00191 ES_STAIR = 0x0080,
00192 ES_SHOP = 0x0100,
00193 ES_ALTAR = 0x0200,
00194 ES_PORTAL = 0x0400,
00195 ES_GLOWING_ITEM = 0x0800,
00196 ES_ARTEFACT = 0x1000,
00197 ES_RUNE = 0x2000,
00198 };
00199
00201
00202
00203 struct travel_target
00204 {
00205 level_pos p;
00206 bool entrance_only;
00207
00208 travel_target(const level_pos &_pos, bool entry = false)
00209 : p(_pos), entrance_only(entry)
00210 {
00211 }
00212 travel_target()
00213 : p(), entrance_only(false)
00214 {
00215 }
00216 void clear()
00217 {
00218 p.clear();
00219 entrance_only = false;
00220 }
00221 bool operator == (const travel_target &other) const
00222 {
00223 return p == other.p && entrance_only == other.entrance_only;
00224 }
00225 bool operator != (const travel_target &other) const
00226 {
00227 return !operator == (other);
00228 }
00229 };
00230
00231
00232 class LevelStashes;
00233 class explore_discoveries
00234 {
00235 public:
00236 explore_discoveries();
00237
00238 void found_feature(const coord_def &pos, dungeon_feature_type grid);
00239 void found_item(const coord_def &pos, const item_def &item);
00240
00241
00242 bool prompt_stop() const;
00243
00244 private:
00245 template <class Z> struct named_thing {
00246 std::string name;
00247 Z thing;
00248
00249 named_thing(const std::string &n, Z t) : name(n), thing(t) { }
00250 operator std::string () const { return name; }
00251
00252 bool operator == (const named_thing<Z> &other) const
00253 {
00254 return (name == other.name);
00255 }
00256 };
00257
00258 bool can_autopickup;
00259 int es_flags;
00260 const LevelStashes *current_level;
00261 std::vector< named_thing<item_def> > items;
00262 std::vector< named_thing<int> > stairs;
00263 std::vector< named_thing<int> > portals;
00264 std::vector< named_thing<int> > shops;
00265 std::vector< named_thing<int> > altars;
00266
00267 std::vector<std::string> marker_msgs;
00268 std::vector<std::string> marked_feats;
00269
00270 private:
00271 template <class C> void say_any(const C &coll, const char *stub) const;
00272 template <class citer> bool has_duplicates(citer, citer) const;
00273
00274 std::string cleaned_feature_description(const coord_def &) const;
00275 void add_item(const item_def &item);
00276 void add_stair(const named_thing<int> &stair);
00277 std::vector<std::string> apply_quantities(
00278 const std::vector< named_thing<int> > &v) const;
00279 bool merge_feature(
00280 std::vector< named_thing<int> > &v,
00281 const named_thing<int> &feat) const;
00282 };
00283
00284 struct stair_info
00285 {
00286 public:
00287 enum stair_type
00288 {
00289 PHYSICAL,
00290 PLACEHOLDER,
00291 };
00292
00293 public:
00294 coord_def position;
00295 dungeon_feature_type grid;
00296 level_pos destination;
00297
00298 int distance;
00299 bool guessed_pos;
00300
00301 stair_type type;
00302
00303 stair_info()
00304 : position(-1, -1), grid(DNGN_FLOOR), destination(),
00305 distance(-1), guessed_pos(true), type(PHYSICAL)
00306 {
00307 }
00308
00309 void clear_distance() { distance = -1; }
00310
00311 void save(writer&) const;
00312 void load(reader&);
00313
00314 std::string describe() const;
00315
00316 bool can_travel() const { return (type == PHYSICAL); }
00317 };
00318
00319
00320 struct LevelInfo
00321 {
00322 LevelInfo() : stairs(), excludes(), stair_distances(), id()
00323 {
00324 da_counters.init(0);
00325 }
00326
00327 void save(writer&) const;
00328 void load(reader&, int minorVersion);
00329
00330 std::vector<stair_info> &get_stairs()
00331 {
00332 return stairs;
00333 }
00334
00335 stair_info *get_stair(int x, int y);
00336 stair_info *get_stair(const coord_def &pos);
00337 bool empty() const;
00338 bool know_stair(const coord_def &pos) const;
00339 int get_stair_index(const coord_def &pos) const;
00340
00341 void clear_distances();
00342 void set_level_excludes();
00343
00344 const exclude_set &get_excludes() const
00345 {
00346 return excludes;
00347 }
00348
00349
00350
00351 int distance_between(const stair_info *s1, const stair_info *s2) const;
00352
00353 void update_excludes();
00354 void update();
00355
00356
00357
00358 void update_stair(const coord_def& stairpos, const level_pos &p,
00359 bool guess = false);
00360
00361
00362 void clear_stairs(dungeon_feature_type grid);
00363
00364
00365
00366 bool is_known_branch(uint8_t branch) const;
00367
00368 FixedVector<int, NUM_DA_COUNTERS> da_counters;
00369
00370 private:
00371
00372
00373 static void get_stairs(std::vector<coord_def> &stairs);
00374
00375 void correct_stair_list(const std::vector<coord_def> &s);
00376 void update_stair_distances();
00377 void sync_all_branch_stairs();
00378 void sync_branch_stairs(const stair_info *si);
00379 void set_distance_between_stairs(int a, int b, int dist);
00380 void fixup();
00381
00382 private:
00383 std::vector<stair_info> stairs;
00384
00385
00386 exclude_set excludes;
00387
00388 std::vector<short> stair_distances;
00389 level_id id;
00390
00391 friend class TravelCache;
00392
00393 private:
00394 void create_placeholder_stair(const coord_def &, const level_pos &);
00395 void resize_stair_distances();
00396 };
00397
00398 const int TRAVEL_WAYPOINT_COUNT = 10;
00399
00400 class TravelCache
00401 {
00402 public:
00403 void clear_distances();
00404
00405 LevelInfo& get_level_info(const level_id &lev)
00406 {
00407 LevelInfo &li = levels[lev];
00408 li.id = lev;
00409 return li;
00410 }
00411
00412 LevelInfo *find_level_info(const level_id &lev)
00413 {
00414 std::map<level_id, LevelInfo>::iterator i = levels.find(lev);
00415 return (i != levels.end()? &i->second : NULL);
00416 }
00417
00418 void erase_level_info(const level_id& lev)
00419 {
00420 levels.erase(lev);
00421 }
00422
00423 bool know_stair(const coord_def &c) const;
00424 bool know_level(const level_id &lev) const
00425 {
00426 return levels.find(lev) != levels.end();
00427 }
00428 std::vector<level_id> known_levels() const;
00429
00430 const level_pos &get_waypoint(int number) const
00431 {
00432 return waypoints[number];
00433 }
00434
00435 int get_waypoint_count() const;
00436
00437 void set_level_excludes();
00438
00439 void add_waypoint(int x = -1, int y = -1);
00440 void delete_waypoint();
00441 uint8_t is_waypoint(const level_pos &lp) const;
00442 void list_waypoints() const;
00443 void update_waypoints() const;
00444
00445 void update_excludes();
00446 void update();
00447
00448 void save(writer&) const;
00449 void load(reader&, int minorVersion);
00450
00451 bool is_known_branch(uint8_t branch) const;
00452
00453 void update_da_counters();
00454
00455 unsigned int query_da_counter(daction_type c);
00456 void clear_da_counter(daction_type c);
00457
00458 private:
00459 void fixup_levels();
00460
00461 private:
00462 typedef std::map<level_id, LevelInfo> travel_levels_map;
00463 travel_levels_map levels;
00464 level_pos waypoints[TRAVEL_WAYPOINT_COUNT];
00465 };
00466
00467
00468
00469
00470
00471 class travel_pathfind
00472 {
00473 public:
00474 travel_pathfind();
00475 virtual ~travel_pathfind();
00476
00477
00478 coord_def pathfind(run_mode_type rt);
00479
00480
00481 void set_floodseed(const coord_def &seed, bool double_flood = false);
00482
00483
00484
00485 void set_src_dst(const coord_def &src, const coord_def &dst);
00486
00487
00488
00489 void set_annotate_map(bool annotate);
00490
00491
00492 void set_distance_grid(travel_distance_grid_t distgrid);
00493
00494
00495 void set_feature_vector(std::vector<coord_def> *features);
00496
00497
00498 void get_features();
00499
00500
00501
00502 const coord_def travel_move() const;
00503
00504
00505
00506 const coord_def explore_target() const;
00507
00508
00509
00510 const coord_def greedy_square() const;
00511
00512
00513
00514
00515 const coord_def unexplored_square() const;
00516
00517 protected:
00518 bool is_greed_inducing_square(const coord_def &c) const;
00519 bool path_examine_point(const coord_def &c);
00520 virtual bool point_traverse_delay(const coord_def &c);
00521 virtual bool path_flood(const coord_def &c, const coord_def &dc);
00522 bool square_slows_movement(const coord_def &c);
00523 void check_square_greed(const coord_def &c);
00524 void good_square(const coord_def &c);
00525
00526 protected:
00527 static const int UNFOUND_DIST = -30000;
00528 static const int INFINITE_DIST = INFINITE_DISTANCE;
00529
00530 protected:
00531 run_mode_type runmode;
00532
00533
00534
00535 coord_def start, dest;
00536
00537
00538
00539
00540 coord_def next_travel_move;
00541
00542
00543 bool floodout, double_flood;
00544
00545
00546
00547 bool ignore_hostile;
00548
00549
00550
00551 bool annotate_map;
00552
00553
00554
00555 const LevelStashes *ls;
00556
00557
00558 bool need_for_greed;
00559
00560
00561 coord_def unexplored_place, greedy_place;
00562
00563
00564 int unexplored_dist, greedy_dist;
00565
00566 const int *refdist;
00567
00568
00569
00570 std::vector<coord_def> reseed_points;
00571
00572 std::vector<coord_def> *features;
00573
00574 travel_distance_col *point_distance;
00575
00576
00577
00578 int points;
00579
00580
00581 int next_iter_points;
00582
00583
00584
00585 int traveled_distance;
00586
00587
00588 int circ_index;
00589
00590
00591
00592 static FixedVector<coord_def, GXM * GYM> circumference[2];
00593 };
00594
00595 extern TravelCache travel_cache;
00596
00597 void do_interlevel_travel();
00598
00599
00600
00601 int click_travel(const coord_def &gc, bool force);
00602
00603 bool check_for_interesting_features();
00604
00605 #endif // TRAVEL_H