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