00001
00002
00003
00004
00005
00006
00007 #ifndef EXTERNS_H
00008 #define EXTERNS_H
00009
00010 #include <vector>
00011 #include <list>
00012 #include <string>
00013 #include <map>
00014 #include <set>
00015 #include <memory>
00016 #include <cstdlib>
00017 #include <deque>
00018
00019 #include <time.h>
00020 #include <stdint.h>
00021 #define __STDC_FORMAT_MACROS
00022 #include <inttypes.h>
00023
00024 #include "defines.h"
00025 #include "enum.h"
00026 #include "fixedarray.h"
00027 #include "mpr.h"
00028 #include "pattern.h"
00029 #include "store.h"
00030
00031 #ifdef USE_TILE
00032
00033 #include "tiledef_defines.h"
00034
00035 struct tile_flavour
00036 {
00037 unsigned short floor_idx;
00038 unsigned short wall_idx;
00039 unsigned short feat_idx;
00040
00041 unsigned short floor;
00042 unsigned short wall;
00043
00044 unsigned short feat;
00045
00046
00047 unsigned short special;
00048 };
00049
00050
00051 class tile_fg_store
00052 {
00053 public:
00054 tile_fg_store() : m_tile(0) {}
00055 tile_fg_store(tileidx_t tile) : m_tile(tile) {}
00056 operator tileidx_t() { return m_tile; }
00057 tileidx_t operator=(tileidx_t tile);
00058 protected:
00059 tileidx_t m_tile;
00060 };
00061
00062
00063 #endif
00064
00065 #define INFO_SIZE 200 // size of message buffers
00066 #define ITEMNAME_SIZE 200 // size of item names/shop names/etc
00067 #define HIGHSCORE_SIZE 800 // <= 10 Lines for long format scores
00068
00069 #define MAX_NUM_GODS 21
00070
00071 #define BURDEN_TO_AUM 0.1f // scale factor for converting burden to aum
00072
00073 extern char info[INFO_SIZE];
00074
00075 #define kNameLen 30
00076 #ifdef SHORT_FILE_NAMES
00077 const int kFileNameLen = 6;
00078 #else
00079 const int kFileNameLen = 250;
00080 #endif
00081
00082
00083 const int kPathLen = 256;
00084
00085
00086
00087 #define NO_BERSERK_PENALTY -1
00088
00089 typedef FixedArray<dungeon_feature_type, GXM, GYM> feature_grid;
00090 typedef FixedArray<unsigned short, GXM, GYM> map_mask;
00091
00092 struct item_def;
00093 struct coord_def;
00094 class level_id;
00095 class player_quiver;
00096 class map_marker;
00097 class actor;
00098 class player;
00099 class monster;
00100 class KillMaster;
00101 class ghost_demon;
00102 struct glyph;
00103
00104 template <typename Z> inline Z sgn(Z x)
00105 {
00106 return (x < 0 ? -1 : (x > 0 ? 1 : 0));
00107 }
00108
00109 inline int dist_range(int x) { return x*x + 1; };
00110
00111 struct coord_def
00112 {
00113 int x;
00114 int y;
00115
00116 explicit coord_def(int x_in = 0, int y_in = 0) : x(x_in), y(y_in) { }
00117
00118 void set(int xi, int yi)
00119 {
00120 x = xi;
00121 y = yi;
00122 }
00123
00124 void reset()
00125 {
00126 set(0, 0);
00127 }
00128
00129 int distance_from(const coord_def &b) const;
00130
00131 bool operator == (const coord_def &other) const
00132 {
00133 return x == other.x && y == other.y;
00134 }
00135
00136 bool operator != (const coord_def &other) const
00137 {
00138 return !operator == (other);
00139 }
00140
00141 bool operator < (const coord_def &other) const
00142 {
00143 return (x < other.x) || (x == other.x && y < other.y);
00144 }
00145
00146 bool operator > (const coord_def &other) const
00147 {
00148 return (x > other.x) || (x == other.x && y > other.y);
00149 }
00150
00151 const coord_def &operator += (const coord_def &other)
00152 {
00153 x += other.x;
00154 y += other.y;
00155 return (*this);
00156 }
00157
00158 const coord_def &operator += (int offset)
00159 {
00160 x += offset;
00161 y += offset;
00162 return (*this);
00163 }
00164
00165 const coord_def &operator -= (const coord_def &other)
00166 {
00167 x -= other.x;
00168 y -= other.y;
00169 return (*this);
00170 }
00171
00172 const coord_def &operator -= (int offset)
00173 {
00174 x -= offset;
00175 y -= offset;
00176 return (*this);
00177 }
00178
00179 const coord_def &operator /= (int div)
00180 {
00181 x /= div;
00182 y /= div;
00183 return (*this);
00184 }
00185
00186 const coord_def &operator *= (int mul)
00187 {
00188 x *= mul;
00189 y *= mul;
00190 return (*this);
00191 }
00192
00193 coord_def operator + (const coord_def &other) const
00194 {
00195 coord_def copy = *this;
00196 return (copy += other);
00197 }
00198
00199 coord_def operator + (int other) const
00200 {
00201 coord_def copy = *this;
00202 return (copy += other);
00203 }
00204
00205 coord_def operator - (const coord_def &other) const
00206 {
00207 coord_def copy = *this;
00208 return (copy -= other);
00209 }
00210
00211 coord_def operator -() const
00212 {
00213 return (coord_def(0, 0) - *this);
00214 }
00215
00216 coord_def operator - (int other) const
00217 {
00218 coord_def copy = *this;
00219 return (copy -= other);
00220 }
00221
00222 coord_def operator / (int div) const
00223 {
00224 coord_def copy = *this;
00225 return (copy /= div);
00226 }
00227
00228 coord_def operator * (int mul) const
00229 {
00230 coord_def copy = *this;
00231 return (copy *= mul);
00232 }
00233
00234 coord_def sgn() const
00235 {
00236 return coord_def(::sgn(x), ::sgn(y));
00237 }
00238
00239 int abs() const
00240 {
00241 return (x * x + y * y);
00242 }
00243
00244 int rdist() const
00245 {
00246 return (std::max(std::abs(x), std::abs(y)));
00247 }
00248
00249 bool origin() const
00250 {
00251 return (!x && !y);
00252 }
00253
00254 bool zero() const
00255 {
00256 return origin();
00257 }
00258
00259 bool equals(const int xi, const int yi) const
00260 {
00261 return (xi == x && yi == y);
00262 }
00263 };
00264 const coord_def INVALID_COORD(-1, -1);
00265
00266 typedef bool (*coord_predicate)(const coord_def &c);
00267
00268 struct run_check_dir
00269 {
00270 dungeon_feature_type grid;
00271 coord_def delta;
00272 };
00273
00274 typedef uint32_t mid_t;
00275 #define MID_PLAYER ((mid_t)0xffffffff)
00276
00277
00278 #define MID_ANON_FRIEND ((mid_t)0xffff0000)
00279
00280 struct cloud_struct
00281 {
00282 coord_def pos;
00283 cloud_type type;
00284 int decay;
00285 uint8_t spread_rate;
00286 kill_category whose;
00287 killer_type killer;
00288 mid_t source;
00289 int colour;
00290 std::string name;
00291 std::string tile;
00292
00293 cloud_struct() : pos(), type(CLOUD_NONE), decay(0), spread_rate(0),
00294 whose(KC_OTHER), killer(KILL_NONE), colour(-1),
00295 name(""), tile("")
00296 {
00297 }
00298
00299 bool defined() const { return type != CLOUD_NONE; }
00300
00301 void set_whose(kill_category _whose);
00302 void set_killer(killer_type _killer);
00303
00304 std::string cloud_name(const std::string &default_name = "",
00305 bool terse = false) const;
00306 void announce_actor_engulfed(const actor *engulfee,
00307 bool beneficial = false) const;
00308
00309 static kill_category killer_to_whose(killer_type killer);
00310 static killer_type whose_to_killer(kill_category whose);
00311 };
00312
00313 struct shop_struct
00314 {
00315 coord_def pos;
00316 uint8_t greed;
00317 shop_type type;
00318 uint8_t level;
00319
00320 FixedVector<uint8_t, 3> keeper_name;
00321
00322 bool defined() const { return type != SHOP_UNASSIGNED; }
00323 };
00324
00325
00326 struct delay_queue_item
00327 {
00328 delay_type type;
00329 int duration;
00330 int parm1;
00331 int parm2;
00332 bool started;
00333 };
00334
00335
00336
00337
00338
00339 class level_id
00340 {
00341 public:
00342 branch_type branch;
00343 int depth;
00344 level_area_type level_type;
00345
00346 public:
00347
00348 static level_id current();
00349
00350
00351
00352 static level_id get_next_level_id(const coord_def &pos);
00353
00354 level_id()
00355 : branch(BRANCH_MAIN_DUNGEON), depth(-1),
00356 level_type(LEVEL_DUNGEON)
00357 {
00358 }
00359 level_id(branch_type br, int dep, level_area_type ltype = LEVEL_DUNGEON)
00360 : branch(br), depth(dep), level_type(ltype)
00361 {
00362 }
00363 level_id(const level_id &ot)
00364 : branch(ot.branch), depth(ot.depth), level_type(ot.level_type)
00365 {
00366 }
00367 level_id(level_area_type ltype)
00368 : branch(BRANCH_MAIN_DUNGEON), depth(-1), level_type(ltype)
00369 {
00370 }
00371
00372 static level_id parse_level_id(const std::string &s) throw (std::string);
00373 static level_id from_packed_place(const unsigned short place);
00374
00375 unsigned short packed_place() const;
00376 std::string describe(bool long_name = false, bool with_number = true) const;
00377
00378 void clear()
00379 {
00380 branch = BRANCH_MAIN_DUNGEON;
00381 depth = -1;
00382 level_type = LEVEL_DUNGEON;
00383 }
00384
00385
00386
00387
00388
00389
00390 int absdepth() const;
00391
00392
00393
00394 int dungeon_absdepth() const;
00395
00396 bool is_valid() const
00397 {
00398 return (branch != NUM_BRANCHES && depth != -1)
00399 || level_type != LEVEL_DUNGEON;
00400 }
00401
00402 const level_id &operator = (const level_id &id)
00403 {
00404 branch = id.branch;
00405 depth = id.depth;
00406 level_type = id.level_type;
00407 return (*this);
00408 }
00409
00410 bool operator == (const level_id &id) const
00411 {
00412 return (level_type == id.level_type
00413 && (level_type != LEVEL_DUNGEON
00414 || (branch == id.branch && depth == id.depth)));
00415 }
00416
00417 bool operator != (const level_id &id) const
00418 {
00419 return !operator == (id);
00420 }
00421
00422 bool operator <(const level_id &id) const
00423 {
00424 if (level_type != id.level_type)
00425 return (level_type < id.level_type);
00426
00427 if (level_type != LEVEL_DUNGEON)
00428 return (false);
00429
00430 return (branch < id.branch) || (branch==id.branch && depth < id.depth);
00431 }
00432
00433 bool operator == (const branch_type _branch) const
00434 {
00435 return (branch == _branch && level_type == LEVEL_DUNGEON);
00436 }
00437
00438 bool operator != (const branch_type _branch) const
00439 {
00440 return !operator == (_branch);
00441 }
00442
00443 void save(writer&) const;
00444 void load(reader&);
00445 };
00446
00447
00448 struct level_pos
00449 {
00450 level_id id;
00451 coord_def pos;
00452
00453 level_pos() : id(), pos()
00454 {
00455 pos.x = pos.y = -1;
00456 }
00457
00458 level_pos(const level_id &lid, const coord_def &coord)
00459 : id(lid), pos(coord)
00460 {
00461 }
00462
00463 level_pos(const level_id &lid)
00464 : id(lid), pos()
00465 {
00466 pos.x = pos.y = -1;
00467 }
00468
00469
00470 static level_pos current();
00471
00472 bool operator == (const level_pos &lp) const
00473 {
00474 return id == lp.id && pos == lp.pos;
00475 }
00476
00477 bool operator != (const level_pos &lp) const
00478 {
00479 return id != lp.id || pos != lp.pos;
00480 }
00481
00482 bool operator < (const level_pos &lp) const
00483 {
00484 return (id < lp.id) || (id == lp.id && pos < lp.pos);
00485 }
00486
00487 bool is_valid() const
00488 {
00489 return id.depth > -1 && pos.x != -1 && pos.y != -1;
00490 }
00491
00492 bool is_on(const level_id _id)
00493 {
00494 return id == _id;
00495 }
00496
00497 void clear()
00498 {
00499 id.clear();
00500 pos = coord_def(-1, -1);
00501 }
00502
00503 void save(writer&) const;
00504 void load(reader&);
00505 };
00506
00507 class monster;
00508
00509
00510
00511
00512
00513 typedef uint32_t iflags_t;
00514
00515 struct item_def
00516 {
00517 object_class_type base_type:8;
00518 uint8_t sub_type;
00519 short plus;
00520 short plus2;
00521 int special;
00522 uint8_t colour;
00523 uint8_t rnd;
00524 short quantity;
00525 iflags_t flags;
00526
00527 coord_def pos;
00528 short link;
00529 short slot;
00530
00531 unsigned short orig_place;
00532 short orig_monnum;
00533
00534 std::string inscription;
00535
00536 CrawlHashTable props;
00537
00538 public:
00539 item_def() : base_type(OBJ_UNASSIGNED), sub_type(0), plus(0), plus2(0),
00540 special(0L), colour(0), rnd(0), quantity(0), flags(0L),
00541 pos(), link(NON_ITEM), slot(0), orig_place(0),
00542 orig_monnum(0), inscription()
00543 {
00544 }
00545
00546 std::string name(description_level_type descrip,
00547 bool terse = false, bool ident = false,
00548 bool with_inscription = true,
00549 bool quantity_in_words = false,
00550 iflags_t ignore_flags = 0x0) const;
00551 bool has_spells() const;
00552 bool cursed() const;
00553 int book_number() const;
00554 zap_type zap() const;
00555
00556
00557
00558 int index() const;
00559
00560 int armour_rating() const;
00561
00562 bool launched_by(const item_def &launcher) const;
00563
00564 void clear()
00565 {
00566 *this = item_def();
00567 }
00568
00569
00570 void set_holding_monster(int midx);
00571
00572
00573 monster* holding_monster() const;
00574
00575
00576 bool held_by_monster() const;
00577
00578 bool defined() const;
00579 bool is_valid() const;
00580
00581
00582 bool is_critical() const;
00583
00584
00585 bool is_mundane() const;
00586
00587 private:
00588 std::string name_aux(description_level_type desc,
00589 bool terse, bool ident, bool with_inscription,
00590 iflags_t ignore_flags) const;
00591 };
00592
00593 typedef item_def item_info;
00594 item_info get_item_info(const item_def& info);
00595
00596 class runrest
00597 {
00598 public:
00599 int runmode;
00600 int mp;
00601 int hp;
00602 coord_def pos;
00603
00604 FixedVector<run_check_dir,3> run_check;
00605
00606 public:
00607 runrest();
00608 void initialise(int rdir, int mode);
00609
00610
00611 operator int () const;
00612
00613
00614 const runrest &operator = (int newrunmode);
00615
00616
00617 bool is_rest() const;
00618 bool is_explore() const;
00619 bool is_any_travel() const;
00620
00621 std::string runmode_name() const;
00622
00623
00624 void clear();
00625
00626
00627 void stop();
00628
00629
00630 void rest();
00631
00632
00633
00634 bool check_stop_running();
00635
00636 private:
00637 void set_run_check(int index, int compass_dir);
00638 bool run_should_stop() const;
00639 };
00640
00641 typedef std::vector<delay_queue_item> delay_queue_type;
00642
00643 class monster_spells : public FixedVector<spell_type, NUM_MONSTER_SPELL_SLOTS>
00644 {
00645 public:
00646 monster_spells()
00647 : FixedVector<spell_type, NUM_MONSTER_SPELL_SLOTS>(SPELL_NO_SPELL)
00648 { }
00649 void clear() { init(SPELL_NO_SPELL); }
00650 };
00651
00652 class reader;
00653 class writer;
00654 class map_markers
00655 {
00656 public:
00657 map_markers();
00658 map_markers(const map_markers &);
00659 map_markers &operator = (const map_markers &);
00660 ~map_markers();
00661
00662 bool need_activate() const { return have_inactive_markers; }
00663 void clear_need_activate();
00664 void activate_all(bool verbose = true);
00665 void activate_markers_at(coord_def p);
00666 void add(map_marker *marker);
00667 void remove(map_marker *marker);
00668 void remove_markers_at(const coord_def &c, map_marker_type type = MAT_ANY);
00669 map_marker *find(const coord_def &c, map_marker_type type = MAT_ANY);
00670 map_marker *find(map_marker_type type);
00671 void move(const coord_def &from, const coord_def &to);
00672 void move_marker(map_marker *marker, const coord_def &to);
00673 std::vector<map_marker*> get_all(map_marker_type type = MAT_ANY);
00674 std::vector<map_marker*> get_all(const std::string &key,
00675 const std::string &val = "");
00676 std::vector<map_marker*> get_markers_at(const coord_def &c);
00677 std::string property_at(const coord_def &c, map_marker_type type,
00678 const std::string &key);
00679 void clear();
00680
00681 void write(writer &) const;
00682 void read(reader &);
00683
00684 private:
00685 typedef std::multimap<coord_def, map_marker *> dgn_marker_map;
00686 typedef std::pair<coord_def, map_marker *> dgn_pos_marker;
00687
00688 void init_from(const map_markers &);
00689 void unlink_marker(const map_marker *);
00690 void check_empty();
00691
00692 private:
00693 dgn_marker_map markers;
00694 bool have_inactive_markers;
00695 };
00696
00697 struct message_filter
00698 {
00699 int channel;
00700 text_pattern pattern;
00701
00702 message_filter(int ch, const std::string &s)
00703 : channel(ch), pattern(s)
00704 {
00705 }
00706
00707 message_filter(const std::string &s) : channel(-1), pattern(s) { }
00708
00709 bool is_filtered(int ch, const std::string &s) const {
00710 bool channel_match = ch == channel || channel == -1;
00711 if (!channel_match || pattern.empty())
00712 return channel_match;
00713 return pattern.matches(s);
00714 }
00715
00716 };
00717
00718 struct sound_mapping
00719 {
00720 text_pattern pattern;
00721 std::string soundfile;
00722 };
00723
00724 struct colour_mapping
00725 {
00726 std::string tag;
00727 text_pattern pattern;
00728 int colour;
00729 };
00730
00731 struct message_colour_mapping
00732 {
00733 message_filter message;
00734 msg_colour_type colour;
00735 };
00736
00737 class InvEntry;
00738 typedef int (*item_sort_fn)(const InvEntry *a, const InvEntry *b);
00739 struct item_comparator
00740 {
00741 item_sort_fn cmpfn;
00742 bool negated;
00743
00744 item_comparator(item_sort_fn cfn, bool neg = false)
00745 : cmpfn(cfn), negated(neg)
00746 {
00747 }
00748 int compare(const InvEntry *a, const InvEntry *b) const
00749 {
00750 return (negated? -cmpfn(a, b) : cmpfn(a, b));
00751 }
00752 };
00753 typedef std::vector<item_comparator> item_sort_comparators;
00754
00755 struct menu_sort_condition
00756 {
00757 public:
00758 menu_type mtype;
00759 int sort;
00760 item_sort_comparators cmp;
00761
00762 public:
00763 menu_sort_condition(menu_type mt = MT_INVLIST, int sort = 0);
00764 menu_sort_condition(const std::string &s);
00765
00766 bool matches(menu_type mt) const;
00767
00768 private:
00769 void set_menu_type(std::string &s);
00770 void set_sort(std::string &s);
00771 void set_comparators(std::string &s);
00772 };
00773
00774 struct mon_display
00775 {
00776 monster_type type;
00777 wchar_t glyph;
00778 unsigned colour;
00779 monster_type detected;
00780
00781 mon_display(monster_type m = MONS_NO_MONSTER,
00782 unsigned gly = 0, unsigned col = 0,
00783 monster_type d = MONS_NO_MONSTER)
00784 : type(m), glyph(gly), colour(col), detected(d) { }
00785 };
00786
00787 struct final_effect
00788 {
00789 final_effect_flavour flavour;
00790 short att, def;
00791 coord_def pos;
00792 int x;
00793 };
00794
00795 #endif // EXTERNS_H