Source:NetHack 3.1.0/quest.c

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