Source:NetHack 3.4.0/minion.c

Below is the full text to minion.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4	2002/01/23	*/ 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 = NON_PM, cnt = 0; 14.  	aligntyp atyp = (ptr->maligntyp==A_NONE) ? A_NONE : 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 == NON_PM) 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 == NON_PM) 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.\"",  130.  		  Amonnam(mtmp), flags.female ? "Sister" : "Brother"); 131. 	    if (!tele_restrict(mtmp)) rloc(mtmp); 132. 	    return(1); 133. 	}  134.  #ifndef GOLDOBJ 135. 	demand = (u.ugold * (rnd(80) + 20 * Athome)) / 136. #else 137. 	demand = (money_cnt(invent) * (rnd(80) + 20 * Athome)) / 138. #endif 139. 	    (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp)))); 140. 	if (!demand)		/* you have no gold */ 141. 	    return mtmp->mpeaceful = 0; 142. 	else { 143. 	    pline("%s demands %ld %s for safe passage.",  144.  		  Amonnam(mtmp), demand, currency(demand)); 145.  146.  	    if ((offer = bribe(mtmp)) >= demand) { 147. 		pline("%s vanishes, laughing about cowardly mortals.",  148.  		      Amonnam(mtmp)); 149. 	    } else { 150. 		if ((long)rnd(40) > (demand - offer)) { 151. 		    pline("%s scowls at you menacingly, then vanishes.",  152.  			  Amonnam(mtmp)); 153. 		} else { 154. 		    pline("%s gets angry...", Amonnam(mtmp)); 155. 		    return mtmp->mpeaceful = 0; 156. 		}  157.  	    }  158.  	}  159.  	mongone(mtmp); 160. 	return(1); 161. }  162.   163.  long 164. bribe(mtmp) 165. struct monst *mtmp; 166. {  167.  	char buf[BUFSZ]; 168. 	long offer; 169. #ifdef GOLDOBJ 170. 	long umoney = money_cnt(invent); 171. #endif 172.  173.  	getlin("How much will you offer?", buf); 174. 	if (sscanf(buf, "%ld", &offer) != 1) offer = 0L; 175.  176.  	/*Michael Paddon -- fix for negative offer to monster*/ 177. 	/*JAR880815 - */ 178. 	if (offer < 0L) { 179. 		You("try to shortchange %s, but fumble.",  180.  			mon_nam(mtmp)); 181. 		return 0L; 182. 	} else if (offer == 0L) { 183. 		You("refuse."); 184. 		return 0L; 185. #ifndef GOLDOBJ 186. 	} else if (offer >= u.ugold) { 187. 		You("give %s all your gold.", mon_nam(mtmp)); 188. 		offer = u.ugold; 189. 	} else { 190. 		You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer)); 191. 	}  192.  	u.ugold -= offer; 193. 	mtmp->mgold += offer; 194. #else 195. 	} else if (offer >= umoney) { 196. 		You("give %s all your gold.", mon_nam(mtmp)); 197. 		offer = umoney; 198. 	} else { 199. 		You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer)); 200. 	}  201.  	(void) money2mon(mtmp, offer); 202. #endif 203. 	flags.botl = 1; 204. 	return(offer); 205. }  206.   207.  int 208. dprince(atyp) 209. aligntyp atyp; 210. {  211.  	int tryct, pm; 212.  213.  	for (tryct = 0; tryct < 20; tryct++) { 214. 	    pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS); 215. 	    if (!(mvitals[pm].mvflags & G_GONE) &&  216.  		    (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) 217. 		return(pm); 218. 	}  219.  	return(dlord(atyp));	/* approximate */ 220. }  221.   222.  int 223. dlord(atyp) 224. aligntyp atyp; 225. {  226.  	int tryct, pm; 227.  228.  	for (tryct = 0; tryct < 20; tryct++) { 229. 	    pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX); 230. 	    if (!(mvitals[pm].mvflags & G_GONE) &&  231.  		    (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) 232. 		return(pm); 233. 	}  234.  	return(ndemon(atyp));	/* approximate */ 235. }  236.   237.  /* create lawful (good) lord */ 238. int 239. llord 240. {  241.  	if (!(mvitals[PM_ARCHON].mvflags & G_GONE)) 242. 		return(PM_ARCHON); 243.  244.  	return(lminion);	/* approximate */ 245. }  246.   247.  int 248. lminion 249. {  250.  	int	tryct; 251. 	struct	permonst *ptr; 252.  253.  	for (tryct = 0; tryct < 20; tryct++) { 254. 	    ptr = mkclass(S_ANGEL,0); 255. 	    if (ptr && !is_lord(ptr)) 256. 		return(monsndx(ptr)); 257. 	}  258.   259.  	return NON_PM; 260. }  261.   262.  int 263. ndemon(atyp) 264. aligntyp atyp; 265. {  266.  	int	tryct; 267. 	struct	permonst *ptr; 268.  269.  	for (tryct = 0; tryct < 20; tryct++) { 270. 	    ptr = mkclass(S_DEMON, 0); 271. 	    if (ptr && is_ndemon(ptr) &&  272.  		    (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp))) 273. 		return(monsndx(ptr)); 274. 	}  275.   276.  	return NON_PM; 277. }  278.   279.  /*minion.c*/