1 | /* SCCS Id: @(#)makemon.c 3.3 2000/06/02 */
2 | /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 | /* NetHack may be freely redistributed. See license for details. */
4 |
5 | #include "hack.h"
6 | #include "epri.h"
7 | #include "emin.h"
8 | #include "edog.h"
9 | #ifdef REINCARNATION
10 | #include <ctype.h>
11 | #endif
12 |
13 | STATIC_VAR NEARDATA struct monst zeromonst;
14 |
15 | #ifdef OVL0
16 | STATIC_DCL boolean FDECL(uncommon, (int));
17 | STATIC_DCL int FDECL(align_shift, (struct permonst *));
18 | #endif /* OVL0 */
19 | STATIC_DCL boolean FDECL(wrong_elem_type, (struct permonst *));
20 | STATIC_DCL void FDECL(m_initgrp,(struct monst *,int,int,int));
21 | STATIC_DCL void FDECL(m_initthrow,(struct monst *,int,int));
22 | STATIC_DCL void FDECL(m_initweap,(struct monst *));
23 | #ifdef OVL1
24 | STATIC_DCL void FDECL(m_initinv,(struct monst *));
25 | #endif /* OVL1 */
26 |
27 | extern const int monstr[];
28 |
29 | #define m_initsgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 3)
30 | #define m_initlgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 10)
31 | #define toostrong(monindx, lev) (monstr[monindx] > lev)
32 | #define tooweak(monindx, lev) (monstr[monindx] < lev)
33 |
34 | #ifdef OVLB
35 | boolean
36 | is_home_elemental(ptr)
37 | register struct permonst *ptr;
38 | {
39 | if (ptr->mlet == S_ELEMENTAL)
40 | switch (monsndx(ptr)) {
41 | case PM_AIR_ELEMENTAL: return Is_airlevel(&u.uz);
42 | case PM_FIRE_ELEMENTAL: return Is_firelevel(&u.uz);
43 | case PM_EARTH_ELEMENTAL: return Is_earthlevel(&u.uz);
44 | case PM_WATER_ELEMENTAL: return Is_waterlevel(&u.uz);
45 | }
46 | return FALSE;
47 | }
48 |
49 | /*
50 | * Return true if the given monster cannot exist on this elemental level.
51 | */
52 | STATIC_OVL boolean
53 | wrong_elem_type(ptr)
54 | register struct permonst *ptr;
55 | {
56 | if (ptr->mlet == S_ELEMENTAL) {
57 | return((boolean)(!is_home_elemental(ptr)));
58 | } else if (Is_earthlevel(&u.uz)) {
59 | /* no restrictions? */
60 | } else if (Is_waterlevel(&u.uz)) {
61 | /* just monsters that can swim */
62 | if(!is_swimmer(ptr)) return TRUE;
63 | } else if (Is_firelevel(&u.uz)) {
64 | if (!pm_resistance(ptr,MR_FIRE)) return TRUE;
65 | } else if (Is_airlevel(&u.uz)) {
66 | if(!(is_flyer(ptr) && ptr->mlet != S_TRAPPER) && !is_floater(ptr)
67 | && !amorphous(ptr) && !noncorporeal(ptr) && !is_whirly(ptr))
68 | return TRUE;
69 | }
70 | return FALSE;
71 | }
72 |
73 | STATIC_OVL void
74 | m_initgrp(mtmp, x, y, n) /* make a group just like mtmp */
75 | register struct monst *mtmp;
76 | register int x, y, n;
77 | {
78 | coord mm;
79 | register int cnt = rnd(n);
80 | struct monst *mon;
81 | #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX))
82 | /* There is an unresolved problem with several people finding that
83 | * the game hangs eating CPU; if interrupted and restored, the level
84 | * will be filled with monsters. Of those reports giving system type,
85 | * there were two DG/UX and two HP-UX, all using gcc as the compiler.
86 | * hcroft@hpopb1.cern.ch, using gcc 2.6.3 on HP-UX, says that the
87 | * problem went away for him and another reporter-to-newsgroup
88 | * after adding this debugging code. This has almost got to be a
89 | * compiler bug, but until somebody tracks it down and gets it fixed,
90 | * might as well go with the "but it went away when I tried to find
91 | * it" code.
92 | */
93 | int cnttmp,cntdiv;
94 |
95 | cnttmp = cnt;
96 | # ifdef DEBUG
97 | pline("init group call x=%d,y=%d,n=%d,cnt=%d.", x, y, n, cnt);
98 | # endif
99 | cntdiv = ((u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1);
100 | #endif
101 | /* Tuning: cut down on swarming at low character levels [mrs] */
102 | cnt /= (u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1;
103 | #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX))
104 | if (cnt != (cnttmp/cntdiv)) {
105 | pline("cnt=%d using %d, cnttmp=%d, cntdiv=%d", cnt,
106 | (u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1,
107 | cnttmp, cntdiv);
108 | }
109 | #endif
110 | if(!cnt) cnt++;
111 | #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX))
112 | if (cnt < 0) cnt = 1;
113 | if (cnt > 10) cnt = 10;
114 | #endif
115 |
116 | mm.x = x;
117 | mm.y = y;
118 | while(cnt--) {
119 | if (peace_minded(mtmp->data)) continue;
120 | /* Don't create groups of peaceful monsters since they'll get
121 | * in our way. If the monster has a percentage chance so some
122 | * are peaceful and some are not, the result will just be a
123 | * smaller group.
124 | */
125 | if (enexto(&mm, mm.x, mm.y, mtmp->data)) {
126 | mon = makemon(mtmp->data, mm.x, mm.y, NO_MM_FLAGS);
127 | mon->mpeaceful = FALSE;
128 | set_malign(mon);
129 | /* Undo the second peace_minded() check in makemon(); if the
130 | * monster turned out to be peaceful the first time we
131 | * didn't create it at all; we don't want a second check.
132 | */
133 | }
134 | }
135 | }
136 |
137 | STATIC_OVL
138 | void
139 | m_initthrow(mtmp,otyp,oquan)
140 | struct monst *mtmp;
141 | int otyp,oquan;
142 | {
143 | register struct obj *otmp;
144 |
145 | otmp = mksobj(otyp, TRUE, FALSE);
146 | otmp->quan = (long) rn1(oquan, 3);
147 | otmp->owt = weight(otmp);
148 | if (otyp == ORCISH_ARROW) otmp->opoisoned = TRUE;
149 | (void) mpickobj(mtmp, otmp);
150 | }
151 |
152 | #endif /* OVLB */
153 | #ifdef OVL2
154 |
155 | STATIC_OVL void
156 | m_initweap(mtmp)
157 | register struct monst *mtmp;
158 | {
159 | register struct permonst *ptr = mtmp->data;
160 | register int mm = monsndx(ptr);
161 | struct obj *otmp;
162 |
163 | #ifdef REINCARNATION
164 | if (Is_rogue_level(&u.uz)) return;
165 | #endif
166 | /*
167 | * first a few special cases:
168 | *
169 | * giants get a boulder to throw sometimes.
170 | * ettins get clubs
171 | * kobolds get darts to throw
172 | * centaurs get some sort of bow & arrows or bolts
173 | * soldiers get all sorts of things.
174 | * kops get clubs & cream pies.
175 | */
176 | switch (ptr->mlet) {
177 | case S_GIANT:
178 | if (rn2(2)) (void)mongets(mtmp, (mm != PM_ETTIN) ?
179 | BOULDER : CLUB);
180 | break;
181 | case S_HUMAN:
182 | if(is_mercenary(ptr)) {
183 | int w1 = 0, w2 = 0;
184 | switch (mm) {
185 |
186 | case PM_WATCHMAN:
187 | case PM_SOLDIER:
188 | if (!rn2(3)) {
189 | w1 = rn1(BEC_DE_CORBIN - PARTISAN + 1, PARTISAN);
190 | w2 = rn2(2) ? DAGGER : KNIFE;
191 | } else w1 = rn2(2) ? SPEAR : SHORT_SWORD;
192 | break;
193 | case PM_SERGEANT:
194 | w1 = rn2(2) ? FLAIL : MACE;
195 | break;
196 | case PM_LIEUTENANT:
197 | w1 = rn2(2) ? BROADSWORD : LONG_SWORD;
198 | break;
199 | case PM_CAPTAIN:
200 | case PM_WATCH_CAPTAIN:
201 | w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
202 | break;
203 | default:
204 | if (!rn2(4)) w1 = DAGGER;
205 | if (!rn2(7)) w2 = SPEAR;
206 | break;
207 | }
208 | if (w1) (void)mongets(mtmp, w1);
209 | if (!w2 && w1 != DAGGER && !rn2(4)) w2 = KNIFE;
210 | if (w2) (void)mongets(mtmp, w2);
211 | } else if (is_elf(ptr)) {
212 | if (rn2(2))
213 | (void) mongets(mtmp,
214 | rn2(2) ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
215 | if (rn2(2)) (void)mongets(mtmp, ELVEN_LEATHER_HELM);
216 | else if (!rn2(4)) (void)mongets(mtmp, ELVEN_BOOTS);
217 | if (rn2(2)) (void)mongets(mtmp, ELVEN_DAGGER);
218 | switch (rn2(3)) {
219 | case 0:
220 | if (!rn2(4)) (void)mongets(mtmp, ELVEN_SHIELD);
221 | if (rn2(3)) (void)mongets(mtmp, ELVEN_SHORT_SWORD);
222 | (void)mongets(mtmp, ELVEN_BOW);
223 | m_initthrow(mtmp, ELVEN_ARROW, 12);
224 | break;
225 | case 1:
226 | (void)mongets(mtmp, ELVEN_BROADSWORD);
227 | if (rn2(2)) (void)mongets(mtmp, ELVEN_SHIELD);
228 | break;
229 | case 2:
230 | if (rn2(2)) {
231 | (void)mongets(mtmp, ELVEN_SPEAR);
232 | (void)mongets(mtmp, ELVEN_SHIELD);
233 | }
234 | break;
235 | }
236 | if (mm == PM_ELVENKING) {
237 | if (rn2(3) || (in_mklev && Is_earthlevel(&u.uz)))
238 | (void)mongets(mtmp, PICK_AXE);
239 | if (!rn2(50)) (void)mongets(mtmp, CRYSTAL_BALL);
240 | }
241 | } else if (ptr->msound == MS_PRIEST) {
242 | otmp = mksobj(MACE, FALSE, FALSE);
243 | if(otmp) {
244 | otmp->spe = rnd(3);
245 | if(!rn2(2)) curse(otmp);
246 | (void) mpickobj(mtmp, otmp);
247 | }
248 | }
249 | break;
250 |
251 | case S_ANGEL:
252 | {
253 | int spe2;
254 |
255 | /* create minion stuff; can't use mongets */
256 | otmp = mksobj(LONG_SWORD, FALSE, FALSE);
257 |
258 | /* maybe make it special */
259 | if (!rn2(20) || is_lord(ptr))
260 | otmp = oname(otmp, artiname(
261 | rn2(2) ? ART_DEMONBANE : ART_SUNSWORD));
262 | bless(otmp);
263 | otmp->oerodeproof = TRUE;
264 | spe2 = rn2(4);
265 | otmp->spe = max(otmp->spe, spe2);
266 | (void) mpickobj(mtmp, otmp);
267 |
268 | otmp = mksobj(!rn2(4) || is_lord(ptr) ?
269 | SHIELD_OF_REFLECTION : LARGE_SHIELD,
270 | FALSE, FALSE);
271 | otmp->cursed = FALSE;
272 | otmp->oerodeproof = TRUE;
273 | otmp->spe = 0;
274 | (void) mpickobj(mtmp, otmp);
275 | }
276 | break;
277 |
278 | case S_HUMANOID:
279 | if (mm == PM_HOBBIT) {
280 | switch (rn2(3)) {
281 | case 0:
282 | (void)mongets(mtmp, DAGGER);
283 | break;
284 | case 1:
285 | (void)mongets(mtmp, ELVEN_DAGGER);
286 | break;
287 | case 2:
288 | (void)mongets(mtmp, SLING);
289 | break;
290 | }
291 | if (!rn2(10)) (void)mongets(mtmp, ELVEN_MITHRIL_COAT);
292 | if (!rn2(10)) (void)mongets(mtmp, DWARVISH_CLOAK);
293 | } else if (is_dwarf(ptr)) {
294 | if (rn2(7)) (void)mongets(mtmp, DWARVISH_CLOAK);
295 | if (rn2(7)) (void)mongets(mtmp, IRON_SHOES);
296 | if (!rn2(4)) {
297 | (void)mongets(mtmp, DWARVISH_SHORT_SWORD);
298 | /* note: you can't use a mattock with a shield */
299 | if (rn2(2)) (void)mongets(mtmp, DWARVISH_MATTOCK);
300 | else {
301 | (void)mongets(mtmp, AXE);
302 | (void)mongets(mtmp, DWARVISH_ROUNDSHIELD);
303 | }
304 | (void)mongets(mtmp, DWARVISH_IRON_HELM);
305 | if (!rn2(3))
306 | (void)mongets(mtmp, DWARVISH_MITHRIL_COAT);
307 | } else {
308 | (void)mongets(mtmp, !rn2(3) ? PICK_AXE : DAGGER);
309 | }
310 | }
311 | break;
312 | # ifdef KOPS
313 | case S_KOP: /* create Keystone Kops with cream pies to
314 | * throw. As suggested by KAA. [MRS]
315 | */
316 | if (!rn2(4)) m_initthrow(mtmp, CREAM_PIE, 2);
317 | if (!rn2(3)) (void)mongets(mtmp,(rn2(2)) ? CLUB : RUBBER_HOSE);
318 | break;
319 | # endif
320 | case S_ORC:
321 | if(rn2(2)) (void)mongets(mtmp, ORCISH_HELM);
322 | switch (mm != PM_ORC_CAPTAIN ? mm :
323 | rn2(2) ? PM_MORDOR_ORC : PM_URUK_HAI) {
324 | case PM_MORDOR_ORC:
325 | if(!rn2(3)) (void)mongets(mtmp, SCIMITAR);
326 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_SHIELD);
327 | if(!rn2(3)) (void)mongets(mtmp, KNIFE);
328 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_CHAIN_MAIL);
329 | break;
330 | case PM_URUK_HAI:
331 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_CLOAK);
332 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_SHORT_SWORD);
333 | if(!rn2(3)) (void)mongets(mtmp, IRON_SHOES);
334 | if(!rn2(3)) {
335 | (void)mongets(mtmp, ORCISH_BOW);
336 | m_initthrow(mtmp, ORCISH_ARROW, 12);
337 | }
338 | if(!rn2(3)) (void)mongets(mtmp, URUK_HAI_SHIELD);
339 | break;
340 | default:
341 | if (mm != PM_ORC_SHAMAN && rn2(2))
342 | (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0)
343 | ? ORCISH_DAGGER : SCIMITAR);
344 | }
345 | break;
346 | case S_OGRE:
347 | if (!rn2(mm == PM_OGRE_KING ? 3 : mm == PM_OGRE_LORD ? 6 : 12))
348 | (void) mongets(mtmp, BATTLE_AXE);
349 | else
350 | (void) mongets(mtmp, CLUB);
351 | break;
352 | case S_TROLL:
353 | if (!rn2(2)) switch (rn2(4)) {
354 | case 0: (void)mongets(mtmp, RANSEUR); break;
355 | case 1: (void)mongets(mtmp, PARTISAN); break;
356 | case 2: (void)mongets(mtmp, GLAIVE); break;
357 | case 3: (void)mongets(mtmp, SPETUM); break;
358 | }
359 | break;
360 | case S_KOBOLD:
361 | if (!rn2(4)) m_initthrow(mtmp, DART, 12);
362 | break;
363 |
364 | case S_CENTAUR:
365 | if (rn2(2)) {
366 | if(ptr == &mons[PM_FOREST_CENTAUR]) {
367 | (void)mongets(mtmp, BOW);
368 | m_initthrow(mtmp, ARROW, 12);
369 | } else {
370 | (void)mongets(mtmp, CROSSBOW);
371 | m_initthrow(mtmp, CROSSBOW_BOLT, 12);
372 | }
373 | }
374 | break;
375 | case S_WRAITH:
376 | (void)mongets(mtmp, KNIFE);
377 | (void)mongets(mtmp, LONG_SWORD);
378 | break;
379 | case S_ZOMBIE:
380 | if (!rn2(4)) (void)mongets(mtmp, LEATHER_ARMOR);
381 | if (!rn2(4))
382 | (void)mongets(mtmp, (rn2(3) ? KNIFE : SHORT_SWORD));
383 | break;
384 | case S_LIZARD:
385 | if (mm == PM_SALAMANDER)
386 | (void)mongets(mtmp, (rn2(7) ? SPEAR : rn2(3) ?
387 | TRIDENT : STILETTO));
388 | break;
389 | case S_DEMON:
390 | switch (mm) {
391 | case PM_BALROG:
392 | (void)mongets(mtmp, BULLWHIP);
393 | (void)mongets(mtmp, BROADSWORD);
394 | break;
395 | case PM_ORCUS:
396 | (void)mongets(mtmp, WAN_DEATH); /* the Wand of Orcus */
397 | break;
398 | case PM_HORNED_DEVIL:
399 | (void)mongets(mtmp, rn2(4) ? TRIDENT : BULLWHIP);
400 | break;
401 | case PM_ICE_DEVIL:
402 | if (!rn2(4)) (void)mongets(mtmp, SPEAR);
403 | break;
404 | case PM_ASMODEUS:
405 | (void)mongets(mtmp, WAN_COLD);
406 | (void)mongets(mtmp, WAN_FIRE);
407 | break;
408 | case PM_DISPATER:
409 | (void)mongets(mtmp, WAN_STRIKING);
410 | break;
411 | case PM_YEENOGHU:
412 | (void)mongets(mtmp, FLAIL);
413 | break;
414 | }
415 | /* prevent djinnis and mail daemons from leaving objects when
416 | * they vanish
417 | */
418 | if (!is_demon(ptr)) break;
419 | /* fall thru */
420 | /*
421 | * Now the general case, Some chance of getting some type
422 | * of weapon for "normal" monsters. Certain special types
423 | * of monsters will get a bonus chance or different selections.
424 | */
425 | default:
426 | {
427 | int bias;
428 |
429 | bias = is_lord(ptr) + is_prince(ptr) * 2 + extra_nasty(ptr);
430 | switch(rnd(14 - (2 * bias))) {
431 | case 1:
432 | if(strongmonst(ptr)) (void) mongets(mtmp, BATTLE_AXE);
433 | else m_initthrow(mtmp, DART, 12);
434 | break;
435 | case 2:
436 | if(strongmonst(ptr))
437 | (void) mongets(mtmp, TWO_HANDED_SWORD);
438 | else {
439 | (void) mongets(mtmp, CROSSBOW);
440 | m_initthrow(mtmp, CROSSBOW_BOLT, 12);
441 | }
442 | break;
443 | case 3:
444 | (void) mongets(mtmp, BOW);
445 | m_initthrow(mtmp, ARROW, 12);
446 | break;
447 | case 4:
448 | if(strongmonst(ptr)) (void) mongets(mtmp, LONG_SWORD);
449 | else m_initthrow(mtmp, DAGGER, 3);
450 | break;
451 | case 5:
452 | if(strongmonst(ptr))
453 | (void) mongets(mtmp, LUCERN_HAMMER);
454 | else (void) mongets(mtmp, AKLYS);
455 | break;
456 | default:
457 | break;
458 | }
459 | }
460 | break;
461 | }
462 | if ((int) mtmp->m_lev > rn2(75))
463 | (void) mongets(mtmp, rnd_offensive_item(mtmp));
464 | }
465 |
466 | #endif /* OVL2 */
467 | #ifdef OVL1
468 |
469 | STATIC_OVL void
470 | m_initinv(mtmp)
471 | register struct monst *mtmp;
472 | {
473 | register int cnt;
474 | register struct obj *otmp;
475 | register struct permonst *ptr = mtmp->data;
476 | #ifdef REINCARNATION
477 | if (Is_rogue_level(&u.uz)) return;
478 | #endif
479 | /*
480 | * Soldiers get armour & rations - armour approximates their ac.
481 | * Nymphs may get mirror or potion of object detection.
482 | */
483 | switch(ptr->mlet) {
484 |
485 | case S_HUMAN:
486 | if(is_mercenary(ptr)) {
487 | register int mac;
488 |
489 | switch(monsndx(ptr)) {
490 | case PM_GUARD: mac = -1; break;
491 | case PM_SOLDIER: mac = 3; break;
492 | case PM_SERGEANT: mac = 0; break;
493 | case PM_LIEUTENANT: mac = -2; break;
494 | case PM_CAPTAIN: mac = -3; break;
495 | case PM_WATCHMAN: mac = 3; break;
496 | case PM_WATCH_CAPTAIN: mac = -2; break;
497 | default: impossible("odd mercenary %d?", monsndx(ptr));
498 | mac = 0;
499 | break;
500 | }
501 |
502 | if (mac < -1 && rn2(5))
503 | mac += 7 + mongets(mtmp, (rn2(5)) ?
504 | PLATE_MAIL : CRYSTAL_PLATE_MAIL);
505 | else if (mac < 3 && rn2(5))
506 | mac += 6 + mongets(mtmp, (rn2(3)) ?
507 | SPLINT_MAIL : BANDED_MAIL);
508 | else if (rn2(5))
509 | mac += 3 + mongets(mtmp, (rn2(3)) ?
510 | RING_MAIL : STUDDED_LEATHER_ARMOR);
511 | else
512 | mac += 2 + mongets(mtmp, LEATHER_ARMOR);
513 |
514 | if (mac < 10 && rn2(3))
515 | mac += 1 + mongets(mtmp, HELMET);
516 | else if (mac < 10 && rn2(2))
517 | mac += 1 + mongets(mtmp, DENTED_POT);
518 | if (mac < 10 && rn2(3))
519 | mac += 1 + mongets(mtmp, SMALL_SHIELD);
520 | else if (mac < 10 && rn2(2))
521 | mac += 2 + mongets(mtmp, LARGE_SHIELD);
522 | if (mac < 10 && rn2(3))
523 | mac += 1 + mongets(mtmp, LOW_BOOTS);
524 | else if (mac < 10 && rn2(2))
525 | mac += 2 + mongets(mtmp, HIGH_BOOTS);
526 | if (mac < 10 && rn2(3))
527 | mac += 1 + mongets(mtmp, LEATHER_GLOVES);
528 | else if (mac < 10 && rn2(2))
529 | mac += 1 + mongets(mtmp, ELVEN_CLOAK);
530 |
531 | if(ptr != &mons[PM_GUARD] &&
532 | ptr != &mons[PM_WATCHMAN] &&
533 | ptr != &mons[PM_WATCH_CAPTAIN]) {
534 | if (!rn2(3)) (void) mongets(mtmp, K_RATION);
535 | if (!rn2(2)) (void) mongets(mtmp, C_RATION);
536 | if (ptr != &mons[PM_SOLDIER] && !rn2(3))
537 | (void) mongets(mtmp, BUGLE);
538 | } else
539 | if (ptr == &mons[PM_WATCHMAN] && rn2(3))
540 | (void) mongets(mtmp, TIN_WHISTLE);
541 | } else if (ptr == &mons[PM_SHOPKEEPER]) {
542 | (void) mongets(mtmp,SKELETON_KEY);
543 | switch (rn2(4)) {
544 | /* MAJOR fall through ... */
545 | case 0: (void) mongets(mtmp, WAN_MAGIC_MISSILE);
546 | case 1: (void) mongets(mtmp, POT_EXTRA_HEALING);
547 | case 2: (void) mongets(mtmp, POT_HEALING);
548 | case 3: (void) mongets(mtmp, WAN_STRIKING);
549 | }
550 | } else if (ptr->msound == MS_PRIEST) {
551 | (void) mongets(mtmp, ROBE);
552 | (void) mongets(mtmp, SMALL_SHIELD);
553 | mtmp->mgold = (long)rn1(10,20);
554 | }
555 | break;
556 | case S_NYMPH:
557 | if(!rn2(2)) (void) mongets(mtmp, MIRROR);
558 | if(!rn2(2)) (void) mongets(mtmp, POT_OBJECT_DETECTION);
559 | break;
560 | case S_GIANT:
561 | if (ptr == &mons[PM_MINOTAUR]) {
562 | if (!rn2(3) || (in_mklev && Is_earthlevel(&u.uz)))
563 | (void) mongets(mtmp, WAN_DIGGING);
564 | } else if (is_giant(ptr)) {
565 | for (cnt = rn2((int)(mtmp->m_lev / 2)); cnt; cnt--) {
566 | otmp = mksobj(rnd_class(DILITHIUM_CRYSTAL,LUCKSTONE-1),
567 | FALSE, FALSE);
568 | otmp->quan = (long) rn1(2, 3);
569 | otmp->owt = weight(otmp);
570 | (void) mpickobj(mtmp, otmp);
571 | }
572 | }
573 | break;
574 | case S_WRAITH:
575 | if (ptr == &mons[PM_NAZGUL]) {
576 | otmp = mksobj(RIN_INVISIBILITY, FALSE, FALSE);
577 | curse(otmp);
578 | (void) mpickobj(mtmp, otmp);
579 | }
580 | break;
581 | case S_LICH:
582 | if (ptr == &mons[PM_MASTER_LICH] && !rn2(13))
583 | (void)mongets(mtmp, (rn2(7) ? ATHAME : WAN_NOTHING));
584 | else if (ptr == &mons[PM_ARCH_LICH] && !rn2(3)) {
585 | otmp = mksobj(rn2(3) ? ATHAME : QUARTERSTAFF,
586 | TRUE, rn2(13) ? FALSE : TRUE);
587 | if (otmp->spe < 2) otmp->spe = rnd(3);
588 | if (!rn2(4)) otmp->oerodeproof = 1;
589 | (void) mpickobj(mtmp, otmp);
590 | }
591 | break;
592 | case S_MUMMY:
593 | if (rn2(7)) (void)mongets(mtmp, MUMMY_WRAPPING);
594 | break;
595 | case S_QUANTMECH:
596 | if (!rn2(20)) {
597 | otmp = mksobj(LARGE_BOX, FALSE, FALSE);
598 | otmp->spe = 1; /* flag for special box */
599 | otmp->owt = weight(otmp);
600 | (void) mpickobj(mtmp, otmp);
601 | }
602 | break;
603 | case S_LEPRECHAUN:
604 | mtmp->mgold = (long) d(level_difficulty(), 30);
605 | break;
606 | default:
607 | break;
608 | }
609 |
610 | /* ordinary soldiers rarely have access to magic (or gold :-) */
611 | if (ptr == &mons[PM_SOLDIER] && rn2(13)) return;
612 |
613 | if ((int) mtmp->m_lev > rn2(50))
614 | (void) mongets(mtmp, rnd_defensive_item(mtmp));
615 | if ((int) mtmp->m_lev > rn2(100))
616 | (void) mongets(mtmp, rnd_misc_item(mtmp));
617 | if (likes_gold(ptr) && !mtmp->mgold && !rn2(5))
618 | mtmp->mgold =
619 | (long) d(level_difficulty(), mtmp->minvent ? 5 : 10);
620 | }
621 |
622 | struct monst *
623 | clone_mon(mon)
624 | struct monst *mon;
625 | {
626 | coord mm;
627 | struct monst *m2;
628 |
629 | /* may be too weak or have been extinguished for population control */
630 | if (mon->mhp <= 1 || (mvitals[monsndx(mon->data)].mvflags & G_EXTINCT))
631 | return (struct monst *)0;
632 |
633 | mm.x = mon->mx;
634 | mm.y = mon->my;
635 | if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y))
636 | return (struct monst *)0;
637 | m2 = newmonst(0);
638 | *m2 = *mon; /* copy condition of old monster */
639 | m2->nmon = fmon;
640 | fmon = m2;
641 | m2->m_id = flags.ident++;
642 | if (!m2->m_id) m2->m_id = flags.ident++; /* ident overflowed */
643 | m2->mx = mm.x;
644 | m2->my = mm.y;
645 |
646 | m2->minvent = (struct obj *) 0; /* objects don't clone */
647 | m2->mleashed = FALSE;
648 | m2->mgold = 0L;
649 | /* Max HP the same, but current HP halved for both. The caller
650 | * might want to override this by halving the max HP also.
651 | * When current HP is odd, the original keeps the extra point.
652 | */
653 | m2->mhpmax = mon->mhpmax;
654 | m2->mhp = mon->mhp / 2;
655 | mon->mhp -= m2->mhp;
656 |
657 | /* since shopkeepers and guards will only be cloned if they've been
658 | * polymorphed away from their original forms, the clone doesn't have
659 | * room for the extra information. we also don't want two shopkeepers
660 | * around for the same shop.
661 | * similarly, clones of named monsters don't have room for the name,
662 | * so we just make the clone unnamed instead of bothering to create
663 | * a clone with room and copying over the name from the right place
664 | * (which changes if the original was a shopkeeper or guard).
665 | */
666 | if (mon->isshk) m2->isshk = FALSE;
667 | if (mon->isgd) m2->isgd = FALSE;
668 | if (mon->ispriest) m2->ispriest = FALSE;
669 | m2->mxlth = 0;
670 | m2->mnamelth = 0;
671 | place_monster(m2, m2->mx, m2->my);
672 | if (emits_light(m2->data))
673 | new_light_source(m2->mx, m2->my, emits_light(m2->data),
674 | LS_MONSTER, (genericptr_t)m2);
675 | newsym(m2->mx,m2->my); /* display the new monster */
676 | if (mon->mtame) {
677 | struct monst *m3;
678 |
679 | /* because m2 is a copy of mon it is tame but not init'ed.
680 | * however, tamedog will not re-tame a tame dog, so m2
681 | * must be made non-tame to get initialized properly.
682 | */
683 | m2->mtame = 0;
684 | if ((m3 = tamedog(m2, (struct obj *)0)) != 0)
685 | m2 = m3;
686 | }
687 | return m2;
688 | }
689 |
690 | /*
691 | * called with [x,y] = coordinates;
692 | * [0,0] means anyplace
693 | * [u.ux,u.uy] means: near player (if !in_mklev)
694 | *
695 | * In case we make a monster group, only return the one at [x,y].
696 | */
697 | struct monst *
698 | makemon(ptr, x, y, mmflags)
699 | register struct permonst *ptr;
700 | register int x, y;
701 | register int mmflags;
702 | {
703 | register struct monst *mtmp;
704 | int mndx, mcham, ct, mitem, xlth;
705 | boolean anymon = (!ptr);
706 | boolean byyou = (x == u.ux && y == u.uy);
707 | boolean allow_minvent = ((mmflags & NO_MINVENT) == 0);
708 | uchar lim;
709 |
710 | /* if caller wants random location, do it here */
711 | if(x == 0 && y == 0) {
712 | int tryct = 0; /* careful with bigrooms */
713 | struct monst fakemon;
714 |
715 | fakemon.data = ptr; /* set up for goodpos */
716 | do {
717 | x = rn1(COLNO-3,2);
718 | y = rn2(ROWNO);
719 | } while(!goodpos(x, y, ptr ? &fakemon : (struct monst *)0) ||
720 | (!in_mklev && tryct++ < 50 && cansee(x, y)));
721 | } else if (byyou && !in_mklev) {
722 | coord bypos;
723 |
724 | if(enexto(&bypos, u.ux, u.uy, ptr)) {
725 | x = bypos.x;
726 | y = bypos.y;
727 | } else
728 | return((struct monst *)0);
729 | }
730 |
731 | /* if a monster already exists at the position, return */
732 | if(MON_AT(x, y))
733 | return((struct monst *) 0);
734 |
735 | if(ptr){
736 | mndx = monsndx(ptr);
737 | /* if you are to make a specific monster and it has
738 | already been genocided, return */
739 | if (mvitals[mndx].mvflags & G_GENOD) return((struct monst *) 0);
740 | #ifdef DEBUG
741 | if (wizard && (mvitals[mndx].mvflags & G_EXTINCT))
742 | pline("Explicitly creating extinct monster %s.",
743 | mons[mndx].mname);
744 | #endif
745 | } else {
746 | /* make a random (common) monster that can survive here.
747 | * (the special levels ask for random monsters at specific
748 | * positions, causing mass drowning on the medusa level,
749 | * for instance.)
750 | */
751 | int tryct = 0; /* maybe there are no good choices */
752 | struct monst fakemon;
753 | do {
754 | if(!(ptr = rndmonst())) {
755 | #ifdef DEBUG
756 | pline("Warning: no monster.");
757 | #endif
758 | return((struct monst *) 0); /* no more monsters! */
759 | }
760 | fakemon.data = ptr; /* set up for goodpos */
761 | } while(!goodpos(x, y, &fakemon) && tryct++ < 50);
762 | mndx = monsndx(ptr);
763 | }
764 | /* if it's unique, don't ever make it again */
765 | if (ptr->geno & G_UNIQ) mvitals[mndx].mvflags |= G_EXTINCT;
766 |
767 | /* Once a certain number of monsters are created, don't create any more
768 | * at random (i.e. make them extinct). The previous (3.2) behavior was
769 | * to do this when a certain number had _died_, which didn't make
770 | * much sense.
771 | * This version makes a little more sense but still requires that
772 | * the caller manually decrement mvitals if the monster is created
773 | * under circumstances where one would not logically expect the
774 | * creation to reduce the supply of wild monsters. Monster cloning
775 | * might be one such case, but we go against logic there in order to
776 | * reduce the possibility of abuse.
777 | */
778 | if (mvitals[mndx].born < 255) mvitals[mndx].born++;
779 | lim = (mndx == PM_NAZGUL ? 9 : mndx == PM_ERINYS ? 3 : MAXMONNO);
780 | if ((int) mvitals[mndx].born >= lim && !(mons[mndx].geno & G_NOGEN) &&
781 | !(mvitals[mndx].mvflags & G_EXTINCT)) {
782 | #ifdef DEBUG
783 | pline("Automatically extinguished %s.",
784 | makeplural(mons[mndx].mname));
785 | #endif
786 | mvitals[mndx].mvflags |= G_EXTINCT;
787 | reset_rndmonst(mndx);
788 | }
789 |
790 | xlth = ptr->pxlth;
791 | if (mmflags & MM_EDOG) xlth += sizeof(struct edog);
792 | else if (mmflags & MM_EMIN) xlth += sizeof(struct emin);
793 | mtmp = newmonst(xlth);
794 | *mtmp = zeromonst; /* clear all entries in structure */
795 | (void)memset((genericptr_t)mtmp->mextra, 0, xlth);
796 | mtmp->nmon = fmon;
797 | fmon = mtmp;
798 | mtmp->m_id = flags.ident++;
799 | if (!mtmp->m_id) mtmp->m_id = flags.ident++; /* ident overflowed */
800 | set_mon_data(mtmp, ptr, 0);
801 | mtmp->mxlth = xlth;
802 | mtmp->mnum = mndx;
803 |
804 | mtmp->m_lev = adj_lev(ptr);
805 | if (is_golem(ptr)) {
806 | mtmp->mhpmax = mtmp->mhp = golemhp(mndx);
807 | } else if (is_rider(ptr)) {
808 | /* We want low HP, but a high mlevel so they can attack well */
809 | mtmp->mhpmax = mtmp->mhp = d(10,8);
810 | } else if (ptr->mlevel > 49) {
811 | /* "special" fixed hp monster
812 | * the hit points are encoded in the mlevel in a somewhat strange
813 | * way to fit in the 50..127 positive range of a signed character
814 | * above the 1..49 that indicate "normal" monster levels */
815 | mtmp->mhpmax = mtmp->mhp = 2*(ptr->mlevel - 6);
816 | mtmp->m_lev = mtmp->mhp / 4; /* approximation */
817 | } else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) {
818 | /* adult dragons */
819 | mtmp->mhpmax = mtmp->mhp = (int) (In_endgame(&u.uz) ?
820 | (8 * mtmp->m_lev) : (4 * mtmp->m_lev + d((int)mtmp->m_lev, 4)));
821 | } else if (!mtmp->m_lev) {
822 | mtmp->mhpmax = mtmp->mhp = rnd(4);
823 | } else {
824 | mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, 8);
825 | if (is_home_elemental(ptr))
826 | mtmp->mhpmax = (mtmp->mhp *= 3);
827 | }
828 |
829 | if (is_female(ptr)) mtmp->female = TRUE;
830 | else if (is_male(ptr)) mtmp->female = FALSE;
831 | else mtmp->female = rn2(2); /* ignored for neuters */
832 |
833 | if (In_sokoban(&u.uz) && !mindless(ptr)) /* know about traps here */
834 | mtmp->mtrapseen = (1L << (PIT - 1)) | (1L << (HOLE - 1));
835 |
836 | place_monster(mtmp, x, y);
837 | mtmp->mcansee = mtmp->mcanmove = TRUE;
838 | mtmp->mpeaceful = (mmflags & MM_ANGRY) ? FALSE : peace_minded(ptr);
839 |
840 | switch(ptr->mlet) {
841 | case S_MIMIC:
842 | set_mimic_sym(mtmp);
843 | break;
844 | case S_SPIDER:
845 | case S_SNAKE:
846 | if(in_mklev)
847 | if(x && y)
848 | (void) mkobj_at(0, x, y, TRUE);
849 | if(hides_under(ptr) && OBJ_AT(x, y))
850 | mtmp->mundetected = TRUE;
851 | break;
852 | case S_LIGHT:
853 | case S_ELEMENTAL:
854 | if (mndx == PM_STALKER || mndx == PM_BLACK_LIGHT) {
855 | mtmp->perminvis = TRUE;
856 | mtmp->minvis = TRUE;
857 | }
858 | break;
859 | case S_EEL:
860 | if (is_pool(x, y))
861 | mtmp->mundetected = TRUE;
862 | break;
863 | case S_LEPRECHAUN:
864 | mtmp->msleeping = 1;
865 | break;
866 | case S_JABBERWOCK:
867 | case S_NYMPH:
868 | if (rn2(5) && !u.uhave.amulet) mtmp->msleeping = 1;
869 | break;
870 | case S_ORC:
871 | if (Race_if(PM_ELF)) mtmp->mpeaceful = FALSE;
872 | break;
873 | case S_UNICORN:
874 | if (is_unicorn(ptr) &&
875 | sgn(u.ualign.type) == sgn(ptr->maligntyp))
876 | mtmp->mpeaceful = TRUE;
877 | break;
878 | case S_BAT:
879 | if (Inhell && is_bat(ptr))
880 | mon_adjust_speed(mtmp, 2);
881 | break;
882 | }
883 | if ((ct = emits_light(mtmp->data)) > 0)
884 | new_light_source(mtmp->mx, mtmp->my, ct,
885 | LS_MONSTER, (genericptr_t)mtmp);
886 | mitem = 0; /* extra inventory item for this monster */
887 |
888 | if ((mcham = pm_to_cham(mndx)) != CHAM_ORDINARY) {
889 | /* If you're protected with a ring, don't create
890 | * any shape-changing chameleons -dgk
891 | */
892 | if (Protection_from_shape_changers)
893 | mtmp->cham = CHAM_ORDINARY;
894 | else {
895 | mtmp->cham = mcham;
896 | (void) newcham(mtmp, rndmonst());
897 | }
898 | } else if (mndx == PM_WIZARD_OF_YENDOR) {
899 | mtmp->iswiz = TRUE;
900 | flags.no_of_wizards++;
901 | if (flags.no_of_wizards == 1 && Is_earthlevel(&u.uz))
902 | mitem = SPE_DIG;
903 | } else if (mndx == PM_DJINNI) {
904 | flags.djinni_count++;
905 | } else if (mndx == PM_GHOST) {
906 | flags.ghost_count++;
907 | if (!(mmflags & MM_NONAME))
908 | mtmp = christen_monst(mtmp, rndghostname());
909 | } else if (mndx == PM_VLAD_THE_IMPALER) {
910 | mitem = CANDELABRUM_OF_INVOCATION;
911 | } else if (mndx == PM_CROESUS) {
912 | mitem = TWO_HANDED_SWORD;
913 | } else if (ptr->msound == MS_NEMESIS) {
914 | mitem = BELL_OF_OPENING;
915 | } else if (mndx == PM_PESTILENCE) {
916 | mitem = POT_SICKNESS;
917 | }
918 | if (mitem && allow_minvent) (void) mongets(mtmp, mitem);
919 |
920 | if(in_mklev) {
921 | if(((is_ndemon(ptr)) ||
922 | (mndx == PM_WUMPUS) ||
923 | (mndx == PM_LONG_WORM) ||
924 | (mndx == PM_GIANT_EEL)) && !u.uhave.amulet && rn2(5))
925 | mtmp->msleeping = TRUE;
926 | } else {
927 | if(byyou) {
928 | newsym(mtmp->mx,mtmp->my);
929 | set_apparxy(mtmp);
930 | }
931 | }
932 | if(is_dprince(ptr) && ptr->msound == MS_BRIBE) {
933 | mtmp->mpeaceful = mtmp->minvis = mtmp->perminvis = 1;
934 | if (uwep && uwep->oartifact == ART_EXCALIBUR)
935 | mtmp->mpeaceful = mtmp->mtame = FALSE;
936 | }
937 | #ifndef DCC30_BUG
938 | if (mndx == PM_LONG_WORM && (mtmp->wormno = get_wormno()) != 0)
939 | #else
940 | /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
941 | * same expression.
942 | */
943 | if (mndx == PM_LONG_WORM &&
944 | (mtmp->wormno = get_wormno(), mtmp->wormno != 0))
945 | #endif
946 | {
947 | /* we can now create worms with tails - 11/91 */
948 | initworm(mtmp, rn2(5));
949 | if (count_wsegs(mtmp)) place_worm_tail_randomly(mtmp, x, y);
950 | }
951 | set_malign(mtmp); /* having finished peaceful changes */
952 | if(anymon) {
953 | if ((ptr->geno & G_SGROUP) && rn2(2)) {
954 | m_initsgrp(mtmp, mtmp->mx, mtmp->my);
955 | } else if (ptr->geno & G_LGROUP) {
956 | if(rn2(3)) m_initlgrp(mtmp, mtmp->mx, mtmp->my);
957 | else m_initsgrp(mtmp, mtmp->mx, mtmp->my);
958 | }
959 | }
960 |
961 | if (allow_minvent) {
962 | if(is_armed(ptr))
963 | m_initweap(mtmp); /* equip with weapons / armor */
964 | m_initinv(mtmp); /* add on a few special items incl. more armor */
965 | m_dowear(mtmp, TRUE);
966 | } else {
967 | /* no initial inventory is allowed */
968 | if (mtmp->minvent) discard_minvent(mtmp);
969 | mtmp->minvent = (struct obj *)0; /* caller expects this */
970 | }
971 | if ((ptr->mflags3 & M3_WAITMASK) && !(mmflags & MM_NOWAIT)) {
972 | if (ptr->mflags3 & M3_WAITFORU)
973 | mtmp->mstrategy |= STRAT_WAITFORU;
974 | if (ptr->mflags3 & M3_CLOSE)
975 | mtmp->mstrategy |= STRAT_CLOSE;
976 | }
977 |
978 | if (!in_mklev)
979 | newsym(mtmp->mx,mtmp->my); /* make sure the mon shows up */
980 |
981 | return(mtmp);
982 | }
983 |
984 | /* used for wand/scroll/spell of create monster */
985 | /* returns TRUE iff you know monsters have been created */
986 | boolean
987 | create_critters(cnt, mptr)
988 | int cnt;
989 | struct permonst *mptr; /* usually null; used for confused reading */
990 | {
991 | coord c;
992 | int x, y;
993 | struct monst *mon;
994 | boolean known = FALSE;
995 | #ifdef WIZARD
996 | boolean ask = wizard;
997 | #endif
998 |
999 | while (cnt--) {
1000 | #ifdef WIZARD
1001 | if (ask) {
1002 | if (create_particular()) {
1003 | known = TRUE;
1004 | continue;
1005 | }
1006 | else ask = FALSE; /* ESC will shut off prompting */
1007 | }
1008 | #endif
1009 | x = u.ux, y = u.uy;
1010 | /* if in water, try to encourage an aquatic monster
1011 | by finding and then specifying another wet location */
1012 | if (!mptr && u.uinwater && enexto(&c, x, y, &mons[PM_GIANT_EEL]))
1013 | x = c.x, y = c.y;
1014 |
1015 | mon = makemon(mptr, x, y, NO_MM_FLAGS);
1016 | if (mon && canspotmon(mon)) known = TRUE;
1017 | }
1018 | return known;
1019 | }
1020 |
1021 | #endif /* OVL1 */
1022 | #ifdef OVL0
1023 |
1024 | STATIC_OVL boolean
1025 | uncommon(mndx)
1026 | int mndx;
1027 | {
1028 | if (mons[mndx].geno & (G_NOGEN | G_UNIQ)) return TRUE;
1029 | if (mvitals[mndx].mvflags & G_GONE) return TRUE;
1030 | if (Inhell)
1031 | return(mons[mndx].maligntyp > A_NEUTRAL);
1032 | else
1033 | return((mons[mndx].geno & G_HELL) != 0);
1034 | }
1035 |
1036 | /*
1037 | * shift the probability of a monster's generation by
1038 | * comparing the dungeon alignment and monster alignment.
1039 | * return an integer in the range of 0-5.
1040 | */
1041 | STATIC_OVL int
1042 | align_shift(ptr)
1043 | register struct permonst *ptr;
1044 | {
1045 | static NEARDATA long oldmoves = 0L; /* != 1, starting value of moves */
1046 | static NEARDATA s_level *lev;
1047 | register int alshift;
1048 |
1049 | if(oldmoves != moves) {
1050 | lev = Is_special(&u.uz);
1051 | oldmoves = moves;
1052 | }
1053 | switch((lev) ? lev->flags.align : dungeons[u.uz.dnum].flags.align) {
1054 | default: /* just in case */
1055 | case AM_NONE: alshift = 0;
1056 | break;
1057 | case AM_LAWFUL: alshift = (ptr->maligntyp+20)/(2*ALIGNWEIGHT);
1058 | break;
1059 | case AM_NEUTRAL: alshift = (20 - abs(ptr->maligntyp))/ALIGNWEIGHT;
1060 | break;
1061 | case AM_CHAOTIC: alshift = (-(ptr->maligntyp-20))/(2*ALIGNWEIGHT);
1062 | break;
1063 | }
1064 | return alshift;
1065 | }
1066 |
1067 | static NEARDATA struct {
1068 | int choice_count;
1069 | char mchoices[SPECIAL_PM]; /* value range is 0..127 */
1070 | } rndmonst_state = { -1, {0} };
1071 |
1072 | /* select a random monster type */
1073 | struct permonst *
1074 | rndmonst()
1075 | {
1076 | register struct permonst *ptr;
1077 | register int mndx, ct;
1078 |
1079 | if (u.uz.dnum == quest_dnum && rn2(7) && (ptr = qt_montype()) != 0)
1080 | return ptr;
1081 |
1082 | if (rndmonst_state.choice_count < 0) { /* need to recalculate */
1083 | int zlevel, minmlev, maxmlev;
1084 | boolean elemlevel;
1085 | #ifdef REINCARNATION
1086 | boolean upper;
1087 | #endif
1088 |
1089 | rndmonst_state.choice_count = 0;
1090 | /* look for first common monster */
1091 | for (mndx = LOW_PM; mndx < SPECIAL_PM; mndx++)
1092 | if (!uncommon(mndx)) break;
1093 | if (mndx == SPECIAL_PM) {
1094 | /* evidently they've all been exterminated */
1095 | #ifdef DEBUG
1096 | pline("rndmonst: no common mons!");
1097 | #endif
1098 | return (struct permonst *)0;
1099 | } /* else `mndx' now ready for use below */
1100 | zlevel = level_difficulty();
1101 | /* determine the level of the weakest monster to make. */
1102 | minmlev = zlevel / 6;
1103 | /* determine the level of the strongest monster to make. */
1104 | maxmlev = (zlevel + u.ulevel) / 2;
1105 | #ifdef REINCARNATION
1106 | upper = Is_rogue_level(&u.uz);
1107 | #endif
1108 | elemlevel = In_endgame(&u.uz) && !Is_astralevel(&u.uz);
1109 |
1110 | /*
1111 | * Find out how many monsters exist in the range we have selected.
1112 | */
1113 | /* (`mndx' initialized above) */
1114 | for ( ; mndx < SPECIAL_PM; mndx++) {
1115 | ptr = &mons[mndx];
1116 | rndmonst_state.mchoices[mndx] = 0;
1117 | if (tooweak(mndx, minmlev) || toostrong(mndx, maxmlev))
1118 | continue;
1119 | #ifdef REINCARNATION
1120 | if (upper && !isupper(def_monsyms[(int)(ptr->mlet)])) continue;
1121 | #endif
1122 | if (elemlevel && wrong_elem_type(ptr)) continue;
1123 | if (uncommon(mndx)) continue;
1124 | if (Inhell && (ptr->geno & G_NOHELL)) continue;
1125 | ct = (int)(ptr->geno & G_FREQ) + align_shift(ptr);
1126 | if (ct < 0 || ct > 127)
1127 | panic("rndmonst: bad count [#%d: %d]", mndx, ct);
1128 | rndmonst_state.choice_count += ct;
1129 | rndmonst_state.mchoices[mndx] = (char)ct;
1130 | }
1131 | /*
1132 | * Possible modification: if choice_count is "too low",
1133 | * expand minmlev..maxmlev range and try again.
1134 | */
1135 | } /* choice_count+mchoices[] recalc */
1136 |
1137 | if (rndmonst_state.choice_count <= 0) {
1138 | /* maybe no common mons left, or all are too weak or too strong */
1139 | #ifdef DEBUG
1140 | Norep("rndmonst: choice_count=%d", rndmonst_state.choice_count);
1141 | #endif
1142 | return (struct permonst *)0;
1143 | }
1144 |
1145 | /*
1146 | * Now, select a monster at random.
1147 | */
1148 | ct = rnd(rndmonst_state.choice_count);
1149 | for (mndx = LOW_PM; mndx < SPECIAL_PM; mndx++)
1150 | if ((ct -= (int)rndmonst_state.mchoices[mndx]) <= 0) break;
1151 |
1152 | if (mndx == SPECIAL_PM || uncommon(mndx)) { /* shouldn't happen */
1153 | impossible("rndmonst: bad `mndx' [#%d]", mndx);
1154 | return (struct permonst *)0;
1155 | }
1156 | return &mons[mndx];
1157 | }
1158 |
1159 | /* called when you change level (experience or dungeon depth) or when
1160 | monster species can no longer be created (genocide or extinction) */
1161 | void
1162 | reset_rndmonst(mndx)
1163 | int mndx; /* particular species that can no longer be created */
1164 | {
1165 | /* cached selection info is out of date */
1166 | if (mndx == NON_PM) {
1167 | rndmonst_state.choice_count = -1; /* full recalc needed */
1168 | } else if (mndx < SPECIAL_PM) {
1169 | rndmonst_state.choice_count -= rndmonst_state.mchoices[mndx];
1170 | rndmonst_state.mchoices[mndx] = 0;
1171 | } /* note: safe to ignore extinction of unique monsters */
1172 | }
1173 |
1174 | #endif /* OVL0 */
1175 | #ifdef OVL1
1176 |
1177 | /* The routine below is used to make one of the multiple types
1178 | * of a given monster class. The second parameter specifies a
1179 | * special casing bit mask to allow the normal genesis
1180 | * masks to be deactivated. Returns 0 if no monsters
1181 | * in that class can be made.
1182 | */
1183 |
1184 | struct permonst *
1185 | mkclass(class,spc)
1186 | char class;
1187 | int spc;
1188 | {
1189 | register int first, last, num = 0;
1190 | int maxmlev, mask = (G_NOGEN | G_UNIQ) & ~spc;
1191 |
1192 | maxmlev = level_difficulty() >> 1;
1193 | if(class < 1 || class >= MAXMCLASSES) {
1194 | impossible("mkclass called with bad class!");
1195 | return((struct permonst *) 0);
1196 | }
1197 | /* Assumption #1: monsters of a given class are contiguous in the
1198 | * mons[] array.
1199 | */
1200 | for (first = LOW_PM; first < SPECIAL_PM; first++)
1201 | if (mons[first].mlet == class) break;
1202 | if (first == SPECIAL_PM) return (struct permonst *) 0;
1203 |
1204 | for (last = first;
1205 | last < SPECIAL_PM && mons[last].mlet == class; last++)
1206 | if (!(mvitals[last].mvflags & G_GONE) && !(mons[last].geno & mask)
1207 | && !is_placeholder(&mons[last])) {
1208 | /* consider it */
1209 | if(num && toostrong(last, maxmlev) &&
1210 | monstr[last] != monstr[last-1] && rn2(2)) break;
1211 | num += mons[last].geno & G_FREQ;
1212 | }
1213 |
1214 | if(!num) return((struct permonst *) 0);
1215 |
1216 | /* Assumption #2: monsters of a given class are presented in ascending
1217 | * order of strength.
1218 | */
1219 | for(num = rnd(num); num > 0; first++)
1220 | if (!(mvitals[first].mvflags & G_GONE) && !(mons[first].geno & mask)
1221 | && !is_placeholder(&mons[first])) {
1222 | /* skew towards lower value monsters at lower exp. levels */
1223 | num -= mons[first].geno & G_FREQ;
1224 | if (num && adj_lev(&mons[first]) > (u.ulevel*2)) {
1225 | /* but not when multiple monsters are same level */
1226 | if (mons[first].mlevel != mons[first+1].mlevel)
1227 | num--;
1228 | }
1229 | }
1230 | first--; /* correct an off-by-one error */
1231 |
1232 | return(&mons[first]);
1233 | }
1234 |
1235 | int
1236 | adj_lev(ptr) /* adjust strength of monsters based on u.uz and u.ulevel */
1237 | register struct permonst *ptr;
1238 | {
1239 | int tmp, tmp2;
1240 |
1241 | if (ptr == &mons[PM_WIZARD_OF_YENDOR]) {
1242 | /* does not depend on other strengths, but does get stronger
1243 | * every time he is killed
1244 | */
1245 | tmp = ptr->mlevel + mvitals[PM_WIZARD_OF_YENDOR].died;
1246 | if (tmp > 49) tmp = 49;
1247 | return tmp;
1248 | }
1249 |
1250 | if((tmp = ptr->mlevel) > 49) return(50); /* "special" demons/devils */
1251 | tmp2 = (level_difficulty() - tmp);
1252 | if(tmp2 < 0) tmp--; /* if mlevel > u.uz decrement tmp */
1253 | else tmp += (tmp2 / 5); /* else increment 1 per five diff */
1254 |
1255 | tmp2 = (u.ulevel - ptr->mlevel); /* adjust vs. the player */
1256 | if(tmp2 > 0) tmp += (tmp2 / 4); /* level as well */
1257 |
1258 | tmp2 = (3 * ((int) ptr->mlevel))/ 2; /* crude upper limit */
1259 | if (tmp2 > 49) tmp2 = 49; /* hard upper limit */
1260 | return((tmp > tmp2) ? tmp2 : (tmp > 0 ? tmp : 0)); /* 0 lower limit */
1261 | }
1262 |
1263 | #endif /* OVL1 */
1264 | #ifdef OVLB
1265 |
1266 | struct permonst *
1267 | grow_up(mtmp, victim) /* `mtmp' might "grow up" into a bigger version */
1268 | struct monst *mtmp, *victim;
1269 | {
1270 | int oldtype, newtype, max_increase, cur_increase,
1271 | lev_limit, hp_threshold;
1272 | struct permonst *ptr = mtmp->data;
1273 |
1274 | /* monster died after killing enemy but before calling this function */
1275 | /* currently possible if killing a gas spore */
1276 | if (mtmp->mhp <= 0)
1277 | return ((struct permonst *)0);
1278 |
1279 | /* growth limits differ depending on method of advancement */
1280 | if (victim) { /* killed a monster */
1281 | /*
1282 | * The HP threshold is the maximum number of hit points for the
1283 | * current level; once exceeded, a level will be gained.
1284 | * Possible bug: if somehow the hit points are already higher
1285 | * than that, monster will gain a level without any increase in HP.
1286 | */
1287 | hp_threshold = mtmp->m_lev * 8; /* normal limit */
1288 | if (!mtmp->m_lev)
1289 | hp_threshold = 4;
1290 | else if (is_golem(ptr)) /* strange creatures */
1291 | hp_threshold = ((mtmp->mhpmax / 10) + 1) * 10 - 1;
1292 | else if (is_home_elemental(ptr))
1293 | hp_threshold *= 3;
1294 | lev_limit = 3 * (int)ptr->mlevel / 2; /* same as adj_lev() */
1295 | /* number of hit points to gain; unlike for the player, we put
1296 | the limit at the bottom of the next level rather than the top */
1297 | max_increase = rnd((int)victim->m_lev + 1);
1298 | if (mtmp->mhpmax + max_increase > hp_threshold + 1)
1299 | max_increase = max((hp_threshold + 1) - mtmp->mhpmax, 0);
1300 | cur_increase = (max_increase > 1) ? rn2(max_increase) : 0;
1301 | } else {
1302 | /* a gain level potion or wraith corpse; always go up a level
1303 | unless already at maximum (49 is hard upper limit except
1304 | for demon lords, who start at 50 and can't go any higher) */
1305 | max_increase = cur_increase = rnd(8);
1306 | hp_threshold = 0; /* smaller than `mhpmax + max_increase' */
1307 | lev_limit = 50; /* recalc below */
1308 | }
1309 |
1310 | mtmp->mhpmax += max_increase;
1311 | mtmp->mhp += cur_increase;
1312 | if (mtmp->mhpmax <= hp_threshold)
1313 | return ptr; /* doesn't gain a level */
1314 |
1315 | if (is_mplayer(ptr)) lev_limit = 30; /* same as player */
1316 | else if (lev_limit < 5) lev_limit = 5; /* arbitrary */
1317 | else if (lev_limit > 49) lev_limit = (ptr->mlevel > 49 ? 50 : 49);
1318 |
1319 | /* note: none of the monsters with special hit point calculations
1320 | have both little and big forms */
1321 | oldtype = monsndx(ptr);
1322 | newtype = little_to_big(oldtype);
1323 | if (newtype == PM_PRIEST && mtmp->female) newtype = PM_PRIESTESS;
1324 | if ((int)++mtmp->m_lev >= mons[newtype].mlevel && newtype != oldtype) {
1325 | ptr = &mons[newtype];
1326 | if (mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */
1327 | if (sensemon(mtmp))
1328 | pline("As %s grows up into %s, %s %s!", mon_nam(mtmp),
1329 | an(ptr->mname), he[pronoun_gender(mtmp)],
1330 | nonliving(ptr) ? "expires" : "dies");
1331 | set_mon_data(mtmp, ptr, -1); /* keep mvitals[] accurate */
1332 | mondied(mtmp);
1333 | return (struct permonst *)0;
1334 | }
1335 | set_mon_data(mtmp, ptr, 1); /* preserve intrinsics */
1336 | newsym(mtmp->mx, mtmp->my); /* color may change */
1337 | lev_limit = (int)mtmp->m_lev; /* never undo increment */
1338 | }
1339 | /* sanity checks */
1340 | if ((int)mtmp->m_lev > lev_limit) {
1341 | mtmp->m_lev--; /* undo increment */
1342 | /* HP might have been allowed to grow when it shouldn't */
1343 | if (mtmp->mhpmax == hp_threshold + 1) mtmp->mhpmax--;
1344 | }
1345 | if (mtmp->mhpmax > 50*8) mtmp->mhpmax = 50*8; /* absolute limit */
1346 | if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
1347 |
1348 | return ptr;
1349 | }
1350 |
1351 | #endif /* OVLB */
1352 | #ifdef OVL1
1353 |
1354 | int
1355 | mongets(mtmp, otyp)
1356 | register struct monst *mtmp;
1357 | register int otyp;
1358 | {
1359 | register struct obj *otmp;
1360 | int spe;
1361 |
1362 | if (!otyp) return 0;
1363 | otmp = mksobj(otyp, TRUE, FALSE);
1364 | if (otmp) {
1365 | if (mtmp->data->mlet == S_DEMON) {
1366 | /* demons never get blessed objects */
1367 | if (otmp->blessed) curse(otmp);
1368 | } else if(is_lminion(mtmp->data)) {
1369 | /* lawful minions don't get cursed, bad, or rusting objects */
1370 | otmp->cursed = FALSE;
1371 | if(otmp->spe < 0) otmp->spe = 0;
1372 | otmp->oerodeproof = TRUE;
1373 | } else if(is_mplayer(mtmp->data) && is_sword(otmp)) {
1374 | otmp->spe = (3 + rn2(4));
1375 | }
1376 |
1377 | if(otmp->otyp == CANDELABRUM_OF_INVOCATION) {
1378 | otmp->spe = 0;
1379 | otmp->age = 0L;
1380 | otmp->lamplit = FALSE;
1381 | otmp->blessed = otmp->cursed = FALSE;
1382 | } else if (otmp->otyp == BELL_OF_OPENING) {
1383 | otmp->blessed = otmp->cursed = FALSE;
1384 | } else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
1385 | otmp->blessed = FALSE;
1386 | otmp->cursed = TRUE;
1387 | }
1388 |
1389 | /* leaders don't tolerate inferior quality battle gear */
1390 | if (is_prince(mtmp->data)) {
1391 | if (otmp->oclass == WEAPON_CLASS && otmp->spe < 1)
1392 | otmp->spe = 1;
1393 | else if (otmp->oclass == ARMOR_CLASS && otmp->spe < 0)
1394 | otmp->spe = 0;
1395 | }
1396 |
1397 | spe = otmp->spe;
1398 | (void) mpickobj(mtmp, otmp); /* might free otmp */
1399 | return(spe);
1400 | } else return(0);
1401 | }
1402 |
1403 | #endif /* OVL1 */
1404 | #ifdef OVLB
1405 |
1406 | int
1407 | golemhp(type)
1408 | int type;
1409 | {
1410 | switch(type) {
1411 | case PM_STRAW_GOLEM: return 20;
1412 | case PM_PAPER_GOLEM: return 20;
1413 | case PM_ROPE_GOLEM: return 30;
1414 | case PM_LEATHER_GOLEM: return 40;
1415 | case PM_GOLD_GOLEM: return 40;
1416 | case PM_WOOD_GOLEM: return 50;
1417 | case PM_FLESH_GOLEM: return 40;
1418 | case PM_CLAY_GOLEM: return 50;
1419 | case PM_STONE_GOLEM: return 60;
1420 | case PM_GLASS_GOLEM: return 60;
1421 | case PM_IRON_GOLEM: return 80;
1422 | default: return 0;
1423 | }
1424 | }
1425 |
1426 | #endif /* OVLB */
1427 | #ifdef OVL1
1428 |
1429 | /*
1430 | * Alignment vs. yours determines monster's attitude to you.
1431 | * ( some "animal" types are co-aligned, but also hungry )
1432 | */
1433 | boolean
1434 | peace_minded(ptr)
1435 | register struct permonst *ptr;
1436 | {
1437 | aligntyp mal = ptr->maligntyp, ual = u.ualign.type;
1438 |
1439 | if (always_peaceful(ptr)) return TRUE;
1440 | if (always_hostile(ptr)) return FALSE;
1441 | if (ptr->msound == MS_LEADER || ptr->msound == MS_GUARDIAN)
1442 | return TRUE;
1443 | if (ptr->msound == MS_NEMESIS) return FALSE;
1444 |
1445 | if (race_peaceful(ptr)) return TRUE;
1446 | if (race_hostile(ptr)) return FALSE;
1447 |
1448 | /* the monster is hostile if its alignment is different from the
1449 | * player's */
1450 | if (sgn(mal) != sgn(ual)) return FALSE;
1451 |
1452 | /* Negative monster hostile to player with Amulet. */
1453 | if (mal < A_NEUTRAL && u.uhave.amulet) return FALSE;
1454 |
1455 | /* minions are hostile to players that have strayed at all */
1456 | if (is_minion(ptr)) return((boolean)(u.ualign.record >= 0));
1457 |
1458 | /* Last case: a chance of a co-aligned monster being
1459 | * hostile. This chance is greater if the player has strayed
1460 | * (u.ualign.record negative) or the monster is not strongly aligned.
1461 | */
1462 | return((boolean)(!!rn2(16 + (u.ualign.record < -15 ? -15 : u.ualign.record)) &&
1463 | !!rn2(2 + abs(mal))));
1464 | }
1465 |
1466 | /* Set malign to have the proper effect on player alignment if monster is
1467 | * killed. Negative numbers mean it's bad to kill this monster; positive
1468 | * numbers mean it's good. Since there are more hostile monsters than
1469 | * peaceful monsters, the penalty for killing a peaceful monster should be
1470 | * greater than the bonus for killing a hostile monster to maintain balance.
1471 | * Rules:
1472 | * it's bad to kill peaceful monsters, potentially worse to kill always-
1473 | * peaceful monsters
1474 | * it's never bad to kill a hostile monster, although it may not be good
1475 | */
1476 | void
1477 | set_malign(mtmp)
1478 | struct monst *mtmp;
1479 | {
1480 | schar mal = mtmp->data->maligntyp;
1481 | boolean coaligned;
1482 |
1483 | if (mtmp->ispriest || mtmp->isminion) {
1484 | /* some monsters have individual alignments; check them */
1485 | if (mtmp->ispriest)
1486 | mal = EPRI(mtmp)->shralign;
1487 | else if (mtmp->isminion)
1488 | mal = EMIN(mtmp)->min_align;
1489 | /* unless alignment is none, set mal to -5,0,5 */
1490 | /* (see align.h for valid aligntyp values) */
1491 | if(mal != A_NONE)
1492 | mal *= 5;
1493 | }
1494 |
1495 | coaligned = (sgn(mal) == sgn(u.ualign.type));
1496 | if (mtmp->data->msound == MS_LEADER) {
1497 | mtmp->malign = -20;
1498 | } else if (mal == A_NONE) {
1499 | if (mtmp->mpeaceful)
1500 | mtmp->malign = 0;
1501 | else
1502 | mtmp->malign = 20; /* really hostile */
1503 | } else if (always_peaceful(mtmp->data)) {
1504 | int absmal = abs(mal);
1505 | if (mtmp->mpeaceful)
1506 | mtmp->malign = -3*max(5,absmal);
1507 | else
1508 | mtmp->malign = 3*max(5,absmal); /* renegade */
1509 | } else if (always_hostile(mtmp->data)) {
1510 | int absmal = abs(mal);
1511 | if (coaligned)
1512 | mtmp->malign = 0;
1513 | else
1514 | mtmp->malign = max(5,absmal);
1515 | } else if (coaligned) {
1516 | int absmal = abs(mal);
1517 | if (mtmp->mpeaceful)
1518 | mtmp->malign = -3*max(3,absmal);
1519 | else /* renegade */
1520 | mtmp->malign = max(3,absmal);
1521 | } else /* not coaligned and therefore hostile */
1522 | mtmp->malign = abs(mal);
1523 | }
1524 |
1525 | #endif /* OVL1 */
1526 | #ifdef OVLB
1527 |
1528 | static NEARDATA char syms[] = {
1529 | MAXOCLASSES, MAXOCLASSES+1, RING_CLASS, WAND_CLASS, WEAPON_CLASS,
1530 | FOOD_CLASS, GOLD_CLASS, SCROLL_CLASS, POTION_CLASS, ARMOR_CLASS,
1531 | AMULET_CLASS, TOOL_CLASS, ROCK_CLASS, GEM_CLASS, SPBOOK_CLASS,
1532 | S_MIMIC_DEF, S_MIMIC_DEF, S_MIMIC_DEF,
1533 | };
1534 |
1535 | void
1536 | set_mimic_sym(mtmp) /* KAA, modified by ERS */
1537 | register struct monst *mtmp;
1538 | {
1539 | int typ, roomno, rt;
1540 | unsigned appear, ap_type;
1541 | int s_sym;
1542 | struct obj *otmp;
1543 | int mx, my;
1544 |
1545 | if (!mtmp) return;
1546 | mx = mtmp->mx; my = mtmp->my;
1547 | typ = levl[mx][my].typ;
1548 | /* only valid for INSIDE of room */
1549 | roomno = levl[mx][my].roomno - ROOMOFFSET;
1550 | if (roomno >= 0)
1551 | rt = rooms[roomno].rtype;
1552 | #ifdef SPECIALIZATION
1553 | else if (IS_ROOM(typ))
1554 | rt = OROOM, roomno = 0;
1555 | #endif
1556 | else rt = 0; /* roomno < 0 case for GCC_WARN */
1557 |
1558 | if (OBJ_AT(mx, my)) {
1559 | ap_type = M_AP_OBJECT;
1560 | appear = level.objects[mx][my]->otyp;
1561 | } else if (IS_DOOR(typ) || IS_WALL(typ) ||
1562 | typ == SDOOR || typ == SCORR) {
1563 | ap_type = M_AP_FURNITURE;
1564 | /*
1565 | * If there is a wall to the left that connects to this
1566 | * location, then the mimic mimics a horizontal closed door.
1567 | * This does not allow doors to be in corners of rooms.
1568 | */
1569 | if (mx != 0 &&
1570 | (levl[mx-1][my].typ == HWALL ||
1571 | levl[mx-1][my].typ == TLCORNER ||
1572 | levl[mx-1][my].typ == TRWALL ||
1573 | levl[mx-1][my].typ == BLCORNER ||
1574 | levl[mx-1][my].typ == TDWALL ||
1575 | levl[mx-1][my].typ == CROSSWALL||
1576 | levl[mx-1][my].typ == TUWALL ))
1577 | appear = S_hcdoor;
1578 | else
1579 | appear = S_vcdoor;
1580 |
1581 | if(!mtmp->minvis || See_invisible)
1582 | block_point(mx,my); /* vision */
1583 | } else if (level.flags.is_maze_lev && rn2(2)) {
1584 | ap_type = M_AP_OBJECT;
1585 | appear = STATUE;
1586 | } else if (roomno < 0) {
1587 | ap_type = M_AP_OBJECT;
1588 | appear = BOULDER;
1589 | if(!mtmp->minvis || See_invisible)
1590 | block_point(mx,my); /* vision */
1591 | } else if (rt == ZOO || rt == VAULT) {
1592 | ap_type = M_AP_OBJECT;
1593 | appear = GOLD_PIECE;
1594 | } else if (rt == DELPHI) {
1595 | if (rn2(2)) {
1596 | ap_type = M_AP_OBJECT;
1597 | appear = STATUE;
1598 | } else {
1599 | ap_type = M_AP_FURNITURE;
1600 | appear = S_fountain;
1601 | }
1602 | } else if (rt == TEMPLE) {
1603 | ap_type = M_AP_FURNITURE;
1604 | appear = S_altar;
1605 | /*
1606 | * We won't bother with beehives, morgues, barracks, throne rooms
1607 | * since they shouldn't contain too many mimics anyway...
1608 | */
1609 | } else if (rt >= SHOPBASE) {
1610 | s_sym = get_shop_item(rt - SHOPBASE);
1611 | if (s_sym < 0) {
1612 | ap_type = M_AP_OBJECT;
1613 | appear = -s_sym;
1614 | } else {
1615 | if (s_sym == RANDOM_CLASS)
1616 | s_sym = syms[rn2((int)sizeof(syms)-2) + 2];
1617 | goto assign_sym;
1618 | }
1619 | } else {
1620 | s_sym = syms[rn2((int)sizeof(syms))];
1621 | assign_sym:
1622 | if (s_sym >= MAXOCLASSES) {
1623 | ap_type = M_AP_FURNITURE;
1624 | appear = s_sym == MAXOCLASSES ? S_upstair : S_dnstair;
1625 | } else if (s_sym == GOLD_CLASS) {
1626 | ap_type = M_AP_OBJECT;
1627 | appear = GOLD_PIECE;
1628 | } else {
1629 | ap_type = M_AP_OBJECT;
1630 | if (s_sym == S_MIMIC_DEF) {
1631 | appear = STRANGE_OBJECT;
1632 | } else {
1633 | otmp = mkobj( (char) s_sym, FALSE );
1634 | appear = otmp->otyp;
1635 | /* make sure container contents are free'ed */
1636 | obfree(otmp, (struct obj *) 0);
1637 | }
1638 | }
1639 | }
1640 | mtmp->m_ap_type = ap_type;
1641 | mtmp->mappearance = appear;
1642 | }
1643 |
1644 | #endif /* OVLB */
1645 |
1646 | /*makemon.c*/