Source:NetHack 3.3.0/allmain.c
Revision as of 10:05, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.3.0/allmain.c moved to Source:NetHack 3.3.0/allmain.c: Robot: moved page)
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
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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 <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. #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*/