Source:NetHack 3.3.0/minion.c

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

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

1.   /*	SCCS Id: @(#)minion.c	3.3	1999/02/08	*/ 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 "emin.h"  7.    #include "epri.h"  8. 9.   void 10.  msummon(ptr)		/* ptr summons a monster */ 11.  register struct permonst *ptr; 12.  {  13.   	register int dtype = 0, cnt = 0; 14.  	aligntyp atyp = sgn(ptr->maligntyp); 15.   16.   	if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) { 17.  	    dtype = (!rn2(20)) ? dprince(atyp) : 18.  				 (!rn2(4)) ? dlord(atyp) : ndemon(atyp); 19.  	    cnt = (!rn2(4) && !is_ndemon(&mons[dtype])) ? 2 : 1; 20.   	} else if (is_dlord(ptr)) { 21.  	    dtype = (!rn2(50)) ? dprince(atyp) : 22.  				 (!rn2(20)) ? dlord(atyp) : ndemon(atyp); 23.  	    cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1; 24.   	} else if (is_ndemon(ptr)) { 25.  	    dtype = (!rn2(20)) ? dlord(atyp) : 26.  				 (!rn2(6)) ? ndemon(atyp) : monsndx(ptr); 27.  	    cnt = 1; 28.  	} else if (is_lminion(ptr)) { 29.  	    dtype = (is_lord(ptr) && !rn2(20)) ? llord : 30.  		     (is_lord(ptr) || !rn2(6)) ? lminion : monsndx(ptr); 31.  	    cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1; 32.   	}  33.    34.   	if (!dtype) return; 35.   36.   	/* sanity checks */ 37.  	if (cnt > 1 && (mons[dtype].geno & G_UNIQ)) cnt = 1; 38.  	/*  39.   	 * If this daemon is unique and being re-summoned (the only way we  40.   	 * could get this far with an extinct dtype), try another. 41.  	 */  42.   	if (mvitals[dtype].mvflags & G_GONE) { 43.  	    dtype = ndemon(atyp); 44.  	    if (!dtype) return; 45.  	}  46.    47.   	while (cnt > 0) { 48.  	    (void)makemon(&mons[dtype], u.ux, u.uy, NO_MM_FLAGS); 49.  	    cnt--; 50.  	}  51.   	return; 52.  }  53.    54.   void 55.  summon_minion(alignment, talk) 56.  aligntyp alignment; 57.  boolean talk; 58.  {  59.       register struct monst *mon; 60.      int mnum; 61.   62.       switch ((int)alignment) { 63.  	case A_LAWFUL: 64.  	    mnum = lminion; 65.  	    break; 66.  	case A_NEUTRAL: 67.  	    mnum = PM_AIR_ELEMENTAL + rn2(4); 68.  	    break; 69.  	case A_CHAOTIC: 70.  	case A_NONE: 71.  	    mnum = ndemon(alignment); 72.  	    break; 73.  	default: 74.  	    impossible("unaligned player?"); 75.  	    mnum = ndemon(A_NONE); 76.  	    break; 77.      }  78.       if (mnum == NON_PM) { 79.  	mon = 0; 80.      } else if (mons[mnum].pxlth == 0) { 81.  	struct permonst *pm = &mons[mnum]; 82.  	mon = makemon(pm, u.ux, u.uy, MM_EMIN); 83.  	if (mon) { 84.  	    mon->isminion = TRUE; 85.  	    EMIN(mon)->min_align = alignment; 86.  	}  87.       } else if (mnum == PM_ANGEL) { 88.  	mon = makemon(&mons[mnum], u.ux, u.uy, NO_MM_FLAGS); 89.  	if (mon) { 90.  	    mon->isminion = TRUE; 91.  	    EPRI(mon)->shralign = alignment;	/* always A_LAWFUL here */ 92.  	}  93.       } else 94.  	mon = makemon(&mons[mnum], u.ux, u.uy, NO_MM_FLAGS); 95.      if (mon) { 96.  	if (talk) { 97.  	    pline_The("voice of %s booms:", align_gname(alignment)); 98.  	    verbalize("Thou shalt pay for thy indiscretion!"); 99.  	    if (!Blind) 100. 		pline("%s appears before you.", Amonnam(mon)); 101. 	}  102.  	mon->mpeaceful = FALSE; 103. 	/* don't call set_malign; player was naughty */ 104.     }  105.  }  106.   107.  #define Athome	(Inhell && !mtmp->cham) 108.  109.  int 110. demon_talk(mtmp)		/* returns 1 if it won't attack. */ 111.  register struct monst *mtmp; 112. {  113.  	long	demand, offer; 114.  115.  	if (uwep && uwep->oartifact == ART_EXCALIBUR) { 116. 	    pline("%s looks very angry.", Amonnam(mtmp)); 117. 	    mtmp->mpeaceful = mtmp->mtame = 0; 118. 	    newsym(mtmp->mx, mtmp->my); 119. 	    return 0; 120. 	}  121.   122.  	/* Slight advantage given. */ 123.  	if (is_dprince(mtmp->data) && mtmp->minvis) { 124. 	    mtmp->minvis = mtmp->perminvis = 0; 125. 	    if (!Blind) pline("%s appears before you.", Amonnam(mtmp)); 126. 	    newsym(mtmp->mx,mtmp->my); 127. 	}  128.  	if (youmonst.data->mlet == S_DEMON) {	/* Won't blackmail their own. */ 129.  	    pline("%s says, \"Good hunting, %s.\" and vanishes.",  130.  		  Amonnam(mtmp), flags.female ? "Sister" : "Brother"); 131. 	    rloc(mtmp); 132. 	    return(1); 133. 	}  134.  	demand = (u.ugold * (rnd(80) + 20 * Athome)) / 135. 		 100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))); 136. 	if (!demand)		/* you have no gold */ 137. 	    return mtmp->mpeaceful = 0; 138. 	else { 139. 	    pline("%s demands %ld zorkmid%s for safe passage.",  140.  		  Amonnam(mtmp), demand, plur(demand)); 141.  142.  	    if ((offer = bribe(mtmp)) >= demand) { 143. 		pline("%s vanishes, laughing about cowardly mortals.",  144.  		      Amonnam(mtmp)); 145. 	    } else { 146. 		if ((long)rnd(40) > (demand - offer)) { 147. 		    pline("%s scowls at you menacingly, then vanishes.",  148.  			  Amonnam(mtmp)); 149. 		} else { 150. 		    pline("%s gets angry...", Amonnam(mtmp)); 151. 		    return mtmp->mpeaceful = 0; 152. 		}  153.  	    }  154.  	}  155.  	mongone(mtmp); 156. 	return(1); 157. }  158.   159.  long 160. bribe(mtmp) 161. struct monst *mtmp; 162. {  163.  	char buf[BUFSZ]; 164. 	long offer; 165.  166.  	getlin("How much will you offer?", buf); 167. 	(void) sscanf(buf, "%ld", &offer); 168.  169.  	/*Michael Paddon -- fix for negative offer to monster*/ 170. 	/*JAR880815 - */ 171. 	if (offer < 0L) { 172. 		You("try to shortchange %s, but fumble.",  173.  			mon_nam(mtmp)); 174. 		offer = 0L; 175. 	} else if (offer == 0L) { 176. 		You("refuse."); 177. 	} else if (offer >= u.ugold) { 178. 		You("give %s all your gold.", mon_nam(mtmp)); 179. 		offer = u.ugold; 180. 	} else You("give %s %ld zorkmid%s.", mon_nam(mtmp), offer,  181.  		   plur(offer)); 182.  183.  	u.ugold -= offer; 184. 	mtmp->mgold += offer; 185. 	flags.botl = 1; 186. 	return(offer); 187. }  188.   189.  int 190. dprince(atyp) 191. aligntyp atyp; 192. {  193.  	int tryct, pm; 194.  195.  	for (tryct = 0; tryct < 20; tryct++) { 196. 	    pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS); 197. 	    if (!(mvitals[pm].mvflags & G_GONE) &&  198.  		    (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) 199. 		return(pm); 200. 	}  201.  	return(dlord(atyp));	/* approximate */ 202. }  203.   204.  int 205. dlord(atyp) 206. aligntyp atyp; 207. {  208.  	int tryct, pm; 209.  210.  	for (tryct = 0; tryct < 20; tryct++) { 211. 	    pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX); 212. 	    if (!(mvitals[pm].mvflags & G_GONE) &&  213.  		    (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) 214. 		return(pm); 215. 	}  216.  	return(ndemon(atyp));	/* approximate */ 217. }  218.   219.  /* create lawful (good) lord */ 220. int 221. llord 222. {  223.  	if (!(mvitals[PM_ARCHON].mvflags & G_GONE)) 224. 		return(PM_ARCHON); 225.  226.  	return(lminion);	/* approximate */ 227. }  228.   229.  int 230. lminion 231. {  232.  	int	tryct; 233. 	struct	permonst *ptr; 234.  235.  	for (tryct = 0; tryct < 20; tryct++) { 236. 	    ptr = mkclass(S_ANGEL,0); 237. 	    if (ptr && !is_lord(ptr)) 238. 		return(monsndx(ptr)); 239. 	}  240.   241.  	return NON_PM; 242. }  243.   244.  int 245. ndemon(atyp) 246. aligntyp atyp; 247. {  248.  	int	tryct; 249. 	struct	permonst *ptr; 250.  251.  	for (tryct = 0; tryct < 20; tryct++) { 252. 	    ptr = mkclass(S_DEMON, 0); 253. 	    if (is_ndemon(ptr) &&  254.  		    (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp))) 255. 		return(monsndx(ptr)); 256. 	}  257.   258.  	return NON_PM; 259. }  260.   261.  /*minion.c*/