About: Source:NetHack 3.2.0/dokick.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 dokick.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/dokick.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/dokick.c
rdfs:comment
  • Below is the full text to dokick.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/dokick.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 dokick.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/dokick.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)dokick.c 3.2 96/03/23 */ 2. /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "eshk.h" 7. 8. #define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH]) 9. #define martial() (Role_is('S') || Role_is('P') || is_bigfoot(uasmon)) 10. 11. static NEARDATA struct rm *maploc; 12. static NEARDATA const char *gate_str; 13. 14. extern boolean notonhead; /* for long worms */ 15. 16. static void FDECL(kickdmg, (struct monst *, BOOLEAN_P)); 17. static void FDECL(kick_monster, (XCHAR_P, XCHAR_P)); 18. static int FDECL(kick_object, (XCHAR_P, XCHAR_P)); 19. static char *FDECL(kickstr, (char *)); 20. static void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, int)); 21. static void FDECL(drop_to, (coord *,SCHAR_P)); 22. 23. static NEARDATA struct obj *kickobj; 24. 25. #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE) 26. 27. static void 28. kickdmg(mon, clumsy) 29. register struct monst *mon; 30. register boolean clumsy; 31. { 32. register int mdx, mdy; 33. register int dmg = ( ACURRSTR + ACURR(A_DEX) + ACURR(A_CON) )/ 15; 34. 35. /* excessive wt affects dex, so it affects dmg */ 36. if(clumsy) dmg = dmg/2; 37. 38. /* kicking a dragon or an elephant will not harm it */ 39. if(thick_skinned(mon->data)) dmg = 0; 40. 41. /* a good kick exercises your dex */ 42. exercise(A_DEX, TRUE); 43. 44. /* it is unchivalrous to attack the defenseless or from behind */ 45. if (Role_is('K') && 46. u.ualign.type == A_LAWFUL && u.ualign.record > -10 && 47. (!mon->mcanmove || mon->msleep || mon->mflee)) 48. adjalign(-1); 49. 50. /* squeeze some guilt feelings... */ 51. if(mon->mtame) { 52. abuse_dog(mon); 53. mon->mflee = mon->mtame ? 1 : 0; 54. #ifdef HISX 55. mon->mfleetim = mon->mfleetim + (dmg ? rnd(dmg) : 1); 56. #else 57. mon->mfleetim += (dmg ? rnd(dmg) : 1); 58. #endif 59. } 60. 61. if (dmg > 0) { 62. /* convert potential damage to actual damage */ 63. dmg = rnd(dmg); 64. if (martial()) dmg += rn2(ACURR(A_DEX)/2 + 1); 65. } 66. dmg += u.udaminc; /* add ring(s) of increase damage */ 67. if (dmg > 0) { 68. mon->mhp -= dmg; 69. if (mon->mhp < 1) { 70. (void) passive(mon, TRUE, 0, TRUE); 71. killed(mon); 72. return; 73. } 74. } 75. if(martial() && !bigmonst(mon->data) && !rn2(3) && mon->mcanmove 76. && mon != u.ustuck) { 77. /* see if the monster has a place to move into */ 78. mdx = mon->mx + u.dx; 79. mdy = mon->my + u.dy; 80. if(goodpos(mdx, mdy, mon, mon->data)) { 81. pline("%s reels from the blow.", Monnam(mon)); 82. remove_monster(mon->mx, mon->my); 83. newsym(mon->mx, mon->my); 84. place_monster(mon, mdx, mdy); 85. newsym(mon->mx, mon->my); 86. set_apparxy(mon); 87. } 88. } 89. (void) passive(mon, FALSE, 1, TRUE); 90. 91. } 92. 93. static void 94. kick_monster(x, y) 95. register xchar x, y; 96. { 97. register boolean clumsy = FALSE; 98. register struct monst *mon = m_at(x, y); 99. register int i, j; 100. 101. bhitpos.x = x; 102. bhitpos.y = y; 103. if (attack_checks(mon, (struct obj *)0)) return; 104. setmangry(mon); 105. 106. /* Kick attacks by kicking monsters are normal attacks, not special. 107. * If you have >1 kick attack, you get all of them. 108. */ 109. if (attacktype(uasmon, AT_KICK)) { 110. schar tmp = find_roll_to_hit(mon); 111. for(i=0; i 112. if (uasmon->mattk[i].aatyp == AT_KICK && multi >= 0) { 113. /* check multi; maybe they had 2 kicks and the first */ 114. /* was a kick against a floating eye */ 115. if (tmp > rnd(20)) { 116. int sum; 117. 118. You("kick %s.", mon_nam(mon)); 119. sum = damageum(mon, &(uasmon->mattk[i])); 120. if (sum == 2) 121. (void)passive(mon, 1, 0, TRUE); 122. else (void)passive(mon, sum, 1, TRUE); 123. } else { 124. missum(mon, &(uasmon->mattk[i])); 125. (void)passive(mon, 0, 1, TRUE); 126. } 127. } 128. } 129. return; 130. } 131. 132. if(noncorporeal(mon->data)) { 133. Your("kick passes through!"); 134. return; 135. } 136. 137. if(Levitation && !rn2(3) && verysmall(mon->data) && 138. !is_flyer(mon->data)) { 139. pline("Floating in the air, you miss wildly!"); 140. exercise(A_DEX, FALSE); 141. (void) passive(mon, FALSE, 1, TRUE); 142. return; 143. } 144. 145. i = -inv_weight(); 146. j = weight_cap(); 147. 148. if(i < (j*3)/10) { 149. if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) { 150. if(martial() && !rn2(2)) goto doit; 151. Your("clumsy kick does no damage."); 152. (void) passive(mon, FALSE, 1, TRUE); 153. return; 154. } 155. if(i < j/10) clumsy = TRUE; 156. else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE; 157. } 158. 159. if(Fumbling) clumsy = TRUE; 160. 161. else if(uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25)) 162. clumsy = TRUE; 163. doit: 164. You("kick %s.", mon_nam(mon)); 165. if(!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) && 166. mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) && 167. mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove && 168. !mon->mstun && !mon->mconf && !mon->msleep && 169. mon->data->mmove >= 12) { 170. if(!nohands(mon->data) && !rn2(martial() ? 5 : 3)) { 171. pline("%s blocks your %skick.", Monnam(mon), 172. clumsy ? "clumsy " : ""); 173. (void) passive(mon, FALSE, 1, TRUE); 174. return; 175. } else { 176. mnexto(mon); 177. if(mon->mx != x || mon->my != y) { 178. pline("%s %s, %s evading your %skick.", Monnam(mon), 179. (can_teleport(mon->data) ? "teleports" : 180. is_floater(mon->data) ? "floats" : 181. is_flyer(mon->data) ? "flutters" : 182. nolimbs(mon->data) ? "slides" : 183. "jumps"), 184. clumsy ? "easily" : "nimbly", 185. clumsy ? "clumsy " : ""); 186. (void) passive(mon, FALSE, 1, TRUE); 187. return; 188. } 189. } 190. } 191. kickdmg(mon, clumsy); 192. } 193. 194. /* 195. * Return TRUE if caught (the gold taken care of), FALSE otherwise. 196. * The gold object is *not* attached to the fobj chain! 197. */ 198. boolean 199. ghitm(mtmp, gold) 200. register struct monst *mtmp; 201. register struct obj *gold; 202. { 203. if(!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest 204. && !is_mercenary(mtmp->data)) { 205. wakeup(mtmp); 206. } else if (!mtmp->mcanmove) { 207. /* too light to do real damage */ 208. if (canseemon(mtmp)) 209. pline_The("gold hits %s.", mon_nam(mtmp)); 210. } else { 211. mtmp->msleep = 0; 212. mtmp->meating = 0; 213. if(!rn2(4)) setmangry(mtmp); /* not always pleasing */ 214. 215. /* greedy monsters catch gold */ 216. if (cansee(mtmp->mx, mtmp->my)) 217. pline("%s catches the gold.", Monnam(mtmp)); 218. mtmp->mgold += gold->quan; 219. if (mtmp->isshk) { 220. long robbed = ESHK(mtmp)->robbed; 221. 222. if (robbed) { 223. robbed -= gold->quan; 224. if (robbed < 0) robbed = 0; 225. pline_The("amount %scovers %s recent losses.", 226. !robbed ? "" : "partially ", 227. his[mtmp->female]); 228. ESHK(mtmp)->robbed = robbed; 229. if(!robbed) 230. make_happy_shk(mtmp, FALSE); 231. } else { 232. if(mtmp->mpeaceful) { 233. ESHK(mtmp)->credit += gold->quan; 234. You("have %ld zorkmid%s in credit.", 235. ESHK(mtmp)->credit, 236. plur(ESHK(mtmp)->credit)); 237. } else verbalize("Thanks, scum!"); 238. } 239. } else if (mtmp->ispriest) { 240. if (mtmp->mpeaceful) 241. verbalize("Thank you for your contribution."); 242. else verbalize("Thanks, scum!"); 243. } else if (is_mercenary(mtmp->data)) { 244. long goldreqd = 0L; 245. 246. if (rn2(3)) { 247. if (mtmp->data == &mons[PM_SOLDIER]) 248. goldreqd = 100L; 249. else if (mtmp->data == &mons[PM_SERGEANT]) 250. goldreqd = 250L; 251. else if (mtmp->data == &mons[PM_LIEUTENANT]) 252. goldreqd = 500L; 253. else if (mtmp->data == &mons[PM_CAPTAIN]) 254. goldreqd = 750L; 255. 256. if (goldreqd) { 257. if (gold->quan > goldreqd + 258. (u.ugold + u.ulevel*rn2(5))/ACURR(A_CHA)) 259. mtmp->mpeaceful = TRUE; 260. } 261. } 262. if (mtmp->mpeaceful) 263. verbalize("That should do. Now beat it!"); 264. else verbalize("That's not enough, coward!"); 265. } 266. 267. dealloc_obj(gold); 268. return(1); 269. } 270. return(0); 271. } 272. 273. static int 274. kick_object(x, y) 275. xchar x, y; 276. { 277. int range; 278. register struct monst *mon, *shkp; 279. register struct obj *otmp; 280. struct trap *trap; 281. char bhitroom; 282. boolean costly, insider, isgold, slide = FALSE; 283. 284. /* if a pile, the "top" object gets kicked */ 285. kickobj = level.objects[x][y]; 286. 287. /* kickobj should always be set due to conditions of call */ 288. if(!kickobj || kickobj->otyp == BOULDER 289. || kickobj == uball || kickobj == uchain) 290. return(0); 291. 292. if((trap = t_at(x,y)) && trap->tseen) { 293. if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) 294. && !passes_walls(uasmon)) 295. || trap->ttyp == WEB) { 296. You_cant("kick %s that's in a %s!", something, 297. trap->ttyp == WEB ? "web" : "pit"); 298. return(1); 299. } 300. } 301. 302. if(Fumbling && !rn2(3)) { 303. Your("clumsy kick missed."); 304. return(1); 305. } 306. 307. /* range < 2 means the object will not move. */ 308. /* maybe dexterity should also figure here. */ 309. range = (int)((ACURRSTR)/2 - kickobj->owt/40); 310. 311. if(martial()) range += rnd(3); 312. 313. if(is_ice(x,y)) { range += rnd(3); slide = TRUE; } 314. if(kickobj->greased) { range += rnd(3); slide = TRUE; } 315. 316. /* Mjollnir is magically too heavy to kick */ 317. if(kickobj->oartifact == ART_MJOLLNIR) range = 1; 318. 319. /* see if the object has a place to move into */ 320. if(!ZAP_POS(levl[x+u.dx][y+u.dy].typ) || closed_door(x+u.dx, y+u.dy)) 321. range = 1; 322. 323. costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) && 324. costly_spot(x, y)); 325. insider = (*u.ushops && inside_shop(u.ux, u.uy) && 326. *in_rooms(x, y, SHOPBASE) == *u.ushops); 327. 328. /* a box gets a chance of breaking open here */ 329. if(Is_box(kickobj)) { 330. boolean otrp = kickobj->otrapped; 331. struct obj *otmp2; 332. long loss = 0L; 333. 334. if(range < 2) pline("THUD!"); 335. 336. for(otmp = kickobj->cobj; otmp; otmp = otmp2) { 337. const char *result = (char *)0; 338. 339. otmp2 = otmp->nobj; 340. if (objects[otmp->otyp].oc_material == GLASS 341. && otmp->oclass != GEM_CLASS 342. && !obj_resists(otmp, 33, 100)) { 343. result = "shatter"; 344. } else if (otmp->otyp == EGG && !rn2(3)) { 345. result = "cracking"; 346. } 347. if (result) { 348. You_hear("a muffled %s.",result); 349. if(costly) loss += stolen_value(otmp, x, y, 350. (boolean)shkp->mpeaceful, TRUE); 351. if (otmp->quan > 1L) 352. useup(otmp); 353. else { 354. obj_extract_self(otmp); 355. obfree(otmp, (struct obj *) 0); 356. } 357. } 358. } 359. if(costly && loss) { 360. if(!insider) { 361. You("caused %ld zorkmids worth of damage!", loss); 362. make_angry_shk(shkp, x, y); 363. } else { 364. You("owe %s %ld zorkmids for objects destroyed.", 365. mon_nam(shkp), loss); 366. } 367. } 368. 369. if (kickobj->olocked) { 370. if (!rn2(5) || (martial() && !rn2(2))) { 371. You("break open the lock!"); 372. kickobj->olocked = 0; 373. kickobj->obroken = 1; 374. if (otrp) (void) chest_trap(kickobj, LEG, FALSE); 375. return(1); 376. } 377. } else { 378. if (!rn2(3) || (martial() && !rn2(2))) { 379. pline_The("lid slams open, then falls shut."); 380. if (otrp) (void) chest_trap(kickobj, LEG, FALSE); 381. return(1); 382. } 383. } 384. if(range < 2) return(1); 385. /* else let it fall through to the next cases... */ 386. } 387. 388. /* fragile objects should not be kicked */ 389. if (breaks(kickobj, kickobj->ox, kickobj->oy, FALSE)) return 1; 390. 391. if(IS_ROCK(levl[x][y].typ)) { 392. if ((!martial() && rn2(20) > ACURR(A_DEX)) 393. || IS_ROCK(levl[u.ux][u.uy].typ)) { 394. if (Blind) pline("It doesn't come loose."); 395. else pline("%s do%sn't come loose.", 396. The(distant_name(kickobj, xname)), 397. (kickobj->quan == 1L) ? "es" : ""); 398. return(!rn2(3) || martial()); 399. } 400. if (Blind) pline("It comes loose."); 401. else pline("%s come%s loose.", 402. The(distant_name(kickobj, xname)), 403. (kickobj->quan == 1L) ? "s" : ""); 404. obj_extract_self(kickobj); 405. newsym(x, y); 406. if (costly && (!costly_spot(u.ux, u.uy) 407. || !index(u.urooms, *in_rooms(x, y, SHOPBASE)))) 408. addtobill(kickobj, FALSE, FALSE, FALSE); 409. if(!flooreffects(kickobj,u.ux,u.uy,"fall")) { 410. place_object(kickobj, u.ux, u.uy); 411. stackobj(kickobj); 412. newsym(u.ux, u.uy); 413. } 414. return(1); 415. } 416. 417. isgold = (kickobj->oclass == GOLD_CLASS); 418. 419. /* too heavy to move. range is calculated as potential distance from 420. * player, so range == 2 means the object may move up to one square 421. * from its current position 422. */ 423. if(range < 2 || (isgold && kickobj->quan > 300L)) { 424. if(!Is_box(kickobj)) pline("Thump!"); 425. return(!rn2(3) || martial()); 426. } 427. 428. if (kickobj->quan > 1L && !isgold) (void) splitobj(kickobj, 1L); 429. 430. if (slide && !Blind) 431. pline("Whee! %s slide%s across the %s.", Doname2(kickobj), 432. kickobj->quan > 1L ? "" : "s", 433. surface(x,y)); 434. 435. obj_extract_self(kickobj); 436. newsym(x, y); 437. mon = bhit(u.dx, u.dy, range, KICKED_WEAPON, 438. (int (*)()) 0, (int (*)()) 0, kickobj); 439. 440. /* We check for whether the object falls down the stairs by 441. * calling ship_object() from bhit(). This is necessary so that if 442. * the object doesn't fall, we can continue bhit() by moving the 443. * object the rest of the way. If it does fall, bhit() returns at 444. * the fall position (which must have stairs at it). This is somewhat 445. * ugly (for instance, we need to duplicate the shop check within 446. * bhit()), and we really should be checking _whether_ it falls in there 447. * and only doing the actual fall here, but this would take a lot of 448. * rewriting. 449. */ 450. if (!mon && down_gate(bhitpos.x, bhitpos.y) != MIGR_NOWHERE) 451. return 1; 452. 453. if(mon) { 454. if (mon->isshk && 455. kickobj->where == OBJ_MINVENT && kickobj->ocarry == mon) 456. return 1; /* alert shk caught it */ 457. notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y); 458. /* awake monster if sleeping */ 459. wakeup(mon); 460. if(isgold ? ghitm(mon, kickobj) : /* caught? */ 461. thitmonst(mon, kickobj)) /* hit && used up? */ 462. return(1); 463. } 464. bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE); 465. if (costly && (!costly_spot(bhitpos.x, bhitpos.y) || 466. *in_rooms(x, y, SHOPBASE) != bhitroom)) { 467. if(isgold) 468. costly_gold(x, y, kickobj->quan); 469. else (void)stolen_value(kickobj, x, y, 470. (boolean)shkp->mpeaceful, FALSE); 471. } 472. 473. if(flooreffects(kickobj,bhitpos.x,bhitpos.y,"fall")) return(1); 474. place_object(kickobj, bhitpos.x, bhitpos.y); 475. stackobj(kickobj); 476. newsym(kickobj->ox, kickobj->oy); 477. return(1); 478. } 479. 480. static char * 481. kickstr(buf) 482. char *buf; 483. { 484. const char *what; 485. 486. if (kickobj) what = distant_name(kickobj,doname); 487. else if (IS_DOOR(maploc->typ)) what = "a door"; 488. else if (IS_STWALL(maploc->typ)) what = "a wall"; 489. else if (IS_ROCK(maploc->typ)) what = "a rock"; 490. else if (IS_THRONE(maploc->typ)) what = "a throne"; 491. #ifdef SINKS 492. else if (IS_SINK(maploc->typ)) what = "a sink"; 493. #endif 494. else if (IS_ALTAR(maploc->typ)) what = "an altar"; 495. else if (IS_DRAWBRIDGE(maploc->typ)) what = "the drawbridge"; 496. else if (maploc->typ == STAIRS) what = "the stairs"; 497. else if (maploc->typ == LADDER) what = "a ladder"; 498. else what = "something weird"; 499. return strcat(strcpy(buf, "kicking "), what); 500. } 501. 502. int 503. dokick() 504. { 505. register int x, y; 506. int avrg_attrib; 507. register struct monst *mtmp; 508. s_level *slev; 509. boolean no_kick = FALSE; 510. char buf[BUFSZ]; 511. 512. if (nolimbs(uasmon)) { 513. You("have no legs to kick with."); 514. no_kick = TRUE; 515. } else if (verysmall(uasmon)) { 516. You("are too small to do any kicking."); 517. no_kick = TRUE; 518. } else if (Wounded_legs) { 519. Your("%s %s in no shape for kicking.", 520. ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES) 521. ? (const char *)makeplural(body_part(LEG)) : body_part(LEG), 522. ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES) ? "are" : "is"); 523. no_kick = TRUE; 524. } else if (near_capacity() > SLT_ENCUMBER) { 525. Your("load is too heavy to balance yourself for a kick."); 526. no_kick = TRUE; 527. } else if (u.uinwater && !rn2(2)) { 528. Your("slow motion kick doesn't hit anything."); 529. no_kick = TRUE; 530. } else if (u.utrap) { 531. switch (u.utraptype) { 532. case TT_PIT: 533. pline("There's not enough room to kick down here."); 534. break; 535. case TT_WEB: 536. case TT_BEARTRAP: 537. You_cant("move your %s!", body_part(LEG)); 538. break; 539. default: 540. break; 541. } 542. no_kick = TRUE; 543. } 544. 545. if (no_kick) { 546. /* discard direction typeahead, if any */ 547. display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */ 548. return 0; 549. } 550. 551. if(!getdir((char *)0)) return(0); 552. if(!u.dx && !u.dy) return(0); 553. 554. x = u.ux + u.dx; 555. y = u.uy + u.dy; 556. avrg_attrib = (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3; 557. 558. if(u.uswallow) { 559. switch(rn2(3)) { 560. case 0: You_cant("move your %s!", body_part(LEG)); 561. break; 562. case 1: if (is_animal(u.ustuck->data)) { 563. pline("%s burps loudly.", Monnam(u.ustuck)); 564. break; 565. } 566. default: Your("feeble kick has no effect."); break; 567. } 568. return(1); 569. } 570. 571. wake_nearby(); 572. u_wipe_engr(2); 573. 574. maploc = &levl[x][y]; 575. 576. /* The next four tests should stay in */ 577. /* their present order: monsters, objects, */ 578. /* non-doors, doors. */ 579. 580. if(MON_AT(x, y)) { 581. struct permonst *mdat = m_at(x,y)->data; 582. kick_monster(x, y); 583. if((Is_airlevel(&u.uz) || Levitation) && flags.move) { 584. int range; 585. 586. range = ((int)uasmon->cwt + (weight_cap() + inv_weight())); 587. if (range < 1) range = 1; /* divide by zero avoidance */ 588. range = (3*(int)mdat->cwt) / range; 589. 590. if(range < 1) range = 1; 591. hurtle(-u.dx, -u.dy, range); 592. } 593. return(1); 594. } 595. 596. kickobj = (struct obj *)0; 597. if (OBJ_AT(x, y) && 598. (!Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) 599. || sobj_at(BOULDER,x,y))) { 600. if(kick_object(x, y)) { 601. if(Is_airlevel(&u.uz)) 602. hurtle(-u.dx, -u.dy, 1); /* assume it's light */ 603. return(1); 604. } 605. goto ouch; 606. } 607. 608. if(!IS_DOOR(maploc->typ)) { 609. if(maploc->typ == SDOOR) { 610. if(!Levitation && rn2(30) < avrg_attrib) { 611. pline("Crash! You kick open a secret door!"); 612. exercise(A_DEX, TRUE); 613. maploc->typ = DOOR; 614. maploc->doormask = exposed_sdoor_mask(maploc); 615. if(maploc->doormask & D_TRAPPED) { 616. maploc->doormask = D_NODOOR; 617. b_trapped("door", FOOT); 618. } else if (maploc->doormask != D_NODOOR) 619. maploc->doormask = D_ISOPEN; 620. if (Blind) 621. feel_location(x,y); /* we know its gone */ 622. else 623. newsym(x,y); 624. unblock_point(x,y); /* vision */ 625. return(1); 626. } else goto ouch; 627. } 628. if(maploc->typ == SCORR) { 629. if(!Levitation && rn2(30) < avrg_attrib) { 630. pline("Crash! You kick open a secret passage!"); 631. exercise(A_DEX, TRUE); 632. maploc->typ = CORR; 633. if (Blind) 634. feel_location(x,y); /* we known its gone */ 635. else 636. newsym(x,y); 637. unblock_point(x,y); /* vision */ 638. return(1); 639. } else goto ouch; 640. } 641. if(IS_THRONE(maploc->typ)) { 642. register int i; 643. if(Levitation) goto dumb; 644. if((Luck < 0 || maploc->doormask) && !rn2(3)) { 645. maploc->typ = ROOM; 646. maploc->doormask = 0; /* don't leave loose ends.. */ 647. mkgold((long)rnd(200), x, y); 648. if (Blind) 649. pline("CRASH! You destroy it."); 650. else { 651. pline("CRASH! You destroy the throne."); 652. newsym(x, y); 653. } 654. exercise(A_DEX, TRUE); 655. return(1); 656. } else if(Luck > 0 && !rn2(3) && !maploc->looted) { 657. mkgold((long) rn1(201, 300), x, y); 658. i = Luck + 1; 659. if(i > 6) i = 6; 660. while(i--) (void) mkobj_at(GEM_CLASS, x, y, TRUE); 661. if (Blind) 662. You("kick %s loose!", something); 663. else { 664. You("kick loose some ornamental coins and gems!"); 665. newsym(x, y); 666. } 667. /* prevent endless milking */ 668. maploc->looted = T_LOOTED; 669. return(1); 670. } else if (!rn2(4)) { 671. if(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) { 672. fall_through(FALSE); 673. return(1); 674. } else goto ouch; 675. } 676. goto ouch; 677. } 678. if(IS_ALTAR(maploc->typ)) { 679. if(Levitation) goto dumb; 680. You("kick %s.",(Blind ? something : "the altar")); 681. if(!rn2(3)) goto ouch; 682. altar_wrath(x, y); 683. exercise(A_DEX, TRUE); 684. return(1); 685. } 686. if(IS_FOUNTAIN(maploc->typ)) { 687. if(Levitation) goto dumb; 688. You("kick %s.",(Blind ? something : "the fountain")); 689. if(!rn2(3)) goto ouch; 690. /* make metal boots rust */ 691. if(uarmf && rn2(3)) 692. if (!rust_dmg(uarmf, "metal boots", 1, FALSE)) { 693. Your("boots get wet."); 694. /* could cause short-lived fumbling here */ 695. } 696. exercise(A_DEX, TRUE); 697. return(1); 698. } 699. #ifdef SINKS 700. if(IS_SINK(maploc->typ)) { 701. if(Levitation) goto dumb; 702. if(rn2(5)) { 703. if(flags.soundok) 704. pline("Klunk! The pipes vibrate noisily."); 705. else pline("Klunk!"); 706. exercise(A_DEX, TRUE); 707. return(1); 708. } else if(!(maploc->looted & S_LPUDDING) && !rn2(3) && 709. !(mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) { 710. if (Blind) 711. You_hear("a gushing sound."); 712. else 713. pline("A %s ooze gushes up from the drain!", 714. hcolor(Black)); 715. (void) makemon(&mons[PM_BLACK_PUDDING], x, y); 716. exercise(A_DEX, TRUE); 717. newsym(x,y); 718. maploc->looted |= S_LPUDDING; 719. return(1); 720. } else if(!(maploc->looted & S_LDWASHER) && !rn2(3) && 721. !(mvitals[poly_gender() == 1 ? PM_INCUBUS 722. : PM_SUCCUBUS].mvflags & G_GONE)) { 723. /* can't resist... */ 724. pline("%s returns!", (Blind ? Something : 725. "The dish washer")); 726. if (makemon(&mons[poly_gender() == 1 ? 727. PM_INCUBUS : PM_SUCCUBUS], x, y)) newsym(x,y); 728. maploc->looted |= S_LDWASHER; 729. exercise(A_DEX, TRUE); 730. return(1); 731. } else if(!rn2(3)) { 732. pline("Flupp! %s.", (Blind ? 733. "You hear a sloshing sound" : 734. "Muddy waste pops up from the drain")); 735. if(!(maploc->looted & S_LRING)) { /* once per sink */ 736. if (!Blind) 737. You("see a ring shining in its midst."); 738. (void) mkobj_at(RING_CLASS, x, y, TRUE); 739. newsym(x, y); 740. exercise(A_DEX, TRUE); 741. exercise(A_WIS, TRUE); /* a discovery! */ 742. maploc->looted |= S_LRING; 743. } 744. return(1); 745. } 746. goto ouch; 747. } 748. #endif 749. if (maploc->typ == STAIRS || maploc->typ == LADDER || 750. IS_STWALL(maploc->typ)) { 751. if(!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN) 752. goto dumb; 753. ouch: 754. pline("Ouch! That hurts!"); 755. exercise(A_DEX, FALSE); 756. exercise(A_STR, FALSE); 757. if (Blind) feel_location(x,y); /* we know we hit it */ 758. if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); 759. losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(buf), 760. KILLED_BY); 761. if(Is_airlevel(&u.uz) || Levitation) 762. hurtle(-u.dx, -u.dy, rn1(2,4)); /* assume it's heavy */ 763. return(1); 764. } 765. if (is_drawbridge_wall(x,y) >= 0) { 766. pline_The("drawbridge is unaffected."); 767. if(Levitation) 768. hurtle(-u.dx, -u.dy, rn1(2,4)); /* it's heavy */ 769. return(1); 770. } 771. goto dumb; 772. } 773. 774. if(maploc->doormask == D_ISOPEN || 775. maploc->doormask == D_BROKEN || 776. maploc->doormask == D_NODOOR) { 777. dumb: 778. exercise(A_DEX, FALSE); 779. if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) { 780. You("kick at empty space."); 781. feel_location(x,y); 782. } else { 783. pline("Dumb move! You strain a muscle."); 784. exercise(A_STR, FALSE); 785. set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); 786. } 787. if ((Is_airlevel(&u.uz) || Levitation) && rn2(2)) { 788. hurtle(-u.dx, -u.dy, 1); 789. return 1; /* you moved, so use up a turn */ 790. } 791. return(0); 792. } 793. 794. /* not enough leverage to kick open doors while levitating */ 795. if(Levitation) goto ouch; 796. 797. exercise(A_DEX, TRUE); 798. /* door is known to be CLOSED or LOCKED */ 799. if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) { 800. boolean shopdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE; 801. /* break the door */ 802. if(maploc->doormask & D_TRAPPED) { 803. if (flags.verbose) You("kick the door."); 804. exercise(A_STR, FALSE); 805. maploc->doormask = D_NODOOR; 806. b_trapped("door", FOOT); 807. } else if(ACURR(A_STR) > 18 && !rn2(5) && !shopdoor) { 808. pline("As you kick the door, it shatters to pieces!"); 809. exercise(A_STR, TRUE); 810. maploc->doormask = D_NODOOR; 811. } else { 812. pline("As you kick the door, it crashes open!"); 813. exercise(A_STR, TRUE); 814. maploc->doormask = D_BROKEN; 815. } 816. if (Blind) 817. feel_location(x,y); /* we know we broke it */ 818. else 819. newsym(x,y); 820. unblock_point(x,y); /* vision */ 821. if (shopdoor) { 822. add_damage(x, y, 400L); 823. pay_for_damage("break"); 824. } 825. if ((slev = Is_special(&u.uz)) && slev->flags.town) 826. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 827. if((mtmp->data == &mons[PM_WATCHMAN] || 828. mtmp->data == &mons[PM_WATCH_CAPTAIN]) && 829. couldsee(mtmp->mx, mtmp->my) && 830. mtmp->mpeaceful) { 831. pline("%s yells:", Amonnam(mtmp)); 832. verbalize("Halt, thief! You're under arrest!"); 833. (void) angry_guards(FALSE); 834. break; 835. } 836. } 837. } else { 838. if (Blind) feel_location(x,y); /* we know we hit it */ 839. exercise(A_STR, TRUE); 840. pline("WHAMMM!!!"); 841. if ((slev = Is_special(&u.uz)) && slev->flags.town) 842. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 843. if ((mtmp->data == &mons[PM_WATCHMAN] || 844. mtmp->data == &mons[PM_WATCH_CAPTAIN]) && 845. mtmp->mpeaceful && couldsee(mtmp->mx, mtmp->my)) { 846. pline("%s yells:", Amonnam(mtmp)); 847. if(levl[x][y].looted & D_WARNED) { 848. verbalize("Halt, vandal! You're under arrest!"); 849. (void) angry_guards(FALSE); 850. } else { 851. verbalize("Hey, stop damaging that door!"); 852. levl[x][y].looted |= D_WARNED; 853. } 854. break; 855. } 856. } 857. } 858. return(1); 859. } 860. 861. static void 862. drop_to(cc, loc) 863. coord *cc; 864. schar loc; 865. { 866. /* cover all the MIGR_xxx choices generated by down_gate() */ 867. switch (loc) { 868. case MIGR_RANDOM: /* trap door or hole */ 869. if (Is_stronghold(&u.uz)) { 870. cc->x = valley_level.dnum; 871. cc->y = valley_level.dlevel; 872. break; 873. } else if (In_endgame(&u.uz) || Is_botlevel(&u.uz)) { 874. cc->y = cc->x = 0; 875. break; 876. } /* else fall to the next cases */ 877. case MIGR_STAIRS_UP: 878. case MIGR_LADDER_UP: 879. cc->x = u.uz.dnum; 880. cc->y = u.uz.dlevel + 1; 881. break; 882. case MIGR_SSTAIRS: 883. cc->x = sstairs.tolev.dnum; 884. cc->y = sstairs.tolev.dlevel; 885. break; 886. default: 887. case MIGR_NOWHERE: 888. /* y==0 means "nowhere", in which case x doesn't matter */ 889. cc->y = cc->x = 0; 890. break; 891. } 892. } 893. 894. void 895. impact_drop(missile, x, y, dlev) 896. struct obj *missile; 897. xchar x, y, dlev; 898. { 899. schar toloc; 900. register struct obj *obj, *obj2; 901. register struct monst *shkp; 902. long oct, dct, price, debit, robbed; 903. boolean angry, costly, isrock; 904. coord cc; 905. 906. if(!OBJ_AT(x, y)) return; 907. 908. toloc = down_gate(x, y); 909. drop_to(&cc, toloc); 910. if (!cc.y) return; 911. 912. if (dlev) { 913. /* send objects next to player falling through trap door. 914. * checked in obj_delivery(). 915. */ 916. toloc = MIGR_NEAR_PLAYER; 917. cc.y = dlev; 918. } 919. 920. costly = costly_spot(x, y); 921. price = debit = robbed = 0L; 922. angry = FALSE; 923. shkp = (struct monst *) 0; 924. /* if 'costly', we must keep a record of ESHK(shkp) before 925. * it undergoes changes through the calls to stolen_value. 926. * the angry bit must be reset, if needed, in this fn, since 927. * stolen_value is called under the 'silent' flag to avoid 928. * unsavory pline repetitions. 929. */ 930. if(costly) { 931. if ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0) { 932. debit = ESHK(shkp)->debit; 933. robbed = ESHK(shkp)->robbed; 934. angry = !shkp->mpeaceful; 935. } 936. } 937. 938. isrock = (missile && missile->otyp == ROCK); 939. oct = dct = 0L; 940. for(obj = level.objects[x][y]; obj; obj = obj2) { 941. obj2 = obj->nexthere; 942. if(obj == missile) continue; 943. /* number of objects in the pile */ 944. oct += obj->quan; 945. if(obj == uball || obj == uchain) continue; 946. /* boulders can fall too, but rarely & never due to rocks */ 947. if((isrock && obj->otyp == BOULDER) || 948. rn2(obj->otyp == BOULDER ? 30 : 3)) continue; 949. obj_extract_self(obj); 950. 951. if(costly) { 952. price += stolen_value(obj, x, y, 953. (costly_spot(u.ux, u.uy) && 954. index(u.urooms, *in_rooms(x, y, SHOPBASE))), 955. TRUE); 956. /* set obj->no_charge to 0 */ 957. if (Has_contents(obj)) 958. picked_container(obj); /* does the right thing */ 959. if (obj->oclass != GOLD_CLASS) 960. obj->no_charge = 0; 961. } 962. 963. add_to_migration(obj); 964. obj->ox = cc.x; 965. obj->oy = cc.y; 966. obj->owornmask = (long)toloc; 967. 968. /* number of fallen objects */ 969. dct += obj->quan; 970. } 971. 972. if (dct) { /* at least one object fell */ 973. const char *what = (dct == 1L ? "object falls" : "objects fall"); 974. if (missile) 975. pline("From the impact, %sother %s.", 976. dct == oct ? "the " : dct == 1L ? "an" : "", what); 977. else 978. if (oct == dct) { 979. pline("%s adjacent %s %s.", 980. dct == 1L ? "The" : "All the", 981. what, gate_str); 982. } else { 983. pline("%s adjacent %s %s.", 984. dct == 1L ? "One of the" : "Some of the", 985. dct == 1L ? "objects falls" : what, 986. gate_str); 987. } 988. } 989. 990. if(costly && shkp && price) { 991. if(ESHK(shkp)->robbed > robbed) { 992. You("removed %ld zorkmids worth of goods!", price); 993. if(cansee(shkp->mx, shkp->my)) { 994. if(ESHK(shkp)->customer[0] == 0) 995. (void) strncpy(ESHK(shkp)->customer, 996. plname, PL_NSIZ); 997. if(angry) 998. pline("%s is infuriated!", Monnam(shkp)); 999. else pline("\"%s, you are a thief!\"", plname); 1000. } else You_hear("a scream, \"Thief!\""); 1001. hot_pursuit(shkp); 1002. (void) angry_guards(FALSE); 1003. return; 1004. } 1005. if(ESHK(shkp)->debit > debit) 1006. You("owe %s %ld zorkmids for goods lost.", 1007. Monnam(shkp), 1008. (ESHK(shkp)->debit - debit)); 1009. } 1010. 1011. } 1012. 1013. /* NOTE: ship_object assumes otmp was FREED from fobj or invent. 1014. * is the point of drop. otmp is _not_ an resident: 1015. * otmp is either a kicked, dropped, or thrown object. 1016. */ 1017. boolean 1018. ship_object(otmp, x, y, shop_floor_obj) 1019. xchar x, y; 1020. struct obj *otmp; 1021. boolean shop_floor_obj; 1022. { 1023. schar toloc; 1024. xchar ox, oy; 1025. coord cc; 1026. struct obj *obj; 1027. struct trap *t; 1028. boolean nodrop, unpaid, container, impact = FALSE; 1029. int n = 0; 1030. 1031. if (!otmp) return(FALSE); 1032. if ((toloc = down_gate(x, y)) == MIGR_NOWHERE) return(FALSE); 1033. drop_to(&cc, toloc); 1034. if (!cc.y) return(FALSE); 1035. 1036. /* objects other than attached iron ball always fall down ladder, 1037. but have a chance of staying otherwise */ 1038. nodrop = (otmp == uball) || (otmp == uchain) || 1039. (toloc != MIGR_LADDER_UP && rn2(3)); 1040. 1041. container = Has_contents(otmp); 1042. unpaid = (otmp->unpaid || (container && count_unpaid(otmp->cobj))); 1043. 1044. if(OBJ_AT(x, y)) { 1045. for(obj = level.objects[x][y]; obj; obj = obj->nexthere) 1046. if(obj != otmp) n++; 1047. if(n) impact = TRUE; 1048. } 1049. /* boulders never fall through trap doors, but they might knock 1050. other things down before plugging the hole */ 1051. if (otmp->otyp == BOULDER && 1052. ((t = t_at(x, y)) != 0) && 1053. (t->ttyp == TRAPDOOR || t->ttyp == HOLE)) { 1054. if (impact) impact_drop(otmp, x, y, 0); 1055. return FALSE; /* let caller finish the drop */ 1056. } 1057. 1058. otransit_msg(otmp, nodrop, n); 1059. 1060. if (nodrop) { 1061. if (impact) impact_drop(otmp, x, y, 0); 1062. return(FALSE); 1063. } 1064. 1065. if(unpaid || shop_floor_obj) { 1066. if(unpaid) { 1067. subfrombill(otmp, shop_keeper(*u.ushops)); 1068. (void)stolen_value(otmp, u.ux, u.uy, TRUE, FALSE); 1069. } else { 1070. ox = otmp->ox; 1071. oy = otmp->oy; 1072. (void)stolen_value(otmp, ox, oy, 1073. (costly_spot(u.ux, u.uy) && 1074. index(u.urooms, *in_rooms(ox, oy, SHOPBASE))), 1075. FALSE); 1076. } 1077. /* set otmp->no_charge to 0 */ 1078. if(container) 1079. picked_container(otmp); /* happens to do the right thing */ 1080. if(otmp->oclass != GOLD_CLASS) 1081. otmp->no_charge = 0; 1082. } 1083. 1084. add_to_migration(otmp); 1085. otmp->ox = cc.x; 1086. otmp->oy = cc.y; 1087. otmp->owornmask = (long)toloc; 1088. 1089. if(impact) { 1090. /* the objs impacted may be in a shop other than 1091. * the one in which the hero is located. another 1092. * check for a shk is made in impact_drop. it is, e.g., 1093. * possible to kick/throw an object belonging to one 1094. * shop into another shop through a gap in the wall, 1095. * and cause objects belonging to the other shop to 1096. * fall down a trapdoor--thereby getting two shopkeepers 1097. * angry at the hero in one shot. 1098. */ 1099. impact_drop(otmp, x, y, 0); 1100. newsym(x,y); 1101. } 1102. return(TRUE); 1103. } 1104. 1105. void 1106. obj_delivery() 1107. { 1108. register struct obj *otmp, *otmp2; 1109. register int nx, ny; 1110. long where; 1111. 1112. for (otmp = migrating_objs; otmp; otmp = otmp2) { 1113. otmp2 = otmp->nobj; 1114. if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel) continue; 1115. 1116. obj_extract_self(otmp); 1117. where = otmp->owornmask; /* destination code */ 1118. otmp->owornmask = 0L; 1119. 1120. switch ((int)where) { 1121. case MIGR_STAIRS_UP: nx = xupstair, ny = yupstair; 1122. break; 1123. case MIGR_LADDER_UP: nx = xupladder, ny = yupladder; 1124. break; 1125. case MIGR_SSTAIRS: nx = sstairs.sx, ny = sstairs.sy; 1126. break; 1127. case MIGR_NEAR_PLAYER: nx = u.ux, ny = u.uy; 1128. break; 1129. default: 1130. case MIGR_RANDOM: nx = ny = 0; 1131. break; 1132. } 1133. if (nx > 0) { 1134. place_object(otmp, nx, ny); 1135. stackobj(otmp); 1136. scatter(nx, ny, rnd(2), 0); 1137. } else { /* random location */ 1138. /* set dummy coordinates because there's no 1139. current position for rloco() to update */ 1140. otmp->ox = otmp->oy = 0; 1141. rloco(otmp); 1142. } 1143. } 1144. } 1145. 1146. static void 1147. otransit_msg(otmp, nodrop, num) 1148. register struct obj *otmp; 1149. register boolean nodrop; 1150. int num; 1151. { 1152. char obuf[BUFSZ]; 1153. 1154. Sprintf(obuf, "%s%s", 1155. (otmp->otyp == CORPSE && 1156. type_is_pname(&mons[otmp->corpsenm])) ? "" : "The ", 1157. xname(otmp)); 1158. 1159. if(num) { /* means: other objects are impacted */ 1160. Sprintf(eos(obuf), " hit%s %s object%s", 1161. otmp->quan == 1L ? "s" : "", 1162. num == 1 ? "another" : "other", 1163. num > 1 ? "s" : ""); 1164. if(nodrop) 1165. Sprintf(eos(obuf), " and stop%s.", 1166. otmp->quan == 1L ? "s" : ""); 1167. else 1168. Sprintf(eos(obuf), " and fall%s %s.", 1169. otmp->quan == 1L ? "s" : "", gate_str); 1170. pline(obuf); 1171. } else if(!nodrop) 1172. pline("%s fall%s %s.", obuf, 1173. otmp->quan == 1L ? "s" : "", gate_str); 1174. } 1175. 1176. /* migration destination for objects which fall down to next level */ 1177. schar 1178. down_gate(x, y) 1179. xchar x, y; 1180. { 1181. struct trap *ttmp; 1182. 1183. gate_str = 0; 1184. /* this matches the player restriction in goto_level() */ 1185. if (on_level(&u.uz, &qstart_level) && !ok_to_quest()) 1186. return MIGR_NOWHERE; 1187. 1188. if ((xdnstair == x && ydnstair == y) || 1189. (sstairs.sx == x && sstairs.sy == y && !sstairs.up)) { 1190. gate_str = "down the stairs"; 1191. return (xdnstair == x && ydnstair == y) ? 1192. MIGR_STAIRS_UP : MIGR_SSTAIRS; 1193. } 1194. if (xdnladder == x && ydnladder == y) { 1195. gate_str = "down the ladder"; 1196. return MIGR_LADDER_UP; 1197. } 1198. 1199. if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen) && 1200. (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)) { 1201. gate_str = (ttmp->ttyp == TRAPDOOR) ? 1202. "through the trap door" : "through the hole"; 1203. return MIGR_RANDOM; 1204. } 1205. return MIGR_NOWHERE; 1206. } 1207. 1208. /*dokick.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