Source:NetHack 3.0.0/hack.c
(Redirected from NetHack 3.0.0/hack.c)
Jump to navigation
Jump to search
Below is the full text to hack.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2. /* NetHack may be freely redistributed. See license for details. */ 3. 4. #include "hack.h" 5. 6. #if defined(UNIX) && !defined(LINT) 7. static const char SCCS_Id[] = "@(#)hack.c 3.0\t88/10/25"; 8. #endif 9. 10. /* called on movement: 11. 1. when throwing ball+chain far away 12. 2. when teleporting 13. 3. when walking out of a lit room 14. */ 15. void 16. unsee() { 17. register xchar x,y; 18. register struct rm *lev; 19. 20. if(seehx){ 21. seehx = 0; 22. } else 23. for(x = u.ux-1; x < u.ux+2; x++) 24. for(y = u.uy-1; y < u.uy+2; y++) { 25. if(!isok(x, y)) continue; 26. lev = &levl[x][y]; 27. if(!lev->lit && lev->scrsym == ROOM_SYM) { 28. lev->scrsym = STONE_SYM; 29. lev->new = 1; 30. on_scr(x,y); 31. } 32. } 33. } 34. 35. /* called: 36. in apply.c: seeoff(0) - when taking a picture of yourself 37. - when donning a blindfold 38. in do.c: seeoff(0) - blind after drinking potion 39. in do.c: seeoff(1) - go up or down the stairs 40. in eat.c: seeoff(0) - blind after eating rotten food 41. in mhitu.c: seeoff(0) - blinded by a glowing eye 42. in mhitu.c: seeoff(1) - swallowed 43. in mthrow.c: seeoff(0) - hit by a cream pie. 44. in potion.c: seeoff(0) - quaffing or sniffing a potion of blindness 45. in spell.c: seeoff(0) - due to a cursed spellbook 46. in trap.c: seeoff(1) - fall through trapdoor 47. */ 48. void 49. seeoff(mode) { /* 1 to redo @, 0 to leave them */ 50. /* 1 means misc movement, 0 means blindness */ 51. register xchar x,y; 52. register struct rm *lev; 53. 54. if(u.udispl && mode){ 55. u.udispl = 0; 56. levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); 57. } 58. if(seehx) { 59. seehx = 0; 60. } else 61. if(!mode) { 62. for(x = u.ux-1; x < u.ux+2; x++) 63. for(y = u.uy-1; y < u.uy+2; y++) { 64. if(!isok(x, y)) continue; 65. lev = &levl[x][y]; 66. if(lev->mmask) unpmon(m_at(x,y)); 67. if(!lev->lit && lev->scrsym == ROOM_SYM) { 68. lev->seen = 0; 69. atl(x, y, (char)STONE_SYM); 70. } 71. } 72. } 73. } 74. 75. static int 76. moverock() { 77. register xchar rx, ry; 78. register struct obj *otmp; 79. register struct trap *ttmp; 80. register struct monst *mtmp; 81. xchar oldrx, oldry; 82. 83. #ifdef POLYSELF 84. if (passes_walls(uasmon)) return 0; 85. #endif 86. while(otmp = sobj_at(BOULDER, u.ux+u.dx, u.uy+u.dy)) { 87. rx = u.ux+2*u.dx; 88. ry = u.uy+2*u.dy; 89. nomul(0); 90. #ifdef POLYSELF 91. if (verysmall(uasmon)) { 92. pline("You're too small to push that boulder."); 93. goto cannot_push; 94. } 95. #endif 96. if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) && 97. (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy)) && 98. !sobj_at(BOULDER, rx, ry)) { 99. if(levl[rx][ry].mmask) { 100. mtmp = m_at(rx,ry); 101. if(canseemon(mtmp)) 102. pline("There's %s on the other side.", 103. mon_nam(mtmp)); 104. else 105. You("hear a monster behind the boulder."); 106. if(flags.verbose) 107. pline("Perhaps that's why you cannot move it."); 108. goto cannot_push; 109. } 110. if(ttmp = t_at(rx,ry)) 111. switch(ttmp->ttyp) { 112. case SPIKED_PIT: 113. case PIT: 114. You("push the boulder into a pit!"); 115. deltrap(ttmp); 116. delobj(otmp); 117. if(flags.verbose) 118. pline("It completely fills the pit!"); 119. continue; 120. case TRAPDOOR: 121. pline("The boulder falls into and plugs a hole in the ground!"); 122. deltrap(ttmp); 123. delobj(otmp); 124. continue; 125. case LEVEL_TELEP: 126. case TELEP_TRAP: 127. You("push the boulder and suddenly it disappears!"); 128. rloco(otmp); 129. continue; 130. } 131. if(levl[rx][ry].typ == DOOR && 132. (levl[rx][ry].doormask & (D_LOCKED | D_CLOSED))) 133. goto nopushmsg; 134. if(is_pool(rx,ry)) { 135. #ifdef STRONGHOLD 136. if(levl[rx][ry].typ == DRAWBRIDGE_UP) 137. levl[rx][ry].drawbridgemask |= DB_FLOOR; 138. else 139. #endif 140. levl[rx][ry].typ = ROOM; 141. mnewsym(rx,ry); 142. if(!Blind) prl(rx,ry); 143. You("push the boulder into the water."); 144. if(flags.verbose && !Blind) 145. pline("Now you can cross the water!"); 146. delobj(otmp); 147. continue; 148. } 149. oldrx = otmp->ox; 150. oldry = otmp->oy; 151. otmp->ox = rx; 152. otmp->oy = ry; 153. set_omask(oldrx, oldry); 154. levl[rx][ry].omask = 1; 155. /* pobj(otmp); */ 156. if(cansee(rx,ry)) atl(rx,ry,otmp->olet); 157. newsym(u.ux+u.dx, u.uy+u.dy); 158. 159. { 160. #ifdef LINT /* static long lastmovetime; */ 161. long lastmovetime; 162. lastmovetime = 0; 163. #else 164. static long lastmovetime; 165. #endif 166. /* note: this var contains garbage initially and 167. after a restore */ 168. if(moves > lastmovetime+2 || moves < lastmovetime) 169. pline("With great effort you move the boulder."); 170. lastmovetime = moves; 171. } 172. } else { 173. nopushmsg: 174. You("try to move the boulder, but in vain."); 175. cannot_push: 176. #ifdef POLYSELF 177. if (throws_rocks(uasmon)) { 178. if(!flags.pickup) 179. pline("However, you easily can push it aside."); 180. else 181. pline("However, you easily can pick it up."); 182. break; 183. } 184. #endif 185. if((!invent || inv_weight()+90 <= 0) && 186. (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ) 187. && IS_ROCK(levl[u.ux+u.dx][u.uy].typ))) 188. #ifdef POLYSELF 189. || verysmall(uasmon) 190. #endif 191. ) 192. { 193. pline("However, you can squeeze yourself into a small opening."); 194. break; 195. } else 196. return (-1); 197. } 198. } 199. return (0); 200. } 201. 202. void 203. movobj(obj, ox, oy) 204. register struct obj *obj; 205. register xchar ox, oy; 206. { 207. register xchar ox2 = obj->ox, oy2= obj->oy; 208. 209. /* Some dirty programming to get display right */ 210. freeobj(obj); 211. unpobj(obj); 212. obj->nobj = fobj; 213. fobj = obj; 214. obj->ox = ox; 215. obj->oy = oy; 216. set_omask(ox2,oy2); 217. levl[ox][oy].omask = 1; 218. } 219. 220. #ifdef SINKS 221. static 222. void 223. dosinkfall() { 224. register struct obj *obj; 225. 226. # ifdef POLYSELF 227. if (is_floater(uasmon)) { 228. You("wobble unsteadily for a moment."); 229. } else { 230. # endif 231. You("crash to the floor!"); 232. losehp((rn1(10, 20 - (int)ACURR(A_CON))),"fall onto a sink"); 233. if(levl[u.ux][u.uy].omask) 234. for(obj=fobj; obj; obj=obj->nobj) 235. if(obj->ox == u.ux && obj->oy == u.uy && 236. obj->olet == WEAPON_SYM) { 237. You("fell on %s.",doname(obj)); 238. losehp(rn2(3),"fall onto a sink"); 239. } 240. # ifdef POLYSELF 241. } 242. # endif 243. 244. HLevitation = (HLevitation & ~TIMEOUT) + 1; 245. if(uleft && uleft->otyp == RIN_LEVITATION) { 246. obj = uleft; 247. Ring_off(obj); 248. off_msg(obj); 249. } 250. if(uright && uright->otyp == RIN_LEVITATION) { 251. obj = uright; 252. Ring_off(obj); 253. off_msg(obj); 254. } 255. if(uarmf && uarmf->otyp == LEVITATION_BOOTS) { 256. obj = uarmf; 257. (void)Boots_off(); 258. off_msg(obj); 259. } 260. HLevitation--; 261. } 262. #endif 263. 264. static boolean 265. is_edge(x,y) 266. register xchar x,y; 267. /* return true if (x,y) is on the edge of a room 268. * we cannot rely on IS_DOOR(levl[x][y].typ) because some of the stronghold 269. * "rooms" are actually outside areas without doors 270. */ 271. { 272. register int roomno = inroom(x,y); 273. 274. if(roomno < 0) return FALSE; 275. return((x == rooms[roomno].lx - 1) || (x == rooms[roomno].hx + 1) || 276. (y == rooms[roomno].ly - 1) || (y == rooms[roomno].hy + 1)); 277. } 278. 279. boolean 280. may_dig(x,y) 281. register xchar x,y; 282. /* intended to be called only on ROCKs */ 283. { 284. return (!(IS_STWALL(levl[x][y].typ) && (levl[x][y].diggable & W_NONDIGGABLE))); 285. } 286. 287. static boolean 288. bad_rock(x,y) 289. register xchar x,y; 290. { 291. return(IS_ROCK(levl[x][y].typ) 292. #ifdef POLYSELF 293. && !passes_walls(uasmon) 294. && (!tunnels(uasmon) || needspick(uasmon) || !may_dig(x,y)) 295. #endif 296. ); 297. } 298. 299. void 300. domove() { 301. register struct monst *mtmp = (struct monst *)0; 302. register struct rm *tmpr,*ust; 303. register xchar x,y; 304. struct trap *trap; 305. 306. u_wipe_engr(rnd(5)); 307. 308. if(inv_weight() > 0){ 309. You("collapse under your load."); 310. nomul(0); 311. return; 312. } 313. if(u.uswallow) { 314. u.dx = u.dy = 0; 315. x = u.ux = u.ustuck->mx; 316. y = u.uy = u.ustuck->my; 317. } else { 318. x = u.ux + u.dx; 319. y = u.uy + u.dy; 320. if(Stunned || (Confusion && !rn2(5))) { 321. register int tries = 0; 322. 323. do { 324. if(tries++ > 50) { 325. nomul(0); 326. return; 327. } 328. confdir(); 329. x = u.ux + u.dx; 330. y = u.uy + u.dy; 331. } while(!isok(x, y) || bad_rock(x, y)); 332. } 333. if(!isok(x, y)) { 334. nomul(0); 335. return; 336. } 337. if((trap = t_at(x, y)) && trap->tseen) 338. nomul(0); 339. if(u.ustuck && (x != u.ustuck->mx || 340. y != u.ustuck->my)) { 341. if(dist(u.ustuck->mx, u.ustuck->my) > 2) { 342. /* perhaps it fled (or was teleported or ... ) */ 343. u.ustuck = 0; 344. } else { 345. #ifdef POLYSELF 346. /* If polymorphed into a sticking monster, 347. * u.ustuck means it's stuck to you, not you 348. * to it. 349. */ 350. if (sticks(uasmon)) { 351. kludge("You release %s.", 352. mon_nam(u.ustuck)); 353. u.ustuck = 0; 354. } else { 355. #endif 356. kludge("You cannot escape from %s!", 357. mon_nam(u.ustuck)); 358. nomul(0); 359. return; 360. #ifdef POLYSELF 361. } 362. #endif 363. } 364. } 365. } 366. 367. u.ux0 = u.ux; 368. u.uy0 = u.uy; 369. /* attack monster */ 370. tmpr = &levl[x][y]; 371. if (tmpr->mmask) { 372. mtmp = m_at(x,y); 373. /* Don't attack if you're running */ 374. if (flags.run && !mtmp->mimic && 375. (Blind ? Telepat : (!mtmp->minvis || See_invisible))) { 376. nomul(0); 377. flags.move = 0; 378. return; 379. } 380. } 381. if(mtmp || u.uswallow) { 382. nomul(0); 383. gethungry(); 384. if(multi < 0) return; /* we just fainted */ 385. 386. /* try to attack; note that it might evade */ 387. if(attack(u.uswallow ? u.ustuck : mtmp)) 388. return; 389. } 390. /* not attacking an animal, so we try to move */ 391. #ifdef POLYSELF 392. if(!uasmon->mmove) { 393. You("are rooted %s.", Levitation ? "in place" 394. : "to the ground"); 395. nomul(0); 396. return; 397. } 398. #endif 399. if(u.utrap) { 400. if(u.utraptype == TT_PIT) { 401. if(flags.verbose) 402. You("are still in a pit."); 403. u.utrap--; 404. } else if (u.utraptype == TT_WEB) { 405. if(flags.verbose) 406. You("are stuck to the web."); 407. u.utrap--; 408. } else { 409. if(flags.verbose) 410. You("are caught in a bear trap."); 411. if((u.dx && u.dy) || !rn2(5)) u.utrap--; 412. } 413. return; 414. } 415. /* check for physical obstacles */ 416. #ifdef POLYSELF 417. if (!passes_walls(uasmon)) { 418. #endif 419. #ifdef STRONGHOLD 420. if(dlevel == stronghold_level && is_db_wall(x,y)) { 421. pline("The drawbridge is up!"); 422. nomul(0); 423. return; 424. } 425. #endif 426. if(IS_DOOR(tmpr->typ) && (tmpr->doormask & (D_LOCKED | D_CLOSED)) 427. #ifdef POLYSELF 428. && !amorphous(uasmon) 429. #endif 430. ){ 431. flags.move = 0; 432. if(x == u.ux || y == u.uy) { 433. if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) 434. pline("Ouch! You bump into a door."); 435. else pline("That door is closed."); 436. } 437. nomul(0); 438. return; 439. } 440. #ifdef POLYSELF 441. } 442. #endif 443. ust = &levl[u.ux][u.uy]; 444. if(bad_rock(x,y) || 445. (u.dx && u.dy && (IS_DOOR(tmpr->typ) || IS_DOOR(ust->typ)))){ 446. flags.move = 0; 447. nomul(0); 448. return; 449. } 450. if(moverock() < 0) return; 451. if(u.dx && u.dy && bad_rock(u.ux,y) && 452. bad_rock(x,u.uy)) { 453. #ifdef POLYSELF 454. if (bigmonst(uasmon)) { 455. Your("body is too large to fit through."); 456. nomul(0); 457. return; 458. } 459. #endif 460. if (invent && inv_weight()+40 > 0) { 461. You("are carrying too much to get through."); 462. nomul(0); 463. return; 464. } 465. } 466. if(Punished && 467. dist2(x, y, uchain->ox, uchain->oy) > 2) { 468. if(carried(uball)) { 469. movobj(uchain, u.ux, u.uy); 470. goto nodrag; 471. } 472. 473. if(dist2(x, y, uball->ox, uball->oy) < 3) { 474. /* leave ball, move chain under/over ball */ 475. movobj(uchain, uball->ox, uball->oy); 476. goto nodrag; 477. } 478. 479. if(inv_weight() + (int)(uball->owt >> 1) > 0) { 480. You("cannot %sdrag the heavy iron ball.", 481. invent ? "carry all that and also " : ""); 482. nomul(0); 483. return; 484. } 485. 486. movobj(uball, uchain->ox, uchain->oy); 487. unpobj(uball); /* BAH %% */ 488. uchain->ox = u.ux; 489. uchain->oy = u.uy; 490. ust->omask = 1; 491. nomul(-2); 492. nomovemsg = ""; 493. nodrag: ; 494. } 495. #ifdef POLYSELF 496. if (tunnels(uasmon) && !needspick(uasmon) && IS_ROCK(tmpr->typ)) { 497. static char *digtxt; 498. 499. if(dig_pos.x != x || dig_pos.y != y 500. || dig_level != dlevel || dig_down) { 501. dig_down = FALSE; 502. dig_pos.x = x; 503. dig_pos.y = y; 504. dig_level = dlevel; 505. dig_effort = 30; 506. You("start chewing a hole in the rock."); 507. return; 508. } else if ((dig_effort += 30) < 100) { 509. if(flags.verbose) 510. You("continue chewing the rock up."); 511. return; 512. } else { 513. if (IS_WALL(tmpr->typ)) { 514. digtxt = "You chew a hole in the wall."; 515. tmpr->typ = DOOR; 516. } else if (tmpr->typ==SDOOR) { 517. digtxt = "You chew through a secret door."; 518. tmpr->typ = DOOR; 519. if(!(tmpr->doormask & D_TRAPPED)) 520. tmpr->doormask = D_BROKEN; 521. } else { 522. digtxt = "You chew a passage through the rock."; 523. tmpr->typ = CORR; 524. } 525. mnewsym(x, y); 526. prl(x, y); 527. pline(digtxt); 528. if(IS_DOOR(tmpr->typ) && (tmpr->doormask & D_TRAPPED)) { 529. b_trapped("door"); 530. tmpr->doormask = D_NODOOR; 531. } 532. dig_level = -1; 533. } 534. } 535. #endif 536. u.ux += u.dx; 537. u.uy += u.dy; 538. if(flags.run) { 539. if(IS_DOOR(tmpr->typ) || 540. #ifdef POLYSELF 541. (IS_ROCK(tmpr->typ)) || 542. #endif 543. (xupstair == u.ux && yupstair == u.uy) || 544. (xdnstair == u.ux && ydnstair == u.uy) 545. #ifdef STRONGHOLD 546. || (xupladder == u.ux && yupladder == u.uy) 547. || (xdnladder == u.ux && ydnladder == u.uy) 548. #endif 549. #ifdef FOUNTAINS 550. || IS_FOUNTAIN(tmpr->typ) 551. #endif 552. #ifdef THRONES 553. || IS_THRONE(tmpr->typ) 554. #endif 555. #ifdef SINKS 556. || IS_SINK(tmpr->typ) 557. #endif 558. #ifdef ALTARS 559. || IS_ALTAR(tmpr->typ) 560. #endif 561. ) 562. nomul(0); 563. } 564. #ifdef POLYSELF 565. if (hides_under(uasmon)) 566. u.uundetected = (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask); 567. else if (u.dx || u.dy) { /* i.e. piercer */ 568. if (u.usym == S_MIMIC_DEF) 569. u.usym = S_MIMIC; 570. u.uundetected = 0; 571. } 572. #endif 573. 574. /* 575. if(u.udispl) { 576. u.udispl = 0; 577. newsym(u.ux0,u.uy0); 578. } 579. */ 580. if(!Blind) { 581. register xchar backx = u.ux0 - u.dx; /* one step beyond old pos */ 582. register xchar backy = u.uy0 - u.dy; 583. register xchar frontx = u.ux + u.dx; /* one step beyond new pos */ 584. register xchar fronty = u.uy + u.dy; 585. register boolean newedge = is_edge(u.ux,u.uy); 586. register boolean oldedge = is_edge(u.ux0,u.uy0); 587. 588. /* ust is old position, tmpr is new position */ 589. if(oldedge && newedge && inroom(u.ux0,u.uy0) == inroom(u.ux,u.uy)) { 590. /* moving along wall */ 591. nose1(backx,backy); 592. prl1(frontx,fronty); 593. 594. } else if(oldedge || newedge) { 595. if(isok(backx,backy) && levl[backx][backy].lit) 596. setsee(); 597. else 598. nose1(backx,backy); 599. 600. if(isok(frontx,fronty) && levl[frontx][fronty].lit) 601. setsee(); 602. else { 603. prl1(frontx,fronty); 604. prl1(u.ux,u.uy); /* make sure side walls are seen */ 605. } 606. 607. } else if(!tmpr->lit) { 608. /* we haven't crossed an edge, so old & new are both light or 609. * both dark. if both light, we need do nothing. 610. */ 611. nose1(backx,backy); 612. prl1(frontx,fronty); 613. } 614. 615. } else { 616. pru(); 617. } 618. #ifdef WALKIES 619. check_leash(u.ux0,u.uy0); 620. #endif 621. if(u.ux0 != u.ux || u.uy0 != u.uy) u.umoved = TRUE; 622. spoteffects(); 623. } 624. 625. void 626. spoteffects() 627. { 628. register struct trap *trap; 629. 630. if(is_pool(u.ux,u.uy) && !(Levitation || Wwalking 631. #ifdef POLYSELF 632. || is_flyer(uasmon) 633. #endif 634. )) 635. drown(); /* not necessarily fatal */ 636. else { 637. (void) inshop(); 638. #ifdef SINKS 639. if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 640. dosinkfall(); 641. #endif 642. if(!flags.nopick && 643. (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask)) 644. pickup(1); 645. else read_engr_at(u.ux,u.uy); 646. if(trap = t_at(u.ux,u.uy)) 647. dotrap(trap); /* fall into pit, arrow trap, etc. */ 648. } 649. 650. } 651. 652. int 653. dopickup() { 654. /* uswallow case added by GAN 01/29/87 */ 655. if(u.uswallow) { 656. if (is_animal(u.ustuck->data)) { 657. You("pick up %s's tongue.", mon_nam(u.ustuck)); 658. pline("But it's kind of slimy, so you drop it."); 659. } else 660. pline("You don't %s anything in here to pick up.", 661. Blind ? "feel" : "see"); 662. return(1); 663. } 664. if(levl[u.ux][u.uy].omask == 0 && levl[u.ux][u.uy].gmask == 0) { 665. pline("There is nothing here to pick up."); 666. return(0); 667. } 668. if(Levitation) { 669. You("cannot reach the floor."); 670. return(1); 671. } 672. pickup(0); 673. return(1); 674. } 675. 676. /* stop running if we see something interesting */ 677. /* turn around a corner if that is the only way we can proceed */ 678. /* do not turn left or right twice */ 679. void 680. lookaround() { 681. register int x, y, i, x0, y0, m0, i0 = 9, corrct = 0, noturn = 0; 682. register struct monst *mtmp; 683. #ifdef LINT 684. /* suppress "used before set" message */ 685. x0 = y0 = 0; 686. #endif 687. if(Blind || flags.run == 0) return; 688. for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) { 689. if(x == u.ux && y == u.uy) continue; 690. if(levl[x][y].mmask && (mtmp = m_at(x,y)) && !mtmp->mimic && 691. (!mtmp->minvis || See_invisible)) { 692. if((flags.run != 1 && !mtmp->mtame) || (x == u.ux+u.dx && y == u.uy+u.dy)) 693. goto stop; 694. } else mtmp = 0; 695. if(levl[x][y].typ == STONE) continue; 696. if(x == u.ux-u.dx && y == u.uy-u.dy) continue; 697. { 698. register uchar sym = levl[x][y].scrsym; 699. 700. if (IS_ROCK(levl[x][y].typ) || sym == ROOM_SYM) continue; 701. else if (sym == DOOR_SYM) { 702. if(x != u.ux && y != u.uy) continue; 703. if(flags.run != 1) goto stop; 704. goto bcorr; 705. } else if (sym == CORR_SYM) { 706. bcorr: 707. if(levl[u.ux][u.uy].typ != ROOM) { 708. if(flags.run == 1 || flags.run == 3) { 709. i = dist2(x,y,u.ux+u.dx,u.uy+u.dy); 710. if(i > 2) continue; 711. if(corrct == 1 && dist2(x,y,x0,y0) != 1) 712. noturn = 1; 713. if(i < i0) { 714. i0 = i; 715. x0 = x; 716. y0 = y; 717. m0 = mtmp ? 1 : 0; 718. } 719. } 720. corrct++; 721. } 722. continue; 723. } else if (sym == TRAP_SYM) { 724. if(flags.run == 1) goto bcorr; /* if you must */ 725. if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 726. continue; 727. } else if (sym == POOL_SYM) { 728. /* pools only stop you if directly in front, and stop 729. * you even if you are running 730. */ 731. if(!Levitation && 732. #ifdef POLYSELF 733. !is_flyer(uasmon) && 734. #endif 735. /* No Wwalking check; otherwise they'd be able 736. * to test boots by trying to SHIFT-direction 737. * into a pool and seeing if the game allowed it 738. */ 739. x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 740. continue; 741. } else { /* e.g. objects or trap or stairs */ 742. if(flags.run == 1) goto bcorr; 743. if(mtmp) continue; /* d */ 744. } 745. stop: 746. nomul(0); 747. return; 748. } 749. } 750. if(corrct > 1 && flags.run == 2) goto stop; 751. if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && 752. (corrct == 1 || (corrct == 2 && i0 == 1))) { 753. /* make sure that we do not turn too far */ 754. if(i0 == 2) { 755. if(u.dx == y0-u.uy && u.dy == u.ux-x0) 756. i = 2; /* straight turn right */ 757. else 758. i = -2; /* straight turn left */ 759. } else if(u.dx && u.dy) { 760. if((u.dx == u.dy && y0 == u.uy) || 761. (u.dx != u.dy && y0 != u.uy)) 762. i = -1; /* half turn left */ 763. else 764. i = 1; /* half turn right */ 765. } else { 766. if((x0-u.ux == y0-u.uy && !u.dy) || 767. (x0-u.ux != y0-u.uy && u.dy)) 768. i = 1; /* half turn right */ 769. else 770. i = -1; /* half turn left */ 771. } 772. i += u.last_str_turn; 773. if(i <= 2 && i >= -2) { 774. u.last_str_turn = i; 775. u.dx = x0-u.ux, u.dy = y0-u.uy; 776. } 777. } 778. } 779. 780. /* something like lookaround, but we are not running */ 781. /* react only to monsters that might hit us */ 782. int 783. monster_nearby() { 784. register int x,y; 785. register struct monst *mtmp; 786. 787. if(!Blind) 788. for(x = u.ux-1; x <= u.ux+1; x++) 789. for(y = u.uy-1; y <= u.uy+1; y++) { 790. if(x == u.ux && y == u.uy) continue; 791. if(levl[x][y].mmask && (mtmp = m_at(x,y)) && !mtmp->mimic && 792. !mtmp->mtame && !mtmp->mpeaceful && 793. !noattacks(mtmp->data) && 794. !mtmp->mfroz && !mtmp->msleep && /* aplvax!jcn */ 795. (!mtmp->minvis || See_invisible) && 796. !onscary(u.ux, u.uy, mtmp)) 797. return(1); 798. } 799. return(0); 800. } 801. 802. int 803. cansee(x,y) 804. xchar x,y; 805. { 806. if(Blind || u.uswallow) return(0); 807. if(dist(x,y) < 3) return(1); 808. if(IS_ROCK(levl[x][y].typ) && levl[u.ux][u.uy].typ == CORR && 809. !levl[u.ux][u.uy].lit) 810. return(0); 811. if(levl[x][y].lit && 812. ((seelx <= x && x <= seehx && seely <= y && y <= seehy) || 813. (seelx2 <= x && x <= seehx2 && seely2 <= y && y <= seehy2))) 814. return(1); 815. return(0); 816. } 817. 818. int 819. sgn(a) 820. register int a; 821. { 822. return((a > 0) ? 1 : (a == 0) ? 0 : -1); 823. } 824. 825. void 826. getcorners(lx1,hx1,ly1,hy1,lx2,hx2,ly2,hy2) 827. xchar *lx1,*hx1,*ly1,*hy1,*lx2,*hx2,*ly2,*hy2; 828. /* return corners of one or two rooms player is in, so we can tell what areas 829. * can be seen, or otherwise affected by room-specific things. (two rooms are 830. * possible when in a doorway of the stronghold) 831. * the player is already known to be in at least one room 832. */ 833. { 834. register int uroom1,uroom2; 835. register xchar ux,uy; 836. 837. uroom1 = inroom(u.ux,u.uy); 838. *lx1 = rooms[uroom1].lx - 1; 839. *hx1 = rooms[uroom1].hx + 1; 840. *ly1 = rooms[uroom1].ly - 1; 841. *hy1 = rooms[uroom1].hy + 1; 842. 843. if(!IS_DOOR(levl[u.ux][u.uy].typ)) { 844. *lx2 = 1; 845. *hx2 = 0; 846. *ly2 = 1; 847. *hy2 = 0; 848. } else { 849. for(ux = u.ux-1; ux <= u.ux+1; ux++) 850. for(uy = u.uy-1; uy <= u.uy+1; uy++) { 851. if(IS_ROCK(levl[ux][uy].typ) || 852. IS_DOOR(levl[ux][uy].typ)) continue; 853. /* might have side-by-side walls, in which case 854. * should only be able to see one room */ 855. uroom2 = inroom(ux,uy); 856. if(uroom2 >= 0 && uroom2 != uroom1 && 857. rooms[uroom2].rlit) { 858. *lx2 = rooms[uroom2].lx - 1; 859. *ly2 = rooms[uroom2].ly - 1; 860. *hx2 = rooms[uroom2].hx + 1; 861. *hy2 = rooms[uroom2].hy + 1; 862. return; 863. } 864. } 865. *lx2 = 1; 866. *hx2 = 0; 867. *ly2 = 1; 868. *hy2 = 0; 869. } 870. } 871. 872. void 873. setsee() { 874. register int x, y; 875. 876. if(Blind) { 877. pru(); 878. return; 879. } 880. if(!levl[u.ux][u.uy].lit) { 881. seelx = u.ux-1; 882. seehx = u.ux+1; 883. seely = u.uy-1; 884. seehy = u.uy+1; 885. seelx2 = seely2 = 1; 886. seehx2 = seehy2 = 0; 887. } else { 888. getcorners(&seelx,&seehx,&seely,&seehy, 889. &seelx2,&seehx2,&seely2,&seehy2); 890. } 891. for(y = seely; y <= seehy; y++) 892. for(x = seelx; x <= seehx; x++) { 893. prl(x,y); 894. } 895. for(y = seely2; y <= seehy2; y++) 896. for(x = seelx2; x <= seehx2; x++) { 897. prl(x,y); 898. } 899. if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ 900. else { 901. if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); 902. if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); 903. if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); 904. if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); 905. } 906. } 907. 908. void 909. nomul(nval) 910. register int nval; 911. { 912. if(multi < nval) return; /* This is a bug fix by ab@unido */ 913. multi = nval; 914. flags.mv = flags.run = 0; 915. } 916. 917. void 918. losehp(n, knam) 919. register int n; 920. register char *knam; 921. { 922. #ifdef POLYSELF 923. if (u.mtimedone) { 924. u.mh -= n; 925. if (u.mhmax < u.mh) u.mhmax = u.mh; 926. flags.botl = 1; 927. if (u.mh < 1) rehumanize(); 928. return; 929. } 930. #endif 931. u.uhp -= n; 932. if(u.uhp > u.uhpmax) 933. u.uhpmax = u.uhp; /* perhaps n was negative */ 934. flags.botl = 1; 935. if(u.uhp < 1) { 936. killer = knam; /* the thing that killed you */ 937. You("die..."); 938. done("died"); 939. } else if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50 && n > 0){ 940. wailmsg = moves; 941. if(index("WEV", pl_character[0])) { 942. if (u.uhp == 1) 943. pline("%s is about to die.", pl_character); 944. else if (4 <= (!!(HTeleportation & INTRINSIC)) + 945. (!!(HSee_invisible & INTRINSIC)) + 946. (!!(HPoison_resistance & INTRINSIC)) + 947. (!!(HCold_resistance & INTRINSIC)) + 948. (!!(HShock_resistance & INTRINSIC)) + 949. (!!(HFire_resistance & INTRINSIC)) + 950. (!!(HSleep_resistance & INTRINSIC)) + 951. (!!(HDisint_resistance & INTRINSIC)) + 952. (!!(HTeleport_control & INTRINSIC)) + 953. (!!(Fast & INTRINSIC)) + 954. (!!(HInvis & INTRINSIC))) 955. pline("%s, all your powers will be lost...", 956. pl_character); 957. else 958. pline("%s, your life force is running out.", 959. pl_character); 960. } else { 961. if(u.uhp == 1) 962. You("hear the wailing of the Banshee..."); 963. else 964. You("hear the howling of the CwnAnnwn..."); 965. } 966. } 967. } 968. 969. int 970. weight_cap() { 971. register int carrcap; 972. 973. #ifdef HARD 974. carrcap = 5 * (((ACURR(A_STR) > 18) ? 20 : ACURR(A_STR)) + u.ulevel); 975. #else 976. carrcap = 5 * u.ulevel; /* New strength stewr 870807 */ 977. if (ACURR(A_STR) < 19) carrcap += 5 * ACURR(A_STR); 978. if (ACURR(A_STR) > 18) carrcap += ACURR(A_STR) - 18 + 90; 979. if (ACURR(A_STR) > 68) carrcap += ACURR(A_STR) - 68; 980. if (ACURR(A_STR) > 93) carrcap += ACURR(A_STR) - 93; 981. if (ACURR(A_STR) > 108) carrcap += 2 * (ACURR(A_STR) - 108); 982. if (ACURR(A_STR) > 113) carrcap += 5 * (ACURR(A_STR) - 113); 983. if (ACURR(A_STR) == 118) carrcap += 100; 984. #endif 985. #ifdef POLYSELF 986. if (u.mtimedone) { 987. /* consistent with can_carry() in mon.c */ 988. if (u.usym==S_NYMPH) carrcap = MAX_CARR_CAP; 989. else if (!uasmon->cwt) 990. carrcap = (carrcap * uasmon->mlevel * 6)/45; 991. else carrcap = (carrcap * uasmon->cwt / 45); 992. } 993. #endif 994. if(Levitation) /* pugh@cornell */ 995. carrcap = MAX_CARR_CAP; 996. else { 997. if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 998. if(Wounded_legs & LEFT_SIDE) carrcap -= 10; 999. if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; 1000. } 1001. return(carrcap); 1002. } 1003. 1004. int 1005. inv_weight() { 1006. register struct obj *otmp = invent; 1007. #ifdef LINT /* long to int conversion */ 1008. register int wt = 0; 1009. #else 1010. register int wt = (int)((u.ugold + 500L)/1000L); 1011. #endif /* LINT */ 1012. while(otmp){ 1013. #ifdef POLYSELF 1014. if (otmp->otyp != BOULDER || !throws_rocks(uasmon)) 1015. #endif 1016. wt += otmp->owt; 1017. otmp = otmp->nobj; 1018. } 1019. return(wt - weight_cap()); 1020. } 1021. 1022. int 1023. inv_cnt() { 1024. register struct obj *otmp = invent; 1025. register int ct = 0; 1026. 1027. while(otmp){ 1028. ct++; 1029. otmp = otmp->nobj; 1030. } 1031. return(ct); 1032. } 1033. 1034. #ifdef STUPID_CPP /* otherwise these functions are macros in hack.h */ 1035. char 1036. yn() { 1037. return(yn_function(ynchars, 'n')); 1038. } 1039. 1040. char 1041. ynq() { 1042. return(yn_function(ynqchars, 'q')); 1043. } 1044. 1045. char 1046. ynaq() { 1047. return(yn_function(ynaqchars, 'y')); 1048. } 1049. 1050. char 1051. nyaq() { 1052. return(yn_function(nyaqchars, 'n')); 1053. } 1054. 1055. int 1056. max(a,b) int a,b; { 1057. return((a > b) ? a : b); 1058. } 1059. 1060. int 1061. min(a,b) int a,b; { 1062. return((a < b) ? a : b); 1063. } 1064. 1065. char * 1066. plur(x) long x; { 1067. return((x == 1L) ? "" : "s"); 1068. } 1069. 1070. void 1071. makeknown(x) unsigned x; { 1072. objects[x].oc_name_known = 1; 1073. } 1074. #endif /* STUPID_CPP */