Fandom

Wikihack

Source:SLASH'EM 0.0.7E7F2/minion.c

2,035pages on
this wiki
Add New Page
Talk0

Below is the full text to minion.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/minion.c#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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.  #define Athome	(Inhell && !mtmp->cham)
139.  
140.  int
141.  demon_talk(mtmp)		/* returns 1 if it won't attack. */
142.  register struct monst *mtmp;
143.  {
144.  	long cash, demand, offer;
145.  
146.  	if (uwep && uwep->oartifact == ART_EXCALIBUR) {
147.  	    pline("%s looks very angry.", Amonnam(mtmp));
148.  	    mtmp->mpeaceful = mtmp->mtame = 0;
149.  	    set_malign(mtmp);
150.  	    newsym(mtmp->mx, mtmp->my);
151.  	    return 0;
152.  	}
153.  
154.  	/* Slight advantage given. */
155.  	if (is_dprince(mtmp->data) && mtmp->minvis) {
156.  	    mtmp->minvis = mtmp->perminvis = 0;
157.  	    if (!Blind) pline("%s appears before you.", Amonnam(mtmp));
158.  	    newsym(mtmp->mx,mtmp->my);
159.  	}
160.  	if (youmonst.data->mlet == S_DEMON) {	/* Won't blackmail their own. */
161.  	    pline("%s says, \"Good hunting, %s.\"",
162.  		  Amonnam(mtmp), flags.female ? "Sister" : "Brother");
163.  	    if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
164.  	    return(1);
165.  	}
166.  #ifndef GOLDOBJ
167.  	cash = u.ugold;
168.  #else
169.  	cash = money_cnt(invent);
170.  #endif
171.  	demand = (cash * (rnd(80) + 20 * Athome)) /
172.  	    (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));
173.  
174.  	if (!demand) {		/* you have no gold */
175.  	    mtmp->mpeaceful = 0;
176.  	    set_malign(mtmp);
177.  	    return 0;
178.  	} else {
179.  	    /* make sure that the demand is unmeetable if the monster
180.  	       has the Amulet, preventing monster from being satisified
181.  	       and removed from the game (along with said Amulet...) */
182.  	    if (mon_has_amulet(mtmp))
183.  		demand = cash + (long)rn1(1000,40);
184.  
185.  	    pline("%s demands %ld %s for safe passage.",
186.  		  Amonnam(mtmp), demand, currency(demand));
187.  
188.  	    if ((offer = bribe(mtmp)) >= demand) {
189.  		pline("%s vanishes, laughing about cowardly mortals.",
190.  		      Amonnam(mtmp));
191.  	    } else if (offer > 0L && (long)rnd(40) > (demand - offer)) {
192.  		pline("%s scowls at you menacingly, then vanishes.",
193.  		      Amonnam(mtmp));
194.  	    } else {
195.  		pline("%s gets angry...", Amonnam(mtmp));
196.  		mtmp->mpeaceful = 0;
197.  		set_malign(mtmp);
198.  		return 0;
199.  	    }
200.  	}
201.  	mongone(mtmp);
202.  	return(1);
203.  }
204.  
205.  int lawful_minion(int difficulty)
206.  /* this routine returns the # of an appropriate minion,
207.     given a difficulty rating from 1 to 30 */
208.  {
209.     difficulty = difficulty + rn2(5) - 2;
210.     if (difficulty < 0) difficulty = 0;
211.     if (difficulty > 30) difficulty = 30;
212.     difficulty /= 3;
213.     switch (difficulty) {
214.        case 0: return PM_TENGU;
215.        case 1: return PM_COUATL;
216.        case 2: return PM_WHITE_UNICORN;
217.        case 3: return PM_MOVANIC_DEVA;
218.        case 4: return PM_MONADIC_DEVA;
219.        case 5: return PM_KI_RIN;
220.        case 6: return PM_ASTRAL_DEVA;
221.        case 7: return PM_ARCHON;
222.        case 8: return PM_PLANETAR;
223.        case 9: return PM_SOLAR;
224.        case 10: return PM_SOLAR;
225.  
226.        default: return PM_TENGU;
227.     }
228.  }
229.  
230.  int neutral_minion(int difficulty)
231.  /* this routine returns the # of an appropriate minion,
232.     given a difficulty rating from 1 to 30 */
233.  {
234.     difficulty = difficulty + rn2(9) - 4;
235.     if (difficulty < 0) difficulty = 0;
236.     if (difficulty > 30) difficulty = 30;
237.     if (difficulty < 6) return PM_GRAY_UNICORN;
238.     if (difficulty < 15) return (PM_AIR_ELEMENTAL+rn2(4));
239.     return (PM_DJINNI /* +rn2(4) */);
240.  }
241.  
242.  int chaotic_minion(int difficulty)
243.  /* this routine returns the # of an appropriate minion,
244.     given a difficulty rating from 1 to 30 */
245.  {
246.     difficulty = difficulty + rn2(5) - 2;
247.     if (difficulty < 0) difficulty = 0;
248.     if (difficulty > 30) difficulty = 30;
249.     /* KMH, balance patch -- avoid using floating-point (not supported by all ports) */
250.  /*   difficulty = (int)((float)difficulty / 1.5);*/
251.     difficulty = (difficulty * 2) / 3;
252.     switch (difficulty) {
253.        case 0: return PM_GREMLIN;
254.        case 1:
255.        case 2: return (PM_DRETCH+rn2(5));
256.        case 3: return PM_BLACK_UNICORN;
257.        case 4: return PM_BLOOD_IMP;
258.        case 5: return PM_SPINED_DEVIL;
259.        case 6: return PM_SHADOW_WOLF;
260.        case 7: return PM_HELL_HOUND;
261.        case 8: return PM_HORNED_DEVIL;
262.        case 9: return PM_BEARDED_DEVIL;
263.        case 10: return PM_BAR_LGURA;
264.        case 11: return PM_CHASME;
265.        case 12: return PM_BARBED_DEVIL;
266.        case 13: return PM_VROCK;
267.        case 14: return PM_BABAU;
268.        case 15: return PM_NALFESHNEE;
269.        case 16: return PM_MARILITH;
270.        case 17: return PM_NABASSU;
271.        case 18: return PM_BONE_DEVIL;
272.        case 19: return PM_ICE_DEVIL;
273.        case 20: return PM_PIT_FIEND;
274.     }
275.     return PM_GREMLIN;
276.  }
277.  
278.  long
279.  bribe(mtmp)
280.  struct monst *mtmp;
281.  {
282.  	char buf[BUFSZ];
283.  	long offer;
284.  #ifdef GOLDOBJ
285.  	long umoney = money_cnt(invent);
286.  #endif
287.  
288.  	getlin("How much will you offer?", buf);
289.  	if (sscanf(buf, "%ld", &offer) != 1) offer = 0L;
290.  
291.  	/*Michael Paddon -- fix for negative offer to monster*/
292.  	/*JAR880815 - */
293.  	if (offer < 0L) {
294.  		You("try to shortchange %s, but fumble.",
295.  			mon_nam(mtmp));
296.  		return 0L;
297.  	} else if (offer == 0L) {
298.  		You("refuse.");
299.  		return 0L;
300.  #ifndef GOLDOBJ
301.  	} else if (offer >= u.ugold) {
302.  		You("give %s all your gold.", mon_nam(mtmp));
303.  		offer = u.ugold;
304.  	} else {
305.  		You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
306.  	}
307.  	u.ugold -= offer;
308.  	mtmp->mgold += offer;
309.  #else
310.  	} else if (offer >= umoney) {
311.  		You("give %s all your money.", mon_nam(mtmp));
312.  		offer = umoney;
313.  	} else {
314.  		You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
315.  	}
316.  	(void) money2mon(mtmp, offer);
317.  #endif
318.  	flags.botl = 1;
319.  	return(offer);
320.  }
321.  
322.  int
323.  dprince(atyp)
324.  aligntyp atyp;
325.  {
326.  	int tryct, pm;
327.  
328.  	for (tryct = 0; tryct < 20; tryct++) {
329.  	    pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
330.  	    if (!(mvitals[pm].mvflags & G_GONE) &&
331.  		    (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
332.  		return(pm);
333.  	}
334.  	return(dlord(atyp));	/* approximate */
335.  }
336.  
337.  int
338.  dlord(atyp)
339.  aligntyp atyp;
340.  {
341.  	int tryct, pm;
342.  
343.  	for (tryct = 0; tryct < 20; tryct++) {
344.  	    pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
345.  	    if (!(mvitals[pm].mvflags & G_GONE) &&
346.  		    (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
347.  		return(pm);
348.  	}
349.  	return(ndemon(atyp));	/* approximate */
350.  }
351.  
352.  /* create lawful (good) lord */
353.  int
354.  llord()
355.  {
356.  	if (!(mvitals[PM_ARCHON].mvflags & G_GONE))
357.  		return(PM_ARCHON);
358.  
359.  	return(lminion());	/* approximate */
360.  }
361.  
362.  int
363.  lminion()
364.  {
365.  	int	tryct;
366.  	struct	permonst *ptr;
367.  
368.  	for (tryct = 0; tryct < 20; tryct++) {
369.  	    ptr = mkclass(S_ANGEL,0);
370.  	    if (ptr && !is_lord(ptr))
371.  		return(monsndx(ptr));
372.  	}
373.  
374.  	return NON_PM;
375.  }
376.  
377.  int
378.  ndemon(atyp)
379.  aligntyp atyp;
380.  {
381.  	int	tryct;
382.  	struct	permonst *ptr;
383.  
384.  	for (tryct = 0; tryct < 20; tryct++) {
385.  	    ptr = mkclass(S_DEMON, 0);
386.  	    if (ptr && is_ndemon(ptr) &&
387.  		    (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp)))
388.  		return(monsndx(ptr));
389.  	}
390.  
391.  	return NON_PM;
392.  }
393.  
394.  /*minion.c*/

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.