Source:NetHack 3.1.0/do.c
Jump to navigation
Jump to search
Below is the full text to do.c from the source code of NetHack 3.1.0.
Warning! This is the source code from an old release. For newer releases, 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: @(#)do.c 3.1 92/11/11 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) */ 6. 7. #include "hack.h" 8. #include "lev.h" 9. 10. #include <errno.h> 11. #ifdef _MSC_VER /* MSC 6.0 defines errno quite differently */ 12. # if (_MSC_VER >= 600) 13. # define SKIP_ERRNO 14. # endif 15. #endif 16. #ifndef SKIP_ERRNO 17. extern int errno; 18. #endif 19. 20. #ifdef MFLOPPY 21. extern struct finfo fileinfo[]; 22. #else 23. extern boolean level_exists[]; 24. #endif 25. 26. #ifdef SINKS 27. # ifdef OVLB 28. static void FDECL(trycall, (struct obj *)); 29. # endif /* OVLB */ 30. STATIC_DCL void FDECL(dosinkring, (struct obj *)); 31. #endif /* SINKS */ 32. 33. STATIC_PTR int FDECL(drop, (struct obj *)); 34. STATIC_PTR int NDECL(wipeoff); 35. 36. #ifdef OVL2 37. static int NDECL(currentlevel_rewrite); 38. /* static boolean FDECL(badspot, (XCHAR_P,XCHAR_P)); */ 39. #endif 40. 41. #ifdef OVLB 42. 43. static const char NEARDATA drop_types[] = 44. { ALLOW_COUNT, GOLD_CLASS, ALL_CLASSES, 0 }; 45. 46. int 47. dodrop() 48. { 49. int result; 50. 51. if (*u.ushops) sellobj_state(TRUE); 52. result = drop(getobj(drop_types, "drop")); 53. if (*u.ushops) sellobj_state(FALSE); 54. reset_occupations(); 55. 56. return result; 57. } 58. 59. #endif /* OVLB */ 60. #ifdef OVL0 61. 62. /* Called when a boulder is dropped, thrown, or pushed. If it ends up 63. * in a pool, it either fills the pool up or sinks away. In either case, 64. * it's gone for good... If the destination is not a pool, returns FALSE. 65. */ 66. boolean 67. boulder_hits_pool(otmp, rx, ry, pushing) 68. struct obj *otmp; 69. register int rx, ry; 70. boolean pushing; 71. { 72. if (!otmp || otmp->otyp != BOULDER) 73. impossible("Not a boulder?"); 74. else if (!Is_waterlevel(&u.uz) && (is_pool(rx,ry) || is_lava(rx,ry))) { 75. boolean lava = is_lava(rx,ry), fills_up; 76. const char *what = lava ? "lava" : "water"; 77. schar ltyp = levl[rx][ry].typ; 78. int chance = rn2(10); /* water: 90%; lava: 10% */ 79. fills_up = lava ? chance == 0 : chance != 0; 80. 81. if (fills_up) { 82. if (ltyp == DRAWBRIDGE_UP) { 83. levl[rx][ry].drawbridgemask &= ~DB_UNDER; /* clear lava */ 84. levl[rx][ry].drawbridgemask |= DB_FLOOR; 85. } else 86. levl[rx][ry].typ = ROOM; 87. 88. delallobj(rx, ry); 89. newsym(rx,ry); 90. if (pushing) { 91. You("push %s into the %s.", the(xname(otmp)), what); 92. if (flags.verbose && !Blind) 93. pline("Now you can cross it!"); 94. /* no splashing in this case */ 95. } 96. } 97. if (!fills_up || !pushing) { /* splashing occurs */ 98. if (pushing ? !Blind : cansee(rx,ry)) 99. pline("There is a large splash as %s %s the %s.", 100. the(xname(otmp)), fills_up ? "fills" : "falls into", 101. lava ? "lava" : ltyp==POOL ? "pool" : "moat"); 102. else if (flags.soundok) 103. You("hear a%s splash.", lava ? " sizzling" : ""); 104. wake_nearby(); 105. 106. if (fills_up && u.uinwater && distu(rx,ry) == 0) { 107. You("find yourself on dry land again!"); 108. u.uinwater = 0; 109. } else if (lava && distu(rx,ry) <= 2) { 110. You("are hit by molten lava%c", 111. Fire_resistance ? '.' : '!'); 112. losehp(d((Fire_resistance ? 1 : 3), 6), 113. "molten lava", KILLED_BY); 114. } else if (!fills_up && flags.verbose && 115. (pushing ? !Blind : cansee(rx,ry))) 116. pline("It sinks without a trace!"); 117. } 118. 119. /* boulder is now gone */ 120. if (pushing) delobj(otmp); 121. else obfree(otmp, (struct obj *)0); 122. return TRUE; 123. } 124. return FALSE; 125. } 126. 127. /* Used for objects which sometimes do special things when dropped; must be 128. * called with the object not in any chain. Returns 1 if the object is 129. * gone. 130. */ 131. boolean 132. flooreffects(obj,x,y,verb) 133. struct obj *obj; 134. int x,y; 135. const char *verb; 136. { 137. struct trap *t; 138. 139. if (obj->otyp == BOULDER && boulder_hits_pool(obj, x, y, FALSE)) 140. return TRUE; 141. else if (obj->otyp == BOULDER && (t = t_at(x,y)) != 0 && 142. (t->ttyp==PIT || t->ttyp==SPIKED_PIT || t->ttyp==TRAPDOOR)) { 143. struct monst *mtmp; 144. 145. delallobj(x, y); 146. if(!Can_fall_thru(&u.uz) && t->ttyp == TRAPDOOR) 147. return FALSE; 148. if (((mtmp = m_at(x, y)) && mtmp->mtrapped) || 149. (u.utrap && x==u.ux && y==u.uy)) { 150. /* u.utrap = 0; /* player remains trapped. See trap.c */ 151. if (*verb) 152. pline("The boulder %ss into the pit%s.", verb, 153. (mtmp)? "" : " with you"); 154. if (mtmp) { 155. if (!passes_walls(mtmp->data) && !throws_rocks(mtmp->data)) 156. if (hmon(mtmp, obj, TRUE)) 157. return FALSE; /* still alive */ 158. else 159. delallobj(x, y); /* treasure, corpse */ 160. } else 161. #ifdef POLYSELF 162. if (!passes_walls(uasmon) && !throws_rocks(uasmon)) 163. #endif 164. { 165. losehp(rnd(15), "squished under a boulder", 166. NO_KILLER_PREFIX); 167. return FALSE; 168. } 169. } 170. if (*verb) { 171. if (Blind) { 172. if ((x == u.ux) && (y == u.uy)) 173. You("hear a CRASH! beneath you."); 174. else 175. You("hear the boulder %s.", verb); 176. } else if (cansee(x, y)) { 177. pline("The boulder %sfills a %s.", 178. t->tseen ? "" : "triggers and ", 179. t->ttyp == TRAPDOOR ? 180. "trap door" : "pit"); 181. } 182. } 183. deltrap(t); 184. obfree(obj, (struct obj *)0); 185. newsym(x,y); 186. return TRUE; 187. } 188. return FALSE; 189. } 190. 191. #endif /* OVL0 */ 192. #ifdef OVLB 193. 194. void 195. doaltarobj(obj) /* obj is an object dropped on an altar */ 196. register struct obj *obj; 197. { 198. if (Blind) return; 199. if (obj->blessed || obj->cursed) { 200. pline("There is %s flash as %s hit%s the altar.", 201. an(Hallucination ? hcolor() : 202. obj->blessed ? amber : Black), 203. doname(obj), 204. (obj->quan == 1L) ? "s" : ""); 205. if (!Hallucination) obj->bknown = 1; 206. } else { 207. pline("%s land%s on the altar.", Doname2(obj), 208. (obj->quan == 1L) ? "s" : ""); 209. if (obj->otyp != GOLD_PIECE) 210. obj->bknown = 1; 211. } 212. } 213. 214. #ifdef SINKS 215. static 216. void 217. trycall(obj) 218. register struct obj *obj; 219. { 220. if(!objects[obj->otyp].oc_name_known && 221. !objects[obj->otyp].oc_uname) 222. docall(obj); 223. } 224. 225. STATIC_OVL 226. void 227. dosinkring(obj) /* obj is a ring being dropped over a kitchen sink */ 228. register struct obj *obj; 229. { 230. register struct obj *otmp,*otmp2; 231. register boolean ideed = TRUE; 232. 233. You("drop %s down the drain.", doname(obj)); 234. switch(obj->otyp) { /* effects that can be noticed without eyes */ 235. case RIN_SEARCHING: 236. You("thought your %s got lost in the sink, but there it is!", 237. xname(obj)); 238. dropx(obj); 239. trycall(obj); 240. return; 241. case RIN_LEVITATION: 242. pline("The sink quivers upward for a moment."); 243. break; 244. case RIN_POISON_RESISTANCE: 245. #ifdef TUTTI_FRUTTI 246. You("smell rotten %s.", makeplural(pl_fruit)); 247. #else 248. You("smell rotten fruit."); 249. #endif 250. break; 251. case RIN_AGGRAVATE_MONSTER: 252. pline("Several flies buzz angrily around the sink."); 253. break; 254. case RIN_SHOCK_RESISTANCE: 255. pline("Static electricity surrounds the sink."); 256. break; 257. case RIN_CONFLICT: 258. You("hear loud noises coming from the drain."); 259. break; 260. case RIN_GAIN_STRENGTH: 261. pline("The water flow seems %ser now.", 262. (obj->spe<0) ? "weak" : "strong"); 263. break; 264. case RIN_INCREASE_DAMAGE: 265. pline("The water's force seems %ser now.", 266. (obj->spe<0) ? "small" : "great"); 267. break; 268. default: 269. ideed = FALSE; 270. break; 271. } 272. if(!Blind && !ideed) { 273. ideed = TRUE; 274. switch(obj->otyp) { /* effects that need eyes */ 275. case RIN_ADORNMENT: 276. pline("The faucets flash brightly for a moment."); 277. break; 278. case RIN_REGENERATION: 279. pline("The sink looks as good as new."); 280. break; 281. case RIN_INVISIBILITY: 282. You("don't see anything happen to the sink."); 283. break; 284. case RIN_SEE_INVISIBLE: 285. You("see some air in the sink."); 286. break; 287. case RIN_STEALTH: 288. pline("The sink seems to blend into the floor for a moment."); 289. break; 290. case RIN_HUNGER: 291. ideed = FALSE; 292. for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) { 293. otmp2 = otmp->nexthere; 294. if(otmp != uball && otmp != uchain) { 295. pline("Suddenly, %s vanishes from the sink!", 296. doname(otmp)); 297. delobj(otmp); 298. ideed = TRUE; 299. } 300. } 301. break; 302. case RIN_FIRE_RESISTANCE: 303. pline("The hot water faucet flashes brightly for a moment."); 304. break; 305. case RIN_COLD_RESISTANCE: 306. pline("The cold water faucet flashes brightly for a moment."); 307. break; 308. case RIN_PROTECTION_FROM_SHAPE_CHAN: 309. pline("The sink looks nothing like a fountain."); 310. break; 311. case RIN_PROTECTION: 312. pline("The sink glows %s for a moment.", 313. Hallucination ? hcolor() : 314. (obj->spe<0) ? Black : silver); 315. break; 316. case RIN_WARNING: 317. pline("The sink glows %s for a moment.", 318. Hallucination ? hcolor() : White); 319. break; 320. case RIN_TELEPORTATION: 321. pline("The sink momentarily vanishes."); 322. break; 323. case RIN_TELEPORT_CONTROL: 324. pline("The sink looks like it is being beamed aboard somewhere."); 325. break; 326. #ifdef POLYSELF 327. case RIN_POLYMORPH: 328. pline("The sink momentarily looks like a fountain."); 329. break; 330. case RIN_POLYMORPH_CONTROL: 331. pline("The sink momentarily looks like a regularly erupting geyser."); 332. break; 333. #endif 334. } 335. } 336. if(ideed) 337. trycall(obj); 338. else 339. You("hear the ring bouncing down the drainpipe."); 340. if (!rn2(20)) { 341. pline("The sink backs up, leaving %s.", doname(obj)); 342. dropx(obj); 343. } 344. else 345. useup(obj); 346. } 347. #endif 348. 349. #endif /* OVLB */ 350. #ifdef OVL0 351. 352. /* some common tests when trying to drop or throw items */ 353. boolean 354. canletgo(obj,word) 355. register struct obj *obj; 356. register const char *word; 357. { 358. if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)){ 359. if (*word) 360. Norep("You cannot %s something you are wearing.",word); 361. return(FALSE); 362. } 363. if (obj->otyp == LOADSTONE && obj->cursed) { 364. if (*word) 365. pline("For some reason, you cannot %s the stone%s!", 366. word, plur(obj->quan)); 367. /* Kludge -- see invent.c */ 368. if (obj->corpsenm) { 369. struct obj *otmp; 370. 371. otmp = obj; 372. obj = obj->nobj; 373. obj->quan += otmp->quan; 374. obj->owt = weight(obj); 375. freeinv(otmp); 376. obfree(otmp, obj); 377. } 378. obj->bknown = 1; 379. return(FALSE); 380. } 381. #ifdef WALKIES 382. if (obj->otyp == LEASH && obj->leashmon != 0) { 383. if (*word) 384. pline ("The leash is tied around your %s.", 385. body_part(HAND)); 386. return(FALSE); 387. } 388. #endif 389. return(TRUE); 390. } 391. 392. STATIC_PTR 393. int 394. drop(obj) 395. register struct obj *obj; 396. { 397. if(!obj) return(0); 398. if(!canletgo(obj,"drop")) 399. return(0); 400. if(obj == uwep) { 401. if(welded(uwep)) { 402. weldmsg(obj, FALSE); 403. return(0); 404. } 405. setuwep((struct obj *)0); 406. if(uwep) return 0; /* lifesaved and rewielded */ 407. } 408. #ifdef SINKS 409. if((obj->oclass == RING_CLASS) && IS_SINK(levl[u.ux][u.uy].typ) 410. && !u.uswallow) { 411. dosinkring(obj); 412. return(1); 413. } 414. #endif 415. if (IS_ALTAR(levl[u.ux][u.uy].typ) && !u.uswallow) { 416. doaltarobj(obj); /* set bknown */ 417. } else 418. if(flags.verbose) You("drop %s.", doname(obj)); 419. dropx(obj); 420. return(1); 421. } 422. 423. /* Called in several places - should not produce texts */ 424. void 425. dropx(obj) 426. register struct obj *obj; 427. { 428. /* Money is *not* in our inventory */ 429. if (obj->otyp != GOLD_PIECE) freeinv(obj); 430. (void) snuff_candle(obj); 431. if(!u.uswallow && obj != uball && 432. ship_object(obj, u.ux, u.uy, FALSE)) return; 433. dropy(obj); 434. } 435. 436. void 437. dropy(obj) 438. register struct obj *obj; 439. { 440. if (!u.uswallow && flooreffects(obj,u.ux,u.uy,"drop")) return; 441. if(obj->otyp == CRYSKNIFE) 442. obj->otyp = WORM_TOOTH; 443. /* uswallow check done by GAN 01/29/87 */ 444. if(u.uswallow) { 445. if (obj->otyp == GOLD_PIECE) { 446. u.ustuck->mgold += obj->quan; 447. delobj(obj); 448. } else if (obj != uball) { /* mon doesn't pick up ball */ 449. (void) snuff_candle(obj); /* security. it's never lit */ 450. mpickobj(u.ustuck,obj); 451. } 452. } else { 453. (void) snuff_candle(obj); 454. obj->nobj = fobj; 455. fobj = obj; 456. place_object(obj, u.ux, u.uy); 457. if (obj == uball) 458. drop_ball(u.ux,u.uy); 459. else 460. sellobj(obj, u.ux, u.uy); 461. stackobj(obj); 462. if(Blind && Levitation) 463. map_object(obj, 0); 464. newsym(u.ux,u.uy); /* remap location under self */ 465. } 466. } 467. 468. /* drop several things */ 469. int 470. doddrop() 471. { 472. int result; 473. 474. if (*u.ushops) sellobj_state(TRUE); 475. result = ggetobj("drop", drop, 0); 476. if (*u.ushops) sellobj_state(FALSE); 477. reset_occupations(); 478. 479. return result; 480. } 481. 482. #endif /* OVL0 */ 483. #ifdef OVL2 484. 485. /* on a ladder, used in goto_level */ 486. static boolean NEARDATA at_ladder = FALSE; 487. 488. int 489. dodown() 490. { 491. struct trap *trap = 0; 492. 493. if( (u.ux != xdnstair || u.uy != ydnstair) 494. && (!xdnladder || u.ux != xdnladder || u.uy != ydnladder) 495. && (!sstairs.sx || u.ux != sstairs.sx || u.uy != sstairs.sy 496. || sstairs.up) 497. ) { 498. if (!(trap = t_at(u.ux,u.uy)) || trap->ttyp != TRAPDOOR 499. || !Can_fall_thru(&u.uz) || !trap->tseen) { 500. You("can't go down here."); 501. return(0); 502. } 503. } 504. if(u.ustuck) { 505. You("are being held, and cannot go down."); 506. return(1); 507. } 508. if(Levitation) { 509. pline("You're floating high above the %s.", 510. levl[u.ux][u.uy].typ == STAIRS ? "stairs" : 511. levl[u.ux][u.uy].typ == LADDER ? "ladder" : 512. "trap door"); 513. return(0); 514. } 515. if (on_level(&valley_level, &u.uz) && !u.uevent.gehennom_entered) { 516. You("are standing at the gate to Gehennom."); 517. pline("Unspeakable cruelty and harm lurk down there."); 518. if (yn("Are you sure you want to enter?") != 'y') 519. return(0); 520. else pline("So be it."); 521. u.uevent.gehennom_entered = 1; /* don't ask again */ 522. } 523. 524. #ifdef WALKIES 525. if(!next_to_u()) { 526. You("are held back by your pet!"); 527. return(0); 528. } 529. #endif 530. if (trap) 531. #ifdef POLYSELF 532. You("%s into the trap door.", locomotion(uasmon, "jump")); 533. #else 534. You("jump into the trap door."); 535. #endif 536. if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE; 537. next_level(!trap); 538. at_ladder = FALSE; 539. return(1); 540. } 541. 542. int 543. doup() 544. { 545. if( (u.ux != xupstair || u.uy != yupstair) 546. && (!xupladder || u.ux != xupladder || u.uy != yupladder) 547. && (!sstairs.sx || u.ux != sstairs.sx || u.uy != sstairs.sy 548. || !sstairs.up) 549. ) { 550. You("can't go up here."); 551. return(0); 552. } 553. if(u.ustuck) { 554. You("are being held, and cannot go up."); 555. return(1); 556. } 557. if(near_capacity() > SLT_ENCUMBER) { 558. /* No levitation check; inv_weight() already allows for it */ 559. Your("load is too heavy to climb the %s.", 560. levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder"); 561. return(1); 562. } 563. if(ledger_no(&u.uz) == 1) { 564. if (yn("Beware, there will be no return! Still climb?") != 'y') 565. return(0); 566. } 567. #ifdef WALKIES 568. if(!next_to_u()) { 569. You("are held back by your pet!"); 570. return(0); 571. } 572. #endif 573. if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE; 574. prev_level(TRUE); 575. at_ladder = FALSE; 576. return(1); 577. } 578. 579. d_level save_dlevel = {0, 0}; 580. 581. /* check that we can write out the current level */ 582. static int 583. currentlevel_rewrite() 584. { 585. register int fd; 586. 587. fd = create_levelfile(ledger_no(&u.uz)); 588. 589. if(fd < 0) { 590. /* 591. * This is not quite impossible: e.g., we may have 592. * exceeded our quota. If that is the case then we 593. * cannot leave this level, and cannot save either. 594. * Another possibility is that the directory was not 595. * writable. 596. */ 597. pline("Cannot create level file for level %d.", 598. ledger_no(&u.uz)); 599. return -1; 600. } 601. 602. #ifdef MFLOPPY 603. if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) { 604. (void) close(fd); 605. delete_levelfile(ledger_no(&u.uz)); 606. pline("NetHack is out of disk space for making levels!"); 607. You("can save, quit, or continue playing."); 608. return -1; 609. } 610. #endif 611. return fd; 612. } 613. 614. #ifdef INSURANCE 615. void 616. save_currentstate() 617. { 618. int fd; 619. 620. if (flags.ins_chkpt) { 621. /* write out just-attained level, with pets and everything */ 622. fd = currentlevel_rewrite(); 623. if(fd < 0) return; 624. bufon(fd); 625. savelev(fd,ledger_no(&u.uz), WRITE_SAVE); 626. bclose(fd); 627. } 628. 629. /* write out non-level state */ 630. savestateinlock(); 631. } 632. #endif 633. 634. /* 635. static boolean 636. badspot(x, y) 637. register xchar x, y; 638. { 639. return((levl[x][y].typ != ROOM && levl[x][y].typ != AIR && 640. levl[x][y].typ != CORR) || MON_AT(x, y)); 641. } 642. */ 643. 644. void 645. goto_level(newlevel, at_stairs, falling, portal) 646. d_level *newlevel; 647. register boolean at_stairs, falling, portal; 648. { 649. register int fd; 650. register boolean up = (depth(newlevel) < depth(&u.uz)); 651. register boolean newdungeon = (u.uz.dnum != newlevel->dnum); 652. #ifdef REINCARNATION 653. int new = 0; /* made a new level? */ 654. #endif 655. 656. if(dunlev(newlevel) > dunlevs_in_dungeon(newlevel)) 657. newlevel->dlevel = dunlevs_in_dungeon(newlevel); 658. if(newdungeon && In_endgame(newlevel)) { /* 1st Endgame Level !!! */ 659. if(u.uhave.amulet) 660. assign_level(newlevel, &earth_level); 661. else return; 662. } 663. if(ledger_no(newlevel) <= 0) 664. done(ESCAPED); /* in fact < 0 is impossible */ 665. /* If you have the amulet and are trying to get out of Hell, going 666. * up a set of stairs sometimes does some very strange things! 667. */ 668. if(Inhell && up && !newdungeon && u.uhave.amulet && 669. (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) { 670. if(!rn2(4)) { 671. if(!u.ualign.type) { /* neutral */ 672. if(rn2(2)) assign_level(newlevel, &u.uz); 673. else assign_rnd_level(newlevel, &u.uz, rnd(3)); 674. } else if(u.ualign.type == A_LAWFUL) { /* lawful */ 675. assign_rnd_level(newlevel, &u.uz, rnd(3)); 676. } else assign_level(newlevel, &u.uz); /* chaotic */ 677. } 678. pline("A mysterious force momentarily surrounds you..."); 679. if(ledger_no(newlevel) < 1) assign_level(newlevel, &u.uz); 680. if(on_level(newlevel, &u.uz)) { 681. (void) safe_teleds(); 682. #ifdef WALKIES 683. (void) next_to_u(); 684. #endif 685. return; 686. } 687. } 688. #ifdef MULDGN 689. /* Prevent the player from going past the first quest level unless 690. * (s)he has been given the go-ahead by the leader. 691. */ 692. if(on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest()) { 693. 694. pline("A mysterious force prevents you from descending."); 695. return; 696. } 697. #endif 698. if(on_level(newlevel, &u.uz)) return; /* this can happen */ 699. 700. fd = currentlevel_rewrite(); 701. if(fd < 0) return; 702. 703. if (falling) /* assuming this is only trapdoor */ 704. impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel); 705. 706. check_special_room(TRUE); /* probably was a trap door */ 707. if(Punished) unplacebc(); 708. u.utrap = 0; /* needed in level_tele */ 709. fill_pit(u.ux, u.uy); 710. u.ustuck = 0; /* idem */ 711. u.uinwater = 0; 712. keepdogs(); 713. if(u.uswallow) /* idem */ 714. u.uswldtim = u.uswallow = 0; 715. /* 716. * We no longer see anything on the level. Make sure that this 717. * follows u.uswallow set to null since uswallow overrides all 718. * normal vision. 719. */ 720. vision_recalc(2); 721. bufon(fd); 722. savelev(fd,ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE); 723. bclose(fd); 724. 725. #ifdef REINCARNATION 726. if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz)) 727. assign_rogue_graphics(Is_rogue_level(newlevel)); 728. #endif 729. assign_level(&u.uz0, &u.uz); 730. assign_level(&u.uz, newlevel); 731. assign_level(&u.utolev, newlevel); 732. u.utotype = 0; 733. if(dunlev_reached(&u.uz) < dunlev(&u.uz)) 734. dunlev_reached(&u.uz) = dunlev(&u.uz); 735. 736. /* set default level change destination areas */ 737. /* the special level code may override these */ 738. (void) memset((genericptr_t) &updest, 0, sizeof updest); 739. (void) memset((genericptr_t) &dndest, 0, sizeof dndest); 740. 741. if(In_endgame(&u.uz) || 742. #ifdef MFLOPPY 743. /* If the level has no .where yet, it hasn't been made */ 744. !fileinfo[ledger_no(&u.uz)].where) { 745. #else 746. !level_exists[ledger_no(&u.uz)]) { 747. #endif 748. mklev(); 749. #ifdef REINCARNATION 750. new = 1; /* made the level */ 751. #endif 752. } else { 753. fd = open_levelfile(ledger_no(&u.uz)); 754. if (fd < 0) { 755. pline("Cannot open file (#%d) for level %d (errno %d).", 756. ledger_no(&u.uz), depth(&u.uz), errno); 757. pline("Probably someone removed it."); 758. done(TRICKED); 759. } 760. #ifdef ZEROCOMP 761. minit(); 762. #endif 763. getlev(fd, hackpid, ledger_no(&u.uz), FALSE); 764. (void) close(fd); 765. } 766. #ifdef MULDGN 767. quest_init(); /* re-initialize */ 768. #endif 769. 770. if(portal && !In_endgame(&u.uz)) { 771. /* find the portal on the new level */ 772. register struct trap *ttrap; 773. 774. for(ttrap = ftrap; ttrap; ttrap = ttrap->ntrap) 775. if(ttrap->ttyp == MAGIC_PORTAL) break; 776. 777. if(ttrap) { 778. u.ux = ttrap->tx; 779. u.uy = ttrap->ty; 780. } else panic("goto_level: no corresponding portal!"); 781. } else if(at_stairs && !In_endgame(&u.uz)) { 782. if(up) { 783. if(at_ladder) { 784. u.ux = xdnladder; 785. u.uy = ydnladder; 786. } else { 787. if(newdungeon) { 788. if(Is_stronghold(&u.uz)) { 789. register xchar x, y; 790. 791. do { 792. x = (COLNO - 2 - rnd(5)); 793. y = rn1(ROWNO - 4, 3); 794. } while(occupied(x, y) || 795. IS_WALL(levl[x][y].typ)); 796. u.ux = x; 797. u.uy = y; 798. } else u_on_sstairs(); 799. } else u_on_dnstairs(); 800. } 801. /* Remove bug which crashes with */ 802. /* levitation/punishment KAA */ 803. if(Punished) { 804. if(!Levitation) 805. pline("With great effort you climb the %s.", 806. !at_ladder ? "stairs" : "ladder"); 807. placebc(); 808. } 809. if(at_ladder && (!Punished || Levitation)) 810. You("climb up the ladder."); 811. } else { /* down */ 812. if(at_ladder) { 813. u.ux = xupladder; 814. u.uy = yupladder; 815. } else { 816. if(newdungeon) u_on_sstairs(); 817. else u_on_upstairs(); 818. } 819. if(at_stairs && u.dz && !up && 820. ((near_capacity()>UNENCUMBERED) || Punished || Fumbling)) { 821. You("fall down the %s.", 822. !at_ladder ? "stairs" : "ladder"); 823. if(Punished) { 824. drag_down(); 825. if(carried(uball)) { 826. if (uwep == uball) 827. setuwep((struct obj *)0); 828. if (uwep != uball) 829. freeinv(uball); 830. } 831. placebc(); 832. } 833. losehp(rnd(3), "falling downstairs", KILLED_BY); 834. selftouch("Falling, you"); 835. } 836. else if(at_ladder && u.dz) 837. You("climb down the ladder."); 838. } 839. } else { /* trap door or level_tele or In_endgame */ 840. if(up) 841. place_lregion(updest.lx, updest.ly, 842. updest.hx, updest.hy, 843. updest.nlx, updest.nly, 844. updest.nhx, updest.nhy, 845. LR_UPTELE, (d_level *) 0); 846. else 847. place_lregion(dndest.lx, dndest.ly, 848. dndest.hx, dndest.hy, 849. dndest.nlx, dndest.nly, 850. dndest.nhx, dndest.nhy, 851. LR_DOWNTELE, (d_level *) 0); 852. if(Punished) { 853. if(falling) ballfall(); 854. placebc(); 855. } 856. if(falling) 857. selftouch("Falling, you"); 858. } 859. 860. losedogs(); 861. obj_delivery(); 862. check_special_room(FALSE); 863. 864. initrack(); 865. 866. if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy)); 867. if(MON_AT(u.ux, u.uy)) { 868. impossible("mnexto failed (do.c)?"); 869. rloc(m_at(u.ux, u.uy)); 870. } 871. remove_cadavers(&fobj); /* remove rotted meat (before seen) */ 872. 873. /* initial movement of bubbles just before vision_recalc */ 874. if (Is_waterlevel(&u.uz)) 875. movebubbles(); 876. 877. /* Reset the screen. */ 878. vision_reset(); /* reset the blockages */ 879. docrt(); /* does a full vision recalc */ 880. 881. /* In Nethack 3.1, Gehennom starts after the stronghold. Moreover, 882. * there are traps in the stronghold, that can send the player 883. * to Gehennom (gnark, gnark)! So we have to test here: 884. */ 885. if(!In_hell(&u.uz0) && Inhell) { 886. if(Is_valley(newlevel)) { 887. You("arrive at the Valley of the Dead..."); 888. pline("There is a smell of burnt flesh and decay here."); 889. #ifdef MICRO 890. display_nhwindow(WIN_MESSAGE, FALSE); 891. #endif 892. pline("The sounds of groans and moans fill the air."); 893. } else pline("It is hot here. You smell smoke..."); 894. } 895. 896. #ifdef REINCARNATION 897. /* 898. * Move all plines beyond the screen reset. 899. */ 900. if (new && Is_rogue_level(&u.uz)) 901. You("have entered what appears to be an older, more primitive world."); 902. #endif 903. /* Final confrontation */ 904. if (In_endgame(&u.uz) && newdungeon && u.uhave.amulet && 905. flags.no_of_wizards == 0) 906. resurrect(); 907. if (newdungeon && In_tower(&u.uz)) 908. pline("The heat and smoke are gone."); 909. #ifdef MULDGN 910. if(!In_quest(&u.uz0) && at_dgn_entrance("The Quest") && 911. !(u.uevent.qexpelled || u.uevent.qcompleted || leaderless())) 912. com_pager(2); /* the message from the leader */ 913. 914. if(Is_knox(&u.uz)) { 915. register struct monst *mtmp; 916. 917. You("penetrated a high security area!"); 918. pline("An alarm sounds!"); 919. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 920. if(mtmp->msleep) mtmp->msleep = 0; 921. } 922. #endif /* MULDGN */ 923. if(on_level(&u.uz, &astral_level)) { 924. register struct monst *mtmp; 925. 926. /* reset monster hostility relative to player */ 927. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 928. reset_hostility(mtmp); 929. 930. /* create some player-monsters */ 931. create_mplayers(rn1(4, 3), TRUE); 932. 933. /* create a guardian angel next to player, if worthy */ 934. if (Conflict) { 935. coord mm; 936. int i = rnd(4); 937. pline("A voice booms: \"Thy desire for conflict shall be rewarded!\""); 938. while(i--) { 939. mm.x = u.ux; 940. mm.y = u.uy; 941. if(enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])) 942. (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type, 943. mm.x, mm.y, FALSE); 944. } 945. 946. } else if(u.ualign.record > 3) { 947. coord mm; 948. 949. pline("A voice whispers: \"Thou hast been worthy of me!\""); 950. mm.x = u.ux; 951. mm.y = u.uy; 952. if(enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])) { 953. if((mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type, 954. mm.x, mm.y, TRUE)) != 0) { 955. register struct obj *otmp = 956. mksobj(SILVER_SABER, FALSE, FALSE); 957. 958. if(!Blind) 959. pline("An angel appears near you."); 960. else 961. You("feel the presence of a friendly angel near you."); 962. /* guardian angel -- the one case mtame doesn't 963. * imply an edog structure, so we don't want to 964. * call tamedog(). 965. */ 966. mtmp->mtame = 10; 967. /* make him strong enough vs. endgame foes */ 968. mtmp->m_lev = rn1(8,15); 969. mtmp->mhp = mtmp->mhpmax = 970. d((int)mtmp->m_lev,10) + 30 + rnd(30); 971. bless(otmp); 972. otmp->spe = 7; 973. mpickobj(mtmp, otmp); 974. } 975. } 976. } 977. } 978. 979. #ifdef MULDGN 980. onquest(); 981. #endif 982. assign_level(&u.uz0, &u.uz); /* reset u.uz0 */ 983. 984. #ifdef INSURANCE 985. save_currentstate(); 986. #endif 987. 988. if(!flags.nopick && OBJ_AT(u.ux, u.uy) && 989. (!is_pool(u.ux,u.uy) || Underwater)) 990. pickup(1); 991. else read_engr_at(u.ux,u.uy); 992. } 993. 994. /* handle something like portal ejection */ 995. void 996. deferred_goto() 997. { 998. if (!on_level(&u.uz, &u.utolev)) { 999. d_level dest; 1000. int typmask = u.utotype; /* save it; goto_level zeroes u.utotype */ 1001. 1002. assign_level(&dest, &u.utolev); 1003. goto_level(&dest, !!(typmask&4), !!(typmask&2), !!(typmask&1)); 1004. if (typmask & 0200) { /* remove portal */ 1005. deltrap(t_at(u.ux, u.uy)); 1006. newsym(u.ux, u.uy); 1007. } 1008. } 1009. } 1010. 1011. #endif /* OVL2 */ 1012. #ifdef OVL3 1013. 1014. void 1015. revive_corpse(corpse, odds, mark_as_old) /* see remove_cadavers() */ 1016. register struct obj *corpse; 1017. int odds; 1018. boolean mark_as_old; 1019. { 1020. register struct monst *mtmp; 1021. 1022. corpse->oldcorpse = mark_as_old; 1023. 1024. /* odds == 0 is a special case meaning 'always revive' */ 1025. if (!odds || !rn2(odds)) { 1026. if (carried(corpse)) { 1027. if (corpse == uwep) { 1028. if ((mtmp = revive(corpse,TRUE)) != 0) 1029. pline("The %s%s %s writhes out of your grasp!", 1030. (mtmp->mhp < mtmp->mhpmax) ? "bite-covered ":"", 1031. mtmp->data->mname, xname(corpse)); 1032. } else if ((mtmp = revive(corpse,TRUE)) != 0) 1033. You("feel squirming in your backpack!"); 1034. } else { 1035. if ((mtmp = revive(corpse,FALSE)) && cansee(mtmp->mx,mtmp->my)) 1036. pline("%s rises from the dead!", 1037. (mtmp->mhp==mtmp->mhpmax) ? Monnam(mtmp) 1038. : Adjmonnam(mtmp, "bite-covered")); 1039. } 1040. } 1041. } 1042. 1043. /* 1044. * Remove old cadavers from any object chain. Regenerate trolls 1045. * thanks to KAA. Follows containers (except ice boxes). 1046. */ 1047. #define TAINT_AGE 50 /* min. limit for tainting. see eat.c */ 1048. #define ODDS_RV1 37 /* 1/37 odds for 50 moves = 75% revive */ 1049. #define ODDS_RV2 2 /* special case 1/2 odds of reviving */ 1050. 1051. void 1052. remove_cadavers(chain) 1053. struct obj **chain; 1054. { 1055. register struct obj *obj, *nobj, *pobj = (struct obj *)0; 1056. register long corpse_age; 1057. boolean ininv = (*chain == invent); 1058. boolean onfloor = (*chain == fobj); 1059. 1060. for (obj = *chain; obj; obj = nobj) { 1061. nobj = obj->nobj; 1062. 1063. if (obj->otyp == CORPSE) { 1064. /* corpses laying on ice deteriorate more slowly */ 1065. if (onfloor && obj->age < monstermoves && 1066. rn2(3) && is_ice(obj->ox, obj->oy)) obj->age++; 1067. corpse_age = monstermoves - obj->age; 1068. 1069. if (is_rider(&mons[obj->corpsenm]) && corpse_age >= 12) { 1070. /* these always come back eventually */ 1071. /* riders can't be picked up, so no need to check onfloor */ 1072. revive_corpse(obj, 3, FALSE); 1073. } else if (mons[obj->corpsenm].mlet == S_TROLL && !obj->oldcorpse 1074. && !(mons[obj->corpsenm].geno & (G_GENOD | G_EXTINCT)) 1075. && (onfloor || ininv)) { 1076. 1077. /* the corpse has 50 moves, the lower limit for tainting, 1078. * to attempt re-animation. if it is unsuccessful it is 1079. * marked to prevent further attempts. if we leave the 1080. * level and return to old corpses that haven't been marked 1081. * they're given a one-shot chance to re-animate. 1082. */ 1083. if (corpse_age < TAINT_AGE) 1084. revive_corpse(obj, ODDS_RV1, FALSE); 1085. else if (corpse_age == TAINT_AGE) 1086. revive_corpse(obj, ODDS_RV1, TRUE); 1087. else revive_corpse(obj, ODDS_RV2, TRUE); 1088. 1089. } else if (obj->corpsenm != PM_LIZARD && (250 < corpse_age)) { 1090. if(ininv) 1091. useup(obj); 1092. else if(onfloor) 1093. delobj(obj); 1094. else { /* in a container */ 1095. if(pobj) pobj->nobj = nobj; 1096. else *chain = nobj; 1097. obfree(obj, (struct obj *) 0); 1098. obj = 0; 1099. } 1100. } 1101. } else if(obj->cobj && Is_container(obj) && obj->otyp != ICE_BOX) 1102. remove_cadavers(&obj->cobj); 1103. /* pobj is only used for containers, which don't allow revive() -dlc */ 1104. if (obj) pobj = obj; 1105. } 1106. } 1107. 1108. int 1109. donull() { 1110. return(1); /* Do nothing, but let other things happen */ 1111. } 1112. 1113. #endif /* OVL3 */ 1114. #ifdef OVLB 1115. 1116. STATIC_PTR int 1117. wipeoff() { 1118. if(u.ucreamed < 4) u.ucreamed = 0; 1119. else u.ucreamed -= 4; 1120. if (Blinded < 4) Blinded = 0; 1121. else Blinded -= 4; 1122. if (!Blinded) { 1123. pline("You've got the glop off."); 1124. u.ucreamed = 0; 1125. Blinded = 1; 1126. make_blinded(0L,TRUE); 1127. return(0); 1128. } else if (!u.ucreamed) { 1129. Your("%s feels clean now.", body_part(FACE)); 1130. return(0); 1131. } 1132. return(1); /* still busy */ 1133. } 1134. 1135. int 1136. dowipe() 1137. { 1138. if(u.ucreamed) { 1139. static char NEARDATA buf[39]; 1140. 1141. Sprintf(buf, "wiping off your %s", body_part(FACE)); 1142. set_occupation(wipeoff, buf, 0); 1143. /* Not totally correct; what if they change back after now 1144. * but before they're finished wiping? 1145. */ 1146. return(1); 1147. } 1148. Your("%s is already clean.", body_part(FACE)); 1149. return(1); 1150. } 1151. 1152. #endif /* OVLB */ 1153. #ifdef OVL1 1154. 1155. /* split obj so that it gets size num */ 1156. /* remainder is put in the object structure delivered by this call */ 1157. struct obj * 1158. splitobj(obj, num) 1159. register struct obj *obj; 1160. register long num; 1161. { 1162. register struct obj *otmp; 1163. /* assert(0 < num && num < obj->quan); */ 1164. otmp = newobj(obj->onamelth); 1165. *otmp = *obj; /* copies whole structure */ 1166. otmp->o_id = flags.ident++; 1167. obj->quan = num; 1168. obj->owt = weight(obj); 1169. otmp->quan -= num; 1170. otmp->owt = weight(otmp); /* -= obj->owt ? */ 1171. obj->nobj = obj->nexthere = otmp; 1172. if (obj->onamelth) 1173. (void)strncpy(ONAME(otmp), ONAME(obj), (int)obj->onamelth); 1174. if(obj->unpaid) splitbill(obj,otmp); 1175. return(otmp); 1176. } 1177. 1178. #endif /* OVL1 */ 1179. #ifdef OVLB 1180. 1181. void 1182. set_wounded_legs(side, timex) 1183. register long side; 1184. register int timex; 1185. { 1186. if(!Wounded_legs) { 1187. ATEMP(A_DEX)--; 1188. flags.botl = 1; 1189. } 1190. 1191. if(!Wounded_legs || (Wounded_legs & TIMEOUT)) 1192. Wounded_legs |= side + timex; 1193. else 1194. Wounded_legs |= side; 1195. } 1196. 1197. void 1198. heal_legs() 1199. { 1200. if(Wounded_legs) { 1201. if (ATEMP(A_DEX) < 0) { 1202. ATEMP(A_DEX)++; 1203. flags.botl = 1; 1204. } 1205. 1206. if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) { 1207. Your("%s feel somewhat better.", 1208. makeplural(body_part(LEG))); 1209. } else { 1210. Your("%s feels somewhat better.", 1211. body_part(LEG)); 1212. } 1213. Wounded_legs = 0; 1214. } 1215. } 1216. 1217. #endif /* OVLB */ 1218. 1219. /*do.c*/