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
Edit
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.
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
Edit
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
Edit
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
Edit
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
Edit
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
Edit
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
Edit
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
Edit
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*/