abstract
| - Below is the full text to wizard.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/wizard.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)wizard.c 3.0 88/04/11 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */ 6. /* - heavily modified to give the wiz balls. (genat!mike) */ 7. /* - dewimped and given some maledictions. -3. */ 8. 9. #include "hack.h" 10. 11. #ifdef HARD 12. /* TODO: Expand this list. */ 13. static const int nasties[] = { 14. PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, PM_RED_DRAGON, 15. PM_GREEN_DRAGON, PM_OWLBEAR, PM_PURPLE_WORM, PM_ROCK_TROLL, PM_XAN, 16. PM_GREMLIN, PM_UMBER_HULK, PM_VAMPIRE_LORD, PM_XORN, PM_ZRUTY, 17. #ifdef ARMY 18. PM_CAPTAIN, 19. #endif 20. }; 21. #endif /* HARD */ 22. 23. /* TODO: investigate this. */ 24. static const char wizapp[] = { 25. S_HUMAN, S_DEMON, S_VAMPIRE, S_DRAGON, S_TROLL, S_UMBER, 26. S_XORN, S_XAN, S_COCKATRICE, S_EYE, S_NAGA, S_TRAPPER, 27. /* '1' /* Historical reference */ }; 28. 29. /* If he has found the Amulet, make the wizard appear after some time */ 30. void 31. amulet(){ 32. register struct monst *mtmp; 33. 34. if(!flags.made_amulet || !flags.no_of_wizards) 35. return; 36. /* find wizard, and wake him if necessary */ 37. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 38. if(mtmp->iswiz && mtmp->msleep && !rn2(40)) 39. if(u.uhave_amulet) { 40. mtmp->msleep = 0; 41. if(dist(mtmp->mx,mtmp->my) > 2) 42. pline( 43. "You get the creepy feeling that somebody noticed your taking the Amulet." 44. ); 45. return; 46. } 47. } 48. 49. int 50. mon_has_amulet(mtmp) 51. register struct monst *mtmp; 52. { 53. register struct obj *otmp; 54. 55. for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj){ 56. if(otmp->otyp == AMULET_OF_YENDOR && otmp->spe >= 0) return(1); 57. } 58. return(0); 59. } 60. 61. /* the wiz's prime directive */ 62. int 63. wiz_get_amulet(mtmp) 64. register struct monst *mtmp; 65. { 66. /* if he doesn't have the amulet */ 67. if(!mon_has_amulet(mtmp)) 68. if(u.uhave_amulet) { 69. 70. /* player has it, dog them til he gets it or dies */ 71. mnexto(mtmp); 72. } else { 73. register struct obj *otmp; 74. 75. /* if it is lying around someplace, he teleports to it */ 76. for(otmp = fobj; otmp; otmp = otmp->nobj) 77. if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) { 78. if(u.ux == otmp->ox && u.uy == otmp->oy) { 79. /* player is standing on it */ 80. mnexto(mtmp); 81. return(0); 82. } 83. if(!levl[otmp->ox][otmp->oy].mmask || 84. (mtmp->mx == otmp->ox && mtmp->my == otmp->oy)) { 85. 86. /* teleport to it and pick it up */ 87. levl[mtmp->mx][mtmp->my].mmask = 0; 88. levl[otmp->ox][otmp->oy].mmask = 1; 89. mtmp->mx = otmp->ox; 90. mtmp->my = otmp->oy; 91. freeobj(otmp); 92. mpickobj(mtmp, otmp); 93. pmon(mtmp); 94. return(1); 95. } 96. break; 97. } 98. /* we don't know where it is */ 99. } 100. 101. /* he has it or can't find it */ 102. /* secondary goal - stayin' alive */ 103. 104. /* if wounded, hole up on or near the stairs (to block them) */ 105. if(mtmp->mhp < 20 + rnd(10)) 106. if (mtmp->mx != xupstair && mtmp->my != yupstair) 107. mnearto(mtmp,xupstair,yupstair,TRUE); 108. 109. /* if you're not around, cast healing spells */ 110. if(dist(mtmp->mx,mtmp->my) > (BOLT_LIM * BOLT_LIM)) 111. if(mtmp->mhp <= mtmp->mhpmax - 8) { 112. mtmp->mhp += rnd(8); 113. return(1); 114. } 115. /* healthy wiz with nothing to do */ 116. else if(!rn2(5)) 117. mnexto(mtmp); 118. 119. /* the effect is that below 30 hp, wily wiz teleports 120. again and again, unless/until he blocks the stairs. 121. 122. if you keep away from the wounded wiz, he sits 123. there healing himself, until he gets healthy 124. and decides to punish you some more. -3. */ 125. 126. return(0); 127. } 128. 129. void 130. aggravate() 131. { 132. register struct monst *mtmp; 133. 134. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 135. mtmp->msleep = 0; 136. if(mtmp->mfroz && !rn2(5)) 137. mtmp->mfroz = 0; 138. } 139. } 140. 141. void 142. clonewiz() 143. { 144. register struct monst *mtmp2; 145. 146. if(mtmp2 = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy)) { 147. mtmp2->msleep = mtmp2->mtame = mtmp2->mpeaceful = 0; 148. if (!u.uhave_amulet && rn2(2)) { /* give clone a fake */ 149. mtmp2->minvent = mksobj(AMULET_OF_YENDOR,FALSE); 150. mtmp2->minvent->spe = -1; 151. } 152. unpmon(mtmp2); 153. mtmp2->mappearance = wizapp[rn2(SIZE(wizapp))]; 154. pmon(mtmp2); 155. } 156. } 157. 158. #ifdef HARD 159. void 160. nasty() { 161. register struct monst *mtmp; 162. register int i, tmp; 163. 164. if(!rn2(10) && Inhell) dsummon(&mons[PM_WIZARD_OF_YENDOR]); 165. else { 166. tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */ 167. 168. for(i = rnd(tmp); i > 0; --i) 169. if((mtmp = makemon(&mons[nasties[rn2(SIZE(nasties))]], u.ux, u.uy))) { 170. 171. mtmp->msleep = mtmp->mpeaceful = mtmp->mtame = 0; 172. } else 173. (void)makemon((struct permonst *)0, u.ux, u.uy); /* GENOD? */ 174. } 175. return; 176. } 177. 178. /* Let's resurrect the wizard, for some unexpected fun. */ 179. void 180. resurrect() 181. { 182. register struct monst *mtmp; 183. 184. if(mtmp = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy)) { 185. mtmp->msleep = mtmp->mtame = mtmp->mpeaceful = 0; 186. pline("A voice booms out..."); 187. pline("\"So thou thought thou couldst kill me, fool.\""); 188. } 189. 190. } 191. 192. /* Here, we make trouble for the poor shmuck who actually */ 193. /* managed to do in the Wizard. */ 194. void 195. intervene() { 196. 197. switch(rn2(6)) { 198. 199. case 0: 200. case 1: You("feel vaguely nervous."); 201. break; 202. case 2: if (!Blind) 203. You("notice a %s glow surrounding you.", 204. Hallucination ? hcolor() : black); 205. rndcurse(); 206. break; 207. case 3: aggravate(); 208. break; 209. case 4: nasty(); 210. break; 211. case 5: if (!flags.no_of_wizards) resurrect(); 212. break; 213. } 214. } 215. 216. void 217. wizdead(mtmp) 218. register struct monst *mtmp; 219. { 220. flags.no_of_wizards--; 221. if(! u.udemigod) { 222. 223. u.udemigod = TRUE; 224. u.udg_cnt = rn1(250, 50); 225. 226. /* Make the wizard meaner the next time he appears */ 227. mtmp->data->mlevel++; 228. mtmp->data->ac--; 229. } else 230. mtmp->data->mlevel++; 231. } 232. #endif /* HARD /**/ 233. 234. const char *random_insult[] = { 235. "antic", 236. "blackguard", 237. "caitiff", 238. "chucklehead", 239. "coistrel", 240. "craven", 241. "cretin", 242. "cur", 243. "dastard", 244. "demon fodder", 245. "dimwit", 246. "dolt", 247. "fool", 248. "footpad", 249. "imbecile", 250. "knave", 251. "maledict", 252. "miscreant", 253. "niddering", 254. "poltroon", 255. "rattlepate", 256. "reprobate", 257. "scapegrace", 258. "varlet", 259. "villein", /* (sic.) */ 260. "wittol", 261. "worm", 262. "wretch", 263. }; 264. 265. const char *random_malediction[] = { 266. "Hell shall soon claim thy remains,", 267. "I chortle at thee, pathetic", 268. "Prepare to die,", 269. "Resistance is useless,", 270. "Surrender or die, thou", 271. "There shall be no mercy, yon", 272. "Thou shalt repent of thy cunning,", 273. "Thou art as a flea to me,", 274. "Thou art doomed,", 275. "Thy fate is sealed,", 276. "Verily, thou shalt be one dead" 277. /* "Go play leapfrog with a unicorn,", */ 278. }; 279. 280. /* Insult the player */ 281. void 282. cuss(mtmp) 283. register struct monst *mtmp; 284. { 285. switch (rn2(5)) { 286. case 0: pline("%s casts aspersions on your ancestry.", 287. Monnam(mtmp)); 288. break; 289. case 1: pline("%s laughs fiendishly.", /* typical bad guy action */ 290. Monnam(mtmp)); 291. break; 292. default: 293. if (u.uhave_amulet && !rn2(SIZE(random_insult))) 294. pline("\"Relinquish the amulet, %s!\"", 295. random_insult[rn2(SIZE(random_insult))]); 296. else if (u.uhp < 5 && !rn2(2)) /* Panic */ 297. pline(rn2(2) ? 298. "\"Even now thy life force ebbs, %s!\"" : 299. "\"Savor thy breath, %s, it be thine last!\"", 300. random_insult[rn2(SIZE(random_insult))]); 301. else if (mtmp->mhp < 5 && !rn2(2)) /* Parthian shot */ 302. pline(rn2(2) ? 303. "\"I shall return.\"" : 304. "\"I'll be back.\""); 305. else 306. pline("\"%s %s!\"", 307. random_malediction[rn2(SIZE(random_malediction))], 308. random_insult[rn2(SIZE(random_insult))]); 309. } 310. }
|