3 * Summary: Fixed size 2D vector class that asserts if you do something bad.
4 * Written by: Linley Henzell
21 #define __STDC_FORMAT_MACROS
26 #include "fixedarray.h"
33 #include "tiledef_defines.h"
37 unsigned short floor_idx
;
38 unsigned short wall_idx
;
39 unsigned short feat_idx
;
43 // Used (primarily) by the vault 'TILE' overlay.
46 // Used as a random value or for special cases e.g. (bazaars, gates).
47 unsigned short special
;
50 // A glorified unsigned int that assists with ref-counting the mcache.
54 tile_fg_store() : m_tile(0) {}
55 tile_fg_store(tileidx_t tile
) : m_tile(tile
) {}
56 operator tileidx_t() { return m_tile
; }
57 tileidx_t
operator=(tileidx_t tile
);
65 #define INFO_SIZE 200 // size of message buffers
66 #define ITEMNAME_SIZE 200 // size of item names/shop names/etc
67 #define HIGHSCORE_SIZE 800 // <= 10 Lines for long format scores
69 #define MAX_NUM_GODS 21
71 #define BURDEN_TO_AUM 0.1f // scale factor for converting burden to aum
73 extern char info
[INFO_SIZE
]; // defined in main.cc {dlb}
76 #ifdef SHORT_FILE_NAMES
77 const int kFileNameLen
= 6;
79 const int kFileNameLen
= 250;
82 // Used only to bound the init file name length
83 const int kPathLen
= 256;
85 // This value is used to mark that the current berserk is free from
86 // penalty (Xom's granted or from a deck of cards).
87 #define NO_BERSERK_PENALTY -1
89 typedef FixedArray
<dungeon_feature_type
, GXM
, GYM
> feature_grid
;
90 typedef FixedArray
<unsigned short, GXM
, GYM
> map_mask
;
104 template <typename Z
> inline Z
sgn(Z x
)
106 return (x
< 0 ? -1 : (x
> 0 ? 1 : 0));
109 inline int dist_range(int x
) { return x
*x
+ 1; };
116 explicit coord_def(int x_in
= 0, int y_in
= 0) : x(x_in
), y(y_in
) { }
118 void set(int xi
, int yi
)
129 int distance_from(const coord_def
&b
) const;
131 bool operator == (const coord_def
&other
) const
133 return x
== other
.x
&& y
== other
.y
;
136 bool operator != (const coord_def
&other
) const
138 return !operator == (other
);
141 bool operator < (const coord_def
&other
) const
143 return (x
< other
.x
) || (x
== other
.x
&& y
< other
.y
);
146 bool operator > (const coord_def
&other
) const
148 return (x
> other
.x
) || (x
== other
.x
&& y
> other
.y
);
151 const coord_def
&operator += (const coord_def
&other
)
158 const coord_def
&operator += (int offset
)
165 const coord_def
&operator -= (const coord_def
&other
)
172 const coord_def
&operator -= (int offset
)
179 const coord_def
&operator /= (int div
)
186 const coord_def
&operator *= (int mul
)
193 coord_def
operator + (const coord_def
&other
) const
195 coord_def copy
= *this;
196 return (copy
+= other
);
199 coord_def
operator + (int other
) const
201 coord_def copy
= *this;
202 return (copy
+= other
);
205 coord_def
operator - (const coord_def
&other
) const
207 coord_def copy
= *this;
208 return (copy
-= other
);
211 coord_def
operator -() const
213 return (coord_def(0, 0) - *this);
216 coord_def
operator - (int other
) const
218 coord_def copy
= *this;
219 return (copy
-= other
);
222 coord_def
operator / (int div
) const
224 coord_def copy
= *this;
225 return (copy
/= div
);
228 coord_def
operator * (int mul
) const
230 coord_def copy
= *this;
231 return (copy
*= mul
);
234 coord_def
sgn() const
236 return coord_def(::sgn(x
), ::sgn(y
));
241 return (x
* x
+ y
* y
);
246 return (std::max(std::abs(x
), std::abs(y
)));
259 bool equals(const int xi
, const int yi
) const
261 return (xi
== x
&& yi
== y
);
264 const coord_def
INVALID_COORD(-1, -1);
266 typedef bool (*coord_predicate
)(const coord_def
&c
);
270 dungeon_feature_type grid
;
274 typedef uint32_t mid_t
;
275 #define MID_PLAYER ((mid_t)0xffffffff)
276 // the numbers are meaningless, there's just plenty of space for gods, env,
277 // and whatever else we want to have, while keeping all monster ids smaller.
278 #define MID_ANON_FRIEND ((mid_t)0xffff0000)
293 cloud_struct() : pos(), type(CLOUD_NONE
), decay(0), spread_rate(0),
294 whose(KC_OTHER
), killer(KILL_NONE
), colour(-1),
299 bool defined() const { return type
!= CLOUD_NONE
; }
301 void set_whose(kill_category _whose
);
302 void set_killer(killer_type _killer
);
304 std::string
cloud_name(const std::string
&default_name
= "",
305 bool terse
= false) const;
306 void announce_actor_engulfed(const actor
*engulfee
,
307 bool beneficial
= false) const;
309 static kill_category
killer_to_whose(killer_type killer
);
310 static killer_type
whose_to_killer(kill_category whose
);
319 std::string shop_name
;
320 std::string shop_type_name
;
321 std::string shop_suffix_name
;
323 FixedVector
<uint8_t, 3> keeper_name
;
325 shop_struct () : pos(), greed(0), type(SHOP_UNASSIGNED
), level(0),
326 shop_name(""), shop_type_name(""), shop_suffix_name("") { }
328 bool defined() const { return type
!= SHOP_UNASSIGNED
; }
332 struct delay_queue_item
344 // Identifies a level. Should never include virtual methods or
345 // dynamically allocated memory (see code to push level_id onto Lua
346 // stack in l_dgn.cc)
350 branch_type branch
; // The branch in which the level is.
351 int depth
; // What depth (in this branch - starting from 1)
352 level_area_type level_type
;
355 // Returns the level_id of the current level.
356 static level_id
current();
358 // Returns the level_id of the level that the stair/portal/whatever at
359 // 'pos' on the current level leads to.
360 static level_id
get_next_level_id(const coord_def
&pos
);
363 : branch(BRANCH_MAIN_DUNGEON
), depth(-1),
364 level_type(LEVEL_DUNGEON
)
367 level_id(branch_type br
, int dep
, level_area_type ltype
= LEVEL_DUNGEON
)
368 : branch(br
), depth(dep
), level_type(ltype
)
371 level_id(const level_id
&ot
)
372 : branch(ot
.branch
), depth(ot
.depth
), level_type(ot
.level_type
)
375 level_id(level_area_type ltype
)
376 : branch(BRANCH_MAIN_DUNGEON
), depth(-1), level_type(ltype
)
380 static level_id
parse_level_id(const std::string
&s
) throw (std::string
);
381 static level_id
from_packed_place(const unsigned short place
);
383 unsigned short packed_place() const;
384 std::string
describe(bool long_name
= false, bool with_number
= true) const;
388 branch
= BRANCH_MAIN_DUNGEON
;
390 level_type
= LEVEL_DUNGEON
;
393 // Returns the absolute depth in the dungeon for the level_id;
394 // non-dungeon branches (specifically Abyss and Pan) will return
395 // depths suitable for use in monster and item generation. If
396 // you're looking for a depth to set you.absdepth0 to, use
397 // dungeon_absdepth().
398 int absdepth() const;
400 // Returns the absolute depth in the dungeon for the level_id, corresponding
402 int dungeon_absdepth() const;
404 bool is_valid() const
406 return (branch
!= NUM_BRANCHES
&& depth
!= -1)
407 || level_type
!= LEVEL_DUNGEON
;
410 const level_id
&operator = (const level_id
&id
)
414 level_type
= id
.level_type
;
418 bool operator == (const level_id
&id
) const
420 return (level_type
== id
.level_type
421 && (level_type
!= LEVEL_DUNGEON
422 || (branch
== id
.branch
&& depth
== id
.depth
)));
425 bool operator != (const level_id
&id
) const
427 return !operator == (id
);
430 bool operator <(const level_id
&id
) const
432 if (level_type
!= id
.level_type
)
433 return (level_type
< id
.level_type
);
435 if (level_type
!= LEVEL_DUNGEON
)
438 return (branch
< id
.branch
) || (branch
==id
.branch
&& depth
< id
.depth
);
441 bool operator == (const branch_type _branch
) const
443 return (branch
== _branch
&& level_type
== LEVEL_DUNGEON
);
446 bool operator != (const branch_type _branch
) const
448 return !operator == (_branch
);
451 void save(writer
&) const;
455 // A position on a particular level.
459 coord_def pos
; // The grid coordinates on this level.
461 level_pos() : id(), pos()
466 level_pos(const level_id
&lid
, const coord_def
&coord
)
467 : id(lid
), pos(coord
)
471 level_pos(const level_id
&lid
)
477 // Returns the level_pos of where the player is standing.
478 static level_pos
current();
480 bool operator == (const level_pos
&lp
) const
482 return id
== lp
.id
&& pos
== lp
.pos
;
485 bool operator != (const level_pos
&lp
) const
487 return id
!= lp
.id
|| pos
!= lp
.pos
;
490 bool operator < (const level_pos
&lp
) const
492 return (id
< lp
.id
) || (id
== lp
.id
&& pos
< lp
.pos
);
495 bool is_valid() const
497 return id
.depth
> -1 && pos
.x
!= -1 && pos
.y
!= -1;
500 bool is_on(const level_id _id
)
508 pos
= coord_def(-1, -1);
511 void save(writer
&) const;
517 // We are not 64 bits clean here yet since many places still pass (or store!)
518 // it as 32 bits or, worse, longs. I considered setting this as uint32_t,
519 // however, since free bits are exhausted, it's very likely we'll have to
520 // extend this in the future, so this should be easier than undoing the change.
521 typedef uint32_t iflags_t
;
525 object_class_type base_type
:8; // basic class (ie OBJ_WEAPON)
526 uint8_t sub_type
; // type within that class (ie WPN_DAGGER)
527 short plus
; // +to hit, charges, corpse mon id
528 short plus2
; // +to dam, sub-sub type for boots/helms
529 int special
; // special stuff
530 uint8_t colour
; // item colour
531 uint8_t rnd
; // random number, used for tile choice
532 short quantity
; // number of items
533 iflags_t flags
; // item status flags
535 coord_def pos
; // for inventory items == (-1, -1)
536 short link
; // link to next item; for inventory items = slot
537 short slot
; // Inventory letter
539 unsigned short orig_place
;
542 std::string inscription
;
544 CrawlHashTable props
;
547 item_def() : base_type(OBJ_UNASSIGNED
), sub_type(0), plus(0), plus2(0),
548 special(0L), colour(0), rnd(0), quantity(0), flags(0L),
549 pos(), link(NON_ITEM
), slot(0), orig_place(0),
550 orig_monnum(0), inscription()
554 std::string
name(description_level_type descrip
,
555 bool terse
= false, bool ident
= false,
556 bool with_inscription
= true,
557 bool quantity_in_words
= false,
558 iflags_t ignore_flags
= 0x0) const;
559 bool has_spells() const;
561 int book_number() const;
562 zap_type
zap() const; // what kind of beam it shoots (if wand).
564 // Returns index in mitm array. Results are undefined if this item is
568 int armour_rating() const;
570 bool launched_by(const item_def
&launcher
) const;
577 // Sets this item as being held by a given monster.
578 void set_holding_monster(int midx
);
580 // Returns monster holding this item. NULL if none.
581 monster
* holding_monster() const;
583 // Returns true if a monster is holding this item.
584 bool held_by_monster() const;
586 bool defined() const;
587 bool is_valid() const;
589 // Returns true if this item should be preserved as far as possible.
590 bool is_critical() const;
592 // Returns true if this item should not normally be enchanted.
593 bool is_mundane() const;
596 std::string
name_aux(description_level_type desc
,
597 bool terse
, bool ident
, bool with_inscription
,
598 iflags_t ignore_flags
) const;
601 typedef item_def item_info
;
602 item_info
get_item_info(const item_def
& info
);
612 FixedVector
<run_check_dir
,3> run_check
; // array of grids to check
616 void initialise(int rdir
, int mode
);
619 operator int () const;
622 const runrest
&operator = (int newrunmode
);
624 // Returns true if we're currently resting.
625 bool is_rest() const;
626 bool is_explore() const;
627 bool is_any_travel() const;
629 std::string
runmode_name() const;
637 // Take one off the rest counter.
640 // Checks if shift-run should be aborted and aborts the run if necessary.
641 // Returns true if you were running and are now no longer running.
642 bool check_stop_running();
645 void set_run_check(int index
, int compass_dir
);
646 bool run_should_stop() const;
649 typedef std::vector
<delay_queue_item
> delay_queue_type
;
651 class monster_spells
: public FixedVector
<spell_type
, NUM_MONSTER_SPELL_SLOTS
>
655 : FixedVector
<spell_type
, NUM_MONSTER_SPELL_SLOTS
>(SPELL_NO_SPELL
)
657 void clear() { init(SPELL_NO_SPELL
); }
666 map_markers(const map_markers
&);
667 map_markers
&operator = (const map_markers
&);
670 bool need_activate() const { return have_inactive_markers
; }
671 void clear_need_activate();
672 void activate_all(bool verbose
= true);
673 void activate_markers_at(coord_def p
);
674 void add(map_marker
*marker
);
675 void remove(map_marker
*marker
);
676 void remove_markers_at(const coord_def
&c
, map_marker_type type
= MAT_ANY
);
677 map_marker
*find(const coord_def
&c
, map_marker_type type
= MAT_ANY
);
678 map_marker
*find(map_marker_type type
);
679 void move(const coord_def
&from
, const coord_def
&to
);
680 void move_marker(map_marker
*marker
, const coord_def
&to
);
681 std::vector
<map_marker
*> get_all(map_marker_type type
= MAT_ANY
);
682 std::vector
<map_marker
*> get_all(const std::string
&key
,
683 const std::string
&val
= "");
684 std::vector
<map_marker
*> get_markers_at(const coord_def
&c
);
685 std::string
property_at(const coord_def
&c
, map_marker_type type
,
686 const std::string
&key
);
689 void write(writer
&) const;
693 typedef std::multimap
<coord_def
, map_marker
*> dgn_marker_map
;
694 typedef std::pair
<coord_def
, map_marker
*> dgn_pos_marker
;
696 void init_from(const map_markers
&);
697 void unlink_marker(const map_marker
*);
701 dgn_marker_map markers
;
702 bool have_inactive_markers
;
705 struct message_filter
707 int channel
; // Use -1 to match any channel.
708 text_pattern pattern
; // Empty pattern matches any message
710 message_filter(int ch
, const std::string
&s
)
711 : channel(ch
), pattern(s
)
715 message_filter(const std::string
&s
) : channel(-1), pattern(s
) { }
717 bool is_filtered(int ch
, const std::string
&s
) const {
718 bool channel_match
= ch
== channel
|| channel
== -1;
719 if (!channel_match
|| pattern
.empty())
720 return channel_match
;
721 return pattern
.matches(s
);
728 text_pattern pattern
;
729 std::string soundfile
;
732 struct colour_mapping
735 text_pattern pattern
;
739 struct message_colour_mapping
741 message_filter message
;
742 msg_colour_type colour
;
746 typedef int (*item_sort_fn
)(const InvEntry
*a
, const InvEntry
*b
);
747 struct item_comparator
752 item_comparator(item_sort_fn cfn
, bool neg
= false)
753 : cmpfn(cfn
), negated(neg
)
756 int compare(const InvEntry
*a
, const InvEntry
*b
) const
758 return (negated
? -cmpfn(a
, b
) : cmpfn(a
, b
));
761 typedef std::vector
<item_comparator
> item_sort_comparators
;
763 struct menu_sort_condition
768 item_sort_comparators cmp
;
771 menu_sort_condition(menu_type mt
= MT_INVLIST
, int sort
= 0);
772 menu_sort_condition(const std::string
&s
);
774 bool matches(menu_type mt
) const;
777 void set_menu_type(std::string
&s
);
778 void set_sort(std::string
&s
);
779 void set_comparators(std::string
&s
);
787 monster_type detected
; // What a monster of type "type" is detected as.
789 mon_display(monster_type m
= MONS_NO_MONSTER
,
790 unsigned gly
= 0, unsigned col
= 0,
791 monster_type d
= MONS_NO_MONSTER
)
792 : type(m
), glyph(gly
), colour(col
), detected(d
) { }
797 final_effect_flavour flavour
;