1 #pragma once 2 3 #include "beh-type.h" 4 #include "coord.h" 5 #include "god-type.h" 6 #include "mgen-enum.h" 7 #include "mon-flags.h" 8 #include "xp-tracking-type.h" 9 10 // Hash key for passing a weapon to be given to 11 // a dancing weapon. 12 #define TUKIMA_WEAPON "tukima-weapon" 13 #define TUKIMA_POWER "tukima-power" 14 15 #define MGEN_NUM_HEADS "num_heads" 16 #define MGEN_BLOB_SIZE "blob_size" 17 #define MGEN_TENTACLE_CONNECT "tentacle_connect" 18 /// doesn't automatically perish over time (for pillars of salt, blocks of ice) 19 #define MGEN_NO_AUTO_CRUMBLE "no_auto_crumble" 20 21 // A structure with all the data needed to whip up a new monster. 22 struct mgen_data 23 { 24 // Monster type. 25 monster_type cls; 26 27 // Determines the behaviour of the monster after it is generated. This 28 // behaviour is an unholy combination of monster attitude 29 // (friendly, hostile) and monster initial state (asleep, wandering). 30 // XXX: Could use splitting up these aspects. 31 beh_type behaviour; 32 33 // Who summoned this monster? Important to know for death accounting 34 // and the summon cap, if and when it goes in. nullptr is no summoner. 35 const actor* summoner; 36 37 // For summoned monsters, this is a measure of how long the summon will 38 // hang around, on a scale of 1-6, 6 being longest. Use 0 for monsters 39 // that aren't summoned. 40 int abjuration_duration; 41 42 // For summoned monsters this is their type of summoning, either the 43 // spell which summoned them or one of the values of the enumeration 44 // mon_summon_type in mon-enum.h. 45 int summon_type; 46 47 // Where the monster will be created. 48 coord_def pos; 49 50 // The monster's foe, i.e. which monster it will want to attack. foe 51 // may be an index into the monster array (0 - (MAX_MONSTERS-1)), or 52 // it may be MHITYOU to indicate that the monster wants to attack the 53 // player, or MHITNOT, to indicate that the monster has no foe and is 54 // just wandering around. 55 unsigned short foe; 56 57 // Generation flags. 58 mgen_flags flags; 59 60 // What god the monster worships, if any. Used for monsters that 61 // are god gifts, to indicate which god sent them, and by priest 62 // monsters, to indicate whose priest they are. 63 god_type god; 64 65 // If the monster is zombie-like, or a specialised draconian, this 66 // is the base monster that the monster is based on - should be 67 // set to MONS_NO_MONSTER when not used. 68 monster_type base_type; 69 70 // The colour of the monster, or COLOUR_UNDEF for col:any 71 int colour; 72 73 // How close to or far from the player the monster should be created. 74 // Is usually used only when the initial position (pos) is unspecified. 75 proximity_type proximity; 76 77 // What place we're in, or pretending to be in, usually the place 78 // the player is actually in. 79 level_id place; 80 81 int hd; 82 int hp; 83 84 // These flags will be appended to the monster's flags after placement. 85 monster_flags_t extra_flags; 86 87 string mname; 88 89 // This is used to account for non-actor summoners. Blasted by an Ice 90 // Fiend ... summoned by the effects of Hell. 91 string non_actor_summoner; 92 93 // This simply stores the initial shape-shifter type. 94 monster_type initial_shifter; 95 96 // A grid feature to prefer when finding a place to create monsters. 97 // For instance, using DNGN_FLOOR when placing flying monsters or 98 // merfolk in the Shoals will force them to appear on land. 99 // preferred_grid_feature will be ignored if it is incompatible with 100 // the monster's native habitat (for instance, if trying to place 101 // a electric eel with preferred_grid_feature DNGN_FLOOR). 102 dungeon_feature_type preferred_grid_feature = DNGN_UNSEEN; 103 104 // Some predefined vaults (aka maps) include flags to suppress random 105 // generation of monsters. When generating monsters, this is a mask of 106 // map flags to honour (such as MMT_NO_MONS to specify that we shouldn't 107 // randomly generate a monster inside a map that doesn't want it). These 108 // map flags are usually respected only when a dungeon level is being 109 // constructed, since at future points vault information may no longer 110 // be available (vault metadata is not preserved across game saves). 111 unsigned map_mask = 0; 112 113 // This can eventually be used to store relevant information. 114 CrawlHashTable props; 115 116 // What class of XP is this for LevelXPInfo tracking purposes. 117 xp_tracking_type xp_tracking; 118 119 mgen_data(monster_type mt = RANDOM_MONSTER, 120 beh_type beh = BEH_HOSTILE, 121 const coord_def &p = coord_def(-1, -1), 122 unsigned short mfoe = MHITNOT, 123 mgen_flags genflags = MG_NONE, 124 god_type which_god = GOD_NO_GOD) 125 clsmgen_data126 : cls(mt), behaviour(beh), summoner(nullptr), abjuration_duration(0), 127 summon_type(0), pos(p), foe(mfoe), flags(genflags), god(which_god), 128 base_type(MONS_NO_MONSTER), colour(COLOUR_INHERIT), 129 proximity(PROX_ANYWHERE), place(level_id::current()), hd(0), hp(0), 130 extra_flags(MF_NO_FLAGS), mname(""), non_actor_summoner(""), 131 initial_shifter(RANDOM_MONSTER), xp_tracking(XP_NON_VAULT) 132 { } 133 set_non_actor_summonermgen_data134 mgen_data &set_non_actor_summoner(string nas) 135 { 136 non_actor_summoner = nas; 137 return *this; 138 } 139 set_placemgen_data140 mgen_data &set_place(level_id _place) 141 { 142 place = _place; 143 return *this; 144 } 145 set_proxmgen_data146 mgen_data &set_prox(proximity_type prox) 147 { 148 proximity = prox; 149 return *this; 150 } 151 set_colmgen_data152 mgen_data &set_col(int col) 153 { 154 colour = col; 155 return *this; 156 } 157 set_basemgen_data158 mgen_data &set_base(monster_type base) 159 { 160 base_type = base; 161 return *this; 162 } 163 164 mgen_data &set_summoned(const actor* _summoner, int abjuration_dur, 165 int _summon_type, god_type _god = GOD_NO_GOD) 166 { 167 summoner = _summoner; 168 abjuration_duration = abjuration_dur; 169 summon_type = _summon_type; 170 if (_god != GOD_NO_GOD) 171 god = _god; 172 173 ASSERT(summon_type == 0 || abjuration_dur >= 1 && abjuration_dur <= 6 174 || cls == MONS_BALL_LIGHTNING || cls == MONS_ORB_OF_DESTRUCTION 175 || cls == MONS_BATTLESPHERE || cls == MONS_BALLISTOMYCETE_SPORE 176 || summon_type == SPELL_DEATH_CHANNEL 177 || summon_type == SPELL_BIND_SOULS 178 || summon_type == SPELL_SIMULACRUM 179 || summon_type == SPELL_AWAKEN_VINES 180 || summon_type == SPELL_FULMINANT_PRISM 181 || summon_type == SPELL_INFESTATION 182 || summon_type == SPELL_FOXFIRE 183 || summon_type == SPELL_MARSHLIGHT); 184 return *this; 185 } 186 permit_bandsmgen_data187 bool permit_bands() const 188 { 189 // The permit flag is set but the forbid flag is not. 190 return (flags & (MG_PERMIT_BANDS|MG_FORBID_BANDS)) == MG_PERMIT_BANDS; 191 } 192 force_placemgen_data193 bool force_place() const { return bool(flags & MG_FORCE_PLACE); } needs_patrol_pointmgen_data194 bool needs_patrol_point() const { return bool(flags & MG_PATROLLING); } 195 196 // Is there a valid position set on this struct that we want to use 197 // when placing the monster? use_positionmgen_data198 bool use_position() const { return in_bounds(pos); }; 199 summonedmgen_data200 bool summoned() const { return abjuration_duration > 0; } 201 202 static mgen_data sleeper_at(monster_type what, 203 const coord_def &where, 204 mgen_flags genflags = MG_NONE) 205 { 206 return mgen_data(what, BEH_SLEEP, where, MHITNOT, genflags); 207 } 208 209 static mgen_data hostile_at(monster_type mt, 210 bool alert = false, 211 const coord_def &p = coord_def(-1, -1)) 212 213 { 214 return mgen_data(mt, BEH_HOSTILE, p, alert ? MHITYOU : MHITNOT); 215 } 216 }; 217