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