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