About: Source:NetHack 3.2.0/ball.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to ball.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/ball.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

AttributesValues
rdfs:label
  • Source:NetHack 3.2.0/ball.c
rdfs:comment
  • Below is the full text to ball.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/ball.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/pro...iPageUsesTemplate
abstract
  • Below is the full text to ball.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/ball.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)ball.c 3.2 95/05/31 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* Ball & Chain =============================================================*/ 6. 7. #include "hack.h" 8. 9. static int NDECL(bc_order); 10. static void NDECL(litter); 11. 12. void 13. ballfall() 14. { 15. boolean gets_hit; 16. 17. gets_hit = (((uball->ox != u.ux) || (uball->oy != u.uy)) && 18. ((uwep == uball)? FALSE : (boolean)rn2(5))); 19. if (carried(uball)) { 20. pline("Startled, you drop the iron ball."); 21. if (uwep == uball) 22. setuwep((struct obj *)0); 23. if (uwep != uball) 24. freeinv(uball); 25. } 26. if(gets_hit){ 27. int dmg = rn1(7,25); 28. pline_The("iron ball falls on your %s.", 29. body_part(HEAD)); 30. if (uarmh) 31. if(is_metallic(uarmh)) { 32. pline("Fortunately, you are wearing a hard helmet."); 33. dmg = 3; 34. } else if (flags.verbose) 35. Your("%s does not protect you.", xname(uarmh)); 36. losehp(dmg, "Crunched in the head by an iron ball", 37. NO_KILLER_PREFIX); 38. } 39. } 40. 41. /* 42. * To make this work, we have to mess with the hero's mind. The rules for 43. * ball&chain are: 44. * 45. * 1. If the hero can see them, fine. 46. * 2. If the hero can't see either, it isn't seen. 47. * 3. If either is felt it is seen. 48. * 4. If either is felt and moved, it disappears. 49. * 50. * If the hero can see, then when a move is done, the ball and chain are 51. * first picked up, the positions under them are corrected, then they 52. * are moved after the hero moves. Not too bad. 53. * 54. * If the hero is blind, then she can "feel" the ball and/or chain at any 55. * time. However, when the hero moves, the felt ball and/or chain become 56. * unfelt and whatever was felt "under" the ball&chain appears. Pretty 57. * nifty, but it requires that the ball&chain "remember" what was under 58. * them --- i.e. they pick-up glyphs when they are felt and drop them when 59. * moved (and felt). When swallowed, the ball&chain are pulled completely 60. * off of the dungeon, but are still on the object chain. They are placed 61. * under the hero when she is expelled. 62. */ 63. 64. /* 65. * from you.h 66. * int u.bglyph glyph under the ball 67. * int u.cglyph glyph under the chain 68. * int u.bc_felt mask for ball/chain being felt 69. * #define BC_BALL 0x01 bit mask in u.bc_felt for ball 70. * #define BC_CHAIN 0x02 bit mask in u.bc_felt for chain 71. * int u.bc_order ball & chain order 72. * 73. * u.bc_felt is also manipulated in display.c and read.c, the others only 74. * in this file. None of these variables are valid unless the player is 75. * Blind. 76. */ 77. 78. /* values for u.bc_order */ 79. #define BCPOS_DIFFER 0 /* ball & chain at different positions */ 80. #define BCPOS_CHAIN 1 /* chain on top of ball */ 81. #define BCPOS_BALL 2 /* ball on top of chain */ 82. 83. 84. 85. /* 86. * Place the ball & chain under the hero. Make sure that the ball & chain 87. * variables are set (actually only needed when blind, but what the heck). 88. * It is assumed that when this is called, the ball and chain are NOT 89. * attached to the object list. 90. * 91. * Should not be called while swallowed. 92. */ 93. void 94. placebc() 95. { 96. if (!uchain || !uball) { 97. impossible("Where are your ball and chain?"); 98. return; 99. } 100. 101. (void) flooreffects(uchain, u.ux, u.uy, ""); /* chain might rust */ 102. 103. if (carried(uball)) /* the ball is carried */ 104. u.bc_order = BCPOS_DIFFER; 105. else { 106. /* ball might rust -- already checked when carried */ 107. (void) flooreffects(uball, u.ux, u.uy, ""); 108. place_object(uball, u.ux, u.uy); 109. u.bc_order = BCPOS_CHAIN; 110. } 111. 112. place_object(uchain, u.ux, u.uy); 113. 114. u.bglyph = u.cglyph = levl[u.ux][u.uy].glyph; /* pick up glyph */ 115. 116. newsym(u.ux,u.uy); 117. } 118. 119. void 120. unplacebc() 121. { 122. if (u.uswallow) return; /* ball&chain not placed while swallowed */ 123. 124. if (!carried(uball)) { 125. obj_extract_self(uball); 126. if (Blind && (u.bc_felt & BC_BALL)) /* drop glyph */ 127. levl[uball->ox][uball->oy].glyph = u.bglyph; 128. 129. newsym(uball->ox,uball->oy); 130. } 131. obj_extract_self(uchain); 132. if (Blind && (u.bc_felt & BC_CHAIN)) /* drop glyph */ 133. levl[uchain->ox][uchain->oy].glyph = u.cglyph; 134. 135. newsym(uchain->ox,uchain->oy); 136. u.bc_felt = 0; /* feel nothing */ 137. } 138. 139. 140. /* 141. * Return the stacking of the hero's ball & chain. This assumes that the 142. * hero is being punished. 143. */ 144. static int 145. bc_order() 146. { 147. struct obj *obj; 148. 149. if (uchain->ox != uball->ox || uchain->oy != uball->oy || carried(uball) 150. || u.uswallow) 151. return BCPOS_DIFFER; 152. 153. for (obj = level.objects[uball->ox][uball->oy]; obj; obj = obj->nexthere) { 154. if (obj == uchain) return BCPOS_CHAIN; 155. if (obj == uball) return BCPOS_BALL; 156. } 157. impossible("bc_order: ball&chain not in same location!"); 158. return BCPOS_DIFFER; 159. } 160. 161. /* 162. * set_bc() 163. * 164. * The hero is either about to go blind or already blind and just punished. 165. * Set up the ball and chain variables so that the ball and chain are "felt". 166. */ 167. void 168. set_bc(already_blind) 169. int already_blind; 170. { 171. int ball_on_floor = !carried(uball); 172. 173. u.bc_order = bc_order(); /* get the order */ 174. u.bc_felt = ball_on_floor ? BC_BALL|BC_CHAIN : BC_CHAIN; /* felt */ 175. 176. if (already_blind || u.uswallow) { 177. u.cglyph = u.bglyph = levl[u.ux][u.uy].glyph; 178. return; 179. } 180. 181. /* 182. * Since we can still see, remove the ball&chain and get the glyph that 183. * would be beneath them. Then put the ball&chain back. This is pretty 184. * disgusting, but it will work. 185. */ 186. remove_object(uchain); 187. if (ball_on_floor) remove_object(uball); 188. 189. newsym(uchain->ox, uchain->oy); 190. u.cglyph = levl[uchain->ox][uchain->oy].glyph; 191. 192. if (u.bc_order == BCPOS_DIFFER) { /* different locations */ 193. place_object(uchain, uchain->ox, uchain->oy); 194. newsym(uchain->ox, uchain->oy); 195. if (ball_on_floor) { 196. newsym(uball->ox, uball->oy); /* see under ball */ 197. u.bglyph = levl[uball->ox][uball->oy].glyph; 198. place_object(uball, uball->ox, uball->oy); 199. newsym(uball->ox, uball->oy); /* restore ball */ 200. } 201. } else { 202. u.bglyph = u.cglyph; 203. if (u.bc_order == BCPOS_CHAIN) { 204. place_object(uball, uball->ox, uball->oy); 205. place_object(uchain, uchain->ox, uchain->oy); 206. } else { 207. place_object(uchain, uchain->ox, uchain->oy); 208. place_object(uball, uball->ox, uball->oy); 209. } 210. newsym(uball->ox, uball->oy); 211. } 212. } 213. 214. 215. /* 216. * move_bc() 217. * 218. * Move the ball and chain. This is called twice for every move. The first 219. * time to pick up the ball and chain before the move, the second time to 220. * place the ball and chain after the move. If the ball is carried, this 221. * function should never have BC_BALL as part of its control. 222. * 223. * Should not be called while swallowed. 224. */ 225. void 226. move_bc(before, control, ballx, bally, chainx, chainy) 227. int before, control; 228. xchar ballx, bally, chainx, chainy; /* only matter !before */ 229. { 230. if (Blind) { 231. /* 232. * The hero is blind. Time to work hard. The ball and chain that 233. * are attached to the hero are very special. The hero knows that 234. * they are attached, so when they move, the hero knows that they 235. * aren't at the last position remembered. This is complicated 236. * by the fact that the hero can "feel" the surrounding locations 237. * at any time, hence, making one or both of them show up again. 238. * So, we have to keep track of which is felt at any one time and 239. * act accordingly. 240. */ 241. if (!before) { 242. if ((control & BC_CHAIN) && (control & BC_BALL)) { 243. /* 244. * Both ball and chain moved. If felt, drop glyph. 245. */ 246. if (u.bc_felt & BC_BALL) 247. levl[uball->ox][uball->oy].glyph = u.bglyph; 248. if (u.bc_felt & BC_CHAIN) 249. levl[uchain->ox][uchain->oy].glyph = u.cglyph; 250. u.bc_felt = 0; 251. 252. /* Pick up glyph at new location. */ 253. u.bglyph = levl[ballx][bally].glyph; 254. u.cglyph = levl[chainx][chainy].glyph; 255. 256. movobj(uball,ballx,bally); 257. movobj(uchain,chainx,chainy); 258. } else if (control & BC_BALL) { 259. if (u.bc_felt & BC_BALL) { 260. if (u.bc_order == BCPOS_DIFFER) { /* ball by itself */ 261. levl[uball->ox][uball->oy].glyph = u.bglyph; 262. } else if (u.bc_order == BCPOS_BALL) { 263. if (u.bc_felt & BC_CHAIN) { /* know chain is there */ 264. map_object(uchain, 0); 265. } else { 266. levl[uball->ox][uball->oy].glyph = u.bglyph; 267. } 268. } 269. u.bc_felt &= ~BC_BALL; /* no longer feel the ball */ 270. } 271. 272. /* Pick up glyph at new position. */ 273. u.bglyph = (ballx != chainx || bally != chainy) ? 274. levl[ballx][bally].glyph : u.cglyph; 275. 276. movobj(uball,ballx,bally); 277. } else if (control & BC_CHAIN) { 278. if (u.bc_felt & BC_CHAIN) { 279. if (u.bc_order == BCPOS_DIFFER) { 280. levl[uchain->ox][uchain->oy].glyph = u.cglyph; 281. } else if (u.bc_order == BCPOS_CHAIN) { 282. if (u.bc_felt & BC_BALL) { 283. map_object(uball, 0); 284. } else { 285. levl[uchain->ox][uchain->oy].glyph = u.cglyph; 286. } 287. } 288. u.bc_felt &= ~BC_CHAIN; 289. } 290. /* Pick up glyph at new position. */ 291. u.cglyph = (ballx != chainx || bally != chainy) ? 292. levl[chainx][chainy].glyph : u.bglyph; 293. 294. movobj(uchain,chainx,chainy); 295. } 296. 297. u.bc_order = bc_order(); /* reset the order */ 298. } 299. 300. } else { 301. /* 302. * The hero is not blind. To make this work correctly, we need to 303. * pick up the ball and chain before the hero moves, then put them 304. * in their new positions after the hero moves. 305. */ 306. if (before) { 307. if (!control) { 308. /* 309. * Neither ball nor chain is moving, so remember which was 310. * on top until !before. Use the variable u.bc_order 311. * since it is only valid when blind. 312. */ 313. u.bc_order = bc_order(); 314. } 315. 316. remove_object(uchain); 317. newsym(uchain->ox, uchain->oy); 318. if (!carried(uball)) { 319. remove_object(uball); 320. newsym(uball->ox, uball->oy); 321. } 322. } else { 323. int on_floor = !carried(uball); 324. 325. if ((control & BC_CHAIN) || 326. (!control && u.bc_order == BCPOS_CHAIN)) { 327. /* If the chain moved or nothing moved & chain on top. */ 328. if (on_floor) place_object(uball, ballx, bally); 329. place_object(uchain, chainx, chainy); /* chain on top */ 330. } else { 331. place_object(uchain, chainx, chainy); 332. if (on_floor) place_object(uball, ballx, bally); 333. /* ball on top */ 334. } 335. newsym(chainx, chainy); 336. if (on_floor) newsym(ballx, bally); 337. } 338. } 339. } 340. 341. /* return TRUE if ball could be dragged 342. * 343. * Should not be called while swallowed. 344. */ 345. boolean 346. drag_ball(x, y, bc_control, ballx, bally, chainx, chainy, cause_delay) 347. xchar x, y; 348. int *bc_control; 349. xchar *ballx, *bally, *chainx, *chainy; 350. boolean *cause_delay; 351. { 352. struct trap *t = (struct trap *)0; 353. 354. *ballx = uball->ox; 355. *bally = uball->oy; 356. *chainx = uchain->ox; 357. *chainy = uchain->oy; 358. *bc_control = 0; 359. *cause_delay = FALSE; 360. 361. if (dist2(x, y, uchain->ox, uchain->oy) <= 2) { /* nothing moved */ 362. move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy); 363. return TRUE; 364. } 365. 366. if (carried(uball) || dist2(x, y, uball->ox, uball->oy) < 3 || 367. (uball->ox == uchain->ox && uball->oy == uchain->oy)) { 368. /* 369. * Case where the ball doesn't move but the chain can't just move 370. * to the player's position: 371. * @ _ 372. * _ moving southwest becomes @_ and not @ 373. * 0 0 0 374. */ 375. *bc_control = BC_CHAIN; 376. move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy); 377. if (dist2(x, y, uball->ox, uball->oy) == 2 && 378. dist2(x, y, uchain->ox, uchain->oy) == 4) { 379. if (uchain->oy == y) 380. *chainx = uball->ox; 381. else 382. *chainy = uball->oy; 383. } else { 384. *chainx = u.ux; 385. *chainy = u.uy; 386. } 387. return TRUE; 388. } 389. 390. if (near_capacity() > SLT_ENCUMBER) { 391. You("cannot %sdrag the heavy iron ball.", 392. invent ? "carry all that and also " : ""); 393. nomul(0); 394. return FALSE; 395. } 396. 397. if ((is_pool(uchain->ox, uchain->oy) && 398. /* water not mere continuation of previous water */ 399. (levl[uchain->ox][uchain->oy].typ == POOL || 400. !is_pool(uball->ox, uball->oy) || 401. levl[uball->ox][uball->oy].typ == POOL)) 402. || ((t = t_at(uchain->ox, uchain->oy)) && 403. (t->ttyp == PIT || 404. t->ttyp == SPIKED_PIT || 405. t->ttyp == HOLE || 406. t->ttyp == TRAPDOOR)) ) { 407. 408. if (Levitation) { 409. You_feel("a tug from the iron ball."); 410. if (t) t->tseen = 1; 411. } else { 412. struct monst *victim; 413. 414. You("are jerked back by the iron ball!"); 415. if ((victim = m_at(uchain->ox, uchain->oy)) != 0) { 416. int tmp; 417. 418. tmp = -2 + Luck + find_mac(victim); 419. 420. if (victim->msleep) { 421. victim->msleep = 0; 422. tmp += 2; 423. } 424. if (!victim->mcanmove) { 425. tmp += 4; 426. if (!rn2(10)) { 427. victim->mcanmove = 1; 428. victim->mfrozen = 0; 429. } 430. } 431. if (tmp >= rnd(20)) 432. (void) hmon(victim,uball,1); 433. else 434. miss(xname(uball), victim); 435. 436. } /* now check again in case mon died */ 437. if (!m_at(uchain->ox, uchain->oy)) { 438. u.ux = uchain->ox; 439. u.uy = uchain->oy; 440. newsym(u.ux0, u.uy0); 441. } 442. nomul(0); 443. 444. *bc_control = BC_BALL; 445. move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy); 446. *ballx = uchain->ox; 447. *bally = uchain->oy; 448. move_bc(0, *bc_control, *ballx, *bally, *chainx, *chainy); 449. spoteffects(); 450. return FALSE; 451. } 452. } 453. 454. *bc_control = BC_BALL|BC_CHAIN;; 455. 456. move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy); 457. *ballx = uchain->ox; 458. *bally = uchain->oy; 459. *chainx = u.ux; 460. *chainy = u.uy; 461. *cause_delay = TRUE; 462. return TRUE; 463. } 464. 465. /* 466. * drop_ball() 467. * 468. * The punished hero drops or throws her iron ball. If the hero is 469. * blind, we must reset the order and glyph. Check for side effects. 470. * This routine expects the ball to be already placed. 471. * 472. * Should not be called while swallowed. 473. */ 474. void 475. drop_ball(x, y) 476. xchar x, y; 477. { 478. if (Blind) { 479. u.bc_order = bc_order(); /* get the order */ 480. /* pick up glyph */ 481. u.bglyph = (u.bc_order) ? u.cglyph : levl[x][y].glyph; 482. } 483. 484. if (x != u.ux || y != u.uy) { 485. struct trap *t; 486. const char *pullmsg = "The ball pulls you out of the %s!"; 487. 488. if (u.utrap && u.utraptype != TT_INFLOOR) { 489. switch(u.utraptype) { 490. case TT_PIT: 491. pline(pullmsg, "pit"); 492. break; 493. case TT_WEB: 494. pline(pullmsg, "web"); 495. pline_The("web is destroyed!"); 496. deltrap(t_at(u.ux,u.uy)); 497. break; 498. case TT_LAVA: 499. pline(pullmsg, "lava"); 500. break; 501. case TT_BEARTRAP: { 502. register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; 503. pline(pullmsg, "bear trap"); 504. Your("%s %s is severely damaged.", 505. (side == LEFT_SIDE) ? "left" : "right", 506. body_part(LEG)); 507. set_wounded_legs(side, rn1(1000, 500)); 508. losehp(2, "leg damage from being pulled out of a bear trap", 509. KILLED_BY); 510. break; 511. } 512. } 513. u.utrap = 0; 514. fill_pit(u.ux, u.uy); 515. } 516. 517. u.ux0 = u.ux; 518. u.uy0 = u.uy; 519. if (!Levitation && !MON_AT(x, y) && !u.utrap && 520. (is_pool(x, y) || 521. ((t = t_at(x, y)) && 522. (t->ttyp == PIT || t->ttyp == SPIKED_PIT || 523. t->ttyp == TRAPDOOR || t->ttyp == HOLE)))) { 524. u.ux = x; 525. u.uy = y; 526. } else { 527. u.ux = x - u.dx; 528. u.uy = y - u.dy; 529. } 530. vision_full_recalc = 1; /* hero has moved, recalculate vision later */ 531. 532. if (Blind) { 533. /* drop glyph under the chain */ 534. if (u.bc_felt & BC_CHAIN) 535. levl[uchain->ox][uchain->oy].glyph = u.cglyph; 536. u.bc_felt = 0; /* feel nothing */ 537. /* pick up new glyph */ 538. u.cglyph = (u.bc_order) ? u.bglyph : levl[u.ux][u.uy].glyph; 539. } 540. movobj(uchain,u.ux,u.uy); /* has a newsym */ 541. if (Blind) { 542. u.bc_order = bc_order(); 543. } 544. newsym(u.ux0,u.uy0); /* clean up old position */ 545. if (u.ux0 != u.ux || u.uy0 != u.uy) 546. spoteffects(); 547. } 548. } 549. 550. 551. static void 552. litter() 553. { 554. struct obj *otmp = invent, *nextobj; 555. int capacity = weight_cap(); 556. 557. while (otmp) { 558. nextobj = otmp->nobj; 559. if ((otmp != uball) && (rnd(capacity) <= (int)otmp->owt)) { 560. if (otmp == uwep) 561. setuwep((struct obj *)0); 562. if ((otmp != uwep) && (canletgo(otmp, ""))) { 563. Your("%s you down the stairs.", 564. aobjnam(otmp, "follow")); 565. dropx(otmp); 566. } 567. } 568. otmp = nextobj; 569. } 570. } 571. 572. void 573. drag_down() 574. { 575. boolean forward; 576. uchar dragchance = 3; 577. 578. /* 579. * Assume that the ball falls forward if: 580. * 581. * a) the character is wielding it, or 582. * b) the character has both hands available to hold it (i.e. is 583. * not wielding any weapon), or 584. * c) (perhaps) it falls forward out of his non-weapon hand 585. */ 586. 587. forward = carried(uball) && (uwep == uball || !uwep || !rn2(3)); 588. 589. if (carried(uball)) 590. You("lose your grip on the iron ball."); 591. 592. if (forward) { 593. if(rn2(6)) { 594. pline_The("iron ball drags you downstairs!"); 595. losehp(rnd(6), "dragged downstairs by an iron ball", 596. NO_KILLER_PREFIX); 597. litter(); 598. } 599. } else { 600. if(rn2(2)) { 601. pline_The("iron ball smacks into you!"); 602. losehp(rnd(20), "iron ball collision", KILLED_BY_AN); 603. exercise(A_STR, FALSE); 604. dragchance -= 2; 605. } 606. if( (int) dragchance >= rnd(6)) { 607. pline_The("iron ball drags you downstairs!"); 608. losehp(rnd(3), "dragged downstairs by an iron ball", 609. NO_KILLER_PREFIX); 610. exercise(A_STR, FALSE); 611. litter(); 612. } 613. } 614. } 615. 616. /*ball.c*/
Alternative Linked Data Views: ODE     Raw Data in: CXML | CSV | RDF ( N-Triples N3/Turtle JSON XML ) | OData ( Atom JSON ) | Microdata ( JSON HTML) | JSON-LD    About   
This material is Open Knowledge   W3C Semantic Web Technology [RDF Data] Valid XHTML + RDFa
OpenLink Virtuoso version 07.20.3217, on Linux (x86_64-pc-linux-gnu), Standard Edition
Data on this page belongs to its respective rights holders.
Virtuoso Faceted Browser Copyright © 2009-2012 OpenLink Software