Source:Allmain.c

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