#ifndef MGEN_DATA_H #define MGEN_DATA_H #include "mgen_enum.h" #include "player.h" // A structure with all the data needed to whip up a new monster. struct mgen_data { // Monster type. monster_type cls; // If the monster is zombie-like, or a specialised draconian, this // is the base monster that the monster is based on - should be // set to MONS_NO_MONSTER when not used. monster_type base_type; // Determines the behaviour of the monster after it is generated. This // behaviour is an unholy combination of monster attitude // (friendly, hostile) and monster initial state (asleep, wandering). // XXX: Could use splitting up these aspects. beh_type behaviour; // Who summoned this monster? Important to know for death accounting // and the summon cap, if and when it goes in. NULL is no summoner. actor* summoner; // For summoned monsters, this is a measure of how long the summon will // hang around, on a scale of 1-6, 6 being longest. Use 0 for monsters // that aren't summoned. int abjuration_duration; // For summoned monsters this is their type of summoning, either the // spell which summoned them or one of the values of the enumeration // mon_summon_type in mon-util.h. int summon_type; // Where the monster will be created. coord_def pos; // The monster's foe, i.e. which monster it will want to attack. foe // may be an index into the monster array (0 - (MAX_MONSTERS-1)), or // it may be MHITYOU to indicate that the monster wants to attack the // player, or MHITNOT, to indicate that the monster has no foe and is // just wandering around. unsigned short foe; // Generation flags from mgen_flag_type. unsigned flags; // What god the monster worships, if any. Used for monsters that // are god gifts, to indicate which god sent them, and by priest // monsters, to indicate whose priest they are. god_type god; // The number of hydra heads, the number of manticore attack volleys, // the number of merged slime creatures, or the indicator for when // Khufu is entombed. // // Note: in older versions this field was used for both this and for // base_type. int number; // The colour of the monster. int colour; // A measure of how powerful the generated monster should be (for // randomly chosen monsters), usually equal to the absolute depth // that the player is in the dungeon. int power; // How close to or far from the player the monster should be created. // Is usually used only when the initial position (pos) is unspecified. proximity_type proximity; // What place we're in, or pretending to be in, usually the place // the player is actually in. level_area_type level_type; // Some predefined vaults (aka maps) include flags to suppress random // generation of monsters. When generating monsters, this is a mask of // map flags to honour (such as MMT_NO_MONS to specify that we shouldn't // randomly generate a monster inside a map that doesn't want it). These // map flags are usually respected only when a dungeon level is being // constructed, since at future points vault information may no longer // be available (vault metadata is not preserved across game saves). unsigned map_mask; // XXX: Also rather hackish. int hd; int hp; // These flags will be appended to the monster's flags after placement. // These flags are MF_XXX, rather than MG_XXX flags. unsigned long extra_flags; // XXX: Rather hackish. std::string mname; // This is used to account for non-actor summoners. Blasted by an Ice // Fiend ... summoned by the effects of Hell. std::string non_actor_summoner; // This can eventually be used to store relevant information. CrawlHashTable props; mgen_data(monster_type mt = RANDOM_MONSTER, beh_type beh = BEH_HOSTILE, actor* sner = 0, int abj = 0, int st = 0, const coord_def &p = coord_def(-1, -1), unsigned short mfoe = MHITNOT, unsigned monflags = 0, god_type which_god = GOD_NO_GOD, monster_type base = MONS_NO_MONSTER, int monnumber = 0, int moncolour = BLACK, int monpower = you.your_level, proximity_type prox = PROX_ANYWHERE, level_area_type ltype = you.level_type, int mhd = 0, int mhp = 0, unsigned long mflags = 0, std::string monname = "", std::string nas = "") : cls(mt), base_type(base), behaviour(beh), summoner(sner), abjuration_duration(abj), summon_type(st), pos(p), foe(mfoe), flags(monflags), god(which_god), number(monnumber), colour(moncolour), power(monpower), proximity(prox), level_type(ltype), map_mask(0), hd(mhd), hp(mhp), extra_flags(mflags), mname(monname), non_actor_summoner(nas), props() { ASSERT(summon_type == 0 || (abj >= 1 && abj <= 6) || mt == MONS_BALL_LIGHTNING || mt == MONS_ORB_OF_DESTRUCTION); } bool permit_bands() const { return (flags & MG_PERMIT_BANDS); } bool force_place() const { return (flags & MG_FORCE_PLACE); } bool needs_patrol_point() const { return (flags & MG_PATROLLING); } // Is there a valid position set on this struct that we want to use // when placing the monster? bool use_position() const; bool summoned() const { return (abjuration_duration > 0); } static mgen_data sleeper_at(monster_type what, const coord_def &where, unsigned flags = 0) { return mgen_data(what, BEH_SLEEP, 0, 0, 0, where, MHITNOT, flags); } static mgen_data hostile_at(monster_type mt, std::string summoner, bool alert = false, int abj = 0, int st = 0, const coord_def &p = coord_def(-1, -1), unsigned monflags = 0, god_type god = GOD_NO_GOD, monster_type base = MONS_NO_MONSTER) { return mgen_data(mt, BEH_HOSTILE, 0, abj, st, p, alert ? MHITYOU : MHITNOT, monflags, god, base, 0, BLACK, you.your_level, PROX_ANYWHERE, you.level_type, 0, 0, 0, "", summoner); } }; #endif