Source:NetHack 3.3.0/allmain.c

Below is the full text to allmain.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/allmain.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)allmain.c	3.3	1999/11/30	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /* various code that was replicated in *main.c */ 6.    7.    #include "hack.h"  8. 9.   #ifndef NO_SIGNAL 10.  #include   11. #endif 12.   13.   #ifdef POSITIONBAR 14.  STATIC_DCL void NDECL(do_positionbar); 15.  #endif 16.   17.   #ifdef OVL0 18.   19.   void 20.  moveloop 21.  {  22.   #ifdef MICRO 23.  	char ch; 24.  	int abort_lev; 25.  #endif 26.  	int moveamt = 0, wtcap = 0, change = 0; 27.  	boolean didmove = FALSE, monscanmove = FALSE; 28.   29.   	flags.moonphase = phase_of_the_moon; 30.  	if(flags.moonphase == FULL_MOON) { 31.  		You("are lucky!  Full moon tonight."); 32.  		change_luck(1); 33.  	} else if(flags.moonphase == NEW_MOON) { 34.  		pline("Be careful!  New moon tonight."); 35.  	}  36.   	flags.friday13 = friday_13th; 37.  	if (flags.friday13) { 38.  		pline("Watch out!  Bad things can happen on Friday the 13th."); 39.  		change_luck(-1); 40.  	}  41.    42.   	initrack; 43.   44.    45.   	/* Note:  these initializers don't do anything except guarantee that 46.  		we're linked properly. 47.  	*/  48.   	decl_init; 49.  	monst_init; 50.  	monstr_init;	/* monster strengths */ 51.  	objects_init; 52.   53.   #ifdef WIZARD 54.  	if (wizard) add_debug_extended_commands; 55.  #endif 56.   57.   	(void) encumber_msg; /* in case they auto-picked up something */ 58.   59.   	u.uz0.dlevel = u.uz.dlevel; 60.   61.   	for { 62.  #ifdef CLIPPING 63.  		cliparound(u.ux, u.uy); 64.  #endif 65.  		get_nh_event; 66.  #ifdef POSITIONBAR 67.  		do_positionbar; 68.  #endif 69.   70.   		didmove = flags.move; 71.  		if(didmove) { 72.  		    /* actual time passed */ 73.  		    if (youmonst.movement >= NORMAL_SPEED) { 74.  			youmonst.movement -= NORMAL_SPEED; 75.  			++moves; 76.  		    }  77.    78.   		    if (u.utotype) deferred_goto; 79.  		    wtcap = encumber_msg; 80.  		    dosounds; 81.   82.   		    flags.mon_moving = TRUE; 83.  		    do { 84.  			monscanmove = movemon; 85.  			if (youmonst.movement > NORMAL_SPEED) 86.  			    break;	/* it's now your turn */ 87.  		    } while (monscanmove); 88.  		    flags.mon_moving = FALSE; 89.   90.   		    if (!monscanmove && youmonst.movement < NORMAL_SPEED) { 91.  			/* both you and the monsters are out of steam this round */ 92.  			struct monst *mtmp; 93.  			mcalcdistress;	/* adjust monsters' trap, blind, etc */ 94.   95.   			/* reallocate movement rations to monsters */ 96.  			for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 97.  			    mcalcmove(mtmp); 98.   99.   			if(!rn2(u.uevent.udemigod ? 25 : 100.  				(depth(&u.uz) > depth(&stronghold_level)) ? 50 : 70)) 101.  			    (void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS); 102.  103.  			/* calculate how much time passed. */ 104.  #ifdef STEED 105. 		      if (u.usteed && flags.mv) { 106. 			/* your speed doesn't augment steed's speed */ 107. 			moveamt = u.usteed->movement; 108. 		      } else { 109. #endif 110. 			moveamt = youmonst.data->mmove; 111.  112.  			if (Very_fast) {	/* speed boots or potion */ 113. 			    /* average movement is 1.67 times normal */ 114. 			    moveamt += NORMAL_SPEED / 2; 115. 			    if (rn2(3) == 0) moveamt += NORMAL_SPEED / 2; 116. 			} else if (Fast) { 117. 			    /* average movement is 1.33 times normal */ 118. 			    if (rn2(3) != 0) moveamt += NORMAL_SPEED / 2; 119. 			}  120.  #ifdef STEED 121. 		      }  122.  #endif 123. 			switch (wtcap) { 124. 			case UNENCUMBERED: break; 125. 			case SLT_ENCUMBER: moveamt -= (moveamt / 4); break; 126. 			case MOD_ENCUMBER: moveamt -= (moveamt / 2); break; 127. 			case HVY_ENCUMBER: moveamt -= ((moveamt * 3) / 4); break; 128. 			case EXT_ENCUMBER: moveamt -= ((moveamt * 7) / 8); break; 129. 			default: break; 130. 			}  131.   132.  			youmonst.movement += moveamt; 133. 			if (youmonst.movement < 0) youmonst.movement = 0; 134. 			settrack; 135.  136.  			monstermoves++; 137. 		    }			  138.   139.  		    if(Glib) glibr; 140. 		    nh_timeout; 141. 		    run_regions; 142.  143.  		    if (u.ublesscnt)  u.ublesscnt--; 144. 		    if(flags.time && !flags.run) 145. 			    flags.botl = 1; 146.  147.  		    /* One possible result of prayer is healing. Whether or 148. * not you get healed depends on your current hit points. 149. 		     * If you are allowed to regenerate during the prayer, the 150. 		     * end-of-prayer calculation messes up on this. 151. 		     * Another possible result is rehumanization, which requires 152. 		     * that encumbrance and movement rate be recalculated. 153. 		     */  154.  		    if (u.uinvulnerable) { 155. 			/* for the moment at least, you're in tiptop shape */ 156. 			wtcap = UNENCUMBERED; 157. 		    } else if (Upolyd && u.mh < u.mhmax) { 158. 			if (u.mh < 1) 159. 			   rehumanize; 160. 			else if (Regeneration ||  161.  				    (wtcap < MOD_ENCUMBER && !(moves%20))) { 162. 			    flags.botl = 1; 163. 			    u.mh++; 164. 			}  165.  		    } else if (u.uhp < u.uhpmax &&  166.  			 (wtcap < MOD_ENCUMBER || !flags.mv || Regeneration)) { 167. 			if (u.ulevel > 9 && !(moves % 3)) { 168. 			    int heal, Con = (int) ACURR(A_CON); 169.  170.  			    if (Con <= 12) { 171. 				heal = 1; 172. 			    } else { 173. 				heal = rnd(Con); 174. 				if (heal > u.ulevel-9) heal = u.ulevel-9; 175. 			    }  176.  			    flags.botl = 1; 177. 			    u.uhp += heal; 178. 			    if(u.uhp > u.uhpmax) 179. 				u.uhp = u.uhpmax; 180. 			} else if (Regeneration ||  181.  			     (u.ulevel <= 9 && 182. 			      !(moves % ((MAXULEV+12) / (u.ulevel+2) + 1)))) { 183. 			    flags.botl = 1; 184. 			    u.uhp++; 185. 			}  186.  		    }  187.   188.  		    if (wtcap > MOD_ENCUMBER && flags.mv) { 189. 			if(!(wtcap < EXT_ENCUMBER ? moves%30 : moves%10)) { 190. 			    if (Upolyd && u.mh > 1) { 191. 				u.mh--; 192. 			    } else if (!Upolyd && u.uhp > 1) { 193. 				u.uhp--; 194. 			    } else { 195. 				You("pass out from exertion!"); 196. 				exercise(A_CON, FALSE); 197. 				fall_asleep(-10, FALSE); 198. 			    }  199.  			}  200.  		    }  201.   202.  		    if ((u.uen < u.uenmax) &&  203.  			((wtcap < MOD_ENCUMBER &&  204.  			  (!(moves%((MAXULEV + 8 - u.ulevel) * 205. 				    (Role_if(PM_WIZARD) ? 3 : 4) / 6)))) 206. 			 || Energy_regeneration)) { 207. 			u.uen += rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1,1); 208. 			if (u.uen > u.uenmax)  u.uen = u.uenmax; 209. 			flags.botl = 1; 210. 		    }  211.   212.  		    if(!u.uinvulnerable) { 213. 			if(Teleportation && !rn2(85)) { 214. #ifdef REDO 215. 			    xchar old_ux = u.ux, old_uy = u.uy; 216. #endif 217. 			    tele; 218. #ifdef REDO 219. 			    if (u.ux != old_ux || u.uy != old_uy) { 220. 			    	/* clear doagain keystrokes */ 221. 				pushch(0); 222. 				savech(0); 223. 			    }  224.  #endif 225. 			}  226.  			if(Polymorph && !rn2(100)) 227. 			    change = 1; 228. 			else if (u.ulycn >= LOW_PM && !rn2(80 - (20 * night))) 229. 			    change = 2; 230. 			if (change && !Unchanging) { 231. 			    if (multi >= 0) { 232. 				if (occupation) 233. 				    stop_occupation; 234. 				else 235. 				    nomul(0); 236. 				if (change == 1) polyself; 237. 				else you_were; 238. 				change = 0; 239. 			    }  240.  			}  241.  		    }  242.   243.  		    if(Searching && multi >= 0) (void) dosearch0(1); 244. 		    do_storms; 245. 		    gethungry; 246. 		    age_spells; 247. 		    exerchk; 248. 		    invault; 249. 		    if (u.uhave.amulet) amulet; 250. 		    if (!rn2(40+(int)(ACURR(A_DEX)*3))) 251. 			u_wipe_engr(rnd(3)); 252. 		    if (u.uevent.udemigod && !u.uinvulnerable) { 253. 			if (u.udg_cnt) u.udg_cnt--; 254. 			if (!u.udg_cnt) { 255. 			    intervene; 256. 			    u.udg_cnt = rn1(200, 50); 257. 			}  258.  		    }  259.  		    restore_attrib; 260. 		    /* underwater and waterlevel vision are done here */ 261. 		    if (Is_waterlevel(&u.uz)) 262. 			movebubbles; 263. 		    else if (Underwater) 264. 		    	under_water(0); 265. 		    /* vision while buried done here */ 266. 		    else if (u.uburied) under_ground(0); 267. 		}  268.  		if(multi < 0) { 269. 		    if (++multi == 0)	/* finished yet? */ 270.  			unmul((char *)0); 271. 		}  272.   273.  		find_ac; 274. 		if(!flags.mv || Blind) { 275. 		    /* redo monsters if hallu or wearing a helm of telepathy */ 276. 		    if (Hallucination) {	/* update screen randomly */ 277. 			see_monsters; 278. 			see_objects; 279. 			see_traps; 280. 			if (u.uswallow) swallowed(0); 281. 		    } else if (Unblind_telepat) { 282. 			see_monsters; 283. 		    }  284.  		    if (vision_full_recalc) vision_recalc(0);	/* vision! */ 285.  		}  286.  		if(flags.botl || flags.botlx) bot; 287.  288.  		flags.move = 1; 289.  290.  		if(multi >= 0 && occupation) { 291. #ifdef MICRO 292. 		    abort_lev = 0; 293. 		    if (kbhit) { 294. 			if ((ch = Getchar) == ABORT) 295. 			    abort_lev++; 296. # ifdef REDO 297. 			else 298. 			    pushch(ch); 299. # endif /* REDO */ 300. 		    }  301.  		    if (!abort_lev && (*occupation) == 0) 302. #else 303. 		    if ((*occupation) == 0) 304. #endif 305. 			occupation = 0; 306. 		    if(  307.  #ifdef MICRO  308.  			   abort_lev ||  309.  #endif  310.  			   monster_nearby) { 311. 			stop_occupation; 312. 			reset_eat; 313. 		    }  314.  #ifdef MICRO 315. 		    if (!(++occtime % 7)) 316. 			display_nhwindow(WIN_MAP, FALSE); 317. #endif 318. 		    continue; 319. 		}  320.   321.  		if ((u.uhave.amulet || Clairvoyant) &&  322.  		    !In_endgame(&u.uz) && !BClairvoyant &&  323.  		    !(moves % 15) && !rn2(2)) 324. 			do_vicinity_map; 325.  326.  		if(u.utrap && u.utraptype == TT_LAVA) { 327. 		    if(!is_lava(u.ux,u.uy)) 328. 			u.utrap = 0; 329. 		    else { 330. 			u.utrap -= 1<<8; 331. 			if(u.utrap < 1<<8) { 332. 			    killer_format = KILLED_BY; 333. 			    killer = "molten lava"; 334. 			    You("sink below the surface and die."); 335. 			    done(DISSOLVED); 336. 			} else if(didmove && !u.umoved) { 337. 			    Norep("You sink deeper into the lava."); 338. 			    u.utrap += rnd(4); 339. 			}  340.  		    }  341.  		}  342.   343.  #ifdef WIZARD 344. 		if (iflags.sanity_check) 345. 		    sanity_check; 346. #endif 347.  348.  		u.umoved = FALSE; 349.  350.  		if (multi > 0) { 351. 		    lookaround; 352. 		    if (!multi) { 353. 			/* lookaround may clear multi */ 354. 			flags.move = 0; 355. 			continue; 356. 		    }  357.  		    if (flags.mv) { 358. 			if(multi < COLNO && !--multi) 359. 			    flags.mv = flags.run = 0; 360. 			domove; 361. 		    } else { 362. 			--multi; 363. 			rhack(save_cm); 364. 		    }  365.  		} else if (multi == 0) { 366. #ifdef MAIL 367. 		    ckmailstatus; 368. #endif 369. 		    rhack((char *)0); 370. 		}  371.  		if (u.utotype)		/* change dungeon level */ 372. 		    deferred_goto;	/* after rhack */ 373. 		/* !flags.move here: multiple movement command stopped */ 374. 		else if (flags.time && (!flags.move || !flags.mv)) 375. 		    flags.botl = 1; 376.  377.  		if (vision_full_recalc) vision_recalc(0);	/* vision! */ 378.  		if (multi && multi%7 == 0) 379. 		    display_nhwindow(WIN_MAP, FALSE); 380. 	}  381.  }  382.   383.  #endif /* OVL0 */ 384. #ifdef OVL1 385.  386.  void 387. stop_occupation 388. {  389.  	if(occupation) { 390. 		You("stop %s.", occtxt); 391. 		occupation = 0; 392. /* fainting stops your occupation, there's no reason to sync. 393. 		sync_hunger; 394. */  395.  #ifdef REDO 396. 		nomul(0); 397. 		pushch(0); 398. #endif 399. 	}  400.  }  401.   402.  #endif /* OVL1 */ 403. #ifdef OVLB 404.  405.  void 406. display_gamewindows 407. {  408.      WIN_MESSAGE = create_nhwindow(NHW_MESSAGE); 409.     WIN_STATUS = create_nhwindow(NHW_STATUS); 410.     WIN_MAP = create_nhwindow(NHW_MAP); 411.     WIN_INVEN = create_nhwindow(NHW_MENU); 412.  413.  #ifdef MAC 414.     /*  415.       * This _is_ the right place for this - maybe we will 416.      * have to split display_gamewindows into create_gamewindows 417.      * and show_gamewindows to get rid of this ifdef...  418. */ 419.  	if ( ! strcmp ( windowprocs. name, "mac" ) ) { 420. 	    SanePositions  ; 421. 	}  422.  #endif 423.  424.      /*  425.       * The mac port is not DEPENDENT on the order of these 426.      * displays, but it looks a lot better this way...  427. */ 428.      display_nhwindow(WIN_STATUS, FALSE); 429.     display_nhwindow(WIN_MESSAGE, FALSE); 430.     clear_glyph_buffer; 431.     display_nhwindow(WIN_MAP, FALSE); 432. }  433.   434.  void 435. newgame 436. {  437.  	int i;  438. 439. #ifdef MFLOPPY 440. 	gameDiskPrompt; 441. #endif 442.  443.  	flags.ident = 1; 444.  445.  	for (i = 0; i < NUMMONS; i++) 446. 		mvitals[i].mvflags = mons[i].geno & G_NOCORPSE; 447.  448.  	init_objects;		/* must be before u_init */ 449. 	u_init; 450. 	init_dungeons;	/* must be after u_init */ 451. 	init_artifacts;	/* must be after u_init */ 452.  453.  #ifndef NO_SIGNAL 454. 	(void) signal(SIGINT, (SIG_RET_TYPE) done1); 455. #endif 456. #ifdef NEWS 457. 	if(iflags.news) display_file(NEWS, FALSE); 458. #endif 459. 	load_qtlist;	/* load up the quest text info */ 460. /*	quest_init;*/	/* Now part of role_init */ 461.  462.  	mklev; 463. 	u_on_upstairs; 464. 	vision_reset;		/* set up internals for level (after mklev) */ 465. 	check_special_room(FALSE); 466.  467.  	flags.botlx = 1; 468.  469.  	/* Move the monster from under you or else 470. 	 * makedog will fail when it calls makemon. 471. 	 *			- ucsfcgl!kneller 472. 	 */  473.  	if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy)); 474. 	(void) makedog; 475. 	docrt; 476.  477.  	if (flags.legacy) { 478. 		flush_screen(1); 479. 		com_pager(1); 480. 	}  481.   482.  #ifdef INSURANCE 483. 	save_currentstate; 484. #endif 485. 	program_state.something_worth_saving++;	/* useful data now exists */ 486.  487.  	/* Success! */ 488.  	welcome(TRUE); 489. 	return; 490. }  491.   492.  /* show "welcome [back] to nethack" message at program startup */ 493. void 494. welcome(new_game) 495. boolean new_game;	/* false => restoring an old game */ 496. {  497.      char buf[BUFSZ]; 498.     boolean currentgend = Upolyd ? u.mfemale : flags.female; 499.  500.      /*  501.       * The "welcome back" message always describes your innate form 502.      * even when polymorphed or wearing a helm of opposite alignment. 503.      * Alignment is shown unconditionally for new games; for restores 504.      * it's only shown if it has changed from its original value. 505.      * Sex is shown for new games except when it is redundant; for 506.      * restores it's only shown if different from its original value. 507.      */  508.      *buf = '\0'; 509.     if (new_game || u.ualignbase[1] != u.ualignbase[0]) 510. 	Sprintf(eos(buf), " %s", align_str(u.ualignbase[1])); 511.     if (!urole.name.f &&  512.  	    (new_game ? (urole.allow & ROLE_GENDMASK) == (ROLE_MALE|ROLE_FEMALE) : 513. 	     currentgend != flags.initgend)) 514. 	Sprintf(eos(buf), " %s", genders[currentgend].adj); 515.  516.      pline(new_game ? "%s %s, welcome to NetHack!  You are a%s %s %s."  517.  		   : "%s %s, the%s %s %s, welcome back to NetHack!",  518.  	  Hello, plname, buf, urace.adj,  519.  	  (currentgend && urole.name.f) ? urole.name.f : urole.name.m); 520. }  521.   522.  #ifdef POSITIONBAR 523. STATIC_DCL void 524. do_positionbar 525. {  526.  	static char pbar[COLNO]; 527. 	char *p; 528. 	  529.  	p = pbar; 530. 	/* up stairway */ 531. 	if (upstair.sx &&  532.  	   (glyph_to_cmap(level.locations[upstair.sx][upstair.sy].glyph) == 533. 	    S_upstair || 534.  	    glyph_to_cmap(level.locations[upstair.sx][upstair.sy].glyph) == 535. 	    S_upladder)) { 536. 		*p++ = '<'; 537. 		*p++ = upstair.sx; 538. 	}  539.  	if (sstairs.sx &&  540.  	   (glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == 541. 	    S_upstair || 542.  	    glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == 543. 	    S_upladder)) { 544. 		*p++ = '<'; 545. 		*p++ = sstairs.sx; 546. 	}  547.   548.  	/* down stairway */ 549. 	if (dnstair.sx &&  550.  	   (glyph_to_cmap(level.locations[dnstair.sx][dnstair.sy].glyph) == 551. 	    S_dnstair || 552.  	    glyph_to_cmap(level.locations[dnstair.sx][dnstair.sy].glyph) == 553. 	    S_dnladder)) { 554. 		*p++ = '>'; 555. 		*p++ = dnstair.sx; 556. 	}  557.  	if (sstairs.sx &&  558.  	   (glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == 559. 	    S_dnstair || 560.  	    glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == 561. 	    S_dnladder)) { 562. 		*p++ = '>'; 563. 		*p++ = sstairs.sx; 564. 	}  565.   566.  	/* hero location */ 567. 	if (u.ux) { 568. 		*p++ = '@'; 569. 		*p++ = u.ux; 570. 	}  571.  	/* fence post */ 572. 	*p = 0; 573.  574.  	update_positionbar(pbar); 575. }  576.  #endif 577.  578.  #endif /* OVLB */ 579.  580.  /*allmain.c*/