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