Apply the new ground_level method.
[crawl.git] / crawl-ref / source / mon-place.cc
blob4fc8a95d83171e43a003eac1e63e0691cad8a5d9
1 /*
2 * File: mon-place.cc
3 * Summary: Functions used when placing monsters in the dungeon.
4 * Written by: Linley Henzell
5 */
7 #include "AppHdr.h"
9 #include <algorithm>
11 #include "mon-place.h"
12 #include "mgen_data.h"
14 #include "areas.h"
15 #include "arena.h"
16 #include "branch.h"
17 #include "colour.h"
18 #include "coord.h"
19 #include "coordit.h"
20 #include "directn.h"
21 #include "dungeon.h"
22 #include "fprop.h"
23 #include "godabil.h"
24 #include "externs.h"
25 #include "options.h"
26 #include "ghost.h"
27 #include "itemname.h"
28 #include "lev-pand.h"
29 #include "libutil.h"
30 #include "message.h"
31 #include "mislead.h"
32 #include "mon-behv.h"
33 #include "mon-gear.h"
34 #include "mon-iter.h"
35 #include "mon-pick.h"
36 #include "mon-util.h"
37 #include "mon-stuff.h"
38 #include "player.h"
39 #include "random.h"
40 #include "religion.h"
41 #include "shopping.h"
42 #include "spl-damage.h"
43 #include "sprint.h"
44 #include "stairs.h"
45 #include "state.h"
46 #include "stuff.h"
47 #include "env.h"
48 #include "terrain.h"
49 #include "traps.h"
50 #include "travel.h"
51 #include "view.h"
52 #include "viewchar.h"
53 #ifdef USE_TILE
54 #include "tiledef-player.h"
55 #include "tilepick.h"
56 #endif
58 band_type active_monster_band = BAND_NO_BAND;
60 static std::vector<int> vault_mon_types;
61 static std::vector<int> vault_mon_bases;
62 static std::vector<int> vault_mon_weights;
64 #define VAULT_MON_TYPES_KEY "vault_mon_types"
65 #define VAULT_MON_BASES_KEY "vault_mon_bases"
66 #define VAULT_MON_WEIGHTS_KEY "vault_mon_weights"
68 // NEW place_monster -- note that power should be set to:
69 // DEPTH_ABYSS for abyss
70 // DEPTH_PAN for pandemonium
71 // x otherwise
73 // proximity is the same as for mons_place:
74 // 0 is no restrictions
75 // 1 attempts to place near player
76 // 2 attempts to avoid player LOS
78 #define BIG_BAND 20
80 static monster_type _resolve_monster_type(monster_type mon_type,
81 proximity_type proximity,
82 monster_type &base_type,
83 coord_def &pos,
84 unsigned mmask,
85 dungeon_char_type *stair_type,
86 int *lev_mons,
87 bool *chose_ood_monster);
89 static monster_type _band_member(band_type band, int power);
90 static band_type _choose_band(int mon_type, int power, int &band_size,
91 bool& natural_leader);
92 // static int _place_monster_aux(int mon_type, beh_type behaviour, int target,
93 // int px, int py, int power, int extra,
94 // bool first_band_member, int dur = 0);
96 static int _place_monster_aux(const mgen_data &mg, bool first_band_member,
97 bool force_pos = false);
99 // Returns whether actual_feat is compatible with feat_wanted for monster
100 // movement and generation.
101 bool feat_compatible(dungeon_feature_type feat_wanted,
102 dungeon_feature_type actual_feat)
104 if (feat_wanted == DNGN_FLOOR)
106 return (actual_feat >= DNGN_FLOOR
107 || actual_feat == DNGN_SHALLOW_WATER);
110 if (feat_wanted >= DNGN_ROCK_WALL
111 && feat_wanted <= DNGN_CLEAR_PERMAROCK_WALL)
113 // A monster can only move through or inhabit permanent rock if that's
114 // exactly what it's asking for.
115 if (actual_feat == DNGN_PERMAROCK_WALL
116 || actual_feat == DNGN_CLEAR_PERMAROCK_WALL)
118 return (feat_wanted == DNGN_PERMAROCK_WALL
119 || feat_wanted == DNGN_CLEAR_PERMAROCK_WALL);
122 return (actual_feat >= DNGN_ROCK_WALL
123 && actual_feat <= DNGN_CLEAR_PERMAROCK_WALL);
126 return (feat_wanted == actual_feat
127 || (feat_wanted == DNGN_DEEP_WATER
128 && (actual_feat == DNGN_SHALLOW_WATER
129 || actual_feat == DNGN_FOUNTAIN_BLUE)));
132 // Can this monster survive on actual_grid?
134 // If you have an actual monster, use this instead of the overloaded function
135 // that uses only the monster class to make decisions.
136 bool monster_habitable_grid(const monster* mon,
137 dungeon_feature_type actual_grid)
139 // Zombified monsters enjoy the same habitat as their original.
140 const monster_type mt = mons_base_type(mon);
142 return (monster_habitable_grid(mt,
143 actual_grid,
144 DNGN_UNSEEN,
145 mons_flies(mon),
146 mon->cannot_move()));
149 bool mons_airborne(int mcls, int flies, bool paralysed)
151 if (flies == -1)
152 flies = mons_class_flies(mcls);
154 return (paralysed ? flies == FL_LEVITATE : flies != FL_NONE);
157 // Can monsters of class monster_class live happily on actual_grid?
158 // Use flies == true to pretend the monster can fly.
160 // [dshaligram] We're trying to harmonise the checks from various places into
161 // one check, so we no longer care if a water elemental springs into existence
162 // on dry land, because they're supposed to be able to move onto dry land
163 // anyway.
164 bool monster_habitable_grid(monster_type mt,
165 dungeon_feature_type actual_grid,
166 dungeon_feature_type wanted_grid_feature,
167 int flies, bool paralysed)
169 // No monster may be placed on open sea.
170 if (actual_grid == DNGN_OPEN_SEA)
171 return (false);
173 const dungeon_feature_type feat_preferred =
174 habitat2grid(mons_class_primary_habitat(mt));
175 const dungeon_feature_type feat_nonpreferred =
176 habitat2grid(mons_class_secondary_habitat(mt));
178 const bool monster_is_airborne = mons_airborne(mt, flies, paralysed);
180 // If the caller insists on a specific feature type, try to honour
181 // the request. This allows the builder to place amphibious
182 // creatures only on land, or flying creatures only on lava, etc.
183 if (wanted_grid_feature != DNGN_UNSEEN
184 && (feat_compatible(feat_preferred, wanted_grid_feature)
185 || feat_compatible(feat_nonpreferred, wanted_grid_feature)
186 || (monster_is_airborne && !feat_is_solid(wanted_grid_feature))))
188 return (feat_compatible(wanted_grid_feature, actual_grid));
191 // Special check for fire elementals since their habitat is floor which
192 // is generally considered compatible with shallow water.
193 if (mt == MONS_FIRE_ELEMENTAL && feat_is_watery(actual_grid))
194 return (false);
196 if (actual_grid == DNGN_TEMP_PORTAL)
198 if (mt == MONS_ELDRITCH_TENTACLE || mt == MONS_ELDRITCH_TENTACLE_SEGMENT)
199 return (true);
200 else
201 return (false);
204 if (feat_compatible(feat_preferred, actual_grid)
205 || (feat_nonpreferred != feat_preferred
206 && feat_compatible(feat_nonpreferred, actual_grid)))
208 return (true);
211 // [dshaligram] Flying creatures are all DNGN_FLOOR, so we
212 // only have to check for the additional valid grids of deep
213 // water and lava.
214 if (monster_is_airborne
215 && (actual_grid == DNGN_LAVA || actual_grid == DNGN_DEEP_WATER))
217 return (true);
220 return (false);
223 // Returns true if the monster can submerge in the given grid.
224 bool monster_can_submerge(const monster* mon, dungeon_feature_type feat)
226 if (testbits(env.pgrid(mon->pos()), FPROP_NO_SUBMERGE))
227 return (false);
228 if (!mon->is_habitable_feat(feat))
229 return (false);
230 if (mons_class_flag(mon->type, M_SUBMERGES))
231 switch (mons_habitat(mon))
233 case HT_WATER:
234 case HT_AMPHIBIOUS:
235 return (feat_is_watery(feat));
236 case HT_LAVA:
237 return (feat == DNGN_LAVA);
238 case HT_LAND:
239 // Currently, trapdoor spider only.
240 return (feat_is_floor(feat));
241 default:
242 return (false);
244 else
245 return (false);
249 bool is_spawn_scaled_area(const level_id &here)
251 return (here.level_type == LEVEL_DUNGEON
252 && !is_hell_subbranch(here.branch)
253 && here.branch != BRANCH_HALL_OF_ZOT);
256 // Scale monster generation parameter with time spent on level. Note:
257 // (target_value - base_value) * dropoff_ramp_turns must be < INT_MAX!
258 static int _scale_spawn_parameter(int base_value,
259 int target_value,
260 int final_value,
261 int dropoff_start_turns = 3000,
262 int dropoff_ramp_turns = 12000)
264 if (!is_spawn_scaled_area(level_id::current()))
265 return base_value;
267 const int turns_on_level = env.turns_on_level;
268 return (turns_on_level <= dropoff_start_turns ? base_value :
269 turns_on_level > dropoff_start_turns + dropoff_ramp_turns ?
270 final_value :
272 // Actual scaling, strictly linear at the moment:
273 (base_value +
274 (target_value - base_value)
275 * (turns_on_level - dropoff_start_turns)
276 / dropoff_ramp_turns));
279 static bool _need_super_ood(int lev_mons)
281 return (env.turns_on_level > 1400 - lev_mons * 117
282 && x_chance_in_y(
283 _scale_spawn_parameter(2, 10000, 10000, 3000, 9000),
284 10000));
287 static int _fuzz_mons_level(int level)
289 // Apply a fuzz to the monster level we're looking for. The fuzz
290 // is intended to mix up monster generation producing moderately
291 // OOD monsters, over and above the +5 OOD that's baked into the
292 // monster selection loop.
294 // The OOD fuzz roll is not applied at level generation time on
295 // D:1, and is applied slightly less often (0.75*0.14) on D:2. All
296 // other levels have a straight 14% chance of moderate OOD fuzz
297 // for each monster at level generation, and the chances of
298 // moderate OODs go up to 100% after a ramp-up period.
299 if ((level > 1
300 // Give 25% chance of not trying for moderate OOD on D:2
301 || (level == 1 && !one_chance_in(4))
302 // Try moderate OOD after 700 turns on level on D:1, or 583 turns
303 // spent on D:2.
304 || env.turns_on_level > 700 - level * 117)
305 && x_chance_in_y(
306 _scale_spawn_parameter(140, 1000, 1000, 3000, 4800),
307 1000))
309 const int fuzzspan = 5;
310 const int fuzz = std::max(0, random_range(-fuzzspan, fuzzspan, 2));
312 #ifdef DEBUG_DIAGNOSTICS
313 if (fuzz)
314 dprf("Monster level fuzz: %d (old: %d, new: %d)",
315 fuzz, level, level + fuzz);
316 #endif
317 return level + fuzz;
319 return (level);
322 static void _hell_spawn_random_monsters()
324 // Monster generation in the Vestibule drops off quickly.
325 const int taper_off_turn = 500;
326 int genodds = 240;
327 // genodds increases once you've spent more than 500 turns in Hell.
328 if (env.turns_on_level > taper_off_turn)
330 genodds += (env.turns_on_level - taper_off_turn);
331 genodds = (genodds < 0 ? 20000 : std::min(genodds, 20000));
334 if (x_chance_in_y(5, genodds))
336 mgen_data mg(WANDERING_MONSTER);
337 mg.proximity = (one_chance_in(10) ? PROX_NEAR_STAIRS
338 : PROX_AWAY_FROM_PLAYER);
339 mons_place(mg);
340 viewwindow();
344 //#define DEBUG_MON_CREATION
346 // This function is now only called about once every 5 turns. (Used to be
347 // every turn independent of how much time an action took, which was not ideal.)
348 // To arrive at spawning rates close to how they used to be, replace the
349 // one_chance_in(value) checks with the new x_chance_in_y(5, value). (jpeg)
350 void spawn_random_monsters()
352 if (crawl_state.game_is_arena() ||
353 (crawl_state.game_is_sprint() &&
354 you.level_type == LEVEL_DUNGEON &&
355 you.char_direction == GDT_DESCENDING))
356 return;
358 #ifdef DEBUG_MON_CREATION
359 mpr("in spawn_random_monsters()", MSGCH_DIAGNOSTICS);
360 #endif
361 if (player_in_branch(BRANCH_VESTIBULE_OF_HELL))
363 _hell_spawn_random_monsters();
364 return;
367 if (env.spawn_random_rate == 0)
369 #ifdef DEBUG_MON_CREATION
370 mpr("random monster gen turned off", MSGCH_DIAGNOSTICS);
371 #endif
372 return;
375 const int rate = (you.char_direction == GDT_DESCENDING) ?
376 _scale_spawn_parameter(env.spawn_random_rate,
377 6 * env.spawn_random_rate,
379 : 8;
381 if (rate == 0)
383 dprf("random monster gen scaled off, %d turns on level",
384 env.turns_on_level);
385 return;
388 // Place normal dungeon monsters, but not in player LOS.
389 if (you.level_type == LEVEL_DUNGEON && x_chance_in_y(5, rate))
391 dprf("Placing monster, rate: %d, turns here: %d",
392 rate, env.turns_on_level);
393 proximity_type prox = (one_chance_in(10) ? PROX_NEAR_STAIRS
394 : PROX_AWAY_FROM_PLAYER);
396 // The rules change once the player has picked up the Orb...
397 if (you.char_direction == GDT_ASCENDING)
398 prox = (one_chance_in(6) ? PROX_CLOSE_TO_PLAYER : PROX_ANYWHERE);
400 mgen_data mg(WANDERING_MONSTER);
401 mg.proximity = prox;
402 mg.foe = (you.char_direction == GDT_ASCENDING) ? MHITYOU : MHITNOT;
403 mons_place(mg);
404 viewwindow();
405 return;
408 // Place Abyss monsters. (Now happens regularly every 5 turns which might
409 // look a bit strange for a place as chaotic as the Abyss. Then again,
410 // the player is unlikely to meet all of them and notice this.)
411 if (you.level_type == LEVEL_ABYSS
412 && (you.char_direction != GDT_GAME_START
413 || x_chance_in_y(5, rate))
414 && (you.religion != GOD_CHEIBRIADOS || coinflip()))
416 mons_place(mgen_data(WANDERING_MONSTER));
417 viewwindow();
418 return;
421 // Place Pandemonium monsters.
422 if (you.level_type == LEVEL_PANDEMONIUM && x_chance_in_y(5, rate))
424 pandemonium_mons();
425 viewwindow();
426 return;
429 // A portal vault *might* decide to turn on random monster spawning,
430 // but it's off by default.
431 if (you.level_type == LEVEL_PORTAL_VAULT && x_chance_in_y(5, rate))
433 mons_place(mgen_data(WANDERING_MONSTER));
434 viewwindow();
437 // No random monsters in the Labyrinth.
440 // Caller must use !invalid_monster_type to check if the return value
441 // is a real monster.
442 monster_type pick_random_monster(const level_id &place,
443 bool *chose_ood_monster)
445 int level;
446 if (place.level_type == LEVEL_PORTAL_VAULT)
447 level = you.absdepth0;
448 else
449 level = place.absdepth();
450 return pick_random_monster(place, level, level, chose_ood_monster);
453 static std::vector<monster_type> _find_valid_monster_types(const level_id &place)
455 static std::vector<monster_type> valid_monster_types;
456 static level_id last_monster_type_place;
458 if (last_monster_type_place == place)
459 return (valid_monster_types);
461 valid_monster_types.clear();
462 for (int i = 0; i < NUM_MONSTERS; ++i)
463 if (mons_rarity(static_cast<monster_type>(i), place) > 0)
464 valid_monster_types.push_back(static_cast<monster_type>(i));
465 last_monster_type_place = place;
466 return (valid_monster_types);
469 static bool _is_random_monster(int mt)
471 return (mt == RANDOM_MONSTER || mt == RANDOM_MOBILE_MONSTER
472 || mt == WANDERING_MONSTER);
475 // Caller must use !invalid_monster_type to check if the return value
476 // is a real monster.
477 monster_type pick_random_monster(const level_id &place, int power,
478 int &lev_mons,
479 bool *chose_ood_monster,
480 bool force_mobile)
482 bool ood_dummy = false;
483 bool *isood = chose_ood_monster? chose_ood_monster : &ood_dummy;
485 *isood = false;
487 if (crawl_state.game_is_arena())
489 monster_type type = arena_pick_random_monster(place, power, lev_mons);
490 if (!_is_random_monster(type))
491 return (type);
494 if (place.level_type == LEVEL_LABYRINTH)
495 return (MONS_PROGRAM_BUG);
497 if (place == BRANCH_ECUMENICAL_TEMPLE)
498 return (MONS_PROGRAM_BUG);
500 if (place.level_type == LEVEL_PORTAL_VAULT)
502 monster_type base_type = (monster_type) 0;
503 coord_def dummy1;
504 dungeon_char_type dummy2;
505 monster_type type =
506 _resolve_monster_type(RANDOM_MONSTER, PROX_ANYWHERE, base_type,
507 dummy1, 0, &dummy2, &lev_mons,
508 chose_ood_monster);
510 #if defined(DEBUG) || defined(DEBUG_DIAGNOSTICS)
511 if (base_type != 0 && base_type != MONS_PROGRAM_BUG)
512 mpr("Random portal vault mon discarding base type.",
513 MSGCH_ERROR);
514 #endif
515 return (type);
518 monster_type mon_type = MONS_PROGRAM_BUG;
520 lev_mons = power;
522 if (place == BRANCH_MAIN_DUNGEON
523 && lev_mons != DEPTH_ABYSS && one_chance_in(4))
525 lev_mons = random2(power);
528 const int original_level = lev_mons;
530 // OODs do not apply to the Abyss, Pan, etc.
531 if (you.level_type == LEVEL_DUNGEON && lev_mons <= 27)
533 // Apply moderate OOD fuzz where appropriate.
534 lev_mons = _fuzz_mons_level(lev_mons);
536 // Potentially nasty surprise, but very rare.
537 if (_need_super_ood(lev_mons))
539 const int new_level = lev_mons + random2avg(27, 2);
540 dprf("Super OOD roll: Old: %d, New: %d", lev_mons, new_level);
541 lev_mons = new_level;
544 lev_mons = std::min(30, lev_mons);
547 // Abyss or Pandemonium. Almost never called from Pan; probably only
548 // if a random demon gets summon anything spell.
549 if (lev_mons == DEPTH_ABYSS
550 || place.level_type == LEVEL_PANDEMONIUM
551 || place.level_type == LEVEL_ABYSS)
555 int count;
559 count = 0;
562 mon_type = static_cast<monster_type>(random2(NUM_MONSTERS));
563 count++;
565 while (mons_abyss(mon_type) == 0 && count < 2000);
566 } while ((crawl_state.game_is_arena() &&
567 arena_veto_random_monster(mon_type)) ||
568 (crawl_state.game_is_sprint() &&
569 sprint_veto_random_abyss_monster(mon_type)) ||
570 (force_mobile && (mons_class_is_stationary(mon_type)
571 || mons_is_mimic(mon_type))
574 if (count == 2000)
575 return (MONS_PROGRAM_BUG);
577 while (random2avg(100, 2) > mons_rare_abyss(mon_type)
578 && !one_chance_in(100));
580 else
582 int level = 0, diff, chance;
584 lev_mons = std::min(30, lev_mons);
586 const int n_pick_tries = 10000;
587 const int n_relax_margin = n_pick_tries / 10;
588 int monster_pick_tries = 10000;
589 const std::vector<monster_type> valid_monster_types =
590 _find_valid_monster_types(place);
592 if (valid_monster_types.empty())
593 return MONS_PROGRAM_BUG;
595 while (monster_pick_tries-- > 0)
597 mon_type = valid_monster_types[random2(valid_monster_types.size())];
599 if (crawl_state.game_is_arena() && arena_veto_random_monster(mon_type)
600 || force_mobile && mons_class_is_stationary(mon_type))
602 continue;
605 level = mons_level(mon_type, place);
606 diff = level - lev_mons;
608 // If we're running low on tries, ignore level differences.
609 if (monster_pick_tries < n_relax_margin)
610 diff = 0;
612 chance = mons_rarity(mon_type, place) - (diff * diff);
614 // If we're running low on tries, remove level restrictions.
615 if ((monster_pick_tries < n_relax_margin
616 || std::abs(lev_mons - level) <= 5)
617 && random2avg(100, 2) <= chance)
619 break;
623 if (monster_pick_tries <= 0)
624 return (MONS_PROGRAM_BUG);
626 if (level > original_level + 5)
627 *isood = true;
630 #ifdef DEBUG_DIAGNOSTICS
631 if (lev_mons > original_level)
632 dprf("Orginal level: %d, Final level: %d, Monster: %s, OOD: %s",
633 original_level, lev_mons,
634 mon_type == MONS_NO_MONSTER || mon_type == MONS_PROGRAM_BUG ?
635 "NONE" : get_monster_data(mon_type)->name,
636 *isood? "YES" : "no");
637 #endif
639 return (mon_type);
642 bool can_place_on_trap(int mon_type, trap_type trap)
644 if (trap == TRAP_TELEPORT)
645 return (false);
647 if (trap == TRAP_SHAFT)
649 if (_is_random_monster(mon_type))
650 return (false);
652 return (mons_class_flies(mon_type) != FL_NONE
653 || get_monster_data(mon_type)->size == SIZE_TINY);
656 return (true);
659 bool drac_colour_incompatible(int drac, int colour)
661 return (drac == MONS_DRACONIAN_SCORCHER && colour == MONS_WHITE_DRACONIAN);
664 // Finds a random square as close to a staircase as possible
665 bool find_mon_place_near_stairs(coord_def& pos,
666 dungeon_char_type *stair_type,
667 branch_type &branch)
669 pos = get_random_stair();
670 const dungeon_feature_type feat = grd(pos);
671 *stair_type = get_feature_dchar(feat);
672 // Is it a branch stair?
673 for (int i = 0; i < NUM_BRANCHES; ++i)
675 if (branches[i].entry_stairs == feat)
677 branch = branches[i].id;
678 break;
680 else if (branches[i].exit_stairs == feat)
682 branch = branches[i].parent_branch;
683 break;
686 const monster_type habitat_target = MONS_MEGABAT;
687 pos = find_newmons_square_contiguous(habitat_target, pos);
688 return (in_bounds(pos));
691 static monster_type _resolve_monster_type(monster_type mon_type,
692 proximity_type proximity,
693 monster_type &base_type,
694 coord_def &pos,
695 unsigned mmask,
696 dungeon_char_type *stair_type,
697 int *lev_mons,
698 bool *chose_ood_monster)
700 if (mon_type == RANDOM_DRACONIAN)
702 // Pick any random drac, constrained by colour if requested.
705 mon_type =
706 static_cast<monster_type>(
707 random_range(MONS_BLACK_DRACONIAN,
708 MONS_DRACONIAN_SCORCHER));
710 while (base_type != MONS_PROGRAM_BUG
711 && mon_type != base_type
712 && (mons_species(mon_type) == mon_type
713 || drac_colour_incompatible(mon_type, base_type)));
715 else if (mon_type == RANDOM_BASE_DRACONIAN)
716 mon_type = random_draconian_monster_species();
717 else if (mon_type == RANDOM_NONBASE_DRACONIAN)
719 mon_type =
720 static_cast<monster_type>(
721 random_range(MONS_DRACONIAN_CALLER, MONS_DRACONIAN_SCORCHER));
724 // (2) Take care of non-draconian random monsters.
725 else if (_is_random_monster(mon_type))
727 level_id place = level_id::current();
729 // Respect destination level for staircases.
730 if (proximity == PROX_NEAR_STAIRS)
732 if (find_mon_place_near_stairs(pos, stair_type, place.branch))
734 // No monsters spawned in the Temple.
735 if (branches[place.branch].id == BRANCH_ECUMENICAL_TEMPLE)
737 proximity = PROX_AWAY_FROM_PLAYER;
739 else
741 if (*stair_type == DCHAR_STAIRS_DOWN) // deeper level
742 ++*lev_mons;
743 else if (*stair_type == DCHAR_STAIRS_UP) // higher level
745 // Monsters don't come from outside the dungeon.
746 if (*lev_mons <= 0)
748 proximity = PROX_AWAY_FROM_PLAYER;
749 // In that case lev_mons stays as it is.
751 else
752 --*lev_mons;
757 else
759 proximity = PROX_AWAY_FROM_PLAYER;
762 } // end proximity check
764 if (place == BRANCH_HALL_OF_BLADES)
765 mon_type = MONS_DANCING_WEAPON;
766 else
768 if (you.level_type == LEVEL_PORTAL_VAULT
769 && vault_mon_types.size() > 0)
771 // XXX: not respecting RANDOM_MOBILE_MONSTER currently.
772 int i = choose_random_weighted(vault_mon_weights.begin(),
773 vault_mon_weights.end());
774 int type = vault_mon_types[i];
775 int base = vault_mon_bases[i];
777 if (type == -1)
779 place = level_id::from_packed_place(base);
780 // If lev_mons is set to you.absdepth0, it was probably
781 // set as a default meaning "the current dungeon depth",
782 // which for a portal vault using its own definition
783 // of random monsters means "the depth of whatever place
784 // we're using for picking the random monster".
785 if (*lev_mons == you.absdepth0)
786 *lev_mons = place.absdepth();
787 // pick_random_monster() is called below
789 else
791 base_type = (monster_type) base;
792 mon_type = (monster_type) type;
793 if (mon_type == RANDOM_DRACONIAN
794 || mon_type == RANDOM_BASE_DRACONIAN
795 || mon_type == RANDOM_NONBASE_DRACONIAN)
797 mon_type =
798 _resolve_monster_type(mon_type, proximity,
799 base_type, pos, mmask,
800 stair_type, lev_mons,
801 chose_ood_monster);
803 return (mon_type);
806 else if (you.level_type == LEVEL_PORTAL_VAULT)
808 // XXX: We don't have a random monster list here, so pick one
809 // from where we were.
810 place.level_type = LEVEL_DUNGEON;
811 *lev_mons = place.absdepth();
814 int tries = 0;
815 while (tries++ < 300)
817 const int original_level = *lev_mons;
818 // Now pick a monster of the given branch and level.
819 mon_type = pick_random_monster(place, *lev_mons, *lev_mons,
820 chose_ood_monster,
821 mon_type == RANDOM_MOBILE_MONSTER);
823 // Don't allow monsters too stupid to use stairs (e.g.
824 // non-spectral zombified undead) to be placed near
825 // stairs.
826 if (proximity != PROX_NEAR_STAIRS
827 || mons_class_can_use_stairs(mon_type))
829 break;
831 *lev_mons = original_level;
834 if (proximity == PROX_NEAR_STAIRS && tries >= 300)
836 proximity = PROX_AWAY_FROM_PLAYER;
838 // Reset target level.
839 if (*stair_type == DCHAR_STAIRS_DOWN)
840 --*lev_mons;
841 else if (*stair_type == DCHAR_STAIRS_UP)
842 ++*lev_mons;
844 mon_type = pick_random_monster(place, *lev_mons, *lev_mons,
845 chose_ood_monster,
846 mon_type == RANDOM_MOBILE_MONSTER);
850 return (mon_type);
853 monster_type pick_random_monster_for_place(const level_id &place,
854 monster_type zombie_monster,
855 bool moderate_ood,
856 bool super_ood,
857 bool want_corpse_capable)
859 int lev = place.absdepth();
861 if (super_ood)
862 lev = 4 + lev * 2;
864 if (moderate_ood)
865 lev += 5;
867 int tries = 100;
868 monster_type chosen = MONS_NO_MONSTER;
869 const zombie_size_type wanted_zombie_size =
870 (zombie_monster != MONS_NO_MONSTER
871 && mons_class_is_zombified(zombie_monster))?
872 zombie_class_size(zombie_monster) : Z_NOZOMBIE;
875 chosen = pick_random_monster(place, lev, lev, NULL);
876 while (!invalid_monster_type(chosen)
877 && wanted_zombie_size != Z_NOZOMBIE
878 && !mons_class_flag(chosen, M_NO_POLY_TO)
879 && mons_zombie_size(chosen) != wanted_zombie_size
880 && (!want_corpse_capable
881 || mons_class_can_leave_corpse(mons_species(chosen)))
882 && --tries > 0);
884 if (!tries)
885 chosen = MONS_NO_MONSTER;
887 return (chosen);
890 // Given a monster_type that includes meta-monster types such as
891 // RANDOM_MONSTER, converts them into a level-appropriate monster.
892 monster_type resolve_monster_type(monster_type mon_type,
893 dungeon_feature_type feat)
895 monster_type base = MONS_NO_MONSTER;
896 coord_def dummy(GXM - 1, GYM - 1);
897 unwind_var<dungeon_feature_type> dummgrid(grd(dummy), feat);
898 dungeon_char_type stair_type = NUM_DCHAR_TYPES;
899 int level = you.absdepth0;
900 bool chose_ood = false;
902 return _resolve_monster_type(mon_type, PROX_ANYWHERE, base,
903 dummy, 0, &stair_type, &level,
904 &chose_ood);
907 // Converts a randomised monster_type into a concrete monster_type, optionally
908 // choosing monsters suitable for generation at the supplied place.
909 monster_type resolve_corpse_monster_type(monster_type mon_type,
910 dungeon_feature_type feat,
911 level_id place)
913 if (mon_type == RANDOM_MONSTER && place.is_valid())
914 return (pick_random_monster_for_place(place, MONS_NO_MONSTER,
915 false, false, true));
917 for (int i = 0; i < 1000; ++i)
919 const monster_type mon = resolve_monster_type(mon_type, feat);
920 if (mons_class_can_leave_corpse(mons_species(mon)))
921 return (mon);
924 return (MONS_NO_MONSTER);
927 // A short function to check the results of near_stairs().
928 // Returns 0 if the point is not near stairs.
929 // Returns 1 if the point is near unoccupied stairs.
930 // Returns 2 if the point is near player-occupied stairs.
931 static int _is_near_stairs(coord_def &p)
933 int result = 0;
935 for (int i = -1; i <= 1; ++i)
936 for (int j = -1; j <= 1; ++j)
938 if (!in_bounds(p))
939 continue;
941 const dungeon_feature_type feat = grd(p);
942 if (feat_is_stair(feat))
944 // Shouldn't matter for escape hatches.
945 if (feat_is_escape_hatch(feat))
946 continue;
948 // Should there be several stairs, don't overwrite the
949 // player on stairs info.
950 if (result < 2)
951 result = (p == you.pos()) ? 2 : 1;
955 return (result);
958 // Checks if the monster is ok to place at mg_pos. If force_location
959 // is true, then we'll be less rigorous in our checks, in particular
960 // allowing land monsters to be placed in shallow water and water
961 // creatures in fountains.
962 static bool _valid_monster_generation_location(const mgen_data &mg,
963 const coord_def &mg_pos)
965 if (!in_bounds(mg_pos)
966 || monster_at(mg_pos)
967 || you.pos() == mg_pos && !fedhas_passthrough_class(mg.cls))
968 return (false);
970 const monster_type montype = (mons_class_is_zombified(mg.cls) ? mg.base_type
971 : mg.cls);
972 if (!monster_habitable_grid(montype, grd(mg_pos), mg.preferred_grid_feature,
973 mons_class_flies(montype), false)
974 || (mg.behaviour != BEH_FRIENDLY && is_sanctuary(mg_pos)))
976 return (false);
979 // Check player proximity to avoid band members being placed
980 // close to the player erroneously.
981 // XXX: This is a little redundant with proximity checks in
982 // place_monster.
983 if (mg.proximity == PROX_AWAY_FROM_PLAYER
984 && distance(you.pos(), mg_pos) <= LOS_RADIUS_SQ)
986 return (false);
989 // Don't generate monsters on top of teleport traps.
990 // (How did they get there?)
991 const trap_def* ptrap = find_trap(mg_pos);
992 if (ptrap && !can_place_on_trap(mg.cls, ptrap->type))
993 return (false);
995 return (true);
998 static bool _valid_monster_generation_location(mgen_data &mg)
1000 return _valid_monster_generation_location(mg, mg.pos);
1003 // Returns true if the player is on a level that should be sheltered from
1004 // OOD packs, based on depth and time spent on-level.
1005 static bool _in_ood_pack_protected_place()
1007 return (env.turns_on_level < 1400 - you.absdepth0 * 117);
1010 int place_monster(mgen_data mg, bool force_pos)
1012 #ifdef DEBUG_MON_CREATION
1013 mpr("in place_monster()", MSGCH_DIAGNOSTICS);
1014 #endif
1016 int tries = 0;
1017 dungeon_char_type stair_type = NUM_DCHAR_TYPES;
1018 int id = -1;
1020 // (1) Early out (summoned to occupied grid).
1021 if (mg.use_position() && monster_at(mg.pos))
1022 return (-1);
1024 bool chose_ood_monster = false;
1025 mg.cls = _resolve_monster_type(mg.cls, mg.proximity, mg.base_type,
1026 mg.pos, mg.map_mask,
1027 &stair_type, &mg.power,
1028 &chose_ood_monster);
1030 if (mg.cls == MONS_NO_MONSTER || mg.cls == MONS_PROGRAM_BUG)
1031 return (-1);
1033 bool create_band = mg.permit_bands();
1034 // If we drew an OOD monster and there hasn't been much time spent
1035 // on level, disable band generation. This applies only to
1036 // randomly picked monsters -- chose_ood_monster will never be set
1037 // true for explicitly specified monsters in vaults and other
1038 // places.
1039 if (chose_ood_monster && _in_ood_pack_protected_place())
1041 dprf("Chose monster with OOD roll: %s, disabling band generation",
1042 get_monster_data(mg.cls)->name);
1043 create_band = false;
1046 // Re-check for PROX_NEAR_STAIRS here - if original monster
1047 // type wasn't RANDOM_MONSTER then the position won't
1048 // have been set.
1049 if (mg.proximity == PROX_NEAR_STAIRS && mg.pos.origin())
1051 branch_type b;
1052 if (!find_mon_place_near_stairs(mg.pos, &stair_type, b))
1054 mg.proximity = PROX_AWAY_FROM_PLAYER;
1056 } // end proximity check
1058 if (mg.cls == MONS_PROGRAM_BUG)
1059 return (-1);
1061 // (3) Decide on banding (good lord!)
1062 int band_size = 1;
1063 bool leader = false;
1064 monster_type band_monsters[BIG_BAND]; // band monster types
1065 band_type band = BAND_NO_BAND;
1066 band_monsters[0] = mg.cls;
1068 // The (very) ugly thing band colour.
1069 static uint8_t ugly_colour = BLACK;
1071 if (create_band)
1073 #ifdef DEBUG_MON_CREATION
1074 mpr("Choose band members...", MSGCH_DIAGNOSTICS);
1075 #endif
1076 band = _choose_band(mg.cls, mg.power, band_size, leader);
1077 band_size++;
1078 for (int i = 1; i < band_size; ++i)
1080 band_monsters[i] = _band_member(band, mg.power);
1082 // Get the (very) ugly thing band colour, so that all (very)
1083 // ugly things in a band will start with it.
1084 if ((band_monsters[i] == MONS_UGLY_THING
1085 || band_monsters[i] == MONS_VERY_UGLY_THING)
1086 && ugly_colour == BLACK)
1088 ugly_colour = ugly_thing_random_colour();
1093 // Set the (very) ugly thing band colour.
1094 if (ugly_colour != BLACK)
1095 mg.colour = ugly_colour;
1097 // Returns 2 if the monster is placed near player-occupied stairs.
1098 int pval = _is_near_stairs(mg.pos);
1099 if (mg.proximity == PROX_NEAR_STAIRS)
1101 // For some cases disallow monsters on stairs.
1102 if (mons_class_is_stationary(mg.cls)
1103 || (pval == 2 // Stairs occupied by player.
1104 && (mons_class_base_speed(mg.cls) == 0
1105 || grd(mg.pos) == DNGN_LAVA
1106 || grd(mg.pos) == DNGN_DEEP_WATER)))
1108 mg.proximity = PROX_AWAY_FROM_PLAYER;
1112 // (4) For first monster, choose location. This is pretty intensive.
1113 bool proxOK;
1114 bool close_to_player;
1116 // Player shoved out of the way?
1117 bool shoved = false;
1119 if (!mg.use_position())
1121 tries = 0;
1123 // Try to pick a position that is
1124 // a) not occupied
1125 // b) compatible
1126 // c) in the 'correct' proximity to the player
1128 while (true)
1130 // Dropped number of tries from 60.
1131 if (tries++ >= 45)
1132 return (-1);
1134 // Placement already decided for PROX_NEAR_STAIRS.
1135 // Else choose a random point on the map.
1136 if (mg.proximity != PROX_NEAR_STAIRS)
1137 mg.pos = random_in_bounds();
1139 if (!_valid_monster_generation_location(mg))
1140 continue;
1142 // Is the grid verboten?
1143 if (map_masked(mg.pos, mg.map_mask))
1144 continue;
1146 // Let's recheck these even for PROX_NEAR_STAIRS, just in case.
1147 // Check proximity to player.
1148 proxOK = true;
1150 switch (mg.proximity)
1152 case PROX_ANYWHERE:
1153 if (distance(you.pos(), mg.pos) < dist_range(2 + random2(3)))
1154 proxOK = false;
1155 break;
1157 case PROX_CLOSE_TO_PLAYER:
1158 case PROX_AWAY_FROM_PLAYER:
1159 // If this is supposed to measure los vs not los,
1160 // then see_cell(mg.pos) should be used instead. (jpeg)
1161 close_to_player = (distance(you.pos(), mg.pos) <=
1162 LOS_RADIUS_SQ);
1164 if (mg.proximity == PROX_CLOSE_TO_PLAYER && !close_to_player
1165 || mg.proximity == PROX_AWAY_FROM_PLAYER && close_to_player)
1167 proxOK = false;
1169 break;
1171 case PROX_NEAR_STAIRS:
1172 if (pval == 2) // player on stairs
1174 if (mons_class_base_speed(mg.cls) == 0)
1176 proxOK = false;
1177 break;
1179 // Swap the monster and the player spots, unless the
1180 // monster was generated in lava or deep water.
1181 if (grd(mg.pos) == DNGN_LAVA
1182 || grd(mg.pos) == DNGN_DEEP_WATER)
1184 proxOK = false;
1185 break;
1188 // You can't be shoved if you're caught in a net.
1189 if (you.caught())
1191 proxOK = false;
1192 break;
1195 shoved = true;
1196 coord_def mpos = mg.pos;
1197 mg.pos = you.pos();
1198 you.moveto(mpos);
1200 proxOK = (pval > 0);
1201 break;
1204 if (!proxOK)
1205 continue;
1207 // Cool.. passes all tests.
1208 break;
1209 } // end while... place first monster
1211 else if (!_valid_monster_generation_location(mg))
1213 // Sanity check that the specified position is valid.
1214 return (-1);
1217 id = _place_monster_aux(mg, true, force_pos);
1219 // Reset the (very) ugly thing band colour.
1220 if (ugly_colour != BLACK)
1221 ugly_colour = BLACK;
1223 // Bail out now if we failed.
1224 if (id == -1)
1225 return (-1);
1227 monster* mon = &menv[id];
1228 if (mg.needs_patrol_point()
1229 || (mon->type == MONS_ALLIGATOR
1230 && !testbits(mon->flags, MF_BAND_MEMBER)))
1232 mon->patrol_point = mon->pos();
1233 #ifdef DEBUG_PATHFIND
1234 mprf("Monster %s is patrolling around (%d, %d).",
1235 mon->name(DESC_PLAIN).c_str(), mon->pos().x, mon->pos().y);
1236 #endif
1239 // Message to player from stairwell/gate appearance.
1240 if (you.see_cell(mg.pos) && mg.proximity == PROX_NEAR_STAIRS)
1242 std::string msg;
1244 if (menv[id].visible_to(&you))
1245 msg = menv[id].name(DESC_CAP_A);
1246 else if (shoved)
1247 msg = "Something";
1249 if (shoved)
1251 msg += " shoves you out of the ";
1252 if (stair_type == DCHAR_ARCH)
1253 msg += "gateway!";
1254 else
1255 msg += "stairwell!";
1256 mpr(msg.c_str());
1258 else if (!msg.empty())
1260 if (stair_type == DCHAR_STAIRS_DOWN)
1261 msg += " comes up the stairs.";
1262 else if (stair_type == DCHAR_STAIRS_UP)
1263 msg += " comes down the stairs.";
1264 else if (stair_type == DCHAR_ARCH)
1265 msg += " comes through the gate.";
1266 else
1267 msg = "";
1269 if (!msg.empty())
1270 mpr(msg.c_str());
1273 // Special case: must update the view for monsters created
1274 // in player LOS.
1275 viewwindow();
1278 // Now, forget about banding if the first placement failed, or there are
1279 // too many monsters already, or we successfully placed by stairs.
1280 // Zotdef change - banding allowed on stairs for extra challenge!
1281 // Frequency reduced, though, and only after 2K turns.
1282 if (id >= MAX_MONSTERS - 30
1283 || (mg.proximity == PROX_NEAR_STAIRS && !crawl_state.game_is_zotdef())
1284 || (crawl_state.game_is_zotdef() && you.num_turns<2000))
1285 return (id);
1287 // Not PROX_NEAR_STAIRS, so it will be part of a band, if there is any.
1288 if (band_size > 1)
1289 menv[id].flags |= MF_BAND_MEMBER;
1291 const bool priest = mon->is_priest();
1293 mgen_data band_template = mg;
1295 if (leader && !mg.summoner)
1297 band_template.summoner = &menv[id];
1298 band_template.flags |= MG_BAND_MINION;
1301 unwind_var<band_type> current_band(active_monster_band, band);
1302 // (5) For each band monster, loop call to place_monster_aux().
1303 for (int i = 1; i < band_size; i++)
1305 if (band_monsters[i] == MONS_NO_MONSTER)
1306 break;
1308 band_template.cls = band_monsters[i];
1310 // We don't want to place a unique that has already been
1311 // generated.
1312 if (mons_is_unique(band_template.cls)
1313 && you.unique_creatures[band_template.cls])
1315 continue;
1318 const int band_id = _place_monster_aux(band_template, false);
1319 if (band_id != -1 && band_id != NON_MONSTER)
1321 menv[band_id].flags |= MF_BAND_MEMBER;
1322 menv[band_id].props["band_leader"].get_int() = menv[id].mid;
1324 // Priestly band leaders should have an entourage of the
1325 // same religion, unless members of that entourage already
1326 // have a different one.
1327 if (priest && menv[band_id].god == GOD_NO_GOD)
1328 menv[band_id].god = mon->god;
1330 if (mon->type == MONS_PIKEL)
1332 // Don't give XP for the slaves to discourage hunting. Pikel
1333 // has an artificially large XP modifier to compensate for
1334 // this.
1335 menv[band_id].flags |= MF_NO_REWARD;
1336 menv[band_id].props["pikel_band"] = true;
1338 if (mon->type == MONS_SHEDU)
1340 // We store these here for later resurrection, etc.
1341 menv[band_id].number = menv[id].mid;
1342 menv[id].number = menv[band_id].mid;
1347 // Placement of first monster, at least, was a success.
1348 return (id);
1351 monster* get_free_monster()
1353 for (int i = 0; i < MAX_MONSTERS; ++i)
1354 if (env.mons[i].type == MONS_NO_MONSTER)
1356 env.mons[i].reset();
1357 return (&env.mons[i]);
1360 return (NULL);
1363 void mons_add_blame(monster* mon, const std::string &blame_string)
1365 const bool exists = mon->props.exists("blame");
1366 CrawlStoreValue& blame = mon->props["blame"];
1367 if (!exists)
1368 blame.new_vector(SV_STR, SFLAG_CONST_TYPE);
1369 blame.get_vector().push_back(blame_string);
1372 static void _place_twister_clouds(monster *mon)
1374 // Yay for the abj_degree having a huge granularity.
1375 if (mon->has_ench(ENCH_ABJ))
1377 mon_enchant abj = mon->get_ench(ENCH_ABJ);
1378 mon->lose_ench_duration(abj, abj.duration / 2);
1381 tornado_damage(mon, -10);
1384 static int _place_monster_aux(const mgen_data &mg,
1385 bool first_band_member, bool force_pos)
1387 coord_def fpos;
1389 // Some sanity checks.
1390 if (mons_is_unique(mg.cls) && you.unique_creatures[mg.cls]
1391 && !crawl_state.game_is_arena()
1392 || mg.cls == MONS_MERGED_SLIME_CREATURE
1393 || mons_is_sensed(mg.cls)
1394 || mg.cls == MONS_PLAYER)
1396 die("invalid monster to place: %s (%d)", mons_class_name(mg.cls), mg.cls);
1399 const monsterentry *m_ent = get_monster_data(mg.cls);
1401 monster* mon = get_free_monster();
1402 if (!mon)
1403 return (-1);
1405 const monster_type montype = (mons_class_is_zombified(mg.cls) ? mg.base_type
1406 : mg.cls);
1408 // Setup habitat and placement.
1409 // If the space is occupied, try some neighbouring square instead.
1410 if (first_band_member && in_bounds(mg.pos)
1411 && (mg.behaviour == BEH_FRIENDLY || !is_sanctuary(mg.pos))
1412 && !monster_at(mg.pos)
1413 && (you.pos() != mg.pos || fedhas_passthrough_class(mg.cls))
1414 && (force_pos || monster_habitable_grid(montype, grd(mg.pos))))
1416 fpos = mg.pos;
1418 else
1420 int i;
1421 // We'll try 1000 times for a good spot.
1422 for (i = 0; i < 1000; ++i)
1424 fpos = mg.pos + coord_def(random_range(-3, 3),
1425 random_range(-3, 3));
1427 if (_valid_monster_generation_location(mg, fpos))
1428 break;
1431 // Did we really try 1000 times?
1432 if (i == 1000)
1433 return (-1);
1436 ASSERT(!monster_at(fpos));
1438 if (crawl_state.game_is_arena()
1439 && arena_veto_place_monster(mg, first_band_member, fpos))
1441 return (-1);
1444 // Now, actually create the monster. (Wheeee!)
1445 mon->set_new_monster_id();
1446 mon->type = mg.cls;
1447 mon->base_monster = mg.base_type;
1448 mon->number = mg.number;
1450 // Set pos and link monster into monster grid.
1451 if (!mon->move_to_pos(fpos))
1453 mon->reset();
1454 return (-1);
1457 if (mons_is_item_mimic(mg.cls))
1459 // Mimics who mimic thin air get the axe.
1460 if (!give_mimic_item(mon))
1462 mon->reset();
1463 mgrd(fpos) = NON_MONSTER;
1464 return (-1);
1468 if (mg.props.exists("serpent_of_hell_flavour"))
1469 mon->props["serpent_of_hell_flavour"] =
1470 mg.props["serpent_of_hell_flavour"].get_int();
1472 // Generate a brand shiny new monster, or zombie.
1473 if (mons_class_is_zombified(mg.cls))
1475 monster_type ztype = mg.base_type;
1477 if (ztype == MONS_NO_MONSTER)
1479 ztype = pick_local_zombifiable_monster(mg.power, true, mg.cls,
1480 fpos);
1483 define_zombie(mon, ztype, mg.cls);
1485 else
1486 define_monster(mon);
1488 // Is it a god gift?
1489 if (mg.god != GOD_NO_GOD)
1491 mon->god = mg.god;
1492 mon->flags |= MF_GOD_GIFT;
1494 // Not a god gift, give priestly monsters a god.
1495 else if (mons_class_flag(mg.cls, M_PRIEST))
1497 // Berserkers belong to Trog.
1498 if (mg.cls == MONS_DEEP_DWARF_BERSERKER
1499 || mg.cls == MONS_SPRIGGAN_BERSERKER)
1501 mon->god = GOD_TROG;
1503 // Deep dwarf death knights belong to Yredelemnul.
1504 else if (mg.cls == MONS_DEEP_DWARF_DEATH_KNIGHT)
1505 mon->god = GOD_YREDELEMNUL;
1506 // Wiglaf belongs to Okawaru.
1507 else if (mg.cls == MONS_WIGLAF)
1508 mon->god = GOD_OKAWARU;
1509 else
1511 switch (mons_genus(mg.cls))
1513 case MONS_ORC:
1514 mon->god = GOD_BEOGH;
1515 break;
1516 case MONS_JELLY:
1517 mon->god = GOD_JIYVA;
1518 break;
1519 case MONS_MUMMY:
1520 case MONS_DRACONIAN:
1521 case MONS_ELF:
1522 // [ds] Vault defs can request priest monsters of unusual types.
1523 default:
1524 mon->god = GOD_NAMELESS;
1525 break;
1529 // The royal jelly belongs to Jiyva.
1530 else if (mg.cls == MONS_ROYAL_JELLY)
1531 mon->god = GOD_JIYVA;
1532 // Mennas belongs to Zin.
1533 else if (mg.cls == MONS_MENNAS)
1534 mon->god = GOD_ZIN;
1535 // 1 out of 7 non-priestly orcs are unbelievers.
1536 else if (mons_genus(mg.cls) == MONS_ORC)
1538 if (!one_chance_in(7))
1539 mon->god = GOD_BEOGH;
1541 // Angels (other than Mennas) and Daevas belong to TSO, but 1 out of
1542 // 7 in the Abyss are adopted by Xom.
1543 else if (mons_class_holiness(mg.cls) == MH_HOLY)
1545 if (mg.level_type != LEVEL_ABYSS || !one_chance_in(7))
1546 mon->god = GOD_SHINING_ONE;
1547 else
1548 mon->god = GOD_XOM;
1550 // 6 out of 7 demons in the Abyss belong to Lugonu.
1551 else if (mons_class_holiness(mg.cls) == MH_DEMONIC)
1553 if (mg.level_type == LEVEL_ABYSS && !one_chance_in(7))
1554 mon->god = GOD_LUGONU;
1557 // Holy monsters need their halo!
1558 if (mon->holiness() == MH_HOLY)
1559 invalidate_agrid(true);
1560 if (mg.cls == MONS_SILENT_SPECTRE)
1561 invalidate_agrid(true);
1563 // If the caller requested a specific colour for this monster, apply
1564 // it now.
1565 if (mg.colour != BLACK)
1566 mon->colour = mg.colour;
1568 if (mg.mname != "")
1569 mon->mname = mg.mname;
1571 if (mg.hd != 0)
1573 mon->hit_dice = mg.hd;
1574 // Re-roll HP.
1575 int hp = hit_points(mg.hd, m_ent->hpdice[1], m_ent->hpdice[2]);
1576 // But only for monsters with random HP.
1577 if (hp > 0)
1579 mon->max_hit_points = hp;
1580 mon->hit_points = hp;
1584 if (mg.hp != 0)
1586 mon->max_hit_points = mg.hp;
1587 mon->hit_points = mg.hp;
1590 // Store the extra flags here.
1591 mon->flags |= mg.extra_flags;
1593 // The return of Boris is now handled in monster_die(). Not setting
1594 // this for Boris here allows for multiple Borises in the dungeon at
1595 // the same time. - bwr
1596 if (mons_is_unique(mg.cls))
1597 you.unique_creatures[mg.cls] = true;
1599 if (mons_class_flag(mg.cls, M_INVIS))
1600 mon->add_ench(ENCH_INVIS);
1602 if (mons_class_flag(mg.cls, M_CONFUSED))
1603 mon->add_ench(ENCH_CONFUSION);
1605 if (mg.cls == MONS_SHAPESHIFTER)
1606 mon->add_ench(ENCH_SHAPESHIFTER);
1608 if (mg.cls == MONS_GLOWING_SHAPESHIFTER)
1609 mon->add_ench(ENCH_GLOWING_SHAPESHIFTER);
1611 if (mg.cls == MONS_SPIRIT)
1612 mon->add_ench(ENCH_FADING_AWAY);
1614 if (mg.cls == MONS_TOADSTOOL || mg.cls == MONS_SALT_PILLAR)
1616 // This enchantment is a timer that counts down until death.
1617 // It should last longer than the lifespan of a corpse, to avoid
1618 // spawning mushrooms in the same place over and over. Aside
1619 // from that, the value is slightly randomised to avoid
1620 // simultaneous die-offs of mushroom rings.
1621 mon->add_ench(ENCH_SLOWLY_DYING);
1623 else if (mg.cls == MONS_HYPERACTIVE_BALLISTOMYCETE)
1625 mon->add_ench(ENCH_EXPLODING);
1628 if (mg.cls == MONS_TWISTER)
1629 mon->add_ench(ENCH_PERM_TORNADO);
1631 if (mons_is_feat_mimic(mg.cls))
1633 switch (mg.cls)
1635 case MONS_DOOR_MIMIC:
1636 // Requires no initialisation.
1637 break;
1639 case MONS_PORTAL_MIMIC:
1641 if (coinflip())
1643 const char *portals[3] = {
1644 "gateway to a bazaar",
1645 "glowing drain",
1646 "sand-covered staircase",
1649 int colors[3] = {
1650 ETC_SHIMMER_BLUE,
1651 LIGHTGREEN,
1652 BROWN
1655 int portal_choice = random2(3);
1657 mon->props["portal_desc"] = std::string(portals[portal_choice]);
1658 mon->colour = colors[portal_choice];
1660 else
1662 mon->colour = CYAN;
1664 break;
1667 case MONS_TRAP_MIMIC:
1668 mon->props["trap_type"] = static_cast<short>(random_trap(DNGN_TRAP_MECHANICAL));
1669 break;
1671 // Needs a more complicated block.
1672 case MONS_SHOP_MIMIC:
1674 // Otherwise we need to make a random name.
1675 shop_type type = static_cast<shop_type>(SHOP_WEAPON+random2(NUM_SHOPS-1));
1677 std::string sh_name = apostrophise(make_name(random_int(), false)) +
1678 " " + shop_type_name(type);
1679 std::string sh_suffix = shop_type_suffix(type, fpos);
1680 if (!sh_suffix.empty())
1681 sh_name += " " + sh_suffix;
1683 mon->props["shop_name"] = sh_name;
1684 mon->props["shop_type"] = static_cast<short>(type);
1685 break;
1688 // Uses complicated logic!
1689 case MONS_STAIR_MIMIC:
1691 // So far, branch stairs.
1692 mon->colour = YELLOW;
1694 bool got_stair = false;
1696 // If we're in lair, and we're in one of the suitable levels,
1697 // and it's the disabled branch, pretend to be that one.
1698 if (you.where_are_you == BRANCH_LAIR)
1700 const branch_type lair_branches[3] = {
1701 BRANCH_SWAMP,
1702 BRANCH_SHOALS,
1703 BRANCH_SNAKE_PIT,
1706 for (int i = 0; i < 3; i++) {
1707 if (branches[lair_branches[i]].startdepth == -1)
1709 mon->props["stair_type"] = static_cast<short>(
1710 branches[lair_branches[i]].entry_stairs);
1711 got_stair = true;
1716 // If we're in the vaults, pick a suitable branch.
1717 if (you.where_are_you == BRANCH_VAULTS)
1719 mon->props["stair_type"] = static_cast<short>(random_choose(
1720 DNGN_ENTER_HALL_OF_BLADES, DNGN_ENTER_CRYPT, -1));
1721 break;
1724 // Tantalise the player with an early temple.
1725 if (you.where_are_you == BRANCH_MAIN_DUNGEON && you.absdepth0 <= 7
1726 && you.absdepth0 >= 4)
1728 mon->props["stair_type"] = static_cast<short>(DNGN_ENTER_TEMPLE);
1729 break;
1732 // Otherwise, give a seemingly valid branch.
1733 if (you.where_are_you == BRANCH_MAIN_DUNGEON)
1735 for (int branch = BRANCH_ORCISH_MINES; branch < NUM_BRANCHES; ++branch)
1737 Branch *b = &branches[branch];
1738 if (b->parent_branch == BRANCH_MAIN_DUNGEON
1739 && you.absdepth0 >= b->mindepth
1740 && you.absdepth0 <= b->maxdepth
1741 && one_chance_in(4))
1743 mon->props["stair_type"] = static_cast<short>(b->entry_stairs);
1744 got_stair = true;
1745 break;
1750 if (got_stair)
1751 break;
1753 // If we get to here, we've not got a stair yet...
1754 // So either choose a stone stair, or an escape hatch.
1755 dungeon_feature_type stair = random_stair();
1756 mon->props["stair_type"] = static_cast<short>(stair);
1757 const feature_def stair_d = get_feature_def(stair);
1758 if (stair == DNGN_ESCAPE_HATCH_DOWN
1759 || stair == DNGN_ESCAPE_HATCH_UP)
1761 mon->colour = stair_d.colour;
1763 else
1764 mon->colour = stair_d.seen_em_colour;
1765 break;
1768 // Just needs a selection of random fountains.
1769 case MONS_FOUNTAIN_MIMIC:
1771 dungeon_feature_type fount = static_cast<dungeon_feature_type>(
1772 DNGN_FOUNTAIN_BLUE+random2(DNGN_PERMADRY_FOUNTAIN-DNGN_FOUNTAIN_BLUE));
1773 const feature_def fount_d = get_feature_def(fount);
1774 mon->props["fountain_type"] = static_cast<short>(fount);
1775 mon->colour = fount_d.colour;
1776 break;
1778 default:
1779 break;
1785 if (!crawl_state.game_is_arena() && you.misled())
1786 update_mislead_monster(mon);
1788 if (monster_can_submerge(mon, grd(fpos)) && !one_chance_in(5))
1789 mon->add_ench(ENCH_SUBMERGED);
1791 mon->flags |= MF_JUST_SUMMONED;
1793 // Don't leave shifters in their starting shape.
1794 if (mg.cls == MONS_SHAPESHIFTER || mg.cls == MONS_GLOWING_SHAPESHIFTER)
1796 no_messages nm;
1797 monster_polymorph(mon, RANDOM_MONSTER);
1799 // It's not actually a known shapeshifter if it happened to be
1800 // placed in LOS of the player.
1801 mon->flags &= ~MF_KNOWN_MIMIC;
1804 // dur should always be 1-6 for monsters that can be abjured.
1805 const bool summoned = mg.abjuration_duration >= 1
1806 && mg.abjuration_duration <= 6;
1808 if (mg.cls == MONS_DANCING_WEAPON)
1810 if (mg.props.exists(TUKIMA_WEAPON))
1811 give_specific_item(mon, mg.props[TUKIMA_WEAPON].get_item());
1812 else
1813 give_item(mon->mindex(), mg.power, summoned);
1815 // Dancing weapons *always* have a weapon. Fail to create them
1816 // otherwise.
1817 const item_def* wpn = mon->mslot_item(MSLOT_WEAPON);
1818 if (!wpn)
1820 mon->destroy_inventory();
1821 mon->reset();
1822 mgrd(fpos) = NON_MONSTER;
1823 return (-1);
1825 else
1826 mon->colour = wpn->colour;
1828 else if (mons_class_itemuse(mg.cls) >= MONUSE_STARTING_EQUIPMENT)
1830 give_item(mon->mindex(), mg.power, summoned);
1831 // Give these monsters a second weapon. - bwr
1832 if (mons_class_wields_two_weapons(mg.cls))
1833 give_weapon(mon->mindex(), mg.power, summoned);
1835 unwind_var<int> save_speedinc(mon->speed_increment);
1836 mon->wield_melee_weapon(false);
1839 if (mg.cls == MONS_SLIME_CREATURE)
1841 if (mg.number > 1)
1843 // Boost HP to what it would have been if it had grown this
1844 // big by merging.
1845 mon->hit_points *= mg.number;
1846 mon->max_hit_points *= mg.number;
1850 // Set attitude, behaviour and target.
1851 mon->attitude = ATT_HOSTILE;
1852 mon->behaviour = mg.behaviour;
1854 // Statues cannot sleep (nor wander but it means they are a bit
1855 // more aware of the player than they'd be otherwise).
1856 if (mons_is_statue(mg.cls))
1857 mon->behaviour = BEH_WANDER;
1859 mon->foe_memory = 0;
1861 // Setting attitude will always make the monster wander...
1862 // If you want sleeping hostiles, use BEH_SLEEP since the default
1863 // attitude is hostile.
1864 if (mg.behaviour > NUM_BEHAVIOURS)
1866 if (mg.behaviour == BEH_FRIENDLY)
1867 mon->attitude = ATT_FRIENDLY;
1869 if (mg.behaviour == BEH_GOOD_NEUTRAL)
1870 mon->attitude = ATT_GOOD_NEUTRAL;
1872 if (mg.behaviour == BEH_NEUTRAL)
1873 mon->attitude = ATT_NEUTRAL;
1875 if (mg.behaviour == BEH_STRICT_NEUTRAL)
1876 mon->attitude = ATT_STRICT_NEUTRAL;
1878 mon->behaviour = BEH_WANDER;
1881 if (summoned)
1883 // Instead of looking for dancing weapons, look for Tukima's dance.
1884 // Dancing weapons can be created with shadow creatures. {due}
1885 bool mark_items = mg.summon_type != SPELL_TUKIMAS_DANCE;
1887 mon->mark_summoned(mg.abjuration_duration,
1888 mark_items,
1889 mg.summon_type);
1891 ASSERT(!invalid_monster_index(mg.foe)
1892 || mg.foe == MHITYOU || mg.foe == MHITNOT);
1893 mon->foe = mg.foe;
1895 std::string blame_prefix;
1897 if (mg.flags & MG_BAND_MINION)
1899 blame_prefix = "led by ";
1901 else if (mg.abjuration_duration > 0)
1903 blame_prefix = "summoned by ";
1905 if (mg.summoner != NULL && mg.summoner->alive()
1906 && mg.summoner->atype() == ACT_MONSTER
1907 && static_cast<const monster* >(mg.summoner)->type == MONS_MARA)
1909 blame_prefix = "woven by ";
1912 else if (mons_class_is_zombified(mg.cls))
1914 blame_prefix = "animated by ";
1916 else if (mg.summon_type == SPELL_STICKS_TO_SNAKES)
1918 blame_prefix = "transmiuted by ";
1920 else
1922 blame_prefix = "created by ";
1924 if (mg.cls == MONS_ELDRITCH_TENTACLE || mg.cls == MONS_ELDRITCH_TENTACLE_SEGMENT)
1925 blame_prefix = "called by ";
1928 if (!mg.non_actor_summoner.empty())
1930 mons_add_blame(mon, blame_prefix + mg.non_actor_summoner);
1932 // NOTE: The summoner might be dead if the summoned is placed by a
1933 // beam which killed the summoner first (like fire vortexes placed
1934 // by the Fire Storm spell); a deceased summoner's mindex might also
1935 // be reused to create its summon, so make sure the summon doesn't
1936 // think it has summoned itself.
1937 else if (mg.summoner != NULL && mg.summoner->alive()
1938 && mg.summoner != mon)
1940 ASSERT(mg.summoner->alive());
1941 if (mg.summoner->atype() == ACT_PLAYER)
1943 mons_add_blame(mon, blame_prefix + "the player character");
1945 else
1947 monster* sum = mg.summoner->as_monster();
1948 mons_add_blame(mon, (blame_prefix
1949 + sum->full_name(DESC_NOCAP_A, true)));
1950 if (sum->props.exists("blame"))
1952 CrawlVector& oldblame = sum->props["blame"].get_vector();
1953 for (CrawlVector::iterator i = oldblame.begin();
1954 i != oldblame.end(); ++i)
1956 mons_add_blame(mon, *i);
1962 // Initialise (very) ugly things and pandemonium demons.
1963 if (mon->type == MONS_UGLY_THING
1964 || mon->type == MONS_VERY_UGLY_THING)
1966 ghost_demon ghost;
1967 ghost.init_ugly_thing(mon->type == MONS_VERY_UGLY_THING, false,
1968 mg.colour);
1969 mon->set_ghost(ghost, false);
1970 mon->uglything_init();
1972 else if (mon->type == MONS_LABORATORY_RAT)
1974 ghost_demon ghost;
1975 ghost.init_labrat(mg.colour);
1976 mon->set_ghost(ghost, false);
1977 mon->labrat_init();
1979 else if (mon->type == MONS_DANCING_WEAPON)
1981 ghost_demon ghost;
1982 // We can't use monster::weapon here because it wants to look
1983 // at attack types, which are in the ghost structure we're
1984 // building.
1985 ASSERT(mon->mslot_item(MSLOT_WEAPON));
1986 // Dancing weapons are placed at pretty high power. Remember, the
1987 // player is fighting them one-on-one, while he will often summon
1988 // several.
1989 ghost.init_dancing_weapon(*(mon->mslot_item(MSLOT_WEAPON)), 180);
1990 mon->set_ghost(ghost);
1991 mon->dancing_weapon_init();
1994 #ifdef USE_TILE
1995 tile_init_props(mon);
1996 #endif
1998 #ifndef DEBUG_DIAGNOSTICS
1999 // A rare case of a debug message NOT showing in the debug mode.
2000 if (mons_class_flag(mon->type, M_UNFINISHED))
2002 mprf(MSGCH_WARN, "Warning: monster '%s' is not yet fully coded.",
2003 mon->name(DESC_PLAIN).c_str());
2005 #endif
2007 mark_interesting_monst(mon, mg.behaviour);
2009 if (crawl_state.game_is_arena())
2010 arena_placed_monster(mon);
2011 else if (!Generating_Level && you.can_see(mon))
2013 // FIXME: This causes "comes into view" messages at the
2014 // wrong time, since code checks for placement
2015 // success before printing messages.
2016 handle_seen_interrupt(mon);
2019 // Area effects can produce additional messages, and thus need to be
2020 // done after come in view ones.
2021 if (mon->type == MONS_TWISTER)
2022 _place_twister_clouds(mon);
2024 return (mon->mindex());
2027 monster_type pick_random_zombie()
2029 static std::vector<monster_type> zombifiable;
2031 if (zombifiable.empty())
2033 for (int i = 0; i < NUM_MONSTERS; ++i)
2035 if (mons_species(i) != i || i == MONS_PROGRAM_BUG)
2036 continue;
2038 const monster_type mcls = static_cast<monster_type>(i);
2040 if (!mons_zombie_size(mcls) || mons_is_unique(mcls))
2041 continue;
2043 zombifiable.push_back(mcls);
2047 return (zombifiable[random2(zombifiable.size())]);
2050 // Check base monster class against zombie type and position if set.
2051 static bool _good_zombie(monster_type base, monster_type cs,
2052 const coord_def& pos)
2054 // Actually pick a monster that is happy where we want to put it.
2055 // Fish zombies on land are helpless and uncool.
2056 if (in_bounds(pos) && !monster_habitable_grid(base, grd(pos)))
2057 return (false);
2059 if (cs == MONS_NO_MONSTER)
2060 return (true);
2062 // If skeleton, monster must have a skeleton.
2063 if ((cs == MONS_SKELETON_SMALL || cs == MONS_SKELETON_LARGE)
2064 && !mons_skeleton(base))
2066 return (false);
2069 // Size must match, but you can make a spectral thing out of
2070 // anything.
2071 if (cs != MONS_SPECTRAL_THING
2072 && mons_zombie_size(base) != zombie_class_size(cs))
2074 return (false);
2077 return (true);
2080 monster_type pick_local_zombifiable_monster(int power, bool hack_hd,
2081 monster_type cs,
2082 const coord_def& pos)
2084 bool ignore_rarity = false;
2085 power = std::min(27, power);
2087 // How OOD this zombie can be.
2088 int relax = 5;
2090 // Pick an appropriate creature to make a zombie out of,
2091 // levelwise. The old code was generating absolutely
2092 // incredible OOD zombies.
2093 while (true)
2095 monster_type base = pick_random_zombie();
2097 // On certain branches, zombie creation will fail if we use
2098 // the mons_rarity() functions, because (for example) there
2099 // are NO zombifiable "native" abyss creatures. Other branches
2100 // where this is a problem are hell levels and the crypt.
2101 // we have to watch for summoned zombies on other levels, too,
2102 // such as the Temple, HoB, and Slime Pits.
2103 if (you.level_type != LEVEL_DUNGEON
2104 || player_in_hell()
2105 || player_in_branch(BRANCH_HALL_OF_ZOT)
2106 || player_in_branch(BRANCH_VESTIBULE_OF_HELL)
2107 || player_in_branch(BRANCH_ECUMENICAL_TEMPLE)
2108 || player_in_branch(BRANCH_CRYPT)
2109 || player_in_branch(BRANCH_TOMB)
2110 || player_in_branch(BRANCH_HALL_OF_BLADES)
2111 || player_in_branch(BRANCH_SNAKE_PIT)
2112 || player_in_branch(BRANCH_SLIME_PITS)
2113 || one_chance_in(1000))
2115 ignore_rarity = true;
2118 // Don't make out-of-rarity zombies when we don't have to.
2119 if (!ignore_rarity && mons_rarity(base) == 0)
2120 continue;
2122 // Does the zombie match the parameters?
2123 if (!_good_zombie(base, cs, pos))
2124 continue;
2126 // Hack -- non-dungeon zombies are always made out of nastier
2127 // monsters.
2128 if (hack_hd && you.level_type != LEVEL_DUNGEON && mons_power(base) > 8)
2129 return (base);
2131 // Check for rarity.. and OOD - identical to mons_place()
2132 int level, diff, chance;
2134 level = mons_level(base) - 4;
2135 diff = level - power;
2137 chance = (ignore_rarity) ? 100
2138 : mons_rarity(base) - (diff * diff) / 2;
2140 if (power > level - relax && power < level + relax
2141 && random2avg(100, 2) <= chance)
2143 return (base);
2146 // Every so often, we'll relax the OOD restrictions. Avoids
2147 // infinite loops (if we don't do this, things like creating
2148 // a large skeleton on level 1 may hang the game!).
2149 if (one_chance_in(5))
2150 relax++;
2154 void roll_zombie_hp(monster* mon)
2156 ASSERT(mons_class_is_zombified(mon->type));
2158 int hp = 0;
2160 switch (mon->type)
2162 case MONS_ZOMBIE_SMALL:
2163 case MONS_ZOMBIE_LARGE:
2164 hp = hit_points(mon->hit_dice, 6, 5);
2165 break;
2167 case MONS_SKELETON_SMALL:
2168 case MONS_SKELETON_LARGE:
2169 hp = hit_points(mon->hit_dice, 5, 4);
2170 break;
2172 case MONS_SIMULACRUM_SMALL:
2173 case MONS_SIMULACRUM_LARGE:
2174 // Simulacra aren't tough, but you can create piles of them. - bwr
2175 hp = hit_points(mon->hit_dice, 1, 4);
2176 break;
2178 case MONS_SPECTRAL_THING:
2179 hp = hit_points(mon->hit_dice, 4, 4);
2180 break;
2182 default:
2183 die("invalid zombie type %d (%s)", mon->type,
2184 mons_class_name(mon->type));
2187 mon->max_hit_points = std::max(hp, 1);
2188 mon->hit_points = mon->max_hit_points;
2191 static void _roll_zombie_ac_ev(monster* mon)
2193 ASSERT(mons_class_is_zombified(mon->type));
2195 int acmod = 0;
2196 int evmod = 0;
2198 switch (mon->type)
2200 case MONS_ZOMBIE_SMALL:
2201 case MONS_ZOMBIE_LARGE:
2202 acmod = -2;
2203 evmod = -5;
2204 break;
2206 case MONS_SKELETON_SMALL:
2207 case MONS_SKELETON_LARGE:
2208 acmod = -6;
2209 evmod = -7;
2210 break;
2212 case MONS_SIMULACRUM_SMALL:
2213 case MONS_SIMULACRUM_LARGE:
2214 // Simulacra aren't tough, but you can create piles of them. - bwr
2215 acmod = -2;
2216 evmod = -5;
2217 break;
2219 case MONS_SPECTRAL_THING:
2220 acmod = +2;
2221 evmod = -5;
2222 break;
2224 default:
2225 die("invalid zombie type %d (%s)", mon->type,
2226 mons_class_name(mon->type));
2229 mon->ac = std::max(mon->ac + acmod, 0);
2230 mon->ev = std::max(mon->ev + evmod, 0);
2233 void define_zombie(monster* mon, monster_type ztype, monster_type cs)
2235 ASSERT(ztype != MONS_NO_MONSTER);
2236 ASSERT(mons_class_is_zombified(cs));
2238 monster_type base = mons_species(ztype);
2240 ASSERT(zombie_class_size(cs) == Z_NOZOMBIE
2241 || zombie_class_size(cs) == mons_zombie_size(base));
2243 // Set type to the original type to calculate appropriate stats.
2244 mon->type = ztype;
2245 define_monster(mon);
2247 mon->type = cs;
2248 mon->base_monster = base;
2250 mon->colour = mons_class_colour(mon->type);
2251 mon->speed = mons_class_zombie_base_speed(mon->base_monster);
2253 // Turn off all melee ability flags except dual-wielding.
2254 mon->flags &= (~MF_MELEE_MASK | MF_TWO_WEAPONS);
2256 // Turn off all spellcasting and priestly ability flags.
2257 // Hack - kraken get to keep their spell-like ability.
2258 if (mon->base_monster != MONS_KRAKEN)
2259 mon->flags &= ~MF_SPELL_MASK;
2261 // Turn off regeneration if the base monster cannot regenerate.
2262 // This is needed for e.g. spectral things of non-regenerating
2263 // monsters.
2264 if (!mons_class_can_regenerate(mon->base_monster))
2265 mon->flags |= MF_NO_REGEN;
2267 roll_zombie_hp(mon);
2268 _roll_zombie_ac_ev(mon);
2271 static band_type _choose_band(int mon_type, int power, int &band_size,
2272 bool &natural_leader)
2274 #ifdef DEBUG_MON_CREATION
2275 mpr("in _choose_band()", MSGCH_DIAGNOSTICS);
2276 #endif
2277 // Band size describes the number of monsters in addition to
2278 // the band leader.
2279 band_size = 0; // Single monster, no band.
2280 natural_leader = false;
2281 band_type band = BAND_NO_BAND;
2283 switch (mon_type)
2285 case MONS_ORC:
2286 if (coinflip())
2287 break;
2288 // intentional fall-through {dlb}
2289 case MONS_ORC_WIZARD:
2290 band = BAND_ORCS;
2291 band_size = 2 + random2(3);
2292 break;
2294 case MONS_ORC_PRIEST:
2295 case MONS_ORC_WARRIOR:
2296 band = BAND_ORC_WARRIOR;
2297 band_size = 2 + random2(3);
2298 break;
2300 case MONS_ORC_WARLORD:
2301 case MONS_SAINT_ROKA:
2302 band_size = 5 + random2(5); // warlords have large bands
2303 // intentional fall through
2304 case MONS_ORC_KNIGHT:
2305 band = BAND_ORC_KNIGHT; // orcs + knight
2306 band_size += 3 + random2(4);
2307 natural_leader = true;
2308 break;
2310 case MONS_ORC_HIGH_PRIEST:
2311 band = BAND_ORC_HIGH_PRIEST;
2312 band_size = 4 + random2(4);
2313 natural_leader = true;
2314 break;
2316 case MONS_BIG_KOBOLD:
2317 if (power > 3)
2319 band = BAND_KOBOLDS;
2320 band_size = 2 + random2(6);
2322 break;
2324 case MONS_KILLER_BEE:
2325 band = BAND_KILLER_BEES;
2326 band_size = 2 + random2(4);
2327 break;
2329 case MONS_FLYING_SKULL:
2330 band = BAND_FLYING_SKULLS;
2331 band_size = 2 + random2(4);
2332 break;
2333 case MONS_SLIME_CREATURE:
2334 band = BAND_SLIME_CREATURES;
2335 band_size = 2 + random2(4);
2336 break;
2337 case MONS_YAK:
2338 band = BAND_YAKS;
2339 band_size = 2 + random2(4);
2340 break;
2341 case MONS_UGLY_THING:
2342 case MONS_VERY_UGLY_THING:
2343 band = BAND_UGLY_THINGS;
2344 band_size = 2 + random2(4);
2345 break;
2346 case MONS_HELL_HOUND:
2347 band = BAND_HELL_HOUNDS;
2348 band_size = 2 + random2(3);
2349 break;
2350 case MONS_JACKAL:
2351 band = BAND_JACKALS;
2352 band_size = 1 + random2(3);
2353 break;
2354 case MONS_MARGERY:
2355 natural_leader = true;
2356 case MONS_HELL_KNIGHT:
2357 band = BAND_HELL_KNIGHTS;
2358 band_size = 4 + random2(4);
2359 break;
2360 case MONS_JOSEPHINE:
2361 case MONS_NECROMANCER:
2362 case MONS_VAMPIRE_MAGE:
2363 natural_leader = true;
2364 band = BAND_NECROMANCER;
2365 band_size = 4 + random2(4);
2366 break;
2367 case MONS_GNOLL:
2368 band = BAND_GNOLLS;
2369 band_size = (coinflip() ? 3 : 2);
2370 break;
2371 case MONS_DEEP_DWARF_SCION:
2372 band = BAND_DEEP_DWARF;
2373 band_size = (one_chance_in(5)? 2: 1) + random2(3);
2374 break;
2375 case MONS_DEEP_DWARF_ARTIFICER:
2376 case MONS_DEEP_DWARF_DEATH_KNIGHT:
2377 band = BAND_DEEP_DWARF;
2378 band_size = 3 + random2(4);
2379 break;
2380 case MONS_GRUM:
2381 natural_leader = true;
2382 band = BAND_WAR_DOGS;
2383 band_size = 2 + random2(3);
2384 break;
2385 case MONS_BUMBLEBEE:
2386 band = BAND_BUMBLEBEES;
2387 band_size = 2 + random2(4);
2388 break;
2389 case MONS_CENTAUR_WARRIOR:
2390 natural_leader = true;
2391 case MONS_CENTAUR:
2392 if (power > 9 && one_chance_in(3) && you.where_are_you != BRANCH_SHOALS)
2394 band = BAND_CENTAURS;
2395 band_size = 2 + random2(4);
2397 break;
2399 case MONS_YAKTAUR_CAPTAIN:
2400 natural_leader = true;
2401 case MONS_YAKTAUR:
2402 if (coinflip())
2404 band = BAND_YAKTAURS;
2405 band_size = 2 + random2(3);
2407 break;
2409 case MONS_DEATH_YAK:
2410 band = BAND_DEATH_YAKS;
2411 band_size = 2 + random2(4);
2412 break;
2413 case MONS_INSUBSTANTIAL_WISP:
2414 band = BAND_INSUBSTANTIAL_WISPS;
2415 band_size = 4 + random2(5);
2416 break;
2417 case MONS_OGRE_MAGE:
2418 natural_leader = true;
2419 band = BAND_OGRE_MAGE;
2420 band_size = 4 + random2(4);
2421 break;
2422 case MONS_BALRUG:
2423 natural_leader = true;
2424 band = BAND_BALRUG; // RED gr demon
2425 band_size = 2 + random2(3);
2426 break;
2427 case MONS_CACODEMON:
2428 natural_leader = true;
2429 band = BAND_CACODEMON; // BROWN gr demon
2430 band_size = 1 + random2(3);
2431 break;
2433 case MONS_EXECUTIONER:
2434 if (coinflip())
2436 natural_leader = true;
2437 band = BAND_EXECUTIONER; // DARKGREY gr demon
2438 band_size = 1 + random2(3);
2440 break;
2442 case MONS_PANDEMONIUM_DEMON:
2443 natural_leader = true;
2444 band = BAND_PANDEMONIUM_DEMON;
2445 band_size = random_range(1, 3);
2446 break;
2448 case MONS_HELLWING:
2449 if (coinflip())
2451 band = BAND_HELLWING; // LIGHTGREY gr demon
2452 band_size = 1 + random2(4);
2454 break;
2456 case MONS_DEEP_ELF_FIGHTER:
2457 if (coinflip())
2459 band = BAND_DEEP_ELF_FIGHTER;
2460 band_size = 3 + random2(4);
2462 break;
2464 case MONS_DEEP_ELF_KNIGHT:
2465 if (coinflip())
2467 band = BAND_DEEP_ELF_KNIGHT;
2468 band_size = 3 + random2(4);
2470 break;
2472 case MONS_DEEP_ELF_HIGH_PRIEST:
2473 if (coinflip())
2475 natural_leader = true;
2476 band = BAND_DEEP_ELF_HIGH_PRIEST;
2477 band_size = 3 + random2(4);
2479 break;
2481 case MONS_KOBOLD_DEMONOLOGIST:
2482 if (coinflip())
2484 band = BAND_KOBOLD_DEMONOLOGIST;
2485 band_size = 3 + random2(6);
2487 break;
2489 case MONS_NAGA_MAGE:
2490 case MONS_NAGA_WARRIOR:
2491 band = BAND_NAGAS;
2492 band_size = 3 + random2(4);
2493 break;
2495 case MONS_WAR_DOG:
2496 band = BAND_WAR_DOGS;
2497 band_size = 2 + random2(4);
2498 break;
2500 case MONS_GREEN_RAT:
2501 band = BAND_GREEN_RATS;
2502 band_size = 4 + random2(6);
2503 break;
2505 case MONS_ORANGE_RAT:
2506 band = BAND_ORANGE_RATS;
2507 band_size = 3 + random2(4);
2508 break;
2510 case MONS_SHEEP:
2511 band = BAND_SHEEP;
2512 band_size = 3 + random2(5);
2513 break;
2515 case MONS_GHOUL:
2516 band = BAND_GHOULS;
2517 band_size = 2 + random2(3);
2518 break;
2520 case MONS_KIRKE:
2521 band_size = 2 + random2(3);
2522 natural_leader = true;
2523 case MONS_HOG:
2524 band = BAND_HOGS;
2525 band_size += 1 + random2(3);
2526 break;
2528 case MONS_VAMPIRE_MOSQUITO:
2529 band = BAND_VAMPIRE_MOSQUITOES;
2530 band_size = 1 + random2(3);
2531 break;
2533 case MONS_DEEP_TROLL:
2534 band = BAND_DEEP_TROLLS;
2535 band_size = 3 + random2(3);
2536 break;
2538 case MONS_HELL_HOG:
2539 band = BAND_HELL_HOGS;
2540 band_size = 1 + random2(3);
2541 break;
2543 case MONS_BOGGART:
2544 band = BAND_BOGGARTS;
2545 band_size = 2 + random2(3);
2546 break;
2548 case MONS_BLINK_FROG:
2549 band = BAND_BLINK_FROGS;
2550 band_size = 2 + random2(3);
2551 break;
2553 case MONS_WIGHT:
2554 band = BAND_WIGHTS;
2555 band_size = 2 + random2(3);
2556 break;
2558 case MONS_SKELETAL_WARRIOR:
2559 band = BAND_SKELETAL_WARRIORS;
2560 band_size = 2 + random2(3);
2561 break;
2563 case MONS_CYCLOPS:
2564 if (one_chance_in(5) || player_in_branch(BRANCH_SHOALS))
2566 natural_leader = true;
2567 band = BAND_SHEEP; // Odyssey reference
2568 band_size = 2 + random2(3);
2570 break;
2572 case MONS_ALLIGATOR:
2573 // Alligators with kids!
2574 if (one_chance_in(5))
2576 natural_leader = true;
2577 band = BAND_ALLIGATOR;
2578 band_size = 2 + random2(3);
2580 break;
2582 case MONS_POLYPHEMUS:
2583 natural_leader = true;
2584 band = BAND_DEATH_YAKS;
2585 band_size = 3 + random2(3);
2586 break;
2588 case MONS_HARPY:
2589 band = BAND_HARPIES;
2590 band_size = 2 + random2(3);
2591 break;
2593 // Journey -- Added Draconian Packs
2594 case MONS_WHITE_DRACONIAN:
2595 case MONS_RED_DRACONIAN:
2596 case MONS_PURPLE_DRACONIAN:
2597 case MONS_MOTTLED_DRACONIAN:
2598 case MONS_YELLOW_DRACONIAN:
2599 case MONS_BLACK_DRACONIAN:
2600 case MONS_GREEN_DRACONIAN:
2601 case MONS_GREY_DRACONIAN:
2602 case MONS_PALE_DRACONIAN:
2603 if (power > 18 && one_chance_in(3) && you.level_type == LEVEL_DUNGEON)
2605 band = BAND_DRACONIAN;
2606 band_size = random_range(2, 4);
2608 break;
2610 case MONS_DRACONIAN_CALLER:
2611 case MONS_DRACONIAN_MONK:
2612 case MONS_DRACONIAN_SCORCHER:
2613 case MONS_DRACONIAN_KNIGHT:
2614 case MONS_DRACONIAN_ANNIHILATOR:
2615 case MONS_DRACONIAN_ZEALOT:
2616 case MONS_DRACONIAN_SHIFTER:
2617 if (power > 20 && you.level_type == LEVEL_DUNGEON)
2619 band = BAND_DRACONIAN;
2620 band_size = random_range(3, 6);
2622 break;
2624 case MONS_TIAMAT:
2625 natural_leader = true;
2626 band = BAND_DRACONIAN;
2627 // yup, scary
2628 band_size = random_range(3,6) + random_range(3,6) + 2;
2629 break;
2631 case MONS_ILSUIW:
2632 band = BAND_ILSUIW;
2633 band_size = 3 + random2(3);
2634 break;
2636 case MONS_AZRAEL:
2637 natural_leader = true;
2638 band = BAND_AZRAEL;
2639 band_size = 4 + random2(5);
2640 break;
2642 case MONS_DUVESSA:
2643 // no natural_leader since this band is supposed to be symmetric
2644 band = BAND_DUVESSA;
2645 band_size = 1;
2646 break;
2648 case MONS_KHUFU:
2649 natural_leader = true;
2650 band = BAND_KHUFU;
2651 band_size = 3;
2652 break;
2654 case MONS_TERPSICHORE:
2655 natural_leader = true;
2656 band = BAND_TERPSICHORE;
2657 band_size = 1 + random_range(1, 3);
2658 break;
2660 case MONS_GOLDEN_EYE:
2661 band = BAND_GOLDEN_EYE;
2662 band_size = 1 + random2(5);
2663 break;
2665 case MONS_PIKEL:
2666 natural_leader = true;
2667 band = BAND_PIKEL;
2668 band_size = 4;
2669 break;
2671 case MONS_MERFOLK_AQUAMANCER:
2672 band = BAND_MERFOLK_AQUAMANCER;
2673 band_size = random_range(3, 6);
2674 break;
2676 case MONS_MERFOLK_JAVELINEER:
2677 band = BAND_MERFOLK_JAVELINEER;
2678 band_size = random_range(3, 5);
2679 break;
2681 case MONS_MERFOLK_IMPALER:
2682 band = BAND_MERFOLK_IMPALER;
2683 band_size = random_range(3, 5);
2684 break;
2686 case MONS_ELEPHANT:
2687 band = BAND_ELEPHANT;
2688 band_size = 2 + random2(4);
2689 break;
2691 case MONS_SHEDU:
2692 band = BAND_SHEDU;
2693 band_size = 1;
2694 break;
2696 } // end switch
2698 if (band != BAND_NO_BAND && band_size == 0)
2699 band = BAND_NO_BAND;
2701 if (band_size >= BIG_BAND)
2702 band_size = BIG_BAND - 1;
2704 return (band);
2707 static monster_type _band_member(band_type band, int power)
2709 monster_type mon_type = MONS_PROGRAM_BUG;
2710 int temp_rand;
2712 if (band == BAND_NO_BAND)
2713 return (MONS_PROGRAM_BUG);
2715 switch (band)
2717 case BAND_KOBOLDS:
2718 mon_type = MONS_KOBOLD;
2719 break;
2721 case BAND_ORCS:
2722 mon_type = MONS_ORC;
2723 if (one_chance_in(6))
2724 mon_type = MONS_ORC_WIZARD;
2725 if (one_chance_in(8))
2726 mon_type = MONS_ORC_PRIEST;
2727 break;
2729 case BAND_ORC_WARRIOR:
2730 mon_type = MONS_ORC;
2731 if (one_chance_in(5))
2732 mon_type = MONS_ORC_WIZARD;
2733 if (one_chance_in(7))
2734 mon_type = MONS_ORC_PRIEST;
2735 break;
2737 case BAND_ORC_KNIGHT:
2738 case BAND_ORC_HIGH_PRIEST:
2739 // XXX: For Beogh punishment, ogres and trolls look out of place...
2740 // (For normal generation, they're okay, of course.)
2741 temp_rand = random2(30);
2742 mon_type = ((temp_rand > 17) ? MONS_ORC : // 12 in 30
2743 (temp_rand > 8) ? MONS_ORC_WARRIOR : // 9 in 30
2744 (temp_rand > 6) ? MONS_WARG : // 2 in 30
2745 (temp_rand > 4) ? MONS_ORC_WIZARD : // 2 in 30
2746 (temp_rand > 2) ? MONS_ORC_PRIEST : // 2 in 30
2747 (temp_rand > 1) ? MONS_OGRE : // 1 in 30
2748 (temp_rand > 0) ? MONS_TROLL // 1 in 30
2749 : MONS_ORC_SORCERER); // 1 in 30
2750 break;
2752 case BAND_KILLER_BEES:
2753 mon_type = MONS_KILLER_BEE;
2754 break;
2756 case BAND_FLYING_SKULLS:
2757 mon_type = MONS_FLYING_SKULL;
2758 break;
2760 case BAND_SLIME_CREATURES:
2761 mon_type = MONS_SLIME_CREATURE;
2762 break;
2764 case BAND_YAKS:
2765 mon_type = MONS_YAK;
2766 break;
2768 case BAND_HARPIES:
2769 mon_type = MONS_HARPY;
2770 break;
2772 case BAND_UGLY_THINGS:
2773 mon_type = ((power > 21 && one_chance_in(4)) ?
2774 MONS_VERY_UGLY_THING : MONS_UGLY_THING);
2775 break;
2777 case BAND_HELL_HOUNDS:
2778 mon_type = MONS_HELL_HOUND;
2779 break;
2781 case BAND_JACKALS:
2782 mon_type = MONS_JACKAL;
2783 break;
2785 case BAND_GNOLLS:
2786 mon_type = MONS_GNOLL;
2787 break;
2789 case BAND_DEEP_DWARF:
2790 mon_type = static_cast<monster_type>(random_choose_weighted(
2791 2, MONS_DEEP_DWARF_BERSERKER,
2792 1, MONS_DEEP_DWARF_DEATH_KNIGHT,
2793 6, MONS_DEEP_DWARF_NECROMANCER,
2794 31, MONS_DEEP_DWARF,
2795 0));
2796 break;
2798 case BAND_BUMBLEBEES:
2799 mon_type = MONS_BUMBLEBEE;
2800 break;
2802 case BAND_CENTAURS:
2803 mon_type = MONS_CENTAUR;
2804 break;
2806 case BAND_YAKTAURS:
2807 mon_type = MONS_YAKTAUR;
2808 break;
2810 case BAND_INSUBSTANTIAL_WISPS:
2811 mon_type = MONS_INSUBSTANTIAL_WISP;
2812 break;
2814 case BAND_DEATH_YAKS:
2815 mon_type = MONS_DEATH_YAK;
2816 break;
2818 case BAND_NECROMANCER: // necromancer
2819 temp_rand = random2(13);
2820 mon_type = ((temp_rand > 9) ? MONS_ZOMBIE_SMALL : // 3 in 13
2821 (temp_rand > 6) ? MONS_ZOMBIE_LARGE : // 3 in 13
2822 (temp_rand > 3) ? MONS_SKELETON_SMALL : // 3 in 13
2823 (temp_rand > 0) ? MONS_SKELETON_LARGE // 3 in 13
2824 : MONS_NECROPHAGE); // 1 in 13
2825 break;
2827 case BAND_BALRUG:
2828 mon_type = (coinflip() ? MONS_NEQOXEC : MONS_ORANGE_DEMON);
2829 break;
2831 case BAND_CACODEMON:
2832 mon_type = MONS_LEMURE;
2833 break;
2835 case BAND_EXECUTIONER:
2836 mon_type = (coinflip() ? MONS_ABOMINATION_SMALL
2837 : MONS_ABOMINATION_LARGE);
2838 break;
2840 case BAND_PANDEMONIUM_DEMON:
2841 if (one_chance_in(7))
2843 mon_type = static_cast<monster_type>(
2844 random_choose_weighted(50, MONS_LICH,
2845 10, MONS_ANCIENT_LICH,
2846 0));
2848 else if (one_chance_in(6))
2850 mon_type = static_cast<monster_type>(
2851 random_choose_weighted(50, MONS_ABOMINATION_SMALL,
2852 40, MONS_ABOMINATION_LARGE,
2853 10, MONS_TENTACLED_MONSTROSITY,
2854 0));
2856 else
2858 mon_type =
2859 summon_any_demon(
2860 static_cast<demon_class_type>(
2861 random_choose_weighted(50, DEMON_COMMON,
2862 20, DEMON_GREATER,
2863 10, DEMON_RANDOM,
2864 0)));
2866 break;
2868 case BAND_HELLWING:
2869 mon_type = (coinflip() ? MONS_HELLWING : MONS_SMOKE_DEMON);
2870 break;
2872 case BAND_DEEP_ELF_FIGHTER: // deep elf fighter
2873 temp_rand = random2(11);
2874 mon_type = ((temp_rand > 4) ? MONS_DEEP_ELF_SOLDIER : // 6 in 11
2875 (temp_rand == 4) ? MONS_DEEP_ELF_FIGHTER : // 1 in 11
2876 (temp_rand == 3) ? MONS_DEEP_ELF_KNIGHT : // 1 in 11
2877 (temp_rand == 2) ? MONS_DEEP_ELF_CONJURER :// 1 in 11
2878 (temp_rand == 1) ? MONS_DEEP_ELF_MAGE // 1 in 11
2879 : MONS_DEEP_ELF_PRIEST); // 1 in 11
2880 break;
2882 case BAND_DEEP_ELF_KNIGHT: // deep elf knight
2883 temp_rand = random2(208);
2884 mon_type =
2885 ((temp_rand > 159) ? MONS_DEEP_ELF_SOLDIER : // 23.08%
2886 (temp_rand > 111) ? MONS_DEEP_ELF_FIGHTER : // 23.08%
2887 (temp_rand > 79) ? MONS_DEEP_ELF_KNIGHT : // 15.38%
2888 (temp_rand > 51) ? MONS_DEEP_ELF_MAGE : // 13.46%
2889 (temp_rand > 35) ? MONS_DEEP_ELF_PRIEST : // 7.69%
2890 (temp_rand > 19) ? MONS_DEEP_ELF_CONJURER : // 7.69%
2891 (temp_rand > 3) ? MONS_DEEP_ELF_SUMMONER : // 7.69%
2892 (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 0.48%
2893 (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 0.48%
2894 (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 0.48%
2895 : MONS_DEEP_ELF_DEATH_MAGE); // 0.48%
2896 break;
2898 case BAND_DEEP_ELF_HIGH_PRIEST: // deep elf high priest
2899 temp_rand = random2(16);
2900 mon_type =
2901 ((temp_rand > 12) ? MONS_DEEP_ELF_SOLDIER : // 3 in 16
2902 (temp_rand > 9) ? MONS_DEEP_ELF_FIGHTER : // 3 in 16
2903 (temp_rand > 6) ? MONS_DEEP_ELF_PRIEST : // 3 in 16
2904 (temp_rand == 6) ? MONS_DEEP_ELF_MAGE : // 1 in 16
2905 (temp_rand == 5) ? MONS_DEEP_ELF_SUMMONER : // 1 in 16
2906 (temp_rand == 4) ? MONS_DEEP_ELF_CONJURER : // 1 in 16
2907 (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 1 in 16
2908 (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 1 in 16
2909 (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 1 in 16
2910 : MONS_DEEP_ELF_DEATH_MAGE); // 1 in 16
2911 break;
2912 case BAND_TERPSICHORE:
2913 mon_type = MONS_DANCING_WEAPON;
2914 if (one_chance_in(4))
2915 mon_type = MONS_PHANTOM;
2916 break;
2917 case BAND_HELL_KNIGHTS:
2918 mon_type = MONS_HELL_KNIGHT;
2919 if (one_chance_in(4))
2920 mon_type = MONS_NECROMANCER;
2921 break;
2923 case BAND_OGRE_MAGE:
2924 mon_type = MONS_OGRE;
2925 if (one_chance_in(3))
2926 mon_type = MONS_TWO_HEADED_OGRE;
2927 break; // ogre mage
2929 case BAND_KOBOLD_DEMONOLOGIST:
2930 temp_rand = random2(13);
2931 mon_type = ((temp_rand > 4) ? MONS_KOBOLD : // 8 in 13
2932 (temp_rand > 0) ? MONS_BIG_KOBOLD // 4 in 13
2933 : MONS_KOBOLD_DEMONOLOGIST);// 1 in 13
2934 break;
2936 case BAND_NAGAS:
2937 mon_type = MONS_NAGA;
2938 break;
2939 case BAND_WAR_DOGS:
2940 mon_type = MONS_WAR_DOG;
2941 break;
2942 case BAND_GREEN_RATS:
2943 mon_type = MONS_GREEN_RAT;
2944 break;
2945 case BAND_ORANGE_RATS:
2946 mon_type = MONS_ORANGE_RAT;
2947 break;
2948 case BAND_SHEEP:
2949 mon_type = MONS_SHEEP;
2950 break;
2951 case BAND_GHOULS:
2952 mon_type = (coinflip() ? MONS_GHOUL : MONS_NECROPHAGE);
2953 break;
2954 case BAND_DEEP_TROLLS:
2955 mon_type = MONS_DEEP_TROLL;
2956 break;
2957 case BAND_HOGS:
2958 mon_type = MONS_HOG;
2959 break;
2960 case BAND_HELL_HOGS:
2961 mon_type = MONS_HELL_HOG;
2962 break;
2963 case BAND_VAMPIRE_MOSQUITOES:
2964 mon_type = MONS_VAMPIRE_MOSQUITO;
2965 break;
2966 case BAND_BOGGARTS:
2967 mon_type = MONS_BOGGART;
2968 break;
2969 case BAND_BLINK_FROGS:
2970 mon_type = MONS_BLINK_FROG;
2971 break;
2972 case BAND_WIGHTS:
2973 mon_type = MONS_WIGHT;
2974 break;
2975 case BAND_SKELETAL_WARRIORS:
2976 mon_type = MONS_SKELETAL_WARRIOR;
2977 break;
2978 case BAND_DRACONIAN:
2980 temp_rand = random2((power < 24) ? 27 : 40);
2981 mon_type =
2982 ((temp_rand > 38) ? MONS_DRACONIAN_CALLER : // 1
2983 (temp_rand > 36) ? MONS_DRACONIAN_KNIGHT : // 2
2984 (temp_rand > 34) ? MONS_DRACONIAN_MONK : // 2
2985 (temp_rand > 32) ? MONS_DRACONIAN_SHIFTER : // 2
2986 (temp_rand > 30) ? MONS_DRACONIAN_ANNIHILATOR :// 2
2987 (temp_rand > 28) ? MONS_DRACONIAN_SCORCHER : // 2
2988 (temp_rand > 26) ? MONS_DRACONIAN_ZEALOT : // 2
2989 (temp_rand > 23) ? MONS_GREY_DRACONIAN : // 3
2990 (temp_rand > 20) ? MONS_YELLOW_DRACONIAN : // 3
2991 (temp_rand > 17) ? MONS_GREEN_DRACONIAN : // 3
2992 (temp_rand > 14) ? MONS_BLACK_DRACONIAN : // 3
2993 (temp_rand > 11) ? MONS_WHITE_DRACONIAN : // 3
2994 (temp_rand > 8) ? MONS_PALE_DRACONIAN : // 3
2995 (temp_rand > 5) ? MONS_PURPLE_DRACONIAN : // 3
2996 (temp_rand > 2) ? MONS_MOTTLED_DRACONIAN : // 3
2997 MONS_RED_DRACONIAN); // 3
2998 break;
3000 case BAND_ILSUIW:
3001 mon_type = static_cast<monster_type>(
3002 random_choose_weighted(30, MONS_MERMAID,
3003 15, MONS_MERFOLK,
3004 10, MONS_MERFOLK_JAVELINEER,
3005 10, MONS_MERFOLK_IMPALER,
3006 0));
3007 break;
3009 case BAND_AZRAEL:
3010 mon_type = coinflip()? MONS_FIRE_ELEMENTAL : MONS_HELL_HOUND;
3011 break;
3013 case BAND_DUVESSA:
3014 mon_type = MONS_DOWAN;
3015 break;
3017 case BAND_ALLIGATOR:
3018 mon_type = MONS_BABY_ALLIGATOR;
3019 break;
3021 case BAND_KHUFU:
3022 mon_type = coinflip()? MONS_GREATER_MUMMY : MONS_MUMMY;
3023 break;
3025 case BAND_GOLDEN_EYE:
3026 mon_type = MONS_GOLDEN_EYE;
3027 break;
3029 case BAND_PIKEL:
3030 mon_type = MONS_SLAVE;
3031 break;
3033 case BAND_MERFOLK_AQUAMANCER:
3034 mon_type = static_cast<monster_type>(
3035 random_choose_weighted(8, MONS_MERFOLK,
3036 10, MONS_ICE_BEAST,
3037 0));
3038 break;
3040 case BAND_MERFOLK_IMPALER:
3041 case BAND_MERFOLK_JAVELINEER:
3042 mon_type = MONS_MERFOLK;
3043 break;
3045 case BAND_ELEPHANT:
3046 mon_type = MONS_ELEPHANT;
3047 break;
3049 case BAND_SHEDU:
3050 mon_type = MONS_SHEDU;
3051 break;
3053 default:
3054 break;
3057 return (mon_type);
3060 static int _ood_limit()
3062 return Options.ood_interesting;
3065 void mark_interesting_monst(monster* mons, beh_type behaviour)
3067 if (crawl_state.game_is_arena())
3068 return;
3070 bool interesting = false;
3072 // Unique monsters are always interesting
3073 if (mons_is_unique(mons->type))
3074 interesting = true;
3075 // If it's never going to attack us, then not interesting
3076 else if (behaviour == BEH_FRIENDLY)
3077 interesting = false;
3078 // Jellies are never interesting to Jiyva.
3079 else if (mons->type == MONS_JELLY && you.religion == GOD_JIYVA)
3080 interesting = false;
3081 else if (you.where_are_you == BRANCH_MAIN_DUNGEON
3082 && you.level_type == LEVEL_DUNGEON
3083 && mons_level(mons->type) >= you.absdepth0 + _ood_limit()
3084 && mons_level(mons->type) < 99
3085 && !(mons->type >= MONS_EARTH_ELEMENTAL
3086 && mons->type <= MONS_AIR_ELEMENTAL)
3087 && !mons_class_flag(mons->type, M_NO_EXP_GAIN))
3089 interesting = true;
3091 else if ((you.level_type == LEVEL_DUNGEON
3092 || you.level_type == LEVEL_ABYSS)
3093 && mons_rarity(mons->type) <= Options.rare_interesting
3094 && mons->hit_dice > 2 // Don't note the really low-hd monsters.
3095 && !mons_class_flag(mons->type, M_NO_EXP_GAIN)
3096 && mons_rarity(mons->type) > 0)
3098 interesting = true;
3100 // Don't waste time on moname() if user isn't using this option
3101 else if (Options.note_monsters.size() > 0)
3103 const std::string iname = mons_type_name(mons->type, DESC_NOCAP_A);
3104 for (unsigned i = 0; i < Options.note_monsters.size(); ++i)
3106 if (Options.note_monsters[i].matches(iname))
3108 interesting = true;
3109 break;
3114 if (interesting)
3115 mons->flags |= MF_INTERESTING;
3118 // PUBLIC FUNCTION -- mons_place().
3120 static monster_type _pick_zot_exit_defender()
3122 if (one_chance_in(11))
3124 #ifdef DEBUG_MON_CREATION
3125 mpr("Create a pandemonium demon!", MSGCH_DIAGNOSTICS);
3126 #endif
3127 return (MONS_PANDEMONIUM_DEMON);
3130 const int temp_rand = random2(276);
3131 const int mon_type =
3132 ((temp_rand > 184) ? MONS_WHITE_IMP + random2(15) : // 33.33%
3133 (temp_rand > 104) ? MONS_HELLION + random2(10) : // 28.99%
3134 (temp_rand > 78) ? MONS_HELL_HOUND : // 9.06%
3135 (temp_rand > 54) ? MONS_ABOMINATION_LARGE : // 8.70%
3136 (temp_rand > 33) ? MONS_ABOMINATION_SMALL : // 7.61%
3137 (temp_rand > 13) ? MONS_RED_DEVIL // 7.25%
3138 : MONS_PIT_FIEND); // 5.07%
3140 return static_cast<monster_type>(mon_type);
3143 int mons_place(mgen_data mg)
3145 #ifdef DEBUG_MON_CREATION
3146 mpr("in mons_place()", MSGCH_DIAGNOSTICS);
3147 #endif
3148 int mon_count = 0;
3149 for (int il = 0; il < MAX_MONSTERS; il++)
3150 if (menv[il].type != MONS_NO_MONSTER)
3151 mon_count++;
3153 if (mg.cls == WANDERING_MONSTER)
3155 if (mon_count > MAX_MONSTERS - 50)
3156 return (-1);
3158 #ifdef DEBUG_MON_CREATION
3159 mpr("Set class RANDOM_MONSTER", MSGCH_DIAGNOSTICS);
3160 #endif
3161 mg.cls = RANDOM_MONSTER;
3164 // All monsters have been assigned? {dlb}
3165 if (mon_count >= MAX_MONSTERS - 1)
3166 return (-1);
3168 // This gives a slight challenge to the player as they ascend the
3169 // dungeon with the Orb.
3170 if (you.char_direction == GDT_ASCENDING && _is_random_monster(mg.cls)
3171 && you.level_type == LEVEL_DUNGEON && !mg.summoned())
3173 #ifdef DEBUG_MON_CREATION
3174 mpr("Call _pick_zot_exit_defender()", MSGCH_DIAGNOSTICS);
3175 #endif
3176 mg.cls = _pick_zot_exit_defender();
3177 mg.flags |= MG_PERMIT_BANDS;
3179 else if (_is_random_monster(mg.cls))
3180 mg.flags |= MG_PERMIT_BANDS;
3182 // Translate level_type.
3183 switch (mg.level_type)
3185 case LEVEL_PANDEMONIUM:
3186 case LEVEL_ABYSS:
3187 mg.power = level_id(mg.level_type).absdepth();
3188 break;
3189 case LEVEL_DUNGEON:
3190 default:
3191 mg.power = you.absdepth0;
3192 if (crawl_state.game_is_zotdef())
3193 mg.power = you.num_turns / (CYCLE_LENGTH * 3);
3194 break;
3197 if (mg.behaviour == BEH_COPY)
3199 mg.behaviour = (mg.summoner == &you) ? BEH_FRIENDLY
3200 : SAME_ATTITUDE((&menv[mg.summoner->mindex()]));
3203 int mid = place_monster(mg);
3204 if (mid == -1)
3205 return (-1);
3207 dprf("Created a %s.", menv[mid].base_name(DESC_PLAIN, true).c_str());
3209 monster* creation = &menv[mid];
3211 // Look at special cases: CHARMED, FRIENDLY, NEUTRAL, GOOD_NEUTRAL,
3212 // HOSTILE.
3213 if (mg.behaviour > NUM_BEHAVIOURS)
3215 if (mg.behaviour == BEH_FRIENDLY)
3216 creation->flags |= MF_NO_REWARD;
3218 if (mg.behaviour == BEH_NEUTRAL || mg.behaviour == BEH_GOOD_NEUTRAL
3219 || mg.behaviour == BEH_STRICT_NEUTRAL)
3221 creation->flags |= MF_WAS_NEUTRAL;
3224 if (mg.behaviour == BEH_CHARMED)
3226 creation->attitude = ATT_HOSTILE;
3227 creation->add_ench(ENCH_CHARM);
3230 if (creation->type == MONS_RAKSHASA_FAKE && !one_chance_in(3))
3231 creation->add_ench(ENCH_INVIS);
3233 if (!(mg.flags & MG_FORCE_BEH) && !crawl_state.game_is_arena())
3234 player_angers_monster(creation);
3236 behaviour_event(creation, ME_EVAL);
3239 return (mid);
3242 static dungeon_feature_type _monster_primary_habitat_feature(int mc)
3244 if (_is_random_monster(mc))
3245 return (DNGN_FLOOR);
3246 return (habitat2grid(mons_class_primary_habitat(mc)));
3249 static dungeon_feature_type _monster_secondary_habitat_feature(int mc)
3251 if (_is_random_monster(mc))
3252 return (DNGN_FLOOR);
3253 return (habitat2grid(mons_class_secondary_habitat(mc)));
3256 class newmons_square_find : public travel_pathfind
3258 private:
3259 dungeon_feature_type feat_wanted;
3260 coord_def start;
3261 int maxdistance;
3263 int best_distance;
3264 int nfound;
3265 public:
3266 // Terrain that we can't spawn on, but that we can skip through.
3267 std::set<dungeon_feature_type> passable;
3268 public:
3269 newmons_square_find(dungeon_feature_type grdw,
3270 const coord_def &pos,
3271 int maxdist = 0)
3272 : feat_wanted(grdw), start(pos), maxdistance(maxdist),
3273 best_distance(0), nfound(0)
3277 coord_def pathfind()
3279 set_floodseed(start);
3280 return travel_pathfind::pathfind(RMODE_EXPLORE);
3283 bool path_flood(const coord_def &c, const coord_def &dc)
3285 if (best_distance && traveled_distance > best_distance)
3286 return (true);
3288 if (!in_bounds(dc)
3289 || (maxdistance > 0 && traveled_distance > maxdistance))
3291 return (false);
3293 if (!feat_compatible(feat_wanted, grd(dc)))
3295 if (passable.find(grd(dc)) != passable.end())
3296 good_square(dc);
3297 return (false);
3299 if (actor_at(dc) == NULL && one_chance_in(++nfound))
3301 greedy_dist = traveled_distance;
3302 greedy_place = dc;
3303 best_distance = traveled_distance;
3305 else
3307 good_square(dc);
3309 return (false);
3313 // Finds a square for a monster of the given class, pathfinding
3314 // through only contiguous squares of habitable terrain.
3315 coord_def find_newmons_square_contiguous(monster_type mons_class,
3316 const coord_def &start,
3317 int distance)
3319 coord_def p;
3321 const dungeon_feature_type feat_preferred =
3322 _monster_primary_habitat_feature(mons_class);
3323 const dungeon_feature_type feat_nonpreferred =
3324 _monster_secondary_habitat_feature(mons_class);
3326 newmons_square_find nmpfind(feat_preferred, start, distance);
3327 const coord_def pp = nmpfind.pathfind();
3328 p = pp;
3330 if (feat_nonpreferred != feat_preferred && !in_bounds(pp))
3332 newmons_square_find nmsfind(feat_nonpreferred, start, distance);
3333 const coord_def ps = nmsfind.pathfind();
3334 p = ps;
3337 return (in_bounds(p) ? p : coord_def(-1, -1));
3340 coord_def find_newmons_square(int mons_class, const coord_def &p)
3342 coord_def empty;
3343 coord_def pos(-1, -1);
3345 if (mons_class == WANDERING_MONSTER)
3346 mons_class = RANDOM_MONSTER;
3348 const dungeon_feature_type feat_preferred =
3349 _monster_primary_habitat_feature(mons_class);
3350 const dungeon_feature_type feat_nonpreferred =
3351 _monster_secondary_habitat_feature(mons_class);
3353 // Might be better if we chose a space and tried to match the monster
3354 // to it in the case of RANDOM_MONSTER, that way if the target square
3355 // is surrounded by water or lava this function would work. -- bwr
3356 if (empty_surrounds(p, feat_preferred, 2, true, empty))
3357 pos = empty;
3359 if (feat_nonpreferred != feat_preferred && !in_bounds(pos)
3360 && empty_surrounds(p, feat_nonpreferred, 2, true, empty))
3362 pos = empty;
3365 return (pos);
3368 bool player_will_anger_monster(monster_type type, bool *holy,
3369 bool *unholy, bool *lawful,
3370 bool *antimagical)
3372 monster dummy;
3373 dummy.type = type;
3375 return (player_will_anger_monster(&dummy, holy, unholy, lawful,
3376 antimagical));
3379 bool player_will_anger_monster(monster* mon, bool *holy,
3380 bool *unholy, bool *lawful,
3381 bool *antimagical)
3383 const bool isHoly =
3384 (is_good_god(you.religion) && (mon->is_unholy() || mon->is_evil()));
3385 const bool isUnholy =
3386 (is_evil_god(you.religion) && mon->is_holy());
3387 const bool isLawful =
3388 (you.religion == GOD_ZIN && (mon->is_unclean() || mon->is_chaotic()));
3389 const bool isAntimagical =
3390 (you.religion == GOD_TROG && mon->is_actual_spellcaster());
3392 if (holy)
3393 *holy = isHoly;
3394 if (unholy)
3395 *unholy = isUnholy;
3396 if (lawful)
3397 *lawful = isLawful;
3398 if (antimagical)
3399 *antimagical = isAntimagical;
3401 return (isHoly || isUnholy || isLawful || isAntimagical);
3404 bool player_angers_monster(monster* mon)
3406 bool holy;
3407 bool unholy;
3408 bool lawful;
3409 bool antimagical;
3411 // Get the drawbacks, not the benefits... (to prevent e.g. demon-scumming).
3412 if (player_will_anger_monster(mon, &holy, &unholy, &lawful, &antimagical)
3413 && mon->wont_attack())
3415 mon->attitude = ATT_HOSTILE;
3416 mon->del_ench(ENCH_CHARM);
3417 behaviour_event(mon, ME_ALERT, MHITYOU);
3419 if (you.can_see(mon))
3421 std::string aura;
3423 if (holy)
3424 aura = "holy";
3425 else if (unholy)
3426 aura = "unholy";
3427 else if (lawful)
3428 aura = "lawful";
3429 else if (antimagical)
3430 aura = "anti-magical";
3432 mprf("%s is enraged by your %s aura!",
3433 mon->name(DESC_CAP_THE).c_str(), aura.c_str());
3436 return (true);
3439 return (false);
3442 int create_monster(mgen_data mg, bool fail_msg)
3444 const int montype = (mons_class_is_zombified(mg.cls) ? mg.base_type
3445 : mg.cls);
3447 int summd = -1;
3449 if (!mg.force_place()
3450 || !in_bounds(mg.pos)
3451 || monster_at(mg.pos)
3452 || you.pos() == mg.pos && !fedhas_passthrough_class(mg.cls)
3453 || !mons_class_can_pass(montype, grd(mg.pos)))
3455 mg.pos = find_newmons_square(montype, mg.pos);
3457 // Gods other than Xom will try to avoid placing their monsters
3458 // directly in harm's way.
3459 if (mg.god != GOD_NO_GOD && mg.god != GOD_XOM)
3461 monster dummy;
3462 const monster_type resistless_mon = MONS_HUMAN;
3463 // If the type isn't known yet assume no resists or anything.
3464 dummy.type = _is_random_monster(mg.cls) ? resistless_mon
3465 : mg.cls;
3466 dummy.base_monster = mg.base_type;
3467 dummy.god = mg.god;
3469 // Monsters that have resistance info in the ghost
3470 // structure cannot be handled as dummies, so treat them
3471 // as a known no-resist monster. mons_avoids_cloud() will
3472 // crash for dummy monsters which should have a
3473 // ghost_demon setup.
3474 if (mons_is_ghost_demon(dummy.type))
3475 dummy.type = resistless_mon;
3477 int tries = 0;
3478 while (tries++ < 50
3479 && (!in_bounds(mg.pos)
3480 || mons_avoids_cloud(&dummy, env.cgrid(mg.pos), true)))
3482 mg.pos = find_newmons_square(montype, mg.pos);
3484 if (!in_bounds(mg.pos))
3485 return (-1);
3487 const int cloud_num = env.cgrid(mg.pos);
3488 // Don't place friendly god gift in a damaging cloud created by
3489 // you if that would anger the god.
3490 if (mons_avoids_cloud(&dummy, cloud_num, true)
3491 && mg.behaviour == BEH_FRIENDLY
3492 && god_hates_attacking_friend(you.religion, &dummy)
3493 && YOU_KILL(env.cloud[cloud_num].killer))
3495 return (-1);
3500 if (in_bounds(mg.pos))
3502 summd = mons_place(mg);
3503 // If the arena vetoed the placement then give no fail message.
3504 if (crawl_state.game_is_arena())
3505 fail_msg = false;
3508 // Determine whether creating a monster is successful (summd != -1) {dlb}:
3509 // then handle the outcome. {dlb}:
3510 if (fail_msg && summd == -1 && you.see_cell(mg.pos))
3511 mpr("You see a puff of smoke.");
3513 // The return value is either -1 (failure of some sort)
3514 // or the index of the monster placed (if I read things right). {dlb}
3515 return (summd);
3518 bool empty_surrounds(const coord_def& where, dungeon_feature_type spc_wanted,
3519 int radius, bool allow_centre, coord_def& empty)
3521 // XXX: A lot of hacks that could be avoided by passing the
3522 // monster generation data through.
3524 // Assume all player summoning originates from player x,y.
3525 // XXX: no longer true with Haunt.
3526 bool playerSummon = (where == you.pos());
3527 bool monsterSummon = !playerSummon && actor_at(where);
3529 // Require LOS and no transparent walls, except for
3530 // summoning monsters.
3531 los_type los = monsterSummon ? LOS_DEFAULT : LOS_NO_TRANS;
3533 int good_count = 0;
3535 for (radius_iterator ri(where, radius, C_ROUND, NULL, !allow_centre);
3536 ri; ++ri)
3538 bool success = false;
3540 if (actor_at(*ri))
3541 continue;
3543 if (!cell_see_cell(where, *ri, los))
3544 continue;
3546 success =
3547 (grd(*ri) == spc_wanted) || feat_compatible(spc_wanted, grd(*ri));
3549 if (success && one_chance_in(++good_count))
3550 empty = *ri;
3553 return (good_count > 0);
3556 monster_type summon_any_demon(demon_class_type dct)
3558 monster_type mon = MONS_PROGRAM_BUG;
3560 if (dct == DEMON_RANDOM)
3561 dct = static_cast<demon_class_type>(random2(DEMON_RANDOM));
3563 int temp_rand; // probability determination {dlb}
3565 switch (dct)
3567 case DEMON_LESSER:
3568 temp_rand = random2(64);
3569 mon = ((temp_rand > 54) ? MONS_IMP : // 15.63%
3570 (temp_rand > 45) ? MONS_WHITE_IMP : // 14.06%
3571 (temp_rand > 36) ? MONS_LEMURE : // 14.06%
3572 (temp_rand > 27) ? MONS_UFETUBUS : // 14.06%
3573 (temp_rand > 18) ? MONS_IRON_IMP : // 14.06%
3574 (temp_rand > 9) ? MONS_MIDGE // 14.06%
3575 : MONS_SHADOW_IMP); // 14.06%
3576 break;
3578 case DEMON_COMMON:
3579 temp_rand = random2(4016);
3580 mon = ((temp_rand > 3897) ? MONS_SIXFIRHY : // 2.94%
3581 (temp_rand > 3317) ? MONS_NEQOXEC : // 14.44%
3582 (temp_rand > 2737) ? MONS_ORANGE_DEMON : // 14.44%
3583 (temp_rand > 2157) ? MONS_HELLWING : // 14.44%
3584 (temp_rand > 1577) ? MONS_SMOKE_DEMON : // 14.44%
3585 (temp_rand > 997) ? MONS_YNOXINUL : // 14.44%
3586 (temp_rand > 839) ? MONS_RED_DEVIL : // 3.93%
3587 (temp_rand > 760) ? MONS_HELLION : // 1.97%
3588 (temp_rand > 681) ? MONS_ROTTING_DEVIL : // 1.97%
3589 (temp_rand > 602) ? MONS_TORMENTOR : // 1.97%
3590 (temp_rand > 523) ? MONS_REAPER : // 1.97%
3591 (temp_rand > 444) ? MONS_SOUL_EATER : // 1.97%
3592 (temp_rand > 365) ? MONS_HAIRY_DEVIL : // 1.97%
3593 (temp_rand > 286) ? MONS_ICE_DEVIL : // 1.97%
3594 (temp_rand > 207) ? MONS_BLUE_DEVIL : // 1.97%
3595 (temp_rand > 128) ? MONS_BEAST : // 1.97%
3596 (temp_rand > 49) ? MONS_IRON_DEVIL // 1.97%
3597 : MONS_SUN_DEMON); // 1.22%
3598 break;
3600 case DEMON_GREATER:
3601 temp_rand = random2(1000);
3602 mon = ((temp_rand > 868) ? MONS_CACODEMON : // 13.10%
3603 (temp_rand > 737) ? MONS_BALRUG : // 13.10%
3604 (temp_rand > 606) ? MONS_BLUE_DEATH : // 13.10%
3605 (temp_rand > 475) ? MONS_GREEN_DEATH : // 13.10%
3606 (temp_rand > 344) ? MONS_EXECUTIONER : // 13.10%
3607 (temp_rand > 244) ? MONS_FIEND : // 10.00%
3608 (temp_rand > 154) ? MONS_ICE_FIEND : // 9.00%
3609 (temp_rand > 73) ? MONS_SHADOW_FIEND // 8.10%
3610 : MONS_PIT_FIEND); // 7.30%
3611 break;
3613 default:
3614 break;
3617 return (mon);
3620 monster_type summon_any_holy_being(holy_being_class_type hbct)
3622 monster_type mon = MONS_PROGRAM_BUG;
3624 switch (hbct)
3626 case HOLY_BEING_WARRIOR:
3627 mon = coinflip() ? MONS_DAEVA : MONS_ANGEL;
3628 break;
3630 default:
3631 break;
3634 return (mon);
3637 monster_type summon_any_dragon(dragon_class_type dct)
3639 monster_type mon = MONS_PROGRAM_BUG;
3641 int temp_rand;
3643 switch (dct)
3645 case DRAGON_LIZARD:
3646 temp_rand = random2(100);
3647 mon = ((temp_rand > 80) ? MONS_SWAMP_DRAKE :
3648 (temp_rand > 59) ? MONS_KOMODO_DRAGON :
3649 (temp_rand > 34) ? MONS_FIRE_DRAKE :
3650 (temp_rand > 11) ? MONS_DEATH_DRAKE :
3651 MONS_DRAGON);
3652 break;
3654 case DRAGON_DRACONIAN:
3655 mon = random_draconian_monster_species();
3656 break;
3658 case DRAGON_DRAGON:
3659 temp_rand = random2(90);
3660 mon = ((temp_rand > 80) ? MONS_MOTTLED_DRAGON :
3661 (temp_rand > 70) ? MONS_LINDWURM :
3662 (temp_rand > 60) ? MONS_STORM_DRAGON :
3663 (temp_rand > 50) ? MONS_MOTTLED_DRAGON :
3664 (temp_rand > 40) ? MONS_STEAM_DRAGON :
3665 (temp_rand > 30) ? MONS_DRAGON :
3666 (temp_rand > 20) ? MONS_ICE_DRAGON :
3667 (temp_rand > 10) ? MONS_SWAMP_DRAGON
3668 : MONS_SHADOW_DRAGON);
3669 break;
3671 default:
3672 break;
3675 return (mon);
3678 /////////////////////////////////////////////////////////////////////////////
3680 // Random monsters for portal vaults.
3682 /////////////////////////////////////////////////////////////////////////////
3684 void set_vault_mon_list(const std::vector<mons_spec> &list)
3686 CrawlHashTable &props = env.properties;
3688 props.erase(VAULT_MON_TYPES_KEY);
3689 props.erase(VAULT_MON_BASES_KEY);
3690 props.erase(VAULT_MON_WEIGHTS_KEY);
3692 unsigned int size = list.size();
3693 if (size == 0)
3695 setup_vault_mon_list();
3696 return;
3699 props[VAULT_MON_TYPES_KEY].new_vector(SV_INT).resize(size);
3700 props[VAULT_MON_BASES_KEY].new_vector(SV_INT).resize(size);
3701 props[VAULT_MON_WEIGHTS_KEY].new_vector(SV_INT).resize(size);
3703 CrawlVector &type_vec = props[VAULT_MON_TYPES_KEY].get_vector();
3704 CrawlVector &base_vec = props[VAULT_MON_BASES_KEY].get_vector();
3705 CrawlVector &weight_vec = props[VAULT_MON_WEIGHTS_KEY].get_vector();
3707 for (unsigned int i = 0; i < size; i++)
3709 const mons_spec &spec = list[i];
3711 if (spec.place.is_valid())
3713 ASSERT(spec.place.level_type != LEVEL_LABYRINTH
3714 && spec.place.level_type != LEVEL_PORTAL_VAULT);
3715 type_vec[i] = -1;
3716 base_vec[i] = spec.place.packed_place();
3718 else
3720 ASSERT(!_is_random_monster(spec.mid)
3721 && !_is_random_monster(spec.monbase));
3722 type_vec[i] = spec.mid;
3723 base_vec[i] = spec.monbase;
3725 weight_vec[i] = spec.genweight;
3728 setup_vault_mon_list();
3731 void get_vault_mon_list(std::vector<mons_spec> &list)
3733 list.clear();
3735 CrawlHashTable &props = env.properties;
3737 if (!props.exists(VAULT_MON_TYPES_KEY))
3738 return;
3740 ASSERT(props.exists(VAULT_MON_BASES_KEY));
3741 ASSERT(props.exists(VAULT_MON_WEIGHTS_KEY));
3743 CrawlVector &type_vec = props[VAULT_MON_TYPES_KEY].get_vector();
3744 CrawlVector &base_vec = props[VAULT_MON_BASES_KEY].get_vector();
3745 CrawlVector &weight_vec = props[VAULT_MON_WEIGHTS_KEY].get_vector();
3747 ASSERT(type_vec.size() == base_vec.size());
3748 ASSERT(type_vec.size() == weight_vec.size());
3750 unsigned int size = type_vec.size();
3751 for (unsigned int i = 0; i < size; i++)
3753 int type = type_vec[i];
3754 int base = base_vec[i];
3756 mons_spec spec;
3758 if (type == -1)
3760 spec.place = level_id::from_packed_place(base);
3761 ASSERT(spec.place.is_valid());
3762 ASSERT(spec.place.level_type != LEVEL_LABYRINTH
3763 && spec.place.level_type != LEVEL_PORTAL_VAULT);
3765 else
3767 spec.mid = type;
3768 spec.monbase = (monster_type) base;
3769 ASSERT(!_is_random_monster(spec.mid)
3770 && !_is_random_monster(spec.monbase));
3772 spec.genweight = weight_vec[i];
3774 list.push_back(spec);
3778 void setup_vault_mon_list()
3780 vault_mon_types.clear();
3781 vault_mon_bases.clear();
3782 vault_mon_weights.clear();
3784 std::vector<mons_spec> list;
3785 get_vault_mon_list(list);
3787 unsigned int size = list.size();
3789 vault_mon_types.resize(size);
3790 vault_mon_bases.resize(size);
3791 vault_mon_weights.resize(size);
3793 for (unsigned int i = 0; i < size; i++)
3795 if (list[i].place.is_valid())
3797 vault_mon_types[i] = -1;
3798 vault_mon_bases[i] = list[i].place.packed_place();
3800 else
3802 vault_mon_types[i] = list[i].mid;
3803 vault_mon_bases[i] = list[i].monbase;
3805 vault_mon_weights[i] = list[i].genweight;