3 * Summary: Functions used when placing monsters in the dungeon.
4 * Written by: Linley Henzell
11 #include "mon-place.h"
15 #include "directn.h" // for the Compass
28 #include "mon-stuff.h"
38 static std::vector<int> vault_mon_types;
39 static std::vector<int> vault_mon_bases;
40 static std::vector<int> vault_mon_weights;
42 #define VAULT_MON_TYPES_KEY "vault_mon_types"
43 #define VAULT_MON_BASES_KEY "vault_mon_bases"
44 #define VAULT_MON_WEIGHTS_KEY "vault_mon_weights"
46 // NEW place_monster -- note that power should be set to:
51 // proximity is the same as for mons_place:
52 // 0 is no restrictions
53 // 1 attempts to place near player
54 // 2 attempts to avoid player LOS
58 static monster_type _resolve_monster_type(monster_type mon_type,
59 proximity_type proximity,
60 monster_type &base_type,
63 dungeon_char_type *stair_type,
66 static void _define_zombie(int mid, monster_type ztype, monster_type cs,
67 int power, coord_def pos);
68 static monster_type _band_member(band_type band, int power);
69 static band_type _choose_band(int mon_type, int power, int &band_size);
70 // static int _place_monster_aux(int mon_type, beh_type behaviour, int target,
71 // int px, int py, int power, int extra,
72 // bool first_band_member, int dur = 0);
74 static int _place_monster_aux(const mgen_data &mg, bool first_band_member,
75 bool force_pos = false);
77 // Returns whether actual_feat is compatible with feat_wanted for monster
78 // movement and generation.
79 bool feat_compatible(dungeon_feature_type feat_wanted,
80 dungeon_feature_type actual_feat)
82 if (feat_wanted == DNGN_FLOOR)
84 return (actual_feat >= DNGN_FLOOR
85 && actual_feat != DNGN_BUILDER_SPECIAL_WALL
86 || actual_feat == DNGN_SHALLOW_WATER);
89 if (feat_wanted >= DNGN_ROCK_WALL
90 && feat_wanted <= DNGN_CLEAR_PERMAROCK_WALL)
92 // A monster can only move through or inhabit permanent rock if that's
93 // exactly what it's asking for.
94 if (actual_feat == DNGN_PERMAROCK_WALL
95 || actual_feat == DNGN_CLEAR_PERMAROCK_WALL)
97 return (feat_wanted == DNGN_PERMAROCK_WALL
98 || feat_wanted == DNGN_CLEAR_PERMAROCK_WALL);
101 return (actual_feat >= DNGN_ROCK_WALL
102 && actual_feat <= DNGN_CLEAR_PERMAROCK_WALL);
105 return (feat_wanted == actual_feat
106 || (feat_wanted == DNGN_DEEP_WATER
107 && (actual_feat == DNGN_SHALLOW_WATER
108 || actual_feat == DNGN_FOUNTAIN_BLUE)));
111 // Can this monster survive on actual_grid?
113 // If you have an actual monster, use this instead of the overloaded function
114 // that uses only the monster class to make decisions.
115 bool monster_habitable_grid(const monsters *m,
116 dungeon_feature_type actual_grid)
118 // Zombified monsters enjoy the same habitat as their original.
119 const monster_type montype = mons_is_zombified(m) ? mons_zombie_base(m)
122 return (monster_habitable_grid(montype, actual_grid, mons_flies(m),
126 inline static bool _mons_airborne(int mcls, int flies, bool paralysed)
129 flies = mons_class_flies(mcls);
131 return (paralysed ? flies == FL_LEVITATE : flies != FL_NONE);
134 // Can monsters of class monster_class live happily on actual_grid?
135 // Use flies == true to pretend the monster can fly.
137 // [dshaligram] We're trying to harmonise the checks from various places into
138 // one check, so we no longer care if a water elemental springs into existence
139 // on dry land, because they're supposed to be able to move onto dry land
141 bool monster_habitable_grid(monster_type montype,
142 dungeon_feature_type actual_grid,
143 int flies, bool paralysed)
145 // No monster may be placed on open sea.
146 if (actual_grid == DNGN_OPEN_SEA)
149 const dungeon_feature_type feat_preferred =
150 habitat2grid(mons_class_primary_habitat(montype));
151 const dungeon_feature_type feat_nonpreferred =
152 habitat2grid(mons_class_secondary_habitat(montype));
154 // Special check for fire elementals since their habitat is floor which
155 // is generally considered compatible with shallow water.
156 if (montype == MONS_FIRE_ELEMENTAL && feat_is_watery(actual_grid))
159 // Krakens are too large for shallow water.
160 if (montype == MONS_KRAKEN && actual_grid == DNGN_SHALLOW_WATER)
163 if (feat_compatible(feat_preferred, actual_grid)
164 || (feat_nonpreferred != feat_preferred
165 && feat_compatible(feat_nonpreferred, actual_grid)))
170 // [dshaligram] Flying creatures are all DNGN_FLOOR, so we
171 // only have to check for the additional valid grids of deep
173 if (_mons_airborne(montype, flies, paralysed)
174 && (actual_grid == DNGN_LAVA || actual_grid == DNGN_DEEP_WATER))
182 // Returns true if the monster can submerge in the given grid.
183 bool monster_can_submerge(const monsters *mons, dungeon_feature_type grid)
185 if (mons->type == MONS_TRAPDOOR_SPIDER && grid == DNGN_FLOOR)
186 return (!find_trap(mons->pos()));
188 switch (mons_primary_habitat(mons))
191 // Monsters can submerge in shallow water - this is intentional.
192 return (feat_is_watery(grid));
195 return (grid == DNGN_LAVA);
202 static bool _need_moderate_ood(int lev_mons)
204 return (env.turns_on_level > 700 - lev_mons * 117);
207 static bool _need_super_ood(int lev_mons)
209 return (env.turns_on_level > 1400 - lev_mons * 117
210 && one_chance_in(5000));
213 static int _fuzz_mons_level(int level)
215 if (one_chance_in(7))
217 const int fuzz = random2avg(9, 2);
218 return (fuzz > 4? level + fuzz - 4 : level);
223 static void _hell_spawn_random_monsters()
225 // Monster generation in the Vestibule drops off quickly.
226 const int taper_off_turn = 500;
228 // genodds increases once you've spent more than 500 turns in Hell.
229 if (env.turns_on_level > taper_off_turn)
231 genodds += (env.turns_on_level - taper_off_turn);
232 genodds = (genodds < 0 ? 20000 : std::min(genodds, 20000));
235 if (x_chance_in_y(5, genodds))
237 mgen_data mg(WANDERING_MONSTER);
238 mg.proximity = (one_chance_in(10) ? PROX_NEAR_STAIRS
239 : PROX_AWAY_FROM_PLAYER);
245 //#define DEBUG_MON_CREATION
247 // This function is now only called about once every 5 turns. (Used to be
248 // every turn independent of how much time an action took, which was not ideal.)
249 // To arrive at spawning rates close to how they used to be, replace the
250 // one_chance_in(value) checks with the new x_chance_in_y(5, value). (jpeg)
251 void spawn_random_monsters()
253 if (crawl_state.arena)
256 #ifdef DEBUG_MON_CREATION
257 mpr("in spawn_random_monsters()", MSGCH_DIAGNOSTICS);
259 if (player_in_branch(BRANCH_VESTIBULE_OF_HELL))
261 _hell_spawn_random_monsters();
265 if (env.spawn_random_rate == 0)
267 #ifdef DEBUG_MON_CREATION
268 mpr("random monster gen turned off", MSGCH_DIAGNOSTICS);
273 const int rate = (you.char_direction == GDT_DESCENDING) ?
274 env.spawn_random_rate : 8;
276 // Place normal dungeon monsters, but not in player LOS.
277 if (you.level_type == LEVEL_DUNGEON && x_chance_in_y(5, rate))
279 #ifdef DEBUG_MON_CREATION
280 mpr("Create wandering monster...", MSGCH_DIAGNOSTICS);
282 proximity_type prox = (one_chance_in(10) ? PROX_NEAR_STAIRS
283 : PROX_AWAY_FROM_PLAYER);
285 // The rules change once the player has picked up the Orb...
286 if (you.char_direction == GDT_ASCENDING)
287 prox = (one_chance_in(6) ? PROX_CLOSE_TO_PLAYER : PROX_ANYWHERE);
289 mgen_data mg(WANDERING_MONSTER);
296 // Place Abyss monsters. (Now happens regularly every 5 turns which might
297 // look a bit strange for a place as chaotic as the Abyss. Then again,
298 // the player is unlikely to meet all of them and notice this.)
299 if (you.level_type == LEVEL_ABYSS
300 && (you.char_direction != GDT_GAME_START
301 || x_chance_in_y(5, rate))
302 && (you.religion != GOD_CHEIBRIADOS || coinflip()))
304 mons_place(mgen_data(WANDERING_MONSTER));
309 // Place Pandemonium monsters.
310 if (you.level_type == LEVEL_PANDEMONIUM && x_chance_in_y(5, rate))
317 // A portal vault *might* decide to turn on random monster spawning,
318 // but it's off by default.
319 if (you.level_type == LEVEL_PORTAL_VAULT && x_chance_in_y(5, rate))
321 mons_place(mgen_data(WANDERING_MONSTER));
325 // No random monsters in the Labyrinth.
328 monster_type pick_random_monster(const level_id &place)
331 if (place.level_type == LEVEL_PORTAL_VAULT)
332 level = you.your_level;
334 level = place.absdepth();
335 return pick_random_monster(place, level, level);
338 monster_type pick_random_monster(const level_id &place, int power,
341 if (crawl_state.arena)
343 monster_type type = arena_pick_random_monster(place, power, lev_mons);
344 if (type != RANDOM_MONSTER)
348 if (place.level_type == LEVEL_LABYRINTH)
349 return (MONS_PROGRAM_BUG);
351 if (place == BRANCH_ECUMENICAL_TEMPLE)
352 return (MONS_PROGRAM_BUG);
354 if (place.level_type == LEVEL_PORTAL_VAULT)
356 monster_type base_type = (monster_type) 0;
358 dungeon_char_type dummy2;
360 _resolve_monster_type(RANDOM_MONSTER, PROX_ANYWHERE, base_type,
361 dummy1, 0, &dummy2, &lev_mons);
363 #if DEBUG || DEBUG_DIAGNOSTICS
364 if (base_type != 0 && base_type != MONS_PROGRAM_BUG)
365 mpr("Random portal vault mon discarding base type.",
371 monster_type mon_type = MONS_PROGRAM_BUG;
375 if (place == BRANCH_MAIN_DUNGEON
376 && lev_mons != 51 && one_chance_in(4))
378 lev_mons = random2(power);
381 if (place == BRANCH_MAIN_DUNGEON
384 // If on D:1, allow moderately out-of-depth monsters only after
385 // a certain elapsed turn count on the level (currently 700 turns).
386 if (lev_mons || _need_moderate_ood(lev_mons))
387 lev_mons = _fuzz_mons_level(lev_mons);
389 // Potentially nasty surprise, but very rare.
390 if (_need_super_ood(lev_mons))
391 lev_mons += random2(12);
393 // Slightly out of depth monsters are more common:
394 // [ds] Replaced with a fuzz above for a more varied mix.
395 //if (need_moderate_ood(lev_mons))
396 // lev_mons += random2(5);
398 lev_mons = std::min(27, lev_mons);
401 // Abyss or Pandemonium. Almost never called from Pan; probably only
402 // if a random demon gets summon anything spell.
404 || place.level_type == LEVEL_PANDEMONIUM
405 || place.level_type == LEVEL_ABYSS)
413 // was: random2(400) {dlb}
414 mon_type = static_cast<monster_type>( random2(NUM_MONSTERS) );
417 while (mons_abyss(mon_type) == 0 && count < 2000);
420 return (MONS_PROGRAM_BUG);
421 if (crawl_state.arena && arena_veto_random_monster(mon_type))
424 while (random2avg(100, 2) > mons_rare_abyss(mon_type)
425 && !one_chance_in(100));
429 int level, diff, chance;
431 lev_mons = std::min(30, lev_mons);
434 for (i = 0; i < 10000; ++i)
440 mon_type = static_cast<monster_type>(random2(NUM_MONSTERS));
443 while (mons_rarity(mon_type, place) == 0 && count < 2000);
446 return (MONS_PROGRAM_BUG);
448 if (crawl_state.arena && arena_veto_random_monster(mon_type))
451 level = mons_level(mon_type, place);
452 diff = level - lev_mons;
453 chance = mons_rarity(mon_type, place) - (diff * diff);
455 if ((lev_mons >= level - 5 && lev_mons <= level + 5)
456 && random2avg(100, 2) <= chance)
463 return (MONS_PROGRAM_BUG);
469 static bool _can_place_on_trap(int mon_type, trap_type trap)
471 if (trap == TRAP_TELEPORT)
474 if (trap == TRAP_SHAFT)
476 if (mon_type == RANDOM_MONSTER)
479 return (mons_class_flies(mon_type) != FL_NONE
480 || get_monster_data(mon_type)->size == SIZE_TINY);
486 bool drac_colour_incompatible(int drac, int colour)
488 return (drac == MONS_DRACONIAN_SCORCHER && colour == MONS_WHITE_DRACONIAN);
491 static monster_type _resolve_monster_type(monster_type mon_type,
492 proximity_type proximity,
493 monster_type &base_type,
496 dungeon_char_type *stair_type,
499 if (mon_type == RANDOM_DRACONIAN)
501 // Pick any random drac, constrained by colour if requested.
505 static_cast<monster_type>(
506 random_range(MONS_BLACK_DRACONIAN,
507 MONS_DRACONIAN_SCORCHER));
509 while (base_type != MONS_PROGRAM_BUG
510 && mon_type != base_type
511 && (mons_species(mon_type) == mon_type
512 || drac_colour_incompatible(mon_type, base_type)));
514 else if (mon_type == RANDOM_BASE_DRACONIAN)
515 mon_type = random_draconian_monster_species();
516 else if (mon_type == RANDOM_NONBASE_DRACONIAN)
519 static_cast<monster_type>(
520 random_range(MONS_DRACONIAN_CALLER, MONS_DRACONIAN_SCORCHER));
523 // (2) Take care of non-draconian random monsters.
524 else if (mon_type == RANDOM_MONSTER)
526 level_id place = level_id::current();
528 // Respect destination level for staircases.
529 if (proximity == PROX_NEAR_STAIRS)
533 while (++tries <= 320)
535 pos = random_in_bounds();
540 // Is the grid verboten?
541 if (!unforbidden( pos, mmask ))
544 // Don't generate monsters on top of teleport traps.
545 const trap_def* ptrap = find_trap(pos);
546 if (ptrap && !_can_place_on_trap(mon_type, ptrap->type))
549 // Check whether there's a stair
550 // and whether it leads to another branch.
551 pval = near_stairs(pos, 1, *stair_type, place.branch);
553 // No monsters spawned in the Temple.
554 if (branches[place.branch].id == BRANCH_ECUMENICAL_TEMPLE)
557 // Found a position near the stairs!
564 // Give up and try somewhere else.
565 proximity = PROX_AWAY_FROM_PLAYER;
569 if (*stair_type == DCHAR_STAIRS_DOWN) // deeper level
571 else if (*stair_type == DCHAR_STAIRS_UP) // higher level
573 // Monsters don't come from outside the dungeon.
576 proximity = PROX_AWAY_FROM_PLAYER;
577 // In that case lev_mons stays as it is.
583 } // end proximity check
585 if (place == BRANCH_HALL_OF_BLADES)
586 mon_type = MONS_DANCING_WEAPON;
589 if (you.level_type == LEVEL_PORTAL_VAULT)
591 if (vault_mon_types.size() == 0)
592 return (MONS_PROGRAM_BUG);
594 int i = choose_random_weighted(vault_mon_weights.begin(),
595 vault_mon_weights.end());
596 int type = vault_mon_types[i];
597 int base = vault_mon_bases[i];
601 place = level_id::from_packed_place(base);
602 // If lev_mons is set to you.your_level, it was probably
603 // set as a default meaning "the current dungeon depth",
604 // which for a portal vault using its own definition
605 // of random monsters means "the depth of whatever place
606 // we're using for picking the random monster".
607 if (*lev_mons == you.your_level)
608 *lev_mons = place.absdepth();
609 // pick_random_monster() is called below
613 base_type = (monster_type) base;
614 mon_type = (monster_type) type;
615 if (mon_type == RANDOM_DRACONIAN
616 || mon_type == RANDOM_BASE_DRACONIAN
617 || mon_type == RANDOM_NONBASE_DRACONIAN)
620 _resolve_monster_type(mon_type, proximity,
621 base_type, pos, mmask,
622 stair_type, lev_mons);
629 while (tries++ < 300)
631 // Now pick a monster of the given branch and level.
632 mon_type = pick_random_monster(place, *lev_mons, *lev_mons);
634 // Don't allow monsters too stupid to use stairs (e.g.
635 // non-spectral zombified undead) to be placed near
637 if (proximity != PROX_NEAR_STAIRS
638 || mons_class_can_use_stairs(mon_type))
644 if (proximity == PROX_NEAR_STAIRS && tries >= 300)
646 proximity = PROX_AWAY_FROM_PLAYER;
648 // Reset target level.
649 if (*stair_type == DCHAR_STAIRS_DOWN)
651 else if (*stair_type == DCHAR_STAIRS_UP)
654 mon_type = pick_random_monster(place, *lev_mons, *lev_mons);
661 // A short function to check the results of near_stairs().
662 // Returns 0 if the point is not near stairs.
663 // Returns 1 if the point is near unoccupied stairs.
664 // Returns 2 if the point is near player-occupied stairs.
665 static int _is_near_stairs(coord_def &p)
669 for (int i = -1; i <= 1; ++i)
670 for (int j = -1; j <= 1; ++j)
675 const dungeon_feature_type feat = grd(p);
676 if (feat_is_stair(feat))
678 // Shouldn't matter for escape hatches.
679 if (feat_is_escape_hatch(feat))
682 // Should there be several stairs, don't overwrite the
683 // player on stairs info.
685 result = (p == you.pos()) ? 2 : 1;
692 // Checks if the monster is ok to place at mg_pos. If force_location
693 // is true, then we'll be less rigorous in our checks, in particular
694 // allowing land monsters to be placed in shallow water and water
695 // creatures in fountains.
696 static bool _valid_monster_generation_location(
698 const coord_def &mg_pos)
700 if (!in_bounds(mg_pos) || actor_at(mg_pos))
703 const monster_type montype = (mons_class_is_zombified(mg.cls) ? mg.base_type
705 if (!monster_habitable_grid(montype, grd(mg_pos),
706 mons_class_flies(montype), false)
707 || (mg.behaviour != BEH_FRIENDLY && is_sanctuary(mg_pos)))
712 // Don't generate monsters on top of teleport traps.
713 // (How did they get there?)
714 const trap_def* ptrap = find_trap(mg_pos);
715 if (ptrap && !_can_place_on_trap(mg.cls, ptrap->type))
721 static bool _valid_monster_generation_location(mgen_data &mg)
723 return _valid_monster_generation_location(mg, mg.pos);
726 int place_monster(mgen_data mg, bool force_pos)
728 #ifdef DEBUG_MON_CREATION
729 mpr("in place_monster()", MSGCH_DIAGNOSTICS);
733 dungeon_char_type stair_type = NUM_DCHAR_TYPES;
736 // (1) Early out (summoned to occupied grid).
737 if (mg.use_position() && monster_at(mg.pos))
740 mg.cls = _resolve_monster_type(mg.cls, mg.proximity, mg.base_type,
742 &stair_type, &mg.power);
744 if (mg.cls == MONS_NO_MONSTER)
747 // (3) Decide on banding (good lord!)
749 monster_type band_monsters[BIG_BAND]; // band monster types
750 band_monsters[0] = mg.cls;
752 // The (very) ugly thing band colour.
753 static unsigned char ugly_colour = BLACK;
755 if (mg.permit_bands())
757 #ifdef DEBUG_MON_CREATION
758 mpr("Choose band members...", MSGCH_DIAGNOSTICS);
760 const band_type band = _choose_band(mg.cls, mg.power, band_size);
763 for (int i = 1; i < band_size; ++i)
765 band_monsters[i] = _band_member(band, mg.power);
767 // Get the (very) ugly thing band colour, so that all (very)
768 // ugly things in a band will start with it.
769 if ((band_monsters[i] == MONS_UGLY_THING
770 || band_monsters[i] == MONS_VERY_UGLY_THING)
771 && ugly_colour == BLACK)
773 ugly_colour = ugly_thing_random_colour();
778 // Set the (very) ugly thing band colour.
779 if (ugly_colour != BLACK)
780 mg.colour = ugly_colour;
782 // Returns 2 if the monster is placed near player-occupied stairs.
783 int pval = _is_near_stairs(mg.pos);
784 if (mg.proximity == PROX_NEAR_STAIRS)
786 // For some cases disallow monsters on stairs.
787 if (mons_class_is_stationary(mg.cls)
788 || (pval == 2 // Stairs occupied by player.
789 && (mons_class_base_speed(mg.cls) == 0
790 || grd(mg.pos) == DNGN_LAVA
791 || grd(mg.pos) == DNGN_DEEP_WATER)))
793 mg.proximity = PROX_AWAY_FROM_PLAYER;
797 // (4) For first monster, choose location. This is pretty intensive.
799 bool close_to_player;
801 // Player shoved out of the way?
804 if (!mg.use_position())
808 // Try to pick a position that is
811 // c) in the 'correct' proximity to the player
815 // Dropped number of tries from 60.
819 // Placement already decided for PROX_NEAR_STAIRS.
820 // Else choose a random point on the map.
821 if (mg.proximity != PROX_NEAR_STAIRS)
822 mg.pos = random_in_bounds();
824 if (!_valid_monster_generation_location(mg))
827 // Is the grid verboten?
828 if (!unforbidden(mg.pos, mg.map_mask))
831 // Let's recheck these even for PROX_NEAR_STAIRS, just in case.
832 // Check proximity to player.
835 switch (mg.proximity)
838 if (grid_distance( you.pos(), mg.pos ) < 2 + random2(3))
842 case PROX_CLOSE_TO_PLAYER:
843 case PROX_AWAY_FROM_PLAYER:
844 // If this is supposed to measure los vs not los,
845 // then see_cell(mg.pos) should be used instead. (jpeg)
846 close_to_player = (distance(you.pos(), mg.pos) < 64);
848 if (mg.proximity == PROX_CLOSE_TO_PLAYER && !close_to_player
849 || mg.proximity == PROX_AWAY_FROM_PLAYER && close_to_player)
855 case PROX_NEAR_STAIRS:
856 if (pval == 2) // player on stairs
858 if (mons_class_base_speed(mg.cls) == 0)
863 // Swap the monster and the player spots, unless the
864 // monster was generated in lava or deep water.
865 if (grd(mg.pos) == DNGN_LAVA
866 || grd(mg.pos) == DNGN_DEEP_WATER)
872 // You can't be shoved if you're caught in a net.
880 coord_def mpos = mg.pos;
891 // Cool.. passes all tests.
893 } // end while... place first monster
895 else if (!_valid_monster_generation_location(mg))
897 // Sanity check that the specified position is valid.
901 id = _place_monster_aux(mg, true, force_pos);
903 // Reset the (very) ugly thing band colour.
904 if (ugly_colour != BLACK)
907 // Bail out now if we failed.
911 monsters *mon = &menv[id];
912 if (mg.needs_patrol_point())
914 mon->patrol_point = mon->pos();
915 #ifdef DEBUG_PATHFIND
916 mprf("Monster %s is patrolling around (%d, %d).",
917 mon->name(DESC_PLAIN).c_str(), mon->pos().x, mon->pos().y);
921 // Message to player from stairwell/gate appearance.
922 if (observe_cell(mg.pos) && mg.proximity == PROX_NEAR_STAIRS)
926 if (menv[id].visible_to(&you))
927 msg = menv[id].name(DESC_CAP_A);
933 msg += " shoves you out of the ";
934 if (stair_type == DCHAR_ARCH)
940 else if (!msg.empty())
942 if (stair_type == DCHAR_STAIRS_DOWN)
943 msg += " comes up the stairs.";
944 else if (stair_type == DCHAR_STAIRS_UP)
945 msg += " comes down the stairs.";
946 else if (stair_type == DCHAR_ARCH)
947 msg += " comes through the gate.";
955 // Special case: must update the view for monsters created
960 // Now, forget about banding if the first placement failed, or there are
961 // too many monsters already, or we successfully placed by stairs.
962 if (id >= MAX_MONSTERS - 30 || mg.proximity == PROX_NEAR_STAIRS)
965 // Not PROX_NEAR_STAIRS, so it will be part of a band, if there is any.
967 menv[id].flags |= MF_BAND_MEMBER;
969 const bool priest = mon->is_priest();
971 mgen_data band_template = mg;
972 // (5) For each band monster, loop call to place_monster_aux().
973 for (int i = 1; i < band_size; i++)
975 if (band_monsters[i] == MONS_NO_MONSTER)
978 band_template.cls = band_monsters[i];
980 // We don't want to place a unique that has already been
982 if (mons_is_unique(band_template.cls)
983 && you.unique_creatures[band_template.cls])
988 const int band_id = _place_monster_aux(band_template, false);
989 if (band_id != -1 && band_id != NON_MONSTER)
991 menv[band_id].flags |= MF_BAND_MEMBER;
992 // Priestly band leaders should have an entourage of the
995 menv[band_id].god = mon->god;
999 // Placement of first monster, at least, was a success.
1003 static int _place_monster_aux(const mgen_data &mg,
1004 bool first_band_member, bool force_pos)
1009 // Gotta be able to pick an ID.
1010 for (id = 0; id < MAX_MONSTERS; id++)
1011 if (menv[id].type == MONS_NO_MONSTER)
1014 // Too many monsters on level?
1015 if (id == MAX_MONSTERS)
1020 const monster_type montype = (mons_class_is_zombified(mg.cls) ? mg.base_type
1023 // Setup habitat and placement.
1024 // If the space is occupied, try some neighbouring square instead.
1025 if (first_band_member && in_bounds(mg.pos)
1026 && (mg.behaviour == BEH_FRIENDLY || !is_sanctuary(mg.pos))
1027 && actor_at(mg.pos) == NULL
1028 && (force_pos || monster_habitable_grid(montype, grd(mg.pos))))
1035 // We'll try 1000 times for a good spot.
1036 for (i = 0; i < 1000; ++i)
1038 fpos = mg.pos + coord_def( random_range(-3, 3),
1039 random_range(-3, 3) );
1041 if (_valid_monster_generation_location(mg, fpos))
1045 // Did we really try 1000 times?
1050 ASSERT(!monster_at(fpos));
1052 if (crawl_state.arena
1053 && arena_veto_place_monster(mg, first_band_member, fpos))
1058 monsters &mons(menv[id]);
1059 // Now, actually create the monster. (Wheeee!)
1061 mons.base_monster = mg.base_type;
1062 mons.number = mg.number;
1066 // Link monster into monster grid.
1069 // Generate a brand shiny new monster, or zombie.
1070 if (mons_class_is_zombified(mg.cls))
1071 _define_zombie(id, mg.base_type, mg.cls, mg.power, fpos);
1075 // Is it a god gift?
1076 if (mg.god != GOD_NO_GOD)
1079 mons.flags |= MF_GOD_GIFT;
1081 // Not a god gift, give priestly monsters a god.
1082 else if (mons_class_flag(mg.cls, M_PRIEST))
1084 switch (mons_genus(mg.cls))
1087 mons.god = GOD_BEOGH;
1090 mons.god = GOD_JIYVA;
1093 case MONS_DRACONIAN:
1095 // [ds] Vault defs can request priest monsters of unusual types.
1097 mons.god = GOD_NAMELESS;
1101 // 1 out of 7 non-priestly orcs are unbelievers.
1102 else if (mons_genus(mg.cls) == MONS_ORC)
1104 if (!one_chance_in(7))
1105 mons.god = GOD_BEOGH;
1107 // The royal jelly belongs to Jiyva.
1108 else if (mg.cls == MONS_ROYAL_JELLY)
1109 mons.god = GOD_JIYVA;
1110 // Angels and Daevas belong to TSO, but 1 out of 7 in the Abyss are
1112 else if (mons_class_holiness(mg.cls) == MH_HOLY)
1114 if (mg.level_type != LEVEL_ABYSS || !one_chance_in(7))
1115 mons.god = GOD_SHINING_ONE;
1119 // 6 out of 7 demons in the Abyss belong to Lugonu.
1120 else if (mons_class_holiness(mg.cls) == MH_DEMONIC)
1122 if (mg.level_type == LEVEL_ABYSS && !one_chance_in(7))
1123 mons.god = GOD_LUGONU;
1126 // If the caller requested a specific colour for this monster, apply
1128 if (mg.colour != BLACK)
1129 mons.colour = mg.colour;
1132 mons.mname = mg.mname;
1134 // The return of Boris is now handled in monster_die(). Not setting
1135 // this for Boris here allows for multiple Borises in the dungeon at
1136 // the same time. - bwr
1137 if (mons_is_unique(mg.cls))
1138 you.unique_creatures[mg.cls] = true;
1140 if (mons_class_flag(mg.cls, M_INVIS))
1141 mons.add_ench(ENCH_INVIS);
1143 if (mons_class_flag(mg.cls, M_CONFUSED))
1144 mons.add_ench(ENCH_CONFUSION);
1146 if (mg.cls == MONS_SHAPESHIFTER)
1147 mons.add_ench(ENCH_SHAPESHIFTER);
1149 if (mg.cls == MONS_GLOWING_SHAPESHIFTER)
1150 mons.add_ench(ENCH_GLOWING_SHAPESHIFTER);
1152 if (mg.cls == MONS_TOADSTOOL)
1154 // This enchantment is a timer that counts down until death.
1155 // It should last longer than the lifespan of a corpse, to avoid
1156 // spawning mushrooms in the same place over and over. Aside
1157 // from that, the value is slightly randomised to avoid
1158 // simultaneous die-offs of mushroom rings.
1159 mons.add_ench(ENCH_SLOWLY_DYING);
1162 if (mg.cls == MONS_BALLISTOMYCETE)
1164 // This enchantment causes giant spore production.
1165 mons.add_ench(ENCH_SPORE_PRODUCTION);
1168 if (monster_can_submerge(&mons, grd(fpos)) && !one_chance_in(5))
1169 mons.add_ench(ENCH_SUBMERGED);
1171 mons.flags |= MF_JUST_SUMMONED;
1173 // Don't leave shifters in their starting shape.
1174 if (mg.cls == MONS_SHAPESHIFTER || mg.cls == MONS_GLOWING_SHAPESHIFTER)
1177 monster_polymorph(&mons, RANDOM_MONSTER);
1179 // It's not actually a known shapeshifter if it happened to be
1180 // placed in LOS of the player.
1181 mons.flags &= ~MF_KNOWN_MIMIC;
1184 // dur should always be 1-6 for monsters that can be abjured.
1185 const bool summoned = mg.abjuration_duration >= 1
1186 && mg.abjuration_duration <= 6;
1188 if (mg.cls == MONS_DANCING_WEAPON)
1190 give_item(id, mg.power, summoned);
1192 // Dancing weapons *always* have a weapon. Fail to create them
1194 const item_def* wpn = mons.mslot_item(MSLOT_WEAPON);
1197 mons.destroy_inventory();
1199 mgrd(fpos) = NON_MONSTER;
1203 mons.colour = wpn->colour;
1205 else if (mons_class_itemuse(mg.cls) >= MONUSE_STARTING_EQUIPMENT)
1207 give_item(id, mg.power, summoned);
1208 // Give these monsters a second weapon -- bwr
1209 if (mons_class_wields_two_weapons(mg.cls))
1210 give_item(id, mg.power, summoned);
1212 unwind_var<int> save_speedinc(mons.speed_increment);
1213 mons.wield_melee_weapon(false);
1216 // Give manticores 8 to 16 spike volleys.
1217 if (mg.cls == MONS_MANTICORE)
1218 mons.number = 8 + random2(9);
1220 if (mg.cls == MONS_SLIME_CREATURE)
1224 // Boost HP to what it would have been if it had grown this
1226 mons.hit_points *= mg.number;
1227 mons.max_hit_points *= mg.number;
1231 // Set attitude, behaviour and target.
1232 mons.attitude = ATT_HOSTILE;
1233 mons.behaviour = mg.behaviour;
1235 // Statues cannot sleep (nor wander but it means they are a bit
1236 // more aware of the player than they'd be otherwise).
1237 if (mons_is_statue(mg.cls))
1238 mons.behaviour = BEH_WANDER;
1240 mons.foe_memory = 0;
1242 // Setting attitude will always make the monster wander...
1243 // If you want sleeping hostiles, use BEH_SLEEP since the default
1244 // attitude is hostile.
1245 if (mg.behaviour > NUM_BEHAVIOURS)
1247 if (mg.behaviour == BEH_FRIENDLY)
1248 mons.attitude = ATT_FRIENDLY;
1250 if (mg.behaviour == BEH_GOOD_NEUTRAL)
1251 mons.attitude = ATT_GOOD_NEUTRAL;
1253 if (mg.behaviour == BEH_NEUTRAL)
1254 mons.attitude = ATT_NEUTRAL;
1256 if (mg.behaviour == BEH_STRICT_NEUTRAL)
1257 mons.attitude = ATT_STRICT_NEUTRAL;
1259 mons.behaviour = BEH_WANDER;
1264 mons.mark_summoned(mg.abjuration_duration, true,
1269 // Initialise (very) ugly things and pandemonium demons.
1270 if (mons.type == MONS_UGLY_THING
1271 || mons.type == MONS_VERY_UGLY_THING)
1274 ghost.init_ugly_thing(mons.type == MONS_VERY_UGLY_THING, false,
1276 mons.set_ghost(ghost, false);
1277 mons.uglything_init();
1279 else if (mons.type == MONS_PANDEMONIUM_DEMON)
1282 ghost.init_random_demon();
1283 mons.set_ghost(ghost);
1284 mons.pandemon_init();
1286 else if (mons.type == MONS_DANCING_WEAPON)
1289 // We can't use monsters::weapon here because it wants to look
1290 // at attack types, which are in the ghost structure we're
1292 ASSERT( mons.mslot_item(MSLOT_WEAPON) );
1293 // Dancing weapons are placed at pretty high power. Remember, the
1294 // player is fighting them one-on-one, while he will often summon
1296 ghost.init_dancing_weapon(*(mons.mslot_item(MSLOT_WEAPON)), 180);
1297 mons.set_ghost(ghost);
1298 mons.dancing_weapon_init();
1301 mark_interesting_monst(&mons, mg.behaviour);
1303 if (you.can_see(&mons))
1304 handle_seen_interrupt(&mons);
1306 if (crawl_state.arena)
1307 arena_placed_monster(&mons);
1312 monster_type pick_random_zombie()
1314 static std::vector<monster_type> zombifiable;
1315 if (zombifiable.empty())
1317 for (int i = 0; i < NUM_MONSTERS; ++i)
1319 if (mons_species(i) != i || i == MONS_PROGRAM_BUG)
1322 const monster_type mcls = static_cast<monster_type>(i);
1323 if (!mons_zombie_size(mcls))
1326 zombifiable.push_back(mcls);
1329 return (zombifiable[random2(zombifiable.size())]);
1332 monster_type pick_local_zombifiable_monster_type(int power)
1334 // Generates a dummy zombie likely to be found.
1335 // Ripped wholly from _define_zombie().
1337 power = std::min(27, power);
1338 // How OOD this zombie can be.
1341 // Pick an appropriate creature to make a zombie out of, levelwise.
1342 // The old code was generating absolutely incredible OOD zombies.
1346 cls = pick_random_zombie();
1348 bool ignore_rarity = false;
1349 // On certain branches, zombie creation will fail if we use the
1350 // mons_rarity() functions, because (for example) there are NO
1351 // zombifiable "native" abyss creatures. Other branches where
1352 // this is a problem are Hell levels and the Crypt. We have to
1353 // watch for summoned zombies on other levels, too, such as the
1354 // Temple, the Hall of Blades and the Slime Pits.
1355 if (you.level_type != LEVEL_DUNGEON
1357 || player_in_branch(BRANCH_HALL_OF_ZOT)
1358 || player_in_branch(BRANCH_VESTIBULE_OF_HELL)
1359 || player_in_branch(BRANCH_ECUMENICAL_TEMPLE)
1360 || player_in_branch(BRANCH_CRYPT)
1361 || player_in_branch(BRANCH_TOMB)
1362 || player_in_branch(BRANCH_HALL_OF_BLADES)
1363 || player_in_branch(BRANCH_SNAKE_PIT)
1364 || player_in_branch(BRANCH_SLIME_PITS)
1365 || one_chance_in(1000))
1367 ignore_rarity = true;
1370 // Don't make out-of-rarity zombies when we don't have to.
1371 if (!ignore_rarity && mons_rarity(cls) == 0)
1374 // Check for rarity.. and OOD - identical to mons_place().
1375 int level, diff, chance;
1377 level = mons_level(cls) - 4;
1378 diff = level - power;
1380 chance = (ignore_rarity) ? 100
1381 : mons_rarity(cls) - (diff * diff) / 2;
1383 if (power > level - relax && power < level + relax
1384 && random2avg(100, 2) <= chance)
1389 // Every so often, we'll relax the OOD restrictions. This
1390 // avoids infinite loops. If we don't do this, things like
1391 // creating a large skeleton on level 1 may hang the game!
1392 if (one_chance_in(5))
1396 return (monster_type)cls;
1399 static void _define_zombie(int mid, monster_type ztype, monster_type cs,
1400 int power, coord_def pos)
1402 ASSERT(mons_class_is_zombified(cs));
1404 monster_type cls = MONS_PROGRAM_BUG;
1405 monster_type mons_sec2 = MONS_PROGRAM_BUG;
1406 zombie_size_type zombie_size = Z_NOZOMBIE;
1407 bool ignore_rarity = false;
1409 power = std::min(27, power);
1411 // Set size based on zombie class (cs).
1414 case MONS_ZOMBIE_SMALL:
1415 case MONS_SIMULACRUM_SMALL:
1416 case MONS_SKELETON_SMALL:
1417 zombie_size = Z_SMALL;
1420 case MONS_ZOMBIE_LARGE:
1421 case MONS_SIMULACRUM_LARGE:
1422 case MONS_SKELETON_LARGE:
1423 zombie_size = Z_BIG;
1426 case MONS_SPECTRAL_THING:
1433 // That is, random creature from which to fashion undead.
1434 if (ztype == MONS_NO_MONSTER)
1436 // How OOD this zombie can be.
1439 // Pick an appropriate creature to make a zombie out of,
1440 // levelwise. The old code was generating absolutely
1441 // incredible OOD zombies.
1444 cls = pick_random_zombie();
1446 // Actually pick a monster that is happy where we want to put it.
1447 // Fish zombies on land are helpless and uncool.
1448 if (!monster_habitable_grid(cls, grd(pos)))
1451 // On certain branches, zombie creation will fail if we use
1452 // the mons_rarity() functions, because (for example) there
1453 // are NO zombifiable "native" abyss creatures. Other branches
1454 // where this is a problem are hell levels and the crypt.
1455 // we have to watch for summoned zombies on other levels, too,
1456 // such as the Temple, HoB, and Slime Pits.
1457 if (you.level_type != LEVEL_DUNGEON
1459 || player_in_branch(BRANCH_HALL_OF_ZOT)
1460 || player_in_branch(BRANCH_VESTIBULE_OF_HELL)
1461 || player_in_branch(BRANCH_ECUMENICAL_TEMPLE)
1462 || player_in_branch(BRANCH_CRYPT)
1463 || player_in_branch(BRANCH_TOMB)
1464 || player_in_branch(BRANCH_HALL_OF_BLADES)
1465 || player_in_branch(BRANCH_SNAKE_PIT)
1466 || player_in_branch(BRANCH_SLIME_PITS)
1467 || one_chance_in(1000))
1469 ignore_rarity = true;
1472 // Don't make out-of-rarity zombies when we don't have to.
1473 if (!ignore_rarity && mons_rarity(cls) == 0)
1476 // If skeleton, monster must have a skeleton.
1477 if ((cs == MONS_SKELETON_SMALL || cs == MONS_SKELETON_LARGE)
1478 && !mons_skeleton(cls))
1483 // Size must match, but you can make a spectral thing out
1485 if (cs != MONS_SPECTRAL_THING
1486 && mons_zombie_size(cls) != zombie_size)
1491 if (cs == MONS_SKELETON_SMALL || cs == MONS_SIMULACRUM_SMALL)
1493 // Skeletal or icy draconians shouldn't be coloured.
1494 // How could you tell?
1495 if (mons_genus(cls) == MONS_DRACONIAN
1496 && cls != MONS_DRACONIAN)
1498 cls = MONS_DRACONIAN;
1500 // The same goes for rats.
1501 else if (mons_genus(cls) == MONS_RAT
1508 // Hack -- non-dungeon zombies are always made out of nastier
1510 if (you.level_type != LEVEL_DUNGEON && mons_power(cls) > 8)
1513 // Check for rarity.. and OOD - identical to mons_place()
1514 int level, diff, chance;
1516 level = mons_level(cls) - 4;
1517 diff = level - power;
1519 chance = (ignore_rarity) ? 100
1520 : mons_rarity(cls) - (diff * diff) / 2;
1522 if (power > level - relax && power < level + relax
1523 && random2avg(100, 2) <= chance)
1528 // Every so often, we'll relax the OOD restrictions. Avoids
1529 // infinite loops (if we don't do this, things like creating
1530 // a large skeleton on level 1 may hang the game!).
1531 if (one_chance_in(5))
1535 // Set type and secondary appropriately.
1536 menv[mid].base_monster = cls;
1541 menv[mid].base_monster = mons_species(ztype);
1542 mons_sec2 = menv[mid].base_monster;
1545 // Set type to the base type to calculate appropriate stats.
1546 menv[mid].type = menv[mid].base_monster;
1548 define_monster(mid);
1550 menv[mid].hit_points = hit_points(menv[mid].hit_dice, 6, 5);
1551 menv[mid].max_hit_points = menv[mid].hit_points;
1554 menv[mid].ac = std::max(0, menv[mid].ac);
1557 menv[mid].ev = std::max(0, menv[mid].ev);
1559 menv[mid].speed = mons_class_zombie_base_speed(menv[mid].base_monster);
1561 // Now override type with the required type.
1562 if (cs == MONS_ZOMBIE_SMALL || cs == MONS_ZOMBIE_LARGE)
1564 menv[mid].type = ((mons_zombie_size(menv[mid].base_monster) == Z_BIG) ?
1565 MONS_ZOMBIE_LARGE : MONS_ZOMBIE_SMALL);
1567 else if (cs == MONS_SKELETON_SMALL || cs == MONS_SKELETON_LARGE)
1569 menv[mid].hit_points = hit_points(menv[mid].hit_dice, 5, 4);
1570 menv[mid].max_hit_points = menv[mid].hit_points;
1573 menv[mid].ac = std::max(0, menv[mid].ac);
1576 menv[mid].ev = std::max(0, menv[mid].ev);
1578 menv[mid].type = ((mons_zombie_size(menv[mid].base_monster) == Z_BIG) ?
1579 MONS_SKELETON_LARGE : MONS_SKELETON_SMALL);
1581 else if (cs == MONS_SIMULACRUM_SMALL || cs == MONS_SIMULACRUM_LARGE)
1583 // Simulacra aren't tough, but you can create piles of them. - bwr
1584 menv[mid].hit_points = hit_points(menv[mid].hit_dice, 1, 4);
1585 menv[mid].max_hit_points = menv[mid].hit_points;
1587 menv[mid].type = ((mons_zombie_size(menv[mid].base_monster) == Z_BIG) ?
1588 MONS_SIMULACRUM_LARGE : MONS_SIMULACRUM_SMALL);
1590 else if (cs == MONS_SPECTRAL_THING)
1592 menv[mid].hit_points = hit_points(menv[mid].hit_dice, 4, 4);
1593 menv[mid].max_hit_points = menv[mid].hit_points;
1597 menv[mid].type = MONS_SPECTRAL_THING;
1600 menv[mid].base_monster = mons_sec2;
1601 menv[mid].colour = mons_class_colour(cs);
1604 static band_type _choose_band(int mon_type, int power, int &band_size)
1606 #ifdef DEBUG_MON_CREATION
1607 mpr("in _choose_band()", MSGCH_DIAGNOSTICS);
1609 // Band size describes the number of monsters in addition to
1611 band_size = 0; // Single monster, no band.
1612 band_type band = BAND_NO_BAND;
1619 // intentional fall-through {dlb}
1620 case MONS_ORC_WIZARD:
1622 band_size = 2 + random2(3);
1625 case MONS_ORC_PRIEST:
1626 case MONS_ORC_WARRIOR:
1627 band = BAND_ORC_WARRIOR;
1628 band_size = 2 + random2(3);
1631 case MONS_ORC_WARLORD:
1632 case MONS_SAINT_ROKA:
1633 band_size = 5 + random2(5); // warlords have large bands
1634 // intentional fall through
1635 case MONS_ORC_KNIGHT:
1636 band = BAND_ORC_KNIGHT; // orcs + knight
1637 band_size += 3 + random2(4);
1640 case MONS_ORC_HIGH_PRIEST:
1641 band = BAND_ORC_HIGH_PRIEST;
1642 band_size = 4 + random2(4);
1645 case MONS_BIG_KOBOLD:
1648 band = BAND_KOBOLDS;
1649 band_size = 2 + random2(6);
1653 case MONS_KILLER_BEE:
1654 band = BAND_KILLER_BEES;
1655 band_size = 2 + random2(4);
1658 case MONS_FLYING_SKULL:
1659 band = BAND_FLYING_SKULLS;
1660 band_size = 2 + random2(4);
1662 case MONS_SLIME_CREATURE:
1663 band = BAND_SLIME_CREATURES;
1664 band_size = 2 + random2(4);
1668 band_size = 2 + random2(4);
1670 case MONS_UGLY_THING:
1671 case MONS_VERY_UGLY_THING:
1672 band = BAND_UGLY_THINGS;
1673 band_size = 2 + random2(4);
1675 case MONS_HELL_HOUND:
1676 band = BAND_HELL_HOUNDS;
1677 band_size = 2 + random2(3);
1680 band = BAND_JACKALS;
1681 band_size = 1 + random2(3);
1683 case MONS_HELL_KNIGHT:
1685 band = BAND_HELL_KNIGHTS;
1686 band_size = 4 + random2(4);
1688 case MONS_JOSEPHINE:
1689 case MONS_NECROMANCER:
1690 case MONS_VAMPIRE_MAGE:
1691 band = BAND_NECROMANCER;
1692 band_size = 4 + random2(4);
1696 band_size = (coinflip() ? 3 : 2);
1699 band = BAND_WAR_DOGS;
1700 band_size = 2 + random2(3);
1702 case MONS_BUMBLEBEE:
1703 band = BAND_BUMBLEBEES;
1704 band_size = 2 + random2(4);
1707 case MONS_CENTAUR_WARRIOR:
1708 if (power > 9 && one_chance_in(3))
1710 band = BAND_CENTAURS;
1711 band_size = 2 + random2(4);
1716 case MONS_YAKTAUR_CAPTAIN:
1719 band = BAND_YAKTAURS;
1720 band_size = 2 + random2(3);
1724 case MONS_DEATH_YAK:
1725 band = BAND_DEATH_YAKS;
1726 band_size = 2 + random2(4);
1728 case MONS_INSUBSTANTIAL_WISP:
1729 band = BAND_INSUBSTANTIAL_WISPS;
1730 band_size = 4 + random2(5);
1732 case MONS_OGRE_MAGE:
1733 band = BAND_OGRE_MAGE;
1734 band_size = 4 + random2(4);
1737 band = BAND_BALRUG; // RED gr demon
1738 band_size = 2 + random2(3);
1740 case MONS_CACODEMON:
1741 band = BAND_CACODEMON; // BROWN gr demon
1742 band_size = 1 + random2(3);
1745 case MONS_EXECUTIONER:
1748 band = BAND_EXECUTIONER; // DARKGREY gr demon
1749 band_size = 1 + random2(3);
1753 case MONS_PANDEMONIUM_DEMON:
1754 band = BAND_PANDEMONIUM_DEMON;
1755 band_size = random_range(1, 3);
1761 band = BAND_HELLWING; // LIGHTGREY gr demon
1762 band_size = 1 + random2(4);
1766 case MONS_DEEP_ELF_FIGHTER:
1769 band = BAND_DEEP_ELF_FIGHTER;
1770 band_size = 3 + random2(4);
1774 case MONS_DEEP_ELF_KNIGHT:
1777 band = BAND_DEEP_ELF_KNIGHT;
1778 band_size = 3 + random2(4);
1782 case MONS_DEEP_ELF_HIGH_PRIEST:
1785 band = BAND_DEEP_ELF_HIGH_PRIEST;
1786 band_size = 3 + random2(4);
1790 case MONS_KOBOLD_DEMONOLOGIST:
1793 band = BAND_KOBOLD_DEMONOLOGIST;
1794 band_size = 3 + random2(6);
1798 case MONS_NAGA_MAGE:
1799 case MONS_NAGA_WARRIOR:
1801 band_size = 3 + random2(4);
1805 band = BAND_WAR_DOGS;
1806 band_size = 2 + random2(4);
1810 band = BAND_GREY_RATS;
1811 band_size = 4 + random2(6);
1814 case MONS_GREEN_RAT:
1815 band = BAND_GREEN_RATS;
1816 band_size = 4 + random2(6);
1819 case MONS_ORANGE_RAT:
1820 band = BAND_ORANGE_RATS;
1821 band_size = 3 + random2(4);
1826 band_size = 3 + random2(5);
1831 band_size = 2 + random2(3);
1835 band_size = 2 + random2(3);
1838 band_size += 1 + random2(3);
1841 case MONS_GIANT_MOSQUITO:
1842 band = BAND_GIANT_MOSQUITOES;
1843 band_size = 1 + random2(3);
1846 case MONS_DEEP_TROLL:
1847 band = BAND_DEEP_TROLLS;
1848 band_size = 3 + random2(3);
1852 band = BAND_HELL_HOGS;
1853 band_size = 1 + random2(3);
1857 band = BAND_BOGGARTS;
1858 band_size = 2 + random2(3);
1861 case MONS_BLINK_FROG:
1862 band = BAND_BLINK_FROGS;
1863 band_size = 2 + random2(3);
1866 case MONS_SKELETAL_WARRIOR:
1867 band = BAND_SKELETAL_WARRIORS;
1868 band_size = 2 + random2(3);
1872 if (one_chance_in(5) || player_in_branch(BRANCH_SHOALS))
1874 band = BAND_SHEEP; // Odyssey reference
1875 band_size = 2 + random2(3);
1879 case MONS_POLYPHEMUS:
1880 band = BAND_DEATH_YAKS;
1881 band_size = 3 + random2(3);
1885 band = BAND_HARPIES;
1886 band_size = 2 + random2(3);
1889 // Journey -- Added Draconian Packs
1890 case MONS_WHITE_DRACONIAN:
1891 case MONS_RED_DRACONIAN:
1892 case MONS_PURPLE_DRACONIAN:
1893 case MONS_MOTTLED_DRACONIAN:
1894 case MONS_YELLOW_DRACONIAN:
1895 case MONS_BLACK_DRACONIAN:
1896 case MONS_GREEN_DRACONIAN:
1897 case MONS_PALE_DRACONIAN:
1898 if (power > 18 && one_chance_in(3) && you.level_type == LEVEL_DUNGEON)
1900 band = BAND_DRACONIAN;
1901 band_size = random_range(2, 4);
1905 case MONS_DRACONIAN_CALLER:
1906 case MONS_DRACONIAN_MONK:
1907 case MONS_DRACONIAN_SCORCHER:
1908 case MONS_DRACONIAN_KNIGHT:
1909 case MONS_DRACONIAN_ANNIHILATOR:
1910 case MONS_DRACONIAN_ZEALOT:
1911 case MONS_DRACONIAN_SHIFTER:
1912 if (power > 20 && you.level_type == LEVEL_DUNGEON)
1914 band = BAND_DRACONIAN;
1915 band_size = random_range(3, 6);
1920 band = BAND_DRACONIAN;
1922 band_size = random_range(3,6) + random_range(3,6) + 2;
1927 band_size = 3 + random2(3);
1932 band_size = 4 + random2(5);
1936 band = BAND_DUVESSA;
1945 case MONS_GOLDEN_EYE:
1946 band = BAND_GOLDEN_EYE;
1947 band_size = 1 + random2(5);
1952 band_size = 1 + random2(3);
1957 if (band != BAND_NO_BAND && band_size == 0)
1958 band = BAND_NO_BAND;
1960 if (band_size >= BIG_BAND)
1961 band_size = BIG_BAND - 1;
1966 static monster_type _band_member(band_type band, int power)
1968 monster_type mon_type = MONS_PROGRAM_BUG;
1971 if (band == BAND_NO_BAND)
1972 return (MONS_PROGRAM_BUG);
1977 mon_type = MONS_KOBOLD;
1981 mon_type = MONS_ORC;
1982 if (one_chance_in(6))
1983 mon_type = MONS_ORC_WIZARD;
1984 if (one_chance_in(8))
1985 mon_type = MONS_ORC_PRIEST;
1988 case BAND_ORC_WARRIOR:
1989 mon_type = MONS_ORC;
1990 if (one_chance_in(5))
1991 mon_type = MONS_ORC_WIZARD;
1992 if (one_chance_in(7))
1993 mon_type = MONS_ORC_PRIEST;
1996 case BAND_ORC_KNIGHT:
1997 case BAND_ORC_HIGH_PRIEST:
1998 // XXX: For Beogh punishment, ogres and trolls look out of place...
1999 // (For normal generation, they're okay, of course.)
2000 temp_rand = random2(30);
2001 mon_type = ((temp_rand > 17) ? MONS_ORC : // 12 in 30
2002 (temp_rand > 8) ? MONS_ORC_WARRIOR : // 9 in 30
2003 (temp_rand > 6) ? MONS_WARG : // 2 in 30
2004 (temp_rand > 4) ? MONS_ORC_WIZARD : // 2 in 30
2005 (temp_rand > 2) ? MONS_ORC_PRIEST : // 2 in 30
2006 (temp_rand > 1) ? MONS_OGRE : // 1 in 30
2007 (temp_rand > 0) ? MONS_TROLL // 1 in 30
2008 : MONS_ORC_SORCERER); // 1 in 30
2011 case BAND_KILLER_BEES:
2012 mon_type = MONS_KILLER_BEE;
2015 case BAND_FLYING_SKULLS:
2016 mon_type = MONS_FLYING_SKULL;
2019 case BAND_SLIME_CREATURES:
2020 mon_type = MONS_SLIME_CREATURE;
2024 mon_type = MONS_YAK;
2028 mon_type = MONS_HARPY;
2031 case BAND_UGLY_THINGS:
2032 mon_type = ((power > 21 && one_chance_in(4)) ?
2033 MONS_VERY_UGLY_THING : MONS_UGLY_THING);
2036 case BAND_HELL_HOUNDS:
2037 mon_type = MONS_HELL_HOUND;
2041 mon_type = MONS_JACKAL;
2045 mon_type = MONS_GNOLL;
2048 case BAND_BUMBLEBEES:
2049 mon_type = MONS_BUMBLEBEE;
2053 mon_type = MONS_CENTAUR;
2057 mon_type = MONS_YAKTAUR;
2060 case BAND_INSUBSTANTIAL_WISPS:
2061 mon_type = MONS_INSUBSTANTIAL_WISP;
2064 case BAND_DEATH_YAKS:
2065 mon_type = MONS_DEATH_YAK;
2068 case BAND_NECROMANCER: // necromancer
2069 temp_rand = random2(13);
2070 mon_type = ((temp_rand > 9) ? MONS_ZOMBIE_SMALL : // 3 in 13
2071 (temp_rand > 6) ? MONS_ZOMBIE_LARGE : // 3 in 13
2072 (temp_rand > 3) ? MONS_SKELETON_SMALL : // 3 in 13
2073 (temp_rand > 0) ? MONS_SKELETON_LARGE // 3 in 13
2074 : MONS_NECROPHAGE); // 1 in 13
2078 mon_type = (coinflip() ? MONS_NEQOXEC : MONS_ORANGE_DEMON);
2081 case BAND_CACODEMON:
2082 mon_type = MONS_LEMURE;
2085 case BAND_EXECUTIONER:
2086 mon_type = (coinflip() ? MONS_ABOMINATION_SMALL
2087 : MONS_ABOMINATION_LARGE);
2090 case BAND_PANDEMONIUM_DEMON:
2091 if (one_chance_in(7))
2093 mon_type = static_cast<monster_type>(
2094 random_choose_weighted(50, MONS_LICH,
2095 10, MONS_ANCIENT_LICH,
2098 else if (one_chance_in(6))
2100 mon_type = static_cast<monster_type>(
2101 random_choose_weighted(50, MONS_ABOMINATION_SMALL,
2102 40, MONS_ABOMINATION_LARGE,
2103 10, MONS_TENTACLED_MONSTROSITY,
2110 static_cast<demon_class_type>(
2111 random_choose_weighted(50, DEMON_COMMON,
2119 mon_type = (coinflip() ? MONS_HELLWING : MONS_SMOKE_DEMON);
2122 case BAND_DEEP_ELF_FIGHTER: // deep elf fighter
2123 temp_rand = random2(11);
2124 mon_type = ((temp_rand > 4) ? MONS_DEEP_ELF_SOLDIER : // 6 in 11
2125 (temp_rand == 4) ? MONS_DEEP_ELF_FIGHTER : // 1 in 11
2126 (temp_rand == 3) ? MONS_DEEP_ELF_KNIGHT : // 1 in 11
2127 (temp_rand == 2) ? MONS_DEEP_ELF_CONJURER :// 1 in 11
2128 (temp_rand == 1) ? MONS_DEEP_ELF_MAGE // 1 in 11
2129 : MONS_DEEP_ELF_PRIEST); // 1 in 11
2132 case BAND_DEEP_ELF_KNIGHT: // deep elf knight
2133 temp_rand = random2(208);
2135 ((temp_rand > 159) ? MONS_DEEP_ELF_SOLDIER : // 23.08%
2136 (temp_rand > 111) ? MONS_DEEP_ELF_FIGHTER : // 23.08%
2137 (temp_rand > 79) ? MONS_DEEP_ELF_KNIGHT : // 15.38%
2138 (temp_rand > 51) ? MONS_DEEP_ELF_MAGE : // 13.46%
2139 (temp_rand > 35) ? MONS_DEEP_ELF_PRIEST : // 7.69%
2140 (temp_rand > 19) ? MONS_DEEP_ELF_CONJURER : // 7.69%
2141 (temp_rand > 3) ? MONS_DEEP_ELF_SUMMONER : // 7.69%
2142 (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 0.48%
2143 (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 0.48%
2144 (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 0.48%
2145 : MONS_DEEP_ELF_DEATH_MAGE); // 0.48%
2148 case BAND_DEEP_ELF_HIGH_PRIEST: // deep elf high priest
2149 temp_rand = random2(16);
2151 ((temp_rand > 12) ? MONS_DEEP_ELF_SOLDIER : // 3 in 16
2152 (temp_rand > 9) ? MONS_DEEP_ELF_FIGHTER : // 3 in 16
2153 (temp_rand > 6) ? MONS_DEEP_ELF_PRIEST : // 3 in 16
2154 (temp_rand == 6) ? MONS_DEEP_ELF_MAGE : // 1 in 16
2155 (temp_rand == 5) ? MONS_DEEP_ELF_SUMMONER : // 1 in 16
2156 (temp_rand == 4) ? MONS_DEEP_ELF_CONJURER : // 1 in 16
2157 (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 1 in 16
2158 (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 1 in 16
2159 (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 1 in 16
2160 : MONS_DEEP_ELF_DEATH_MAGE); // 1 in 16
2163 case BAND_HELL_KNIGHTS:
2164 mon_type = MONS_HELL_KNIGHT;
2165 if (one_chance_in(4))
2166 mon_type = MONS_NECROMANCER;
2169 case BAND_OGRE_MAGE:
2170 mon_type = MONS_OGRE;
2171 if (one_chance_in(3))
2172 mon_type = MONS_TWO_HEADED_OGRE;
2175 case BAND_KOBOLD_DEMONOLOGIST:
2176 temp_rand = random2(13);
2177 mon_type = ((temp_rand > 4) ? MONS_KOBOLD : // 8 in 13
2178 (temp_rand > 0) ? MONS_BIG_KOBOLD // 4 in 13
2179 : MONS_KOBOLD_DEMONOLOGIST);// 1 in 13
2183 mon_type = MONS_NAGA;
2186 mon_type = MONS_WAR_DOG;
2188 case BAND_GREY_RATS:
2189 mon_type = MONS_GREY_RAT;
2191 case BAND_GREEN_RATS:
2192 mon_type = MONS_GREEN_RAT;
2194 case BAND_ORANGE_RATS:
2195 mon_type = MONS_ORANGE_RAT;
2198 mon_type = MONS_SHEEP;
2201 mon_type = (coinflip() ? MONS_GHOUL : MONS_NECROPHAGE);
2203 case BAND_DEEP_TROLLS:
2204 mon_type = MONS_DEEP_TROLL;
2207 mon_type = MONS_HOG;
2209 case BAND_HELL_HOGS:
2210 mon_type = MONS_HELL_HOG;
2212 case BAND_GIANT_MOSQUITOES:
2213 mon_type = MONS_GIANT_MOSQUITO;
2216 mon_type = MONS_BOGGART;
2218 case BAND_BLINK_FROGS:
2219 mon_type = MONS_BLINK_FROG;
2221 case BAND_SKELETAL_WARRIORS:
2222 mon_type = MONS_SKELETAL_WARRIOR;
2224 case BAND_DRACONIAN:
2226 temp_rand = random2( (power < 24) ? 24 : 37 );
2228 ((temp_rand > 35) ? MONS_DRACONIAN_CALLER : // 1 in 34
2229 (temp_rand > 33) ? MONS_DRACONIAN_KNIGHT : // 2 in 34
2230 (temp_rand > 31) ? MONS_DRACONIAN_MONK : // 2 in 34
2231 (temp_rand > 29) ? MONS_DRACONIAN_SHIFTER : // 2 in 34
2232 (temp_rand > 27) ? MONS_DRACONIAN_ANNIHILATOR :// 2 in 34
2233 (temp_rand > 25) ? MONS_DRACONIAN_SCORCHER : // 2 in 34
2234 (temp_rand > 23) ? MONS_DRACONIAN_ZEALOT : // 2 in 34
2235 (temp_rand > 20) ? MONS_YELLOW_DRACONIAN : // 3 in 34
2236 (temp_rand > 17) ? MONS_GREEN_DRACONIAN : // 3 in 34
2237 (temp_rand > 14) ? MONS_BLACK_DRACONIAN : // 3 in 34
2238 (temp_rand > 11) ? MONS_WHITE_DRACONIAN : // 3 in 34
2239 (temp_rand > 8) ? MONS_PALE_DRACONIAN : // 3 in 34
2240 (temp_rand > 5) ? MONS_PURPLE_DRACONIAN : // 3 in 34
2241 (temp_rand > 2) ? MONS_MOTTLED_DRACONIAN : // 3 in 34
2242 MONS_RED_DRACONIAN ); // 3 in 34
2246 mon_type = coinflip()? MONS_MERFOLK : MONS_MERMAID;
2250 mon_type = coinflip()? MONS_FIRE_ELEMENTAL : MONS_HELL_HOUND;
2254 mon_type = MONS_DOWAN;
2258 mon_type = coinflip()? MONS_GREATER_MUMMY : MONS_MUMMY;
2261 case BAND_GOLDEN_EYE:
2262 mon_type = MONS_GOLDEN_EYE;
2266 mon_type = MONS_HUMAN;
2276 static int _ood_limit()
2278 return Options.ood_interesting;
2281 void mark_interesting_monst(struct monsters* monster, beh_type behaviour)
2283 if (crawl_state.arena)
2286 bool interesting = false;
2288 // Unique monsters are always intersting
2289 if (mons_is_unique(monster->type))
2291 // If it's never going to attack us, then not interesting
2292 else if (behaviour == BEH_FRIENDLY)
2293 interesting = false;
2294 else if (you.where_are_you == BRANCH_MAIN_DUNGEON
2295 && you.level_type == LEVEL_DUNGEON
2296 && mons_level(monster->type) >= you.your_level + _ood_limit()
2297 && mons_level(monster->type) < 99
2298 && !(monster->type >= MONS_EARTH_ELEMENTAL
2299 && monster->type <= MONS_AIR_ELEMENTAL)
2300 && !mons_class_flag( monster->type, M_NO_EXP_GAIN ))
2304 else if ((you.level_type == LEVEL_DUNGEON
2305 || you.level_type == LEVEL_ABYSS)
2306 && mons_rarity(monster->type) <= Options.rare_interesting
2307 && monster->hit_dice > 2 // Don't note the really low-hd monsters.
2308 && mons_rarity(monster->type) > 0)
2312 // Don't waste time on moname() if user isn't using this option
2313 else if (Options.note_monsters.size() > 0)
2315 const std::string iname = mons_type_name(monster->type, DESC_NOCAP_A);
2316 for (unsigned i = 0; i < Options.note_monsters.size(); ++i)
2318 if (Options.note_monsters[i].matches(iname))
2327 monster->flags |= MF_INTERESTING;
2330 // PUBLIC FUNCTION -- mons_place().
2332 static monster_type _pick_zot_exit_defender()
2334 if (one_chance_in(11))
2336 #ifdef DEBUG_MON_CREATION
2337 mpr("Create a pandemonium demon!", MSGCH_DIAGNOSTICS);
2339 return (MONS_PANDEMONIUM_DEMON);
2342 const int temp_rand = random2(276);
2343 const int mon_type =
2344 ((temp_rand > 184) ? MONS_WHITE_IMP + random2(15) : // 33.33%
2345 (temp_rand > 104) ? MONS_HELLION + random2(10) : // 28.99%
2346 (temp_rand > 78) ? MONS_HELL_HOUND : // 9.06%
2347 (temp_rand > 54) ? MONS_ABOMINATION_LARGE : // 8.70%
2348 (temp_rand > 33) ? MONS_ABOMINATION_SMALL : // 7.61%
2349 (temp_rand > 13) ? MONS_RED_DEVIL // 7.25%
2350 : MONS_PIT_FIEND); // 5.07%
2352 return static_cast<monster_type>(mon_type);
2355 int mons_place(mgen_data mg)
2357 #ifdef DEBUG_MON_CREATION
2358 mpr("in mons_place()", MSGCH_DIAGNOSTICS);
2361 for (int il = 0; il < MAX_MONSTERS; il++)
2362 if (menv[il].type != MONS_NO_MONSTER)
2365 if (mg.cls == WANDERING_MONSTER)
2367 if (mon_count > MAX_MONSTERS - 50)
2370 #ifdef DEBUG_MON_CREATION
2371 mpr("Set class RANDOM_MONSTER", MSGCH_DIAGNOSTICS);
2373 mg.cls = RANDOM_MONSTER;
2376 // All monsters have been assigned? {dlb}
2377 if (mon_count >= MAX_MONSTERS - 1)
2380 // This gives a slight challenge to the player as they ascend the
2381 // dungeon with the Orb.
2382 if (you.char_direction == GDT_ASCENDING && mg.cls == RANDOM_MONSTER
2383 && you.level_type == LEVEL_DUNGEON && !mg.summoned())
2385 #ifdef DEBUG_MON_CREATION
2386 mpr("Call _pick_zot_exit_defender()", MSGCH_DIAGNOSTICS);
2388 mg.cls = _pick_zot_exit_defender();
2389 mg.flags |= MG_PERMIT_BANDS;
2391 else if (mg.cls == RANDOM_MONSTER || mg.level_type == LEVEL_PANDEMONIUM)
2392 mg.flags |= MG_PERMIT_BANDS;
2394 // Translate level_type.
2395 switch (mg.level_type)
2397 case LEVEL_PANDEMONIUM:
2399 mg.power = level_id(mg.level_type).absdepth();
2403 mg.power = you.your_level;
2407 int mid = place_monster(mg);
2411 monsters *creation = &menv[mid];
2413 // Look at special cases: CHARMED, FRIENDLY, NEUTRAL, GOOD_NEUTRAL,
2415 if (mg.behaviour > NUM_BEHAVIOURS)
2417 if (mg.behaviour == BEH_FRIENDLY)
2418 creation->flags |= MF_CREATED_FRIENDLY;
2420 if (mg.behaviour == BEH_NEUTRAL || mg.behaviour == BEH_GOOD_NEUTRAL
2421 || mg.behaviour == BEH_STRICT_NEUTRAL)
2423 creation->flags |= MF_WAS_NEUTRAL;
2426 if (mg.behaviour == BEH_CHARMED)
2428 creation->attitude = ATT_HOSTILE;
2429 creation->add_ench(ENCH_CHARM);
2432 if (creation->type == MONS_RAKSHASA_FAKE && !one_chance_in(3))
2433 creation->add_ench(ENCH_INVIS);
2435 if (!(mg.flags & MG_FORCE_BEH) && !crawl_state.arena)
2436 player_angers_monster(creation);
2438 if (crawl_state.arena)
2439 behaviour_event(creation, ME_EVAL);
2441 // Make summoned being aware of player's presence.
2442 behaviour_event(creation, ME_ALERT, MHITYOU);
2448 static dungeon_feature_type _monster_primary_habitat_feature(int mc)
2450 if (mc == RANDOM_MONSTER)
2451 return (DNGN_FLOOR);
2452 return (habitat2grid(mons_class_primary_habitat(mc)));
2455 static dungeon_feature_type _monster_secondary_habitat_feature(int mc)
2457 if (mc == RANDOM_MONSTER)
2458 return (DNGN_FLOOR);
2459 return (habitat2grid(mons_class_secondary_habitat(mc)));
2462 class newmons_square_find : public travel_pathfind
2465 dungeon_feature_type feat_wanted;
2472 // Terrain that we can't spawn on, but that we can skip through.
2473 std::set<dungeon_feature_type> passable;
2475 newmons_square_find(dungeon_feature_type grdw,
2476 const coord_def &pos,
2478 : feat_wanted(grdw), start(pos), maxdistance(maxdist),
2479 best_distance(0), nfound(0)
2483 coord_def pathfind()
2485 set_floodseed(start);
2486 return travel_pathfind::pathfind(RMODE_EXPLORE);
2489 bool path_flood(const coord_def &c, const coord_def &dc)
2491 if (best_distance && traveled_distance > best_distance)
2495 || (maxdistance > 0 && traveled_distance > maxdistance))
2499 if (!feat_compatible(feat_wanted, grd(dc)))
2501 if (passable.find(grd(dc)) != passable.end())
2505 if (actor_at(dc) == NULL && one_chance_in(++nfound))
2507 greedy_dist = traveled_distance;
2509 best_distance = traveled_distance;
2519 // Finds a square for a monster of the given class, pathfinding
2520 // through only contiguous squares of habitable terrain.
2521 coord_def find_newmons_square_contiguous(monster_type mons_class,
2522 const coord_def &start,
2527 const dungeon_feature_type feat_preferred =
2528 _monster_primary_habitat_feature(mons_class);
2529 const dungeon_feature_type feat_nonpreferred =
2530 _monster_secondary_habitat_feature(mons_class);
2532 newmons_square_find nmpfind(feat_preferred, start, distance);
2533 const coord_def pp = nmpfind.pathfind();
2536 if (feat_nonpreferred != feat_preferred && !in_bounds(pp))
2538 newmons_square_find nmsfind(feat_nonpreferred, start, distance);
2539 const coord_def ps = nmsfind.pathfind();
2543 return (in_bounds(p) ? p : coord_def(-1, -1));
2546 coord_def find_newmons_square(int mons_class, const coord_def &p)
2549 coord_def pos(-1, -1);
2551 if (mons_class == WANDERING_MONSTER)
2552 mons_class = RANDOM_MONSTER;
2554 const dungeon_feature_type feat_preferred =
2555 _monster_primary_habitat_feature(mons_class);
2556 const dungeon_feature_type feat_nonpreferred =
2557 _monster_secondary_habitat_feature(mons_class);
2559 // Might be better if we chose a space and tried to match the monster
2560 // to it in the case of RANDOM_MONSTER, that way if the target square
2561 // is surrounded by water or lava this function would work. -- bwr
2562 if (empty_surrounds(p, feat_preferred, 2, true, empty))
2565 if (feat_nonpreferred != feat_preferred && !in_bounds(pos)
2566 && empty_surrounds(p, feat_nonpreferred, 2, true, empty))
2574 bool player_will_anger_monster(monster_type type, bool *holy,
2575 bool *unholy, bool *lawful,
2581 return (player_will_anger_monster(&dummy, holy, unholy, lawful,
2585 bool player_will_anger_monster(monsters *mon, bool *holy,
2586 bool *unholy, bool *lawful,
2590 (is_good_god(you.religion) && mon->is_evil());
2591 const bool isUnholy =
2592 (is_evil_god(you.religion) && mon->is_holy());
2593 const bool isLawful =
2594 (you.religion == GOD_ZIN && mon->is_chaotic());
2595 const bool isAntimagical =
2596 (you.religion == GOD_TROG && mon->is_actual_spellcaster());
2605 *antimagical = isAntimagical;
2607 return (isHoly || isUnholy || isLawful || isAntimagical);
2610 bool player_angers_monster(monsters *mon)
2617 // Get the drawbacks, not the benefits... (to prevent e.g. demon-scumming).
2618 if (player_will_anger_monster(mon, &holy, &unholy, &lawful, &antimagical)
2619 && mon->wont_attack())
2621 mon->attitude = ATT_HOSTILE;
2622 mon->del_ench(ENCH_CHARM);
2623 behaviour_event(mon, ME_ALERT, MHITYOU);
2625 if (you.can_see(mon))
2635 else if (antimagical)
2636 aura = "anti-magical";
2638 mprf("%s is enraged by your %s aura!",
2639 mon->name(DESC_CAP_THE).c_str(), aura.c_str());
2648 int create_monster(mgen_data mg, bool fail_msg)
2650 const int montype = (mons_class_is_zombified(mg.cls) ? mg.base_type
2655 if (!mg.force_place()
2656 || !in_bounds(mg.pos)
2658 || !mons_class_can_pass(montype, grd(mg.pos)))
2660 mg.pos = find_newmons_square(montype, mg.pos);
2662 // Gods other than Xom will try to avoid placing their monsters
2663 // directly in harm's way.
2664 if (mg.god != GOD_NO_GOD && mg.god != GOD_XOM)
2667 // If the type isn't known yet assume no resists or anything.
2668 dummy.type = (mg.cls == RANDOM_MONSTER) ? MONS_HUMAN
2670 dummy.base_monster = mg.base_type;
2675 && (!in_bounds(mg.pos)
2676 || mons_avoids_cloud(&dummy, env.cgrid(mg.pos),
2679 mg.pos = find_newmons_square(montype, mg.pos);
2681 if (!in_bounds(mg.pos))
2684 const int cloud_num = env.cgrid(mg.pos);
2685 // Don't place friendly god gift in a damaging cloud created by
2686 // you if that would anger the god.
2687 if (mons_avoids_cloud(&dummy, cloud_num, NULL, true)
2688 && mg.behaviour == BEH_FRIENDLY
2689 && god_hates_attacking_friend(you.religion, &dummy)
2690 && YOU_KILL(env.cloud[cloud_num].killer))
2697 if (in_bounds(mg.pos))
2699 summd = mons_place(mg);
2700 // If the arena vetoed the placement then give no fail message.
2701 if (crawl_state.arena)
2705 // Determine whether creating a monster is successful (summd != -1) {dlb}:
2706 // then handle the outcome. {dlb}:
2707 if (fail_msg && summd == -1 && observe_cell(mg.pos))
2708 mpr("You see a puff of smoke.");
2710 // The return value is either -1 (failure of some sort)
2711 // or the index of the monster placed (if I read things right). {dlb}
2715 bool empty_surrounds(const coord_def& where, dungeon_feature_type spc_wanted,
2716 int radius, bool allow_centre, coord_def& empty)
2718 // Assume all player summoning originates from player x,y.
2719 bool playerSummon = (where == you.pos());
2723 for (radius_iterator ri(where, radius, true, false, !allow_centre);
2726 bool success = false;
2731 // Players won't summon out of LOS, or past transparent walls.
2732 if (!you.see_cell_no_trans(*ri) && playerSummon)
2736 (grd(*ri) == spc_wanted) || feat_compatible(spc_wanted, grd(*ri));
2738 if (success && one_chance_in(++good_count))
2742 return (good_count > 0);
2745 monster_type summon_any_demon(demon_class_type dct)
2747 monster_type mon = MONS_PROGRAM_BUG;
2749 if (dct == DEMON_RANDOM)
2750 dct = static_cast<demon_class_type>(random2(DEMON_RANDOM));
2752 int temp_rand; // probability determination {dlb}
2757 temp_rand = random2(60);
2758 mon = ((temp_rand > 49) ? MONS_IMP : // 10 in 60
2759 (temp_rand > 40) ? MONS_WHITE_IMP : // 9 in 60
2760 (temp_rand > 31) ? MONS_LEMURE : // 9 in 60
2761 (temp_rand > 22) ? MONS_UFETUBUS : // 9 in 60
2762 (temp_rand > 13) ? MONS_MANES : // 9 in 60
2763 (temp_rand > 4) ? MONS_MIDGE // 9 in 60
2764 : MONS_SHADOW_IMP); // 5 in 60
2768 temp_rand = random2(3948);
2769 mon = ((temp_rand > 3367) ? MONS_NEQOXEC : // 14.69%
2770 (temp_rand > 2787) ? MONS_ORANGE_DEMON : // 14.69%
2771 (temp_rand > 2207) ? MONS_HELLWING : // 14.69%
2772 (temp_rand > 1627) ? MONS_SMOKE_DEMON : // 14.69%
2773 (temp_rand > 1047) ? MONS_YNOXINUL : // 14.69%
2774 (temp_rand > 889) ? MONS_RED_DEVIL : // 4.00%
2775 (temp_rand > 810) ? MONS_HELLION : // 2.00%
2776 (temp_rand > 731) ? MONS_ROTTING_DEVIL : // 2.00%
2777 (temp_rand > 652) ? MONS_TORMENTOR : // 2.00%
2778 (temp_rand > 573) ? MONS_REAPER : // 2.00%
2779 (temp_rand > 494) ? MONS_SOUL_EATER : // 2.00%
2780 (temp_rand > 415) ? MONS_HAIRY_DEVIL : // 2.00%
2781 (temp_rand > 336) ? MONS_ICE_DEVIL : // 2.00%
2782 (temp_rand > 257) ? MONS_BLUE_DEVIL : // 2.00%
2783 (temp_rand > 178) ? MONS_BEAST : // 2.00%
2784 (temp_rand > 99) ? MONS_IRON_DEVIL : // 2.00%
2785 (temp_rand > 49) ? MONS_SUN_DEMON // 1.26%
2786 : MONS_SHADOW_IMP); // 1.26%
2790 temp_rand = random2(1000);
2791 mon = ((temp_rand > 868) ? MONS_CACODEMON : // 13.1%
2792 (temp_rand > 737) ? MONS_BALRUG : // 13.1%
2793 (temp_rand > 606) ? MONS_BLUE_DEATH : // 13.1%
2794 (temp_rand > 475) ? MONS_GREEN_DEATH : // 13.1%
2795 (temp_rand > 344) ? MONS_EXECUTIONER : // 13.1%
2796 (temp_rand > 244) ? MONS_FIEND : // 10.0%
2797 (temp_rand > 154) ? MONS_ICE_FIEND : // 9.0%
2798 (temp_rand > 73) ? MONS_SHADOW_FIEND // 8.1%
2799 : MONS_PIT_FIEND); // 7.4%
2809 monster_type summon_any_holy_being(holy_being_class_type hbct)
2811 monster_type mon = MONS_PROGRAM_BUG;
2815 case HOLY_BEING_WARRIOR:
2816 mon = coinflip() ? MONS_DAEVA : MONS_ANGEL;
2826 monster_type summon_any_dragon(dragon_class_type dct)
2828 monster_type mon = MONS_PROGRAM_BUG;
2835 temp_rand = random2(100);
2836 mon = ((temp_rand > 80) ? MONS_SWAMP_DRAKE :
2837 (temp_rand > 59) ? MONS_KOMODO_DRAGON :
2838 (temp_rand > 34) ? MONS_FIREDRAKE :
2839 (temp_rand > 11) ? MONS_DEATH_DRAKE :
2843 case DRAGON_DRACONIAN:
2844 temp_rand = random2(70);
2845 mon = ((temp_rand > 60) ? MONS_YELLOW_DRACONIAN :
2846 (temp_rand > 50) ? MONS_BLACK_DRACONIAN :
2847 (temp_rand > 40) ? MONS_PALE_DRACONIAN :
2848 (temp_rand > 30) ? MONS_GREEN_DRACONIAN :
2849 (temp_rand > 20) ? MONS_PURPLE_DRACONIAN :
2850 (temp_rand > 10) ? MONS_RED_DRACONIAN
2851 : MONS_WHITE_DRACONIAN);
2855 temp_rand = random2(90);
2856 mon = ((temp_rand > 80) ? MONS_MOTTLED_DRAGON :
2857 (temp_rand > 70) ? MONS_LINDWURM :
2858 (temp_rand > 60) ? MONS_STORM_DRAGON :
2859 (temp_rand > 50) ? MONS_MOTTLED_DRAGON :
2860 (temp_rand > 40) ? MONS_STEAM_DRAGON :
2861 (temp_rand > 30) ? MONS_DRAGON :
2862 (temp_rand > 20) ? MONS_ICE_DRAGON :
2863 (temp_rand > 10) ? MONS_SWAMP_DRAGON
2864 : MONS_SHADOW_DRAGON);
2874 /////////////////////////////////////////////////////////////////////////////
2877 // The pathfinding is an implementation of the A* algorithm. Beginning at the
2878 // destination square we check all neighbours of a given grid, estimate the
2879 // distance needed for any shortest path including this grid and push the
2880 // result into a hash. We can then easily access all points with the shortest
2881 // distance estimates and then check _their_ neighbours and so on.
2882 // The algorithm terminates once we reach the monster position since - because
2883 // of the sorting of grids by shortest distance in the hash - there can be no
2884 // path between start and target that is shorter than the current one. There
2885 // could be other paths that have the same length but that has no real impact.
2886 // If the hash has been cleared and the start grid has not been encountered,
2887 // then there's no path that matches the requirements fed into monster_pathfind.
2888 // (These requirements are usually preference of habitat of a specific monster
2889 // or a limit of the distance between start and any grid on the path.)
2891 int mons_tracking_range(const monsters *mon)
2895 switch (mons_intel(mon))
2910 // Highly intelligent monsters can find their way
2911 // anywhere. (range == 0 means no restriction.)
2917 if (mons_is_native_in_branch(mon))
2919 else if (mons_class_flag(mon->type, M_BLOOD_SCENT))
2926 //#define DEBUG_PATHFIND
2927 monster_pathfind::monster_pathfind()
2928 : mons(), target(), range(0), min_length(0), max_length(0), dist(), prev()
2932 monster_pathfind::~monster_pathfind()
2936 void monster_pathfind::set_range(int r)
2942 coord_def monster_pathfind::next_pos(const coord_def &c) const
2944 return c + Compass[prev[c.x][c.y]];
2947 // The main method in the monster_pathfind class.
2948 // Returns true if a path was found, else false.
2949 bool monster_pathfind::init_pathfind(const monsters *mon, coord_def dest,
2950 bool diag, bool msg, bool pass_unmapped)
2954 // We're doing a reverse search from target to monster.
2956 target = mon->pos();
2958 allow_diagonals = diag;
2959 traverse_unmapped = pass_unmapped;
2962 if (start == target)
2965 mpr("The monster is already there!");
2970 return start_pathfind(msg);
2973 bool monster_pathfind::init_pathfind(coord_def src, coord_def dest, bool diag,
2979 allow_diagonals = diag;
2982 if (start == target)
2985 return start_pathfind(msg);
2988 bool monster_pathfind::start_pathfind(bool msg)
2990 // NOTE: We never do any traversable() check for the starting square
2991 // (target). This means that even if the target cannot be reached
2992 // we may still find a path leading adjacent to this position, which
2993 // is desirable if e.g. the player is hovering over deep water
2994 // surrounded by shallow water or floor, or if a foe is hiding in
2996 // If the surrounding squares also are not traversable, we return
2997 // early that no path could be found.
2999 max_length = min_length = grid_distance(pos.x, pos.y, target.x, target.y);
3000 for (int i = 0; i < GXM; i++)
3001 for (int j = 0; j < GYM; j++)
3002 dist[i][j] = INFINITE_DISTANCE;
3004 dist[pos.x][pos.y] = 0;
3006 bool success = false;
3009 // Calculate the distance to all neighbours of the current position,
3010 // and add them to the hash, if they haven't already been looked at.
3011 success = calc_path_to_neighbours();
3015 // Pull the position with shortest distance estimate to our target grid.
3016 success = get_best_position();
3022 mprf("Couldn't find a path from (%d,%d) to (%d,%d).",
3023 target.x, target.y, start.x, start.y);
3031 // Returns true as soon as we encounter the target.
3032 bool monster_pathfind::calc_path_to_neighbours()
3035 int distance, old_dist, total;
3037 // For each point, we look at all neighbour points. Check the orthogonals
3038 // last, so that, should an orthogonal and a diagonal direction have the
3039 // same total travel cost, the orthogonal will be picked first, and thus
3040 // zigzagging will be significantly reduced.
3042 // 1 0 3 This means directions are looked at, in order,
3043 // \ | / 1, 3, 5, 7 (diagonals) followed by 0, 2, 4, 6
3044 // 6--.--2 (orthogonals). This is achieved by the assignment
3045 // / | \ of (dir = 0) once dir has passed 7.
3048 for (int dir = 1; dir < 8; (dir += 2) == 9 && (dir = 0))
3050 // Skip diagonal movement.
3051 if (!allow_diagonals && (dir % 2))
3054 npos = pos + Compass[dir];
3056 #ifdef DEBUG_PATHFIND
3057 mprf("Looking at neighbour (%d,%d)", npos.x, npos.y);
3059 if (!in_bounds(npos))
3062 if (!traversable(npos))
3065 // Ignore this grid if it takes us above the allowed distance.
3066 if (range && estimated_cost(npos) > range)
3069 distance = dist[pos.x][pos.y] + travel_cost(npos);
3070 old_dist = dist[npos.x][npos.y];
3071 #ifdef DEBUG_PATHFIND
3072 mprf("old dist: %d, new dist: %d, infinite: %d", old_dist, distance,
3075 // If the new distance is better than the old one (initialised with
3076 // INFINITE), update the position.
3077 if (distance < old_dist)
3079 // Calculate new total path length.
3080 total = distance + estimated_cost(npos);
3081 if (old_dist == INFINITE_DISTANCE)
3083 #ifdef DEBUG_PATHFIND
3084 mprf("Adding (%d,%d) to hash (total dist = %d)",
3085 npos.x, npos.y, total);
3087 add_new_pos(npos, total);
3088 if (total > max_length)
3093 #ifdef DEBUG_PATHFIND
3094 mprf("Improving (%d,%d) to total dist %d",
3095 npos.x, npos.y, total);
3098 update_pos(npos, total);
3101 // Update distance start->pos.
3102 dist[npos.x][npos.y] = distance;
3104 // Set backtracking information.
3105 // Converts the Compass direction to its counterpart.
3107 // 7 . 3 ==> 3 . 7 e.g. (3 + 4) % 8 = 7
3108 // 6 5 4 2 1 0 (7 + 4) % 8 = 11 % 8 = 3
3110 prev[npos.x][npos.y] = (dir + 4) % 8;
3115 #ifdef DEBUG_PATHFIND
3116 mpr("Arrived at target.");
3125 // Starting at known min_length (minimum total estimated path distance), check
3126 // the hash for existing vectors, then pick the last entry of the first vector
3127 // that matches. Update min_length, if necessary.
3128 bool monster_pathfind::get_best_position()
3130 for (int i = min_length; i <= max_length; i++)
3132 if (!hash[i].empty())
3137 std::vector<coord_def> &vec = hash[i];
3138 // Pick the last position pushed into the vector as it's most
3139 // likely to be close to the target.
3140 pos = vec[vec.size()-1];
3143 #ifdef DEBUG_PATHFIND
3144 mprf("Returning (%d, %d) as best pos with total dist %d.",
3145 pos.x, pos.y, min_length);
3150 #ifdef DEBUG_PATHFIND
3151 mprf("No positions for path length %d.", i);
3155 // Nothing found? Then there's no path! :(
3159 // Using the prev vector backtrack from start to target to find all steps to
3160 // take along the shortest path.
3161 std::vector<coord_def> monster_pathfind::backtrack()
3163 #ifdef DEBUG_PATHFIND
3164 mpr("Backtracking...");
3166 std::vector<coord_def> path;
3168 path.push_back(pos);
3176 dir = prev[pos.x][pos.y];
3177 pos = pos + Compass[dir];
3178 ASSERT(in_bounds(pos));
3179 #ifdef DEBUG_PATHFIND
3180 mprf("prev: (%d, %d), pos: (%d, %d)", Compass[dir].x, Compass[dir].y,
3183 path.push_back(pos);
3185 if (pos.x == 0 && pos.y == 0)
3188 while (pos != start);
3189 ASSERT(pos == start);
3194 // Reduces the path coordinates to only a couple of key waypoints needed
3195 // to reach the target. Waypoints are chosen such that from one waypoint you
3196 // can see (and, more importantly, reach) the next one. Note that
3197 // can_go_straight() is probably rather too conservative in these estimates.
3198 // This is done because Crawl's pathfinding - once a target is in sight and easy
3199 // reach - is both very robust and natural, especially if we want to flexibly
3200 // avoid plants and other monsters in the way.
3201 std::vector<coord_def> monster_pathfind::calc_waypoints()
3203 std::vector<coord_def> path = backtrack();
3205 // If no path found, nothing to be done.
3209 dungeon_feature_type can_move;
3210 if (mons_amphibious(mons))
3211 can_move = DNGN_DEEP_WATER;
3213 can_move = DNGN_SHALLOW_WATER;
3215 std::vector<coord_def> waypoints;
3218 #ifdef DEBUG_PATHFIND
3219 mpr(EOL "Waypoints:");
3221 for (unsigned int i = 1; i < path.size(); i++)
3223 if (can_go_straight(pos, path[i], can_move))
3228 waypoints.push_back(pos);
3229 #ifdef DEBUG_PATHFIND
3230 mprf("waypoint: (%d, %d)", pos.x, pos.y);
3235 // Add the actual target to the list of waypoints, so we can later check
3236 // whether a tracked enemy has moved too much, in case we have to update
3238 if (pos != path[path.size() - 1])
3239 waypoints.push_back(path[path.size() - 1]);
3244 bool monster_pathfind::traversable(const coord_def p)
3246 if (traverse_unmapped && grd(p) == DNGN_UNSEEN)
3250 return mons_traversable(p);
3252 return (!feat_is_solid(grd(p)) && !feat_destroys_items(grd(p)));
3255 // Checks whether a given monster can pass over a certain position, respecting
3256 // its preferred habit and capability of flight or opening doors.
3257 bool monster_pathfind::mons_traversable(const coord_def p)
3259 const monster_type montype = mons_is_zombified(mons) ? mons_zombie_base(mons)
3262 if (!monster_habitable_grid(montype, grd(p)))
3265 // Monsters that can't open doors won't be able to pass them.
3266 if (feat_is_closed_door(grd(p)) || grd(p) == DNGN_SECRET_DOOR)
3268 if (mons_is_zombified(mons))
3270 if (mons_class_itemuse(montype) < MONUSE_OPEN_DOORS)
3273 else if (mons_itemuse(mons) < MONUSE_OPEN_DOORS)
3277 // Your friends only know about doors you know about, unless they feel
3278 // at home in this branch.
3279 if (grd(p) == DNGN_SECRET_DOOR && mons->friendly()
3280 && (mons_intel(mons) < I_NORMAL || !mons_is_native_in_branch(mons)))
3285 const trap_def* ptrap = find_trap(p);
3288 const trap_type tt = ptrap->type;
3290 // Don't allow allies to pass over known (to them) Zot traps.
3292 && ptrap->is_known(mons)
3293 && mons->friendly())
3298 // Monsters cannot travel over teleport traps.
3299 if (!_can_place_on_trap(montype, tt))
3306 int monster_pathfind::travel_cost(coord_def npos)
3309 return mons_travel_cost(npos);
3314 // Assumes that grids that really cannot be entered don't even get here.
3315 // (Checked by traversable().)
3316 int monster_pathfind::mons_travel_cost(coord_def npos)
3318 ASSERT(grid_distance(pos, npos) <= 1);
3320 // Doors need to be opened.
3321 if (feat_is_closed_door(grd(npos)) || grd(npos) == DNGN_SECRET_DOOR)
3324 const int montype = mons_is_zombified(mons) ? mons_zombie_base(mons)
3327 const bool airborne = _mons_airborne(montype, -1, false);
3329 // Travelling through water, entering or leaving water is more expensive
3330 // for non-amphibious monsters, so they'll avoid it where possible.
3331 // (The resulting path might not be optimal but it will lead to a path
3332 // a monster of such habits is likely to prefer.)
3333 // Only tested for shallow water since they can't enter deep water anyway.
3334 if (!airborne && !mons_class_amphibious(montype)
3335 && (grd(pos) == DNGN_SHALLOW_WATER || grd(npos) == DNGN_SHALLOW_WATER))
3340 // Try to avoid (known) traps.
3341 const trap_def* ptrap = find_trap(npos);
3344 const bool knows_trap = ptrap->is_known(mons);
3345 const trap_type tt = ptrap->type;
3346 if (tt == TRAP_ALARM || tt == TRAP_ZOT)
3348 // Your allies take extra precautions to avoid known alarm traps.
3349 // Zot traps are considered intraversable.
3350 if (knows_trap && mons->friendly())
3353 // To hostile monsters, these traps are completely harmless.
3357 // Mechanical traps can be avoided by flying, as can shafts, and
3358 // tele traps are never traversable anyway.
3359 if (knows_trap && !airborne)
3366 // The estimated cost to reach a grid is simply max(dx, dy).
3367 int monster_pathfind::estimated_cost(coord_def p)
3369 return (grid_distance(p, target));
3372 void monster_pathfind::add_new_pos(coord_def npos, int total)
3374 hash[total].push_back(npos);
3377 void monster_pathfind::update_pos(coord_def npos, int total)
3379 // Find hash position of old distance and delete it,
3380 // then call_add_new_pos.
3381 int old_total = dist[npos.x][npos.y] + estimated_cost(npos);
3383 std::vector<coord_def> &vec = hash[old_total];
3384 for (unsigned int i = 0; i < vec.size(); i++)
3388 vec.erase(vec.begin() + i);
3393 add_new_pos(npos, total);
3396 /////////////////////////////////////////////////////////////////////////////
3398 // Random monsters for portal vaults.
3400 /////////////////////////////////////////////////////////////////////////////
3402 void set_vault_mon_list(const std::vector<mons_spec> &list)
3404 CrawlHashTable &props = env.properties;
3406 props.erase(VAULT_MON_TYPES_KEY);
3407 props.erase(VAULT_MON_BASES_KEY);
3408 props.erase(VAULT_MON_WEIGHTS_KEY);
3410 unsigned int size = list.size();
3413 setup_vault_mon_list();
3417 props[VAULT_MON_TYPES_KEY].new_vector(SV_LONG).resize(size);
3418 props[VAULT_MON_BASES_KEY].new_vector(SV_LONG).resize(size);
3419 props[VAULT_MON_WEIGHTS_KEY].new_vector(SV_LONG).resize(size);
3421 CrawlVector &type_vec = props[VAULT_MON_TYPES_KEY].get_vector();
3422 CrawlVector &base_vec = props[VAULT_MON_BASES_KEY].get_vector();
3423 CrawlVector &weight_vec = props[VAULT_MON_WEIGHTS_KEY].get_vector();
3425 for (unsigned int i = 0; i < size; i++)
3427 const mons_spec &spec = list[i];
3429 if (spec.place.is_valid())
3431 ASSERT(spec.place.level_type != LEVEL_LABYRINTH
3432 && spec.place.level_type != LEVEL_PORTAL_VAULT);
3433 type_vec[i] = (long) -1;
3434 base_vec[i] = (long) spec.place.packed_place();
3438 ASSERT(spec.mid != RANDOM_MONSTER
3439 && spec.monbase != RANDOM_MONSTER);
3440 type_vec[i] = (long) spec.mid;
3441 base_vec[i] = (long) spec.monbase;
3443 weight_vec[i] = (long) spec.genweight;
3446 setup_vault_mon_list();
3449 void get_vault_mon_list(std::vector<mons_spec> &list)
3453 CrawlHashTable &props = env.properties;
3455 if (!props.exists(VAULT_MON_TYPES_KEY))
3458 ASSERT(props.exists(VAULT_MON_BASES_KEY));
3459 ASSERT(props.exists(VAULT_MON_WEIGHTS_KEY));
3461 CrawlVector &type_vec = props[VAULT_MON_TYPES_KEY].get_vector();
3462 CrawlVector &base_vec = props[VAULT_MON_BASES_KEY].get_vector();
3463 CrawlVector &weight_vec = props[VAULT_MON_WEIGHTS_KEY].get_vector();
3465 ASSERT(type_vec.size() == base_vec.size());
3466 ASSERT(type_vec.size() == weight_vec.size());
3468 unsigned int size = type_vec.size();
3469 for (unsigned int i = 0; i < size; i++)
3471 int type = (long) type_vec[i];
3472 int base = (long) base_vec[i];
3478 spec.place = level_id::from_packed_place(base);
3479 ASSERT(spec.place.is_valid());
3480 ASSERT(spec.place.level_type != LEVEL_LABYRINTH
3481 && spec.place.level_type != LEVEL_PORTAL_VAULT);
3486 spec.monbase = (monster_type) base;
3487 ASSERT(spec.mid != RANDOM_MONSTER
3488 && spec.monbase != RANDOM_MONSTER);
3490 spec.genweight = (long) weight_vec[i];
3492 list.push_back(spec);
3496 void setup_vault_mon_list()
3498 vault_mon_types.clear();
3499 vault_mon_bases.clear();
3500 vault_mon_weights.clear();
3502 std::vector<mons_spec> list;
3503 get_vault_mon_list(list);
3505 unsigned int size = list.size();
3507 vault_mon_types.resize(size);
3508 vault_mon_bases.resize(size);
3509 vault_mon_weights.resize(size);
3511 for (unsigned int i = 0; i < size; i++)
3513 if (list[i].place.is_valid())
3515 vault_mon_types[i] = -1;
3516 vault_mon_bases[i] = list[i].place.packed_place();
3520 vault_mon_types[i] = list[i].mid;
3521 vault_mon_bases[i] = list[i].monbase;
3523 vault_mon_weights[i] = list[i].genweight;