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.
Top of file
Edit
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.
summon_minion
Edit
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.
demon_talk
Edit
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*/