Wikihack
Advertisement

Below is the full text to src/mplayer.c from NetHack 3.4.3. To link to a particular line, write [[mplayer.c#line123]], for example.

Top of file[]

1.    /*	SCCS Id: @(#)mplayer.c	3.4	1997/02/04	*/
2.    /*	Copyright (c) Izchak Miller, 1992.			  */
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.    
7.    STATIC_DCL const char *NDECL(dev_name);
8.    STATIC_DCL void FDECL(get_mplname, (struct monst *, char *));
9.    STATIC_DCL void FDECL(mk_mplayer_armor, (struct monst *, SHORT_P));
10.   

developers[]

11.   /* These are the names of those who
12.    * contributed to the development of NetHack 3.2/3.3/3.4.
13.    *
14.    * Keep in alphabetical order within teams.
15.    * Same first name is entered once within each team.
16.    */
17.   static const char *developers[] = {
18.   	/* devteam */
19.   	"Dave", "Dean", "Eric", "Izchak", "Janet", "Jessie",
20.   	"Ken", "Kevin", "Michael", "Mike", "Pat", "Paul", "Steve", "Timo",
21.   	"Warwick",
22.   	/* PC team */
23.   	"Bill", "Eric", "Keizo", "Ken", "Kevin", "Michael", "Mike", "Paul",
24.   	"Stephen", "Steve", "Timo", "Yitzhak",
25.   	/* Amiga team */
26.   	"Andy", "Gregg", "Janne", "Keni", "Mike", "Olaf", "Richard",
27.   	/* Mac team */
28.   	"Andy", "Chris", "Dean", "Jon", "Jonathan", "Kevin", "Wang",
29.   	/* Atari team */
30.   	"Eric", "Marvin", "Warwick",
31.   	/* NT team */
32.   	"Alex", "Dion", "Michael",
33.   	/* OS/2 team */
34.   	"Helge", "Ron", "Timo",
35.   	/* VMS team */
36.   	"Joshua", "Pat",
37.   	""};
38.   
39.   

dev_name[]

40.   /* return a randomly chosen developer name */
41.   STATIC_OVL const char *
42.   dev_name()
43.   {
44.   	register int i, m = 0, n = SIZE(developers);
45.   	register struct monst *mtmp;
46.   	register boolean match;
47.   
48.   	do {
49.   	    match = FALSE;
50.   	    i = rn2(n);
51.   	    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
52.   		if(!is_mplayer(mtmp->data)) continue;
53.   		if(!strncmp(developers[i], NAME(mtmp),
54.   			               strlen(developers[i]))) {
55.   		    match = TRUE;
56.   		    break;
57.   	        }
58.   	    }
59.   	    m++;
60.   	} while (match && m < 100); /* m for insurance */
61.   
62.   	if (match) return (const char *)0;
63.   	return(developers[i]);
64.   }
65.   

get_mplname[]

66.   STATIC_OVL void
67.   get_mplname(mtmp, nam)
68.   register struct monst *mtmp;
69.   char *nam;
70.   {
71.   	boolean fmlkind = is_female(mtmp->data);
72.   	const char *devnam;
73.   
74.   	devnam = dev_name();
75.   	if (!devnam)
76.   	    Strcpy(nam, fmlkind ? "Eve" : "Adam");
77.   	else if (fmlkind && !!strcmp(devnam, "Janet"))
78.   	    Strcpy(nam, rn2(2) ? "Maud" : "Eve");
79.   	else Strcpy(nam, devnam);
80.   
81.   	if (fmlkind || !strcmp(nam, "Janet"))
82.   	    mtmp->female = 1;
83.   	else
84.   	    mtmp->female = 0;
85.   	Strcat(nam, " the ");
86.   	Strcat(nam, rank_of((int)mtmp->m_lev,
87.   			    monsndx(mtmp->data),
88.   			    (boolean)mtmp->female));
89.   }
90.   

mk_mplayer_armor[]

91.   STATIC_OVL void
92.   mk_mplayer_armor(mon, typ)
93.   struct monst *mon;
94.   short typ;
95.   {
96.   	struct obj *obj;
97.   
98.   	if (typ == STRANGE_OBJECT) return;
99.   	obj = mksobj(typ, FALSE, FALSE);
100.  	if (!rn2(3)) obj->oerodeproof = 1;
101.  	if (!rn2(3)) curse(obj);
102.  	if (!rn2(3)) bless(obj);
103.  	/* Most players who get to the endgame who have cursed equipment
104.  	 * have it because the wizard or other monsters cursed it, so its
105.  	 * chances of having plusses is the same as usual....
106.  	 */
107.  	obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4,4)) : -rnd(3);
108.  	(void) mpickobj(mon, obj);
109.  }
110.  

mk_mplayer[]

