1 /**
2  * @file
3  * @brief Definitions for common structs.
4 **/
5 
6 #pragma once
7 
8 #define __STDC_FORMAT_MACROS
9 #include <cinttypes>
10 #include <cstdint>
11 #include <cstdlib>
12 #include <ctime>
13 #include <deque>
14 #include <list>
15 #include <map>
16 #include <memory>
17 #include <set>
18 #include <stdexcept>
19 #include <string>
20 #include <sstream>
21 #include <vector>
22 
23 #include "bitary.h"
24 #include "description-level-type.h"
25 #include "dungeon-feature-type.h"
26 #include "enum.h"
27 #include "spell-type.h"
28 #include "branch-type.h"
29 #include "fixedarray.h"
30 #include "kill-category.h"
31 #include "killer-type.h"
32 #include "map-marker-type.h"
33 #include "menu-type.h"
34 
35 #include "object-class-type.h"
36 #include "pattern.h"
37 #include "skill-type.h"
38 #include "shop-type.h"
39 #include "cloud-type.h"
40 #include "store.h"
41 #include "rltiles/tiledef_defines.h"
42 #include "tag-version.h"
43 
44 #include "coord-def.h"
45 #include "item-def.h"
46 #include "level-id.h"
47 #include "monster-type.h"
48 
49 #include "ray.h"
50 
51 struct tile_flavour
52 {
53     unsigned short floor_idx;
54     unsigned short wall_idx;
55     unsigned short feat_idx;
56 
57     unsigned short floor;
58     unsigned short wall;
59     // Used (primarily) by the vault 'TILE' overlay.
60     unsigned short feat;
61 
62     // Used as a random value or for special cases e.g. (bazaars, gates).
63     unsigned short special;
64 
tile_flavourtile_flavour65     tile_flavour(): floor_idx(0), wall_idx(0), feat_idx(0),
66                     floor(0), wall(0), feat(0), special(0) {}
67 };
68 
69 // A glorified unsigned int that assists with ref-counting the mcache.
70 class tile_fg_store
71 {
72 public:
tile_fg_store()73     tile_fg_store() : m_tile(0) {}
tile_fg_store(tileidx_t tile)74     tile_fg_store(tileidx_t tile) : m_tile(tile) {}
tileidx_t()75     operator tileidx_t() { return m_tile; }
76     tileidx_t operator=(tileidx_t tile);
77 protected:
78     tileidx_t m_tile;
79 };
80 
81 #define MAX_NAME_LENGTH 30
82 
83 typedef FixedArray<dungeon_feature_type, GXM, GYM> feature_grid;
84 typedef FixedArray<unsigned int, GXM, GYM> map_mask;
85 typedef FixedBitArray<GXM, GYM> map_bitmask;
86 
87 struct item_def;
88 struct coord_def;
89 class level_id;
90 class map_marker;
91 class actor;
92 class player;
93 class ghost_demon;
94 
95 constexpr coord_def INVALID_COORD {-1, -1};
96 constexpr coord_def NO_CURSOR { INVALID_COORD };
97 
98 typedef bool (*coord_predicate)(const coord_def &c);
99 
100 struct run_check_dir
101 {
102     dungeon_feature_type grid;
103     coord_def delta;
104 };
105 
106 /**
107  * Persistent unique identifier for an actor.
108  *
109  * An mid_t is a persistent (across levels and across save/restore)
110  * and unique (within a given game) identifier for a monster, player,
111  * or fake actor. The value 0 indicates "no actor", and any value
112  * greater than or equal to MID_FIRST_NON_MONSTER indicates an actor
113  * other than a monster.
114  *
115  * mid_t should be used for anything that needs to remember monster
116  * identity from one turn to the next, as mindexes may be reused
117  * if a monster dies, and are not unique across levels.
118  */
119 typedef uint32_t mid_t;
120 #define PRImidt PRIu32
121 #define MID_NOBODY        ((mid_t)0x00000000)
122 #define MID_PLAYER        ((mid_t)0xffffffff)
123 // the numbers are meaningless, there's just plenty of space for gods, env,
124 // and whatever else we want to have, while keeping all monster ids smaller.
125 #define MID_ANON_FRIEND   ((mid_t)0xffff0000)
126 #define MID_YOU_FAULTLESS ((mid_t)0xffff0001)
127 /// Upper bound on the number of monsters that can ever exist in a game.
128 #define MID_FIRST_NON_MONSTER MID_ANON_FRIEND
129 
130 /**
131  * Define overloaded ++ and -- operators for the enum T.
132  *
133  * This macro produces several inline function definitions; use it only at
134  * file/namespace scope. It requires a trailing semicolon.
135  *
136  * @param T A type expression naming the enum type to augument. Evaluated
137  *          several times.
138  */
139 #define DEF_ENUM_INC(T) \
140     static inline T &operator++(T &x) { return x = static_cast<T>(x + 1); } \
141     static inline T &operator--(T &x) { return x = static_cast<T>(x - 1); } \
142     static inline T operator++(T &x, int) { T y = x; ++x; return y; } \
143     static inline T operator--(T &x, int) { T y = x; --x; return y; } \
144     COMPILE_CHECK(is_enum<T>::value)
145 
146 DEF_ENUM_INC(monster_type);
147 DEF_ENUM_INC(spell_type);
148 DEF_ENUM_INC(skill_type);
149 
150 /// Exception indicating a bad level_id, level_range, or depth_range.
151 struct bad_level_id : public runtime_error
152 {
bad_level_idbad_level_id153     explicit bad_level_id(const string &msg) : runtime_error(msg) {}
bad_level_idbad_level_id154     explicit bad_level_id(const char *msg) : runtime_error(msg) {}
155 };
156 
157 /**
158  * Create a bad_level_id exception from a printf-like specification.
159  * Users of this macro must #include "stringutil.h" themselves.
160  */
161 #define bad_level_id_f(...) bad_level_id(make_stringf(__VA_ARGS__))
162 
163 class runrest
164 {
165 public:
166     int runmode;
167     int mp;
168     int hp;
169     bool notified_mp_full;
170     bool notified_hp_full;
171     bool notified_ancestor_hp_full;
172     coord_def pos;
173     int travel_speed;
174     int direction;
175     int turns_passed;
176 
177     FixedVector<run_check_dir,3> run_check; // array of grids to check
178 
179 public:
180     runrest();
181     void initialise(int rdir, int mode);
182     void init_travel_speed();
183 
184     // returns runmode
185     operator int () const;
186 
187     // sets runmode
188     const runrest &operator = (int newrunmode);
189 
190     // Returns true if we're currently resting.
191     bool is_rest() const;
192     bool is_explore() const;
193     bool is_any_travel() const;
194 
195     string runmode_name() const;
196 
197     // Clears run state.
198     void clear();
199 
200     // Stops running.
201     void stop(bool clear_delays = true);
202 
203     // Take one off the rest counter.
204     void rest();
205 
206     // Checks if shift-run should be aborted and aborts the run if necessary.
207     // Returns true if you were running and are now no longer running.
208     bool check_stop_running();
209 
210 private:
211     void set_run_check(int index, int compass_dir);
212     bool run_should_stop() const;
213     bool diag_run_passes_door() const;
214 };
215 
216 enum mon_spell_slot_flag
217 {
218     MON_SPELL_NO_FLAGS  = 0,
219     MON_SPELL_EMERGENCY   = 1 <<  0, // only use this spell slot in emergencies
220     MON_SPELL_NATURAL     = 1 <<  1, // physiological, not really a spell
221     MON_SPELL_MAGICAL     = 1 <<  2, // magical ability, affected by AM
222     MON_SPELL_VOCAL       = 1 <<  3, // natural ability, but affected by silence
223     MON_SPELL_WIZARD      = 1 <<  4, // real spell, affected by AM and silence
224     MON_SPELL_PRIEST      = 1 <<  5, // divine ability, affected by silence
225 
226     MON_SPELL_FIRST_CATEGORY = MON_SPELL_NATURAL,
227     MON_SPELL_LAST_CATEGORY  = MON_SPELL_PRIEST,
228 
229     MON_SPELL_BREATH      = 1 <<  6, // sets a breath timer, requires it to be 0
230 #if TAG_MAJOR_VERSION == 34
231     MON_SPELL_NO_SILENT   = 1 <<  7, // can't be used while silenced/mute/etc.
232 #endif
233 
234     MON_SPELL_INSTANT     = 1 <<  8, // allows another action on the same turn
235     MON_SPELL_NOISY       = 1 <<  9, // makes noise despite being innate
236 
237     MON_SPELL_SHORT_RANGE = 1 << 10, // only use at short distances
238     MON_SPELL_LONG_RANGE  = 1 << 11, // only use at long distances
239     MON_SPELL_EVOKE       = 1 << 12, // a spell from an evoked item
240 
241     MON_SPELL_LAST_FLAG = MON_SPELL_EVOKE,
242 };
243 DEF_BITFIELD(mon_spell_slot_flags, mon_spell_slot_flag, 12);
244 const int MON_SPELL_LAST_EXPONENT = mon_spell_slot_flags::last_exponent;
245 COMPILE_CHECK(mon_spell_slot_flags::exponent(MON_SPELL_LAST_EXPONENT)
246               == MON_SPELL_LAST_FLAG);
247 
248 constexpr mon_spell_slot_flags MON_SPELL_TYPE_MASK
249     = MON_SPELL_NATURAL | MON_SPELL_MAGICAL | MON_SPELL_WIZARD
250       | MON_SPELL_PRIEST | MON_SPELL_VOCAL;
251 
252 // Doesn't make noise when cast (unless flagged with MON_SPELL_NOISY).
253 constexpr mon_spell_slot_flags MON_SPELL_INNATE_MASK
254     = MON_SPELL_NATURAL | MON_SPELL_MAGICAL;
255 
256 // Affected by antimagic.
257 constexpr mon_spell_slot_flags MON_SPELL_ANTIMAGIC_MASK
258     = MON_SPELL_MAGICAL | MON_SPELL_WIZARD;
259 
260 // Affected by silence.
261 constexpr mon_spell_slot_flags MON_SPELL_SILENCE_MASK
262     = MON_SPELL_WIZARD  | MON_SPELL_PRIEST  | MON_SPELL_VOCAL;
263 
264 struct mon_spell_slot
265 {
266     // Allow implicit conversion (and thus copy-initialization) from a
267     // three-element initializer list, but not from a smaller list or
268     // from a plain spell_type.
mon_spell_slotmon_spell_slot269     constexpr mon_spell_slot(spell_type spell_, uint8_t freq_,
270                              mon_spell_slot_flags flags_)
271         : spell(spell_), freq(freq_), flags(flags_)
272     { }
273     explicit constexpr mon_spell_slot(spell_type spell_ = SPELL_NO_SPELL,
274                                       uint8_t freq_ = 0)
mon_spell_slotmon_spell_slot275         : mon_spell_slot(spell_, freq_, MON_SPELL_NO_FLAGS)
276     { }
277 
278     spell_type spell;
279     uint8_t freq;
280     mon_spell_slot_flags flags;
281 };
282 
283 typedef vector<mon_spell_slot> monster_spells;
284 
285 class InvEntry;
286 typedef int (*item_sort_fn)(const InvEntry *a, const InvEntry *b);
287 struct item_comparator
288 {
289     item_sort_fn cmpfn;
290     bool negated;
291 
292     item_comparator(item_sort_fn cfn, bool neg = false)
cmpfnitem_comparator293         : cmpfn(cfn), negated(neg)
294     {
295     }
compareitem_comparator296     int compare(const InvEntry *a, const InvEntry *b) const
297     {
298         return negated? -cmpfn(a, b) : cmpfn(a, b);
299     }
300 };
301 typedef vector<item_comparator> item_sort_comparators;
302 
303 struct menu_sort_condition
304 {
305 public:
306     menu_type mtype;
307     int       sort;
308     item_sort_comparators cmp;
309 
310 public:
311     menu_sort_condition(menu_type mt = menu_type::invlist, int sort = 0);
312     menu_sort_condition(const string &s);
313 
314     bool matches(menu_type mt) const;
315 
316 private:
317     void set_menu_type(string &s);
318     void set_sort(string &s);
319     void set_comparators(string &s);
320 };
321 
322 struct cglyph_t
323 {
324     char32_t ch;
325     unsigned short col; // XXX: real or unreal depending on context...
326 
327     cglyph_t(char32_t _ch = 0, unsigned short _col = LIGHTGREY)
chcglyph_t328         : ch(_ch), col(_col)
329     {
330     }
331 };
332 
333 typedef FixedArray<bool, NUM_OBJECT_CLASSES, MAX_SUBTYPES> id_arr;
334 
335 namespace quiver
336 {
337     struct action_cycler;
338 }
339 
340 // input and output to targeting actions
341 // TODO: rename, move to its own .h, remove camel case
342 // For the exact details of interactive vs non-interactive targeting, see
343 // dist::needs_targeting() in directn.cc.
344 class dist
345 {
346 public:
347     dist();
348 
349     bool isMe() const;
350     bool needs_targeting() const;
351 
352     bool isValid;       // output: valid target chosen?
353     bool isTarget;      // output: target (true), or direction (false)?
354     bool isEndpoint;    // input: Does the player want the attack to stop at target?
355     bool isCancel;      // output: user cancelled (usually <ESC> key)
356     bool choseRay;      // output: user wants a specific beam
357     bool interactive;   // input and output: if true, forces an interactive targeter.
358                         // behavior when false depends on `target` and `find_target`.
359                         // on output, whether an interactive targeter was chosen.
360 
361     coord_def target;   // input and output: target x,y or logical extension of beam to map edge
362     coord_def delta;    // input and output: delta x and y if direction - always -1,0,1
363     ray_def ray;        // output: ray chosen if necessary
364     bool find_target;   // input: use the targeter to find a target, possibly by modifying `target`.
365                         // requests non-interactive mode, but does not override `interactive`.
366     const quiver::action_cycler *fire_context;
367                             // input: if triggered from the action system, what the
368                             // quiver was that triggered it. May be nullptr.
369                             // sort of ugly to have this here...
370     int cmd_result;     // output: a resulting command. See quiver::action_cycler::target for
371                         // which commands may be handled and how. This is an `int` for include
372                         // order reasons, unfortunately
373 };
374