Source:NetHack 3.4.3/src/allmain.c
Jump to navigation
Jump to search
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 <signal.h> 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*/