111.  struct monst *
112.  mk_mplayer(ptr, x, y, special)
113.  register struct permonst *ptr;
114.  xchar x, y;
115.  register boolean special;
116.  {
117.  	register struct monst *mtmp;
118.  	char nam[PL_NSIZ];
119.  
120.  	if(!is_mplayer(ptr))
121.  		return((struct monst *)0);
122.  
123.  	if(MON_AT(x, y))
124.  		(void) rloc(m_at(x, y), FALSE); /* insurance */
125.  
126.  	if(!In_endgame(&u.uz)) special = FALSE;
127.  
128.  	if ((mtmp = makemon(ptr, x, y, NO_MM_FLAGS)) != 0) {
129.  	    short weapon = rn2(2) ? LONG_SWORD : rnd_class(SPEAR, BULLWHIP);
130.  	    short armor = rnd_class(GRAY_DRAGON_SCALE_MAIL, YELLOW_DRAGON_SCALE_MAIL);
131.  	    short cloak = !rn2(8) ? STRANGE_OBJECT :
132.  	    		rnd_class(OILSKIN_CLOAK, CLOAK_OF_DISPLACEMENT);
133.  	    short helm = !rn2(8) ? STRANGE_OBJECT :
134.  	    		rnd_class(ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY);
135.  	    short shield = !rn2(8) ? STRANGE_OBJECT :
136.  	    		rnd_class(ELVEN_SHIELD, SHIELD_OF_REFLECTION);
137.  	    int quan;
138.  	    struct obj *otmp;
139.  
140.  	    mtmp->m_lev = (special ? rn1(16,15) : rnd(16));
141.  	    mtmp->mhp = mtmp->mhpmax = d((int)mtmp->m_lev,10) +
142.  					(special ? (30 + rnd(30)) : 30);
143.  	    if(special) {
144.  	        get_mplname(mtmp, nam);
145.  	        mtmp = christen_monst(mtmp, nam);
146.  		/* that's why they are "stuck" in the endgame :-) */
147.  		(void)mongets(mtmp, FAKE_AMULET_OF_YENDOR);
148.  	    }
149.  	    mtmp->mpeaceful = 0;
150.  	    set_malign(mtmp); /* peaceful may have changed again */
151.  
152.  	    switch(monsndx(ptr)) {
153.  		case PM_ARCHEOLOGIST:
154.  		    if (rn2(2)) weapon = BULLWHIP;
155.  		    break;
156.  		case PM_BARBARIAN:
157.  		    if (rn2(2)) {
158.  		    	weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;
159.  		    	shield = STRANGE_OBJECT;
160.  		    }
161.  		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
162.  		    if (helm == HELM_OF_BRILLIANCE) helm = STRANGE_OBJECT;
163.  		    break;
164.  		case PM_CAVEMAN:
165.  		case PM_CAVEWOMAN:
166.  		    if (rn2(4)) weapon = MACE;
167.  		    else if (rn2(2)) weapon = CLUB;
168.  		    if (helm == HELM_OF_BRILLIANCE) helm = STRANGE_OBJECT;
169.  		    break;
170.  		case PM_HEALER:
171.  		    if (rn2(4)) weapon = QUARTERSTAFF;
172.  		    else if (rn2(2)) weapon = rn2(2) ? UNICORN_HORN : SCALPEL;
173.  		    if (rn2(4)) helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
174.  		    if (rn2(2)) shield = STRANGE_OBJECT;
175.  		    break;
176.  		case PM_KNIGHT:
177.  		    if (rn2(4)) weapon = LONG_SWORD;
178.  		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
179.  		    break;
180.  		case PM_MONK:
181.  		    weapon = STRANGE_OBJECT;
182.  		    armor = STRANGE_OBJECT;
183.  		    cloak = ROBE;
184.  		    if (rn2(2)) shield = STRANGE_OBJECT;
185.  		    break;
186.  		case PM_PRIEST:
187.  		case PM_PRIESTESS:
188.  		    if (rn2(2)) weapon = MACE;
189.  		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
190.  		    if (rn2(4)) cloak = ROBE;
191.  		    if (rn2(4)) helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
192.  		    if (rn2(2)) shield = STRANGE_OBJECT;
193.  		    break;
194.  		case PM_RANGER:
195.  		    if (rn2(2)) weapon = ELVEN_DAGGER;
196.  		    break;
197.  		case PM_ROGUE:
198.  		    if (rn2(2)) weapon = SHORT_SWORD;
199.  		    break;
200.  		case PM_SAMURAI:
201.  		    if (rn2(2)) weapon = KATANA;
202.  		    break;
203.  #ifdef TOURIST
204.  		case PM_TOURIST:
205.  		    /* Defaults are just fine */
206.  		    break;
207.  #endif
208.  		case PM_VALKYRIE:
209.  		    if (rn2(2)) weapon = WAR_HAMMER;
210.  		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
211.  		    break;
212.  		case PM_WIZARD:
213.  		    if (rn2(4)) weapon = rn2(2) ? QUARTERSTAFF : ATHAME;
214.  		    if (rn2(2)) {
215.  		    	armor = rn2(2) ? BLACK_DRAGON_SCALE_MAIL :
216.  		    			SILVER_DRAGON_SCALE_MAIL;
217.  		    	cloak = CLOAK_OF_MAGIC_RESISTANCE;
218.  		    }
219.  		    if (rn2(4)) helm = HELM_OF_BRILLIANCE;
220.  		    shield = STRANGE_OBJECT;
221.  		    break;
222.  		default: impossible("bad mplayer monster");
223.  		    weapon = 0;
224.  		    break;
225.  	    }
226.  
227.  	    if (weapon != STRANGE_OBJECT) {
228.  		otmp = mksobj(weapon, TRUE, FALSE);
229.  		otmp->spe = (special ? rn1(5,4) : rn2(4));
230.  		if (!rn2(3)) otmp->oerodeproof = 1;
231.  		else if (!rn2(2)) otmp->greased = 1;
232.  		if (special && rn2(2))
233.  		    otmp = mk_artifact(otmp, A_NONE);
234.  		/* mplayers knew better than to overenchant Magicbane */
235.  		if (otmp->oartifact == ART_MAGICBANE)
236.  		    otmp->spe = rnd(4);
237.  		(void) mpickobj(mtmp, otmp);
238.  	    }
239.  
240.  	    if(special) {
241.  		if (!rn2(10))
242.  		    (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE);
243.  		mk_mplayer_armor(mtmp, armor);
244.  		mk_mplayer_armor(mtmp, cloak);
245.  		mk_mplayer_armor(mtmp, helm);
246.  		mk_mplayer_armor(mtmp, shield);
247.  		if (rn2(8))
248.  		    mk_mplayer_armor(mtmp, rnd_class(LEATHER_GLOVES,
249.  					       GAUNTLETS_OF_DEXTERITY));
250.  		if (rn2(8))
251.  		    mk_mplayer_armor(mtmp, rnd_class(LOW_BOOTS, LEVITATION_BOOTS));
252.  		m_dowear(mtmp, TRUE);
253.  
254.  		quan = rn2(3) ? rn2(3) : rn2(16);
255.  		while(quan--)
256.  		    (void)mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE));
257.  		/* To get the gold "right" would mean a player can double his */
258.  		/* gold supply by killing one mplayer.  Not good. */
259.  #ifndef GOLDOBJ
260.  		mtmp->mgold = rn2(1000);
261.  #else
262.  		mkmonmoney(mtmp, rn2(1000));
263.  #endif
264.  		quan = rn2(10);
265.  		while(quan--)
266.  		    (void) mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE));
267.  	    }
268.  	    quan = rnd(3);
269.  	    while(quan--)
270.  		(void)mongets(mtmp, rnd_offensive_item(mtmp));
271.  	    quan = rnd(3);
272.  	    while(quan--)
273.  		(void)mongets(mtmp, rnd_defensive_item(mtmp));
274.  	    quan = rnd(3);
275.  	    while(quan--)
276.  		(void)mongets(mtmp, rnd_misc_item(mtmp));
277.  	}
278.  
279.  	return(mtmp);
280.  }
281.  

