Wikihack
Advertisement

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[]

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    #include "hack.h"
6.    #include "emin.h"
7.    #include "epri.h"
8.    

msummon[]

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[]

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[]

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.  

bribe[]

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.  

dprince[]

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.  

dlord[]

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.  

llord[]

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.  

lminion[]

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.  

ndemon[]

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*/
Advertisement