Fandom

Wikihack

Source:NetHack 3.0.0/makemon.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Below is the full text to makemon.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/makemon.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)makemon.c	3.0	88/04/11
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include	"hack.h"
6.    
7.    struct monst zeromonst;
8.    static int uncommon P((struct permonst *));
9.    
10.   static int monstr[NUMMONS];
11.   
12.   #define m_initsgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 3)
13.   #define m_initlgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 10)
14.   #define toostrong(monindx, lev) (monstr[monindx] > lev)
15.   #define tooweak(monindx, lev)	(monstr[monindx] < lev)
16.   
17.   static void
18.   m_initgrp(mtmp, x, y, n)	/* make a group just like mtmp */
19.   register struct monst *mtmp;
20.   register int x, y, n;
21.   {
22.   	coord mm;
23.   	register int cnt = rnd(n);
24.   	struct monst *mon;
25.   
26.   	mm.x = x;
27.   	mm.y = y;
28.   	while(cnt--) {
29.   		if (peace_minded(mtmp->data)) continue;
30.   		/* Don't create groups of peaceful monsters since they'll get
31.   		 * in our way.  If the monster has a percentage chance so some
32.   		 * are peaceful and some are not, the result will just be a
33.   		 * smaller group.
34.   		 */
35.   		enexto(&mm, mm.x, mm.y);
36.   		mon = makemon(mtmp->data, mm.x, mm.y);
37.   		mon->mpeaceful = 0;
38.   		set_malign(mon);
39.   		/* Undo the second peace_minded() check in makemon(); if the
40.   		 * monster turned out to be peaceful the first time we didn't
41.   		 * create it at all; we don't want a second check.
42.   		 */
43.   	}
44.   }
45.   
46.   static void
47.   m_initthrow(mtmp,otyp,oquan)
48.   struct monst *mtmp;
49.   int otyp,oquan;
50.   {
51.   	register struct obj *otmp;
52.   
53.   	otmp = mksobj(otyp,FALSE);
54.   	otmp->quan = 2 + rnd(oquan);
55.   	otmp->owt = weight(otmp);
56.   #ifdef TOLKIEN
57.   	if (otyp == ORCISH_ARROW) otmp->opoisoned = 1;
58.   #endif
59.   	mpickobj(mtmp, otmp);
60.   }
61.   
62.   static void
63.   m_initweap(mtmp)
64.   register struct monst *mtmp;
65.   {
66.   	register struct permonst *ptr = mtmp->data;
67.   #ifdef REINCARNATION
68.   	if (dlevel==rogue_level) return;
69.   #endif
70.   /*
71.    *	first a few special cases:
72.    *
73.    *		giants get a boulder to throw sometimes.
74.    *		ettins get clubs
75.    *		kobolds get darts to throw
76.    *		centaurs get some sort of bow & arrows or bolts
77.    *		soldiers get all sorts of things.
78.    *		kops get clubs & cream pies.
79.    */
80.   	switch (mtmp->data->mlet) {
81.   	    case S_GIANT:
82.   		if (rn2(2)) (void)mongets(mtmp, (ptr != &mons[PM_ETTIN]) ?
83.   				    BOULDER : CLUB);
84.   		break;
85.   	    case S_HUMAN:
86.   		if(is_mercenary(ptr))
87.   		    switch(monsndx(ptr)) {
88.   
89.   #ifdef ARMY
90.   			case PM_SOLDIER:
91.   			  (void) mongets(mtmp, rn2(2) ? SPEAR : SHORT_SWORD);
92.   			  break;
93.   			case PM_SERGEANT:
94.   			  (void) mongets(mtmp, rn2(2) ? FLAIL : MACE);
95.   			  break;
96.   			case PM_LIEUTENANT:
97.   			  (void) mongets(mtmp, rn2(2) ? GLAIVE : LONG_SWORD);
98.   			  break;
99.   			case PM_CAPTAIN:
100.  			  (void) mongets(mtmp, rn2(2) ? LONG_SWORD : SCIMITAR);
101.  			  break;
102.  #endif
103.  			default:    if (!rn2(4)) (void) mongets(mtmp, DAGGER);
104.  				    if (!rn2(7)) (void) mongets(mtmp, SPEAR);
105.  				    break;
106.  		    }
107.  		    break;
108.  
109.  	    case S_HUMANOID:
110.  #ifdef TOLKIEN
111.  		if (monsndx(ptr) == PM_HOBBIT) {
112.  		    switch (rn2(3)) {
113.  		  	case 0:
114.  			    (void)mongets(mtmp, DAGGER);
115.  			    break;
116.  			case 1:
117.  			    (void)mongets(mtmp, ELVEN_DAGGER);
118.  			    break;
119.  		      }
120.  		    if (!rn2(10)) (void)mongets(mtmp, ELVEN_MITHRIL_COAT);
121.  		} else if (is_dwarf(ptr)) {
122.  		    (void)mongets(mtmp, DWARVISH_CLOAK);
123.  		    (void)mongets(mtmp, IRON_SHOES);
124.  		    if (!rn2(4)) {
125.  			(void)mongets(mtmp, DWARVISH_SHORT_SWORD);
126.  			(void)mongets(mtmp,
127.  			    rn2(3) ? DWARVISH_MATTOCK : AXE);
128.  			(void)mongets(mtmp, DWARVISH_IRON_HELM);
129.  			(void)mongets(mtmp, DWARVISH_ROUNDSHIELD);
130.  			if (!rn2(3))
131.  			    (void)mongets(mtmp, DWARVISH_MITHRIL_COAT);
132.  		    } else {
133.  			(void)mongets(mtmp, PICK_AXE);
134.  		    }
135.  		} else if (is_elf(ptr)) {
136.  		    (void)mongets(mtmp,
137.  			rn2(2) ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
138.  		    if (rn2(2)) (void)mongets(mtmp, ELVEN_LEATHER_HELM);
139.  		    if (rn2(3)) (void)mongets(mtmp, ELVEN_DAGGER);
140.  		    switch (rn2(3)) {
141.  			case 0:
142.  			    if (!rn2(4)) (void)mongets(mtmp, ELVEN_SHIELD);
143.  			    (void)mongets(mtmp, ELVEN_SHORT_SWORD);
144.  			    (void)mongets(mtmp, ELVEN_BOW);
145.  			    m_initthrow(mtmp, ELVEN_ARROW, 12);
146.  			    break;
147.  			case 1:
148.  			    (void)mongets(mtmp, ELVEN_BROADSWORD);
149.  			    if (rn2(2)) (void)mongets(mtmp, ELVEN_SHIELD);
150.  			    break;
151.  			case 2:
152.  			    (void)mongets(mtmp, ELVEN_SPEAR);
153.  			    (void)mongets(mtmp, ELVEN_SHIELD);
154.  			    break;
155.  		    }
156.  		}
157.  #else /* TOLKIEN */
158.  		if (is_dwarf(ptr)) {
159.  		    (void)mongets(mtmp, IRON_SHOES);
160.  		    if (rn2(4) == 0) {
161.  			(void)mongets(mtmp, SHORT_SWORD);
162.  			(void)mongets(mtmp,
163.  			    (rn2(3) == 0) ? AXE : TWO_HANDED_SWORD);
164.  			(void)mongets(mtmp, LARGE_SHIELD);
165.  			if (rn2(3) == 0)
166.  			    (void)mongets(mtmp, DWARVISH_MITHRIL_COAT);
167.  		    } else {
168.  			(void)mongets(mtmp, PICK_AXE);
169.  		    }
170.  		} else if (is_elf(ptr)) {
171.  		    (void)mongets(mtmp, ELVEN_CLOAK);
172.  		    if (rn2(3)) (void)mongets(mtmp, DAGGER);
173.  		    switch (rn2(3)) {
174.  			case 0:
175.  			    if (!rn2(4)) (void)mongets(mtmp, SMALL_SHIELD);
176.  			    (void)mongets(mtmp, SHORT_SWORD);
177.  			    (void)mongets(mtmp, BOW);
178.  			    m_initthrow(mtmp, ARROW, 12);
179.  			    break;
180.  			case 1:
181.  			    (void)mongets(mtmp, BROADSWORD);
182.  			    if (rn2(2)) (void)mongets(mtmp, SMALL_SHIELD);
183.  			    break;
184.  			case 2:
185.  			    (void)mongets(mtmp, SPEAR);
186.  			    (void)mongets(mtmp, SMALL_SHIELD);
187.  			    break;
188.  		    }
189.  		}
190.  #endif /* TOLKIEN */
191.  		break;
192.  # ifdef KOPS
193.  	    case S_KOP:		/* create Keystone Kops with cream pies to
194.  				 * throw. As suggested by KAA.	   [MRS]
195.  				 */
196.  		if (!rn2(4)) m_initthrow(mtmp, CREAM_PIE, 2);
197.  		if (!rn2(3)) (void)mongets(mtmp, (rn2(2)) ? CLUB : RUBBER_HOSE);
198.  		break;
199.  #endif
200.  	    case S_ORC:
201.  #ifdef TOLKIEN
202.  		{ int mm = monsndx(ptr);
203.  		  if(rn2(2)) (void)mongets(mtmp, ORCISH_HELM);
204.  		  if (mm == PM_MORDOR_ORC ||
205.  		     (mm == PM_ORC_CAPTAIN && rn2(2))) {
206.  		      if(rn2(2)) (void)mongets(mtmp, SCIMITAR);
207.  		      if(rn2(2)) (void)mongets(mtmp, ORCISH_SHIELD);
208.  		      if(rn2(2)) (void)mongets(mtmp, KNIFE);
209.  		      if(rn2(2)) (void)mongets(mtmp, ORCISH_CHAIN_MAIL);
210.  		  } else if (mm == PM_URUK_HAI || mm == PM_ORC_CAPTAIN) {
211.  		      if(rn2(2)) (void)mongets(mtmp, ORCISH_CLOAK);
212.  		      if(rn2(2)) (void)mongets(mtmp, ORCISH_SHORT_SWORD);
213.  		      if(rn2(2)) (void)mongets(mtmp, IRON_SHOES);
214.  		      if(rn2(2)) {
215.  			  (void)mongets(mtmp, ORCISH_BOW);
216.  			  m_initthrow(mtmp, ORCISH_ARROW, 12);
217.  		      }
218.  		      if(rn2(2)) (void)mongets(mtmp, URUK_HAI_SHIELD);
219.  		  } else if (mm != PM_ORC_SHAMAN) {
220.  		      (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0) ?
221.  				    ORCISH_DAGGER : SCIMITAR);
222.  		  }
223.  		}
224.  #else /* TOLKIEN */
225.  		{ int mm = monsndx(ptr);
226.  		  if(rn2(2)) (void)mongets(mtmp, ORCISH_HELM);
227.  		  if (mm == PM_ORC_CAPTAIN) {
228.  		      if(rn2(2)) {
229.  			  if(rn2(2)) (void)mongets(mtmp, SCIMITAR);
230.  			  if(rn2(2)) (void)mongets(mtmp, SMALL_SHIELD);
231.  			  if(rn2(2)) (void)mongets(mtmp, KNIFE);
232.  			  if(rn2(2)) (void)mongets(mtmp, CHAIN_MAIL);
233.  		      } else {
234.  			  if(rn2(2)) (void)mongets(mtmp, SHORT_SWORD);
235.  			  if(rn2(2)) (void)mongets(mtmp, IRON_SHOES);
236.  			  if(rn2(2)) {
237.  			      (void)mongets(mtmp, BOW);
238.  			      m_initthrow(mtmp, ARROW, 12);
239.  			  }
240.  			  if(rn2(2)) (void)mongets(mtmp, SMALL_SHIELD);
241.  		      }
242.  		  } else if (mm != PM_ORC_SHAMAN) {
243.  		      (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0) ?
244.  				    DAGGER : SCIMITAR);
245.  		  }
246.  		}
247.  #endif /* TOLKIEN */
248.  		break;
249.  	    case S_KOBOLD:
250.  		if (!rn2(4)) m_initthrow(mtmp, DART, 12);
251.  		break;
252.  
253.  	    case S_CENTAUR:
254.  		if (rn2(2)) {
255.  		    if(ptr == &mons[PM_FOREST_CENTAUR]) {
256.  			(void)mongets(mtmp, BOW);
257.  			m_initthrow(mtmp, ARROW, 12);
258.  		    } else {
259.  			(void)mongets(mtmp, CROSSBOW);
260.  			m_initthrow(mtmp, CROSSBOW_BOLT, 12);
261.  		    }
262.  		}
263.  		break;
264.  	    case S_WRAITH:
265.  		(void)mongets(mtmp, KNIFE);
266.  		(void)mongets(mtmp, LONG_SWORD);
267.  		break;
268.  	    case S_DEMON:
269.  #ifdef HARD
270.  		if (monsndx(ptr) == PM_BALROG) {
271.  		    (void)mongets(mtmp, BULLWHIP);
272.  		    (void)mongets(mtmp, BROADSWORD);
273.  		    break;
274.  		}
275.  #endif
276.  		/* prevent djinnis and mail daemons from leaving objects when
277.  		 * they vanish
278.  		 */
279.  		if (!is_demon(ptr)) break;
280.  		/* fall thru */
281.  /*
282.   *	Now the general case, ~40% chance of getting some type
283.   *	of weapon. TODO: Add more weapons types (use bigmonst());
284.   */
285.  	    default:
286.  		switch(rnd(12)) {
287.  		    case 1:
288.  			m_initthrow(mtmp, DART, 12);
289.  			break;
290.  		    case 2:
291.  			(void) mongets(mtmp, CROSSBOW);
292.  			m_initthrow(mtmp, CROSSBOW_BOLT, 12);
293.  			break;
294.  		    case 3:
295.  			(void) mongets(mtmp, BOW);
296.  			m_initthrow(mtmp, ARROW, 12);
297.  			break;
298.  		    case 4:
299.  			m_initthrow(mtmp, DAGGER, 3);
300.  			break;
301.  		    case 5:
302.  			(void) mongets(mtmp, AKLYS);
303.  			break;
304.  		    default:
305.  			break;
306.  		}
307.  		break;
308.  	}
309.  }
310.  
311.  static void
312.  m_initinv(mtmp)
313.  register struct	monst	*mtmp;
314.  {
315.  	register int cnt;
316.  	register struct obj *otmp;
317.  	register struct permonst *ptr = mtmp->data;
318.  #ifdef REINCARNATION
319.  	if (dlevel==rogue_level) return;
320.  #endif
321.  /*
322.   *	Soldiers get armour & rations - armour approximates their ac.
323.   *	Nymphs may get mirror or potion of object detection.
324.   */
325.  	switch(mtmp->data->mlet) {
326.  
327.  	    case S_HUMAN:
328.  		if(is_mercenary(ptr)) {
329.  		    register int mac;
330.  
331.  		    if((mac = ptr->ac) < -1)
332.  			mac += 7 + mongets(mtmp, (rn2(5)) ?
333.  					   PLATE_MAIL : CRYSTAL_PLATE_MAIL);
334.  		    else if(mac < 3)
335.  			mac += 6 + mongets(mtmp, (rn2(3)) ?
336.  					   SPLINT_MAIL : BANDED_MAIL);
337.  		    else
338.  			mac += 3 + mongets(mtmp, (rn2(3)) ?
339.  					   RING_MAIL : STUDDED_LEATHER_ARMOR);
340.  
341.  		    if(mac < 10) {
342.  			mac += 1 + mongets(mtmp, HELMET);
343.  			if(mac < 10) {
344.  			    mac += 1 + mongets(mtmp, SMALL_SHIELD);
345.  			    if(mac < 10) {
346.  				mac += 1 + mongets(mtmp, ELVEN_CLOAK);
347.  				if(mac < 10)
348.  				    mac += 1 +mongets(mtmp, LEATHER_GLOVES);
349.  			    }
350.  			}
351.  		    }
352.  
353.  		    if(mac != 10) {	/* make up the difference */
354.  			otmp = mksobj(RIN_PROTECTION,FALSE);
355.  			otmp->spe = (10 - mac);
356.  			if(otmp->spe < 0) curse(otmp);
357.  			mpickobj(mtmp, otmp);
358.  		    }
359.  #ifdef ARMY
360.  		    if(ptr != &mons[PM_GUARD]) {
361.  			if (!rn2(3)) (void) mongets(mtmp, K_RATION);
362.  			if (!rn2(2)) (void) mongets(mtmp, C_RATION);
363.  		    }
364.  #endif
365.  		}
366.  		break;
367.  
368.  	    case S_NYMPH:
369.  #ifdef MEDUSA
370.  		if(!rn2(2)) (void) mongets(mtmp, MIRROR);
371.  #endif
372.  		if(!rn2(2)) (void) mongets(mtmp, POT_OBJECT_DETECTION);
373.  		break;
374.  
375.  	    case S_GIANT:
376.  		if(mtmp->data == &mons[PM_MINOTAUR])
377.  		    (void) mongets(mtmp, WAN_DIGGING);
378.  		else if (is_giant(mtmp->data)) {
379.  		    for(cnt = rn2((int)(mtmp->m_lev / 2)); cnt; cnt--) {
380.  			    do
381.  				otmp = mkobj(GEM_SYM,FALSE);
382.  			    while (otmp->otyp >= LAST_GEM+5);
383.  			    otmp->quan = 2 + rnd(2);
384.  			    otmp->owt = weight(otmp);
385.  			    mpickobj(mtmp, otmp);
386.  		    }
387.  		}
388.  		break;
389.  #ifdef TOLKIEN
390.  	    case S_WRAITH:
391.  		if(mtmp->data == &mons[PM_NAZGUL]) {
392.  			otmp = mksobj(RIN_INVISIBILITY, FALSE);
393.  			curse(otmp);
394.  			mpickobj(mtmp, otmp);
395.  		}
396.  		break;
397.  #endif
398.  	    default:
399.  		break;
400.  	}
401.  }
402.  
403.  /*
404.   * called with [x,y] = coordinates;
405.   *	[0,0] means anyplace
406.   *	[u.ux,u.uy] means: call mnexto (if !in_mklev)
407.   *
408.   *	In case we make a monster group, only return the one at [x,y].
409.   */
410.  struct monst *
411.  makemon(ptr, x, y)
412.  register struct permonst *ptr;
413.  register int	x, y;
414.  {
415.  	register struct monst *mtmp;
416.  	register int	ct;
417.  	boolean anything = (!ptr);
418.  
419.  	/* if caller wants random location, do it here */
420.  	if(x == 0 && y == 0) {
421.  		do {
422.  			x = rn1(COLNO-3,2);
423.  			y = rn2(ROWNO);
424.  		} while(!goodpos(x, y));
425.  	}
426.  
427.  	/* if a monster already exists at the position, return */
428.  	if(levl[x][y].mmask) return((struct monst *) 0);
429.  
430.  	if(ptr){
431.  		/* if you are to make a specific monster and it has 
432.  		   already been genocided, return */
433.  		if(ptr->geno & G_GENOD) return((struct monst *) 0);
434.  	} else {
435.  		/* make a random (common) monster. */
436.  #ifdef REINCARNATION
437.  		if (!(ptr = (dlevel==rogue_level) ? roguemon() : rndmonst()))
438.  #else
439.  		if(!(ptr = rndmonst()))
440.  #endif
441.  		{
442.  #ifdef DEBUG
443.  		    pline("Warning: no monster.");
444.  #endif
445.  		    return((struct monst *) 0);	/* no more monsters! */
446.  		}
447.  	}
448.  	/* if it's unique, don't ever make it again */
449.  	if (ptr->geno & G_UNIQ) ptr->geno &= G_GENOD;
450.  /* gotmon:	/* label not referenced */
451.  	mtmp = newmonst(ptr->pxlth);
452.  	*mtmp = zeromonst;		/* clear all entries in structure */
453.  	for(ct = 0; ct < ptr->pxlth; ct++)
454.  		((char *) &(mtmp->mextra[0]))[ct] = 0;
455.   	if(type_is_pname(ptr))
456.   		Strcpy(NAME(mtmp), ptr->mname);
457.  	mtmp->nmon = fmon;
458.  	fmon = mtmp;
459.  	mtmp->m_id = flags.ident++;
460.  	mtmp->data = ptr;
461.  	mtmp->mxlth = ptr->pxlth;
462.  
463.  	mtmp->m_lev = adj_lev(ptr);
464.  #ifdef GOLEMS
465.  	if (is_golem(ptr))
466.  	    mtmp->mhpmax = mtmp->mhp = golemhp(monsndx(ptr));
467.  	else
468.  #endif /* GOLEMS */
469.   	if(ptr->mlevel > 49) {
470.  	    /* "special" fixed hp monster
471.  	     * the hit points are encoded in the mlevel in a somewhat strange
472.  	     * way to fit in the 50..127 positive range of a signed character
473.  	     * above the 1..49 that indicate "normal" monster levels */
474.   	    mtmp->mhpmax = mtmp->mhp = 2*(ptr->mlevel - 6);
475.   	    mtmp->m_lev = mtmp->mhp / 4;	/* approximation */
476.   	} else if((ptr->mlet == S_DRAGON) && (ptr >= &mons[PM_GREY_DRAGON]))
477.  	    mtmp->mhpmax = mtmp->mhp = 80;
478.  	else if(!mtmp->m_lev) mtmp->mhpmax = mtmp->mhp = rnd(4);
479.  	else mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, 8);
480.  	mtmp->mx = x;
481.  	mtmp->my = y;
482.  	levl[x][y].mmask = 1;
483.  	mtmp->mcansee = 1;
484.  	mtmp->mpeaceful = peace_minded(ptr);
485.  
486.  	switch(ptr->mlet) {
487.  		case S_MIMIC:
488.  			set_mimic_sym(mtmp);
489.  			break;
490.  		case S_SPIDER:
491.  		case S_SNAKE:
492.  			mtmp->mhide = mtmp->mundetected = 1;
493.  			if(in_mklev)
494.  			    if(mtmp->mx && mtmp->my)
495.  				(void) mkobj_at(0, mtmp->mx, mtmp->my);
496.  			break;
497.  		case S_CHAMELEON:
498.  			/* If you're protected with a ring, don't create
499.  			 * any shape-changing chameleons -dgk
500.  			 */
501.  			if (Protection_from_shape_changers)
502.  				mtmp->cham = 0;
503.  			else {
504.  				mtmp->cham = 1;
505.  				(void) newcham(mtmp, rndmonst());
506.  			}
507.  			break;
508.  		case S_STALKER:
509.  		case S_EEL:
510.  			mtmp->minvis = 1;
511.  			break;
512.  		case S_LEPRECHAUN:
513.  			mtmp->msleep = 1;
514.  			break;
515.  		case S_NYMPH:
516.  			if(rn2(5) && !u.uhave_amulet) mtmp->msleep = 1;
517.  			break;
518.  		case S_UNICORN:
519.  			if ((ptr==&mons[PM_WHITE_UNICORN] && 
520.  				u.ualigntyp == U_LAWFUL) ||
521.  			(ptr==&mons[PM_GREY_UNICORN] && 
522.  				u.ualigntyp == U_NEUTRAL) ||
523.  			(ptr==&mons[PM_BLACK_UNICORN] && 
524.  				u.ualigntyp == U_CHAOTIC))
525.  				mtmp->mpeaceful = 1;
526.  			break;
527.  	}
528.  	if (ptr == &mons[PM_WIZARD_OF_YENDOR]) {
529.  		mtmp->iswiz = 1;
530.  		flags.no_of_wizards++;
531.  	}
532.  
533.  	if(in_mklev) {
534.  		if(((is_ndemon(ptr)) ||
535.  		    (ptr == &mons[PM_WUMPUS]) ||
536.  #ifdef WORM
537.  		    (ptr == &mons[PM_LONG_WORM]) ||
538.  #endif
539.  		    (ptr == &mons[PM_GIANT_EEL])) && rn2(5))
540.  			mtmp->msleep = 1;
541.  	} else {
542.  		if(x == u.ux && y == u.uy && ptr->mlet != S_GHOST) {
543.  			mnexto(mtmp);
544.  			if (ptr->mlet == S_MIMIC) set_mimic_sym(mtmp);
545.  		}
546.  	}
547.  #ifdef HARD
548.  	if(is_dprince(ptr)) {
549.  	    mtmp->mpeaceful = mtmp->minvis = 1;
550.  # ifdef NAMED_ITEMS
551.  	    if(uwep)
552.  		if(!strcmp(ONAME(uwep), "Excalibur"))
553.  		    mtmp->mpeaceful = mtmp->mtame = 0;
554.  # endif
555.  	}
556.  #endif
557.  #ifdef WORM
558.  	if(ptr == &mons[PM_LONG_WORM] && getwn(mtmp))  initworm(mtmp);
559.  #endif
560.  	set_malign(mtmp);		/* having finished peaceful changes */
561.  	if(anything) {
562.  	    if((ptr->geno & G_SGROUP) && rn2(2))
563.  		m_initsgrp(mtmp, mtmp->mx, mtmp->my);
564.  	    else if(ptr->geno & G_LGROUP) {
565.  			if(rn2(3))  m_initlgrp(mtmp, mtmp->mx, mtmp->my);
566.  			else	    m_initsgrp(mtmp, mtmp->mx, mtmp->my);
567.  	    }
568.  	}
569.  
570.  	if(is_armed(ptr))
571.  		m_initweap(mtmp);	/* equip with weapons / armour */
572.  	m_initinv(mtmp);		/* add on a few special items */
573.  
574.  	return(mtmp);
575.  }
576.  
577.  void
578.  enexto(cc, xx,yy)
579.  coord *cc;
580.  register xchar xx, yy;
581.  {
582.  	register xchar x,y;
583.  	coord foo[15], *tfoo;
584.  	int range, i;
585.  
586.  	tfoo = foo;
587.  	range = 1;
588.  	do {	/* full kludge action. */
589.  		for(x = xx-range; x <= xx+range; x++)
590.  			if(goodpos(x, yy-range)) {
591.  				tfoo->x = x;
592.  				(tfoo++)->y = yy-range;
593.  				if(tfoo == &foo[15]) goto foofull;
594.  			}
595.  		for(x = xx-range; x <= xx+range; x++)
596.  			if(goodpos(x,yy+range)) {
597.  				tfoo->x = x;
598.  				(tfoo++)->y = yy+range;
599.  				if(tfoo == &foo[15]) goto foofull;
600.  			}
601.  		for(y = yy+1-range; y < yy+range; y++)
602.  			if(goodpos(xx-range,y)) {
603.  				tfoo->x = xx-range;
604.  				(tfoo++)->y = y;
605.  				if(tfoo == &foo[15]) goto foofull;
606.  			}
607.  		for(y = yy+1-range; y < yy+range; y++)
608.  			if(goodpos(xx+range,y)) {
609.  				tfoo->x = xx+range;
610.  				(tfoo++)->y = y;
611.  				if(tfoo == &foo[15]) goto foofull;
612.  			}
613.  		range++;
614.  	} while(tfoo == foo);
615.  foofull:
616.  	i = rn2(tfoo - foo);
617.  	cc->x = foo[i].x;
618.  	cc->y = foo[i].y;
619.  	return;
620.  }
621.  
622.  int
623.  goodpos(x, y)
624.  {
625.  #ifdef STUPID
626.  	if (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
627.  	    levl[x][y].mmask || !ACCESSIBLE(levl[x][y].typ))
628.  	  return 0;
629.  	if (IS_DOOR(levl[x][y].typ) &&
630.  	    (levl[x][y].doormask & (D_LOCKED | D_CLOSED)))
631.  	  return 0;
632.  	return !((x == u.ux && y == u.uy) || sobj_at(BOULDER, x, y));
633.  #else
634.  	return
635.  	! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
636.  	   levl[x][y].mmask || !ACCESSIBLE(levl[x][y].typ) ||
637.  	   (IS_DOOR(levl[x][y].typ) && 
638.  		(levl[x][y].doormask & (D_LOCKED | D_CLOSED)) )
639.  	   || (x == u.ux && y == u.uy)
640.  	   || sobj_at(BOULDER, x, y)
641.  	);
642.  #endif /* STUPID */
643.  }
644.  
645.  void
646.  rloc(mtmp)
647.  struct monst *mtmp;
648.  {
649.  	register int tx, ty;
650.  
651.  #ifdef WORM		/* do not relocate worms */
652.  	if(mtmp->wormno && mtmp->mx) return;
653.  #endif
654.  	/* if the wiz teleports away to heal, try the up staircase,
655.  	   to block the player's escaping before he's healed */
656.  	if(!mtmp->iswiz || !goodpos(tx = xupstair, ty = yupstair))
657.  	   do {
658.  		tx = rn1(COLNO-3,2);
659.  		ty = rn2(ROWNO);
660.  	   } while(!goodpos(tx,ty));
661.  	if(mtmp->mx != 0 && mtmp->my != 0)
662.  		levl[mtmp->mx][mtmp->my].mmask = 0;
663.  	mtmp->mx = tx;
664.  	mtmp->my = ty;
665.  	levl[tx][ty].mmask = 1;
666.  	if(u.ustuck == mtmp){
667.  		if(u.uswallow) {
668.  			u.ux = tx;
669.  			u.uy = ty;
670.  			docrt();
671.  		} else	u.ustuck = 0;
672.  	}
673.  	pmon(mtmp);
674.  	set_apparxy(mtmp);
675.  }
676.  
677.  struct monst *
678.  mkmon_at(name, x, y)
679.  char *name;
680.  register int x,y;
681.  {
682.  	register int ct;
683.  	register struct permonst *ptr;
684.  
685.  	for(ct = PM_CHAMELEON; ct >= 0; ct--) { /* Chameleon is last monster */
686.  		ptr = &mons[ct];
687.  		if(!strcmp(ptr->mname, name))
688.  			return(makemon(ptr, x, y));
689.  	}
690.  	return((struct monst *)0);
691.  }
692.  
693.  static int
694.  cmnum()	{	/* return the number of "common" monsters */
695.  
696.  	int	i, count;
697.  
698.  	for(i = count = 0; mons[i].mlet; i++)
699.  	   if(!uncommon(&mons[i]))  count++;
700.  
701.  	return(count);
702.  }
703.  
704.  static int
705.  uncommon(ptr)
706.  struct	permonst *ptr;
707.  {
708.  	return (ptr->geno & (G_GENOD | G_NOGEN | G_UNIQ)) ||
709.  		(!Inhell ? ptr->geno & G_HELL : ptr->maligntyp > 0);
710.  }
711.  
712.  /* This routine is designed to return an integer value which represents
713.   * an approximation of monster strength.  It uses a similar method of
714.   * determination as "experience()" to arrive at the strength.
715.   */
716.  static int
717.  mstrength(ptr)
718.  struct permonst *ptr;
719.  {
720.  	int	i, tmp2, n, tmp = ptr->mlevel;
721.  
722.   	if(tmp > 49)		/* special fixed hp monster */
723.  	    tmp = 2*(tmp - 6) / 4;
724.  
725.  /*	For creation in groups */
726.  	n = (!!(ptr->geno & G_SGROUP));
727.  	n += (!!(ptr->geno & G_LGROUP)) << 1;
728.  
729.  /*	For higher ac values */
730.  	n += (ptr->ac < 0);
731.  
732.  /*	For very fast monsters */
733.  	n += (ptr->mmove >= 18);
734.  
735.  /*	For each attack and "special" attack */
736.  	for(i = 0; i < NATTK; i++) {
737.  
738.  	    tmp2 = ptr->mattk[i].aatyp;
739.  	    n += (tmp2 > 0);
740.  	    n += (tmp2 == AT_MAGC);
741.  	}
742.  
743.  /*	For each "special" damage type */
744.  	for(i = 0; i < NATTK; i++) {
745.  
746.  	    tmp2 = ptr->mattk[i].adtyp;
747.  	    if((tmp2 == AD_DRLI) || (tmp2 == AD_STON)) n += 2;
748.  	    else n += (tmp2 != AD_PHYS);
749.  	    n += ((ptr->mattk[i].damd * ptr->mattk[i].damn) > 23);
750.  	}
751.  
752.  /*	Finally, adjust the monster level  0 <= n <= 24 (approx.) */
753.  	if(n == 0) tmp--;
754.  	else if(n >= 6) tmp += ( n / 2 );
755.  	else tmp += ( n / 3 + 1);
756.  
757.  	return((tmp >= 0) ? tmp : 0);
758.  }
759.  
760.  void
761.  init_monstr()
762.  {
763.  	register int ct;
764.  
765.  	for(ct = 0; mons[ct].mlet; ct++)
766.  		monstr[ct] = mstrength(&(mons[ct]));
767.  }
768.  
769.  struct	permonst *
770.  rndmonst() {		/* select a random monster */
771.  	register struct permonst *ptr;
772.  	register int i, ct;
773.  	register int zlevel;
774.  	static int minmlev, maxmlev, accept;
775.  	static long oldmoves = 0L;	/* != 1, starting value of moves */
776.  
777.  	if(oldmoves != moves) {		/* must recalculate accept */
778.  	    oldmoves = moves;
779.  	    zlevel = u.uhave_amulet ? MAXLEVEL : dlevel;
780.  	    if(cmnum() <= 0) {
781.  #ifdef DEBUG
782.  		pline("cmnum() fails!");
783.  #endif
784.  		return((struct permonst *) 0);
785.  	    }
786.  
787.  	    /* determine the level of the weakest monster to make. */
788.  	    minmlev = zlevel/6;
789.  	    /* determine the level of the strongest monster to make. */
790.  	    maxmlev = (zlevel + u.ulevel)>>1;
791.  /*
792.   *	Find out how many monsters exist in the range we have selected.
793.   */
794.  	    for(accept = ct = 0 ; mons[ct].mlet; ct++) {
795.  		ptr = &(mons[ct]);
796.  		if(uncommon(ptr)) continue;
797.  		if(tooweak(ct, minmlev) || toostrong(ct, maxmlev))
798.  		    continue;
799.  		accept += (ptr->geno & G_FREQ);
800.  	    }
801.  	}
802.  
803.  	if(!accept) {
804.  #ifdef DEBUG
805.  		pline("no accept!");
806.  #endif
807.  		return((struct permonst *) 0);
808.  	}
809.  /*
810.   *	Now, select a monster at random.
811.   */
812.  	ct = rnd(accept);
813.  	for(i = 0; mons[i].mlet && ct > 0; i++) {
814.  		ptr = &(mons[i]);
815.  		if(uncommon(ptr)) continue;
816.  		if(tooweak(i, minmlev) || toostrong(i, maxmlev))
817.  		    continue;
818.  		ct -= (ptr->geno & G_FREQ);
819.  	}
820.  	if(ct > 0) {
821.  #ifdef DEBUG
822.  		pline("no count!");
823.  #endif
824.  		return((struct permonst *) 0);
825.  	}
826.  	return(ptr);
827.  }
828.  
829.  /*	The routine below is used to make one of the multiple types
830.   *	of a given monster class.  It will return 0 if no monsters
831.   *	in that class can be made.
832.   */
833.  
834.  struct permonst *
835.  mkclass(mlet)
836.  char	mlet;
837.  {
838.  	register int	first, last, num = 0;
839.  
840.  	if(!mlet) {
841.  	    impossible("mkclass called with null arg!");
842.  	    return((struct permonst *) 0);
843.  	}
844.  /*	Assumption #1:	monsters of a given class are contiguous in the
845.   *			mons[] array.
846.   */
847.  	for(first = 0; mons[first].mlet != mlet; first++)
848.  		if(!mons[first].mlet)	return((struct permonst *) 0);
849.  
850.  	for(last = first; mons[last].mlet && mons[last].mlet == mlet; last++)
851.  	    if(!(mons[last].geno & (G_GENOD | G_NOGEN | G_UNIQ)))
852.  		num += mons[last].geno & G_FREQ;
853.  
854.  	if(!num) return((struct permonst *) 0);
855.  
856.  /*	Assumption #2:	monsters of a given class are presented in ascending
857.   *			order of strength.
858.   */
859.  	for(num = rnd(num); num > 0; first++)
860.  	    if(!(mons[first].geno & (G_GENOD | G_NOGEN | G_UNIQ))) { /* consider it */
861.  		/* skew towards lower value monsters at lower exp. levels */
862.  		if(adj_lev(&mons[first]) > (u.ulevel*2)) num--;
863.  		num -= mons[first].geno & G_FREQ;
864.  	    }
865.  	first--; /* correct an off-by-one error */
866.  
867.  	return(&mons[first]);
868.  }
869.  
870.  int
871.  adj_lev(ptr)	/* adjust strength of monsters based on dlevel and u.ulevel */
872.  register struct permonst *ptr;
873.  {
874.  	int	tmp, tmp2;
875.  
876.  	if((tmp = ptr->mlevel) > 49) return(50); /* "special" demons/devils */
877.  	tmp2 = (dlevel - tmp);
878.  	if(tmp2 < 0) tmp--;		/* if mlevel > dlevel decrement tmp */
879.  	else tmp += (tmp2 / 5);		/* else increment 1 per five diff */
880.  
881.  	tmp2 = (u.ulevel - ptr->mlevel);	/* adjust vs. the player */
882.  	if(tmp2 > 0) tmp += (tmp2 / 4);		/* level as well */
883.  
884.  	tmp2 = 3 * ptr->mlevel/ 2;		/* crude upper limit */
885.  	return((tmp > tmp2) ? tmp2 : (tmp > 0 ? tmp : 0)); /* 0 lower limit */
886.  }
887.  
888.  struct permonst *
889.  grow_up(mtmp)		/* mon mtmp "grows up" to a bigger version. */
890.  register struct monst *mtmp;
891.  {
892.  	register int newtype;
893.  	register struct permonst *ptr = mtmp->data;
894.  
895.  	if (ptr->mlevel >= 50 || mtmp->mhpmax <= 8*mtmp->m_lev)
896.  	    return ptr;
897.  	newtype = little_to_big(monsndx(ptr));
898.  	if (++mtmp->m_lev >= mons[newtype].mlevel) {
899.  		if (mons[newtype].geno & G_GENOD) {
900.  			pline("As %s grows up into a%s %s, %s dies!",
901.  				mon_nam(mtmp),
902.  				index(vowels,*mons[newtype].mname) ? "n" : "",
903.  				mons[newtype].mname,
904.  				mon_nam(mtmp));
905.  			mondied(mtmp);
906.  			return (struct permonst *)0;
907.  		}
908.  		mtmp->data = &mons[newtype];
909.  		mtmp->m_lev = mons[newtype].mlevel;
910.  	}
911.  	if (mtmp->m_lev > 3*mtmp->data->mlevel / 2)
912.  		mtmp->m_lev = 3*mtmp->data->mlevel / 2;
913.  	return(mtmp->data);
914.  }
915.  
916.  int
917.  mongets(mtmp, otyp)
918.  register struct monst *mtmp;
919.  register int otyp;
920.  {
921.  	register struct obj *otmp;
922.  
923.  	if((otmp = (otyp) ? mksobj(otyp,FALSE) : mkobj(otyp,FALSE))) {
924.  	    if (mtmp->data->mlet == S_DEMON) {
925.  		/* demons always get cursed objects */
926.  		curse(otmp);
927.  	    }
928.  	    mpickobj(mtmp, otmp);
929.  	    return(otmp->spe);	    
930.  	} else return(0);
931.  }
932.  
933.  #ifdef REINCARNATION
934.  struct permonst *
935.  roguemon()
936.  {
937.  /* Make a monster for a Rogue-like level; only capital letters.  There are
938.   * no checks for "too hard" or "too easy", though dragons are specifically
939.   * ruled out because playtesting showed they made the level too hard.
940.   * Modified from rndmonst().
941.   */
942.  #define isupper(x) ('A'<=(x) && (x)<='Z')
943.  	register struct permonst *ptr;
944.  	register int accept,ct,i;
945.  
946.  	/* See how many there are. */
947.  	accept = 0;
948.  	for(ct = PM_APE ; isupper(mons[ct].mlet); ct++) {
949.  		if (mons[ct].mlet == S_DRAGON) continue;
950.  		ptr = &(mons[ct]);
951.  		if(uncommon(ptr)) continue;
952.  		accept += (ptr->geno & G_FREQ);
953.  	}
954.  	if(!accept) return((struct permonst *) 0);
955.  
956.  	/* Now, select one at random. */
957.  	ct = rnd(accept);
958.  	for(i = PM_APE; isupper(mons[i].mlet) && ct > 0; i++) {
959.  		if (mons[i].mlet == S_DRAGON) continue;
960.  		ptr = &(mons[i]);
961.  		if(uncommon(ptr)) continue;
962.  		ct -= (ptr->geno & G_FREQ);
963.  	}
964.  	if(ct > 0) return((struct permonst *) 0);
965.  	return(ptr);
966.  }
967.  #endif
968.  
969.  #ifdef GOLEMS
970.  int
971.  golemhp(type)
972.  int type;
973.  {
974.  	switch(type) {
975.  		case PM_STRAW_GOLEM: return 20;
976.  		case PM_ROPE_GOLEM: return 30;
977.  		case PM_LEATHER_GOLEM: return 40;
978.  		case PM_WOOD_GOLEM: return 50;
979.  		case PM_FLESH_GOLEM: return 40;
980.  		case PM_CLAY_GOLEM: return 50;
981.  		case PM_STONE_GOLEM: return 60;
982.  		case PM_IRON_GOLEM: return 80;
983.  		default: return 0;
984.  	}
985.  }
986.  #endif /* GOLEMS */
987.  
988.  /*
989.   *	Alignment vs. yours determines monster's attitude to you.
990.   *	( some "animal" types are co-aligned, but also hungry )
991.   */
992.  boolean
993.  peace_minded(ptr)
994.  register struct permonst *ptr;
995.  {
996.  	schar mal = ptr->maligntyp, ual = u.ualigntyp;
997.  
998.  	if (always_peaceful(ptr)) return TRUE;
999.  	if (always_hostile(ptr)) return FALSE;
1000. 
1001. 	/* the monster is hostile if its alignment is different from the
1002. 	 * player's */
1003. 	if (sgn(mal) != sgn(ual)) return FALSE;
1004. 
1005. 	/* Negative monster hostile to player with Amulet. */
1006. 	if (mal < 0 && u.uhave_amulet) return FALSE;
1007. 
1008. 	/* Last case:  a chance of a co-aligned monster being
1009. 	 * hostile.  This chance is greater if the player has strayed
1010. 	 * (u.ualign negative) or the monster is not strongly aligned.
1011. 	 */
1012. 	return !!rn2(16 + (u.ualign < -15 ? -15 : u.ualign)) &&
1013. 		!!rn2(2 + abs(mal));
1014. }
1015. 
1016. /* Set malign to have the proper effect on player alignment if monster is
1017.  * killed.  Negative numbers mean it's bad to kill this monster; positive
1018.  * numbers mean it's good.  Since there are more hostile monsters than
1019.  * peaceful monsters, the penalty for killing a peaceful monster should be
1020.  * greater than the bonus for killing a hostile monster to maintain balance.
1021.  * Rules:
1022.  *   it's bad to kill peaceful monsters, potentially worse to kill always-
1023.  *	peaceful monsters
1024.  *   it's never bad to kill a hostile monster, although it may not be good
1025.  */
1026. void
1027. set_malign(mtmp)
1028. struct monst *mtmp;
1029. {
1030. 	schar mal = mtmp->data->maligntyp;
1031. 	boolean coaligned = (sgn(mal) == sgn(u.ualigntyp));
1032. 
1033. 	if (always_peaceful(mtmp->data))
1034. 		mtmp->malign = -3*max(5,abs(mal));
1035. 	else if (always_hostile(mtmp->data)) {
1036. 		if (coaligned)
1037. 			mtmp->malign = 0;
1038. 		else
1039. 			mtmp->malign = max(5,abs(mal));
1040. 	} else if (coaligned) {
1041. 		if (mtmp->mpeaceful)
1042. 			mtmp->malign = -3*max(3,abs(mal));
1043. 		else	/* renegade */
1044. 			mtmp->malign = max(3,abs(mal));
1045. 	} else	/* not coaligned and therefore hostile */
1046. 		mtmp->malign = abs(mal);
1047. }
1048. 
1049. static char syms[] = { 0, 0, RING_SYM, WAND_SYM, WEAPON_SYM, FOOD_SYM, GOLD_SYM,
1050. 	SCROLL_SYM, POTION_SYM, ARMOR_SYM, AMULET_SYM, TOOL_SYM, ROCK_SYM,
1051. 	GEM_SYM,
1052. #ifdef SPELLS
1053. 	SPBOOK_SYM,
1054. #endif
1055. 	S_MIMIC_DEF, S_MIMIC_DEF, S_MIMIC_DEF,
1056. };
1057. 
1058. void
1059. set_mimic_sym(mtmp) /* KAA */
1060. register struct monst *mtmp;
1061. {
1062. 	int roomno, rt;
1063. 	char sym;
1064. 	if (!mtmp) return;
1065. 
1066. 	syms[0] = UP_SYM;
1067. 	syms[1] = DN_SYM;
1068. 
1069. 	mtmp->mimic = 1;
1070. 	roomno = inroom(mtmp->mx, mtmp->my);
1071. 	if (levl[mtmp->mx][mtmp->my].gmask)
1072. 		sym = GOLD_SYM;
1073. 	else if (levl[mtmp->mx][mtmp->my].omask)
1074. 		sym = o_at(mtmp->mx,mtmp->my)->olet;
1075. 	else if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ) ||
1076. 		 IS_WALL(levl[mtmp->mx][mtmp->my].typ))
1077. 		sym = DOOR_SYM;
1078. 	else if (is_maze_lev)
1079. 		sym = rn2(2) ? ROCK_SYM : syms[rn2(sizeof syms)];
1080. 	else if (roomno < 0)
1081. 		sym = ROCK_SYM;
1082. 	else if ((rt = rooms[roomno].rtype) == ZOO || rt == VAULT)
1083. 		sym = GOLD_SYM;
1084. #ifdef ORACLE
1085. 	else if (rt == DELPHI)
1086. 		sym = rn2(2) ? ROCK_SYM : FOUNTAIN_SYM;
1087. #endif
1088. #ifdef ALTARS
1089. 	else if (rt == TEMPLE)
1090. 		sym = ALTAR_SYM;
1091. #endif
1092. 	/* We won't bother with beehives, morgues, barracks, throne rooms
1093. 	 * since they shouldn't contain mimics anyway...
1094. 	 */
1095. 	else if (rt >= SHOPBASE) {
1096. 		int s_sym = get_shop_item(rt - SHOPBASE);
1097. 
1098. 		if (s_sym < 0) sym = objects[-sym].oc_olet;
1099. 		else if (sym == RANDOM_SYM)
1100. 			sym = syms[rn2(sizeof(syms)-2) + 2];
1101. 		else sym = s_sym;
1102. 	} else sym = syms[rn2(sizeof syms)];
1103. 	mtmp->mappearance = sym;
1104. }

Also on Fandom

Random Wiki