Source:NetHack 3.4.0/allmain.c

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