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*/