/* * File: externs.h * Summary: Fixed size 2D vector class that asserts if you do something bad. * Written by: Linley Henzell */ #ifndef EXTERNS_H #define EXTERNS_H #include #include #include #include #include #include #include #include #include #include "defines.h" #include "enum.h" #include "fixedarray.h" #include "libutil.h" #include "mpr.h" #include "store.h" #ifdef USE_TILE struct tile_flavour { // The floor tile to use. unsigned short floor; // The wall tile to use. unsigned short wall; // Used as a random value or for special cases e.g. (bazaars, gates). unsigned short special; // Used (primarily) by the vault 'TILE' overlay. unsigned short feat; }; // A glorified unsigned int that assists with ref-counting the mcache. class tile_fg_store { public: tile_fg_store() : m_tile(0) {} tile_fg_store(unsigned int tile) : m_tile(tile) {} operator unsigned int() { return m_tile; } unsigned int operator=(unsigned int tile); protected: unsigned int m_tile; }; #endif #define INFO_SIZE 200 // size of message buffers #define ITEMNAME_SIZE 200 // size of item names/shop names/etc #define HIGHSCORE_SIZE 800 // <= 10 Lines for long format scores #define MAX_NUM_GODS 21 #define BURDEN_TO_AUM 0.1f // scale factor for converting burden to aum extern char info[INFO_SIZE]; // defined in acr.cc {dlb} const int kNameLen = 30; #ifdef SHORT_FILE_NAMES const int kFileNameLen = 6; #else const int kFileNameLen = 250; #endif // Used only to bound the init file name length const int kPathLen = 256; // This value is used to mark that the current berserk is free from // penalty (Xom's granted or from a deck of cards). #define NO_BERSERK_PENALTY -1 typedef FixedArray feature_grid; struct item_def; class melee_attack; struct coord_def; class level_id; class player_quiver; class map_marker; class actor; class player; class monster; class KillMaster; class ghost_demon; struct glyph; template inline Z sgn(Z x) { return (x < 0 ? -1 : (x > 0 ? 1 : 0)); } struct coord_def { int x; int y; explicit coord_def( int x_in = 0, int y_in = 0 ) : x(x_in), y(y_in) { } void set(int xi, int yi) { x = xi; y = yi; } void reset() { set(0, 0); } int distance_from(const coord_def &b) const; bool operator == (const coord_def &other) const { return x == other.x && y == other.y; } bool operator != (const coord_def &other) const { return !operator == (other); } bool operator < (const coord_def &other) const { return (x < other.x) || (x == other.x && y < other.y); } bool operator > (const coord_def &other) const { return (x > other.x) || (x == other.x && y > other.y); } const coord_def &operator += (const coord_def &other) { x += other.x; y += other.y; return (*this); } const coord_def &operator += (int offset) { x += offset; y += offset; return (*this); } const coord_def &operator -= (const coord_def &other) { x -= other.x; y -= other.y; return (*this); } const coord_def &operator -= (int offset) { x -= offset; y -= offset; return (*this); } const coord_def &operator /= (int div) { x /= div; y /= div; return (*this); } const coord_def &operator *= (int mul) { x *= mul; y *= mul; return (*this); } coord_def operator + (const coord_def &other) const { coord_def copy = *this; return (copy += other); } coord_def operator + (int other) const { coord_def copy = *this; return (copy += other); } coord_def operator - (const coord_def &other) const { coord_def copy = *this; return (copy -= other); } coord_def operator -() const { return (coord_def(0, 0) - *this); } coord_def operator - (int other) const { coord_def copy = *this; return (copy -= other); } coord_def operator / (int div) const { coord_def copy = *this; return (copy /= div); } coord_def operator * (int mul) const { coord_def copy = *this; return (copy *= mul); } coord_def sgn() const { return coord_def(::sgn(x), ::sgn(y)); } int abs() const { return (x * x + y * y); } int rdist() const { return (std::max(std::abs(x), std::abs(y))); } bool origin() const { return (!x && !y); } bool zero() const { return origin(); } bool equals(const int xi, const int yi) const { return (xi == x && yi == y); } }; typedef bool (*coord_predicate)(const coord_def &c); struct run_check_dir { dungeon_feature_type grid; coord_def delta; }; struct cloud_struct { coord_def pos; cloud_type type; int decay; unsigned char spread_rate; kill_category whose; killer_type killer; int colour; std::string name; std::string tile; cloud_struct() : pos(), type(CLOUD_NONE), decay(0), spread_rate(0), whose(KC_OTHER), killer(KILL_NONE), colour(-1), name(""), tile("") { } void set_whose(kill_category _whose); void set_killer(killer_type _killer); static kill_category killer_to_whose(killer_type killer); static killer_type whose_to_killer(kill_category whose); }; struct shop_struct { coord_def pos; unsigned char greed; shop_type type; unsigned char level; FixedVector keeper_name; }; struct delay_queue_item { delay_type type; int duration; int parm1; int parm2; bool started; }; // Identifies a level. Should never include virtual methods or // dynamically allocated memory (see code to push level_id onto Lua // stack in l_dgn.cc) class level_id { public: branch_type branch; // The branch in which the level is. int depth; // What depth (in this branch - starting from 1) level_area_type level_type; public: // Returns the level_id of the current level. static level_id current(); // Returns the level_id of the level that the stair/portal/whatever at // 'pos' on the current level leads to. static level_id get_next_level_id(const coord_def &pos); level_id() : branch(BRANCH_MAIN_DUNGEON), depth(-1), level_type(LEVEL_DUNGEON) { } level_id(branch_type br, int dep, level_area_type ltype = LEVEL_DUNGEON) : branch(br), depth(dep), level_type(ltype) { } level_id(const level_id &ot) : branch(ot.branch), depth(ot.depth), level_type(ot.level_type) { } level_id(level_area_type ltype) : branch(BRANCH_MAIN_DUNGEON), depth(-1), level_type(ltype) { } static level_id parse_level_id(const std::string &s) throw (std::string); static level_id from_packed_place(const unsigned short place); unsigned short packed_place() const; std::string describe(bool long_name = false, bool with_number = true) const; void clear() { branch = BRANCH_MAIN_DUNGEON; depth = -1; level_type = LEVEL_DUNGEON; } // Returns the absolute depth in the dungeon for the level_id; // non-dungeon branches (specifically Abyss and Pan) will return // depths suitable for use in monster and item generation. If // you're looking for a depth to set you.your_level to, use // dungeon_absdepth(). int absdepth() const; // Returns the absolute depth in the dungeon for the level_id, corresponding // to you.your_level. int dungeon_absdepth() const; bool is_valid() const { return (branch != NUM_BRANCHES && depth != -1) || level_type != LEVEL_DUNGEON; } const level_id &operator = (const level_id &id) { branch = id.branch; depth = id.depth; level_type = id.level_type; return (*this); } bool operator == ( const level_id &id ) const { return (level_type == id.level_type && (level_type != LEVEL_DUNGEON || (branch == id.branch && depth == id.depth))); } bool operator != ( const level_id &id ) const { return !operator == (id); } bool operator <( const level_id &id ) const { if (level_type != id.level_type) return (level_type < id.level_type); if (level_type != LEVEL_DUNGEON) return (false); return (branch < id.branch) || (branch==id.branch && depth < id.depth); } bool operator == ( const branch_type _branch ) const { return (branch == _branch && level_type == LEVEL_DUNGEON); } bool operator != ( const branch_type _branch ) const { return !operator == (_branch); } void save(writer&) const; void load(reader&); }; // A position on a particular level. struct level_pos { level_id id; coord_def pos; // The grid coordinates on this level. level_pos() : id(), pos() { pos.x = pos.y = -1; } level_pos(const level_id &lid, const coord_def &coord) : id(lid), pos(coord) { } level_pos(const level_id &lid) : id(lid), pos() { pos.x = pos.y = -1; } // Returns the level_pos of where the player is standing. static level_pos current(); bool operator == ( const level_pos &lp ) const { return id == lp.id && pos == lp.pos; } bool operator != ( const level_pos &lp ) const { return id != lp.id || pos != lp.pos; } bool operator < ( const level_pos &lp ) const { return (id < lp.id) || (id == lp.id && pos < lp.pos); } bool is_valid() const { return id.depth > -1 && pos.x != -1 && pos.y != -1; } bool is_on( const level_id _id) { return id == _id; } void clear() { id.clear(); pos = coord_def(-1, -1); } void save(writer&) const; void load(reader&); }; class monsters; struct item_def { object_class_type base_type; // basic class (ie OBJ_WEAPON) unsigned char sub_type; // type within that class (ie WPN_DAGGER) short plus; // +to hit, charges, corpse mon id short plus2; // +to dam, sub-sub type for boots/helms long special; // special stuff unsigned char colour; // item colour unsigned long flags; // item status flags short quantity; // number of items coord_def pos; // for inventory items == (-1, -1) short link; // link to next item; for inventory items = slot short slot; // Inventory letter unsigned short orig_place; short orig_monnum; std::string inscription; CrawlHashTable props; public: item_def() : base_type(OBJ_UNASSIGNED), sub_type(0), plus(0), plus2(0), special(0L), colour(0), flags(0L), quantity(0), pos(), link(NON_ITEM), slot(0), orig_place(0), orig_monnum(0), inscription() { } std::string name(description_level_type descrip, bool terse = false, bool ident = false, bool with_inscription = true, bool quantity_in_words = false, unsigned long ignore_flags = 0x0) const; bool has_spells() const; bool cursed() const; int book_number() const; zap_type zap() const; // what kind of beam it shoots (if wand). // Returns index in mitm array. Results are undefined if this item is // not in the array! int index() const; int armour_rating() const; bool launched_by(const item_def &launcher) const; void clear() { *this = item_def(); } // Sets this item as being held by a given monster. void set_holding_monster(int midx); // Returns monster holding this item. NULL if none. monsters* holding_monster() const; // Returns true if a monster is holding this item. bool held_by_monster() const; bool is_valid() const; // Returns true if this item should be preserved as far as possible. bool is_critical() const; // Returns true if this item should not normally be enchanted. bool is_mundane() const; private: std::string name_aux(description_level_type desc, bool terse, bool ident, unsigned long ignore_flags) const; }; class runrest { public: int runmode; int mp; int hp; coord_def pos; FixedVector run_check; // array of grids to check public: runrest(); void initialise(int rdir, int mode); // returns runmode operator int () const; // sets runmode const runrest &operator = (int newrunmode); // Returns true if we're currently resting. bool is_rest() const; bool is_explore() const; bool is_any_travel() const; // Clears run state. void clear(); // Stops running. void stop(); // Take one off the rest counter. void rest(); // Checks if shift-run should be aborted and aborts the run if necessary. // Returns true if you were running and are now no longer running. bool check_stop_running(); private: void set_run_check(int index, int compass_dir); bool run_grids_changed() const; }; class PlaceInfo { public: int level_type; // enum level_area_type int branch; // enum branch_type if LEVEL_DUNGEON; otherwise -1 unsigned long num_visits; unsigned long levels_seen; unsigned long mon_kill_exp; unsigned long mon_kill_exp_avail; unsigned long mon_kill_num[KC_NCATEGORIES]; long turns_total; long turns_explore; long turns_travel; long turns_interlevel; long turns_resting; long turns_other; double elapsed_total; double elapsed_explore; double elapsed_travel; double elapsed_interlevel; double elapsed_resting; double elapsed_other; public: PlaceInfo(); bool is_global() const; void make_global(); void assert_validity() const; const std::string short_name() const; const PlaceInfo &operator += (const PlaceInfo &other); const PlaceInfo &operator -= (const PlaceInfo &other); PlaceInfo operator + (const PlaceInfo &other) const; PlaceInfo operator - (const PlaceInfo &other) const; }; typedef std::vector delay_queue_type; class monster_spells : public FixedVector { public: monster_spells() : FixedVector(SPELL_NO_SPELL) { } void clear() { init(SPELL_NO_SPELL); } }; class reader; class writer; class map_markers { public: map_markers(); map_markers(const map_markers &); map_markers &operator = (const map_markers &); ~map_markers(); void activate_all(bool verbose = true); void add(map_marker *marker); void remove(map_marker *marker); void remove_markers_at(const coord_def &c, map_marker_type type = MAT_ANY); map_marker *find(const coord_def &c, map_marker_type type = MAT_ANY); map_marker *find(map_marker_type type); void move(const coord_def &from, const coord_def &to); void move_marker(map_marker *marker, const coord_def &to); std::vector get_all(map_marker_type type = MAT_ANY); std::vector get_all(const std::string &key, const std::string &val = ""); std::vector get_markers_at(const coord_def &c); std::string property_at(const coord_def &c, map_marker_type type, const std::string &key); void clear(); void write(writer &) const; void read(reader &, int minorVersion); private: typedef std::multimap dgn_marker_map; typedef std::pair dgn_pos_marker; void init_from(const map_markers &); void unlink_marker(const map_marker *); private: dgn_marker_map markers; }; struct message_filter { int channel; // Use -1 to match any channel. text_pattern pattern; // Empty pattern matches any message message_filter( int ch, const std::string &s ) : channel(ch), pattern(s) { } message_filter( const std::string &s ) : channel(-1), pattern(s) { } bool is_filtered( int ch, const std::string &s ) const { bool channel_match = ch == channel || channel == -1; if (!channel_match || pattern.empty()) return channel_match; return pattern.matches(s); } }; struct sound_mapping { text_pattern pattern; std::string soundfile; }; struct colour_mapping { std::string tag; text_pattern pattern; int colour; }; struct message_colour_mapping { message_filter message; int colour; }; class InvEntry; typedef int (*item_sort_fn)(const InvEntry *a, const InvEntry *b); struct item_comparator { item_sort_fn cmpfn; bool negated; item_comparator(item_sort_fn cfn, bool neg = false) : cmpfn(cfn), negated(neg) { } int compare(const InvEntry *a, const InvEntry *b) const { return (negated? -cmpfn(a, b) : cmpfn(a, b)); } }; typedef std::vector item_sort_comparators; struct menu_sort_condition { public: menu_type mtype; int sort; item_sort_comparators cmp; public: menu_sort_condition(menu_type mt = MT_INVLIST, int sort = 0); menu_sort_condition(const std::string &s); bool matches(menu_type mt) const; private: void set_menu_type(std::string &s); void set_sort(std::string &s); void set_comparators(std::string &s); }; struct mon_display { monster_type type; unsigned glyph; unsigned colour; monster_type detected; // What a monster of type "type" is detected as. mon_display(monster_type m = MONS_NO_MONSTER, unsigned gly = 0, unsigned col = 0, monster_type d = MONS_NO_MONSTER) : type(m), glyph(gly), colour(col), detected(d) { } }; #include "msvc.h" #endif // EXTERNS_H