Fix indentation.
[crawl.git] / crawl-ref / source / zotdef.cc
blobea2aa6f046056ee32249487a9b9ea6e0cf54fb95
1 /*
2 * File: zotdef.cc
3 * Summary: Zot Def specific functions
4 * Written by: Mark Mackey
5 */
7 #include "AppHdr.h"
9 #include "branch.h"
10 #include "directn.h"
11 #include "dungeon.h" // for Zotdef unique placement
12 #include "env.h"
13 #include "externs.h"
14 #include "ghost.h"
15 #include "items.h" // // for find_floor_item
16 #include "itemname.h" // // for make_name
17 #include "lev-pand.h"
18 #include "los.h"
19 #include "makeitem.h"
20 #include "message.h"
21 #include "mgen_data.h"
22 #include "mon-stuff.h"
23 #include "mon-place.h"
24 #include "mon-pick.h"
25 #include "mon-util.h"
26 #include "player.h"
27 #include "religion.h"
28 #include "random.h"
29 #include "state.h"
30 #include "stuff.h"
31 #include "terrain.h"
32 #include "traps.h"
33 #include "view.h"
34 #include "zotdef.h"
36 // Size of the mons_alloc array (or at least the bit of
37 // it that we use).
38 #define NSLOTS (MAX_MONS_ALLOC - 1)
39 #define BOSS_SLOT NSLOTS
41 //#define DEBUG_WAVE 1
43 static monster_type _pick_unique(int level);
45 static int _fuzz_mons_level(int level)
47 if (level > 1 && one_chance_in(7))
49 const int fuzz = random2avg(9, 2);
50 return (fuzz > 4 ? level + fuzz - 4 : level);
52 return (level);
55 // Choose a random branch. Which branches may be chosen is a function of
56 // the wave number
57 branch_type zotdef_random_branch()
59 int wavenum = you.num_turns / CYCLE_LENGTH;
61 while (true)
63 branch_type pb = static_cast<branch_type>(random2(NUM_BRANCHES));
64 bool ok = true;
65 switch (pb)
67 case BRANCH_MAIN_DUNGEON:
68 ok = true;
69 // reduce freq at high levels
70 if (wavenum > 40)
71 ok = coinflip();
72 break;
74 case BRANCH_SNAKE_PIT:
75 ok = wavenum > 10;
76 // reduce freq at high levels
77 if (wavenum > 40 && !coinflip())
78 ok = false;
79 break;
81 default:
82 case BRANCH_ECUMENICAL_TEMPLE:
83 case BRANCH_VAULTS:
84 case BRANCH_VESTIBULE_OF_HELL:
85 ok = false;
86 break; // vaults/vestibule same as dungeon
88 case BRANCH_ORCISH_MINES:
89 ok = wavenum < 30; // <6K turns only
90 break;
91 case BRANCH_ELVEN_HALLS:
92 ok = wavenum > 10 && wavenum < 60; // 2.2-12K turns
93 break;
94 case BRANCH_LAIR:
95 ok = wavenum < 40; // <8K turns only
96 break;
97 case BRANCH_SWAMP:
98 ok = wavenum > 12 && wavenum < 40; // 2.6-8K turns
99 break;
100 case BRANCH_SHOALS:
101 ok = wavenum > 12 && wavenum < 60; // 2.6-12K turns
102 break;
103 case BRANCH_CRYPT:
104 ok = wavenum > 13; // 2.8K-
105 break;
106 case BRANCH_SLIME_PITS:
107 ok = wavenum > 20 && coinflip(); // 4K-
108 break; // >4K turns only
109 case BRANCH_HIVE:
110 ok = wavenum > 12 && wavenum < 35; // 2.6-7.5K
111 break;
112 case BRANCH_HALL_OF_BLADES:
113 ok = wavenum > 30; // 6K-
114 break;
115 case BRANCH_TOMB:
116 ok = wavenum > 30 && coinflip(); // 6K-
117 break;
118 case BRANCH_DIS: // 8K-
119 case BRANCH_COCYTUS:
120 case BRANCH_TARTARUS:
121 case BRANCH_GEHENNA:
122 ok = wavenum > 40 && one_chance_in(3);
123 break;
124 case BRANCH_HALL_OF_ZOT: // 10K-
125 ok = wavenum > 50;
126 break;
128 if (ok)
129 return (one_chance_in(4) ? BRANCH_MAIN_DUNGEON : pb);
130 // strong bias to main dungeon
134 int mon_strength(monster_type mon_type)
136 monsterentry *mentry = get_monster_data(mon_type);
137 if (!mentry)
138 return 0; // sanity
139 int strength = (mentry->hpdice[0] * mentry->exp_mod) / 10;
140 // Fix for skeletons and zombies
141 switch (mon_type)
143 case MONS_SKELETON_SMALL:
144 case MONS_ZOMBIE_SMALL:
145 strength += 3;
146 break;
147 case MONS_SKELETON_LARGE:
148 case MONS_ZOMBIE_LARGE:
149 strength += 4;
150 break;
151 case MONS_PANDEMONIUM_DEMON: // base init has 4HD (!)
152 strength = 30;
153 break;
154 default:
155 break;
157 return strength;
160 // Fill the wave list with selections from a supplied array.
161 // Each array contains a monster if random2(power)>chance. Power
162 // is also compared to the strength of each critter to allow later
163 // waves to be stronger than earlier ones.
165 // Note that this fills in the boss slot as well.
166 static void _zotdef_fill_from_list(monster_type mlist[], int chance, int power)
168 for (int i = 0; i <= NSLOTS; i++)
170 env.mons_alloc[i] = MONS_PROGRAM_BUG;
171 if (i < NSLOTS && random2(power) < chance)
172 continue; // no monster this entry
173 while (env.mons_alloc[i] == MONS_PROGRAM_BUG)
175 monster_type mon_type = RANDOM_ELEMENT(mlist);
176 if (random2((power * 3) / 2) > mon_strength(mon_type))
177 continue; // bias away from weaker critters
178 if (random2((power * 3) / 2) > mon_strength(mon_type))
179 env.mons_alloc[i] = mon_type;
180 if (one_chance_in(100))
181 env.mons_alloc[i] = mon_type; // occasional random pick
186 // Choose a boss from the supplied list. If a unique is chosen and has
187 // already been seen we try again. After a few tries we give up and
188 // leave the existing entry there.
189 static void _zotdef_choose_boss(monster_type mlist[], int power)
191 int tries = 0;
192 while (tries++ < 100)
194 monster_type mon_type = RANDOM_ELEMENT(mlist);
195 if (mons_is_unique(mon_type)
196 && you.unique_creatures[mon_type])
198 continue;
200 if (random2avg(power * 3, 2) < mon_strength(mon_type))
201 continue;
203 // OK, take this one
204 env.mons_alloc[BOSS_SLOT] = mon_type;
205 break;
209 static void _zotdef_danger_msg(const char *msg)
211 mpr(msg, MSGCH_DANGER);
212 more();
215 void hydra_wave(int power)
217 #ifdef DEBUG_WAVE
218 mpr("HYDRA WAVE");
219 #endif
220 monster_type hydras[] = {MONS_HYDRA};
221 monster_type boss[] = {MONS_LERNAEAN_HYDRA};
222 _zotdef_fill_from_list(hydras, 4, power); // 66% full at power 12
223 _zotdef_choose_boss(boss, power * 2);
224 _zotdef_danger_msg("You hear a distant many-voiced hissing!");
227 void fire_wave(int power)
229 #ifdef DEBUG_WAVE
230 mpr("FIRE WAVE");
231 #endif
232 monster_type firemons[] = {MONS_FIRE_ELEMENTAL, MONS_FIRE_DRAKE, MONS_IMP,
233 MONS_DRAGON, MONS_FIRE_VORTEX ,MONS_FIRE_GIANT, MONS_HELLION,
234 MONS_MOLTEN_GARGOYLE, MONS_SALAMANDER, MONS_SUN_DEMON,
235 MONS_RED_DRACONIAN, MONS_MOTTLED_DRACONIAN, MONS_DRACONIAN_SCORCHER,
236 MONS_FLAMING_CORPSE, MONS_MOTTLED_DRAGON, MONS_EFREET,
237 MONS_HELL_KNIGHT, MONS_FIEND, MONS_BALRUG, MONS_HELL_HOUND,
238 MONS_HELL_HOG};
239 monster_type boss[] = {MONS_AZRAEL, MONS_XTAHUA, MONS_SERPENT_OF_HELL,
240 MONS_MARGERY, MONS_FIEND, MONS_BALRUG, MONS_FIRE_GIANT};
241 _zotdef_fill_from_list(firemons, 0, power);
242 _zotdef_choose_boss(boss, power);
243 _zotdef_danger_msg("You hear roaring flames in the distance!");
246 void cold_wave(int power)
248 #ifdef DEBUG_WAVE
249 mpr("COLD WAVE");
250 #endif
251 monster_type coldmons[] = {MONS_ICE_BEAST, MONS_AZURE_JELLY,
252 MONS_FREEZING_WRAITH, MONS_WHITE_IMP, MONS_ICE_DEVIL, MONS_ICE_FIEND,
253 MONS_WHITE_DRACONIAN, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE,
254 MONS_FROST_GIANT, MONS_POLAR_BEAR, MONS_BLUE_DEVIL};
255 monster_type boss[] = {MONS_ANTAEUS, MONS_ICE_FIEND, MONS_AZURE_JELLY,
256 MONS_WHITE_DRACONIAN};
257 _zotdef_fill_from_list(coldmons, 4, power);
258 _zotdef_choose_boss(boss, power);
259 _zotdef_danger_msg("A deadly chill settles over the dungeon!");
262 void gnoll_wave(int power)
264 #ifdef DEBUG_WAVE
265 mpr("GNOLL WAVE");
266 #endif
267 monster_type gnolls[] = {MONS_GNOLL, MONS_GNOLL, MONS_GNOLL,
268 MONS_GNOLL, MONS_GNOLL, MONS_GNOLL, MONS_TROLL};
269 monster_type boss[] = {MONS_GRUM, MONS_TROLL};
270 _zotdef_fill_from_list(gnolls, 0, power); // full
271 _zotdef_choose_boss(boss, power);
272 _zotdef_danger_msg("Harsh voices can be heard, coming closer!");
275 void rat_wave(int power)
277 #ifdef DEBUG_WAVE
278 mpr("RAT WAVE");
279 #endif
280 monster_type rats[] = {MONS_RAT, MONS_GREEN_RAT, MONS_GREY_RAT,
281 MONS_ORANGE_RAT};
282 monster_type boss[] = {MONS_ORANGE_RAT};
283 _zotdef_fill_from_list(rats, 0, power); // full power
284 _zotdef_choose_boss(boss, power);
285 _zotdef_danger_msg("You hear distant squeaking!");
288 void hound_wave(int power)
290 #ifdef DEBUG_WAVE
291 mpr("HOUND WAVE");
292 #endif
293 monster_type hounds[] = {MONS_JACKAL, MONS_HOUND, MONS_WARG,
294 MONS_WOLF, MONS_WAR_DOG};
295 monster_type boss[] = {MONS_HELL_HOUND};
296 _zotdef_fill_from_list(hounds, 0, power); // full
297 _zotdef_choose_boss(boss, power);
298 _zotdef_danger_msg("Horrible howls echo around!");
301 void abomination_wave(int power)
303 #ifdef DEBUG_WAVE
304 mpr("ABOMINATION WAVE");
305 #endif
306 monster_type aboms[] = {MONS_ABOMINATION_SMALL, MONS_ABOMINATION_LARGE};
307 monster_type boss[] = {MONS_TENTACLED_MONSTROSITY};
308 _zotdef_fill_from_list(aboms, 0, power); // full
309 _zotdef_choose_boss(boss, power);
310 _zotdef_danger_msg("A dreadful chittering sound fills the air. It's coming closer...");
313 void ugly_wave(int power)
315 #ifdef DEBUG_WAVE
316 mpr("UGLY WAVE");
317 #endif
318 monster_type ugly[] = {MONS_UGLY_THING, MONS_UGLY_THING, MONS_UGLY_THING,
319 MONS_VERY_UGLY_THING};
320 monster_type boss[] = {MONS_VERY_UGLY_THING};
321 _zotdef_fill_from_list(ugly, 6, power); // reduced size
322 _zotdef_choose_boss(boss, power);
323 _zotdef_danger_msg("You feel uneasy.");
326 void golem_wave(int power)
328 #ifdef DEBUG_WAVE
329 mpr("GOLEM WAVE");
330 #endif
331 monster_type golems[] = {MONS_CLAY_GOLEM, MONS_WOOD_GOLEM, MONS_STONE_GOLEM,
332 MONS_IRON_GOLEM, MONS_CRYSTAL_GOLEM, MONS_TOENAIL_GOLEM};
333 monster_type boss[] = {MONS_ELECTRIC_GOLEM};
334 _zotdef_fill_from_list(golems, 6, power * 2 / 3); // reduced size
335 _zotdef_choose_boss(boss, power);
336 _zotdef_danger_msg("Booming thuds herald the arrival of something large...");
339 void human_wave(int power)
341 #ifdef DEBUG_WAVE
342 mpr("HUMAN WAVE");
343 #endif
344 monster_type humans[] = {MONS_HUMAN, MONS_HELL_KNIGHT, MONS_NECROMANCER,
345 MONS_WIZARD, MONS_VAULT_GUARD, MONS_KILLER_KLOWN};
346 monster_type boss[] = {MONS_HELL_KNIGHT, MONS_KILLER_KLOWN,
347 MONS_VAULT_GUARD, MONS_JOSEPH, MONS_ERICA, MONS_JOSEPHINE,
348 MONS_HAROLD, MONS_JOZEF, MONS_AGNES,
349 MONS_MAUD, MONS_LOUISE, MONS_FRANCES,
350 MONS_RUPERT, MONS_KIRKE,
351 MONS_NORRIS, MONS_FREDERICK, MONS_MARGERY, MONS_EUSTACHIO,
352 MONS_MAURICE};
353 _zotdef_fill_from_list(humans, 4, power); // reduced size due to banding
355 // Get too many hell knights with the defaults, due to their large band
356 // size. Reduce here
357 for (int i = 0; i < NSLOTS; i++)
359 if (env.mons_alloc[i] == MONS_HELL_KNIGHT && random2(power) < 8)
360 env.mons_alloc[i] = MONS_PROGRAM_BUG;
363 _zotdef_choose_boss(boss, power);
364 _zotdef_danger_msg("War cries fill the air!");
367 void butterfly_wave(int power)
369 #ifdef DEBUG_WAVE
370 mpr("BUTTERFLY WAVE");
371 #endif
372 monster_type bfs[] = {MONS_BUTTERFLY};
373 _zotdef_fill_from_list(bfs, 0, power); // full
374 _zotdef_danger_msg("You feel a sudden sense of peace!");
377 void beast_wave(int power)
379 #ifdef DEBUG_WAVE
380 mpr("BEAST WAVE");
381 #endif
382 monster_type bst[] = {MONS_BEAST};
383 _zotdef_fill_from_list(bst, 0, power); // full
384 _zotdef_danger_msg("A hideous howling noise can be heard in the distance!");
387 void frog_wave(int power)
389 #ifdef DEBUG_WAVE
390 mpr("FROG WAVE");
391 #endif
392 monster_type frogs[] = {MONS_GIANT_FROG, MONS_GIANT_TOAD,
393 MONS_SPINY_FROG, MONS_BLINK_FROG};
394 monster_type boss[] = {MONS_PRINCE_RIBBIT, MONS_SPINY_FROG, MONS_BLINK_FROG};
395 _zotdef_fill_from_list(frogs, 0, power); // full
396 _zotdef_choose_boss(boss, power);
397 _zotdef_danger_msg("Croaking noises echo off the walls!");
400 void bear_wave(int power)
402 #ifdef DEBUG_WAVE
403 mpr("BEAR WAVE");
404 #endif
405 monster_type bears[] = {MONS_BEAR, MONS_GRIZZLY_BEAR, MONS_POLAR_BEAR,
406 MONS_BLACK_BEAR};
407 monster_type boss[] = {MONS_GRIZZLY_BEAR, MONS_POLAR_BEAR};
408 _zotdef_fill_from_list(bears, 0, power); // full
409 _zotdef_choose_boss(boss, power);
410 _zotdef_danger_msg("Gravelly voices can be heard calling for porridge!");
413 void wraith_wave(int power)
415 #ifdef DEBUG_WAVE
416 mpr("WRAITH WAVE");
417 #endif
418 monster_type wraiths[] = {MONS_WRAITH, MONS_SHADOW_WRAITH, MONS_FREEZING_WRAITH,
419 MONS_EIDOLON, MONS_PHANTASMAL_WARRIOR, MONS_SPECTRAL_THING};
420 monster_type boss[] = {MONS_EIDOLON, MONS_PHANTASMAL_WARRIOR, MONS_SPECTRAL_THING};
421 _zotdef_fill_from_list(wraiths, 0, power); // full
422 _zotdef_choose_boss(boss, power);
423 _zotdef_danger_msg("The hair rises on the back of your neck!");
426 void giant_wave(int power)
428 #ifdef DEBUG_WAVE
429 mpr("GIANT WAVE");
430 #endif
431 monster_type giants[] = {MONS_ETTIN, MONS_CYCLOPS, MONS_TWO_HEADED_OGRE,
432 MONS_OGRE, MONS_TROLL, MONS_MINOTAUR, MONS_HILL_GIANT,
433 MONS_STONE_GIANT, MONS_FIRE_GIANT, MONS_FROST_GIANT, MONS_OGRE_MAGE,
434 MONS_ROCK_TROLL, MONS_IRON_TROLL, MONS_DEEP_TROLL, MONS_TITAN};
435 monster_type boss[] = {MONS_EROLCHA, MONS_POLYPHEMUS, MONS_ANTAEUS,
436 MONS_SNORG, MONS_PURGY, MONS_STONE_GIANT, MONS_FIRE_GIANT,
437 MONS_FROST_GIANT, MONS_TITAN};
438 _zotdef_fill_from_list(giants, 0, power); // full
439 _zotdef_choose_boss(boss, power);
440 _zotdef_danger_msg("The stamp of enormous boots can be heard in the distance.");
443 void yak_wave(int power)
445 #ifdef DEBUG_WAVE
446 mpr("YAK WAVE");
447 #endif
448 monster_type yaks[] = {MONS_SHEEP, MONS_YAK, MONS_DEATH_YAK,
449 MONS_SHEEP, MONS_YAK, MONS_DEATH_YAK,
450 MONS_SHEEP, MONS_YAK, MONS_DEATH_YAK,
451 MONS_CYCLOPS};
452 monster_type boss[] = {MONS_POLYPHEMUS, MONS_CYCLOPS};
453 _zotdef_fill_from_list(yaks, 0, power); // full
454 _zotdef_choose_boss(boss, power);
455 _zotdef_danger_msg("Bleats and roars echo around!");
458 void insect_wave(int power)
460 #ifdef DEBUG_WAVE
461 mpr("INSECT WAVE");
462 #endif
463 monster_type insects[] = {MONS_GIANT_ANT, MONS_KILLER_BEE, MONS_YELLOW_WASP,
464 MONS_GIANT_BEETLE, MONS_QUEEN_BEE, MONS_WOLF_SPIDER, MONS_BUTTERFLY,
465 MONS_BOULDER_BEETLE, MONS_GIANT_MITE, MONS_BUMBLEBEE, MONS_REDBACK,
466 MONS_GIANT_BLOWFLY, MONS_RED_WASP, MONS_SOLDIER_ANT, MONS_QUEEN_ANT,
467 MONS_GIANT_COCKROACH, MONS_BORING_BEETLE, MONS_TRAPDOOR_SPIDER,
468 MONS_SCORPION, MONS_GIANT_MOSQUITO, MONS_GIANT_CENTIPEDE};
469 monster_type boss[] = {MONS_GIANT_BEETLE, MONS_BOULDER_BEETLE,
470 MONS_QUEEN_ANT, MONS_BORING_BEETLE, MONS_QUEEN_BEE};
471 _zotdef_fill_from_list(insects, 0, power); // full
472 _zotdef_choose_boss(boss, power);
473 _zotdef_danger_msg("You hear an ominous buzzing.");
476 void pan_wave(int power)
478 #ifdef DEBUG_WAVE
479 mpr("PAN WAVE");
480 #endif
481 // The unique '&'s are a bit too strong at lower levels. Lom
482 // Lobon in particular is almost unkillable
483 monster_type boss[] = {MONS_MNOLEG, MONS_LOM_LOBON, MONS_CEREBOV,
484 MONS_GLOORX_VLOQ, MONS_GERYON, MONS_DISPATER,
485 MONS_ASMODEUS, MONS_ERESHKIGAL, MONS_PANDEMONIUM_DEMON};
486 monster_type weakboss[] = {MONS_PANDEMONIUM_DEMON, MONS_FIEND,
487 MONS_PIT_FIEND, MONS_ICE_FIEND, MONS_BLUE_DEATH};
489 for (int i = 0; i <= NSLOTS; i++)
491 env.mons_alloc[i] = MONS_PROGRAM_BUG;
492 while (env.mons_alloc[i] == MONS_PROGRAM_BUG)
494 monster_type mon_type = static_cast<monster_type>(random2(NUM_MONSTERS));
495 monsterentry *mentry = get_monster_data(mon_type);
496 int pow = random2avg(power, 2);
497 switch (mentry->showchar)
499 case '5': if (pow > 4) continue; break;
500 case '4': if (pow > 4) continue; break;
501 case '3': if (pow > 6) continue; break;
502 case '2': if (pow > 10) continue; break;
503 case '1': if (pow > 12) continue; break;
504 default: continue;
506 env.mons_alloc[i] = mon_type;
509 // Weak bosses only at lower power
510 _zotdef_choose_boss((power < 27 ? weakboss : boss), power);
511 _zotdef_danger_msg("Hellish voices call for your blood. They are coming!");
514 void zotdef_set_special_wave(int power)
516 void (*wave_fn)(int) = NULL;
517 int tries = 0;
519 while (wave_fn == NULL && tries++ < 10000)
521 int wpow = 0;
522 switch (random2(21))
524 case 0: wave_fn = hydra_wave; wpow = 10; break;
525 case 1: wave_fn = fire_wave; wpow = 12; break;
526 case 2: wave_fn = cold_wave; wpow = 12; break;
527 case 3: wave_fn = gnoll_wave; wpow = 4; break;
528 case 4: wave_fn = rat_wave; wpow = 2; break;
529 case 5: wave_fn = hound_wave; wpow = 2; break;
530 case 6: wave_fn = abomination_wave; wpow = 12; break;
531 case 7: wave_fn = ugly_wave; wpow = 14; break;
532 case 8: wave_fn = golem_wave; wpow = 22; break;
533 case 9: wave_fn = human_wave; wpow = 12; break;
534 case 10: wave_fn = butterfly_wave; wpow = 1; break;
535 case 11: wave_fn = beast_wave; wpow = 12; break;
536 case 12: wave_fn = frog_wave; wpow = 4; break;
537 case 13: wave_fn = bear_wave; wpow = 6; break;
538 case 14: wave_fn = wraith_wave; wpow = 8; break;
539 case 15: wave_fn = giant_wave; wpow = 16; break;
540 case 16: wave_fn = yak_wave; wpow = 12; break; // lots of bands
541 case 17: wave_fn = insect_wave; wpow = 4; break;
542 case 18: wave_fn = pan_wave; wpow = 24; break;
543 // extra copies of fire and cold at higher power
544 case 19: wave_fn = fire_wave; wpow = 20; break;
545 case 20: wave_fn = cold_wave; wpow = 20; break;
547 // Algorithm: doesn't appear before 'wpow-5'. Max probability
548 // at 'wpow'. Doesn't appear after 'wpow*2+4'.
549 // OK: do we keep this one?
550 if (power >= (wpow - 5) && power <= (wpow * 2 + 4))
552 int diff = power - wpow;
553 if (diff > 0)
554 diff /= 2; // weaker waves more common
555 if (one_chance_in(diff * diff))
556 break; // keep this one
558 // Nope, don't keep
559 wave_fn = NULL;
561 if (wave_fn)
562 wave_fn(power);
565 void debug_waves()
567 for (int i = 0; i < 15 * FREQUENCY_OF_RUNES; i++)
569 you.num_turns += CYCLE_LENGTH;
570 zotdef_set_wave();
574 monster_type get_zotdef_monster(level_id &place, int power)
576 monster_type mon_type;
577 monster_type mon_type_ret = MONS_PROGRAM_BUG;
578 for (int i = 0; i <= 10000; ++i)
580 int count = 0;
581 int rarity;
585 mon_type = static_cast<monster_type>(random2(NUM_MONSTERS));
586 count++;
587 rarity = (place.branch == NUM_BRANCHES) ? 30 : mons_rarity(mon_type, place);
589 while (rarity == 0 && count < 2000);
591 if (count == 2000)
592 return (MONS_PROGRAM_BUG);
594 // Calculate strength
595 monsterentry *mentry = get_monster_data(mon_type);
596 if (!mentry)
597 continue; // sanity
598 if (mentry == get_monster_data(MONS_PROGRAM_BUG))
599 continue; // sanity
600 if (mons_is_unique(mon_type))
601 continue; // No uniques here!
602 if (mons_class_is_stationary(mon_type))
603 continue; // Must be able to move!
605 int strength = mon_strength(mon_type);
607 // get default level
608 int lev_mons = (place.branch == NUM_BRANCHES)
609 ? ((strength * 3) / 2)
610 : mons_level(mon_type, place);
612 // if >50, bail out - these are special flags
613 if (lev_mons >= 50)
614 continue;
616 //int orig_lev_mons = lev_mons;
618 // adjust level based on strength, as weak monsters with high
619 // level pop up on some branches and we want to allow them
620 if (place.branch != BRANCH_MAIN_DUNGEON
621 && lev_mons > power
622 && lev_mons > strength * 3)
624 lev_mons = (lev_mons + 2 * strength) / 3;
627 // reduce power to 32 if that reduces diff
628 if (lev_mons <= 32 && power > 32)
629 power = 32;
630 int diff = power - lev_mons;
631 if (power > 20)
632 diff = diff * 20 / power; // reduce diff at high power
634 int chance = rarity - (diff * diff);
635 // Occasionally accept a weaker monster
636 if (diff > 0 && chance <= 0)
638 chance = 1;
639 if (lev_mons > 20) chance = 3;
640 if (lev_mons > 25) chance = 5;
643 // Rarely accept monsters too far outside the power range
644 if ((diff <- 5 || diff > 5) && !one_chance_in(3))
645 continue;
647 // Less OOD allowed on early levels
648 if (diff < std::min(-3,-power))
649 continue;
651 const char *bn = "RANDOM";
652 if (place.branch != NUM_BRANCHES)
653 bn = branches[place.branch].shortname;
655 if (random2avg(100, 2) <= chance)
657 dprf("ZOTDEF %d %s chose monster %s rarity %d power %d strength %d "
658 "level %d chance %d", i, bn,mentry->name, rarity, power,
659 strength, lev_mons, chance);
660 mon_type_ret = mon_type;
661 break;
664 if (i == 10000)
665 return (MONS_PROGRAM_BUG);
668 return mon_type_ret;
671 void zotdef_set_random_branch_wave(int power)
673 //mprf("RANDOM WAVE");
674 for (int i = 0; i < NSLOTS; i++)
676 level_id l(zotdef_random_branch(), -1);
677 env.mons_alloc[i] = get_zotdef_monster(l, _fuzz_mons_level(power));
679 level_id l(zotdef_random_branch(), -1);
680 env.mons_alloc[BOSS_SLOT] = get_zotdef_monster(l,
681 power + BOSS_MONSTER_EXTRA_POWER);
684 void zotdef_set_branch_wave(branch_type b, int power)
686 level_id l(b,-1);
687 dprf("BRANCH WAVE: BRANCH %s",
688 (b == NUM_BRANCHES) ? "RANDOM" : branches[b].shortname);
689 for (int i = 0; i < NSLOTS; i++)
690 env.mons_alloc[i] = get_zotdef_monster(l, _fuzz_mons_level(power));
691 env.mons_alloc[BOSS_SLOT] = get_zotdef_monster(l,
692 power + BOSS_MONSTER_EXTRA_POWER);
695 void zotdef_set_boss_unique()
697 for (int tries = 0; tries < 100; tries++)
699 int level = random2avg(you.num_turns / CYCLE_LENGTH, 2) + 1;
700 monster_type which_unique = _pick_unique(level);
702 // Sometimes, we just quit if a unique is already placed.
703 if (which_unique == MONS_PROGRAM_BUG
704 || you.unique_creatures[which_unique] && one_chance_in(5))
706 continue;
709 env.mons_alloc[BOSS_SLOT] = which_unique;
710 break;
714 // Set the env.mons_alloc data for this wave. Note that
715 // mons_alloc[BOSS_SLOT] is the boss.
717 // A game lasts for 15 runes, each rune 1400 turns apart
718 // (assuming FREQUENCY_OF_RUNES=7, CYCLE_LENGTH=200). That's
719 // a total of 105 waves. Set probabilities accordingly.
720 void zotdef_set_wave()
722 // power ramps up from 1 to 35 over the course of the game.
723 int power = (you.num_turns + CYCLE_LENGTH * 2) / (CYCLE_LENGTH * 3);
725 // Early waves are all DUNGEON
726 if (you.num_turns < CYCLE_LENGTH * 4)
728 zotdef_set_branch_wave(BRANCH_MAIN_DUNGEON, power);
729 return;
732 switch (random2(5))
734 case 0:
735 case 1:
736 zotdef_set_branch_wave(BRANCH_MAIN_DUNGEON, power);
737 break;
738 case 2:
739 case 3:
741 branch_type b = zotdef_random_branch();
742 // HoB branch waves v. rare before 10K turns
743 if (b == BRANCH_HALL_OF_BLADES && you.num_turns / CYCLE_LENGTH < 50)
744 b = zotdef_random_branch();
745 zotdef_set_branch_wave(b, power);
746 break;
748 // A random mixture of monsters from across the branches
749 case 4:
750 zotdef_set_random_branch_wave(power);
751 break;
754 // special waves have their own boss choices. Note that flavour
755 // messages can be emitted by each individual wave type
756 if (one_chance_in(8))
757 zotdef_set_special_wave(power);
758 else
760 // Truly random wave, (crappily) signalled by passing branch=NUM_BRANCHES
761 if (power > 8 && one_chance_in(20))
763 _zotdef_danger_msg("The air ripples, and you hear distant laughter!");
764 zotdef_set_branch_wave(NUM_BRANCHES, power);
767 // overwrite the previously-set boss with a random unique?
768 if (one_chance_in(3))
769 zotdef_set_boss_unique();
773 for (int i = 0; i < 20; i++)
775 monsterentry *mentry = get_monster_data(env.mons_alloc[i]);
776 mprf("NEW WAVE: monster %d is %s",i,mentry->name);
781 int zotdef_spawn(bool boss)
783 monster_type mt = env.mons_alloc[random2(NSLOTS)];
784 if (boss)
786 mt = env.mons_alloc[BOSS_SLOT];
787 // check if unique
788 if (mons_is_unique(mt) && you.unique_creatures[mt])
789 mt = env.mons_alloc[0]; // grab slot 0 as crap alternative
791 if (mt == MONS_PROGRAM_BUG)
792 return -1;
794 // Generate a monster of the appropriate branch and strength
795 mgen_data mg(mt, BEH_SEEK, NULL, 0, 0, coord_def(), MHITYOU);
796 mg.proximity = PROX_NEAR_STAIRS;
797 mg.flags |= MG_PERMIT_BANDS;
799 int mid = mons_place(mg);
801 // Boss monsters which aren't uniques are named, and beefed a bit further
802 if (mid != -1 && boss && !mons_is_unique(mt))
804 // Use the proper name function: if that fails, fall back
805 // to the randart name generator
806 if (!menv[mid].is_named()) // Don't rename uniques!
808 if (!give_monster_proper_name(&menv[mid], false))
809 menv[mid].mname = make_name(random_int(), false);
812 menv[mid].hit_points = (menv[mid].hit_points * 3) / 2;
813 menv[mid].max_hit_points = menv[mid].hit_points;
816 return mid;
819 rune_type get_rune(int runenumber)
821 switch (runenumber)
823 case 1:
824 return RUNE_DIS;
825 case 2:
826 return RUNE_GEHENNA;
827 case 3:
828 return RUNE_COCYTUS;
829 case 4:
830 return RUNE_TARTARUS;
831 case 5:
832 return RUNE_SLIME_PITS;
833 case 6:
834 return RUNE_VAULTS;
835 case 7:
836 return RUNE_SNAKE_PIT;
837 case 8:
838 return RUNE_TOMB;
839 case 9:
840 return RUNE_SWAMP;
841 case 10:
842 return RUNE_DEMONIC;
843 case 11:
844 return RUNE_ABYSSAL;
845 case 12:
846 return RUNE_MNOLEG;
847 case 13:
848 return RUNE_LOM_LOBON;
849 case 14:
850 return RUNE_CEREBOV;
851 case 15:
852 return RUNE_GLOORX_VLOQ;
853 default:
854 return RUNE_DEMONIC;
858 // Dowan is automatically placed together with Duvessa.
859 static monster_type _choose_unique_by_depth(int step)
861 int ret;
862 switch (step)
864 case 0: // depth <= 3
865 ret = random_choose(MONS_TERENCE, MONS_JESSICA, MONS_IJYB,
866 MONS_SIGMUND, -1);
867 break;
868 case 1: // depth <= 7
869 ret = random_choose(MONS_IJYB, MONS_SIGMUND, MONS_BLORK_THE_ORC,
870 MONS_EDMUND, MONS_PRINCE_RIBBIT, MONS_PURGY,
871 MONS_MENKAURE, MONS_DUVESSA, MONS_PIKEL, -1);
872 break;
873 case 2: // depth <= 9
874 ret = random_choose(MONS_BLORK_THE_ORC, MONS_EDMUND, MONS_PSYCHE, MONS_JOSEPH,
875 MONS_EROLCHA, MONS_PRINCE_RIBBIT, MONS_GRUM,
876 MONS_GASTRONOK, MONS_GRINDER, MONS_MAURICE,
877 MONS_PIKEL, -1);
878 break;
879 case 3: // depth <= 13
880 ret = random_choose(MONS_PSYCHE, MONS_EROLCHA, MONS_DONALD, MONS_URUG,
881 MONS_EUSTACHIO, MONS_SONJA, MONS_GRUM, MONS_NIKOLA,
882 MONS_ERICA, MONS_JOSEPHINE, MONS_JOZEF,
883 MONS_HAROLD, MONS_GASTRONOK, MONS_ILSUIW,
884 MONS_MAURICE, -1);
885 break;
886 case 4: // depth <= 16
887 ret = random_choose(MONS_URUG, MONS_EUSTACHIO, MONS_SONJA,
888 MONS_SNORG, MONS_ERICA, MONS_JOSEPHINE, MONS_HAROLD,
889 MONS_ROXANNE, MONS_RUPERT, MONS_JOZEF, MONS_NIKOLA,
890 MONS_AZRAEL, MONS_NESSOS, MONS_AGNES, MONS_AIZUL,
891 MONS_MAUD, MONS_LOUISE, MONS_NERGALLE, MONS_KIRKE, -1);
892 break;
893 case 5: // depth <= 19
894 ret = random_choose(MONS_SNORG, MONS_LOUISE, MONS_FRANCES, MONS_KHUFU,
895 MONS_RUPERT, MONS_NORRIS, MONS_AGNES,
896 MONS_AZRAEL, MONS_NESSOS, MONS_NERGALLE,
897 MONS_ROXANNE, MONS_SAINT_ROKA, MONS_KIRKE,
898 MONS_WIGLAF, -1);
899 break;
900 case 6: // depth > 19
901 default:
902 ret = random_choose(MONS_FRANCES, MONS_MARA, MONS_WIGLAF, MONS_MENNAS,
903 MONS_XTAHUA, MONS_NORRIS, MONS_FREDERICK, MONS_TIAMAT,
904 MONS_MARGERY, MONS_BORIS, MONS_SAINT_ROKA, -1);
907 return static_cast<monster_type>(ret);
910 static monster_type _pick_unique(int level)
912 // Pick generic unique depending on depth.
913 int which_unique =
914 ((level <= 3) ? _choose_unique_by_depth(0) :
915 (level <= 7) ? _choose_unique_by_depth(1) :
916 (level <= 9) ? _choose_unique_by_depth(2) :
917 (level <= 13) ? _choose_unique_by_depth(3) :
918 (level <= 16) ? _choose_unique_by_depth(4) :
919 (level <= 19) ? _choose_unique_by_depth(5) :
920 _choose_unique_by_depth(6));
922 return static_cast<monster_type>(which_unique);
925 // Ask for a location and place a trap there. Returns true
926 // for success
927 bool create_trap(trap_type spec_type)
929 dist abild;
930 direction_chooser_args args;
931 args.restricts = DIR_TARGET;
932 args.needs_path = false;
933 args.may_target_monster = false;
934 args.top_prompt = "Make ";
935 args.top_prompt += trap_name(spec_type);
936 args.top_prompt += " trap where?";
937 direction(abild, args);
938 const dungeon_feature_type grid = grd(abild.target);
939 if (!abild.isValid)
941 if (abild.isCancel)
942 canned_msg(MSG_OK);
943 return (false);
945 // only try to create on floor squares
946 if (grid >= DNGN_FLOOR_MIN && grid <= DNGN_FLOOR_MAX)
947 return place_specific_trap(abild.target, spec_type);
948 else
950 mpr("You can't create a trap there!");
951 return (false);
955 bool create_zotdef_ally(monster_type mtyp, const char *successmsg)
957 dist abild;
958 std::string msg = "Make ";
959 msg += get_monster_data(mtyp)->name;
960 msg += " where?";
962 direction_chooser_args args;
963 args.restricts = DIR_TARGET;
964 args.needs_path = false;
965 args.may_target_monster = false;
966 args.top_prompt = msg;
967 direction(abild, args);
969 if (!abild.isValid)
971 if (abild.isCancel)
972 canned_msg(MSG_OK);
973 return (false);
975 if (mons_place(mgen_data(mtyp, BEH_FRIENDLY, &you, 0, 0, abild.target,
976 you.pet_target)) == -1)
978 mpr("You can't create it there!");
979 return (false);
981 mpr(successmsg);
982 return (true);
985 void zotdef_bosses_check()
987 if ((you.num_turns + 1) % CYCLE_LENGTH == 0)
989 int mon = zotdef_spawn(true); // boss monster=true
991 if (mon > -1)
993 const char *msg = "You sense that a powerful threat has arrived.";
994 if (!(((you.num_turns + 1) / CYCLE_LENGTH) % FREQUENCY_OF_RUNES))
996 int which_rune = get_rune(((you.num_turns + 1) / CYCLE_LENGTH)
997 / FREQUENCY_OF_RUNES);
998 int ip = items(1, OBJ_MISCELLANY, MISC_RUNE_OF_ZOT, true,
999 which_rune, which_rune);
1000 int *const item_made = &ip;
1001 if (*item_made != NON_ITEM && *item_made != -1)
1003 move_item_to_grid(item_made, menv[mon].pos());
1004 msg = "You feel a sense of great excitement!";
1007 _zotdef_danger_msg(msg);
1011 if ((you.num_turns + 1) % CYCLE_LENGTH == CYCLE_INTERVAL)
1013 // Set the next wave
1014 zotdef_set_wave();