Difference between revisions of "Source:NetHack 3.1.0/hack.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 3.1.0/hack.c moved to Source:NetHack 3.1.0/hack.c: Robot: moved page) |
(No difference)
|
Latest revision as of 06:34, 4 March 2008
Below is the full text to hack.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1 92/12/04 */ 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. STATIC_DCL int NDECL(moverock); 8. #ifdef POLYSELF 9. STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P)); 10. #endif 11. #ifdef SINKS 12. STATIC_DCL void NDECL(dosinkfall); 13. #endif 14. STATIC_DCL boolean FDECL(bad_rock,(XCHAR_P,XCHAR_P)); 15. STATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int)); 16. 17. static void FDECL(move_update, (BOOLEAN_P)); 18. 19. #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE) 20. 21. #ifdef OVL2 22. 23. boolean 24. revive_nasty(x, y, msg) 25. int x,y; 26. const char *msg; 27. { 28. register struct obj *otmp, *otmp2; 29. struct monst *mtmp; 30. coord cc; 31. boolean revived = FALSE; 32. 33. /* prevent freeobj() of revivable corpses */ 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. revive_corpse(otmp, 0, FALSE); 44. revived = MON_AT(x,y); 45. } 46. } 47. 48. /* this location might not be safe, if not, move revived monster */ 49. if (revived) { 50. mtmp = m_at(x,y); 51. if (mtmp && !goodpos(x, y, mtmp, mtmp->data) && 52. enexto(&cc, x, y, mtmp->data)) { 53. rloc_to(mtmp, cc.x, cc.y); 54. } 55. /* else impossible? */ 56. } 57. 58. return (revived); 59. } 60. 61. STATIC_OVL int 62. moverock() 63. { 64. register xchar rx, ry; 65. register struct obj *otmp, *otmp2; 66. register struct trap *ttmp; 67. register struct monst *mtmp; 68. 69. while ((otmp = sobj_at(BOULDER, u.ux+u.dx, u.uy+u.dy)) != 0) { 70. rx = u.ux+2*u.dx; 71. ry = u.uy+2*u.dy; 72. nomul(0); 73. if (Levitation || Is_airlevel(&u.uz)) { 74. if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy); 75. You("don't have enough leverage to push %s.", the(xname(otmp))); 76. /* Give them a chance to climb over it? */ 77. return -1; 78. } 79. #ifdef POLYSELF 80. if (verysmall(uasmon)) { 81. if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy); 82. pline("You're too small to push that %s.", xname(otmp)); 83. goto cannot_push; 84. } 85. #endif 86. if (isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) && 87. (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || ( 88. #ifdef REINCARNATION 89. !Is_rogue_level(&u.uz) && 90. #endif 91. (levl[rx][ry].doormask & ~D_BROKEN) == D_NODOOR)) && 92. !sobj_at(BOULDER, rx, ry)) { 93. ttmp = t_at(rx, ry); 94. mtmp = m_at(rx, ry); 95. 96. if (revive_nasty(rx, ry, "You sense movement on the other side.")) 97. return (-1); 98. 99. if (mtmp && (!mtmp->mtrapped || 100. !(ttmp && ((ttmp->ttyp == PIT) || 101. (ttmp->ttyp == SPIKED_PIT))))) { 102. if (canseemon(mtmp)) 103. pline("There's %s on the other side.", mon_nam(mtmp)); 104. else { 105. if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy); 106. You("hear a monster behind %s.", the(xname(otmp))); 107. } 108. if (flags.verbose) 109. pline("Perhaps that's why you cannot move it."); 110. goto cannot_push; 111. } 112. 113. if (ttmp) 114. switch(ttmp->ttyp) { 115. case SPIKED_PIT: 116. case PIT: 117. freeobj(otmp); 118. if (!flooreffects(otmp, rx, ry, "fall")) { 119. place_object(otmp, rx, ry); 120. otmp->nobj = fobj; 121. fobj = otmp; 122. } 123. continue; 124. case TRAPDOOR: 125. pline("%s falls into and plugs a hole in the ground!", 126. The(xname(otmp))); 127. deltrap(ttmp); 128. delobj(otmp); 129. delallobj(rx, ry); 130. if (cansee(rx,ry)) newsym(rx,ry); 131. continue; 132. case LEVEL_TELEP: 133. case TELEP_TRAP: 134. You("push %s and suddenly it disappears!", 135. the(xname(otmp))); 136. rloco(otmp); 137. continue; 138. } 139. if (closed_door(rx, ry)) 140. goto nopushmsg; 141. if (boulder_hits_pool(otmp, rx, ry, TRUE)) 142. continue; 143. /* 144. * Re-link at top of fobj chain so that pile order is preserved 145. * when level is restored. 146. */ 147. if (otmp != fobj) { 148. otmp2 = fobj; 149. while (otmp2->nobj && otmp2->nobj != otmp) 150. otmp2 = otmp2->nobj; 151. if (!otmp2->nobj) { 152. impossible("moverock: error in fobj chain"); 153. } else { 154. otmp2->nobj = otmp->nobj; 155. otmp->nobj = fobj; 156. fobj = otmp; 157. } 158. } 159. 160. { 161. #ifdef LINT /* static long lastmovetime; */ 162. long lastmovetime; 163. lastmovetime = 0; 164. #else 165. static long NEARDATA lastmovetime; 166. #endif 167. /* note: this var contains garbage initially and 168. after a restore */ 169. if (moves > lastmovetime+2 || moves < lastmovetime) 170. pline("With great effort you move %s.", the(xname(otmp))); 171. exercise(A_STR, TRUE); 172. lastmovetime = moves; 173. } 174. 175. /* Move the boulder *after* the message. */ 176. move_object(otmp, rx, ry); 177. if (Blind) { 178. feel_location(rx,ry); 179. feel_location(u.ux+u.dx, u.uy+u.dy); 180. } else { 181. newsym(rx,ry); 182. newsym(u.ux+u.dx, u.uy+u.dy); 183. } 184. } else { 185. nopushmsg: 186. You("try to move %s, but in vain.", the(xname(otmp))); 187. if (Blind) feel_location(u.ux+u.dx, u.uy+u.dy); 188. cannot_push: 189. #ifdef POLYSELF 190. if (throws_rocks(uasmon)) { 191. if (!flags.pickup) 192. pline("However, you easily can push it aside."); 193. else 194. pline("However, you easily can pick it up."); 195. break; 196. } 197. #endif 198. if (((!invent || inv_weight() <= -850) && 199. (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ) 200. && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))) 201. #ifdef POLYSELF 202. || verysmall(uasmon) 203. #endif 204. ) { 205. pline("However, you can squeeze yourself into a small opening."); 206. break; 207. } else 208. return (-1); 209. } 210. } 211. return (0); 212. } 213. 214. #ifdef POLYSELF 215. /* 216. * still_chewing() 217. * 218. * Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE 219. * when done. 220. */ 221. STATIC_OVL int 222. still_chewing(x,y) 223. xchar x, y; 224. { 225. struct rm *lev = &(levl[x][y]); 226. struct obj *boulder = sobj_at(BOULDER,x,y); 227. 228. if (dig_pos.x != x || dig_pos.y != y || 229. !on_level(&dig_level, &u.uz) || dig_down) { 230. if (!boulder && (lev->diggable & W_NONDIGGABLE)) 231. You("hurt your teeth on the hard stone."); 232. else { 233. dig_down = FALSE; 234. dig_pos.x = x; 235. dig_pos.y = y; 236. assign_level(&dig_level, &u.uz); 237. dig_effort = IS_ROCK(lev->typ) ? 30 : 60; /* rock takes more time */ 238. if (boulder) 239. You("start chewing on a boulder."); 240. else 241. You("start chewing a hole in the %s.", 242. IS_ROCK(lev->typ) ? "rock" : "door"); 243. } 244. return 1; 245. } else if ((dig_effort += 30) < 100) { 246. if (flags.verbose) 247. You("continue chewing on the %s.", boulder ? "boulder" : 248. (IS_ROCK(lev->typ) ? "rock" : "door")); 249. return 1; 250. } 251. 252. if (boulder) { 253. You("eat the boulder."); /* yum */ 254. delobj(boulder); /* boulder goes bye-bye */ 255. 256. /* 257. * The location could still block because of 258. * 1. More than one boulder 259. * 2. Boulder stuck in a wall/stone/door. 260. * 261. * [perhaps use does_block() below (from vision.c)] 262. */ 263. if (IS_ROCK(lev->typ) || closed_door(x,y) || sobj_at(BOULDER,x,y)) { 264. block_point(x,y); /* delobj will unblock the point */ 265. dig_pos.x = 0; /* reset dig messages */ 266. return 1; 267. } 268. 269. } else if (IS_WALL(lev->typ)) { 270. You("chew a hole in the wall."); 271. if (level.flags.is_maze_lev) { 272. lev->typ = ROOM; 273. } else if (level.flags.is_cavernous_lev) { 274. lev->typ = CORR; 275. } else { 276. lev->typ = DOOR; 277. lev->doormask = D_NODOOR; 278. } 279. } else if (lev->typ == SDOOR) { 280. if (lev->doormask & D_TRAPPED) { 281. b_trapped("secret door"); 282. lev->doormask = D_NODOOR; 283. } else { 284. You("chew through the secret door."); 285. lev->doormask = D_BROKEN; 286. } 287. lev->typ = DOOR; 288. 289. } else if (IS_DOOR(lev->typ)) { 290. if (lev->doormask & D_TRAPPED) { 291. b_trapped("door"); 292. lev->doormask = D_NODOOR; 293. } else { 294. You("chew through the door."); 295. lev->doormask = D_BROKEN; 296. } 297. 298. } else { /* STONE or SCORR */ 299. You("chew a passage through the rock."); 300. lev->typ = CORR; 301. } 302. 303. unblock_point(x, y); /* vision */ 304. newsym(x, y); 305. dig_level.dnum = 0; 306. dig_level.dlevel = -1; 307. return 0; 308. } 309. #endif /* POLYSELF */ 310. 311. #endif /* OVL2 */ 312. #ifdef OVLB 313. 314. void 315. movobj(obj, ox, oy) 316. register struct obj *obj; 317. register xchar ox, oy; 318. { 319. remove_object(obj); 320. newsym(obj->ox, obj->oy); 321. place_object(obj, ox, oy); 322. newsym(ox, oy); 323. } 324. 325. #ifdef SINKS 326. STATIC_OVL void 327. dosinkfall() 328. { 329. register struct obj *obj; 330. 331. # ifdef POLYSELF 332. if (is_floater(uasmon)) { 333. You("wobble unsteadily for a moment."); 334. } else { 335. # endif 336. You("crash to the floor!"); 337. losehp((rn1(10, 20 - (int)ACURR(A_CON))), 338. "fell onto a sink", NO_KILLER_PREFIX); 339. exercise(A_DEX, FALSE); 340. for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) 341. if(obj->oclass == WEAPON_CLASS) { 342. You("fell on %s.",doname(obj)); 343. losehp(rn2(3),"fell onto a sink", NO_KILLER_PREFIX); 344. exercise(A_CON, FALSE); 345. } 346. # ifdef POLYSELF 347. } 348. # endif 349. 350. HLevitation = (HLevitation & ~TIMEOUT) + 1; 351. if(uleft && uleft->otyp == RIN_LEVITATION) { 352. obj = uleft; 353. Ring_off(obj); 354. off_msg(obj); 355. } 356. if(uright && uright->otyp == RIN_LEVITATION) { 357. obj = uright; 358. Ring_off(obj); 359. off_msg(obj); 360. } 361. if(uarmf && uarmf->otyp == LEVITATION_BOOTS) { 362. obj = uarmf; 363. (void)Boots_off(); 364. off_msg(obj); 365. } 366. HLevitation--; 367. } 368. #endif 369. 370. #endif /* OVLB */ 371. 372. #ifdef OVLB 373. 374. boolean 375. may_dig(x,y) 376. register xchar x,y; 377. /* intended to be called only on ROCKs */ 378. { 379. return (!(IS_STWALL(levl[x][y].typ) && (levl[x][y].diggable & W_NONDIGGABLE))); 380. } 381. 382. #endif /* OVLB */ 383. #ifdef OVL1 384. 385. STATIC_OVL boolean 386. bad_rock(x,y) 387. register xchar x,y; 388. { 389. return(IS_ROCK(levl[x][y].typ) 390. #ifdef POLYSELF 391. && !passes_walls(uasmon) 392. && (!tunnels(uasmon) || needspick(uasmon) || !may_dig(x,y)) 393. #endif 394. ); 395. } 396. 397. boolean 398. invocation_pos(x, y) 399. xchar x, y; 400. { 401. return(Invocation_lev(&u.uz) && x == inv_pos.x && y == inv_pos.y); 402. } 403. 404. #endif /* OVL1 */ 405. #ifdef OVL3 406. 407. void 408. domove() 409. { 410. register struct monst *mtmp; 411. register struct rm *tmpr,*ust; 412. register xchar x,y; 413. struct trap *trap; 414. int wtcap; 415. boolean on_ice; 416. xchar chainx, chainy, ballx, bally; /* ball&chain new positions */ 417. int bc_control; /* control for ball&chain */ 418. 419. u_wipe_engr(rnd(5)); 420. 421. if(((wtcap = near_capacity()) >= OVERLOADED 422. || (wtcap > SLT_ENCUMBER && (u.uhp < 10 && u.uhp != u.uhpmax))) 423. && !Is_airlevel(&u.uz)) { 424. if(wtcap < OVERLOADED) { 425. You("don't have enough stamina to move."); 426. exercise(A_CON, FALSE); 427. } else 428. You("collapse under your load."); 429. nomul(0); 430. return; 431. } 432. if(u.uswallow) { 433. u.dx = u.dy = 0; 434. u.ux = x = u.ustuck->mx; 435. u.uy = y = u.ustuck->my; 436. mtmp = u.ustuck; 437. } else { 438. if(Is_airlevel(&u.uz) && rn2(4) && !Levitation 439. #ifdef POLYSELF 440. && !is_flyer(uasmon) 441. #endif 442. ) { 443. switch(rn2(3)) { 444. case 0: 445. You("tumble in place."); 446. exercise(A_DEX, FALSE); 447. break; 448. case 1: 449. You("can't control your movements very well."); break; 450. case 2: 451. pline("It's hard to walk in thin air."); 452. exercise(A_DEX, TRUE); 453. break; 454. } 455. return; 456. } 457. 458. /* check slippery ice */ 459. on_ice = !Levitation && is_ice(u.ux, u.uy); 460. if (on_ice) { 461. static int skates = 0; 462. if (!skates) skates = find_skates(); 463. if ((uarmf && uarmf->otyp == skates) 464. #ifdef POLYSELF 465. || resists_cold(uasmon) || is_flyer(uasmon) 466. || is_floater(uasmon) || is_clinger(uasmon) 467. || is_whirly(uasmon) 468. #endif 469. ) on_ice = FALSE; 470. else if (!rn2(Cold_resistance ? 3 : 2)) { 471. Fumbling |= FROMOUTSIDE; 472. if (!(Fumbling & TIMEOUT)) Fumbling += rnd(20); 473. } 474. } 475. if (!on_ice && (Fumbling & FROMOUTSIDE)) { 476. Fumbling &= ~FROMOUTSIDE; 477. if (!(Fumbling & ~TIMEOUT)) Fumbling = 0; 478. } 479. 480. x = u.ux + u.dx; 481. y = u.uy + u.dy; 482. if(Stunned || (Confusion && !rn2(5))) { 483. register int tries = 0; 484. 485. do { 486. if(tries++ > 50) { 487. nomul(0); 488. return; 489. } 490. confdir(); 491. x = u.ux + u.dx; 492. y = u.uy + u.dy; 493. } while(!isok(x, y) || bad_rock(x, y)); 494. } 495. if(!isok(x, y)) { 496. nomul(0); 497. return; 498. } 499. if((trap = t_at(x, y)) && trap->tseen) { 500. if(flags.run >= 2) { 501. nomul(0); 502. flags.move = 0; 503. return; 504. } else 505. nomul(0); 506. } 507. 508. if(u.ustuck && (x != u.ustuck->mx || 509. y != u.ustuck->my)) { 510. if (distu(u.ustuck->mx, u.ustuck->my) > 2) { 511. /* perhaps it fled (or was teleported or ... ) */ 512. u.ustuck = 0; 513. } else { 514. #ifdef POLYSELF 515. /* If polymorphed into a sticking monster, 516. * u.ustuck means it's stuck to you, not you 517. * to it. 518. */ 519. if (sticks(uasmon)) { 520. You("release %s.", mon_nam(u.ustuck)); 521. u.ustuck = 0; 522. } else { 523. #endif 524. You("cannot escape from %s!", 525. mon_nam(u.ustuck)); 526. nomul(0); 527. return; 528. #ifdef POLYSELF 529. } 530. #endif 531. } 532. } 533. mtmp = m_at(x,y); 534. if (mtmp) { 535. /* Don't attack if you're running, and can see it */ 536. if (flags.run && 537. ((!Blind && mon_visible(mtmp) && 538. ((mtmp->m_ap_type != M_AP_FURNITURE && 539. mtmp->m_ap_type != M_AP_OBJECT) || 540. Protection_from_shape_changers)) || 541. sensemon(mtmp))) { 542. nomul(0); 543. flags.move = 0; 544. return; 545. } 546. } 547. } 548. 549. u.ux0 = u.ux; 550. u.uy0 = u.uy; 551. bhitpos.x = x; 552. bhitpos.y = y; 553. tmpr = &levl[x][y]; 554. 555. /* attack monster */ 556. if(mtmp) { 557. nomul(0); 558. /* only attack if we know it's there */ 559. /* or if it hides_under, in which case we call attack() to print 560. * the Wait! message. 561. * This is different from ceiling hiders, who aren't handled in 562. * attack(). 563. */ 564. if(!mtmp->mundetected || sensemon(mtmp) || 565. (hides_under(mtmp->data) && !is_safepet(mtmp))){ 566. gethungry(); 567. if(wtcap >= HVY_ENCUMBER && moves%3) { 568. if(u.uhp > 1) 569. u.uhp--; 570. else { 571. pline("You pass out from exertion!"); 572. exercise(A_CON, FALSE); 573. nomul(-10); 574. u.usleep = 1; 575. } 576. } 577. if(multi < 0) return; /* we just fainted */ 578. 579. /* try to attack; note that it might evade */ 580. /* also, we don't attack tame when _safepet_ */ 581. if(attack(mtmp)) return; 582. } 583. } 584. 585. /* not attacking an animal, so we try to move */ 586. #ifdef POLYSELF 587. if(!uasmon->mmove) { 588. You("are rooted %s.", 589. Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ? 590. "in place" : "to the ground"); 591. nomul(0); 592. return; 593. } 594. #endif 595. if(u.utrap) { 596. if(u.utraptype == TT_PIT) { 597. if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) { 598. Your("%s gets stuck in a crevice.", body_part(LEG)); 599. display_nhwindow(WIN_MESSAGE, FALSE); 600. clear_nhwindow(WIN_MESSAGE); 601. You("free your %s.", body_part(LEG)); 602. } else if (!(--u.utrap)) { 603. You("crawl to the edge of the pit."); 604. fill_pit(u.ux, u.uy); 605. vision_full_recalc = 1; /* vision limits change */ 606. } else if (flags.verbose) 607. Norep( (Hallucination && !rn2(5)) ? 608. "You've fallen, and you can't get up." : 609. "You are still in a pit." ); 610. } else if (u.utraptype == TT_LAVA) { 611. if(flags.verbose) 612. Norep("You are stuck in the lava."); 613. if(!is_lava(x,y)) { 614. u.utrap--; 615. if((u.utrap & 0xff) == 0) { 616. You("pull yourself to the edge of the lava."); 617. u.utrap = 0; 618. } 619. } 620. u.umoved = TRUE; 621. } else if (u.utraptype == TT_WEB) { 622. if(--u.utrap) { 623. if(flags.verbose) 624. Norep("You are stuck to the web."); 625. } else You("disentangle yourself."); 626. } else if (u.utraptype == TT_INFLOOR) { 627. if(--u.utrap) { 628. if(flags.verbose) 629. Norep("You are stuck in the floor."); 630. } else You("finally wiggle free."); 631. } else { 632. if(flags.verbose) 633. Norep("You are caught in a bear trap."); 634. if((u.dx && u.dy) || !rn2(5)) u.utrap--; 635. } 636. return; 637. } 638. 639. 640. /* 641. * Check for physical obstacles. First, the place we are going. 642. */ 643. if (IS_ROCK(tmpr->typ)) { 644. if (Blind) feel_location(x,y); 645. #ifdef POLYSELF 646. if (passes_walls(uasmon)) { 647. ; /* do nothing */ 648. } else if (tunnels(uasmon) && !needspick(uasmon)) { 649. /* Eat the rock. */ 650. if (still_chewing(x,y)) return; 651. } else { 652. #endif 653. if (Is_stronghold(&u.uz) && is_db_wall(x,y)) 654. pline("The drawbridge is up!"); 655. flags.move = 0; 656. nomul(0); 657. return; 658. #ifdef POLYSELF 659. } 660. #endif 661. } else if (IS_DOOR(tmpr->typ)) { 662. if (closed_door(x,y)) { 663. if (Blind) feel_location(x,y); 664. #ifdef POLYSELF 665. if (passes_walls(uasmon)) 666. ; /* do nothing */ 667. else if (amorphous(uasmon)) 668. You("ooze under the door."); 669. else if (tunnels(uasmon) && !needspick(uasmon)) { 670. /* Eat the door. */ 671. if (still_chewing(x,y)) return; 672. } else { 673. #endif 674. flags.move = 0; 675. if (x == u.ux || y == u.uy) { 676. if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) { 677. pline("Ouch! You bump into a door."); 678. exercise(A_DEX, FALSE); 679. } else pline("That door is closed."); 680. } 681. nomul(0); 682. return; 683. #ifdef POLYSELF 684. } 685. #endif 686. } else if (u.dx && u.dy 687. #ifdef POLYSELF 688. && !passes_walls(uasmon) 689. #endif 690. && ((tmpr->doormask & ~D_BROKEN) 691. #ifdef REINCARNATION 692. || Is_rogue_level(&u.uz) 693. #endif 694. || block_door(x,y))) { 695. /* Diagonal moves into a door are not allowed. */ 696. if (Blind) feel_location(x,y); /* ?? */ 697. flags.move = 0; 698. nomul(0); 699. return; 700. } 701. } 702. if (u.dx && u.dy && bad_rock(u.ux,y) && bad_rock(x,u.uy)) { 703. /* Move at a diagonal. */ 704. #ifdef POLYSELF 705. if (bigmonst(uasmon)) { 706. Your("body is too large to fit through."); 707. nomul(0); 708. return; 709. } 710. #endif 711. if (invent && inv_weight() > -400) { 712. You("are carrying too much to get through."); 713. nomul(0); 714. return; 715. } 716. } 717. 718. ust = &levl[u.ux][u.uy]; 719. 720. /* Now see if other things block our way . . */ 721. if (u.dx && u.dy 722. #ifdef POLYSELF 723. && !passes_walls(uasmon) 724. #endif 725. && (IS_DOOR(ust->typ) && ((ust->doormask & ~D_BROKEN) 726. #ifdef REINCARNATION 727. || Is_rogue_level(&u.uz) 728. #endif 729. || block_entry(x, y)) 730. )) { 731. /* Can't move at a diagonal out of a doorway with door. */ 732. flags.move = 0; 733. nomul(0); 734. return; 735. } 736. 737. if (sobj_at(BOULDER,x,y) 738. #ifdef POLYSELF 739. && !passes_walls(uasmon) 740. #endif 741. ) { 742. if (!(Blind || Hallucination) && (flags.run >= 2)) { 743. nomul(0); 744. flags.move = 0; 745. return; 746. } 747. #ifdef POLYSELF 748. /* tunneling monsters will chew before pushing */ 749. if (tunnels(uasmon) && !needspick(uasmon)) { 750. if (still_chewing(x,y)) return; 751. } else 752. #endif 753. if (moverock() < 0) return; 754. } 755. 756. /* OK, it is a legal place to move. */ 757. 758. /* Move ball and chain. */ 759. if (Punished) 760. if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy)) 761. return; 762. 763. /* now move the hero */ 764. mtmp = m_at(x, y); 765. if (u.uinwater) water_friction(); 766. u.ux += u.dx; 767. u.uy += u.dy; 768. /* if safepet at destination then move the pet to the hero's 769. * previous location using the same conditions as in attack(). 770. * there are special extenuating circumstances: 771. * (1) if the pet dies then your god angers, 772. * (2) if the pet gets trapped then your god may disapprove, 773. * (3) if the pet was already trapped and you attempt to free it 774. * not only do you encounter the trap but you may frighten your 775. * pet causing it to go wild! moral: don't abuse this privilege. 776. */ 777. /* Ceiling-hiding pets are skipped by this section of code, to 778. * be caught by the normal falling-monster code. 779. */ 780. if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) { 781. int swap_result; 782. 783. /* if trapped, there's a chance the pet goes wild */ 784. if (mtmp->mtrapped && !rn2(4)) { 785. pline ("%s suddenly goes wild!", 786. mtmp->mnamelth ? NAME(mtmp) : Monnam(mtmp)); 787. mtmp->mtame = mtmp->mpeaceful = mtmp->msleep = 0; 788. } 789. 790. mtmp->mtrapped = 0; 791. mtmp->mundetected = 0; 792. remove_monster(x, y); 793. place_monster(mtmp, u.ux0, u.uy0); 794. 795. /* check first to see if monster drowned. 796. * then check for traps. 797. */ 798. if (minwater(mtmp)) { 799. swap_result = 2; 800. } else swap_result = mintrap(mtmp); 801. 802. switch (swap_result) { 803. case 0: 804. You("%s %s.", mtmp->mtame ? "displaced" : "frightened", 805. mtmp->mnamelth ? NAME(mtmp) : mon_nam(mtmp)); 806. break; 807. case 1: /* trapped */ 808. case 3: /* changed levels */ 809. /* there's already been a trap message, reinforce it */ 810. pline("Trapping your pet was a selfish move."); 811. if (!rn2(4)) { 812. pline("You'll pay!"); 813. adjalign(-5); 814. } 815. break; 816. case 2: 817. /* it may have drowned or died. that's no way to 818. * treat a pet! your god gets angry and complains. 819. */ 820. if (rn2(4)) { 821. pline ("%s complains in a booming voice:", u_gname()); 822. verbalize("Losing your pet like this was a mistake!"); 823. u.ugangr++ ; 824. adjalign(-15); 825. } 826. break; 827. default: 828. pline("that's strange, unknown mintrap result!"); 829. break; 830. } 831. } 832. 833. reset_occupations(); 834. if(flags.run) { 835. if(IS_DOOR(tmpr->typ) || 836. #ifdef POLYSELF 837. (IS_ROCK(tmpr->typ)) || 838. #endif 839. (xupstair == u.ux && yupstair == u.uy) || 840. (xdnstair == u.ux && ydnstair == u.uy) 841. || (sstairs.sx == u.ux && sstairs.sy == u.uy) 842. || (xupladder == u.ux && yupladder == u.uy) 843. || (xdnladder == u.ux && ydnladder == u.uy) 844. || IS_FOUNTAIN(tmpr->typ) 845. || IS_THRONE(tmpr->typ) 846. #ifdef SINKS 847. || IS_SINK(tmpr->typ) 848. #endif 849. || IS_ALTAR(tmpr->typ) 850. ) 851. nomul(0); 852. } 853. #ifdef POLYSELF 854. if (hides_under(uasmon)) 855. u.uundetected = OBJ_AT(u.ux, u.uy); 856. else if (u.dx || u.dy) { /* piercer */ 857. if (u.usym == S_MIMIC_DEF) 858. u.usym = S_MIMIC; 859. u.uundetected = 0; 860. } 861. #endif 862. 863. #ifdef WALKIES 864. check_leash(u.ux0,u.uy0); 865. #endif 866. if(u.ux0 != u.ux || u.uy0 != u.uy) { 867. u.umoved = TRUE; 868. /* Clean old position -- vision_recalc() will print our new one. */ 869. newsym(u.ux0,u.uy0); 870. /* Since the hero has moved, adjust what can be seen/unseen. */ 871. vision_recalc(1); /* Do the work now in the recover time. */ 872. 873. /* a special clue-msg when on the Invocation position */ 874. if(invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) { 875. register struct obj *otmp; 876. 877. You("feel a strange vibration under your %s.", 878. makeplural(body_part(FOOT))); 879. 880. for(otmp = invent; otmp; otmp = otmp->nobj) { 881. if(otmp->otyp == CANDELABRUM_OF_INVOCATION && 882. otmp->spe == 7 && otmp->lamplit) { 883. pline("%s glows with a strange light!", 884. The(xname(otmp))); 885. break; 886. } 887. } 888. 889. } 890. } 891. 892. if (Punished) /* put back ball and chain */ 893. move_bc(0,bc_control,ballx,bally,chainx,chainy); 894. 895. spoteffects(); 896. } 897. 898. #endif /* OVL3 */ 899. #ifdef OVL2 900. 901. void 902. spoteffects() 903. { 904. register struct trap *trap; 905. register struct monst *mtmp; 906. 907. if(u.uinwater) { 908. int was_underwater; 909. 910. if (!is_pool(u.ux,u.uy)) { 911. if (Is_waterlevel(&u.uz)) 912. You("pop into an air bubble."); 913. else 914. You("are on solid ground again."); 915. } 916. else if (Is_waterlevel(&u.uz)) 917. goto stillinwater; 918. else if (Levitation || is_floater(uasmon)) 919. You("pop out of the water like a cork!"); 920. else if (is_flyer(uasmon)) 921. You("fly out of the water."); 922. else if (Wwalking) 923. You("slowly rise above the surface."); 924. else 925. goto stillinwater; 926. was_underwater = Underwater && !Is_waterlevel(&u.uz); 927. u.uinwater = 0; /* leave the water */ 928. if (was_underwater) { /* restore vision */ 929. docrt(); 930. vision_full_recalc = 1; 931. } 932. } 933. stillinwater:; 934. if(!Levitation && !u.ustuck 935. #ifdef POLYSELF 936. && !is_flyer(uasmon) 937. #endif 938. ) { 939. /* limit recursive calls through teleds() */ 940. if(is_lava(u.ux,u.uy) && lava_effects()) 941. return; 942. if(is_pool(u.ux,u.uy) && !Wwalking && drown()) 943. return; 944. } 945. check_special_room(FALSE); 946. #ifdef SINKS 947. if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 948. dosinkfall(); 949. #endif 950. if(!flags.nopick && OBJ_AT(u.ux, u.uy) && 951. (!is_pool(u.ux,u.uy) || Underwater)) 952. pickup(1); 953. else read_engr_at(u.ux,u.uy); 954. if(trap = t_at(u.ux,u.uy)) 955. dotrap(trap); /* fall into pit, arrow trap, etc. */ 956. if((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) { 957. mtmp->mundetected = 0; 958. switch(mtmp->data->mlet) { 959. case S_PIERCER: 960. pline("%s suddenly drops from the ceiling!", 961. Amonnam(mtmp)); 962. if(mtmp->mtame) /* jumps to greet you, not attack */ 963. ; 964. else if(uarmh) 965. pline("Its blow glances off your helmet."); 966. else if (u.uac + 3 <= rnd(20)) 967. You("are almost hit by %s!", 968. x_monnam(mtmp, 2, "falling", 1)); 969. else { 970. int dmg; 971. You("are hit by %s!", 972. x_monnam(mtmp, 2, "falling", 1)); 973. dmg = d(4,6); 974. if(Half_physical_damage) dmg = (dmg+1) / 2; 975. mdamageu(mtmp, dmg); 976. } 977. break; 978. default: /* monster surprises you. */ 979. if(mtmp->mtame) 980. pline("%s jumps near you from the ceiling.", 981. Amonnam(mtmp)); 982. else if(mtmp->mpeaceful) { 983. You("surprise %s!", 984. Blind && !sensemon(mtmp) ? 985. "something" : a_monnam(mtmp)); 986. mtmp->mpeaceful = 0; 987. } else 988. pline("%s attacks you by surprise!", 989. Amonnam(mtmp)); 990. break; 991. } 992. mnexto(mtmp); /* have to move the monster */ 993. } 994. } 995. 996. STATIC_OVL boolean 997. monstinroom(mdat,roomno) 998. struct permonst *mdat; 999. int roomno; 1000. { 1001. register struct monst *mtmp; 1002. 1003. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1004. if(mtmp->data == mdat && 1005. index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET)) 1006. return(TRUE); 1007. return(FALSE); 1008. } 1009. 1010. char * 1011. in_rooms(x, y, typewanted) 1012. register xchar x, y; 1013. register int typewanted; 1014. { 1015. static char buf[5]; 1016. char rno, *ptr = &buf[4]; 1017. int typefound, min_x, min_y, max_x, max_y_offset, step; 1018. register struct rm *lev; 1019. 1020. #define goodtype(rno) (!typewanted || \ 1021. ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) || \ 1022. ((typewanted == SHOPBASE) && (typefound > SHOPBASE))) \ 1023. 1024. switch (rno = levl[x][y].roomno) { 1025. case NO_ROOM: 1026. return(ptr); 1027. case SHARED: 1028. step = 2; 1029. break; 1030. case SHARED_PLUS: 1031. step = 1; 1032. break; 1033. default: /* i.e. a regular room # */ 1034. if (goodtype(rno)) 1035. *(--ptr) = rno; 1036. return(ptr); 1037. } 1038. 1039. min_x = x - 1; 1040. max_x = x + 1; 1041. if (x < 0) 1042. min_x += step; 1043. else 1044. if (x >= COLNO) 1045. max_x -= step; 1046. 1047. min_y = y - 1; 1048. max_y_offset = 2; 1049. if (min_y < 0) { 1050. min_y += step; 1051. max_y_offset -= step; 1052. } else 1053. if ((min_y + max_y_offset) >= ROWNO) 1054. max_y_offset -= step; 1055. 1056. for (x = min_x; x <= max_x; x += step) { 1057. lev = &levl[x][min_y]; 1058. y = 0; 1059. if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1060. !index(ptr, rno) && goodtype(rno)) 1061. *(--ptr) = rno; 1062. y += step; 1063. if (y > max_y_offset) 1064. continue; 1065. if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1066. !index(ptr, rno) && goodtype(rno)) 1067. *(--ptr) = rno; 1068. y += step; 1069. if (y > max_y_offset) 1070. continue; 1071. if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1072. !index(ptr, rno) && goodtype(rno)) 1073. *(--ptr) = rno; 1074. } 1075. return(ptr); 1076. } 1077. 1078. static void 1079. move_update(newlev) 1080. register boolean newlev; 1081. { 1082. char *ptr1, *ptr2, *ptr3, *ptr4; 1083. 1084. Strcpy(u.urooms0, u.urooms); 1085. Strcpy(u.ushops0, u.ushops); 1086. if (newlev) { 1087. u.urooms[0] = '\0'; 1088. u.uentered[0] = '\0'; 1089. u.ushops[0] = '\0'; 1090. u.ushops_entered[0] = '\0'; 1091. Strcpy(u.ushops_left, u.ushops0); 1092. return; 1093. } 1094. Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0)); 1095. 1096. for (ptr1 = &u.urooms[0], 1097. ptr2 = &u.uentered[0], 1098. ptr3 = &u.ushops[0], 1099. ptr4 = &u.ushops_entered[0]; 1100. *ptr1; ptr1++) { 1101. if (!index(u.urooms0, *ptr1)) 1102. *(ptr2++) = *ptr1; 1103. if (IS_SHOP(*ptr1 - ROOMOFFSET)) { 1104. *(ptr3++) = *ptr1; 1105. if (!index(u.ushops0, *ptr1)) 1106. *(ptr4++) = *ptr1; 1107. } 1108. } 1109. *ptr2 = '\0'; 1110. *ptr3 = '\0'; 1111. *ptr4 = '\0'; 1112. 1113. /* filter u.ushops0 -> u.ushops_left */ 1114. for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++) 1115. if (!index(u.ushops, *ptr1)) 1116. *(ptr2++) = *ptr1; 1117. *ptr2 = '\0'; 1118. } 1119. 1120. void 1121. check_special_room(newlev) 1122. register boolean newlev; 1123. { 1124. register struct monst *mtmp; 1125. char *ptr; 1126. 1127. move_update(newlev); 1128. 1129. if (*u.ushops0) 1130. u_left_shop(u.ushops_left, newlev); 1131. 1132. if (!*u.uentered && !*u.ushops_entered) 1133. return; /* no entrance messages necessary */ 1134. 1135. /* Did we just enter a shop? */ 1136. if (*u.ushops_entered) 1137. u_entered_shop(u.ushops_entered); 1138. 1139. for (ptr = &u.uentered[0]; *ptr; ptr++) { 1140. register int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype; 1141. 1142. /* Did we just enter some other special room? */ 1143. /* vault.c insists that a vault remain a VAULT, 1144. * and temples should remain TEMPLEs, 1145. * but everything else gives a message only the first time */ 1146. if(!newlev) 1147. switch (rt) { 1148. case ZOO: 1149. pline("Welcome to David's treasure zoo!"); 1150. break; 1151. case SWAMP: 1152. pline("It %s rather %s down here.", 1153. Blind ? "feels" : "looks", 1154. Blind ? "humid" : "muddy"); 1155. break; 1156. case COURT: 1157. You("enter an opulent throne room!"); 1158. break; 1159. case MORGUE: 1160. if(midnight()) 1161. pline("Run away! Run away!"); 1162. else 1163. You("have an uncanny feeling..."); 1164. break; 1165. case BEEHIVE: 1166. You("enter a giant beehive!"); 1167. break; 1168. #ifdef ARMY 1169. case BARRACKS: 1170. if(monstinroom(&mons[PM_SOLDIER], roomno) || 1171. monstinroom(&mons[PM_SERGEANT], roomno) || 1172. monstinroom(&mons[PM_LIEUTENANT], roomno) || 1173. monstinroom(&mons[PM_CAPTAIN], roomno)) 1174. You("enter a military barracks!"); 1175. else 1176. You("enter an abandoned barracks."); 1177. break; 1178. #endif 1179. case DELPHI: 1180. if(monstinroom(&mons[PM_ORACLE], roomno)) 1181. verbalize("Hello, %s, welcome to Delphi!", plname); 1182. break; 1183. case TEMPLE: 1184. intemple(roomno + ROOMOFFSET); 1185. /* fall through */ 1186. default: 1187. rt = 0; 1188. } 1189. else 1190. rt = 0; 1191. 1192. if(rt != 0) { 1193. rooms[roomno].rtype = OROOM; 1194. if (!search_special(rt)) { 1195. /* No more room of that type */ 1196. switch(rt) { 1197. case COURT: 1198. level.flags.has_court = 0; 1199. break; 1200. case SWAMP: 1201. level.flags.has_swamp = 0; 1202. break; 1203. case MORGUE: 1204. level.flags.has_morgue = 0; 1205. break; 1206. case ZOO: 1207. level.flags.has_zoo = 0; 1208. break; 1209. #ifdef ARMY 1210. case BARRACKS: 1211. level.flags.has_barracks = 0; 1212. break; 1213. #endif 1214. case TEMPLE: 1215. level.flags.has_temple = 0; 1216. break; 1217. case BEEHIVE: 1218. level.flags.has_beehive = 0; 1219. break; 1220. } 1221. } 1222. if(rt==COURT || rt==SWAMP || rt==MORGUE || rt==ZOO) 1223. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1224. if(!Stealth && !rn2(3)) 1225. mtmp->msleep = 0; 1226. } 1227. } 1228. 1229. return; 1230. } 1231. 1232. #endif /* OVL2 */ 1233. #ifdef OVLB 1234. 1235. int 1236. dopickup() 1237. { 1238. int count; 1239. /* awful kludge to work around parse()'s pre-decrement */ 1240. count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0; 1241. multi = 0; /* always reset */ 1242. /* uswallow case added by GAN 01/29/87 */ 1243. if(u.uswallow) { 1244. if (is_animal(u.ustuck->data)) { 1245. You("pick up %s tongue.", 1246. s_suffix(mon_nam(u.ustuck))); 1247. pline("But it's kind of slimy, so you drop it."); 1248. } else 1249. You("don't %s anything in here to pick up.", 1250. Blind ? "feel" : "see"); 1251. return(1); 1252. } 1253. if(!OBJ_AT(u.ux, u.uy)) { 1254. pline("There is nothing here to pick up."); 1255. return(0); 1256. } 1257. if(Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) { 1258. You("cannot reach the floor."); 1259. return(1); 1260. } 1261. if(is_pool(u.ux, u.uy)) { 1262. if(Wwalking 1263. #ifdef POLYSELF 1264. || is_flyer(uasmon) || is_clinger(uasmon) 1265. #endif 1266. ) { 1267. You("cannot dive into the water to pick things up."); 1268. return(1); 1269. } 1270. else if(!Underwater) { 1271. You("can't even see the bottom, let alone pick up something."); 1272. return(1); 1273. } 1274. } 1275. pickup(-count); 1276. return(1); 1277. } 1278. 1279. #endif /* OVLB */ 1280. #ifdef OVL2 1281. 1282. /* stop running if we see something interesting */ 1283. /* turn around a corner if that is the only way we can proceed */ 1284. /* do not turn left or right twice */ 1285. void 1286. lookaround() 1287. { 1288. register int x, y, i, x0 = 0, y0 = 0, m0 = 1, i0 = 9; 1289. register int corrct = 0, noturn = 0; 1290. register struct monst *mtmp; 1291. register struct trap *trap; 1292. 1293. #ifdef POLYSELF 1294. /* Grid bugs stop if trying to move diagonal, even if blind. Maybe */ 1295. /* they polymorphed while in the middle of a long move. */ 1296. if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) { 1297. nomul(0); 1298. return; 1299. } 1300. #endif 1301. if(Blind || flags.run == 0) return; 1302. for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) { 1303. if(!isok(x,y)) continue; 1304. #ifdef POLYSELF 1305. if(u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy) continue; 1306. #endif 1307. if(x == u.ux && y == u.uy) continue; 1308. 1309. if((mtmp = m_at(x,y)) && 1310. mtmp->m_ap_type != M_AP_FURNITURE && 1311. mtmp->m_ap_type != M_AP_OBJECT && 1312. (!mtmp->minvis || See_invisible) && !mtmp->mundetected) { 1313. if((flags.run != 1 && !mtmp->mtame) 1314. || (x == u.ux+u.dx && y == u.uy+u.dy)) 1315. goto stop; 1316. } 1317. 1318. if (levl[x][y].typ == STONE) continue; 1319. if (x == u.ux-u.dx && y == u.uy-u.dy) continue; 1320. 1321. if (IS_ROCK(levl[x][y].typ) || (levl[x][y].typ == ROOM) || 1322. IS_AIR(levl[x][y].typ)) 1323. continue; 1324. else if (closed_door(x,y)) { 1325. if(x != u.ux && y != u.uy) continue; 1326. if(flags.run != 1) goto stop; 1327. goto bcorr; 1328. } else if (levl[x][y].typ == CORR) { 1329. bcorr: 1330. if(levl[u.ux][u.uy].typ != ROOM) { 1331. if(flags.run == 1 || flags.run == 3) { 1332. i = dist2(x,y,u.ux+u.dx,u.uy+u.dy); 1333. if(i > 2) continue; 1334. if(corrct == 1 && dist2(x,y,x0,y0) != 1) 1335. noturn = 1; 1336. if(i < i0) { 1337. i0 = i; 1338. x0 = x; 1339. y0 = y; 1340. m0 = mtmp ? 1 : 0; 1341. } 1342. } 1343. corrct++; 1344. } 1345. continue; 1346. } else if ((trap = t_at(x,y)) && trap->tseen) { 1347. if(flags.run == 1) goto bcorr; /* if you must */ 1348. if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 1349. continue; 1350. } else if (is_pool(x,y) || is_lava(x,y)) { 1351. /* water and lava only stop you if directly in front, and stop 1352. * you even if you are running 1353. */ 1354. if(!Levitation && 1355. #ifdef POLYSELF 1356. !is_flyer(uasmon) && !is_clinger(uasmon) && 1357. #endif 1358. /* No Wwalking check; otherwise they'd be able 1359. * to test boots by trying to SHIFT-direction 1360. * into a pool and seeing if the game allowed it 1361. */ 1362. x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 1363. continue; 1364. } else { /* e.g. objects or trap or stairs */ 1365. if(flags.run == 1) goto bcorr; 1366. if(mtmp) continue; /* d */ 1367. if(((x == u.ux - u.dx) && (y != u.uy + u.dy)) || 1368. ((y == u.uy - u.dy) && (x != u.ux + u.dx))) 1369. continue; 1370. } 1371. stop: 1372. nomul(0); 1373. return; 1374. } /* end for loops */ 1375. 1376. if(corrct > 1 && flags.run == 2) goto stop; 1377. if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && 1378. (corrct == 1 || (corrct == 2 && i0 == 1))) { 1379. /* make sure that we do not turn too far */ 1380. if(i0 == 2) { 1381. if(u.dx == y0-u.uy && u.dy == u.ux-x0) 1382. i = 2; /* straight turn right */ 1383. else 1384. i = -2; /* straight turn left */ 1385. } else if(u.dx && u.dy) { 1386. if((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy)) 1387. i = -1; /* half turn left */ 1388. else 1389. i = 1; /* half turn right */ 1390. } else { 1391. if((x0-u.ux == y0-u.uy && !u.dy) || (x0-u.ux != y0-u.uy && u.dy)) 1392. i = 1; /* half turn right */ 1393. else 1394. i = -1; /* half turn left */ 1395. } 1396. 1397. i += u.last_str_turn; 1398. if(i <= 2 && i >= -2) { 1399. u.last_str_turn = i; 1400. u.dx = x0-u.ux; 1401. u.dy = y0-u.uy; 1402. } 1403. } 1404. } 1405. 1406. /* something like lookaround, but we are not running */ 1407. /* react only to monsters that might hit us */ 1408. int 1409. monster_nearby() 1410. { 1411. register int x,y; 1412. register struct monst *mtmp; 1413. 1414. if(!Blind) 1415. for(x = u.ux-1; x <= u.ux+1; x++) 1416. for(y = u.uy-1; y <= u.uy+1; y++) { 1417. if(!isok(x,y)) continue; 1418. if(x == u.ux && y == u.uy) continue; 1419. if((mtmp = m_at(x,y)) && 1420. mtmp->m_ap_type != M_AP_FURNITURE && 1421. mtmp->m_ap_type != M_AP_OBJECT && 1422. !mtmp->mpeaceful && 1423. (!is_hider(mtmp->data) || !mtmp->mundetected) && 1424. !noattacks(mtmp->data) && 1425. mtmp->mcanmove && !mtmp->msleep && /* aplvax!jcn */ 1426. (!mtmp->minvis || See_invisible) && 1427. !onscary(u.ux, u.uy, mtmp)) 1428. return(1); 1429. } 1430. return(0); 1431. } 1432. 1433. void 1434. nomul(nval) 1435. register int nval; 1436. { 1437. if(multi < nval) return; /* This is a bug fix by ab@unido */ 1438. u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */ 1439. u.usleep = 0; 1440. multi = nval; 1441. flags.mv = flags.run = 0; 1442. } 1443. 1444. #endif /* OVL2 */ 1445. #ifdef OVL1 1446. 1447. void 1448. losehp(n, knam, k_format) 1449. register int n; 1450. register const char *knam; 1451. boolean k_format; 1452. { 1453. #ifdef POLYSELF 1454. if (u.mtimedone) { 1455. u.mh -= n; 1456. if (u.mhmax < u.mh) u.mhmax = u.mh; 1457. flags.botl = 1; 1458. if (u.mh < 1) rehumanize(); 1459. return; 1460. } 1461. #endif 1462. u.uhp -= n; 1463. if(u.uhp > u.uhpmax) 1464. u.uhpmax = u.uhp; /* perhaps n was negative */ 1465. flags.botl = 1; 1466. if(u.uhp < 1) { 1467. killer_format = k_format; 1468. killer = knam; /* the thing that killed you */ 1469. You("die..."); 1470. done(DIED); 1471. } else if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50 && n > 0){ 1472. wailmsg = moves; 1473. if(index("WEV", pl_character[0])) { 1474. if (u.uhp == 1) 1475. pline("%s is about to die.", pl_character); 1476. else if (4 <= (!!(HTeleportation & INTRINSIC)) + 1477. (!!(HSee_invisible & INTRINSIC)) + 1478. (!!(HPoison_resistance & INTRINSIC)) + 1479. (!!(HCold_resistance & INTRINSIC)) + 1480. (!!(HShock_resistance & INTRINSIC)) + 1481. (!!(HFire_resistance & INTRINSIC)) + 1482. (!!(HSleep_resistance & INTRINSIC)) + 1483. (!!(HDisint_resistance & INTRINSIC)) + 1484. (!!(HTeleport_control & INTRINSIC)) + 1485. (!!(Stealth & INTRINSIC)) + 1486. (!!(Fast & INTRINSIC)) + 1487. (!!(HInvis & INTRINSIC))) 1488. pline("%s, all your powers will be lost...", 1489. pl_character); 1490. else 1491. pline("%s, your life force is running out.", 1492. pl_character); 1493. } else { 1494. if(u.uhp == 1) 1495. You("hear the wailing of the Banshee..."); 1496. else 1497. You("hear the howling of the CwnAnnwn..."); 1498. } 1499. } 1500. } 1501. 1502. int 1503. weight_cap() 1504. { 1505. register long carrcap; 1506. 1507. carrcap = (((ACURRSTR + ACURR(A_CON))/2)+1)*50; 1508. #ifdef POLYSELF 1509. if (u.mtimedone) { 1510. /* consistent with can_carry() in mon.c */ 1511. if (u.usym == S_NYMPH) 1512. carrcap = MAX_CARR_CAP; 1513. else if (!uasmon->cwt) 1514. carrcap = (carrcap * (long)uasmon->msize) / MZ_HUMAN; 1515. else if (!strongmonst(uasmon) 1516. || (strongmonst(uasmon) && (uasmon->cwt > WT_HUMAN))) 1517. carrcap = (carrcap * (long)uasmon->cwt / WT_HUMAN); 1518. } 1519. #endif 1520. if(Levitation || Is_airlevel(&u.uz)) /* pugh@cornell */ 1521. carrcap = MAX_CARR_CAP; 1522. else { 1523. if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 1524. if(Wounded_legs & LEFT_SIDE) carrcap -= 100; 1525. if(Wounded_legs & RIGHT_SIDE) carrcap -= 100; 1526. } 1527. return((int) carrcap); 1528. } 1529. 1530. /* returns how far beyond the normal capacity the player is currently. */ 1531. /* inv_weight() is negative if the player is below normal capacity. */ 1532. int 1533. inv_weight() 1534. { 1535. register struct obj *otmp = invent; 1536. #ifdef LINT /* long to int conversion */ 1537. register int wt = 0; 1538. #else 1539. register int wt = (int)((u.ugold + 50L)/100L); 1540. #endif /* LINT */ 1541. while(otmp){ 1542. #ifdef POLYSELF 1543. if (otmp->otyp != BOULDER || !throws_rocks(uasmon)) 1544. #endif 1545. wt += otmp->owt; 1546. otmp = otmp->nobj; 1547. } 1548. return(wt - weight_cap()); 1549. } 1550. 1551. /* 1552. * Returns 0 if below normal capacity, or the number of "capacity units" 1553. * over the normal capacity the player is loaded. Max is 5. 1554. */ 1555. int 1556. near_capacity() 1557. { 1558. int cap, wt = inv_weight(); 1559. 1560. if (wt < 0) return UNENCUMBERED; 1561. cap = (wt / (weight_cap()/2)) + 1; 1562. return min(cap, OVERLOADED); 1563. } 1564. 1565. int 1566. max_capacity() 1567. { 1568. return(inv_weight() - (2 * weight_cap())); 1569. } 1570. 1571. boolean 1572. check_capacity(str) 1573. const char *str; 1574. { 1575. if(near_capacity() >= EXT_ENCUMBER) { 1576. if(str) 1577. pline(str); 1578. else 1579. You("can't do that while carrying so much stuff."); 1580. return 1; 1581. } 1582. return 0; 1583. } 1584. 1585. #endif /* OVL1 */ 1586. #ifdef OVLB 1587. 1588. int 1589. inv_cnt() 1590. { 1591. register struct obj *otmp = invent; 1592. register int ct = 0; 1593. 1594. while(otmp){ 1595. ct++; 1596. otmp = otmp->nobj; 1597. } 1598. return(ct); 1599. } 1600. 1601. int 1602. identify(otmp) /* also called by newmail() */ 1603. register struct obj *otmp; 1604. { 1605. makeknown(otmp->otyp); 1606. otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; 1607. prinv(NULL, otmp, 0L); 1608. return(1); 1609. } 1610. 1611. #endif /* OVLB */ 1612. 1613. /*hack.c*/