abstract
| - Below is the full text to hack.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/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, 1984. */ 2. 3. #include "hack.h" 4. #include 5. 6. 7. extern char news0(); 8. extern char *nomovemsg; 9. extern char *exclam(); 10. extern struct obj *addinv(); 11. extern boolean hmon(); 12. 13. 14. 15. /* called on movement: 16. 1. when throwing ball+chain far away 17. 2. when teleporting 18. 3. when walking out of a lit room 19. */ 20. unsee() { 21. register x,y; 22. register struct rm *lev; 23. 24. /* 25. if(u.udispl){ 26. u.udispl = 0; 27. newsym(u.udisx, u.udisy); 28. } 29. */ 30. #ifndef QUEST 31. if(seehx){ 32. seehx = 0; 33. } else 34. #endif QUEST 35. for(x = u.ux-1; x < u.ux+2; x++) 36. for(y = u.uy-1; y < u.uy+2; y++) { 37. lev = &levl[x][y]; 38. if(!lev->lit && lev->scrsym == '.') { 39. lev->scrsym =' '; 40. lev->new = 1; 41. on_scr(x,y); 42. } 43. } 44. } 45. 46. /* called: 47. in hack.eat.c: seeoff(0) - blind after eating rotten food 48. in hack.mon.c: seeoff(0) - blinded by a yellow light 49. in hack.mon.c: seeoff(1) - swallowed 50. in hack.do.c: seeoff(0) - blind after drinking potion 51. in hack.do.c: seeoff(1) - go up or down the stairs 52. in hack.trap.c:seeoff(1) - fall through trapdoor 53. */ 54. seeoff(mode) /* 1 to redo @, 0 to leave them */ 55. { /* 1 means misc movement, 0 means blindness */ 56. register x,y; 57. register struct rm *lev; 58. 59. if(u.udispl && mode){ 60. u.udispl = 0; 61. levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); 62. } 63. #ifndef QUEST 64. if(seehx) { 65. seehx = 0; 66. } else 67. #endif QUEST 68. if(!mode) { 69. for(x = u.ux-1; x < u.ux+2; x++) 70. for(y = u.uy-1; y < u.uy+2; y++) { 71. lev = &levl[x][y]; 72. if(!lev->lit && lev->scrsym == '.') 73. lev->seen = 0; 74. } 75. } 76. } 77. 78. /* 'rogue'-like direction commands */ 79. char sdir[] = "hykulnjb"; 80. schar xdir[8] = { -1,-1,0,1,1,1,0,-1 }; 81. schar ydir[8] = { 0,-1,-1,-1,0,1,1,1 }; 82. 83. movecm(cmd) 84. register char *cmd; 85. { 86. register char *dp; 87. if(!(dp = index(sdir, *cmd))) return(0); 88. u.dx = xdir[dp-sdir]; 89. u.dy = ydir[dp-sdir]; 90. return(1); 91. } 92. 93. #ifdef QUEST 94. finddir(){ 95. register int i, ui = u.di; 96. for(i = 0; i <= 8; i++){ 97. if(flags.run & 1) ui++; else ui += 7; 98. ui %= 8; 99. if(i == 8){ 100. pline("Not near a wall."); 101. flags.move = multi = 0; 102. return(0); 103. } 104. if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui])) 105. break; 106. } 107. for(i = 0; i <= 8; i++){ 108. if(flags.run & 1) ui += 7; else ui++; 109. ui %= 8; 110. if(i == 8){ 111. pline("Not near a room."); 112. flags.move = multi = 0; 113. return(0); 114. } 115. if(isroom(u.ux+xdir[ui], u.uy+ydir[ui])) 116. break; 117. } 118. u.di = ui; 119. u.dx = xdir[ui]; 120. u.dy = ydir[ui]; 121. } 122. 123. isroom(x,y) register x,y; { 124. return(isok(x,y) && (levl[x][y].typ == ROOM || 125. (levl[x][y].typ >= LDOOR && flags.run >= 6))); 126. } 127. #endif QUEST 128. 129. isok(x,y) register x,y; { 130. return(x >= 0 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1); 131. } 132. 133. domove() 134. { 135. xchar oldx,oldy; 136. register struct monst *mtmp; 137. register struct rm *tmpr,*ust; 138. struct gen *trap; 139. register struct obj *otmp; 140. 141. wipe_engr_at(u.ux, u.uy, rnd(5)); 142. if(inv_weight() > 0){ 143. pline("You collapse under your load."); 144. nomul(0); 145. return; 146. } 147. if(Confusion) { 148. do { 149. u.dx = rn1(3,-1); 150. u.dy = rn1(3,-1); 151. tmpr = &levl[u.ux+u.dx][u.uy+u.dy]; 152. } while((!u.dx && !u.dy) || 153. !isok(u.ux+u.dx, u.uy+u.dy) || tmpr->typ < DOOR); 154. } else tmpr = &levl[u.ux+u.dx][u.uy+u.dy]; 155. if(!isok(u.ux+u.dx, u.uy+u.dy)){ 156. nomul(0); 157. return; 158. } 159. 160. ust = &levl[u.ux][u.uy]; 161. oldx = u.ux; 162. oldy = u.uy; 163. if(!u.uswallow) 164. if(trap = g_at(u.ux+u.dx,u.uy+u.dy,ftrap)) { 165. if(trap->gflag & SEEN) nomul(0); 166. } 167. if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx || 168. u.uy+u.dy != u.ustuck->my)) { 169. if(dist(u.ustuck->mx, u.ustuck->my) > 2){ 170. /* perhaps it fled (or was teleported or ... ) */ 171. u.ustuck = 0; 172. } else { 173. if(Blind) pline("You cannot escape from it!"); 174. else pline("You cannot escape from %s!.", 175. monnam(u.ustuck)); 176. nomul(0); 177. return; 178. } 179. } 180. if((mtmp = m_at(u.ux+u.dx,u.uy+u.dy)) || u.uswallow) { 181. /* attack monster */ 182. schar tmp; 183. boolean malive = TRUE; 184. register struct permonst *mdat; 185. 186. nomul(0); 187. gethungry(); 188. if(multi < 0) return; /* we just fainted */ 189. if(u.uswallow) mtmp = u.ustuck; 190. mdat = mtmp->data; 191. if(mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep && 192. !mtmp->mconf && mtmp->mcansee && !rn2(7) && 193. (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */ 194. mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) 195. goto nomon; 196. if(mtmp->mimic){ 197. if(!u.ustuck && !mtmp->mflee) u.ustuck = mtmp; 198. switch(levl[u.ux+u.dx][u.uy+u.dy].scrsym){ 199. case '+': 200. pline("The door actually was a Mimic."); 201. break; 202. case '$': 203. pline("The chest was a Mimic!"); 204. break; 205. default: 206. pline("Wait! That's a Mimic!"); 207. } 208. wakeup(mtmp); /* clears mtmp->mimic */ 209. return; 210. } 211. wakeup(mtmp); /* clears mtmp->mimic */ 212. if(mtmp->mhide && mtmp->mundetected){ 213. register struct obj *obj; 214. mtmp->mundetected = 0; 215. if((obj = o_at(mtmp->mx,mtmp->my)) && !Blind) 216. pline("Wait! There's a %s hiding under %s!", 217. mdat->mname, doname(obj)); 218. return; 219. } 220. tmp = u.uluck + u.ulevel + mdat->ac + abon(); 221. if(uwep) { 222. if(uwep->olet == WEAPON_SYM) 223. tmp += uwep->spe; 224. if(uwep->otyp == TWO_HANDED_SWORD) tmp -= 1; 225. else if(uwep->otyp == DAGGER) tmp += 2; 226. else if(uwep->otyp == CRYSKNIFE) tmp += 3; 227. else if(uwep->otyp == SPEAR && 228. index("XDne", mdat->mlet)) tmp += 2; 229. } 230. if(mtmp->msleep) { 231. mtmp->msleep = 0; 232. tmp += 2; 233. } 234. if(mtmp->mfroz) { 235. tmp += 4; 236. if(!rn2(10)) mtmp->mfroz = 0; 237. } 238. if(mtmp->mflee) tmp += 2; 239. if(u.utrap) tmp -= 3; 240. if(tmp <= rnd(20) && !u.uswallow){ 241. if(Blind) pline("You miss it."); 242. else pline("You miss %s.",monnam(mtmp)); 243. } else { 244. /* we hit the monster; be careful: it might die! */ 245. 246. if((malive = hmon(mtmp,uwep,0)) == TRUE) { 247. /* monster still alive */ 248. if(!rn2(25) && mtmp->mhp < mtmp->orig_hp/2) { 249. mtmp->mflee = 1; 250. if(u.ustuck == mtmp && !u.uswallow) 251. u.ustuck = 0; 252. } 253. #ifndef NOWORM 254. if(mtmp->wormno) 255. cutworm(mtmp, u.ux+u.dx, u.uy+u.dy, 256. uwep ? uwep->otyp : 0); 257. #endif NOWORM 258. } 259. if(mdat->mlet == 'a') { 260. if(rn2(2)) { 261. pline("You are splashed by the blob's acid!"); 262. losehp_m(rnd(6), mtmp); 263. } 264. if(!rn2(6)) corrode_weapon(); 265. else if(!rn2(60)) corrode_armor(); 266. } 267. } 268. if(malive && !Blind && mdat->mlet == 'E' && rn2(3)) { 269. if(mtmp->mcansee) { 270. pline("You are frozen by the floating eye's gaze!"); 271. nomul((u.ulevel > 6 || rn2(4)) ? rn1(20,-21) : -200); 272. } else { 273. pline("The blinded floating eye cannot defend itself."); 274. if(!rn2(500)) u.uluck--; 275. } 276. } 277. return; 278. } 279. nomon: 280. /* not attacking an animal, so we try to move */ 281. if(u.utrap) { 282. if(u.utraptype == TT_PIT) { 283. pline("You are still in a pit."); 284. u.utrap--; 285. } else { 286. pline("You are caught in a beartrap."); 287. if((u.dx && u.dy) || !rn2(5)) u.utrap--; 288. } 289. return; 290. } 291. if((tmpr->typ < DOOR) || 292. (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){ 293. flags.move = 0; 294. nomul(0); 295. return; 296. } 297. while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) { 298. register xchar rx = u.ux+2*u.dx, ry = u.uy+2*u.dy; 299. register struct gen *gtmp; 300. nomul(0); 301. if(isok(rx,ry) && (levl[rx][ry].typ > DOOR || 302. (levl[rx][ry].typ == DOOR && (!u.dx || !u.dy)))) { 303. if(m_at(rx,ry)) { 304. pline("You hear a monster behind the rock."); 305. pline("Perhaps that's why you cannot move it."); 306. return; 307. } 308. if(gtmp = g_at(rx,ry,ftrap)) 309. #include "def.trap.h" 310. switch(gtmp->gflag & ~SEEN) { 311. case PIT: 312. pline("You push the rock into a pit!"); 313. deltrap(gtmp); 314. delobj(otmp); 315. pline("It completely fills the pit!"); 316. continue; 317. case TELEP_TRAP: 318. pline("You push the rock and suddenly it disappears!"); 319. delobj(otmp); 320. continue; 321. } 322. otmp->ox = rx; 323. otmp->oy = ry; 324. /* pobj(otmp); */ 325. if(cansee(rx,ry)) atl(rx,ry,otmp->olet); 326. if(Invis) newsym(u.ux+u.dx, u.uy+u.dy); 327. 328. { static int lastmovetime; 329. /* note: this var contains garbage initially and 330. after a restore */ 331. if(moves > lastmovetime+2 || moves < lastmovetime) 332. pline("With great effort you move the enormous rock."); 333. lastmovetime = moves; 334. } 335. } else { 336. pline("You try to move the enormous rock, but in vain."); 337. return; 338. } 339. } 340. if(u.dx && u.dy && levl[u.ux][u.uy+u.dy].typ < DOOR && 341. levl[u.ux+u.dx][u.uy].typ < DOOR && 342. invent && inv_weight()+40 > 0) { 343. pline("You are carrying too much to get through."); 344. nomul(0); 345. return; 346. } 347. if(Punished && 348. DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){ 349. if(carried(uball)) { 350. movobj(uchain, u.ux, u.uy); 351. goto nodrag; 352. } 353. 354. if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){ 355. /* leave ball, move chain under/over ball */ 356. movobj(uchain, uball->ox, uball->oy); 357. goto nodrag; 358. } 359. 360. if(inv_weight() + (int) uball->owt/2 > 0) { 361. pline("You cannot %sdrag the heavy iron ball.", 362. invent ? "carry all that and also " : ""); 363. nomul(0); 364. return; 365. } 366. 367. movobj(uball, uchain->ox, uchain->oy); 368. unpobj(uball); /* BAH %% */ 369. uchain->ox = u.ux; 370. uchain->oy = u.uy; 371. nomul(-2); 372. nomovemsg = ""; 373. nodrag: ; 374. } 375. u.ux += u.dx; 376. u.uy += u.dy; 377. if(flags.run) { 378. if(tmpr->typ == DOOR || 379. (xupstair == u.ux && yupstair == u.uy) || 380. (xdnstair == u.ux && ydnstair == u.uy)) 381. nomul(0); 382. } 383. /* 384. if(u.udispl) { 385. u.udispl = 0; 386. newsym(oldx,oldy); 387. } 388. */ 389. if(!Blind) { 390. #ifdef QUEST 391. setsee(); 392. #else 393. if(ust->lit) { 394. if(tmpr->lit) { 395. if(tmpr->typ == DOOR) prl1(u.ux+u.dx,u.uy+u.dy); 396. else if(ust->typ == DOOR) nose1(oldx-u.dx,oldy-u.dy); 397. } else { 398. unsee(); 399. prl1(u.ux+u.dx,u.uy+u.dy); 400. } 401. } else { 402. if(tmpr->lit) setsee(); 403. else { 404. prl1(u.ux+u.dx,u.uy+u.dy); 405. if(tmpr->typ == DOOR) { 406. if(u.dy) { 407. prl(u.ux-1,u.uy); 408. prl(u.ux+1,u.uy); 409. } else { 410. prl(u.ux,u.uy-1); 411. prl(u.ux,u.uy+1); 412. } 413. } 414. } 415. nose1(oldx-u.dx,oldy-u.dy); 416. } 417. #endif QUEST 418. } else { 419. pru(); 420. } 421. if(!flags.nopick) pickup(); 422. if(trap) dotrap(trap); /* fall into pit, arrow trap, etc. */ 423. (void) inshop(); 424. if(!Blind) read_engr_at(u.ux,u.uy); 425. } 426. 427. movobj(obj, ox, oy) 428. register struct obj *obj; 429. register int ox, oy; 430. { 431. /* Some dirty programming to get display right */ 432. freeobj(obj); 433. unpobj(obj); 434. obj->nobj = fobj; 435. fobj = obj; 436. obj->ox = ox; 437. obj->oy = oy; 438. } 439. 440. pickup(){ 441. register struct gen *gold; 442. register struct obj *obj, *obj2; 443. register int wt; 444. if(Levitation) return; 445. while(gold = g_at(u.ux,u.uy,fgold)) { 446. pline("%u gold piece%s.", gold->gflag, plur(gold->gflag)); 447. u.ugold += gold->gflag; 448. flags.botl = 1; 449. freegold(gold); 450. if(flags.run) nomul(0); 451. if(Invis) newsym(u.ux,u.uy); 452. } 453. for(obj = fobj; obj; obj = obj2) { 454. obj2 = obj->nobj; /* perhaps obj will be picked up */ 455. if(obj->ox == u.ux && obj->oy == u.uy) { 456. if(flags.run) nomul(0); 457. 458. #define DEAD_c CORPSE+('c'-'a'+'Z'-'@'+1) 459. if(obj->otyp == DEAD_COCKATRICE && !uarmg){ 460. pline("Touching the dead cockatrice is a fatal mistake."); 461. pline("You turn to stone."); 462. killer = "cockatrice cadaver"; 463. done("died"); 464. } 465. 466. if(obj->otyp == SCR_SCARE_MONSTER){ 467. if(!obj->spe) obj->spe = 1; 468. else { 469. /* Note: perhaps the 1st pickup failed: you cannot 470. carry anymore, and so we never dropped it - 471. let's assume that treading on it twice also 472. destroys the scroll */ 473. pline("The scroll turns to dust as you pick it up."); 474. delobj(obj); 475. continue; 476. } 477. } 478. 479. /* do not pick up uchain */ 480. if(Punished && obj == uchain) 481. continue; 482. 483. wt = inv_weight() + obj->owt; 484. if(wt > 0) { 485. if(obj->quan > 1) { 486. /* see how many we can lift */ 487. extern struct obj *splitobj(); 488. int savequan = obj->quan; 489. int iw = inv_weight(); 490. int qq; 491. for(qq = 1; qq < savequan; qq++){ 492. obj->quan = qq; 493. if(iw + weight(obj) > 0) 494. break; 495. } 496. obj->quan = savequan; 497. qq--; 498. /* we can carry qq of them */ 499. if(!qq) goto too_heavy; 500. pline("You can only carry %s of the %s lying here.", 501. (qq == 1) ? "one" : "some", 502. doname(obj)); 503. (void) splitobj(obj, qq); 504. /* note: obj2 is set already, so we'll never 505. * encounter the other half; if it should be 506. * otherwise then write 507. * obj2 = splitobj(obj,qq); 508. */ 509. goto lift_some; 510. } 511. too_heavy: 512. pline("There %s %s here, but %s.", 513. (obj->quan == 1) ? "is" : "are", 514. doname(obj), 515. !invent ? "it is too heavy for you to lift" 516. : "you cannot carry anymore"); 517. break; 518. } 519. lift_some: 520. if(inv_cnt() >= 52) { 521. pline("Your knapsack cannot accomodate anymore items."); 522. break; 523. } 524. if(wt > -5) pline("You have a little trouble lifting"); 525. freeobj(obj); 526. if(Invis) newsym(u.ux,u.uy); 527. addtobill(obj); /* sets obj->unpaid if necessary */ 528. { int pickquan = obj->quan; 529. int mergquan; 530. if(!Blind) obj->dknown = 1; /* this is done by prinv(), 531. but addinv() needs it already for merging */ 532. obj = addinv(obj); /* might merge it with other objects */ 533. mergquan = obj->quan; 534. obj->quan = pickquan; /* to fool prinv() */ 535. prinv(obj); 536. obj->quan = mergquan; 537. } 538. } 539. } 540. } 541. 542. /* stop running if we see something interesting */ 543. /* turn around a corner if that is the only way we can proceed */ 544. /* do not turn left or right twice */ 545. lookaround(){ 546. register x,y,i,x0,y0,m0,i0 = 9; 547. register int corrct = 0, noturn = 0; 548. register struct monst *mtmp; 549. #ifdef lint 550. /* suppress "used before set" message */ 551. x0 = y0 = 0; 552. #endif lint 553. if(Blind || flags.run == 0) return; 554. if(flags.run == 1 && levl[u.ux][u.uy].typ >= ROOM) return; 555. #ifdef QUEST 556. if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop; 557. #endif QUEST 558. for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ 559. if(x == u.ux && y == u.uy) continue; 560. if(!levl[x][y].typ) continue; 561. if((mtmp = m_at(x,y)) && !mtmp->mimic && 562. (!mtmp->minvis || See_invisible)){ 563. if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy)) 564. goto stop; 565. } else mtmp = 0; /* invisible M cannot influence us */ 566. if(x == u.ux-u.dx && y == u.uy-u.dy) continue; 567. switch(levl[x][y].scrsym){ 568. case '|': 569. case '-': 570. case '.': 571. case ' ': 572. break; 573. case '+': 574. if(x != u.ux && y != u.uy) break; 575. if(flags.run != 1) goto stop; 576. /* fall into next case */ 577. case CORR_SYM: 578. corr: 579. if(flags.run == 1 || flags.run == 3) { 580. i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); 581. if(i > 2) break; 582. if(corrct == 1 && DIST(x,y,x0,y0) != 1) 583. noturn = 1; 584. if(i < i0) { 585. i0 = i; 586. x0 = x; 587. y0 = y; 588. m0 = mtmp ? 1 : 0; 589. } 590. } 591. corrct++; 592. break; 593. case '^': 594. if(flags.run == 1) goto corr; /* if you must */ 595. if(x == u.ux+u.dx && y == u.uy+u.dx) goto stop; 596. break; 597. default: /* e.g. objects or trap or stairs */ 598. if(flags.run == 1) goto corr; 599. if(mtmp) break; /* d */ 600. stop: 601. nomul(0); 602. return; 603. } 604. } 605. #ifdef QUEST 606. if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop; 607. #endif QUEST 608. if(corrct > 1 && flags.run == 2) goto stop; 609. if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && 610. (corrct == 1 || (corrct == 2 && i0 == 1))) { 611. /* make sure that we do not turn too far */ 612. if(i0 == 2) { 613. if(u.dx == y0-u.uy && u.dy == u.ux-x0) 614. i = 2; /* straight turn right */ 615. else 616. i = -2; /* straight turn left */ 617. } else if(u.dx && u.dy) { 618. if((u.dx == u.dy && y0 == u.uy) || 619. (u.dx != u.dy && y0 != u.uy)) 620. i = -1; /* half turn left */ 621. else 622. i = 1; /* half turn right */ 623. } else { 624. if((x0-u.ux == y0-u.uy && !u.dy) || 625. (x0-u.ux != y0-u.uy && u.dy)) 626. i = 1; /* half turn right */ 627. else 628. i = -1; /* half turn left */ 629. } 630. i += u.last_str_turn; 631. if(i <= 2 && i >= -2) { 632. u.last_str_turn = i; 633. u.dx = x0-u.ux, u.dy = y0-u.uy; 634. } 635. } 636. } 637. 638. #ifdef QUEST 639. cansee(x,y) xchar x,y; { 640. register int dx,dy,adx,ady,sdx,sdy,dmax,d; 641. if(Blind) return(0); 642. if(!isok(x,y)) return(0); 643. d = dist(x,y); 644. if(d < 3) return(1); 645. if(d > u.uhorizon*u.uhorizon) return(0); 646. if(!levl[x][y].lit) 647. return(0); 648. dx = x - u.ux; adx = abs(dx); sdx = sgn(dx); 649. dy = y - u.uy; ady = abs(dy); sdy = sgn(dy); 650. if(dx == 0 || dy == 0 || adx == ady){ 651. dmax = (dx == 0) ? ady : adx; 652. for(d = 1; d <= dmax; d++) 653. if(!rroom(sdx*d,sdy*d)) 654. return(0); 655. return(1); 656. } else if(ady > adx){ 657. for(d = 1; d <= ady; d++){ 658. if(!rroom(sdx*( (d*adx)/ady ), sdy*d) || 659. !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d)) 660. return(0); 661. } 662. return(1); 663. } else { 664. for(d = 1; d <= adx; d++){ 665. if(!rroom(sdx*d, sdy*( (d*ady)/adx )) || 666. !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 ))) 667. return(0); 668. } 669. return(1); 670. } 671. } 672. 673. rroom(x,y) register int x,y; { 674. return(levl[u.ux+x][u.uy+y].typ >= ROOM); 675. } 676. 677. #else 678. 679. cansee(x,y) xchar x,y; { 680. if(Blind || u.uswallow) return(0); 681. if(dist(x,y) < 3) return(1); 682. if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y && 683. y <= seehy) return(1); 684. return(0); 685. } 686. #endif QUEST 687. 688. sgn(a) register int a; { 689. return((a> 0) ? 1 : (a == 0) ? 0 : -1); 690. } 691. 692. pow(num) /* returns 2 to the num */ 693. register unsigned num; 694. { 695. return(1 << num); 696. } 697. 698. #ifdef QUEST 699. setsee() 700. { 701. register x,y; 702. 703. if(Blind) { 704. pru(); 705. return; 706. } 707. for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++) 708. for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) { 709. if(cansee(x,y)) 710. prl(x,y); 711. } 712. } 713. 714. #else 715. 716. setsee() 717. { 718. register x,y; 719. 720. if(Blind) { 721. pru(); 722. return; 723. } 724. if(!levl[u.ux][u.uy].lit) { 725. seelx = u.ux-1; 726. seehx = u.ux+1; 727. seely = u.uy-1; 728. seehy = u.uy+1; 729. } else { 730. for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--); 731. for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++); 732. for(seely = u.uy; levl[u.ux][seely-1].lit; seely--); 733. for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++); 734. } 735. for(y = seely; y <= seehy; y++) 736. for(x = seelx; x <= seehx; x++) { 737. prl(x,y); 738. } 739. if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ 740. else { 741. if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); 742. if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); 743. if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); 744. if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); 745. } 746. } 747. #endif QUEST 748. 749. nomul(nval) 750. register nval; 751. { 752. if(multi < 0) return; 753. multi = nval; 754. flags.mv = flags.run = 0; 755. } 756. 757. abon() 758. { 759. if(u.ustr == 3) return(-3); 760. else if(u.ustr < 6) return(-2); 761. else if(u.ustr < 8) return(-1); 762. else if(u.ustr < 17) return(0); 763. else if(u.ustr < 69) return(1); /* up to 18/50 */ 764. else if(u.ustr < 118) return(2); 765. else return(3); 766. } 767. 768. dbon() 769. { 770. if(u.ustr < 6) return(-1); 771. else if(u.ustr < 16) return(0); 772. else if(u.ustr < 18) return(1); 773. else if(u.ustr == 18) return(2); /* up to 18 */ 774. else if(u.ustr < 94) return(3); /* up to 18/75 */ 775. else if(u.ustr < 109) return(4); /* up to 18/90 */ 776. else if(u.ustr < 118) return(5); /* up to 18/99 */ 777. else return(6); 778. } 779. 780. losestr(num) 781. register num; 782. { 783. u.ustr -= num; 784. while(u.ustr < 3) { 785. u.ustr++; 786. u.uhp -= 6; 787. u.uhpmax -= 6; 788. } 789. flags.botl = 1; 790. } 791. 792. losehp(n,knam) 793. register n; 794. register char *knam; 795. { 796. u.uhp -= n; 797. if(u.uhp > u.uhpmax) 798. u.uhpmax = u.uhp; /* perhaps n was negative */ 799. flags.botl = 1; 800. if(u.uhp < 1) 801. killer = knam; /* the thing that killed you */ 802. } 803. 804. losehp_m(n,mtmp) 805. register n; 806. register struct monst *mtmp; 807. { 808. u.uhp -= n; 809. flags.botl = 1; 810. if(u.uhp < 1) done_in_by(mtmp); 811. } 812. 813. losexp() /* hit by V or W */ 814. { 815. register num; 816. 817. if(u.ulevel > 1) pline("Goodbye level %d.",u.ulevel--); 818. else u.uhp = -1; 819. num = rnd(10); 820. u.uhp -= num; 821. u.uhpmax -= num; 822. u.uexp = 10*pow(u.ulevel-1); 823. flags.botl = 1; 824. } 825. 826. inv_weight(){ 827. register struct obj *otmp = invent; 828. register int wt = 0; 829. register int carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel); 830. if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 831. if(Wounded_legs & LEFT_SIDE) carrcap -= 10; 832. if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; 833. while(otmp){ 834. wt += otmp->owt; 835. otmp = otmp->nobj; 836. } 837. return(wt - carrcap); 838. } 839. 840. inv_cnt(){ 841. register struct obj *otmp = invent; 842. register int ct = 0; 843. while(otmp){ 844. ct++; 845. otmp = otmp->nobj; 846. } 847. return(ct); 848. }
|