Source:NetHack 3.2.0/do.c
(Redirected from NetHack 3.2.0/do.c)
Jump to navigation
Jump to search
Below is the full text to do.c from the source code of NetHack 3.2.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.2 96/03/09 */ 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. #ifdef _DCC 18. const 19. #endif 20. extern int errno; 21. #endif 22. 23. #ifdef USE_TILES 24. # ifdef MSDOS 25. extern boolean tiles_on; /* video.c */ 26. # endif 27. #endif 28. 29. 30. #ifdef SINKS 31. # ifdef OVLB 32. static void FDECL(trycall, (struct obj *)); 33. # endif /* OVLB */ 34. STATIC_DCL void FDECL(dosinkring, (struct obj *)); 35. #endif /* SINKS */ 36. 37. STATIC_PTR int FDECL(drop, (struct obj *)); 38. STATIC_PTR int NDECL(wipeoff); 39. 40. #ifdef OVL0 41. static int FDECL(menu_drop, (int)); 42. #endif 43. #ifdef OVL2 44. static int NDECL(currentlevel_rewrite); 45. /* static boolean FDECL(badspot, (XCHAR_P,XCHAR_P)); */ 46. #endif 47. 48. #ifdef OVLB 49. 50. static NEARDATA const char drop_types[] = 51. { ALLOW_COUNT, GOLD_CLASS, ALL_CLASSES, 0 }; 52. 53. /* 'd' command: drop one inventory item */ 54. int 55. dodrop() 56. { 57. int result, i = (invent || u.ugold) ? 0 : (SIZE(drop_types) - 1); 58. 59. if (*u.ushops) sellobj_state(TRUE); 60. result = drop(getobj(&drop_types[i], "drop")); 61. if (*u.ushops) sellobj_state(FALSE); 62. reset_occupations(); 63. 64. return result; 65. } 66. 67. #endif /* OVLB */ 68. #ifdef OVL0 69. 70. /* Called when a boulder is dropped, thrown, or pushed. If it ends up 71. * in a pool, it either fills the pool up or sinks away. In either case, 72. * it's gone for good... If the destination is not a pool, returns FALSE. 73. */ 74. boolean 75. boulder_hits_pool(otmp, rx, ry, pushing) 76. struct obj *otmp; 77. register int rx, ry; 78. boolean pushing; 79. { 80. if (!otmp || otmp->otyp != BOULDER) 81. impossible("Not a boulder?"); 82. else if (!Is_waterlevel(&u.uz) && (is_pool(rx,ry) || is_lava(rx,ry))) { 83. boolean lava = is_lava(rx,ry), fills_up; 84. const char *what = lava ? "lava" : "water"; 85. schar ltyp = levl[rx][ry].typ; 86. int chance = rn2(10); /* water: 90%; lava: 10% */ 87. fills_up = lava ? chance == 0 : chance != 0; 88. 89. if (fills_up) { 90. if (ltyp == DRAWBRIDGE_UP) { 91. levl[rx][ry].drawbridgemask &= ~DB_UNDER; /* clear lava */ 92. levl[rx][ry].drawbridgemask |= DB_FLOOR; 93. } else 94. levl[rx][ry].typ = ROOM; 95. 96. bury_objs(rx, ry); 97. newsym(rx,ry); 98. if (pushing) { 99. You("push %s into the %s.", the(xname(otmp)), what); 100. if (flags.verbose && !Blind) 101. pline("Now you can cross it!"); 102. /* no splashing in this case */ 103. } 104. } 105. if (!fills_up || !pushing) { /* splashing occurs */ 106. if (!u.uinwater) { 107. if (pushing ? !Blind : cansee(rx,ry)) { 108. boolean moat = (ltyp != WATER) && 109. !Is_medusa_level(&u.uz) && !Is_waterlevel(&u.uz); 110. 111. pline("There is a large splash as %s %s the %s.", 112. the(xname(otmp)), fills_up? "fills":"falls into", 113. lava ? "lava" : ltyp==POOL ? "pool" : 114. moat ? "moat" : "water"); 115. } else if (flags.soundok) 116. You_hear("a%s splash.", lava ? " sizzling" : ""); 117. wake_nearto(rx, ry, 40); 118. } 119. 120. if (fills_up && u.uinwater && distu(rx,ry) == 0) { 121. u.uinwater = 0; 122. docrt(); 123. vision_full_recalc = 1; 124. You("find yourself on dry land again!"); 125. } else if (lava && distu(rx,ry) <= 2) { 126. You("are hit by molten lava%c", 127. Fire_resistance ? '.' : '!'); 128. losehp(d((Fire_resistance ? 1 : 3), 6), 129. "molten lava", KILLED_BY); 130. } else if (!fills_up && flags.verbose && 131. (pushing ? !Blind : cansee(rx,ry))) 132. pline("It sinks without a trace!"); 133. } 134. 135. /* boulder is now gone */ 136. if (pushing) delobj(otmp); 137. else obfree(otmp, (struct obj *)0); 138. return TRUE; 139. } 140. return FALSE; 141. } 142. 143. /* Used for objects which sometimes do special things when dropped; must be 144. * called with the object not in any chain. Returns TRUE if the object goes 145. * away. 146. */ 147. boolean 148. flooreffects(obj,x,y,verb) 149. struct obj *obj; 150. int x,y; 151. const char *verb; 152. { 153. struct trap *t; 154. struct monst *mtmp; 155. 156. if (obj->where != OBJ_FREE) 157. panic("flooreffects: obj not free"); 158. 159. /* make sure things like water_damage() have no pointers to follow */ 160. obj->nobj = obj->nexthere = (struct obj *)0; 161. 162. if (obj->otyp == BOULDER && boulder_hits_pool(obj, x, y, FALSE)) 163. return TRUE; 164. else if (obj->otyp == BOULDER && (t = t_at(x,y)) != 0 && 165. (t->ttyp==PIT || t->ttyp==SPIKED_PIT 166. || t->ttyp==TRAPDOOR || t->ttyp==HOLE)) { 167. if (((mtmp = m_at(x, y)) && mtmp->mtrapped) || 168. (u.utrap && u.ux == x && u.uy == y)) { 169. if (*verb) 170. pline_The("boulder %ss into the pit%s.", verb, 171. (mtmp) ? "" : " with you"); 172. if (mtmp) { 173. if (!passes_walls(mtmp->data) && 174. !throws_rocks(mtmp->data)) { 175. if (hmon(mtmp, obj, TRUE)) 176. return FALSE; /* still alive */ 177. } else mtmp->mtrapped = 0; 178. } else { 179. if (!passes_walls(uasmon) && !throws_rocks(uasmon)) { 180. losehp(rnd(15), "squished under a boulder", 181. NO_KILLER_PREFIX); 182. return FALSE; /* player remains trapped */ 183. } else u.utrap = 0; 184. } 185. } 186. if (*verb) { 187. if (Blind) { 188. if ((x == u.ux) && (y == u.uy)) 189. You_hear("a CRASH! beneath you."); 190. else 191. You_hear("the boulder %s.", verb); 192. } else if (cansee(x, y)) { 193. pline_The("boulder %s%s.", 194. t->tseen ? "" : "triggers and ", 195. t->ttyp == TRAPDOOR ? "plugs a trap door" : 196. t->ttyp == HOLE ? "plugs a hole" : 197. "fills a pit"); 198. } 199. } 200. deltrap(t); 201. obfree(obj, (struct obj *)0); 202. bury_objs(x, y); 203. newsym(x,y); 204. return TRUE; 205. } else if (is_pool(x, y)) { 206. water_damage(obj, FALSE, FALSE); 207. } 208. return FALSE; 209. } 210. 211. #endif /* OVL0 */ 212. #ifdef OVLB 213. 214. void 215. doaltarobj(obj) /* obj is an object dropped on an altar */ 216. register struct obj *obj; 217. { 218. if (Blind) return; 219. if (obj->blessed || obj->cursed) { 220. pline("There is %s flash as %s hit%s the altar.", 221. an(hcolor(obj->blessed ? amber : Black)), 222. doname(obj), 223. (obj->quan == 1L) ? "s" : ""); 224. if (!Hallucination) obj->bknown = 1; 225. } else { 226. pline("%s land%s on the altar.", Doname2(obj), 227. (obj->quan == 1L) ? "s" : ""); 228. obj->bknown = 1; 229. } 230. } 231. 232. #ifdef SINKS 233. static 234. void 235. trycall(obj) 236. register struct obj *obj; 237. { 238. if(!objects[obj->otyp].oc_name_known && 239. !objects[obj->otyp].oc_uname) 240. docall(obj); 241. } 242. 243. STATIC_OVL 244. void 245. dosinkring(obj) /* obj is a ring being dropped over a kitchen sink */ 246. register struct obj *obj; 247. { 248. register struct obj *otmp,*otmp2; 249. register boolean ideed = TRUE; 250. 251. You("drop %s down the drain.", doname(obj)); 252. #ifndef NO_SIGNAL 253. obj->in_use = TRUE; /* block free identification via interrupt */ 254. #endif 255. switch(obj->otyp) { /* effects that can be noticed without eyes */ 256. case RIN_SEARCHING: 257. You("thought your %s got lost in the sink, but there it is!", 258. xname(obj)); 259. #ifndef NO_SIGNAL 260. obj->in_use = FALSE; 261. #endif 262. dropx(obj); 263. trycall(obj); 264. return; 265. case RIN_LEVITATION: 266. pline_The("sink quivers upward for a moment."); 267. break; 268. case RIN_POISON_RESISTANCE: 269. You("smell rotten %s.", makeplural(pl_fruit)); 270. break; 271. case RIN_AGGRAVATE_MONSTER: 272. pline("Several flies buzz angrily around the sink."); 273. break; 274. case RIN_SHOCK_RESISTANCE: 275. pline("Static electricity surrounds the sink."); 276. break; 277. case RIN_CONFLICT: 278. You_hear("loud noises coming from the drain."); 279. break; 280. case RIN_GAIN_STRENGTH: 281. pline_The("water flow seems %ser now.", 282. (obj->spe<0) ? "weak" : "strong"); 283. break; 284. case RIN_INCREASE_DAMAGE: 285. pline_The("water's force seems %ser now.", 286. (obj->spe<0) ? "small" : "great"); 287. break; 288. default: 289. ideed = FALSE; 290. break; 291. } 292. if(!Blind && !ideed) { 293. ideed = TRUE; 294. switch(obj->otyp) { /* effects that need eyes */ 295. case RIN_ADORNMENT: 296. pline_The("faucets flash brightly for a moment."); 297. break; 298. case RIN_REGENERATION: 299. pline_The("sink looks as good as new."); 300. break; 301. case RIN_INVISIBILITY: 302. You("don't see anything happen to the sink."); 303. break; 304. case RIN_SEE_INVISIBLE: 305. You("see some air in the sink."); 306. break; 307. case RIN_STEALTH: 308. pline_The("sink seems to blend into the floor for a moment."); 309. break; 310. case RIN_HUNGER: 311. ideed = FALSE; 312. for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) { 313. otmp2 = otmp->nexthere; 314. if(otmp != uball && otmp != uchain) { 315. pline("Suddenly, %s vanishes from the sink!", 316. doname(otmp)); 317. delobj(otmp); 318. ideed = TRUE; 319. } 320. } 321. break; 322. case RIN_FIRE_RESISTANCE: 323. pline_The("hot water faucet flashes brightly for a moment."); 324. break; 325. case RIN_COLD_RESISTANCE: 326. pline_The("cold water faucet flashes brightly for a moment."); 327. break; 328. case RIN_PROTECTION_FROM_SHAPE_CHAN: 329. pline_The("sink looks nothing like a fountain."); 330. break; 331. case RIN_PROTECTION: 332. pline_The("sink glows %s for a moment.", 333. hcolor((obj->spe<0) ? Black : silver)); 334. break; 335. case RIN_WARNING: 336. pline_The("sink glows %s for a moment.", hcolor(White)); 337. break; 338. case RIN_TELEPORTATION: 339. pline_The("sink momentarily vanishes."); 340. break; 341. case RIN_TELEPORT_CONTROL: 342. pline_The("sink looks like it is being beamed aboard somewhere."); 343. break; 344. case RIN_POLYMORPH: 345. pline_The("sink momentarily looks like a fountain."); 346. break; 347. case RIN_POLYMORPH_CONTROL: 348. pline_The("sink momentarily looks like a regularly erupting geyser."); 349. break; 350. } 351. } 352. if(ideed) 353. trycall(obj); 354. else 355. You_hear("the ring bouncing down the drainpipe."); 356. if (!rn2(20)) { 357. pline_The("sink backs up, leaving %s.", doname(obj)); 358. #ifndef NO_SIGNAL 359. obj->in_use = FALSE; 360. #endif 361. dropx(obj); 362. } 363. else 364. useup(obj); 365. } 366. #endif 367. 368. #endif /* OVLB */ 369. #ifdef OVL0 370. 371. /* some common tests when trying to drop or throw items */ 372. boolean 373. canletgo(obj,word) 374. register struct obj *obj; 375. register const char *word; 376. { 377. if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)){ 378. if (*word) 379. Norep("You cannot %s %s you are wearing.",word, 380. something); 381. return(FALSE); 382. } 383. if (obj->otyp == LOADSTONE && obj->cursed) { 384. if (*word) 385. pline("For some reason, you cannot %s the stone%s!", 386. word, plur(obj->quan)); 387. /* Kludge -- see invent.c */ 388. if (obj->corpsenm) { 389. struct obj *otmp; 390. 391. otmp = obj; 392. obj = obj->nobj; 393. obj->quan += otmp->quan; 394. obj->owt = weight(obj); 395. freeinv(otmp); 396. obfree(otmp, obj); 397. } 398. obj->bknown = 1; 399. return(FALSE); 400. } 401. if (obj->otyp == LEASH && obj->leashmon != 0) { 402. if (*word) 403. pline ("The leash is tied around your %s.", 404. body_part(HAND)); 405. return(FALSE); 406. } 407. return(TRUE); 408. } 409. 410. STATIC_PTR 411. int 412. drop(obj) 413. register struct obj *obj; 414. { 415. if(!obj) return(0); 416. if(!canletgo(obj,"drop")) 417. return(0); 418. if(obj == uwep) { 419. if(welded(uwep)) { 420. weldmsg(obj, FALSE); 421. return(0); 422. } 423. setuwep((struct obj *)0); 424. if(uwep) return 0; /* lifesaved and rewielded */ 425. } 426. 427. if (u.uswallow) { 428. /* barrier between you and the floor */ 429. if(flags.verbose) 430. You("drop %s into %s %s.", doname(obj), 431. s_suffix(mon_nam(u.ustuck)), 432. is_animal(u.ustuck->data) ? 433. "stomach" : "interior"); 434. } else { 435. #ifdef SINKS 436. if((obj->oclass == RING_CLASS) && IS_SINK(levl[u.ux][u.uy].typ)) { 437. dosinkring(obj); 438. return(1); 439. } 440. #endif 441. if (!can_reach_floor()) { 442. if(flags.verbose) You("drop %s.", doname(obj)); 443. if (obj->oclass != GOLD_CLASS || obj == invent) freeinv(obj); 444. hitfloor(obj); 445. return(1); 446. } 447. if (IS_ALTAR(levl[u.ux][u.uy].typ)) { 448. doaltarobj(obj); /* set bknown */ 449. } else 450. if(flags.verbose) You("drop %s.", doname(obj)); 451. } 452. dropx(obj); 453. return(1); 454. } 455. 456. /* Called in several places - should not produce texts */ 457. void 458. dropx(obj) 459. register struct obj *obj; 460. { 461. /* Money is usually not in our inventory */ 462. if (obj->oclass != GOLD_CLASS || obj == invent) freeinv(obj); 463. if (!u.uswallow && ship_object(obj, u.ux, u.uy, FALSE)) return; 464. dropy(obj); 465. } 466. 467. void 468. dropy(obj) 469. register struct obj *obj; 470. { 471. if (!u.uswallow && flooreffects(obj,u.ux,u.uy,"drop")) return; 472. if(obj->otyp == CRYSKNIFE) 473. obj->otyp = WORM_TOOTH; 474. /* uswallow check done by GAN 01/29/87 */ 475. if(u.uswallow) { 476. if (obj != uball) { /* mon doesn't pick up ball */ 477. mpickobj(u.ustuck,obj); 478. } 479. } else { 480. place_object(obj, u.ux, u.uy); 481. if (obj == uball) 482. drop_ball(u.ux,u.uy); 483. else 484. sellobj(obj, u.ux, u.uy); 485. stackobj(obj); 486. if(Blind && Levitation) 487. map_object(obj, 0); 488. newsym(u.ux,u.uy); /* remap location under self */ 489. } 490. } 491. 492. /* 'D' command: drop several things */ 493. int 494. doddrop() 495. { 496. int result = 0; 497. 498. add_valid_menu_class(0); /* clear any classes already there */ 499. if (*u.ushops) sellobj_state(TRUE); 500. if (flags.menu_style != MENU_TRADITIONAL || 501. (result = ggetobj("drop", drop, 0, FALSE)) < -1) 502. result = menu_drop(result); 503. if (*u.ushops) sellobj_state(FALSE); 504. reset_occupations(); 505. 506. return result; 507. } 508. 509. /* Drop things from the hero's inventory, using a menu. */ 510. static int 511. menu_drop(retry) 512. int retry; 513. { 514. int n, i, n_dropped = 0; 515. long cnt; 516. struct obj *otmp, *otmp2, *u_gold = 0; 517. menu_item *pick_list; 518. boolean all_categories = TRUE; 519. boolean drop_everything = FALSE; 520. 521. if (u.ugold) { 522. /* Hack: gold is not in the inventory, so make a gold object 523. and put it at the head of the inventory list. */ 524. u_gold = mkgoldobj(u.ugold); /* removes from u.ugold */ 525. u.ugold = u_gold->quan; /* put the gold back */ 526. assigninvlet(u_gold); /* might end up as NOINVSYM */ 527. u_gold->nobj = invent; 528. invent = u_gold; 529. } 530. 531. if (retry) { 532. all_categories = (retry == -2); 533. } else if (flags.menu_style == MENU_FULL) { 534. all_categories = FALSE; 535. n = query_category("Drop what type of items?", 536. invent, 537. UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL, 538. &pick_list, PICK_ANY); 539. if (!n) goto drop_done; 540. for (i = 0; i < n; i++) { 541. if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) 542. all_categories = TRUE; 543. else if (pick_list[i].item.a_int == 'A') 544. drop_everything = TRUE; 545. else 546. add_valid_menu_class(pick_list[i].item.a_int); 547. } 548. free((genericptr_t) pick_list); 549. } else if (flags.menu_style == MENU_COMBINATION) { 550. all_categories = FALSE; 551. /* Gather valid classes via traditional NetHack method */ 552. i = ggetobj("drop", drop, 0, TRUE); 553. if (i == -2) all_categories = TRUE; 554. } 555. 556. if (drop_everything) { 557. for(otmp = invent; otmp; otmp = otmp2) { 558. otmp2 = otmp->nobj; 559. n_dropped += drop(otmp); 560. } 561. } else { 562. /* should coordinate with perm invent, maybe not show worn items */ 563. n = query_objlist("What would you like to drop?", invent, 564. USE_INVLET|INVORDER_SORT, &pick_list, 565. PICK_ANY, all_categories ? allow_all : allow_category); 566. if (n > 0) { 567. for (i = 0; i < n; i++) { 568. otmp = pick_list[i].item.a_obj; 569. cnt = pick_list[i].count; 570. if (cnt < otmp->quan && !welded(otmp) && 571. (!otmp->cursed || otmp->otyp != LOADSTONE)) { 572. otmp2 = splitobj(otmp, cnt); 573. /* assume other worn items aren't mergable */ 574. if (otmp == uwep) setuwep(otmp2); 575. } 576. n_dropped += drop(otmp); 577. } 578. free((genericptr_t) pick_list); 579. } 580. } 581. 582. drop_done: 583. if (u_gold && invent && invent->oclass == GOLD_CLASS) { 584. /* didn't drop [all of] it */ 585. u_gold = invent; 586. invent = u_gold->nobj; 587. dealloc_obj(u_gold); 588. } 589. return n_dropped; 590. } 591. 592. #endif /* OVL0 */ 593. #ifdef OVL2 594. 595. /* on a ladder, used in goto_level */ 596. static NEARDATA boolean at_ladder = FALSE; 597. 598. int 599. dodown() 600. { 601. struct trap *trap = 0; 602. boolean stairs_down = ((u.ux == xdnstair && u.uy == ydnstair) || 603. (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)), 604. ladder_down = (u.ux == xdnladder && u.uy == ydnladder); 605. 606. if (Levitation) { 607. if ((HLevitation & (I_SPECIAL|W_ARTI)) != 0) { 608. /* end controlled levitation */ 609. if (float_down(I_SPECIAL|W_ARTI|TIMEOUT)) 610. return 1; /* came down, so moved */ 611. } 612. floating_above(stairs_down ? "stairs" : ladder_down ? 613. "ladder" : surface(u.ux, u.uy)); 614. return 0; /* didn't move */ 615. } 616. if (!stairs_down && !ladder_down) { 617. if (!(trap = t_at(u.ux,u.uy)) || 618. (trap->ttyp != TRAPDOOR && trap->ttyp != HOLE) 619. || !Can_fall_thru(&u.uz) || !trap->tseen) { 620. You_cant("go down here."); 621. return(0); 622. } 623. } 624. if(u.ustuck) { 625. You("are being held, and cannot go down."); 626. return(1); 627. } 628. if (on_level(&valley_level, &u.uz) && !u.uevent.gehennom_entered) { 629. You("are standing at the gate to Gehennom."); 630. pline("Unspeakable cruelty and harm lurk down there."); 631. if (yn("Are you sure you want to enter?") != 'y') 632. return(0); 633. else pline("So be it."); 634. u.uevent.gehennom_entered = 1; /* don't ask again */ 635. } 636. 637. if(!next_to_u()) { 638. You("are held back by your pet!"); 639. return(0); 640. } 641. 642. if (trap) 643. You("%s %s.", locomotion(uasmon, "jump"), 644. trap->ttyp == HOLE ? "down the hole" : "through the trap door"); 645. 646. if (trap && Is_stronghold(&u.uz)) { 647. goto_hell(TRUE, TRUE); 648. } else { 649. at_ladder = (boolean) (levl[u.ux][u.uy].typ == LADDER); 650. next_level(!trap); 651. at_ladder = FALSE; 652. } 653. return(1); 654. } 655. 656. int 657. doup() 658. { 659. if( (u.ux != xupstair || u.uy != yupstair) 660. && (!xupladder || u.ux != xupladder || u.uy != yupladder) 661. && (!sstairs.sx || u.ux != sstairs.sx || u.uy != sstairs.sy 662. || !sstairs.up) 663. ) { 664. You_cant("go up here."); 665. return(0); 666. } 667. if(u.ustuck) { 668. You("are being held, and cannot go up."); 669. return(1); 670. } 671. if(near_capacity() > SLT_ENCUMBER) { 672. /* No levitation check; inv_weight() already allows for it */ 673. Your("load is too heavy to climb the %s.", 674. levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder"); 675. return(1); 676. } 677. if(ledger_no(&u.uz) == 1) { 678. if (yn("Beware, there will be no return! Still climb?") != 'y') 679. return(0); 680. } 681. if(!next_to_u()) { 682. You("are held back by your pet!"); 683. return(0); 684. } 685. if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE; 686. prev_level(TRUE); 687. at_ladder = FALSE; 688. return(1); 689. } 690. 691. d_level save_dlevel = {0, 0}; 692. 693. /* check that we can write out the current level */ 694. static int 695. currentlevel_rewrite() 696. { 697. register int fd; 698. 699. /* since level change might be a bit slow, flush any buffered screen 700. * output (like "you fall through a trapdoor") */ 701. mark_synch(); 702. 703. fd = create_levelfile(ledger_no(&u.uz)); 704. 705. if(fd < 0) { 706. /* 707. * This is not quite impossible: e.g., we may have 708. * exceeded our quota. If that is the case then we 709. * cannot leave this level, and cannot save either. 710. * Another possibility is that the directory was not 711. * writable. 712. */ 713. pline("Cannot create level file for level %d.", 714. ledger_no(&u.uz)); 715. return -1; 716. } 717. 718. #ifdef MFLOPPY 719. if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) { 720. (void) close(fd); 721. delete_levelfile(ledger_no(&u.uz)); 722. pline("NetHack is out of disk space for making levels!"); 723. You("can save, quit, or continue playing."); 724. return -1; 725. } 726. #endif 727. return fd; 728. } 729. 730. #ifdef INSURANCE 731. void 732. save_currentstate() 733. { 734. int fd; 735. 736. if (flags.ins_chkpt) { 737. /* write out just-attained level, with pets and everything */ 738. fd = currentlevel_rewrite(); 739. if(fd < 0) return; 740. bufon(fd); 741. savelev(fd,ledger_no(&u.uz), WRITE_SAVE); 742. bclose(fd); 743. } 744. 745. /* write out non-level state */ 746. savestateinlock(); 747. } 748. #endif 749. 750. /* 751. static boolean 752. badspot(x, y) 753. register xchar x, y; 754. { 755. return((levl[x][y].typ != ROOM && levl[x][y].typ != AIR && 756. levl[x][y].typ != CORR) || MON_AT(x, y)); 757. } 758. */ 759. 760. void 761. goto_level(newlevel, at_stairs, falling, portal) 762. d_level *newlevel; 763. boolean at_stairs, falling, portal; 764. { 765. int fd, l_idx; 766. xchar new_ledger; 767. boolean cant_go_back, 768. up = (depth(newlevel) < depth(&u.uz)), 769. newdungeon = (u.uz.dnum != newlevel->dnum), 770. was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz), 771. familiar = FALSE; 772. boolean new = FALSE; /* made a new level? */ 773. 774. if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel)) 775. newlevel->dlevel = dunlevs_in_dungeon(newlevel); 776. if (newdungeon && In_endgame(newlevel)) { /* 1st Endgame Level !!! */ 777. if (u.uhave.amulet) 778. assign_level(newlevel, &earth_level); 779. else return; 780. } 781. new_ledger = ledger_no(newlevel); 782. if (new_ledger <= 0) 783. done(ESCAPED); /* in fact < 0 is impossible */ 784. 785. /* If you have the amulet and are trying to get out of Gehennom, going 786. * up a set of stairs sometimes does some very strange things! 787. * Biased against law and towards chaos, but not nearly as strongly 788. * as it used to be (prior to 3.2.0). 789. * Odds: old new 790. * "up" L N C "up" L N C 791. * +1 75.0 75.0 75.0 +1 75.0 75.0 75.0 792. * 0 0.0 12.5 25.0 0 6.25 8.33 12.5 793. * -1 8.33 4.17 0.0 -1 6.25 8.33 12.5 794. * -2 8.33 4.17 0.0 -2 6.25 8.33 0.0 795. * -3 8.33 4.17 0.0 -3 6.25 0.0 0.0 796. */ 797. if (Inhell && up && u.uhave.amulet && !newdungeon && !portal && 798. (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) { 799. if (!rn2(4)) { 800. int odds = 3 + (int)u.ualign.type, /* 2..4 */ 801. diff = odds <= 1 ? 0 : rn2(odds); /* paranoia */ 802. 803. if (diff != 0) { 804. assign_rnd_level(newlevel, &u.uz, diff); 805. /* if inside the tower, stay inside */ 806. if (was_in_W_tower && 807. !On_W_tower_level(newlevel)) diff = 0; 808. } 809. if (diff == 0) 810. assign_level(newlevel, &u.uz); 811. 812. new_ledger = ledger_no(newlevel); 813. 814. pline("A mysterious force momentarily surrounds you..."); 815. if (on_level(newlevel, &u.uz)) { 816. (void) safe_teleds(); 817. (void) next_to_u(); 818. return; 819. } else 820. at_stairs = at_ladder = FALSE; 821. } 822. } 823. 824. /* Prevent the player from going past the first quest level unless 825. * (s)he has been given the go-ahead by the leader. 826. */ 827. if (on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest()) { 828. pline("A mysterious force prevents you from descending."); 829. return; 830. } 831. 832. if (on_level(newlevel, &u.uz)) return; /* this can happen */ 833. 834. fd = currentlevel_rewrite(); 835. if (fd < 0) return; 836. 837. if (falling) /* assuming this is only trapdoor or hole */ 838. impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel); 839. 840. check_special_room(TRUE); /* probably was a trap door */ 841. if (Punished) unplacebc(); 842. u.utrap = 0; /* needed in level_tele */ 843. fill_pit(u.ux, u.uy); 844. u.ustuck = 0; /* idem */ 845. u.uinwater = 0; 846. keepdogs(FALSE); 847. if (u.uswallow) /* idem */ 848. u.uswldtim = u.uswallow = 0; 849. /* 850. * We no longer see anything on the level. Make sure that this 851. * follows u.uswallow set to null since uswallow overrides all 852. * normal vision. 853. */ 854. vision_recalc(2); 855. 856. /* 857. * Save the level we're leaving. If we're entering the endgame, 858. * we can get rid of all existing levels because they cannot be 859. * reached any more. We still need to use savelev()'s cleanup 860. * for the level being left, to recover dynamic memory in use and 861. * to avoid dangling timers and light sources. 862. */ 863. cant_go_back = (newdungeon && In_endgame(newlevel)); 864. if (!cant_go_back) bufon(fd); /* use buffered output */ 865. savelev(fd, ledger_no(&u.uz), 866. cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE)); 867. bclose(fd); 868. if (cant_go_back) { 869. /* discard unreachable levels; keep #0 */ 870. for (l_idx = maxledgerno(); l_idx > 0; --l_idx) 871. delete_levelfile(l_idx); 872. } 873. 874. #ifdef REINCARNATION 875. if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz)) 876. assign_rogue_graphics(Is_rogue_level(newlevel)); 877. #endif 878. #ifdef USE_TILES 879. # if defined(MSDOS) 880. if (flags.grmode) { 881. if (Is_rogue_level(newlevel) && tiles_on) 882. tiles_on = FALSE; 883. else tiles_on = TRUE; 884. } 885. # endif 886. substitute_tiles(newlevel); 887. #endif 888. assign_level(&u.uz0, &u.uz); 889. assign_level(&u.uz, newlevel); 890. assign_level(&u.utolev, newlevel); 891. u.utotype = 0; 892. if (dunlev_reached(&u.uz) < dunlev(&u.uz)) 893. dunlev_reached(&u.uz) = dunlev(&u.uz); 894. reset_rndmonst(NON_PM); /* u.uz change affects monster generation */ 895. 896. /* set default level change destination areas */ 897. /* the special level code may override these */ 898. (void) memset((genericptr_t) &updest, 0, sizeof updest); 899. (void) memset((genericptr_t) &dndest, 0, sizeof dndest); 900. 901. if (!(level_info[new_ledger].flags & LFILE_EXISTS)) { 902. /* entering this level for first time; make it now */ 903. if (level_info[new_ledger].flags & (FORGOTTEN|VISITED)) { 904. impossible("goto_level: returning to discarded level?"); 905. level_info[new_ledger].flags &= ~(FORGOTTEN|VISITED); 906. } 907. mklev(); 908. new = TRUE; /* made the level */ 909. } else { 910. /* returning to previously visited level; reload it */ 911. fd = open_levelfile(new_ledger); 912. if (fd < 0) { 913. pline("Cannot open file (#%d) for level %d (errno %d).", 914. (int) new_ledger, depth(&u.uz), errno); 915. pline("Probably someone removed it."); 916. done(TRICKED); 917. } 918. minit(); /* ZEROCOMP */ 919. getlev(fd, hackpid, new_ledger, FALSE); 920. (void) close(fd); 921. } 922. 923. if (portal && !In_endgame(&u.uz)) { 924. /* find the portal on the new level */ 925. register struct trap *ttrap; 926. 927. for (ttrap = ftrap; ttrap; ttrap = ttrap->ntrap) 928. if (ttrap->ttyp == MAGIC_PORTAL) break; 929. 930. if (!ttrap) panic("goto_level: no corresponding portal!"); 931. u_on_newpos(ttrap->tx, ttrap->ty); 932. } else if (at_stairs && !In_endgame(&u.uz)) { 933. if (up) { 934. if (at_ladder) { 935. u_on_newpos(xdnladder, ydnladder); 936. } else { 937. if (newdungeon) { 938. if (Is_stronghold(&u.uz)) { 939. register xchar x, y; 940. 941. do { 942. x = (COLNO - 2 - rnd(5)); 943. y = rn1(ROWNO - 4, 3); 944. } while(occupied(x, y) || 945. IS_WALL(levl[x][y].typ)); 946. u_on_newpos(x, y); 947. } else u_on_sstairs(); 948. } else u_on_dnstairs(); 949. } 950. /* Remove bug which crashes with levitation/punishment KAA */ 951. if (Punished && !Levitation) { 952. pline("With great effort you climb the %s.", 953. at_ladder ? "ladder" : "stairs"); 954. } else if (at_ladder) 955. You("climb up the ladder."); 956. } else { /* down */ 957. if (at_ladder) { 958. u_on_newpos(xupladder, yupladder); 959. } else { 960. if (newdungeon) u_on_sstairs(); 961. else u_on_upstairs(); 962. } 963. if (u.dz && 964. (near_capacity() > UNENCUMBERED || Punished || Fumbling)) { 965. You("fall down the %s.", at_ladder ? "ladder" : "stairs"); 966. if (Punished) { 967. drag_down(); 968. if (carried(uball)) { 969. if (uwep == uball) 970. setuwep((struct obj *)0); 971. freeinv(uball); 972. } 973. } 974. losehp(rnd(3), "falling downstairs", KILLED_BY); 975. selftouch("Falling, you"); 976. } else if (u.dz && at_ladder) 977. You("climb down the ladder."); 978. } 979. } else { /* trap door or level_tele or In_endgame */ 980. if (was_in_W_tower && On_W_tower_level(&u.uz)) 981. /* Stay inside the Wizard's tower when feasible. */ 982. /* Note: up vs down doesn't really matter in this case. */ 983. place_lregion(dndest.nlx, dndest.nly, 984. dndest.nhx, dndest.nhy, 985. 0,0, 0,0, LR_DOWNTELE, (d_level *) 0); 986. else if (up) 987. place_lregion(updest.lx, updest.ly, 988. updest.hx, updest.hy, 989. updest.nlx, updest.nly, 990. updest.nhx, updest.nhy, 991. LR_UPTELE, (d_level *) 0); 992. else 993. place_lregion(dndest.lx, dndest.ly, 994. dndest.hx, dndest.hy, 995. dndest.nlx, dndest.nly, 996. dndest.nhx, dndest.nhy, 997. LR_DOWNTELE, (d_level *) 0); 998. if (falling) { 999. if (Punished) ballfall(); 1000. selftouch("Falling, you"); 1001. } 1002. } 1003. 1004. if (Punished) placebc(); 1005. obj_delivery(); /* before killing geno'd monsters' eggs */ 1006. losedogs(); 1007. kill_genocided_monsters(); /* for those wiped out while in limbo */ 1008. /* 1009. * Expire all timers that have gone off while away. Must be 1010. * after migrating monsters and objects are delivered 1011. * (losedogs and obj_delivery). 1012. */ 1013. run_timers(); 1014. 1015. initrack(); 1016. 1017. if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy)); 1018. if(MON_AT(u.ux, u.uy)) { 1019. impossible("mnexto failed (do.c)?"); 1020. rloc(m_at(u.ux, u.uy)); 1021. } 1022. 1023. /* initial movement of bubbles just before vision_recalc */ 1024. if (Is_waterlevel(&u.uz)) 1025. movebubbles(); 1026. 1027. if (level_info[new_ledger].flags & FORGOTTEN) { 1028. forget_map(ALL_MAP); /* forget the map */ 1029. forget_traps(); /* forget all traps too */ 1030. familiar = TRUE; 1031. level_info[new_ledger].flags &= ~FORGOTTEN; 1032. } 1033. 1034. /* Reset the screen. */ 1035. vision_reset(); /* reset the blockages */ 1036. docrt(); /* does a full vision recalc */ 1037. 1038. /* 1039. * Move all plines beyond the screen reset. 1040. */ 1041. 1042. /* give room entrance message, if any */ 1043. check_special_room(FALSE); 1044. 1045. /* Check whether we just entered Gehennom. */ 1046. if (!In_hell(&u.uz0) && Inhell) { 1047. if (Is_valley(&u.uz)) { 1048. You("arrive at the Valley of the Dead..."); 1049. pline_The("odor of burnt flesh and decay pervades the air."); 1050. #ifdef MICRO 1051. display_nhwindow(WIN_MESSAGE, FALSE); 1052. #endif 1053. You_hear("groans and moans everywhere."); 1054. } else pline("It is hot here. You smell smoke..."); 1055. } 1056. 1057. if (familiar) { 1058. static const char *fam_msgs[4] = { 1059. "You have a sense of deja vu.", 1060. "You feel like you've been here before.", 1061. "This place looks familiar...", 1062. 0 /* no message */ 1063. }; 1064. static const char *halu_fam_msgs[4] = { 1065. "Whoa! Everything looks different.", 1066. "You are surrounded by twisty little passages, all alike.", 1067. "Gee, this looks like uncle Conan's place...", 1068. 0 /* no message */ 1069. }; 1070. const char *mesg; 1071. int which = rn2(4); 1072. 1073. if (Hallucination) 1074. mesg = halu_fam_msgs[which]; 1075. else 1076. mesg = fam_msgs[which]; 1077. if (mesg) pline(mesg); 1078. } 1079. 1080. #ifdef REINCARNATION 1081. if (new && Is_rogue_level(&u.uz)) 1082. You("enter what seems to be an older, more primitive world."); 1083. #endif 1084. /* Final confrontation */ 1085. if (In_endgame(&u.uz) && newdungeon && u.uhave.amulet) 1086. resurrect(); 1087. if (newdungeon && In_V_tower(&u.uz) && In_hell(&u.uz0)) 1088. pline_The("heat and smoke are gone."); 1089. 1090. /* the message from your quest leader */ 1091. if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest") && 1092. !(u.uevent.qexpelled || u.uevent.qcompleted || leaderless())) { 1093. 1094. if (u.uevent.qcalled) { 1095. com_pager(Role_is('R') ? 4 : 3); 1096. } else { 1097. com_pager(2); 1098. u.uevent.qcalled = TRUE; 1099. } 1100. } 1101. 1102. /* once Croesus is dead, his alarm doesn't work any more */ 1103. if (Is_knox(&u.uz) && (new || !mvitals[PM_CROESUS].died)) { 1104. register struct monst *mtmp; 1105. 1106. You("penetrated a high security area!"); 1107. pline("An alarm sounds!"); 1108. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1109. if(mtmp->msleep) mtmp->msleep = 0; 1110. } 1111. 1112. if(on_level(&u.uz, &astral_level)) { 1113. register struct monst *mtmp; 1114. 1115. /* reset monster hostility relative to player */ 1116. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1117. reset_hostility(mtmp); 1118. 1119. /* create some player-monsters */ 1120. create_mplayers(rn1(4, 3), TRUE); 1121. 1122. /* create a guardian angel next to player, if worthy */ 1123. if (Conflict) { 1124. coord mm; 1125. int i = rnd(4); 1126. pline("A voice booms: \"Thy desire for conflict shall be fulfilled!\""); 1127. while(i--) { 1128. mm.x = u.ux; 1129. mm.y = u.uy; 1130. if(enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])) 1131. (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type, 1132. mm.x, mm.y, FALSE); 1133. } 1134. 1135. } else if(u.ualign.record > 8 /* fervent */) { 1136. coord mm; 1137. 1138. pline("A voice whispers: \"Thou hast been worthy of me!\""); 1139. mm.x = u.ux; 1140. mm.y = u.uy; 1141. if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])) { 1142. if ((mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type, 1143. mm.x, mm.y, TRUE)) != 0) { 1144. register struct obj *otmp; 1145. 1146. if (!Blind) 1147. pline("An angel appears near you."); 1148. else 1149. You_feel("the presence of a friendly angel near you."); 1150. /* guardian angel -- the one case mtame doesn't 1151. * imply an edog structure, so we don't want to 1152. * call tamedog(). 1153. */ 1154. mtmp->mtame = 10; 1155. /* make him strong enough vs. endgame foes */ 1156. mtmp->m_lev = rn1(8,15); 1157. mtmp->mhp = mtmp->mhpmax = 1158. d((int)mtmp->m_lev,10) + 30 + rnd(30); 1159. if ((otmp = select_hwep(mtmp)) == 0) { 1160. otmp = mksobj(SILVER_SABER, FALSE, FALSE); 1161. mpickobj(mtmp, otmp); 1162. } 1163. bless(otmp); 1164. if (otmp->spe < 4) otmp->spe += rnd(4); 1165. if ((otmp = which_armor(mtmp, W_ARMS)) == 0 1166. || otmp->otyp != SHIELD_OF_REFLECTION) { 1167. (void) mongets(mtmp, AMULET_OF_REFLECTION); 1168. m_dowear(mtmp, TRUE); 1169. } 1170. } 1171. } 1172. } 1173. } 1174. 1175. onquest(); 1176. assign_level(&u.uz0, &u.uz); /* reset u.uz0 */ 1177. 1178. #ifdef INSURANCE 1179. save_currentstate(); 1180. #endif 1181. 1182. pickup(1); 1183. } 1184. 1185. static char *dfr_pre_msg = 0, /* pline() before level change */ 1186. *dfr_post_msg = 0; /* pline() after level change */ 1187. 1188. /* change levels at the end of this turn, after monsters finish moving */ 1189. void 1190. schedule_goto(tolev, at_stairs, falling, portal_flag, pre_msg, post_msg) 1191. d_level *tolev; 1192. boolean at_stairs, falling; 1193. int portal_flag; 1194. const char *pre_msg, *post_msg; 1195. { 1196. int typmask = 0100; /* non-zero triggers `deferred_goto' */ 1197. 1198. /* destination flags (`goto_level' args) */ 1199. if (at_stairs) typmask |= 1; 1200. if (falling) typmask |= 2; 1201. if (portal_flag) typmask |= 4; 1202. if (portal_flag < 0) typmask |= 0200; /* flag for portal removal */ 1203. u.utotype = typmask; 1204. /* destination level */ 1205. assign_level(&u.utolev, tolev); 1206. 1207. if (pre_msg) 1208. dfr_pre_msg = strcpy((char *)alloc(strlen(pre_msg) + 1), pre_msg); 1209. if (post_msg) 1210. dfr_post_msg = strcpy((char *)alloc(strlen(post_msg)+1), post_msg); 1211. 1212. /* we don't actually have to wait unless this is a monster's move */ 1213. if (!flags.mon_moving) deferred_goto(); 1214. } 1215. 1216. /* handle something like portal ejection */ 1217. void 1218. deferred_goto() 1219. { 1220. if (!on_level(&u.uz, &u.utolev)) { 1221. d_level dest; 1222. int typmask = u.utotype; /* save it; goto_level zeroes u.utotype */ 1223. 1224. assign_level(&dest, &u.utolev); 1225. if (dfr_pre_msg) pline(dfr_pre_msg); 1226. goto_level(&dest, !!(typmask&1), !!(typmask&2), !!(typmask&4)); 1227. if (typmask & 0200) { /* remove portal */ 1228. struct trap *t = t_at(u.ux, u.uy); 1229. 1230. if (t) { 1231. deltrap(t); 1232. newsym(u.ux, u.uy); 1233. } 1234. } 1235. if (dfr_post_msg) pline(dfr_post_msg); 1236. } 1237. u.utotype = 0; /* our caller keys off of this */ 1238. if (dfr_pre_msg) 1239. free((genericptr_t)dfr_pre_msg), dfr_pre_msg = 0; 1240. if (dfr_post_msg) 1241. free((genericptr_t)dfr_post_msg), dfr_post_msg = 0; 1242. } 1243. 1244. #endif /* OVL2 */ 1245. #ifdef OVL3 1246. 1247. /* 1248. * Return TRUE if we created a monster for the corpse. If successful, the 1249. * corpse is gone. 1250. */ 1251. boolean 1252. revive_corpse(corpse) 1253. struct obj *corpse; 1254. { 1255. struct monst *mtmp, *mcarry; 1256. boolean is_uwep, chewed; 1257. xchar where; 1258. char *cname, cname_buf[BUFSZ]; 1259. 1260. where = corpse->where; 1261. is_uwep = corpse == uwep; 1262. cname = eos(strcpy(cname_buf, "bite-covered ")); 1263. Strcpy(cname, corpse_xname(corpse, TRUE)); 1264. mcarry = (where == OBJ_MINVENT) ? corpse->ocarry : 0; 1265. mtmp = revive(corpse); /* corpse is gone if successful */ 1266. 1267. if (mtmp) { 1268. chewed = (mtmp->mhp < mtmp->mhpmax); 1269. if (chewed) cname = cname_buf; /* include "bite-covered" prefix */ 1270. switch (where) { 1271. case OBJ_INVENT: 1272. if (is_uwep) 1273. pline_The("%s writhes out of your grasp!", cname); 1274. else 1275. You_feel("squirming in your backpack!"); 1276. break; 1277. 1278. case OBJ_FLOOR: 1279. if (cansee(mtmp->mx, mtmp->my)) 1280. pline("%s rises from the dead!", chewed ? 1281. Adjmonnam(mtmp, "bite-covered") : Monnam(mtmp)); 1282. break; 1283. 1284. case OBJ_MINVENT: /* probably a nymph's */ 1285. if (cansee(mtmp->mx, mtmp->my)) { 1286. if (canseemon(mcarry)) 1287. pline("Startled, %s drops %s as it revives!", 1288. mon_nam(mcarry), an(cname)); 1289. else 1290. pline("%s suddenly appears!", chewed ? 1291. Adjmonnam(mtmp, "bite-covered") : Monnam(mtmp)); 1292. } 1293. break; 1294. 1295. default: 1296. /* we should be able to handle the other cases... */ 1297. impossible("revive_corpse: lost corpse @ %d", where); 1298. break; 1299. } 1300. return TRUE; 1301. } 1302. return FALSE; 1303. } 1304. 1305. /* Revive the corpse via a timeout. */ 1306. /*ARGSUSED*/ 1307. void 1308. revive_mon(arg, timeout) 1309. genericptr_t arg; 1310. long timeout; 1311. { 1312. struct obj *body = (struct obj *) arg; 1313. 1314. /* if we succeed, the corpse is gone, otherwise, rot it away */ 1315. if (!revive_corpse(body)) { 1316. if (is_rider(&mons[body->corpsenm])) 1317. You_feel("less hassled."); 1318. (void) start_timer(250L - (monstermoves-body->age), 1319. TIMER_OBJECT, ROT_CORPSE, arg); 1320. } 1321. } 1322. 1323. int 1324. donull() 1325. { 1326. return(1); /* Do nothing, but let other things happen */ 1327. } 1328. 1329. #endif /* OVL3 */ 1330. #ifdef OVLB 1331. 1332. STATIC_PTR int 1333. wipeoff() 1334. { 1335. if(u.ucreamed < 4) u.ucreamed = 0; 1336. else u.ucreamed -= 4; 1337. if (Blinded < 4) Blinded = 0; 1338. else Blinded -= 4; 1339. if (!Blinded) { 1340. pline("You've got the glop off."); 1341. u.ucreamed = 0; 1342. Blinded = 1; 1343. make_blinded(0L,TRUE); 1344. return(0); 1345. } else if (!u.ucreamed) { 1346. Your("%s feels clean now.", body_part(FACE)); 1347. return(0); 1348. } 1349. return(1); /* still busy */ 1350. } 1351. 1352. int 1353. dowipe() 1354. { 1355. if(u.ucreamed) { 1356. static NEARDATA char buf[39]; 1357. 1358. Sprintf(buf, "wiping off your %s", body_part(FACE)); 1359. set_occupation(wipeoff, buf, 0); 1360. /* Not totally correct; what if they change back after now 1361. * but before they're finished wiping? 1362. */ 1363. return(1); 1364. } 1365. Your("%s is already clean.", body_part(FACE)); 1366. return(1); 1367. } 1368. 1369. void 1370. set_wounded_legs(side, timex) 1371. register long side; 1372. register int timex; 1373. { 1374. if(!Wounded_legs) { 1375. ATEMP(A_DEX)--; 1376. flags.botl = 1; 1377. } 1378. 1379. if(!Wounded_legs || (Wounded_legs & TIMEOUT)) 1380. Wounded_legs |= side + timex; 1381. else 1382. Wounded_legs |= side; 1383. (void)encumber_msg(); 1384. } 1385. 1386. void 1387. heal_legs() 1388. { 1389. if(Wounded_legs) { 1390. if (ATEMP(A_DEX) < 0) { 1391. ATEMP(A_DEX)++; 1392. flags.botl = 1; 1393. } 1394. 1395. if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) { 1396. Your("%s feel somewhat better.", 1397. makeplural(body_part(LEG))); 1398. } else { 1399. Your("%s feels somewhat better.", 1400. body_part(LEG)); 1401. } 1402. Wounded_legs = 0; 1403. } 1404. (void)encumber_msg(); 1405. } 1406. 1407. #endif /* OVLB */ 1408. 1409. /*do.c*/