abstract
| - Below is the full text to quest.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/quest.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)quest.c 3.1 92/11/13 */ 2. /* Copyright 1991, M. Stephenson */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. #ifdef MULDGN 8. /* quest dungeon branch routines. */ 9. 10. #include "quest.h" 11. #include "qtext.h" 12. 13. #define Not_firsttime (on_level(&u.uz0, &u.uz)) 14. #define Qstat(x) (quest_status.x) 15. 16. static void NDECL(on_start); 17. static void NDECL(on_locate); 18. static void NDECL(on_goal); 19. static boolean NDECL(not_capable); 20. static boolean NDECL(not_pure); 21. static void FDECL(expulsion, (BOOLEAN_P)); 22. static void NDECL(chat_with_leader); 23. static void NDECL(chat_with_nemesis); 24. static void NDECL(chat_with_guardian); 25. 26. static void 27. on_start() { 28. if(!Qstat(first_start)) { 29. qt_pager(QT_FIRSTTIME); 30. Qstat(first_start) = TRUE; 31. } else if((u.uz0.dnum != u.uz.dnum) || (u.uz0.dlevel < u.uz.dlevel)) { 32. if(Qstat(not_ready) <= 2) qt_pager(QT_NEXTTIME); 33. else qt_pager(QT_OTHERTIME); 34. } 35. } 36. 37. static void 38. on_locate() { 39. if(!Qstat(first_locate)) { 40. qt_pager(QT_FIRSTLOCATE); 41. Qstat(first_locate) = TRUE; 42. } else if(u.uz0.dlevel < u.uz.dlevel) 43. qt_pager(QT_NEXTLOCATE); 44. } 45. 46. static void 47. on_goal() { 48. if(!Qstat(made_goal)) { 49. qt_pager(QT_FIRSTGOAL); 50. Qstat(made_goal) = 1; 51. } else { 52. qt_pager(QT_NEXTGOAL); 53. if(Qstat(made_goal) < 7) Qstat(made_goal)++; 54. } 55. } 56. 57. void 58. quest_init() { 59. /* 60. * Special setup modifications here: 61. * 62. * Unfortunately, this is going to have to be done on each level, 63. * on start-up, and on entry, since you lose the permonst mods 64. * across a save/restore :-) 65. * 66. * 1 - The Rogue Leader is the Tourist Nemesis. 67. * 1 - Elves can have one of two different leaders, work it out here. 68. * 2 - Priests start with a random alignment - convert the leader and 69. * guardians here. 70. */ 71. #ifdef TOURIST 72. if(pl_character[0] == 'T' && Is_nemesis(&u.uz)) { 73. register struct monst *mtmp; 74. mons[PM_MASTER_OF_THIEVES].msound = MS_NEMESIS; 75. mons[PM_MASTER_OF_THIEVES].mflags2 &= ~(M2_PEACEFUL); 76. mons[PM_MASTER_OF_THIEVES].mflags2 |= (M2_NASTY|M2_STALK|M2_HOSTILE); 77. mons[PM_MASTER_OF_THIEVES].mflags3 = M3_WANTSARTI | M3_WAITFORU; 78. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) /* find the leader... */ 79. if(mtmp->data->msound == MS_NEMESIS) { 80. set_malign(mtmp); /* changed M2_PEACEFUL */ 81. break; 82. } 83. } else 84. #endif 85. if(pl_character[0] == 'E' && flags.female && Is_qstart(&u.uz)) { 86. register struct monst *mtmp; 87. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) /* find the leader... */ 88. if(mtmp->data->msound == MS_LEADER) { 89. mtmp->data = &mons[PM_ELWING]; /* sex-change */ 90. break; 91. } 92. } else if(pl_character[0] == 'P' && Is_qstart(&u.uz)) { 93. 94. register struct monst *mtmp; 95. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) /* find leader & guards */ 96. if(mtmp->data->msound == MS_LEADER || 97. mtmp->data->msound == MS_GUARDIAN) { 98. /* use game-start alignment for reference */ 99. mtmp->data->maligntyp = u.ualignbase[1]*3; 100. mtmp->mpeaceful = TRUE; 101. set_malign(mtmp); /* mpeaceful may have changed */ 102. } 103. } 104. } 105. 106. void 107. onquest() { 108. 109. if(Not_firsttime) return; 110. if(!Is_special(&u.uz)) return; 111. 112. if(Is_qstart(&u.uz)) on_start(); 113. else if(Is_qlocate(&u.uz) && u.uz.dlevel > u.uz0.dlevel) on_locate(); 114. else if(Is_nemesis(&u.uz)) on_goal(); 115. return; 116. } 117. 118. void 119. nemdead() { 120. if(!Qstat(killed_nemesis)) { 121. Qstat(killed_nemesis) = TRUE; 122. qt_pager(QT_KILLEDNEM); 123. } 124. } 125. 126. void 127. artitouch() { 128. if(!Qstat(touched_artifact)) { 129. Qstat(touched_artifact) = TRUE; 130. qt_pager(QT_GOTIT); 131. exercise(A_WIS, TRUE); 132. } 133. } 134. 135. /* external hook for do.c (level change check) */ 136. boolean 137. ok_to_quest() { 138. 139. return(Qstat(got_quest)); 140. } 141. 142. static boolean 143. not_capable() { 144. return(u.ulevel < MIN_QUEST_LEVEL); 145. } 146. 147. /* TODO: This one needs tuning. */ 148. static boolean 149. not_pure() { 150. #ifdef WIZARD 151. if(wizard && (u.ualign.record < MIN_QUEST_ALIGN)) { 152. 153. You("are currently %d and require %d.", 154. u.ualign.record, MIN_QUEST_ALIGN); 155. if(yn_function("adjust?", NULL, 'y') == 'y') 156. u.ualign.record = MIN_QUEST_ALIGN; 157. } 158. #endif 159. return(u.ualign.record < MIN_QUEST_ALIGN); 160. } 161. 162. /* 163. * Expell the player to the stairs on the parent of the quest dungeon. 164. * 165. * This assumes that the hero is currently _in_ the quest dungeon and that 166. * there is a single branch to and from it. 167. */ 168. static void 169. expulsion(seal) 170. boolean seal; 171. { 172. branch *br; 173. d_level *dest; 174. 175. br = dungeon_branch("The Quest"); 176. dest = (br->end1.dnum == u.uz.dnum) ? &br->end2 : &br->end1; 177. assign_level(&u.utolev, dest); 178. u.utotype = 1; /* portal */ 179. if (seal) { /* remove the portal to the quest - sealing it off */ 180. u.utotype |= 0200; 181. u.uevent.qexpelled = 1; 182. } 183. } 184. 185. static void 186. chat_with_leader() 187. { 188. /* Rule 0: Cheater checks. */ 189. if(u.uhave.questart && !Qstat(met_nemesis)) 190. Qstat(cheater) = TRUE; 191. 192. /* It is possible for you to get the amulet without completing 193. * the quest. If so, try to induce the player to quest. 194. */ 195. if(Qstat(got_thanks)) { 196. /* Rule 1: You've gone back with/whithout the amulet. */ 197. if(u.uhave.amulet) qt_pager(QT_HASAMULET); 198. 199. /* Rule 2: You've gone back before going for the amulet. */ 200. else qt_pager(QT_POSTHANKS); 201. } 202. 203. /* Rule 3: You've got the artifact and are back to return it. */ 204. else if(u.uhave.questart) { 205. if(u.uhave.amulet) qt_pager(QT_HASAMULET); 206. else qt_pager(QT_OFFEREDIT); 207. Qstat(got_thanks) = TRUE; 208. u.uevent.qcompleted = 1; /* you did it! */ 209. 210. /* Rule 4: You haven't got the artifact yet. */ 211. } else if(Qstat(got_quest)) qt_pager(rn1(10, QT_ENCOURAGE)); 212. 213. /* Rule 5: You aren't yet acceptable - or are you? */ 214. else { 215. if(!Qstat(met_leader)) { 216. qt_pager(QT_FIRSTLEADER); 217. Qstat(met_leader) = TRUE; 218. Qstat(not_ready) = 0; 219. } else qt_pager(QT_NEXTLEADER); 220. 221. if(not_capable()) { 222. qt_pager(QT_BADLEVEL); 223. exercise(A_WIS, TRUE); 224. expulsion(FALSE); 225. } else if(not_pure()) { 226. qt_pager(QT_BADALIGN); 227. if(Qstat(not_ready) == MAX_QUEST_TRIES) { 228. qt_pager(QT_LASTLEADER); 229. expulsion(TRUE); 230. } else { 231. Qstat(not_ready)++; 232. exercise(A_WIS, TRUE); 233. expulsion(FALSE); 234. } 235. } else { /* You are worthy! */ 236. qt_pager(QT_ASSIGNQUEST); 237. exercise(A_WIS, TRUE); 238. Qstat(got_quest) = TRUE; 239. } 240. } 241. } 242. 243. void 244. leader_speaks(mtmp) 245. 246. register struct monst *mtmp; 247. { 248. /* maybe you attacked leader? */ 249. if(!mtmp->mpeaceful) { 250. Qstat(pissed_off) = TRUE; 251. mtmp->data->mflags3 = 0; /* end the inaction */ 252. } 253. 254. if(Qstat(pissed_off)) { 255. qt_pager(QT_LASTLEADER); 256. expulsion(TRUE); 257. } else chat_with_leader(); 258. 259. } 260. 261. static void 262. chat_with_nemesis() 263. { 264. /* The nemesis will do most of the talking, but... */ 265. qt_pager(rn1(10, QT_DISCOURAGE)); 266. if(!Qstat(met_nemesis)) Qstat(met_nemesis++); 267. } 268. 269. void 270. nemesis_speaks() 271. { 272. if(!Qstat(in_battle)) { 273. if(u.uhave.questart) qt_pager(QT_NEMWANTSIT); 274. else if(!Qstat(made_goal)) qt_pager(QT_FIRSTNEMESIS); 275. else if(Qstat(made_goal) < 3) qt_pager(QT_NEXTNEMESIS); 276. else if(Qstat(made_goal) < 7) qt_pager(QT_OTHERNEMESIS); 277. else if(!rn2(5)) qt_pager(rn1(10, QT_DISCOURAGE)); 278. if(Qstat(made_goal) < 7) Qstat(made_goal)++; 279. Qstat(met_nemesis) = TRUE; 280. } else /* he will spit out random maledictions */ 281. if(!rn2(5)) qt_pager(rn1(10, QT_DISCOURAGE)); 282. } 283. 284. static void 285. chat_with_guardian() 286. { 287. /* These guys/gals really don't have much to say... */ 288. qt_pager(rn1(5, QT_GUARDTALK)); 289. } 290. 291. void 292. quest_chat(mtmp) 293. 294. register struct monst *mtmp; 295. { 296. 297. switch(mtmp->data->msound) { 298. case MS_LEADER: chat_with_leader(); break; 299. case MS_NEMESIS: chat_with_nemesis(); break; 300. case MS_GUARDIAN: chat_with_guardian(); break; 301. default: impossible("quest_chat: Unknown quest character %s.", 302. mon_nam(mtmp)); 303. } 304. } 305. 306. void 307. quest_talk(mtmp) 308. 309. register struct monst *mtmp; 310. { 311. switch(mtmp->data->msound) { 312. case MS_LEADER: leader_speaks(mtmp); break; 313. case MS_NEMESIS: nemesis_speaks(); break; 314. default: break; 315. } 316. } 317. 318. void 319. quest_stat_check(mtmp) 320. 321. struct monst *mtmp; 322. { 323. if(mtmp->data->msound == MS_NEMESIS) 324. Qstat(in_battle) = 325. (mtmp->mcanmove && !mtmp->msleep && monnear(mtmp, u.ux, u.uy)); 326. } 327. 328. #endif /* MULDGN */ 329. 330. /*quest.c*/
|