Source:NetHack 3.1.0/quest.c
Revision as of 07:19, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.1.0/quest.c moved to Source:NetHack 3.1.0/quest.c: Robot: moved page)
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
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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*/