abstract
| - Below is the full text to hack.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/hack.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2. 3. #include 4. #include "hack.h" 5. #ifdef UNIX 6. static char SCCS_Id[] = "@(#)hack.c 2.3 88/02/18"; 7. #endif 8. extern char news0(); 9. extern char *nomovemsg; 10. extern char *exclam(); 11. extern struct obj *addinv(); 12. extern boolean hmon(); 13. 14. /* called on movement: 15. 1. when throwing ball+chain far away 16. 2. when teleporting 17. 3. when walking out of a lit room 18. */ 19. unsee() { 20. register x,y; 21. register struct rm *lev; 22. 23. /* 24. if(u.udispl){ 25. u.udispl = 0; 26. newsym(u.udisx, u.udisy); 27. } 28. */ 29. #ifndef QUEST 30. if(seehx){ 31. seehx = 0; 32. } else 33. #endif 34. for(x = u.ux-1; x < u.ux+2; x++) 35. for(y = u.uy-1; y < u.uy+2; y++) { 36. if(!isok(x, y)) continue; 37. lev = &levl[x][y]; 38. if(!lev->lit && lev->scrsym == ROOM_SYM) { 39. lev->scrsym = STONE_SYM; 40. lev->new = 1; 41. on_scr(x,y); 42. } 43. } 44. } 45. 46. /* called: 47. in apply.c: seeoff(0) - when taking a picture of yourself 48. - when donning a blindfold 49. in do.c: seeoff(0) - blind after drinking potion 50. in do.c: seeoff(1) - go up or down the stairs 51. in eat.c: seeoff(0) - blind after eating rotten food 52. in mhitu.c: seeoff(0) - blinded by a yellow light 53. in mon.c: seeoff(1) - swallowed 54. in potion.c: seeoff(0) - quaffing or sniffing a potion of blindness 55. in spell.c: seeoff(0) - due to a cursed spellbook 56. in trap.c: seeoff(1) - fall through trapdoor 57. in wizard.c: seeoff(0) - hit by a cream pie. 58. */ 59. seeoff(mode) /* 1 to redo @, 0 to leave them */ 60. { /* 1 means misc movement, 0 means blindness */ 61. register x,y; 62. register struct rm *lev; 63. 64. if(u.udispl && mode){ 65. u.udispl = 0; 66. levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); 67. } 68. #ifndef QUEST 69. if(seehx) { 70. seehx = 0; 71. } else 72. #endif 73. if(!mode) { 74. for(x = u.ux-1; x < u.ux+2; x++) 75. for(y = u.uy-1; y < u.uy+2; y++) { 76. if(!isok(x, y)) continue; 77. lev = &levl[x][y]; 78. if(!lev->lit && lev->scrsym == ROOM_SYM) 79. lev->seen = 0; 80. } 81. } 82. } 83. 84. static 85. moverock() { 86. register xchar rx, ry; 87. register struct obj *otmp; 88. register struct trap *ttmp; 89. register struct monst *mtmp; 90. struct monst *m_at(); 91. 92. while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) { 93. rx = u.ux+2*u.dx; 94. ry = u.uy+2*u.dy; 95. nomul(0); 96. if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) && 97. (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) && 98. !sobj_at(ENORMOUS_ROCK, rx, ry)) { 99. if((mtmp = m_at(rx,ry))) { 100. if(canseemon(mtmp)) 101. pline("There's %s on the other side.", monnam(mtmp)); 102. else 103. pline("You hear a monster behind the rock."); 104. pline("Perhaps that's why you cannot move it."); 105. goto cannot_push; 106. } 107. if(ttmp = t_at(rx,ry)) 108. switch(ttmp->ttyp) { 109. case PIT: 110. pline("You push the rock into a pit!"); 111. deltrap(ttmp); 112. delobj(otmp); 113. pline("It completely fills the pit!"); 114. continue; 115. case TELEP_TRAP: 116. pline("You push the rock and suddenly it disappears!"); 117. delobj(otmp); 118. continue; 119. } 120. if(levl[rx][ry].typ == POOL) { 121. levl[rx][ry].typ = ROOM; 122. mnewsym(rx,ry); 123. prl(rx,ry); 124. pline("You push the rock into the water."); 125. pline("Now you can cross the water!"); 126. delobj(otmp); 127. continue; 128. } 129. otmp->ox = rx; 130. otmp->oy = ry; 131. /* pobj(otmp); */ 132. if(cansee(rx,ry)) atl(rx,ry,otmp->olet); 133. if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy); 134. 135. { static long lastmovetime; 136. /* note: this var contains garbage initially and 137. after a restore */ 138. if(moves > lastmovetime+2 || moves < lastmovetime) 139. pline("With great effort you move the enormous rock."); 140. lastmovetime = moves; 141. } 142. } else { 143. pline("You try to move the enormous rock, but in vain."); 144. cannot_push: 145. #ifdef KAA 146. if (u.usym=='9') { 147. # ifdef DGKMOD 148. if(!flags.pickup) 149. pline("You easily can push it aside."); 150. else 151. # endif 152. pline("However, you easily can pick it up."); 153. break; 154. } 155. #endif 156. if((!invent || inv_weight()+90 <= 0) && 157. (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ) 158. && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){ 159. pline("However, you can squeeze yourself into a small opening."); 160. break; 161. } else 162. return (-1); 163. } 164. } 165. return (0); 166. } 167. 168. domove() 169. { 170. register struct monst *mtmp; 171. register struct rm *tmpr,*ust; 172. struct trap *trap; 173. 174. u_wipe_engr(rnd(5)); 175. 176. if(inv_weight() > 0){ 177. pline("You collapse under your load."); 178. nomul(0); 179. return; 180. } 181. if(u.uswallow) { 182. u.dx = u.dy = 0; 183. u.ux = u.ustuck->mx; 184. u.uy = u.ustuck->my; 185. } else { 186. if(Confusion) { 187. do { 188. confdir(); 189. } while(!isok(u.ux+u.dx, u.uy+u.dy) || 190. IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ)); 191. } 192. if(!isok(u.ux+u.dx, u.uy+u.dy)){ 193. nomul(0); 194. return; 195. } 196. } 197. 198. ust = &levl[u.ux][u.uy]; 199. u.ux0 = u.ux; 200. u.uy0 = u.uy; 201. if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen) 202. nomul(0); 203. if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx || 204. u.uy+u.dy != u.ustuck->my)) { 205. if(dist(u.ustuck->mx, u.ustuck->my) > 2){ 206. /* perhaps it fled (or was teleported or ... ) */ 207. u.ustuck = 0; 208. } else { 209. if(Blind) pline("You cannot escape from it!"); 210. else pline("You cannot escape from %s!", 211. monnam(u.ustuck)); 212. nomul(0); 213. return; 214. } 215. } 216. if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) { 217. /* attack monster */ 218. 219. #ifdef SAFE_ATTACK 220. /* Don't attack if you're running */ 221. if (flags.run && !mtmp->mimic 222. && (Blind ? Telepat : (!mtmp->minvis || See_invisible))) { 223. nomul(0); 224. flags.move = 0; 225. return; 226. } 227. #endif 228. nomul(0); 229. gethungry(); 230. if(multi < 0) return; /* we just fainted */ 231. 232. /* try to attack; note that it might evade */ 233. if(attack(u.uswallow ? u.ustuck : mtmp)) 234. return; 235. } 236. /* not attacking an animal, so we try to move */ 237. if(u.utrap) { 238. if(u.utraptype == TT_PIT) { 239. pline("You are still in a pit."); 240. u.utrap--; 241. #ifdef SPIDERS 242. } else if (u.utraptype == TT_WEB) { 243. pline("You are stuck to the web."); 244. u.utrap--; 245. #endif 246. } else { 247. pline("You are caught in a bear trap."); 248. if((u.dx && u.dy) || !rn2(5)) u.utrap--; 249. } 250. return; 251. } 252. tmpr = &levl[u.ux+u.dx][u.uy+u.dy]; 253. if(IS_ROCK(tmpr->typ) || 254. (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){ 255. flags.move = 0; 256. nomul(0); 257. return; 258. } 259. if(moverock() < 0) return; 260. if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) && 261. IS_ROCK(levl[u.ux+u.dx][u.uy].typ) && 262. invent && inv_weight()+40 > 0) { 263. pline("You are carrying too much to get through."); 264. nomul(0); 265. return; 266. } 267. if(Punished && 268. DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){ 269. if(carried(uball)) { 270. movobj(uchain, u.ux, u.uy); 271. goto nodrag; 272. } 273. 274. if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){ 275. /* leave ball, move chain under/over ball */ 276. movobj(uchain, uball->ox, uball->oy); 277. goto nodrag; 278. } 279. 280. if(inv_weight() + (int) uball->owt/2 > 0) { 281. pline("You cannot %sdrag the heavy iron ball.", 282. invent ? "carry all that and also " : ""); 283. nomul(0); 284. return; 285. } 286. 287. movobj(uball, uchain->ox, uchain->oy); 288. unpobj(uball); /* BAH %% */ 289. uchain->ox = u.ux; 290. uchain->oy = u.uy; 291. nomul(-2); 292. nomovemsg = ""; 293. nodrag: ; 294. } 295. u.ux += u.dx; 296. u.uy += u.dy; 297. if(flags.run) { 298. if(tmpr->typ == DOOR || 299. (xupstair == u.ux && yupstair == u.uy) || 300. (xdnstair == u.ux && ydnstair == u.uy) 301. #ifdef FOUNTAINS 302. || IS_FOUNTAIN(levl[u.ux][u.uy].typ) 303. #endif 304. #ifdef NEWCLASS 305. || IS_THRONE(levl[u.ux][u.uy].typ) 306. #endif 307. #ifdef SINKS 308. || IS_SINK(levl[u.ux][u.uy].typ) 309. #endif 310. ) 311. nomul(0); 312. } 313. 314. #ifdef SINKS 315. if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 316. dosinkfall(); 317. #endif 318. if(tmpr->typ == POOL && !Levitation) 319. drown(); /* not necessarily fatal */ 320. 321. /* 322. if(u.udispl) { 323. u.udispl = 0; 324. newsym(u.ux0,u.uy0); 325. } 326. */ 327. if(!Blind) { 328. #ifdef QUEST 329. setsee(); 330. #else 331. if(ust->lit) { 332. if(tmpr->lit) { 333. if(tmpr->typ == DOOR) 334. prl1(u.ux+u.dx,u.uy+u.dy); 335. else if(ust->typ == DOOR) 336. nose1(u.ux0-u.dx,u.uy0-u.dy); 337. } else { 338. unsee(); 339. prl1(u.ux+u.dx,u.uy+u.dy); 340. } 341. } else { 342. if(tmpr->lit) setsee(); 343. else { 344. prl1(u.ux+u.dx,u.uy+u.dy); 345. if(tmpr->typ == DOOR) { 346. if(u.dy) { 347. prl(u.ux-1,u.uy); 348. prl(u.ux+1,u.uy); 349. } else { 350. prl(u.ux,u.uy-1); 351. prl(u.ux,u.uy+1); 352. } 353. } 354. } 355. nose1(u.ux0-u.dx,u.uy0-u.dy); 356. } 357. #endif /* QUEST /**/ 358. } else { 359. pru(); 360. } 361. if(!flags.nopick) pickup(1); 362. if(trap) dotrap(trap); /* fall into pit, arrow trap, etc. */ 363. (void) inshop(); 364. if(!Blind) read_engr_at(u.ux,u.uy); 365. } 366. 367. movobj(obj, ox, oy) 368. register struct obj *obj; 369. register int ox, oy; 370. { 371. /* Some dirty programming to get display right */ 372. freeobj(obj); 373. unpobj(obj); 374. obj->nobj = fobj; 375. fobj = obj; 376. obj->ox = ox; 377. obj->oy = oy; 378. } 379. 380. dopickup(){ 381. /* uswallow case added by GAN 01/29/87 */ 382. if(u.uswallow) { 383. pline("You pick up %s's tongue.",monnam(u.ustuck)); 384. pline("But it's kind of slimy, so you drop it."); 385. return(1); 386. } 387. if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) { 388. pline("There is nothing here to pick up."); 389. return(0); 390. } 391. if(Levitation) { 392. pline("You cannot reach the floor."); 393. return(1); 394. } 395. pickup(0); 396. return(1); 397. } 398. 399. pickup(all) 400. { 401. register struct gold *gold; 402. register struct obj *obj, *obj2; 403. register int wt; 404. char buf[BUFSZ]; 405. register char *ip; 406. register char sym; 407. register int oletct = 0, iletct = 0; 408. char olets[20], ilets[20]; 409. 410. if(Levitation) return; 411. #ifdef DGKMOD 412. if (all && !flags.pickup) { 413. int ct = 0; 414. 415. for (obj = fobj; obj; obj = obj->nobj) 416. if (obj->ox == u.ux && obj->oy == u.uy) 417. if (!Punished || obj != uchain) 418. ct++; 419. /* If gold is the only thing here, pick it up. 420. */ 421. if (!ct && g_at(u.ux, u.uy)) { 422. if (flags.run) nomul(0); 423. while (gold = g_at(u.ux,u.uy)) { 424. pline("%ld gold piece%s.", gold->amount, 425. plur(gold->amount)); 426. u.ugold += gold->amount; 427. flags.botl = 1; 428. freegold(gold); 429. } 430. if (Invisible) newsym(u.ux,u.uy); 431. } 432. 433. /* If there are objects here, take a look. 434. */ 435. if (ct) { 436. if (flags.run) 437. nomul(0); 438. nscr(); 439. if (ct < 5) 440. dolook(); 441. else 442. pline("There are several objects here."); 443. } 444. return; 445. } 446. #endif 447. while(gold = g_at(u.ux,u.uy)) { 448. pline("%ld gold piece%s.", gold->amount, plur(gold->amount)); 449. u.ugold += gold->amount; 450. flags.botl = 1; 451. freegold(gold); 452. if(flags.run) nomul(0); 453. if(Invisible) newsym(u.ux,u.uy); 454. } 455. /* check for more than one object */ 456. if(!all) { 457. register int ct = 0; 458. 459. for(obj = fobj; obj; obj = obj->nobj) 460. if(obj->ox == u.ux && obj->oy == u.uy) ct++; 461. if(g_at(u.ux,u.uy)) 462. ct++; 463. if(ct < 2) 464. all++; 465. else 466. pline("There are several objects here."); 467. } 468. 469. /* added by GAN 10/24/86 to allow selective picking up */ 470. if(!all) { 471. register struct obj *otmp = fobj; 472. 473. if(g_at(u.ux,u.uy)) ilets[iletct++] = GOLD_SYM; 474. ilets[iletct] = 0; 475. while(otmp) { 476. if(!index(ilets, otmp->olet) && 477. otmp->ox == u.ux && otmp->oy == u.uy) { 478. ilets[iletct++] = otmp->olet; 479. ilets[iletct] = 0; 480. } 481. otmp = otmp->nobj; 482. } 483. if(iletct == 1) 484. strcpy(buf,ilets); 485. else { 486. ilets[iletct++] = ' '; 487. ilets[iletct++] = 'a'; 488. ilets[iletct++] = 'A'; 489. ilets[iletct] = 0; 490. 491. if(iletct = 3) 492. pline("What kinds of thing do you want to pick up? [%s] ", ilets); 493. getlin(buf); 494. if(buf[0] == '\033') { 495. clrlin(); 496. return; 497. } 498. #ifdef KJSMODS 499. else if(!buf[0]) strcpy(buf,"A"); 500. #endif 501. } 502. ip = buf; 503. olets[0] = 0; 504. while(sym = *ip++){ 505. /* new A function (selective all) added by 506. * GAN 01/09/87 507. */ 508. if(sym == 'A') { 509. for(oletct = 0; ilets[oletct] != ' '; oletct++) 510. olets[oletct] = ilets[oletct]; 511. olets[oletct] = 0; 512. break; 513. } 514. if(sym == ' ') continue; 515. if(sym == 'a') all++; else 516. if(index(ilets, sym)){ 517. if(!index(olets, sym)){ 518. olets[oletct++] = sym; 519. olets[oletct] = 0; 520. } 521. } 522. else pline("There are no %c's here.", sym); 523. } 524. } 525. 526. if(all || index(olets, GOLD_SYM)) 527. while(gold = g_at(u.ux,u.uy)) { 528. pline("%ld gold piece%s.", gold->amount, 529. plur(gold->amount)); 530. u.ugold += gold->amount; 531. flags.botl = 1; 532. freegold(gold); 533. if(flags.run) nomul(0); 534. if(Invis) newsym(u.ux,u.uy); 535. } 536. 537. 538. for(obj = fobj; obj; obj = obj2) { 539. obj2 = obj->nobj; /* perhaps obj will be picked up */ 540. if(obj->ox == u.ux && obj->oy == u.uy) { 541. if(flags.run) nomul(0); 542. 543. if(!all) { 544. char c; 545. 546. if(!index(olets,obj->olet)) continue; 547. 548. pline("Pick up %s ? [ynaq]", doname(obj)); 549. while(!index("ynaq ", (c = readchar()))) 550. bell(); 551. if(c == 'q') return; 552. if(c == 'n') continue; 553. if(c == 'a') all = 1; 554. } 555. 556. if(obj->otyp == DEAD_COCKATRICE && !uarmg && u.usym != 'c') { 557. pline("Touching the dead cockatrice is a fatal mistake."); 558. pline("You turn to stone."); 559. pline("You die..."); 560. killer = "cockatrice cadaver"; 561. done("died"); 562. } 563. 564. if(obj->otyp == SCR_SCARE_MONSTER){ 565. if(!obj->spe) obj->spe = 1; 566. else { 567. /* Note: perhaps the 1st pickup failed: you cannot 568. carry anymore, and so we never dropped it - 569. lets assume that treading on it twice also 570. destroys the scroll */ 571. pline("The scroll turns to dust as you pick it up."); 572. #ifdef KAA 573. if(!(objects[SCR_SCARE_MONSTER].oc_name_known) && 574. !(objects[SCR_SCARE_MONSTER].oc_uname)) 575. docall(obj); 576. #endif 577. delobj(obj); 578. continue; 579. } 580. } 581. 582. /* do not pick up uchain */ 583. if(Punished && obj == uchain) 584. continue; 585. 586. 587. wt = inv_weight() + obj->owt; 588. if(wt > 0) { 589. if(obj->quan > 1) { 590. /* see how many we can lift */ 591. extern struct obj *splitobj(); 592. int savequan = obj->quan; 593. int iw = inv_weight(); 594. int qq; 595. for(qq = 1; qq < savequan; qq++){ 596. obj->quan = qq; 597. if(iw + weight(obj) > 0) 598. break; 599. } 600. obj->quan = savequan; 601. qq--; 602. /* we can carry qq of them */ 603. if(!qq) goto too_heavy; 604. pline("You can only carry %s of the %s lying here.", 605. (qq == 1) ? "one" : "some", 606. doname(obj)); 607. { 608. register struct obj *obj3; 609. 610. obj3 = splitobj(obj, qq); 611. if(obj3->otyp == SCR_SCARE_MONSTER) 612. if(obj3->spe) obj->spe = 0; 613. } 614. /* note: obj2 is set already, so well never 615. * encounter the other half; if it should be 616. * otherwise then write 617. * obj2 = splitobj(obj,qq); 618. */ 619. goto lift_some; 620. } 621. too_heavy: 622. pline("There %s %s here, but %s.", 623. (obj->quan == 1) ? "is" : "are", 624. doname(obj), 625. !invent ? "it is too heavy for you to lift" 626. /* There is no such word as "anymore". KAA */ 627. : "you cannot carry any more"); 628. if(obj->otyp == SCR_SCARE_MONSTER) 629. if(obj->spe) obj->spe = 0; 630. break; 631. } 632. lift_some: 633. if(inv_cnt() >= 52) { 634. pline("Your knapsack cannot accommodate any more items."); 635. if(obj->otyp == SCR_SCARE_MONSTER) 636. if(obj->spe) obj->spe = 0; 637. break; 638. } 639. freeobj(obj); 640. if(Invisible) newsym(u.ux,u.uy); 641. addtobill(obj); /* sets obj->unpaid if necessary */ 642. if(wt > -5) pline("You have a little trouble lifting"); 643. { int pickquan = obj->quan; 644. int mergquan; 645. #ifdef KAA 646. if(!Blind) if(obj->olet != WEAPON_SYM) obj->dknown = 1; 647. #else 648. if(!Blind) obj->dknown = 1; /* this is done by prinv(), 649. but addinv() needs it already for merging */ 650. #endif 651. obj = addinv(obj); /* might merge it with other objects */ 652. mergquan = obj->quan; 653. obj->quan = pickquan; /* to fool prinv() */ 654. prinv(obj); 655. obj->quan = mergquan; 656. } 657. } 658. } 659. } 660. 661. /* stop running if we see something interesting */ 662. /* turn around a corner if that is the only way we can proceed */ 663. /* do not turn left or right twice */ 664. lookaround(){ 665. register x,y,i,x0,y0,m0,i0 = 9; 666. register int corrct = 0, noturn = 0; 667. register struct monst *mtmp; 668. #ifdef LINT 669. /* suppress "used before set" message */ 670. x0 = y0 = 0; 671. #endif 672. if(Blind || flags.run == 0) return; 673. if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return; 674. #ifdef QUEST 675. if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop; 676. #endif 677. for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ 678. if(x == u.ux && y == u.uy) continue; 679. if(!levl[x][y].typ) continue; 680. if((mtmp = m_at(x,y)) && !mtmp->mimic && 681. (!mtmp->minvis || See_invisible)){ 682. if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy)) 683. goto stop; 684. } else mtmp = 0; /* invisible M cannot influence us */ 685. if(x == u.ux-u.dx && y == u.uy-u.dy) continue; 686. { 687. register uchar sym = levl[x][y].scrsym; 688. 689. if (sym == VWALL_SYM || sym == HWALL_SYM 690. || sym == ROOM_SYM || sym == STONE_SYM 691. || IS_CORNER(sym)) 692. continue; 693. else if (sym == DOOR_SYM) { 694. if(x != u.ux && y != u.uy) continue; 695. if(flags.run != 1) goto stop; 696. goto corr; 697. } else if (sym == CORR_SYM) { 698. corr: 699. if(flags.run == 1 || flags.run == 3) { 700. i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); 701. if(i > 2) continue; 702. if(corrct == 1 && DIST(x,y,x0,y0) != 1) 703. noturn = 1; 704. if(i < i0) { 705. i0 = i; 706. x0 = x; 707. y0 = y; 708. m0 = mtmp ? 1 : 0; 709. } 710. } 711. corrct++; 712. continue; 713. } else if (sym == TRAP_SYM) { 714. if(flags.run == 1) goto corr; /* if you must */ 715. if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 716. continue; 717. } else { /* e.g. objects or trap or stairs */ 718. if(flags.run == 1) goto corr; 719. if(mtmp) continue; /* d */ 720. } 721. stop: 722. nomul(0); 723. return; 724. } 725. } 726. #ifdef QUEST 727. if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop; 728. #endif 729. if(corrct > 1 && flags.run == 2) goto stop; 730. if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && 731. (corrct == 1 || (corrct == 2 && i0 == 1))) { 732. /* make sure that we do not turn too far */ 733. if(i0 == 2) { 734. if(u.dx == y0-u.uy && u.dy == u.ux-x0) 735. i = 2; /* straight turn right */ 736. else 737. i = -2; /* straight turn left */ 738. } else if(u.dx && u.dy) { 739. if((u.dx == u.dy && y0 == u.uy) || 740. (u.dx != u.dy && y0 != u.uy)) 741. i = -1; /* half turn left */ 742. else 743. i = 1; /* half turn right */ 744. } else { 745. if((x0-u.ux == y0-u.uy && !u.dy) || 746. (x0-u.ux != y0-u.uy && u.dy)) 747. i = 1; /* half turn right */ 748. else 749. i = -1; /* half turn left */ 750. } 751. i += u.last_str_turn; 752. if(i <= 2 && i >= -2) { 753. u.last_str_turn = i; 754. u.dx = x0-u.ux, u.dy = y0-u.uy; 755. } 756. } 757. } 758. 759. /* something like lookaround, but we are not running */ 760. /* react only to monsters that might hit us */ 761. monster_nearby() { 762. register int x,y; 763. register struct monst *mtmp; 764. if(!Blind) 765. for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ 766. if(x == u.ux && y == u.uy) continue; 767. if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame && 768. !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) && 769. !mtmp->mfroz && !mtmp->msleep && /* aplvax!jcn */ 770. (!mtmp->minvis || See_invisible)) 771. return(1); 772. } 773. return(0); 774. } 775. 776. #ifdef QUEST 777. cansee(x,y) xchar x,y; { 778. register int dx,dy,adx,ady,sdx,sdy,dmax,d; 779. if(Blind) return(0); 780. if(!isok(x,y)) return(0); 781. d = dist(x,y); 782. if(d < 3) return(1); 783. if(d > u.uhorizon*u.uhorizon) return(0); 784. if(!levl[x][y].lit) 785. return(0); 786. dx = x - u.ux; adx = abs(dx); sdx = sgn(dx); 787. dy = y - u.uy; ady = abs(dy); sdy = sgn(dy); 788. if(dx == 0 || dy == 0 || adx == ady){ 789. dmax = (dx == 0) ? ady : adx; 790. for(d = 1; d <= dmax; d++) 791. if(!rroom(sdx*d,sdy*d)) 792. return(0); 793. return(1); 794. } else if(ady > adx){ 795. for(d = 1; d <= ady; d++){ 796. if(!rroom(sdx*( (d*adx)/ady ), sdy*d) || 797. !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d)) 798. return(0); 799. } 800. return(1); 801. } else { 802. for(d = 1; d <= adx; d++){ 803. if(!rroom(sdx*d, sdy*( (d*ady)/adx )) || 804. !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 ))) 805. return(0); 806. } 807. return(1); 808. } 809. } 810. 811. rroom(x,y) register int x,y; { 812. return(IS_ROOM(levl[u.ux+x][u.uy+y].typ)); 813. } 814. 815. #else 816. 817. cansee(x,y) xchar x,y; { 818. if(Blind || u.uswallow) return(0); 819. if(dist(x,y) < 3) return(1); 820. if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y && 821. y <= seehy) return(1); 822. return(0); 823. } 824. #endif /* QUEST /**/ 825. 826. sgn(a) register int a; { 827. return((a > 0) ? 1 : (a == 0) ? 0 : -1); 828. } 829. 830. #ifdef QUEST 831. setsee() 832. { 833. register x,y; 834. 835. if(Blind) { 836. pru(); 837. return; 838. } 839. for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++) 840. for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) { 841. if(cansee(x,y)) 842. prl(x,y); 843. } 844. } 845. 846. #else 847. 848. setsee() 849. { 850. register x,y; 851. 852. if(Blind) { 853. pru(); 854. return; 855. } 856. if(!levl[u.ux][u.uy].lit) { 857. seelx = u.ux-1; 858. seehx = u.ux+1; 859. seely = u.uy-1; 860. seehy = u.uy+1; 861. } else { 862. for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--); 863. for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++); 864. for(seely = u.uy; levl[u.ux][seely-1].lit; seely--); 865. for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++); 866. } 867. for(y = seely; y <= seehy; y++) 868. for(x = seelx; x <= seehx; x++) { 869. prl(x,y); 870. } 871. if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ 872. else { 873. if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); 874. if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); 875. if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); 876. if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); 877. } 878. } 879. #endif /* QUEST /**/ 880. 881. nomul(nval) 882. register nval; 883. { 884. #ifdef DGKMOD 885. if(multi < nval) return; /* This is a bug fix by ab@unido */ 886. #else 887. if(multi < 0) return; 888. #endif 889. multi = nval; 890. flags.mv = flags.run = 0; 891. } 892. 893. abon() 894. { 895. #ifdef KAA 896. if (u.usym != '@') return(mons[u.umonnum].mlevel-3); 897. #endif 898. if(u.ustr == 3) return(-3); 899. else if(u.ustr < 6) return(-2); 900. else if(u.ustr < 8) return(-1); 901. else if(u.ustr < 17) return(0); 902. else if(u.ustr < 69) return(1); /* up to 18/50 */ 903. else if(u.ustr < 118) return(2); 904. else return(3); 905. } 906. 907. dbon() 908. { 909. if (u.usym != '@') return(0); 910. 911. if(u.ustr < 6) return(-1); 912. else if(u.ustr < 16) return(0); 913. else if(u.ustr < 18) return(1); 914. else if(u.ustr == 18) return(2); /* up to 18 */ 915. else if(u.ustr < 94) return(3); /* up to 18/75 */ 916. else if(u.ustr < 109) return(4); /* up to 18/90 */ 917. else if(u.ustr < 118) return(5); /* up to 18/99 */ 918. else return(6); 919. } 920. 921. losestr(num) /* may kill you; cause may be poison or monster like 'A' */ 922. register num; 923. { 924. u.ustr -= num; 925. while(u.ustr < 3) { 926. u.ustr++; 927. u.uhp -= 6; 928. u.uhpmax -= 6; 929. } 930. flags.botl = 1; 931. } 932. 933. losehp(n,knam) 934. register n; 935. register char *knam; 936. { 937. #ifdef KAA 938. if (u.mtimedone) { 939. u.mh -= n; 940. if (u.mhmax < u.mh) u.mhmax = u.mh; 941. flags.botl = 1; 942. if (u.mh < 1) rehumanize(); 943. return; 944. } 945. #endif 946. u.uhp -= n; 947. if(u.uhp > u.uhpmax) 948. u.uhpmax = u.uhp; /* perhaps n was negative */ 949. flags.botl = 1; 950. if(u.uhp < 1) { 951. killer = knam; /* the thing that killed you */ 952. pline("You die..."); 953. done("died"); 954. } 955. } 956. 957. losehp_m(n,mtmp) 958. register n; 959. register struct monst *mtmp; 960. { 961. #ifdef KAA 962. if (u.mtimedone) { 963. u.mh -= n; 964. flags.botl = 1; 965. if (u.mh < 1) rehumanize(); 966. return; 967. } 968. #endif 969. u.uhp -= n; 970. flags.botl = 1; 971. if(u.uhp < 1) 972. done_in_by(mtmp); 973. } 974. 975. losexp() /* hit by V or W */ 976. { 977. register num; 978. extern long newuexp(); 979. 980. if (u.usym == 'V' || u.usym=='W') return; 981. 982. if(u.ulevel > 1) 983. pline("Goodbye level %u.", u.ulevel--); 984. else 985. u.uhp = -1; 986. num = rnd(10); 987. u.uhp -= num; 988. u.uhpmax -= num; 989. #ifdef SPELLS 990. num = rnd(u.ulevel/2+1) + 1; /* M. Stephenson */ 991. u.uen -= num; 992. if (u.uen < 0) u.uen = 0; 993. u.uenmax -= num; 994. if (u.uenmax < 0) u.uenmax = 0; 995. #endif 996. u.uexp = newuexp(); 997. flags.botl = 1; 998. } 999. 1000. inv_weight(){ 1001. register struct obj *otmp = invent; 1002. register int wt = (u.ugold + 500)/1000; 1003. register int carrcap; 1004. #ifdef KAA 1005. if (u.mtimedone) { 1006. if (u.usym == '9') carrcap = MAX_CARR_CAP * 4; 1007. else if (u.usym == 'N') carrcap = MAX_CARR_CAP; 1008. else if (mons[u.umonnum].mlevel <= 3) 1009. carrcap = 5*mons[u.umonnum].mlevel + 30; 1010. else carrcap = 5*mons[u.umonnum].mlevel + 100; 1011. } 1012. #endif 1013. if(Levitation) /* pugh@cornell */ 1014. carrcap = MAX_CARR_CAP; 1015. else { 1016. #ifdef HARD 1017. carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel); 1018. #else 1019. carrcap = 5*u.ulevel; /* New strength stewr 870807 */ 1020. if (u.ustr < 19) carrcap += 5*u.ustr; 1021. if (u.ustr > 18) carrcap += u.ustr - 18 + 90; 1022. if (u.ustr > 68) carrcap += u.ustr - 68; 1023. if (u.ustr > 93) carrcap += u.ustr - 93; 1024. if (u.ustr > 108) carrcap += 2*(u.ustr - 108); 1025. if (u.ustr > 113) carrcap += 5*(u.ustr - 113); 1026. if (u.ustr == 118) carrcap += 100; 1027. #endif 1028. if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 1029. if(Wounded_legs & LEFT_SIDE) carrcap -= 10; 1030. if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; 1031. } 1032. while(otmp){ 1033. wt += otmp->owt; 1034. otmp = otmp->nobj; 1035. } 1036. return(wt - carrcap); 1037. } 1038. 1039. inv_cnt(){ 1040. register struct obj *otmp = invent; 1041. register int ct = 0; 1042. while(otmp){ 1043. ct++; 1044. otmp = otmp->nobj; 1045. } 1046. return(ct); 1047. } 1048. 1049. long 1050. newuexp() 1051. { 1052. return(10*(1L << (u.ulevel-1))); 1053. } 1054. 1055. change_luck(n) 1056. register schar n; 1057. { 1058. u.uluck += n; 1059. if (u.uluck < 0 && u.uluck < LUCKMIN) u.uluck = LUCKMIN; 1060. if (u.uluck > 0 && u.uluck > LUCKMAX) u.uluck = LUCKMAX; 1061. } 1062. 1063. #ifdef SINKS 1064. dosinkfall() { 1065. register struct obj *obj; 1066. pline("You crash to the floor!"); 1067. losehp(rn2(15) + 3*u.ulevel,"fall onto a sink"); 1068. for(obj=fobj; obj; obj=obj->nobj) 1069. if(obj->ox == u.ux && obj->oy == u.uy && obj->olet == WEAPON_SYM) { 1070. pline("You fell on %s.",doname(obj)); 1071. losehp(rn2(3),"fall onto a sink"); 1072. } 1073. 1074. Levitation += 1; 1075. if(uleft && uleft->otyp == RIN_LEVITATION) { 1076. obj = uleft; 1077. ringoff(obj); 1078. off_msg(obj); 1079. } 1080. if(uright && uright->otyp == RIN_LEVITATION) { 1081. obj = uright; 1082. ringoff(obj); 1083. off_msg(obj); 1084. } 1085. Levitation = 0; 1086. } 1087. #endif
|