Source:Minion.c

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