Apply the new ground_level method.
[crawl.git] / crawl-ref / source / zotdef.cc
blobf155254618c519aa2ccd9614c119ff2e0f793032
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 "files.h"
15 #include "ghost.h"
16 #include "items.h" // // for find_floor_item
17 #include "itemname.h" // // for make_name
18 #include "makeitem.h"
19 #include "message.h"
20 #include "mgen_data.h"
21 #include "mon-stuff.h"
22 #include "mon-place.h"
23 #include "mon-pick.h"
24 #include "mon-util.h"
25 #include "player.h"
26 #include "random.h"
27 #include "state.h"
28 #include "stuff.h"
29 #include "terrain.h"
30 #include "traps.h"
31 #include "libutil.h"
32 #include "zotdef.h"
34 // Size of the mons_alloc array (or at least the bit of
35 // it that we use).
36 #define NSLOTS (MAX_MONS_ALLOC - 1)
37 #define BOSS_SLOT NSLOTS
38 #define END static_cast<monster_type>(-1)
40 static monster_type _pick_unique(int level);
42 static int _fuzz_mons_level(int level)
44 if (level > 1 && one_chance_in(7))
46 const int fuzz = random2avg(9, 2);
47 return (fuzz > 4 ? level + fuzz - 4 : level);
49 return (level);
52 // Choose a random branch. Which branches may be chosen is a function of
53 // the wave number
54 static branch_type _zotdef_random_branch()
56 int wavenum = you.num_turns / CYCLE_LENGTH;
58 while (true)
60 branch_type pb = static_cast<branch_type>(random2(NUM_BRANCHES));
61 bool ok = true;
62 switch (pb)
64 case BRANCH_MAIN_DUNGEON:
65 ok = true;
66 // reduce freq at high levels
67 if (wavenum > 40)
68 ok = coinflip();
69 break;
71 case BRANCH_SNAKE_PIT:
72 ok = wavenum > 10;
73 // reduce freq at high levels
74 if (wavenum > 40 && !coinflip())
75 ok = false;
76 break;
78 default:
79 case BRANCH_ECUMENICAL_TEMPLE:
80 case BRANCH_VAULTS:
81 case BRANCH_VESTIBULE_OF_HELL:
82 ok = false;
83 break; // vaults/vestibule same as dungeon
85 case BRANCH_ORCISH_MINES:
86 ok = wavenum < 30; // <6K turns only
87 break;
88 case BRANCH_ELVEN_HALLS:
89 ok = wavenum > 10 && wavenum < 60; // 2.2-12K turns
90 break;
91 case BRANCH_LAIR:
92 ok = wavenum < 40; // <8K turns only
93 break;
94 case BRANCH_SWAMP:
95 ok = wavenum > 12 && wavenum < 40; // 2.6-8K turns
96 break;
97 case BRANCH_SHOALS:
98 ok = wavenum > 12 && wavenum < 60; // 2.6-12K turns
99 break;
100 case BRANCH_CRYPT:
101 ok = wavenum > 13; // 2.8K-
102 break;
103 case BRANCH_SLIME_PITS:
104 ok = wavenum > 20 && coinflip(); // 4K-
105 break; // >4K turns only
106 case BRANCH_HIVE:
107 ok = wavenum > 12 && wavenum < 35; // 2.6-7.5K
108 break;
109 case BRANCH_HALL_OF_BLADES:
110 ok = wavenum > 30; // 6K-
111 break;
112 case BRANCH_TOMB:
113 ok = wavenum > 30 && coinflip(); // 6K-
114 break;
115 case BRANCH_DIS: // 8K-
116 case BRANCH_COCYTUS:
117 case BRANCH_TARTARUS:
118 case BRANCH_GEHENNA:
119 ok = wavenum > 40 && one_chance_in(3);
120 break;
121 case BRANCH_HALL_OF_ZOT: // 10K-
122 ok = wavenum > 50;
123 break;
125 if (ok)
126 return (one_chance_in(4) ? BRANCH_MAIN_DUNGEON : pb);
127 // strong bias to main dungeon
131 static int _mon_strength(monster_type mon_type)
133 monsterentry *mentry = get_monster_data(mon_type);
134 if (!mentry)
135 return 0; // sanity
136 int strength = (mentry->hpdice[0] * mentry->exp_mod) / 10;
137 // Fix for skeletons and zombies
138 switch (mon_type)
140 case MONS_SKELETON_SMALL:
141 case MONS_ZOMBIE_SMALL:
142 strength += 3;
143 break;
144 case MONS_SKELETON_LARGE:
145 case MONS_ZOMBIE_LARGE:
146 strength += 4;
147 break;
148 case MONS_PANDEMONIUM_DEMON: // base init has 4HD (!)
149 strength = 30;
150 break;
151 default:
152 break;
154 return strength;
157 // Fill the wave list with selections from a supplied array.
158 // Each array contains a monster if random2(power)>chance. Power
159 // is also compared to the strength of each critter to allow later
160 // waves to be stronger than earlier ones.
162 // Note that this fills in the boss slot as well.
163 static void _zotdef_fill_from_list(monster_type mlist[], int chance, int power)
165 int ls = 0;
166 while (mlist[ls] != END)
167 ls++;
168 ASSERT(ls > 0);
170 for (int i = 0; i <= NSLOTS; i++)
172 env.mons_alloc[i] = MONS_PROGRAM_BUG;
173 if (i < NSLOTS && random2(power) < chance)
174 continue; // no monster this entry
175 while (env.mons_alloc[i] == MONS_PROGRAM_BUG)
177 monster_type mon_type = mlist[random2(ls)];
178 if (random2((power * 3) / 2) > _mon_strength(mon_type))
179 continue; // bias away from weaker critters
180 if (random2((power * 3) / 2) > _mon_strength(mon_type))
181 env.mons_alloc[i] = mon_type;
182 if (one_chance_in(100))
183 env.mons_alloc[i] = mon_type; // occasional random pick
188 // Choose a boss from the supplied list. If a unique is chosen and has
189 // already been seen we try again. After a few tries we give up and
190 // leave the existing entry there.
191 static void _zotdef_choose_boss(monster_type mlist[], int power)
193 int ls = 0;
194 while (mlist[ls] != END)
195 ls++;
196 ASSERT(ls > 0);
198 int tries = 0;
199 while (tries++ < 100)
201 monster_type mon_type = mlist[random2(ls)];
202 if (mons_is_unique(mon_type)
203 && you.unique_creatures[mon_type])
205 continue;
207 if (random2avg(power * 3, 2) < _mon_strength(mon_type))
208 continue;
210 // OK, take this one
211 env.mons_alloc[BOSS_SLOT] = mon_type;
212 break;
216 static void _zotdef_danger_msg(const char *msg)
218 mpr(msg, MSGCH_DANGER);
219 more();
222 static void wave_name(const char *n)
224 you.zotdef_wave_name = n;
225 dprf("%s", n);
228 static void _hydra_wave(int power)
230 wave_name("HYDRA WAVE");
231 monster_type hydras[] = {MONS_HYDRA, END};
232 monster_type boss[] = {MONS_LERNAEAN_HYDRA, END};
233 _zotdef_fill_from_list(hydras, 4, power); // 66% full at power 12
234 _zotdef_choose_boss(boss, power * 2);
235 _zotdef_danger_msg("You hear a distant many-voiced hissing!");
238 static void _fire_wave(int power)
240 wave_name("FIRE WAVE");
241 monster_type firemons[] = {MONS_FIRE_ELEMENTAL, MONS_FIRE_DRAKE, MONS_IMP,
242 MONS_DRAGON, MONS_FIRE_VORTEX ,MONS_FIRE_GIANT, MONS_HELLION,
243 MONS_MOLTEN_GARGOYLE, MONS_SALAMANDER, MONS_SUN_DEMON,
244 MONS_RED_DRACONIAN, MONS_MOTTLED_DRACONIAN, MONS_DRACONIAN_SCORCHER,
245 MONS_FLAMING_CORPSE, MONS_MOTTLED_DRAGON, MONS_EFREET,
246 MONS_HELL_KNIGHT, MONS_FIEND, MONS_BALRUG, MONS_HELL_HOUND,
247 MONS_HELL_HOG, END};
248 monster_type boss[] = {MONS_AZRAEL, MONS_XTAHUA, MONS_SERPENT_OF_HELL,
249 MONS_MARGERY, MONS_FIEND, MONS_BALRUG, MONS_FIRE_GIANT, END};
250 _zotdef_fill_from_list(firemons, 0, power);
251 _zotdef_choose_boss(boss, power);
252 _zotdef_danger_msg("You hear roaring flames in the distance!");
255 static void _cold_wave(int power)
257 wave_name("COLD WAVE");
258 monster_type coldmons[] = {MONS_ICE_BEAST, MONS_AZURE_JELLY,
259 MONS_FREEZING_WRAITH, MONS_WHITE_IMP, MONS_ICE_DEVIL, MONS_ICE_FIEND,
260 MONS_WHITE_DRACONIAN, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE,
261 MONS_FROST_GIANT, MONS_POLAR_BEAR, MONS_BLUE_DEVIL, END};
262 monster_type boss[] = {MONS_ANTAEUS, MONS_ICE_FIEND, MONS_AZURE_JELLY,
263 MONS_WHITE_DRACONIAN, END};
264 _zotdef_fill_from_list(coldmons, 4, power);
265 _zotdef_choose_boss(boss, power);
266 _zotdef_danger_msg("A deadly chill settles over the dungeon!");
269 static void _gnoll_wave(int power)
271 wave_name("GNOLL WAVE");
272 monster_type gnolls[] = {MONS_GNOLL, MONS_GNOLL, MONS_GNOLL,
273 MONS_GNOLL, MONS_GNOLL, MONS_GNOLL, MONS_TROLL, END};
274 monster_type boss[] = {MONS_GRUM, MONS_TROLL, END};
275 _zotdef_fill_from_list(gnolls, 0, power); // full
276 _zotdef_choose_boss(boss, power);
277 _zotdef_danger_msg("Harsh voices can be heard, coming closer!");
280 static void _rat_wave(int power)
282 wave_name("RAT WAVE");
283 monster_type rats[] = {MONS_RAT, MONS_GREEN_RAT, MONS_GREY_RAT,
284 MONS_ORANGE_RAT, END};
285 monster_type boss[] = {MONS_ORANGE_RAT, END};
286 _zotdef_fill_from_list(rats, 0, power); // full power
287 _zotdef_choose_boss(boss, power);
288 _zotdef_danger_msg("You hear distant squeaking!");
291 static void _hound_wave(int power)
293 wave_name("HOUND WAVE");
294 monster_type hounds[] = {MONS_JACKAL, MONS_HOUND, MONS_WARG,
295 MONS_WOLF, MONS_WAR_DOG, END};
296 monster_type boss[] = {MONS_HELL_HOUND, END};
297 _zotdef_fill_from_list(hounds, 0, power); // full
298 _zotdef_choose_boss(boss, power);
299 _zotdef_danger_msg("Horrible howls echo around!");
302 static void _abomination_wave(int power)
304 wave_name("ABOMINATION WAVE");
305 monster_type aboms[] = {MONS_ABOMINATION_SMALL, MONS_ABOMINATION_LARGE, END};
306 monster_type boss[] = {MONS_TENTACLED_MONSTROSITY, END};
307 _zotdef_fill_from_list(aboms, 0, power); // full
308 _zotdef_choose_boss(boss, power);
309 _zotdef_danger_msg("A dreadful chittering sound fills the air. It's coming closer...");
312 static void _ugly_wave(int power)
314 wave_name("UGLY WAVE");
315 monster_type ugly[] = {MONS_UGLY_THING, MONS_UGLY_THING, MONS_UGLY_THING,
316 MONS_VERY_UGLY_THING, END};
317 monster_type boss[] = {MONS_VERY_UGLY_THING, END};
318 _zotdef_fill_from_list(ugly, 6, power); // reduced size
319 _zotdef_choose_boss(boss, power);
320 _zotdef_danger_msg("You feel uneasy.");
323 static void _golem_wave(int power)
325 wave_name("GOLEM WAVE");
326 monster_type golems[] = {MONS_CLAY_GOLEM, MONS_WOOD_GOLEM, MONS_STONE_GOLEM,
327 MONS_IRON_GOLEM, MONS_CRYSTAL_GOLEM, MONS_TOENAIL_GOLEM, END};
328 monster_type boss[] = {MONS_ELECTRIC_GOLEM, END};
329 _zotdef_fill_from_list(golems, 6, power * 2 / 3); // reduced size
330 _zotdef_choose_boss(boss, power);
331 _zotdef_danger_msg("Booming thuds herald the arrival of something large...");
334 static void _human_wave(int power)
336 wave_name("HUMAN WAVE");
337 monster_type humans[] = {MONS_HUMAN, MONS_HELL_KNIGHT, MONS_NECROMANCER,
338 MONS_WIZARD, MONS_VAULT_GUARD, MONS_KILLER_KLOWN, END};
339 monster_type boss[] = {MONS_HELL_KNIGHT, MONS_KILLER_KLOWN,
340 MONS_VAULT_GUARD, MONS_JOSEPH, MONS_ERICA, MONS_JOSEPHINE,
341 MONS_HAROLD, MONS_JOZEF, MONS_AGNES,
342 MONS_MAUD, MONS_LOUISE, MONS_FRANCES,
343 MONS_RUPERT, MONS_KIRKE,
344 MONS_NORRIS, MONS_FREDERICK, MONS_MARGERY, MONS_EUSTACHIO,
345 MONS_MAURICE, END};
346 _zotdef_fill_from_list(humans, 4, power); // reduced size due to banding
348 // Get too many hell knights with the defaults, due to their large band
349 // size. Reduce here
350 for (int i = 0; i < NSLOTS; i++)
352 if (env.mons_alloc[i] == MONS_HELL_KNIGHT && random2(power) < 8)
353 env.mons_alloc[i] = MONS_PROGRAM_BUG;
356 _zotdef_choose_boss(boss, power);
357 _zotdef_danger_msg("War cries fill the air!");
360 static void _butterfly_wave(int power)
362 wave_name("BUTTERFLY WAVE");
363 monster_type bfs[] = {MONS_BUTTERFLY, END};
364 _zotdef_fill_from_list(bfs, 0, power); // full
365 _zotdef_danger_msg("You feel a sudden sense of peace!");
368 static void _beast_wave(int power)
370 wave_name("BEAST WAVE");
371 monster_type bst[] = {MONS_BEAST, END};
372 _zotdef_fill_from_list(bst, 0, power); // full
373 _zotdef_danger_msg("A hideous howling noise can be heard in the distance!");
376 static void _frog_wave(int power)
378 wave_name("FROG WAVE");
379 monster_type frogs[] = {MONS_GIANT_FROG, MONS_GIANT_TOAD,
380 MONS_SPINY_FROG, MONS_BLINK_FROG, END};
381 monster_type boss[] = {MONS_PRINCE_RIBBIT, MONS_SPINY_FROG, MONS_BLINK_FROG, END};
382 _zotdef_fill_from_list(frogs, 0, power); // full
383 _zotdef_choose_boss(boss, power);
384 _zotdef_danger_msg("Croaking noises echo off the walls!");
387 static void _bear_wave(int power)
389 wave_name("BEAR WAVE");
390 monster_type bears[] = {MONS_BEAR, MONS_GRIZZLY_BEAR, MONS_POLAR_BEAR,
391 MONS_BLACK_BEAR, END};
392 monster_type boss[] = {MONS_GRIZZLY_BEAR, MONS_POLAR_BEAR, END};
393 _zotdef_fill_from_list(bears, 0, power); // full
394 _zotdef_choose_boss(boss, power);
395 _zotdef_danger_msg("Gravelly voices can be heard calling for porridge!");
398 static void _wraith_wave(int power)
400 wave_name("WRAITH WAVE");
401 monster_type wraiths[] = {MONS_WRAITH, MONS_SHADOW_WRAITH, MONS_FREEZING_WRAITH,
402 MONS_EIDOLON, MONS_PHANTASMAL_WARRIOR, MONS_SPECTRAL_THING, END};
403 monster_type boss[] = {MONS_EIDOLON, MONS_PHANTASMAL_WARRIOR,
404 MONS_SPECTRAL_THING, END};
405 _zotdef_fill_from_list(wraiths, 0, power); // full
406 _zotdef_choose_boss(boss, power);
407 _zotdef_danger_msg("The hair rises on the back of your neck!");
410 static void _giant_wave(int power)
412 wave_name("GIANT WAVE");
413 monster_type giants[] = {MONS_ETTIN, MONS_CYCLOPS, MONS_TWO_HEADED_OGRE,
414 MONS_OGRE, MONS_TROLL, MONS_MINOTAUR, MONS_HILL_GIANT,
415 MONS_STONE_GIANT, MONS_FIRE_GIANT, MONS_FROST_GIANT, MONS_OGRE_MAGE,
416 MONS_ROCK_TROLL, MONS_IRON_TROLL, MONS_DEEP_TROLL, MONS_TITAN, END};
417 monster_type boss[] = {MONS_EROLCHA, MONS_POLYPHEMUS, MONS_ANTAEUS,
418 MONS_SNORG, MONS_PURGY, MONS_STONE_GIANT, MONS_FIRE_GIANT,
419 MONS_FROST_GIANT, MONS_TITAN, END};
420 _zotdef_fill_from_list(giants, 0, power); // full
421 _zotdef_choose_boss(boss, power);
422 _zotdef_danger_msg("The stamp of enormous boots can be heard in the distance.");
425 static void _yak_wave(int power)
427 wave_name("YAK WAVE");
428 monster_type yaks[] = {MONS_SHEEP, MONS_YAK, MONS_DEATH_YAK,
429 MONS_SHEEP, MONS_YAK, MONS_DEATH_YAK,
430 MONS_SHEEP, MONS_YAK, MONS_DEATH_YAK,
431 MONS_CYCLOPS, END};
432 monster_type boss[] = {MONS_POLYPHEMUS, MONS_CYCLOPS, END};
433 _zotdef_fill_from_list(yaks, 0, power); // full
434 _zotdef_choose_boss(boss, power);
435 _zotdef_danger_msg("Bleats and roars echo around!");
438 static void _insect_wave(int power)
440 wave_name("INSECT WAVE");
441 monster_type insects[] = {MONS_WORKER_ANT, MONS_KILLER_BEE, MONS_YELLOW_WASP,
442 MONS_GOLIATH_BEETLE, MONS_QUEEN_BEE, MONS_WOLF_SPIDER, MONS_BUTTERFLY,
443 MONS_BOULDER_BEETLE, MONS_GIANT_MITE, MONS_BUMBLEBEE, MONS_REDBACK,
444 MONS_VAMPIRE_MOSQUITO, MONS_RED_WASP, MONS_SOLDIER_ANT, MONS_QUEEN_ANT,
445 MONS_GIANT_COCKROACH, MONS_BORING_BEETLE, MONS_TRAPDOOR_SPIDER,
446 MONS_SCORPION, MONS_GIANT_CENTIPEDE, END};
447 monster_type boss[] = {MONS_GOLIATH_BEETLE, MONS_BOULDER_BEETLE,
448 MONS_QUEEN_ANT, MONS_BORING_BEETLE, MONS_QUEEN_BEE, END};
449 _zotdef_fill_from_list(insects, 0, power); // full
450 _zotdef_choose_boss(boss, power);
451 _zotdef_danger_msg("You hear an ominous buzzing.");
454 static void _pan_wave(int power)
456 wave_name("PAN WAVE");
457 // The unique '&'s are a bit too strong at lower levels. Lom
458 // Lobon in particular is almost unkillable
459 monster_type boss[] = {MONS_MNOLEG, MONS_LOM_LOBON, MONS_CEREBOV,
460 MONS_GLOORX_VLOQ, MONS_GERYON, MONS_DISPATER,
461 MONS_ASMODEUS, MONS_ERESHKIGAL, MONS_PANDEMONIUM_DEMON, END};
462 monster_type weakboss[] = {MONS_PANDEMONIUM_DEMON, MONS_FIEND,
463 MONS_PIT_FIEND, MONS_ICE_FIEND, MONS_BLUE_DEATH, END};
465 for (int i = 0; i <= NSLOTS; i++)
467 env.mons_alloc[i] = MONS_PROGRAM_BUG;
468 while (env.mons_alloc[i] == MONS_PROGRAM_BUG)
470 monster_type mon_type = static_cast<monster_type>(random2(NUM_MONSTERS));
471 monsterentry *mentry = get_monster_data(mon_type);
472 int pow = random2avg(power, 2);
473 switch (mentry->showchar)
475 case '5': if (pow > 4) continue; break;
476 case '4': if (pow > 4) continue; break;
477 case '3': if (pow > 6) continue; break;
478 case '2': if (pow > 10) continue; break;
479 case '1': if (pow > 12) continue; break;
480 default: continue;
482 env.mons_alloc[i] = mon_type;
485 // Weak bosses only at lower power
486 _zotdef_choose_boss((power < 27 ? weakboss : boss), power);
487 _zotdef_danger_msg("Hellish voices call for your blood. They are coming!");
490 static void _zotdef_set_special_wave(int power)
492 void (*wave_fn)(int) = NULL;
493 int tries = 0;
495 while (wave_fn == NULL && tries++ < 10000)
497 int wpow = 0;
498 switch (random2(21))
500 case 0: wave_fn = _hydra_wave; wpow = 10; break;
501 case 1: wave_fn = _fire_wave; wpow = 12; break;
502 case 2: wave_fn = _cold_wave; wpow = 12; break;
503 case 3: wave_fn = _gnoll_wave; wpow = 4; break;
504 case 4: wave_fn = _rat_wave; wpow = 2; break;
505 case 5: wave_fn = _hound_wave; wpow = 2; break;
506 case 6: wave_fn = _abomination_wave; wpow = 12; break;
507 case 7: wave_fn = _ugly_wave; wpow = 14; break;
508 case 8: wave_fn = _golem_wave; wpow = 22; break;
509 case 9: wave_fn = _human_wave; wpow = 12; break;
510 case 10: wave_fn = _butterfly_wave; wpow = 1; break;
511 case 11: wave_fn = _beast_wave; wpow = 12; break;
512 case 12: wave_fn = _frog_wave; wpow = 4; break;
513 case 13: wave_fn = _bear_wave; wpow = 6; break;
514 case 14: wave_fn = _wraith_wave; wpow = 8; break;
515 case 15: wave_fn = _giant_wave; wpow = 16; break;
516 case 16: wave_fn = _yak_wave; wpow = 12; break; // lots of bands
517 case 17: wave_fn = _insect_wave; wpow = 4; break;
518 case 18: wave_fn = _pan_wave; wpow = 24; break;
519 // extra copies of fire and cold at higher power
520 case 19: wave_fn = _fire_wave; wpow = 20; break;
521 case 20: wave_fn = _cold_wave; wpow = 20; break;
523 // Algorithm: doesn't appear before 'wpow-5'. Max probability
524 // at 'wpow'. Doesn't appear after 'wpow*2+4'.
525 // OK: do we keep this one?
526 if (power >= (wpow - 5) && power <= (wpow * 2 + 4))
528 int diff = power - wpow;
529 if (diff > 0)
530 diff /= 2; // weaker waves more common
531 if (one_chance_in(diff * diff))
532 break; // keep this one
534 // Nope, don't keep
535 wave_fn = NULL;
537 if (wave_fn)
538 wave_fn(power);
541 void debug_waves()
543 // Test more than just 15 runes, the player may stay longer, and if
544 // for some reason a rune is lost, he will have to, and get extra
545 // demonics.
546 for (int i = 0; i < 30 * FREQUENCY_OF_RUNES; i++)
548 you.num_turns += CYCLE_LENGTH;
549 zotdef_set_wave();
550 // debuglog("%i: %s\n", i, zotdef_debug_wave_desc().c_str());
554 static monster_type _get_zotdef_monster(level_id &place, int power)
556 monster_type mon_type;
557 monster_type mon_type_ret = MONS_PROGRAM_BUG;
558 for (int i = 0; i <= 10000; ++i)
560 int count = 0;
561 int rarity;
565 mon_type = static_cast<monster_type>(random2(NUM_MONSTERS));
566 count++;
567 rarity = (place.branch == NUM_BRANCHES) ? 30 : mons_rarity(mon_type, place);
569 while (rarity == 0 && count < 2000);
571 if (count == 2000)
572 return (MONS_PROGRAM_BUG);
574 // Calculate strength
575 monsterentry *mentry = get_monster_data(mon_type);
576 if (!mentry)
577 continue; // sanity
578 if (mentry == get_monster_data(MONS_PROGRAM_BUG))
579 continue; // sanity
580 if (mons_class_flag(mon_type, M_NO_POLY_TO))
581 continue;
582 if (mons_class_flag(mon_type, M_UNFINISHED))
583 continue;
584 if (mons_is_unique(mon_type))
585 continue; // No uniques here!
586 if (mons_class_is_stationary(mon_type))
587 continue; // Must be able to move!
589 int strength = _mon_strength(mon_type);
591 // get default level
592 int lev_mons = (place.branch == NUM_BRANCHES)
593 ? ((strength * 3) / 2)
594 : mons_level(mon_type, place);
596 // if >50, bail out - these are special flags
597 if (lev_mons >= 50)
598 continue;
600 //int orig_lev_mons = lev_mons;
602 // adjust level based on strength, as weak monsters with high
603 // level pop up on some branches and we want to allow them
604 if (place.branch != BRANCH_MAIN_DUNGEON
605 && lev_mons > power
606 && lev_mons > strength * 3)
608 lev_mons = (lev_mons + 2 * strength) / 3;
611 // reduce power to 32 if that reduces diff
612 if (lev_mons <= 32 && power > 32)
613 power = 32;
614 int diff = power - lev_mons;
615 if (power > 20)
616 diff = diff * 20 / power; // reduce diff at high power
618 int chance = rarity - (diff * diff);
619 // Occasionally accept a weaker monster
620 if (diff > 0 && chance <= 0)
622 chance = 1;
623 if (lev_mons > 20) chance = 3;
624 if (lev_mons > 25) chance = 5;
627 // Rarely accept monsters too far outside the power range
628 if ((diff <- 5 || diff > 5) && !one_chance_in(3))
629 continue;
631 // Less OOD allowed on early levels
632 if (diff < std::min(-3,-power))
633 continue;
635 const char *bn = "RANDOM";
636 if (place.branch != NUM_BRANCHES)
637 bn = branches[place.branch].shortname;
639 if (random2avg(100, 2) <= chance)
641 dprf("ZOTDEF %d %s chose monster %s rarity %d power %d strength %d "
642 "level %d chance %d", i, bn,mentry->name, rarity, power,
643 strength, lev_mons, chance);
644 mon_type_ret = mon_type;
645 break;
648 if (i == 10000)
649 return (MONS_PROGRAM_BUG);
652 return mon_type_ret;
655 static void _zotdef_set_random_branch_wave(int power)
657 wave_name("RANDOM WAVE");
658 for (int i = 0; i < NSLOTS; i++)
660 level_id l(_zotdef_random_branch(), -1);
661 env.mons_alloc[i] = _get_zotdef_monster(l, _fuzz_mons_level(power));
663 level_id l(_zotdef_random_branch(), -1);
664 env.mons_alloc[BOSS_SLOT] = _get_zotdef_monster(l,
665 power + BOSS_MONSTER_EXTRA_POWER);
668 static void _zotdef_set_branch_wave(branch_type b, int power)
670 level_id l(b,-1);
671 char buf[128];
672 snprintf(buf, sizeof(buf), "BRANCH WAVE: BRANCH %s",
673 (b == NUM_BRANCHES) ? "RANDOM" : branches[b].shortname);
674 wave_name(buf);
675 for (int i = 0; i < NSLOTS; i++)
676 env.mons_alloc[i] = _get_zotdef_monster(l, _fuzz_mons_level(power));
677 env.mons_alloc[BOSS_SLOT] = _get_zotdef_monster(l,
678 power + BOSS_MONSTER_EXTRA_POWER);
681 static void _zotdef_set_boss_unique()
683 for (int tries = 0; tries < 100; tries++)
685 int level = random2avg(you.num_turns / CYCLE_LENGTH, 2) + 1;
686 monster_type which_unique = _pick_unique(level);
688 // Sometimes, we just quit if a unique is already placed.
689 if (which_unique == MONS_PROGRAM_BUG
690 || you.unique_creatures[which_unique] && one_chance_in(5))
692 continue;
695 env.mons_alloc[BOSS_SLOT] = which_unique;
696 break;
700 // Set the env.mons_alloc data for this wave. Note that
701 // mons_alloc[BOSS_SLOT] is the boss.
703 // A game lasts for 15 runes, each rune 1400 turns apart
704 // (assuming FREQUENCY_OF_RUNES=7, CYCLE_LENGTH=200). That's
705 // a total of 105 waves. Set probabilities accordingly.
706 void zotdef_set_wave()
708 // power ramps up from 1 to 35 over the course of the game.
709 int power = (you.num_turns + CYCLE_LENGTH * 2) / (CYCLE_LENGTH * 3);
711 // Early waves are all DUNGEON
712 if (you.num_turns < CYCLE_LENGTH * 4)
714 _zotdef_set_branch_wave(BRANCH_MAIN_DUNGEON, power);
715 return;
718 switch (random2(5))
720 case 0:
721 case 1:
722 _zotdef_set_branch_wave(BRANCH_MAIN_DUNGEON, power);
723 break;
724 case 2:
725 case 3:
727 branch_type b = _zotdef_random_branch();
728 // HoB branch waves v. rare before 10K turns
729 if (b == BRANCH_HALL_OF_BLADES && you.num_turns / CYCLE_LENGTH < 50)
730 b = _zotdef_random_branch();
731 _zotdef_set_branch_wave(b, power);
732 break;
734 // A random mixture of monsters from across the branches
735 case 4:
736 _zotdef_set_random_branch_wave(power);
737 break;
740 // special waves have their own boss choices. Note that flavour
741 // messages can be emitted by each individual wave type
742 if (one_chance_in(8))
743 _zotdef_set_special_wave(power);
744 else
746 // Truly random wave, (crappily) signalled by passing branch=NUM_BRANCHES
747 if (power > 8 && one_chance_in(20))
749 _zotdef_danger_msg("The air ripples, and you hear distant laughter!");
750 _zotdef_set_branch_wave(NUM_BRANCHES, power);
753 // overwrite the previously-set boss with a random unique?
754 if (one_chance_in(3))
755 _zotdef_set_boss_unique();
758 dprf("NEW WAVE: %s", zotdef_debug_wave_desc().c_str());
761 std::string zotdef_debug_wave_desc()
763 std::string list = you.zotdef_wave_name + " [";
764 for (int i = 0; i <= NSLOTS; i++)
766 if (i)
767 list += ", ";
768 monsterentry *mentry = get_monster_data(env.mons_alloc[i]);
769 if (!env.mons_alloc[i])
770 list += "EMPTY";
771 else if (mentry)
772 list += mentry->name;
773 else
774 list += make_stringf("!!!INVALID (%d)!!!", env.mons_alloc[i]);
776 return list + "]";
779 int zotdef_spawn(bool boss)
781 monster_type mt = env.mons_alloc[random2(NSLOTS)];
782 if (boss)
784 mt = env.mons_alloc[BOSS_SLOT];
785 // check if unique
786 if (mons_is_unique(mt) && you.unique_creatures[mt])
787 mt = env.mons_alloc[0]; // grab slot 0 as crap alternative
789 if (mt == MONS_PROGRAM_BUG)
790 return -1;
792 // Generate a monster of the appropriate branch and strength
793 mgen_data mg(mt, BEH_SEEK, NULL, 0, 0, coord_def(), MHITYOU);
794 mg.proximity = PROX_NEAR_STAIRS;
795 mg.flags |= MG_PERMIT_BANDS;
797 int mid = mons_place(mg);
799 // Boss monsters which aren't uniques are named, and beefed a bit further
800 if (mid != -1 && boss && !mons_is_unique(mt))
802 // Use the proper name function: if that fails, fall back
803 // to the randart name generator
804 if (!menv[mid].is_named()) // Don't rename uniques!
806 if (!give_monster_proper_name(&menv[mid], false))
807 menv[mid].mname = make_name(random_int(), false);
810 menv[mid].hit_points = (menv[mid].hit_points * 3) / 2;
811 menv[mid].max_hit_points = menv[mid].hit_points;
814 return mid;
817 static rune_type _get_rune(int runenumber)
819 switch (runenumber)
821 case 1:
822 return RUNE_DIS;
823 case 2:
824 return RUNE_GEHENNA;
825 case 3:
826 return RUNE_COCYTUS;
827 case 4:
828 return RUNE_TARTARUS;
829 case 5:
830 return RUNE_SLIME_PITS;
831 case 6:
832 return RUNE_VAULTS;
833 case 7:
834 return RUNE_SNAKE_PIT;
835 case 8:
836 return RUNE_TOMB;
837 case 9:
838 return RUNE_SWAMP;
839 case 10:
840 return RUNE_SHOALS;
841 case 11:
842 return RUNE_ABYSSAL;
843 case 12:
844 return RUNE_MNOLEG;
845 case 13:
846 return RUNE_LOM_LOBON;
847 case 14:
848 return RUNE_CEREBOV;
849 case 15:
850 return RUNE_GLOORX_VLOQ;
851 default:
852 return RUNE_DEMONIC;
856 // Dowan is automatically placed together with Duvessa.
857 static monster_type _choose_unique_by_depth(int step)
859 int ret;
860 switch (step)
862 case 0: // depth <= 3
863 ret = random_choose(MONS_TERENCE, MONS_JESSICA, MONS_IJYB,
864 MONS_SIGMUND, -1);
865 break;
866 case 1: // depth <= 7
867 ret = random_choose(MONS_IJYB, MONS_SIGMUND, MONS_BLORK_THE_ORC,
868 MONS_EDMUND, MONS_PRINCE_RIBBIT, MONS_PURGY,
869 MONS_MENKAURE, MONS_DUVESSA, MONS_PIKEL, -1);
870 break;
871 case 2: // depth <= 9
872 ret = random_choose(MONS_BLORK_THE_ORC, MONS_EDMUND, MONS_PSYCHE, MONS_JOSEPH,
873 MONS_EROLCHA, MONS_PRINCE_RIBBIT, MONS_GRUM,
874 MONS_GASTRONOK, MONS_GRINDER, MONS_MAURICE,
875 MONS_PIKEL, -1);
876 break;
877 case 3: // depth <= 13
878 ret = random_choose(MONS_PSYCHE, MONS_EROLCHA, MONS_DONALD, MONS_URUG,
879 MONS_EUSTACHIO, MONS_SONJA, MONS_GRUM, MONS_NIKOLA,
880 MONS_ERICA, MONS_JOSEPHINE, MONS_JOZEF,
881 MONS_HAROLD, MONS_GASTRONOK, MONS_ILSUIW,
882 MONS_MAURICE, -1);
883 break;
884 case 4: // depth <= 16
885 ret = random_choose(MONS_URUG, MONS_EUSTACHIO, MONS_SONJA,
886 MONS_SNORG, MONS_ERICA, MONS_JOSEPHINE, MONS_HAROLD,
887 MONS_ROXANNE, MONS_RUPERT, MONS_JOZEF, MONS_NIKOLA,
888 MONS_AZRAEL, MONS_NESSOS, MONS_AGNES, MONS_AIZUL,
889 MONS_MAUD, MONS_LOUISE, MONS_NERGALLE, MONS_KIRKE, -1);
890 break;
891 case 5: // depth <= 19
892 ret = random_choose(MONS_SNORG, MONS_LOUISE, MONS_FRANCES, MONS_KHUFU,
893 MONS_RUPERT, MONS_NORRIS, MONS_AGNES,
894 MONS_AZRAEL, MONS_NESSOS, MONS_NERGALLE,
895 MONS_ROXANNE, MONS_SAINT_ROKA, MONS_KIRKE,
896 MONS_WIGLAF, -1);
897 break;
898 case 6: // depth > 19
899 default:
900 ret = random_choose(MONS_FRANCES, MONS_MARA, MONS_WIGLAF, MONS_MENNAS,
901 MONS_XTAHUA, MONS_NORRIS, MONS_FREDERICK, MONS_TIAMAT,
902 MONS_MARGERY, MONS_BORIS, MONS_SAINT_ROKA, -1);
905 return static_cast<monster_type>(ret);
908 static monster_type _pick_unique(int level)
910 // Pick generic unique depending on depth.
911 int which_unique =
912 ((level <= 3) ? _choose_unique_by_depth(0) :
913 (level <= 7) ? _choose_unique_by_depth(1) :
914 (level <= 9) ? _choose_unique_by_depth(2) :
915 (level <= 13) ? _choose_unique_by_depth(3) :
916 (level <= 16) ? _choose_unique_by_depth(4) :
917 (level <= 19) ? _choose_unique_by_depth(5) :
918 _choose_unique_by_depth(6));
920 return static_cast<monster_type>(which_unique);
923 // Ask for a location and place a trap there. Returns true
924 // for success
925 bool create_trap(trap_type spec_type)
927 dist abild;
928 direction_chooser_args args;
929 args.restricts = DIR_TARGET;
930 args.needs_path = false;
931 args.may_target_monster = false;
932 args.top_prompt = "Make ";
933 args.top_prompt += trap_name(spec_type);
934 args.top_prompt += " trap where?";
935 direction(abild, args);
936 const dungeon_feature_type grid = grd(abild.target);
937 if (!abild.isValid)
939 if (abild.isCancel)
940 canned_msg(MSG_OK);
941 return (false);
943 // only try to create on floor squares
944 if (!feat_is_floor(grid))
946 mpr("You can't create a trap there!");
947 return (false);
949 bool result = place_specific_trap(abild.target, spec_type);
951 if (result)
952 grd(abild.target) = env.trap[env.tgrid(abild.target)].category();
954 return result;
957 bool create_zotdef_ally(monster_type mtyp, const char *successmsg)
959 if (count_allies() > MAX_MONSTERS / 2)
961 mpr("The place is too crowded already!");
962 return false;
965 dist abild;
966 std::string msg = "Make ";
967 msg += get_monster_data(mtyp)->name;
968 msg += " where?";
970 direction_chooser_args args;
971 args.restricts = DIR_TARGET;
972 args.needs_path = false;
973 args.may_target_monster = false;
974 args.top_prompt = msg;
975 direction(abild, args);
977 if (!abild.isValid)
979 if (abild.isCancel)
980 canned_msg(MSG_OK);
981 return (false);
983 if (mons_place(mgen_data(mtyp, BEH_FRIENDLY, &you, 0, 0, abild.target,
984 you.pet_target)) == -1)
986 mpr("You can't create it there!");
987 return (false);
989 mpr(successmsg);
990 return (true);
993 void zotdef_bosses_check()
995 if ((you.num_turns + 1) % CYCLE_LENGTH == 0)
997 int mon = zotdef_spawn(true); // boss monster=true
999 if (mon > -1)
1001 const char *msg = "You sense that a powerful threat has arrived.";
1002 if (!(((you.num_turns + 1) / CYCLE_LENGTH) % FREQUENCY_OF_RUNES))
1004 const rune_type which_rune =
1005 _get_rune(((you.num_turns + 1) / CYCLE_LENGTH)
1006 / FREQUENCY_OF_RUNES);
1007 int ip = items(1, OBJ_MISCELLANY, MISC_RUNE_OF_ZOT, true,
1008 which_rune, which_rune);
1009 int *const item_made = &ip;
1010 if (*item_made != NON_ITEM && *item_made != -1)
1012 mitm[ip].plus = which_rune;
1013 move_item_to_grid(item_made, menv[mon].pos());
1014 msg = "You feel a sense of great excitement!";
1017 _zotdef_danger_msg(msg);
1020 // since you don't move between maps, any crash would be fatal
1021 save_game(false);
1024 if ((you.num_turns + 1) % CYCLE_LENGTH == CYCLE_INTERVAL)
1026 // Set the next wave
1027 zotdef_set_wave();