Difference between revisions of "Source:NetHack 3.4.0/hack.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 3.4.0/hack.c moved to Source:NetHack 3.4.0/hack.c: Robot: moved page) |
(No difference)
|
Latest revision as of 13:00, 4 March 2008
Below is the full text to hack.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/hack.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: @(#)hack.c 3.4 2002/03/09 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. #ifdef OVL1 8. STATIC_DCL void NDECL(maybe_wail); 9. #endif /*OVL1*/ 10. STATIC_DCL int NDECL(moverock); 11. STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P)); 12. #ifdef SINKS 13. STATIC_DCL void NDECL(dosinkfall); 14. #endif 15. STATIC_DCL void NDECL(findtravelpath); 16. STATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int)); 17. 18. STATIC_DCL void FDECL(move_update, (BOOLEAN_P)); 19. 20. #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE) 21. 22. #ifdef OVL2 23. 24. boolean 25. revive_nasty(x, y, msg) 26. int x,y; 27. const char *msg; 28. { 29. register struct obj *otmp, *otmp2; 30. struct monst *mtmp; 31. coord cc; 32. boolean revived = FALSE; 33. 34. for(otmp = level.objects[x][y]; otmp; otmp = otmp2) { 35. otmp2 = otmp->nexthere; 36. if (otmp->otyp == CORPSE && 37. (is_rider(&mons[otmp->corpsenm]) || 38. otmp->corpsenm == PM_WIZARD_OF_YENDOR)) { 39. /* move any living monster already at that location */ 40. if((mtmp = m_at(x,y)) && enexto(&cc, x, y, mtmp->data)) 41. rloc_to(mtmp, cc.x, cc.y); 42. if(msg) Norep("%s", msg); 43. revived = revive_corpse(otmp); 44. } 45. } 46. 47. /* this location might not be safe, if not, move revived monster */ 48. if (revived) { 49. mtmp = m_at(x,y); 50. if (mtmp && !goodpos(x, y, mtmp) && 51. enexto(&cc, x, y, mtmp->data)) { 52. rloc_to(mtmp, cc.x, cc.y); 53. } 54. /* else impossible? */ 55. } 56. 57. return (revived); 58. } 59. 60. STATIC_OVL int 61. moverock() 62. { 63. register xchar rx, ry, sx, sy; 64. register struct obj *otmp; 65. register struct trap *ttmp; 66. register struct monst *mtmp; 67. 68. sx = u.ux + u.dx, sy = u.uy + u.dy; /* boulder starting position */ 69. while ((otmp = sobj_at(BOULDER, sx, sy)) != 0) { 70. /* make sure that this boulder is visible as the top object */ 71. if (otmp != level.objects[sx][sy]) movobj(otmp, sx, sy); 72. 73. rx = u.ux + 2 * u.dx; /* boulder destination position */ 74. ry = u.uy + 2 * u.dy; 75. nomul(0); 76. if (Levitation || Is_airlevel(&u.uz)) { 77. if (Blind) feel_location(sx, sy); 78. You("don't have enough leverage to push %s.", the(xname(otmp))); 79. /* Give them a chance to climb over it? */ 80. return -1; 81. } 82. if (verysmall(youmonst.data) 83. #ifdef STEED 84. && !u.usteed 85. #endif 86. ) { 87. if (Blind) feel_location(sx, sy); 88. pline("You're too small to push that %s.", xname(otmp)); 89. goto cannot_push; 90. } 91. if (isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) && 92. (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || ( 93. #ifdef REINCARNATION 94. !Is_rogue_level(&u.uz) && 95. #endif 96. (levl[rx][ry].doormask & ~D_BROKEN) == D_NODOOR)) && 97. !sobj_at(BOULDER, rx, ry)) { 98. ttmp = t_at(rx, ry); 99. mtmp = m_at(rx, ry); 100. 101. /* KMH -- Sokoban doesn't let you push boulders diagonally */ 102. if (In_sokoban(&u.uz) && u.dx && u.dy) { 103. if (Blind) feel_location(sx,sy); 104. pline("%s won't roll diagonally on this %s.", 105. The(xname(otmp)), surface(sx, sy)); 106. goto cannot_push; 107. } 108. 109. if (revive_nasty(rx, ry, "You sense movement on the other side.")) 110. return (-1); 111. 112. if (mtmp && !noncorporeal(mtmp->data) && 113. (!mtmp->mtrapped || 114. !(ttmp && ((ttmp->ttyp == PIT) || 115. (ttmp->ttyp == SPIKED_PIT))))) { 116. if (canspotmon(mtmp)) 117. pline("There's %s on the other side.", mon_nam(mtmp)); 118. else { 119. if (Blind) feel_location(sx, sy); 120. You_hear("a monster behind %s.", the(xname(otmp))); 121. map_invisible(rx, ry); 122. } 123. if (flags.verbose) 124. pline("Perhaps that's why %s cannot move it.", 125. #ifdef STEED 126. u.usteed ? mon_nam(u.usteed) : 127. #endif 128. "you"); 129. goto cannot_push; 130. } 131. 132. if (ttmp) 133. switch(ttmp->ttyp) { 134. case LANDMINE: 135. if (rn2(10)) { 136. pline("KAABLAMM!!! %s %s land mine.", 137. Tobjnam(otmp, "trigger"), 138. ttmp->madeby_u ? "your" : "a"); 139. obj_extract_self(otmp); 140. place_object(otmp, rx, ry); 141. blow_up_landmine(ttmp); 142. /* if the boulder remains, it should fill the pit */ 143. fill_pit(u.ux, u.uy); 144. if (cansee(rx,ry)) newsym(rx,ry); 145. continue; 146. } 147. break; 148. case SPIKED_PIT: 149. case PIT: 150. obj_extract_self(otmp); 151. /* vision kludge to get messages right; 152. the pit will temporarily be seen even 153. if this is one among multiple boulders */ 154. if (!Blind) viz_array[ry][rx] |= IN_SIGHT; 155. if (!flooreffects(otmp, rx, ry, "fall")) { 156. place_object(otmp, rx, ry); 157. } 158. if (mtmp && !Blind) newsym(rx, ry); 159. continue; 160. case HOLE: 161. case TRAPDOOR: 162. if (Blind) 163. pline("Kerplunk! You no longer feel %s.", 164. the(xname(otmp))); 165. else 166. pline("%s%s and %s a %s in the %s!", 167. Tobjnam(otmp, 168. (ttmp->ttyp == TRAPDOOR) ? "trigger" : "fall"), 169. (ttmp->ttyp == TRAPDOOR) ? nul : " into", 170. otense(otmp, "plug"), 171. (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole", 172. surface(rx, ry)); 173. deltrap(ttmp); 174. delobj(otmp); 175. bury_objs(rx, ry); 176. if (cansee(rx,ry)) newsym(rx,ry); 177. continue; 178. case LEVEL_TELEP: 179. case TELEP_TRAP: 180. #ifdef STEED 181. if (u.usteed) 182. pline("%s pushes %s and suddenly it disappears!", 183. Monnam(u.usteed), the(xname(otmp))); 184. else 185. #endif 186. You("push %s and suddenly it disappears!", 187. the(xname(otmp))); 188. if (ttmp->ttyp == TELEP_TRAP) 189. rloco(otmp); 190. else { 191. int newlev = random_teleport_level(); 192. d_level dest; 193. 194. if (newlev == depth(&u.uz) || In_endgame(&u.uz)) 195. continue; 196. obj_extract_self(otmp); 197. add_to_migration(otmp); 198. get_level(&dest, newlev); 199. otmp->ox = dest.dnum; 200. otmp->oy = dest.dlevel; 201. otmp->owornmask = (long)MIGR_RANDOM; 202. } 203. seetrap(ttmp); 204. continue; 205. } 206. if (closed_door(rx, ry)) 207. goto nopushmsg; 208. if (boulder_hits_pool(otmp, rx, ry, TRUE)) 209. continue; 210. /* 211. * Re-link at top of fobj chain so that pile order is preserved 212. * when level is restored. 213. */ 214. if (otmp != fobj) { 215. remove_object(otmp); 216. place_object(otmp, otmp->ox, otmp->oy); 217. } 218. 219. { 220. #ifdef LINT /* static long lastmovetime; */ 221. long lastmovetime; 222. lastmovetime = 0; 223. #else 224. static NEARDATA long lastmovetime; 225. #endif 226. /* note: this var contains garbage initially and 227. after a restore */ 228. #ifdef STEED 229. if (!u.usteed) { 230. #endif 231. if (moves > lastmovetime+2 || moves < lastmovetime) 232. pline("With %s effort you move %s.", 233. throws_rocks(youmonst.data) ? "little" : "great", 234. the(xname(otmp))); 235. exercise(A_STR, TRUE); 236. #ifdef STEED 237. } else 238. pline("%s moves %s.", Monnam(u.usteed), the(xname(otmp))); 239. #endif 240. lastmovetime = moves; 241. } 242. 243. /* Move the boulder *after* the message. */ 244. if (glyph_is_invisible(levl[rx][ry].glyph)) 245. unmap_object(rx, ry); 246. movobj(otmp, rx, ry); /* does newsym(rx,ry) */ 247. if (Blind) { 248. feel_location(rx,ry); 249. feel_location(sx, sy); 250. } else { 251. newsym(sx, sy); 252. } 253. } else { 254. nopushmsg: 255. #ifdef STEED 256. if (u.usteed) 257. pline("%s tries to move %s, but cannot.", 258. Monnam(u.usteed), the(xname(otmp))); 259. else 260. #endif 261. You("try to move %s, but in vain.", the(xname(otmp))); 262. if (Blind) feel_location(sx, sy); 263. cannot_push: 264. if (throws_rocks(youmonst.data)) { 265. #ifdef STEED 266. if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) { 267. You("aren't skilled enough to %s %s from %s.", 268. (flags.pickup && !In_sokoban(&u.uz)) 269. ? "pick up" : "push aside", 270. the(xname(otmp)), mon_nam(u.usteed)); 271. } else 272. #endif 273. { 274. pline("However, you can easily %s.", 275. (flags.pickup && !In_sokoban(&u.uz)) 276. ? "pick it up" : "push it aside"); 277. if (In_sokoban(&u.uz)) 278. change_luck(-1); /* Sokoban guilt */ 279. break; 280. } 281. break; 282. } 283. 284. if ( 285. #ifdef STEED 286. !u.usteed && 287. #endif 288. (((!invent || inv_weight() <= -850) && 289. (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][sy].typ) 290. && IS_ROCK(levl[sx][u.uy].typ)))) 291. || verysmall(youmonst.data))) { 292. pline("However, you can squeeze yourself into a small opening."); 293. if (In_sokoban(&u.uz)) 294. change_luck(-1); /* Sokoban guilt */ 295. break; 296. } else 297. return (-1); 298. } 299. } 300. return (0); 301. } 302. 303. /* 304. * still_chewing() 305. * 306. * Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE 307. * when done. 308. */ 309. STATIC_OVL int 310. still_chewing(x,y) 311. xchar x, y; 312. { 313. struct rm *lev = &levl[x][y]; 314. struct obj *boulder = sobj_at(BOULDER,x,y); 315. const char *digtxt = (char *)0, *dmgtxt = (char *)0; 316. 317. if (digging.down) /* not continuing previous dig (w/ pick-axe) */ 318. (void) memset((genericptr_t)&digging, 0, sizeof digging); 319. 320. if (!boulder && IS_ROCK(lev->typ) && !may_dig(x,y)) { 321. You("hurt your teeth on the %s.", 322. IS_TREE(lev->typ) ? "tree" : "hard stone"); 323. nomul(0); 324. return 1; 325. } else if (digging.pos.x != x || digging.pos.y != y || 326. !on_level(&digging.level, &u.uz)) { 327. digging.down = FALSE; 328. digging.chew = TRUE; 329. digging.warned = FALSE; 330. digging.pos.x = x; 331. digging.pos.y = y; 332. assign_level(&digging.level, &u.uz); 333. /* solid rock takes more work & time to dig through */ 334. digging.effort = 335. (IS_ROCK(lev->typ) && !IS_TREE(lev->typ) ? 30 : 60) + u.udaminc; 336. You("start chewing %s %s.", 337. (boulder || IS_TREE(lev->typ)) ? "on a" : "a hole in the", 338. boulder ? "boulder" : 339. IS_TREE(lev->typ) ? "tree" : IS_ROCK(lev->typ) ? "rock" : "door"); 340. watch_dig((struct monst *)0, x, y, FALSE); 341. return 1; 342. } else if ((digging.effort += (30 + u.udaminc)) <= 100) { 343. if (flags.verbose) 344. You("%s chewing on the %s.", 345. digging.chew ? "continue" : "begin", 346. boulder ? "boulder" : 347. IS_TREE(lev->typ) ? "tree" : 348. IS_ROCK(lev->typ) ? "rock" : "door"); 349. digging.chew = TRUE; 350. watch_dig((struct monst *)0, x, y, FALSE); 351. return 1; 352. } 353. 354. /* Okay, you've chewed through something */ 355. u.uconduct.food++; 356. u.uhunger += rnd(20); 357. 358. if (boulder) { 359. delobj(boulder); /* boulder goes bye-bye */ 360. You("eat the boulder."); /* yum */ 361. 362. /* 363. * The location could still block because of 364. * 1. More than one boulder 365. * 2. Boulder stuck in a wall/stone/door. 366. * 367. * [perhaps use does_block() below (from vision.c)] 368. */ 369. if (IS_ROCK(lev->typ) || closed_door(x,y) || sobj_at(BOULDER,x,y)) { 370. block_point(x,y); /* delobj will unblock the point */ 371. /* reset dig state */ 372. (void) memset((genericptr_t)&digging, 0, sizeof digging); 373. return 1; 374. } 375. 376. } else if (IS_WALL(lev->typ)) { 377. if (*in_rooms(x, y, SHOPBASE)) { 378. add_damage(x, y, 10L * ACURRSTR); 379. dmgtxt = "damage"; 380. } 381. digtxt = "chew a hole in the wall."; 382. if (level.flags.is_maze_lev) { 383. lev->typ = ROOM; 384. } else if (level.flags.is_cavernous_lev) { 385. lev->typ = CORR; 386. } else { 387. lev->typ = DOOR; 388. lev->doormask = D_NODOOR; 389. } 390. } else if (lev->typ == SDOOR) { 391. if (lev->doormask & D_TRAPPED) { 392. lev->doormask = D_NODOOR; 393. b_trapped("secret door", 0); 394. } else { 395. digtxt = "chew through the secret door."; 396. lev->doormask = D_BROKEN; 397. } 398. lev->typ = DOOR; 399. 400. } else if (IS_DOOR(lev->typ)) { 401. if (*in_rooms(x, y, SHOPBASE)) { 402. add_damage(x, y, 400L); 403. dmgtxt = "break"; 404. } 405. if (lev->doormask & D_TRAPPED) { 406. lev->doormask = D_NODOOR; 407. b_trapped("door", 0); 408. } else { 409. digtxt = "chew through the door."; 410. lev->doormask = D_BROKEN; 411. } 412. 413. } else { /* STONE or SCORR */ 414. digtxt = "chew a passage through the rock."; 415. lev->typ = CORR; 416. } 417. 418. unblock_point(x, y); /* vision */ 419. newsym(x, y); 420. if (digtxt) You(digtxt); /* after newsym */ 421. if (dmgtxt) pay_for_damage(dmgtxt); 422. (void) memset((genericptr_t)&digging, 0, sizeof digging); 423. return 0; 424. } 425. 426. #endif /* OVL2 */ 427. #ifdef OVLB 428. 429. void 430. movobj(obj, ox, oy) 431. register struct obj *obj; 432. register xchar ox, oy; 433. { 434. /* optimize by leaving on the fobj chain? */ 435. remove_object(obj); 436. newsym(obj->ox, obj->oy); 437. place_object(obj, ox, oy); 438. newsym(ox, oy); 439. } 440. 441. #ifdef SINKS 442. static NEARDATA const char fell_on_sink[] = "fell onto a sink"; 443. 444. STATIC_OVL void 445. dosinkfall() 446. { 447. register struct obj *obj; 448. 449. if (is_floater(youmonst.data) || (HLevitation & FROMOUTSIDE)) { 450. You("wobble unsteadily for a moment."); 451. } else { 452. You("crash to the floor!"); 453. losehp(rn1(8, 25 - (int)ACURR(A_CON)), 454. fell_on_sink, NO_KILLER_PREFIX); 455. exercise(A_DEX, FALSE); 456. selftouch("Falling, you"); 457. for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) 458. if (obj->oclass == WEAPON_CLASS || is_weptool(obj)) { 459. You("fell on %s.", doname(obj)); 460. losehp(rnd(3), fell_on_sink, NO_KILLER_PREFIX); 461. exercise(A_CON, FALSE); 462. } 463. } 464. 465. ELevitation &= ~W_ARTI; 466. HLevitation &= ~(I_SPECIAL|TIMEOUT); 467. HLevitation++; 468. if(uleft && uleft->otyp == RIN_LEVITATION) { 469. obj = uleft; 470. Ring_off(obj); 471. off_msg(obj); 472. } 473. if(uright && uright->otyp == RIN_LEVITATION) { 474. obj = uright; 475. Ring_off(obj); 476. off_msg(obj); 477. } 478. if(uarmf && uarmf->otyp == LEVITATION_BOOTS) { 479. obj = uarmf; 480. (void)Boots_off(); 481. off_msg(obj); 482. } 483. HLevitation--; 484. } 485. #endif 486. 487. boolean 488. may_dig(x,y) 489. register xchar x,y; 490. /* intended to be called only on ROCKs */ 491. { 492. return (boolean)(!(IS_STWALL(levl[x][y].typ) && 493. (levl[x][y].wall_info & W_NONDIGGABLE))); 494. } 495. 496. boolean 497. may_passwall(x,y) 498. register xchar x,y; 499. { 500. return (boolean)(!(IS_STWALL(levl[x][y].typ) && 501. (levl[x][y].wall_info & W_NONPASSWALL))); 502. } 503. 504. #endif /* OVLB */ 505. #ifdef OVL1 506. 507. boolean 508. bad_rock(mdat,x,y) 509. struct permonst *mdat; 510. register xchar x,y; 511. { 512. return((boolean) ((In_sokoban(&u.uz) && sobj_at(BOULDER,x,y)) || 513. (IS_ROCK(levl[x][y].typ) 514. && (!tunnels(mdat) || needspick(mdat) || !may_dig(x,y)) 515. && !(passes_walls(mdat) && may_passwall(x,y))))); 516. } 517. 518. boolean 519. invocation_pos(x, y) 520. xchar x, y; 521. { 522. return((boolean)(Invocation_lev(&u.uz) && x == inv_pos.x && y == inv_pos.y)); 523. } 524. 525. #endif /* OVL1 */ 526. #ifdef OVL3 527. 528. /* return TRUE if (dx,dy) is an OK place to move */ 529. boolean 530. test_move(ux, uy, dx, dy, test_only) 531. int ux, uy, dx, dy; 532. boolean test_only; 533. { 534. int x = ux+dx; 535. int y = uy+dy; 536. register struct rm *tmpr = &levl[x][y]; 537. register struct rm *ust; 538. 539. /* 540. * Check for physical obstacles. First, the place we are going. 541. */ 542. if (IS_ROCK(tmpr->typ) || tmpr->typ == IRONBARS) { 543. if (Blind && !test_only) feel_location(x,y); 544. if (Passes_walls && may_passwall(x,y)) { 545. ; /* do nothing */ 546. } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) { 547. /* Eat the rock. */ 548. if (!test_only && still_chewing(x,y)) return FALSE; 549. } else if (flags.autodig && !flags.run && !flags.nopick && 550. uwep && is_pick(uwep)) { 551. /* MRKR: Automatic digging when wielding the appropriate tool */ 552. if (!test_only) 553. (void) use_pick_axe2(uwep); 554. return FALSE; 555. } else { 556. if ( !test_only ) { 557. if (Is_stronghold(&u.uz) && is_db_wall(x,y)) 558. pline_The("drawbridge is up!"); 559. if (Passes_walls && !may_passwall(x,y) && In_sokoban(&u.uz)) 560. pline_The("Sokoban walls resist your ability."); 561. } 562. return FALSE; 563. } 564. } else if (IS_DOOR(tmpr->typ)) { 565. if (closed_door(x,y)) { 566. if (Blind && !test_only) feel_location(x,y); 567. if (Passes_walls) 568. ; /* do nothing */ 569. else if (can_ooze(&youmonst)) { 570. if ( !test_only ) You("ooze under the door."); 571. } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) { 572. /* Eat the door. */ 573. if (!test_only && still_chewing(x,y)) return FALSE; 574. } else { 575. if ( !test_only ) { 576. if (amorphous(youmonst.data)) 577. You("try to ooze under the door, but can't squeeze your possessions through."); 578. else if (x == ux || y == uy) { 579. if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) { 580. #ifdef STEED 581. if (u.usteed) 582. You_cant("lead %s through that closed door.", 583. x_monnam(u.usteed, 584. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 585. (char *)0, SUPPRESS_SADDLE, FALSE)); 586. else { 587. #else 588. pline("Ouch! You bump into a door."); 589. exercise(A_DEX, FALSE); 590. #endif 591. #ifdef STEED 592. } 593. #endif 594. } else pline("That door is closed."); 595. } 596. } 597. return FALSE; 598. } 599. } else if (dx && dy && !Passes_walls 600. && ((tmpr->doormask & ~D_BROKEN) 601. #ifdef REINCARNATION 602. || Is_rogue_level(&u.uz) 603. #endif 604. || block_door(x,y))) { 605. /* Diagonal moves into a door are not allowed. */ 606. if ( Blind && !test_only ) 607. feel_location(x,y); 608. return FALSE; 609. } 610. } 611. if (dx && dy 612. && bad_rock(youmonst.data,ux,y) && bad_rock(youmonst.data,x,uy)) { 613. /* Move at a diagonal. */ 614. if (In_sokoban(&u.uz)) { 615. if ( !test_only ) 616. You("cannot pass that way."); 617. return FALSE; 618. } 619. if (bigmonst(youmonst.data)) { 620. if ( !test_only ) 621. Your("body is too large to fit through."); 622. return FALSE; 623. } 624. if (invent && (inv_weight() + weight_cap() > 600)) { 625. if ( !test_only ) 626. You("are carrying too much to get through."); 627. return FALSE; 628. } 629. } 630. 631. ust = &levl[ux][uy]; 632. 633. /* Now see if other things block our way . . */ 634. if (dx && dy && !Passes_walls 635. && (IS_DOOR(ust->typ) && ((ust->doormask & ~D_BROKEN) 636. #ifdef REINCARNATION 637. || Is_rogue_level(&u.uz) 638. #endif 639. || block_entry(x, y)) 640. )) { 641. /* Can't move at a diagonal out of a doorway with door. */ 642. return FALSE; 643. } 644. 645. if (sobj_at(BOULDER,x,y) && (In_sokoban(&u.uz) || !Passes_walls)) { 646. if (!(Blind || Hallucination) && (flags.run >= 2)) 647. return FALSE; 648. if (!test_only) { 649. /* tunneling monsters will chew before pushing */ 650. if (tunnels(youmonst.data) && !needspick(youmonst.data) && 651. !In_sokoban(&u.uz)) { 652. if (still_chewing(x,y)) return FALSE; 653. } else 654. if (moverock() < 0) return FALSE; 655. } 656. /* test_only will assume you'll be able to push it when you get there... */ 657. } 658. 659. /* OK, it is a legal place to move. */ 660. return TRUE; 661. } 662. 663. static void findtravelpath() 664. { 665. if ( u.tx != u.ux || u.ty != u.uy ) { 666. xchar travel[COLNO][ROWNO]; 667. xchar travelstepx[2][COLNO*ROWNO]; 668. xchar travelstepy[2][COLNO*ROWNO]; 669. int n=1; 670. int set=0; 671. int dia=1; 672. 673. (void) memset((genericptr_t)travel,0,sizeof(travel)); 674. 675. travelstepx[0][0] = u.tx; 676. travelstepy[0][0] = u.ty; 677. while ( n ) { 678. int i; 679. int nn=0; 680. for (i=0; i<n; i++) { 681. int dir; 682. int x = travelstepx[set][i]; 683. int y = travelstepy[set][i]; 684. static int ordered[] = { 0, 2, 4, 6, 1, 3, 5, 7 }; 685. for (dir=0; dir<8; dir++) { 686. int nx = x+xdir[ordered[dir]]; 687. int ny = y+ydir[ordered[dir]]; 688. /*printf("try %d,%d\n",nx,ny);*/ 689. if ( isok(nx,ny) && test_move( x, y, nx-x, ny-y, 1 ) ) { 690. if ( nx == u.ux && ny == u.uy ) { 691. u.dx = x-u.ux; 692. u.dy = y-u.uy; 693. /*printf("found\n");*/ 694. /*printf("findtravelpath %d,%d -> %d,%d by %d,%d\n",u.ux,u.uy,u.tx,u.ty,u.dx,u.dy); 695. */ 696. return; 697. } else { 698. /*printf("%d %d %d",isok(nx,ny), !travel[nx][ny], ACCESSIBLE(levl[nx][ny].typ));*/ 699. if ( !travel[nx][ny] ) { 700. travelstepx[1-set][nn]=nx; 701. travelstepy[1-set][nn]=ny; 702. travel[nx][ny]=dia; 703. nn++; 704. } 705. } 706. } 707. } 708. } 709. n = nn; 710. set = 1-set; 711. dia++; 712. } 713. 714. /* give up */ 715. } 716. 717. u.dx = 0; 718. u.dy = 0; 719. nomul(0); 720. } 721. 722. void 723. domove() 724. { 725. register struct monst *mtmp; 726. register struct rm *tmpr; 727. register xchar x,y; 728. struct trap *trap; 729. int wtcap; 730. boolean on_ice; 731. xchar chainx, chainy, ballx, bally; /* ball&chain new positions */ 732. int bc_control; /* control for ball&chain */ 733. boolean cause_delay = FALSE; /* dragging ball will skip a move */ 734. 735. u_wipe_engr(rnd(5)); 736. 737. if ( flags.travel ) 738. findtravelpath(); 739. 740. if(((wtcap = near_capacity()) >= OVERLOADED 741. || (wtcap > SLT_ENCUMBER && 742. (Upolyd ? (u.mh < 5 && u.mh != u.mhmax) 743. : (u.uhp < 10 && u.uhp != u.uhpmax)))) 744. && !Is_airlevel(&u.uz)) { 745. if(wtcap < OVERLOADED) { 746. You("don't have enough stamina to move."); 747. exercise(A_CON, FALSE); 748. } else 749. You("collapse under your load."); 750. nomul(0); 751. return; 752. } 753. if(u.uswallow) { 754. u.dx = u.dy = 0; 755. u.ux = x = u.ustuck->mx; 756. u.uy = y = u.ustuck->my; 757. mtmp = u.ustuck; 758. } else { 759. if (Is_airlevel(&u.uz) && rn2(4) && 760. !Levitation && !Flying) { 761. switch(rn2(3)) { 762. case 0: 763. You("tumble in place."); 764. exercise(A_DEX, FALSE); 765. break; 766. case 1: 767. You_cant("control your movements very well."); break; 768. case 2: 769. pline("It's hard to walk in thin air."); 770. exercise(A_DEX, TRUE); 771. break; 772. } 773. return; 774. } 775. 776. /* check slippery ice */ 777. on_ice = !Levitation && is_ice(u.ux, u.uy); 778. if (on_ice) { 779. static int skates = 0; 780. if (!skates) skates = find_skates(); 781. if ((uarmf && uarmf->otyp == skates) 782. || resists_cold(&youmonst) || Flying 783. || is_floater(youmonst.data) || is_clinger(youmonst.data) 784. || is_whirly(youmonst.data)) 785. on_ice = FALSE; 786. else if (!rn2(Cold_resistance ? 3 : 2)) { 787. HFumbling |= FROMOUTSIDE; 788. HFumbling &= ~TIMEOUT; 789. HFumbling += 1; /* slip on next move */ 790. } 791. } 792. if (!on_ice && (HFumbling & FROMOUTSIDE)) 793. HFumbling &= ~FROMOUTSIDE; 794. 795. x = u.ux + u.dx; 796. y = u.uy + u.dy; 797. if(Stunned || (Confusion && !rn2(5))) { 798. register int tries = 0; 799. 800. do { 801. if(tries++ > 50) { 802. nomul(0); 803. return; 804. } 805. confdir(); 806. x = u.ux + u.dx; 807. y = u.uy + u.dy; 808. } while(!isok(x, y) || bad_rock(youmonst.data, x, y)); 809. } 810. /* turbulence might alter your actual destination */ 811. if (u.uinwater) { 812. water_friction(); 813. if (!u.dx && !u.dy) { 814. nomul(0); 815. return; 816. } 817. x = u.ux + u.dx; 818. y = u.uy + u.dy; 819. } 820. if(!isok(x, y)) { 821. nomul(0); 822. return; 823. } 824. if((trap = t_at(x, y)) && trap->tseen) { 825. if(flags.run >= 2) { 826. nomul(0); 827. flags.move = 0; 828. return; 829. } else 830. nomul(0); 831. } 832. 833. if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) { 834. if (distu(u.ustuck->mx, u.ustuck->my) > 2) { 835. /* perhaps it fled (or was teleported or ... ) */ 836. u.ustuck = 0; 837. } else if (sticks(youmonst.data)) { 838. /* When polymorphed into a sticking monster, 839. * u.ustuck means it's stuck to you, not you to it. 840. */ 841. You("release %s.", mon_nam(u.ustuck)); 842. u.ustuck = 0; 843. } else { 844. /* If holder is asleep or paralyzed: 845. * 37.5% chance of getting away, 846. * 12.5% chance of waking/releasing it; 847. * otherwise: 848. * 7.5% chance of getting away. 849. * [strength ought to be a factor] 850. * If holder is tame and there is no conflict, 851. * guaranteed escape. 852. */ 853. switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) { 854. case 0: case 1: case 2: 855. pull_free: 856. You("pull free from %s.", mon_nam(u.ustuck)); 857. u.ustuck = 0; 858. break; 859. case 3: 860. if (!u.ustuck->mcanmove) { 861. /* it's free to move on next turn */ 862. u.ustuck->mfrozen = 1; 863. u.ustuck->msleeping = 0; 864. } 865. /*FALLTHRU*/ 866. default: 867. if (u.ustuck->mtame && 868. !Conflict && !u.ustuck->mconf) 869. goto pull_free; 870. You("cannot escape from %s!", mon_nam(u.ustuck)); 871. nomul(0); 872. return; 873. } 874. } 875. } 876. 877. mtmp = m_at(x,y); 878. if (mtmp) { 879. /* Don't attack if you're running, and can see it */ 880. /* We should never get here if forcefight */ 881. if (flags.run && 882. ((!Blind && mon_visible(mtmp) && 883. ((mtmp->m_ap_type != M_AP_FURNITURE && 884. mtmp->m_ap_type != M_AP_OBJECT) || 885. Protection_from_shape_changers)) || 886. sensemon(mtmp))) { 887. nomul(0); 888. flags.move = 0; 889. return; 890. } 891. } 892. } 893. 894. u.ux0 = u.ux; 895. u.uy0 = u.uy; 896. bhitpos.x = x; 897. bhitpos.y = y; 898. tmpr = &levl[x][y]; 899. 900. /* attack monster */ 901. if(mtmp) { 902. nomul(0); 903. /* only attack if we know it's there */ 904. /* or if we used the 'F' command to fight blindly */ 905. /* or if it hides_under, in which case we call attack() to print 906. * the Wait! message. 907. * This is different from ceiling hiders, who aren't handled in 908. * attack(). 909. */ 910. 911. /* If they used a 'm' command, trying to move onto a monster 912. * prints the below message and wastes a turn. The exception is 913. * if the monster is unseen and the player doesn't remember an 914. * invisible monster--then, we fall through to attack() and 915. * attack_check(), which still wastes a turn, but prints a 916. * different message and makes the player remember the monster. */ 917. if(flags.nopick && 918. (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))){ 919. if(mtmp->m_ap_type && !Protection_from_shape_changers 920. && !sensemon(mtmp)) 921. stumble_onto_mimic(mtmp); 922. else if (mtmp->mpeaceful && !Hallucination) 923. pline("Pardon me, %s.", m_monnam(mtmp)); 924. else 925. You("move right into %s.", mon_nam(mtmp)); 926. return; 927. } 928. if(flags.forcefight || !mtmp->mundetected || sensemon(mtmp) || 929. ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) && 930. !is_safepet(mtmp))){ 931. gethungry(); 932. if(wtcap >= HVY_ENCUMBER && moves%3) { 933. if (Upolyd && u.mh > 1) { 934. u.mh--; 935. } else if (!Upolyd && u.uhp > 1) { 936. u.uhp--; 937. } else { 938. You("pass out from exertion!"); 939. exercise(A_CON, FALSE); 940. fall_asleep(-10, FALSE); 941. } 942. } 943. if(multi < 0) return; /* we just fainted */ 944. 945. /* try to attack; note that it might evade */ 946. /* also, we don't attack tame when _safepet_ */ 947. if(attack(mtmp)) return; 948. } 949. } 950. 951. /* specifying 'F' with no monster wastes a turn */ 952. if (flags.forcefight || 953. /* remembered an 'I' && didn't use a move command */ 954. (glyph_is_invisible(levl[x][y].glyph) && !flags.nopick)) { 955. char buf[BUFSZ]; 956. Sprintf(buf,"a vacant spot on the %s", surface(x,y)); 957. You("attack %s.", 958. !Underwater ? "thin air" : is_pool(x,y) ? "empty water" : buf); 959. unmap_object(x, y); /* known empty -- remove 'I' if present */ 960. newsym(x, y); 961. nomul(0); 962. return; 963. } 964. if (glyph_is_invisible(levl[x][y].glyph)) { 965. unmap_object(x, y); 966. newsym(x, y); 967. } 968. /* not attacking an animal, so we try to move */ 969. #ifdef STEED 970. if (u.usteed && !u.usteed->mcanmove && (u.dx || u.dy)) { 971. pline("%s won't move!", 972. upstart(x_monnam(u.usteed, 973. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 974. (char *)0, SUPPRESS_SADDLE, FALSE))); 975. nomul(0); 976. return; 977. } else 978. #endif 979. if(!youmonst.data->mmove) { 980. You("are rooted %s.", 981. Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ? 982. "in place" : "to the ground"); 983. nomul(0); 984. return; 985. } 986. if(u.utrap) { 987. if(u.utraptype == TT_PIT) { 988. if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) { 989. Your("%s gets stuck in a crevice.", body_part(LEG)); 990. display_nhwindow(WIN_MESSAGE, FALSE); 991. clear_nhwindow(WIN_MESSAGE); 992. You("free your %s.", body_part(LEG)); 993. } else if (!(--u.utrap)) { 994. You("%s to the edge of the pit.", 995. (In_sokoban(&u.uz) && Levitation) ? 996. "struggle against the air currents and float" : 997. #ifdef STEED 998. u.usteed ? "ride" : 999. #endif 1000. "crawl"); 1001. fill_pit(u.ux, u.uy); 1002. vision_full_recalc = 1; /* vision limits change */ 1003. } else if (flags.verbose) { 1004. #ifdef STEED 1005. if (u.usteed) 1006. Norep("%s is still in a pit.", 1007. upstart(x_monnam(u.usteed, 1008. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1009. (char *)0, SUPPRESS_SADDLE, FALSE))); 1010. else 1011. #endif 1012. Norep( (Hallucination && !rn2(5)) ? 1013. "You've fallen, and you can't get up." : 1014. "You are still in a pit." ); 1015. } 1016. } else if (u.utraptype == TT_LAVA) { 1017. if(flags.verbose) { 1018. char *predicament = "stuck in the lava"; 1019. #ifdef STEED 1020. if (u.usteed) 1021. Norep("%s is %s.", 1022. upstart(x_monnam(u.usteed, 1023. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1024. (char *)0, SUPPRESS_SADDLE, FALSE)), 1025. predicament); 1026. else 1027. #endif 1028. Norep("You are %s.", predicament); 1029. } 1030. if(!is_lava(x,y)) { 1031. u.utrap--; 1032. if((u.utrap & 0xff) == 0) { 1033. #ifdef STEED 1034. if (u.usteed) 1035. You("lead %s to the edge of the lava.", 1036. x_monnam(u.usteed, 1037. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1038. (char *)0, SUPPRESS_SADDLE, FALSE)); 1039. else 1040. #endif 1041. You("pull yourself to the edge of the lava."); 1042. u.utrap = 0; 1043. } 1044. } 1045. u.umoved = TRUE; 1046. } else if (u.utraptype == TT_WEB) { 1047. if(uwep && uwep->oartifact == ART_STING) { 1048. u.utrap = 0; 1049. pline("Sting cuts through the web!"); 1050. return; 1051. } 1052. if(--u.utrap) { 1053. if(flags.verbose) { 1054. char *predicament = "stuck to the web"; 1055. #ifdef STEED 1056. if (u.usteed) 1057. Norep("%s is %s.", 1058. upstart(x_monnam(u.usteed, 1059. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1060. (char *)0, SUPPRESS_SADDLE, FALSE)), 1061. predicament); 1062. else 1063. #endif 1064. Norep("You are %s.", predicament); 1065. } 1066. } else { 1067. #ifdef STEED 1068. if (u.usteed) 1069. pline("%s breaks out of the web.", 1070. upstart(x_monnam(u.usteed, 1071. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1072. (char *)0, SUPPRESS_SADDLE, FALSE))); 1073. else 1074. #endif 1075. You("disentangle yourself."); 1076. } 1077. } else if (u.utraptype == TT_INFLOOR) { 1078. if(--u.utrap) { 1079. if(flags.verbose) { 1080. char *predicament = "stuck in the"; 1081. #ifdef STEED 1082. if (u.usteed) 1083. Norep("%s is %s %s.", 1084. upstart(x_monnam(u.usteed, 1085. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1086. (char *)0, SUPPRESS_SADDLE, FALSE)), 1087. predicament, surface(u.ux, u.uy)); 1088. else 1089. #endif 1090. Norep("You are %s %s.", predicament, surface(u.ux, u.uy)); 1091. } 1092. } else { 1093. #ifdef STEED 1094. if (u.usteed) 1095. pline("%s finally wiggles free.", 1096. upstart(x_monnam(u.usteed, 1097. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1098. (char *)0, SUPPRESS_SADDLE, FALSE))); 1099. else 1100. #endif 1101. You("finally wiggle free."); 1102. } 1103. } else { 1104. if(flags.verbose) { 1105. char *predicament = "caught in a bear trap"; 1106. #ifdef STEED 1107. if (u.usteed) 1108. Norep("%s is %s.", 1109. upstart(x_monnam(u.usteed, 1110. u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1111. (char *)0, SUPPRESS_SADDLE, FALSE)), 1112. predicament); 1113. else 1114. #endif 1115. Norep("You are %s.", predicament); 1116. } 1117. if((u.dx && u.dy) || !rn2(5)) u.utrap--; 1118. } 1119. return; 1120. } 1121. 1122. if ( !test_move( u.ux, u.uy, x-u.ux, y-u.uy, 0 ) ) { 1123. flags.move = 0; 1124. nomul(0); 1125. return; 1126. } 1127. 1128. /* Move ball and chain. */ 1129. if (Punished) 1130. if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy, 1131. &cause_delay)) 1132. return; 1133. 1134. /* Check regions entering/leaving */ 1135. if (!in_out_region(x,y)) 1136. return; 1137. 1138. /* now move the hero */ 1139. mtmp = m_at(x, y); 1140. u.ux += u.dx; 1141. u.uy += u.dy; 1142. #ifdef STEED 1143. /* Move your steed, too */ 1144. if (u.usteed) { 1145. u.usteed->mx = u.ux; 1146. u.usteed->my = u.uy; 1147. exercise_steed(); 1148. } 1149. #endif 1150. 1151. /* 1152. * If safepet at destination then move the pet to the hero's 1153. * previous location using the same conditions as in attack(). 1154. * there are special extenuating circumstances: 1155. * (1) if the pet dies then your god angers, 1156. * (2) if the pet gets trapped then your god may disapprove, 1157. * (3) if the pet was already trapped and you attempt to free it 1158. * not only do you encounter the trap but you may frighten your 1159. * pet causing it to go wild! moral: don't abuse this privilege. 1160. * 1161. * Ceiling-hiding pets are skipped by this section of code, to 1162. * be caught by the normal falling-monster code. 1163. */ 1164. if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) { 1165. /* if trapped, there's a chance the pet goes wild */ 1166. if (mtmp->mtrapped) { 1167. if (!rn2(mtmp->mtame)) { 1168. mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0; 1169. if (mtmp->mleashed) m_unleash(mtmp, TRUE); 1170. growl(mtmp); 1171. } else { 1172. yelp(mtmp); 1173. } 1174. } 1175. mtmp->mundetected = 0; 1176. if (mtmp->m_ap_type) seemimic(mtmp); 1177. else if (!mtmp->mtame) newsym(mtmp->mx, mtmp->my); 1178. 1179. if (mtmp->mtrapped && 1180. (trap = t_at(mtmp->mx, mtmp->my)) != 0 && 1181. (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && 1182. sobj_at(BOULDER, trap->tx, trap->ty)) { 1183. /* can't swap places with pet pinned in a pit by a boulder */ 1184. u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */ 1185. } else { 1186. char pnambuf[BUFSZ]; 1187. 1188. /* save its current description in case of polymorph */ 1189. Strcpy(pnambuf, y_monnam(mtmp)); 1190. mtmp->mtrapped = 0; 1191. remove_monster(x, y); 1192. place_monster(mtmp, u.ux0, u.uy0); 1193. 1194. /* check for displacing it into pools and traps */ 1195. switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) { 1196. case 0: 1197. You("%s %s.", mtmp->mtame ? "displaced" : "frightened", 1198. pnambuf); 1199. break; 1200. case 1: /* trapped */ 1201. case 3: /* changed levels */ 1202. /* there's already been a trap message, reinforce it */ 1203. abuse_dog(mtmp); 1204. adjalign(-3); 1205. break; 1206. case 2: 1207. /* it may have drowned or died. that's no way to 1208. * treat a pet! your god gets angry. 1209. */ 1210. if (rn2(4)) { 1211. You_feel("guilty about losing your pet like this."); 1212. u.ugangr++; 1213. adjalign(-15); 1214. } 1215. 1216. /* you killed your pet by direct action. 1217. * minliquid and mintrap don't know to do this 1218. */ 1219. u.uconduct.killer++; 1220. break; 1221. default: 1222. pline("that's strange, unknown mintrap result!"); 1223. break; 1224. } 1225. } 1226. } 1227. 1228. reset_occupations(); 1229. if (flags.run) { 1230. if ( flags.run < 8 ) 1231. if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) || 1232. IS_FURNITURE(tmpr->typ)) 1233. nomul(0); 1234. } 1235. 1236. if (hides_under(youmonst.data)) 1237. u.uundetected = OBJ_AT(u.ux, u.uy); 1238. else if (youmonst.data->mlet == S_EEL) 1239. u.uundetected = is_pool(u.ux, u.uy) && !Is_waterlevel(&u.uz); 1240. else if (u.dx || u.dy) 1241. u.uundetected = 0; 1242. 1243. /* 1244. * Mimics (or whatever) become noticeable if they move and are 1245. * imitating something that doesn't move. We could extend this 1246. * to non-moving monsters... 1247. */ 1248. if ((u.dx || u.dy) && (youmonst.m_ap_type == M_AP_OBJECT 1249. || youmonst.m_ap_type == M_AP_FURNITURE)) 1250. youmonst.m_ap_type = M_AP_NOTHING; 1251. 1252. check_leash(u.ux0,u.uy0); 1253. 1254. if(u.ux0 != u.ux || u.uy0 != u.uy) { 1255. u.umoved = TRUE; 1256. /* Clean old position -- vision_recalc() will print our new one. */ 1257. newsym(u.ux0,u.uy0); 1258. /* Since the hero has moved, adjust what can be seen/unseen. */ 1259. vision_recalc(1); /* Do the work now in the recover time. */ 1260. invocation_message(); 1261. } 1262. 1263. if (Punished) /* put back ball and chain */ 1264. move_bc(0,bc_control,ballx,bally,chainx,chainy); 1265. 1266. spoteffects(TRUE); 1267. 1268. /* delay next move because of ball dragging */ 1269. /* must come after we finished picking up, in spoteffects() */ 1270. if (cause_delay) { 1271. nomul(-2); 1272. nomovemsg = ""; 1273. } 1274. } 1275. 1276. void 1277. invocation_message() 1278. { 1279. /* a special clue-msg when on the Invocation position */ 1280. if(invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) { 1281. struct obj *otmp = carrying(CANDELABRUM_OF_INVOCATION); 1282. 1283. You_feel("a strange vibration under your %s.", 1284. makeplural(body_part(FOOT))); 1285. if (otmp && otmp->spe == 7 && otmp->lamplit) 1286. pline("%s %s!", The(xname(otmp)), 1287. Blind ? "throbs palpably" : "glows with a strange light"); 1288. } 1289. } 1290. 1291. #endif /* OVL3 */ 1292. #ifdef OVL2 1293. 1294. void 1295. spoteffects(pick) 1296. boolean pick; 1297. { 1298. register struct trap *trap; 1299. register struct monst *mtmp; 1300. 1301. if(u.uinwater) { 1302. int was_underwater; 1303. 1304. if (!is_pool(u.ux,u.uy)) { 1305. if (Is_waterlevel(&u.uz)) 1306. You("pop into an air bubble."); 1307. else if (is_lava(u.ux, u.uy)) 1308. You("leave the water..."); /* oops! */ 1309. else 1310. You("are on solid %s again.", 1311. is_ice(u.ux, u.uy) ? "ice" : "land"); 1312. } 1313. else if (Is_waterlevel(&u.uz)) 1314. goto stillinwater; 1315. else if (Levitation) 1316. You("pop out of the water like a cork!"); 1317. else if (Flying) 1318. You("fly out of the water."); 1319. else if (Wwalking) 1320. You("slowly rise above the surface."); 1321. else 1322. goto stillinwater; 1323. was_underwater = Underwater && !Is_waterlevel(&u.uz); 1324. u.uinwater = 0; /* leave the water */ 1325. if (was_underwater) { /* restore vision */ 1326. docrt(); 1327. vision_full_recalc = 1; 1328. } 1329. } 1330. stillinwater:; 1331. if (!Levitation && !u.ustuck && !Flying) { 1332. /* limit recursive calls through teleds() */ 1333. if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) { 1334. #ifdef STEED 1335. if (u.usteed && !is_flyer(u.usteed->data) && 1336. !is_floater(u.usteed->data) && 1337. !is_clinger(u.usteed->data)) { 1338. dismount_steed(Underwater ? 1339. DISMOUNT_FELL : DISMOUNT_GENERIC); 1340. /* dismount_steed() -> float_down() -> pickup() */ 1341. if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) 1342. pick = FALSE; 1343. } else 1344. #endif 1345. if (is_lava(u.ux, u.uy)) { 1346. if (lava_effects()) return; 1347. } else if (!Wwalking && drown()) 1348. return; 1349. } 1350. } 1351. check_special_room(FALSE); 1352. #ifdef SINKS 1353. if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 1354. dosinkfall(); 1355. #endif 1356. if (pick && !in_steed_dismounting) 1357. (void) pickup(1); 1358. /* if dismounting, we'll check again later */ 1359. if ((trap = t_at(u.ux,u.uy)) != 0 && !in_steed_dismounting) 1360. dotrap(trap, 0); /* fall into pit, arrow trap, etc. */ 1361. if((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) { 1362. mtmp->mundetected = mtmp->msleeping = 0; 1363. switch(mtmp->data->mlet) { 1364. case S_PIERCER: 1365. pline("%s suddenly drops from the %s!", 1366. Amonnam(mtmp), ceiling(u.ux,u.uy)); 1367. if(mtmp->mtame) /* jumps to greet you, not attack */ 1368. ; 1369. else if(uarmh) 1370. pline("Its blow glances off your helmet."); 1371. else if (u.uac + 3 <= rnd(20)) 1372. You("are almost hit by %s!", 1373. x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE)); 1374. else { 1375. int dmg; 1376. You("are hit by %s!", 1377. x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE)); 1378. dmg = d(4,6); 1379. if(Half_physical_damage) dmg = (dmg+1) / 2; 1380. mdamageu(mtmp, dmg); 1381. } 1382. break; 1383. default: /* monster surprises you. */ 1384. if(mtmp->mtame) 1385. pline("%s jumps near you from the %s.", 1386. Amonnam(mtmp), ceiling(u.ux,u.uy)); 1387. else if(mtmp->mpeaceful) { 1388. You("surprise %s!", 1389. Blind && !sensemon(mtmp) ? 1390. something : a_monnam(mtmp)); 1391. mtmp->mpeaceful = 0; 1392. } else 1393. pline("%s attacks you by surprise!", 1394. Amonnam(mtmp)); 1395. break; 1396. } 1397. mnexto(mtmp); /* have to move the monster */ 1398. } 1399. } 1400. 1401. STATIC_OVL boolean 1402. monstinroom(mdat,roomno) 1403. struct permonst *mdat; 1404. int roomno; 1405. { 1406. register struct monst *mtmp; 1407. 1408. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1409. if(!DEADMONSTER(mtmp) && mtmp->data == mdat && 1410. index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET)) 1411. return(TRUE); 1412. return(FALSE); 1413. } 1414. 1415. char * 1416. in_rooms(x, y, typewanted) 1417. register xchar x, y; 1418. register int typewanted; 1419. { 1420. static char buf[5]; 1421. char rno, *ptr = &buf[4]; 1422. int typefound, min_x, min_y, max_x, max_y_offset, step; 1423. register struct rm *lev; 1424. 1425. #define goodtype(rno) (!typewanted || \ 1426. ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) || \ 1427. ((typewanted == SHOPBASE) && (typefound > SHOPBASE))) \ 1428. 1429. switch (rno = levl[x][y].roomno) { 1430. case NO_ROOM: 1431. return(ptr); 1432. case SHARED: 1433. step = 2; 1434. break; 1435. case SHARED_PLUS: 1436. step = 1; 1437. break; 1438. default: /* i.e. a regular room # */ 1439. if (goodtype(rno)) 1440. *(--ptr) = rno; 1441. return(ptr); 1442. } 1443. 1444. min_x = x - 1; 1445. max_x = x + 1; 1446. if (x < 1) 1447. min_x += step; 1448. else 1449. if (x >= COLNO) 1450. max_x -= step; 1451. 1452. min_y = y - 1; 1453. max_y_offset = 2; 1454. if (min_y < 0) { 1455. min_y += step; 1456. max_y_offset -= step; 1457. } else 1458. if ((min_y + max_y_offset) >= ROWNO) 1459. max_y_offset -= step; 1460. 1461. for (x = min_x; x <= max_x; x += step) { 1462. lev = &levl[x][min_y]; 1463. y = 0; 1464. if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1465. !index(ptr, rno) && goodtype(rno)) 1466. *(--ptr) = rno; 1467. y += step; 1468. if (y > max_y_offset) 1469. continue; 1470. if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1471. !index(ptr, rno) && goodtype(rno)) 1472. *(--ptr) = rno; 1473. y += step; 1474. if (y > max_y_offset) 1475. continue; 1476. if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1477. !index(ptr, rno) && goodtype(rno)) 1478. *(--ptr) = rno; 1479. } 1480. return(ptr); 1481. } 1482. 1483. STATIC_OVL void 1484. move_update(newlev) 1485. register boolean newlev; 1486. { 1487. char *ptr1, *ptr2, *ptr3, *ptr4; 1488. 1489. Strcpy(u.urooms0, u.urooms); 1490. Strcpy(u.ushops0, u.ushops); 1491. if (newlev) { 1492. u.urooms[0] = '\0'; 1493. u.uentered[0] = '\0'; 1494. u.ushops[0] = '\0'; 1495. u.ushops_entered[0] = '\0'; 1496. Strcpy(u.ushops_left, u.ushops0); 1497. return; 1498. } 1499. Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0)); 1500. 1501. for (ptr1 = &u.urooms[0], 1502. ptr2 = &u.uentered[0], 1503. ptr3 = &u.ushops[0], 1504. ptr4 = &u.ushops_entered[0]; 1505. *ptr1; ptr1++) { 1506. if (!index(u.urooms0, *ptr1)) 1507. *(ptr2++) = *ptr1; 1508. if (IS_SHOP(*ptr1 - ROOMOFFSET)) { 1509. *(ptr3++) = *ptr1; 1510. if (!index(u.ushops0, *ptr1)) 1511. *(ptr4++) = *ptr1; 1512. } 1513. } 1514. *ptr2 = '\0'; 1515. *ptr3 = '\0'; 1516. *ptr4 = '\0'; 1517. 1518. /* filter u.ushops0 -> u.ushops_left */ 1519. for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++) 1520. if (!index(u.ushops, *ptr1)) 1521. *(ptr2++) = *ptr1; 1522. *ptr2 = '\0'; 1523. } 1524. 1525. void 1526. check_special_room(newlev) 1527. register boolean newlev; 1528. { 1529. register struct monst *mtmp; 1530. char *ptr; 1531. 1532. move_update(newlev); 1533. 1534. if (*u.ushops0) 1535. u_left_shop(u.ushops_left, newlev); 1536. 1537. if (!*u.uentered && !*u.ushops_entered) /* implied by newlev */ 1538. return; /* no entrance messages necessary */ 1539. 1540. /* Did we just enter a shop? */ 1541. if (*u.ushops_entered) 1542. u_entered_shop(u.ushops_entered); 1543. 1544. for (ptr = &u.uentered[0]; *ptr; ptr++) { 1545. register int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype; 1546. 1547. /* Did we just enter some other special room? */ 1548. /* vault.c insists that a vault remain a VAULT, 1549. * and temples should remain TEMPLEs, 1550. * but everything else gives a message only the first time */ 1551. switch (rt) { 1552. case ZOO: 1553. pline("Welcome to David's treasure zoo!"); 1554. break; 1555. case SWAMP: 1556. pline("It %s rather %s down here.", 1557. Blind ? "feels" : "looks", 1558. Blind ? "humid" : "muddy"); 1559. break; 1560. case COURT: 1561. You("enter an opulent throne room!"); 1562. break; 1563. case LEPREHALL: 1564. You("enter a leprechaun hall!"); 1565. break; 1566. case MORGUE: 1567. if(midnight()) { 1568. const char *run = locomotion(youmonst.data, "Run"); 1569. pline("%s away! %s away!", run, run); 1570. } else 1571. You("have an uncanny feeling..."); 1572. break; 1573. case BEEHIVE: 1574. You("enter a giant beehive!"); 1575. break; 1576. case COCKNEST: 1577. You("enter a disgusting nest!"); 1578. break; 1579. case ANTHOLE: 1580. You("enter an anthole!"); 1581. break; 1582. case BARRACKS: 1583. if(monstinroom(&mons[PM_SOLDIER], roomno) || 1584. monstinroom(&mons[PM_SERGEANT], roomno) || 1585. monstinroom(&mons[PM_LIEUTENANT], roomno) || 1586. monstinroom(&mons[PM_CAPTAIN], roomno)) 1587. You("enter a military barracks!"); 1588. else 1589. You("enter an abandoned barracks."); 1590. break; 1591. case DELPHI: 1592. if(monstinroom(&mons[PM_ORACLE], roomno)) 1593. verbalize("%s, %s, welcome to Delphi!", 1594. Hello((struct monst *) 0), plname); 1595. break; 1596. case TEMPLE: 1597. intemple(roomno + ROOMOFFSET); 1598. /* fall through */ 1599. default: 1600. rt = 0; 1601. } 1602. 1603. if (rt != 0) { 1604. rooms[roomno].rtype = OROOM; 1605. if (!search_special(rt)) { 1606. /* No more room of that type */ 1607. switch(rt) { 1608. case COURT: 1609. level.flags.has_court = 0; 1610. break; 1611. case SWAMP: 1612. level.flags.has_swamp = 0; 1613. break; 1614. case MORGUE: 1615. level.flags.has_morgue = 0; 1616. break; 1617. case ZOO: 1618. level.flags.has_zoo = 0; 1619. break; 1620. case BARRACKS: 1621. level.flags.has_barracks = 0; 1622. break; 1623. case TEMPLE: 1624. level.flags.has_temple = 0; 1625. break; 1626. case BEEHIVE: 1627. level.flags.has_beehive = 0; 1628. break; 1629. } 1630. } 1631. if (rt == COURT || rt == SWAMP || rt == MORGUE || rt == ZOO) 1632. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1633. if (!DEADMONSTER(mtmp) && !Stealth && !rn2(3)) mtmp->msleeping = 0; 1634. } 1635. } 1636. 1637. return; 1638. } 1639. 1640. #endif /* OVL2 */ 1641. #ifdef OVLB 1642. 1643. int 1644. dopickup() 1645. { 1646. int count; 1647. /* awful kludge to work around parse()'s pre-decrement */ 1648. count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0; 1649. multi = 0; /* always reset */ 1650. /* uswallow case added by GAN 01/29/87 */ 1651. if(u.uswallow) { 1652. if (!u.ustuck->minvent) { 1653. if (is_animal(u.ustuck->data)) { 1654. You("pick up %s tongue.", s_suffix(mon_nam(u.ustuck))); 1655. pline("But it's kind of slimy, so you drop it."); 1656. } else 1657. You("don't %s anything in here to pick up.", 1658. Blind ? "feel" : "see"); 1659. return(1); 1660. } else { 1661. int tmpcount = -count; 1662. return loot_mon(u.ustuck, &tmpcount, (boolean *)0); 1663. } 1664. } 1665. if(is_pool(u.ux, u.uy)) { 1666. if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data) 1667. || (Flying && !Breathless)) { 1668. You("cannot dive into the water to pick things up."); 1669. return(0); 1670. } else if (!Underwater) { 1671. You_cant("even see the bottom, let alone pick up %s.", 1672. something); 1673. return(0); 1674. } 1675. } 1676. if (is_lava(u.ux, u.uy)) { 1677. if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data) 1678. || (Flying && !Breathless)) { 1679. You_cant("reach the bottom to pick things up."); 1680. return(0); 1681. } else if (!likes_lava(youmonst.data)) { 1682. You("would burn to a crisp trying to pick things up."); 1683. return(0); 1684. } 1685. } 1686. if(!OBJ_AT(u.ux, u.uy)) { 1687. There("is nothing here to pick up."); 1688. return(0); 1689. } 1690. if (!can_reach_floor()) { 1691. #ifdef STEED 1692. if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) 1693. You("aren't skilled enough to reach from %s.", 1694. mon_nam(u.usteed)); 1695. else 1696. #endif 1697. You("cannot reach the %s.", surface(u.ux,u.uy)); 1698. return(0); 1699. } 1700. return (pickup(-count)); 1701. } 1702. 1703. #endif /* OVLB */ 1704. #ifdef OVL2 1705. 1706. /* stop running if we see something interesting */ 1707. /* turn around a corner if that is the only way we can proceed */ 1708. /* do not turn left or right twice */ 1709. void 1710. lookaround() 1711. { 1712. register int x, y, i, x0 = 0, y0 = 0, m0 = 1, i0 = 9; 1713. register int corrct = 0, noturn = 0; 1714. register struct monst *mtmp; 1715. register struct trap *trap; 1716. 1717. /* Grid bugs stop if trying to move diagonal, even if blind. Maybe */ 1718. /* they polymorphed while in the middle of a long move. */ 1719. if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) { 1720. nomul(0); 1721. return; 1722. } 1723. 1724. if(Blind || flags.run == 0) return; 1725. for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) { 1726. if(!isok(x,y)) continue; 1727. 1728. if(u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy) continue; 1729. 1730. if(x == u.ux && y == u.uy) continue; 1731. 1732. if((mtmp = m_at(x,y)) && 1733. mtmp->m_ap_type != M_AP_FURNITURE && 1734. mtmp->m_ap_type != M_AP_OBJECT && 1735. (!mtmp->minvis || See_invisible) && !mtmp->mundetected) { 1736. if((flags.run != 1 && !mtmp->mtame) 1737. || (x == u.ux+u.dx && y == u.uy+u.dy)) 1738. goto stop; 1739. } 1740. 1741. if (levl[x][y].typ == STONE) continue; 1742. if (x == u.ux-u.dx && y == u.uy-u.dy) continue; 1743. 1744. if (IS_ROCK(levl[x][y].typ) || (levl[x][y].typ == ROOM) || 1745. IS_AIR(levl[x][y].typ)) 1746. continue; 1747. else if (closed_door(x,y)) { 1748. if(x != u.ux && y != u.uy) continue; 1749. if(flags.run != 1) goto stop; 1750. goto bcorr; 1751. } else if (levl[x][y].typ == CORR) { 1752. bcorr: 1753. if(levl[u.ux][u.uy].typ != ROOM) { 1754. if(flags.run == 1 || flags.run == 3 || flags.run == 8) { 1755. i = dist2(x,y,u.ux+u.dx,u.uy+u.dy); 1756. if(i > 2) continue; 1757. if(corrct == 1 && dist2(x,y,x0,y0) != 1) 1758. noturn = 1; 1759. if(i < i0) { 1760. i0 = i; 1761. x0 = x; 1762. y0 = y; 1763. m0 = mtmp ? 1 : 0; 1764. } 1765. } 1766. corrct++; 1767. } 1768. continue; 1769. } else if ((trap = t_at(x,y)) && trap->tseen) { 1770. if(flags.run == 1) goto bcorr; /* if you must */ 1771. if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 1772. continue; 1773. } else if (is_pool(x,y) || is_lava(x,y)) { 1774. /* water and lava only stop you if directly in front, and stop 1775. * you even if you are running 1776. */ 1777. if(!Levitation && !Flying && !is_clinger(youmonst.data) && 1778. x == u.ux+u.dx && y == u.uy+u.dy) 1779. /* No Wwalking check; otherwise they'd be able 1780. * to test boots by trying to SHIFT-direction 1781. * into a pool and seeing if the game allowed it 1782. */ 1783. goto stop; 1784. continue; 1785. } else { /* e.g. objects or trap or stairs */ 1786. if(flags.run == 1) goto bcorr; 1787. if(flags.run == 8) continue; 1788. if(mtmp) continue; /* d */ 1789. if(((x == u.ux - u.dx) && (y != u.uy + u.dy)) || 1790. ((y == u.uy - u.dy) && (x != u.ux + u.dx))) 1791. continue; 1792. } 1793. stop: 1794. nomul(0); 1795. return; 1796. } /* end for loops */ 1797. 1798. if(corrct > 1 && flags.run == 2) goto stop; 1799. if((flags.run == 1 || flags.run == 3 || flags.run == 8) && 1800. !noturn && !m0 && i0 && (corrct == 1 || (corrct == 2 && i0 == 1))) 1801. { 1802. /* make sure that we do not turn too far */ 1803. if(i0 == 2) { 1804. if(u.dx == y0-u.uy && u.dy == u.ux-x0) 1805. i = 2; /* straight turn right */ 1806. else 1807. i = -2; /* straight turn left */ 1808. } else if(u.dx && u.dy) { 1809. if((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy)) 1810. i = -1; /* half turn left */ 1811. else 1812. i = 1; /* half turn right */ 1813. } else { 1814. if((x0-u.ux == y0-u.uy && !u.dy) || (x0-u.ux != y0-u.uy && u.dy)) 1815. i = 1; /* half turn right */ 1816. else 1817. i = -1; /* half turn left */ 1818. } 1819. 1820. i += u.last_str_turn; 1821. if(i <= 2 && i >= -2) { 1822. u.last_str_turn = i; 1823. u.dx = x0-u.ux; 1824. u.dy = y0-u.uy; 1825. } 1826. } 1827. } 1828. 1829. /* something like lookaround, but we are not running */ 1830. /* react only to monsters that might hit us */ 1831. int 1832. monster_nearby() 1833. { 1834. register int x,y; 1835. register struct monst *mtmp; 1836. 1837. /* Also see the similar check in dochugw() in monmove.c */ 1838. for(x = u.ux-1; x <= u.ux+1; x++) 1839. for(y = u.uy-1; y <= u.uy+1; y++) { 1840. if(!isok(x,y)) continue; 1841. if(x == u.ux && y == u.uy) continue; 1842. if((mtmp = m_at(x,y)) && 1843. mtmp->m_ap_type != M_AP_FURNITURE && 1844. mtmp->m_ap_type != M_AP_OBJECT && 1845. (!mtmp->mpeaceful || Hallucination) && 1846. (!is_hider(mtmp->data) || !mtmp->mundetected) && 1847. !noattacks(mtmp->data) && 1848. mtmp->mcanmove && !mtmp->msleeping && /* aplvax!jcn */ 1849. !onscary(u.ux, u.uy, mtmp) && 1850. canspotmon(mtmp)) 1851. return(1); 1852. } 1853. return(0); 1854. } 1855. 1856. void 1857. nomul(nval) 1858. register int nval; 1859. { 1860. if(multi < nval) return; /* This is a bug fix by ab@unido */ 1861. u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */ 1862. u.usleep = 0; 1863. multi = nval; 1864. flags.travel = flags.mv = flags.run = 0; 1865. } 1866. 1867. /* called when a non-movement, multi-turn action has completed */ 1868. void unmul(msg_override) 1869. const char *msg_override; 1870. { 1871. multi = 0; /* caller will usually have done this already */ 1872. if (msg_override) nomovemsg = msg_override; 1873. else if (!nomovemsg) nomovemsg = You_can_move_again; 1874. if (*nomovemsg) pline(nomovemsg); 1875. nomovemsg = 0; 1876. u.usleep = 0; 1877. if (afternmv) (*afternmv)(); 1878. afternmv = 0; 1879. } 1880. 1881. #endif /* OVL2 */ 1882. #ifdef OVL1 1883. 1884. STATIC_OVL void 1885. maybe_wail() 1886. { 1887. static short powers[] = { TELEPORT, SEE_INVIS, POISON_RES, COLD_RES, 1888. SHOCK_RES, FIRE_RES, SLEEP_RES, DISINT_RES, 1889. TELEPORT_CONTROL, STEALTH, FAST, INVIS }; 1890. 1891. if (moves <= wailmsg + 50) return; 1892. 1893. wailmsg = moves; 1894. if (Role_if(PM_WIZARD) || Race_if(PM_ELF) || Role_if(PM_VALKYRIE)) { 1895. const char *who; 1896. int i, powercnt; 1897. 1898. who = (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE)) ? 1899. urole.name.m : "Elf"; 1900. if (u.uhp == 1) { 1901. pline("%s is about to die.", who); 1902. } else { 1903. for (i = 0, powercnt = 0; i < SIZE(powers); ++i) 1904. if (u.uprops[powers[i]].intrinsic & INTRINSIC) ++powercnt; 1905. 1906. pline(powercnt >= 4 ? "%s, all your powers will be lost..." 1907. : "%s, your life force is running out.", who); 1908. } 1909. } else { 1910. You_hear(u.uhp == 1 ? "the wailing of the Banshee..." 1911. : "the howling of the CwnAnnwn..."); 1912. } 1913. } 1914. 1915. void 1916. losehp(n, knam, k_format) 1917. register int n; 1918. register const char *knam; 1919. boolean k_format; 1920. { 1921. if (Upolyd) { 1922. u.mh -= n; 1923. if (u.mhmax < u.mh) u.mhmax = u.mh; 1924. flags.botl = 1; 1925. if (u.mh < 1) 1926. rehumanize(); 1927. else if (n > 0 && u.mh*10 < u.mhmax && Unchanging) 1928. maybe_wail(); 1929. return; 1930. } 1931. 1932. u.uhp -= n; 1933. if(u.uhp > u.uhpmax) 1934. u.uhpmax = u.uhp; /* perhaps n was negative */ 1935. flags.botl = 1; 1936. if(u.uhp < 1) { 1937. killer_format = k_format; 1938. killer = knam; /* the thing that killed you */ 1939. You("die..."); 1940. done(DIED); 1941. } else if (n > 0 && u.uhp*10 < u.uhpmax) { 1942. maybe_wail(); 1943. } 1944. } 1945. 1946. int 1947. weight_cap() 1948. { 1949. register long carrcap; 1950. 1951. carrcap = (((ACURRSTR + ACURR(A_CON))/2)+1)*50; 1952. if (Upolyd) { 1953. /* consistent with can_carry() in mon.c */ 1954. if (youmonst.data->mlet == S_NYMPH) 1955. carrcap = MAX_CARR_CAP; 1956. else if (!youmonst.data->cwt) 1957. carrcap = (carrcap * (long)youmonst.data->msize) / MZ_HUMAN; 1958. else if (!strongmonst(youmonst.data) 1959. || (strongmonst(youmonst.data) && (youmonst.data->cwt > WT_HUMAN))) 1960. carrcap = (carrcap * (long)youmonst.data->cwt / WT_HUMAN); 1961. } 1962. 1963. if (Levitation || Is_airlevel(&u.uz) /* pugh@cornell */ 1964. #ifdef STEED 1965. || (u.usteed && strongmonst(u.usteed->data)) 1966. #endif 1967. ) 1968. carrcap = MAX_CARR_CAP; 1969. else { 1970. if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 1971. if (!Flying) { 1972. if(EWounded_legs & LEFT_SIDE) carrcap -= 100; 1973. if(EWounded_legs & RIGHT_SIDE) carrcap -= 100; 1974. } 1975. if (carrcap < 0) carrcap = 0; 1976. } 1977. return((int) carrcap); 1978. } 1979. 1980. static int wc; /* current weight_cap(); valid after call to inv_weight() */ 1981. 1982. /* returns how far beyond the normal capacity the player is currently. */ 1983. /* inv_weight() is negative if the player is below normal capacity. */ 1984. int 1985. inv_weight() 1986. { 1987. register struct obj *otmp = invent; 1988. register int wt = 0; 1989. 1990. #ifndef GOLDOBJ 1991. /* when putting stuff into containers, gold is inserted at the head 1992. of invent for easier manipulation by askchain & co, but it's also 1993. retained in u.ugold in order to keep the status line accurate; we 1994. mustn't add its weight in twice under that circumstance */ 1995. wt = (otmp && otmp->oclass == GOLD_CLASS) ? 0 : 1996. (int)((u.ugold + 50L) / 100L); 1997. #endif 1998. while (otmp) { 1999. #ifndef GOLDOBJ 2000. if (otmp->otyp != BOULDER || !throws_rocks(youmonst.data)) 2001. #else 2002. if (otmp->oclass == GOLD_CLASS) 2003. wt += (int)(((long)otmp->quan + 50L) / 100L); 2004. else if (otmp->otyp != BOULDER || !throws_rocks(youmonst.data)) 2005. #endif 2006. wt += otmp->owt; 2007. otmp = otmp->nobj; 2008. } 2009. wc = weight_cap(); 2010. return (wt - wc); 2011. } 2012. 2013. /* 2014. * Returns 0 if below normal capacity, or the number of "capacity units" 2015. * over the normal capacity the player is loaded. Max is 5. 2016. */ 2017. int 2018. calc_capacity(xtra_wt) 2019. int xtra_wt; 2020. { 2021. int cap, wt = inv_weight() + xtra_wt; 2022. 2023. if (wt <= 0) return UNENCUMBERED; 2024. if (wc <= 1) return OVERLOADED; 2025. cap = (wt*2 / wc) + 1; 2026. return min(cap, OVERLOADED); 2027. } 2028. 2029. int 2030. near_capacity() 2031. { 2032. return calc_capacity(0); 2033. } 2034. 2035. int 2036. max_capacity() 2037. { 2038. int wt = inv_weight(); 2039. 2040. return (wt - (2 * wc)); 2041. } 2042. 2043. boolean 2044. check_capacity(str) 2045. const char *str; 2046. { 2047. if(near_capacity() >= EXT_ENCUMBER) { 2048. if(str) 2049. pline(str); 2050. else 2051. You_cant("do that while carrying so much stuff."); 2052. return 1; 2053. } 2054. return 0; 2055. } 2056. 2057. #endif /* OVL1 */ 2058. #ifdef OVLB 2059. 2060. int 2061. inv_cnt() 2062. { 2063. register struct obj *otmp = invent; 2064. register int ct = 0; 2065. 2066. while(otmp){ 2067. ct++; 2068. otmp = otmp->nobj; 2069. } 2070. return(ct); 2071. } 2072. 2073. #ifdef GOLDOBJ 2074. /* Counts the money in an object chain. */ 2075. /* Intended use is for your or some monsters inventory, */ 2076. /* now that u.gold/m.gold is gone.*/ 2077. /* Counting money in a container might be possible too. */ 2078. long money_cnt(otmp) 2079. struct obj *otmp; 2080. { 2081. while(otmp) { 2082. /* Must change when silver & copper is implemented: */ 2083. if (otmp->oclass == GOLD_CLASS) return otmp->quan; 2084. otmp = otmp->nobj; 2085. } 2086. return 0; 2087. } 2088. #endif 2089. #endif /* OVLB */ 2090. 2091. /*hack.c*/