create_mplayers[]

282.  /* create the indicated number (num) of monster-players,
283.   * randomly chosen, and in randomly chosen (free) locations
284.   * on the level.  If "special", the size of num should not
285.   * be bigger than the number of _non-repeated_ names in the
286.   * developers array, otherwise a bunch of Adams and Eves will
287.   * fill up the overflow.
288.   */
289.  void
290.  create_mplayers(num, special)
291.  register int num;
292.  boolean special;
293.  {
294.  	int pm, x, y;
295.  	struct monst fakemon;
296.  
297.  	while(num) {
298.  		int tryct = 0;
299.  
300.  		/* roll for character class */
301.  		pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1);
302.  		fakemon.data = &mons[pm];
303.  
304.  		/* roll for an available location */
305.  		do {
306.  		    x = rn1(COLNO-4, 2);
307.  		    y = rnd(ROWNO-2);
308.  		} while(!goodpos(x, y, &fakemon, 0) && tryct++ <= 50);
309.  
310.  		/* if pos not found in 50 tries, don't bother to continue */
311.  		if(tryct > 50) return;
312.  
313.  		(void) mk_mplayer(&mons[pm], (xchar)x, (xchar)y, special);
314.  		num--;
315.  	}
316.  }
317.  

mplayer_talk[]

318.  void
319.  mplayer_talk(mtmp)
320.  register struct monst *mtmp;
321.  {
322.  	static const char *same_class_msg[3] = {
323.  		"I can't win, and neither will you!",
324.  		"You don't deserve to win!",
325.  		"Mine should be the honor, not yours!",
326.  	},		  *other_class_msg[3] = {
327.  		"The low-life wants to talk, eh?",
328.  		"Fight, scum!",
329.  		"Here is what I have to say!",
330.  	};
331.  
332.  	if(mtmp->mpeaceful) return; /* will drop to humanoid talk */
333.  
334.  	pline("Talk? -- %s",
335.  		(mtmp->data == &mons[urole.malenum] ||
336.  		mtmp->data == &mons[urole.femalenum]) ?
337.  		same_class_msg[rn2(3)] : other_class_msg[rn2(3)]);
338.  }
339.  
340.  /*mplayer.c*/
Advertisement