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