Below is the full text to src/dokick.c from NetHack 3.4.3. To link to a particular line, write [[dokick.c#line123]], for example.
Top of file[]
1. /* SCCS Id: @(#)dokick.c 3.4 2003/12/04 */ 2. /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4.
The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
5. #include "hack.h" 6. #include "eshk.h" 7. 8. #define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH]) 9. #define martial() (martial_bonus() || is_bigfoot(youmonst.data) || \ 10. (uarmf && uarmf->otyp == KICKING_BOOTS)) 11. 12. static NEARDATA struct rm *maploc; 13. static NEARDATA const char *gate_str; 14. 15. extern boolean notonhead; /* for long worms */ 16. 17. STATIC_DCL void FDECL(kickdmg, (struct monst *, BOOLEAN_P)); 18. STATIC_DCL void FDECL(kick_monster, (XCHAR_P, XCHAR_P)); 19. STATIC_DCL int FDECL(kick_object, (XCHAR_P, XCHAR_P)); 20. STATIC_DCL char *FDECL(kickstr, (char *)); 21. STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long)); 22. STATIC_DCL void FDECL(drop_to, (coord *,SCHAR_P)); 23. 24. static NEARDATA struct obj *kickobj; 25. 26. static const char kick_passes_thru[] = "kick passes harmlessly through"; 27.
kickdmg[]
28. STATIC_OVL void 29. kickdmg(mon, clumsy) 30. register struct monst *mon; 31. register boolean clumsy; 32. { 33. register int mdx, mdy; 34. register int dmg = ( ACURRSTR + ACURR(A_DEX) + ACURR(A_CON) )/ 15; 35. int kick_skill = P_NONE; 36. int blessed_foot_damage = 0; 37. boolean trapkilled = FALSE; 38. 39. if (uarmf && uarmf->otyp == KICKING_BOOTS) 40. dmg += 5; 41. 42. /* excessive wt affects dex, so it affects dmg */ 43. if (clumsy) dmg /= 2; 44. 45. /* kicking a dragon or an elephant will not harm it */ 46. if (thick_skinned(mon->data)) dmg = 0; 47. 48. /* attacking a shade is useless */ 49. if (mon->data == &mons[PM_SHADE]) 50. dmg = 0; 51. 52. if ((is_undead(mon->data) || is_demon(mon->data)) && uarmf && 53. uarmf->blessed) 54. blessed_foot_damage = 1; 55. 56. if (mon->data == &mons[PM_SHADE] && !blessed_foot_damage) { 57. pline_The("%s.", kick_passes_thru); 58. /* doesn't exercise skill or abuse alignment or frighten pet, 59. and shades have no passive counterattack */ 60. return; 61. } 62. 63. if(mon->m_ap_type) seemimic(mon); 64. 65. check_caitiff(mon); 66. 67. /* squeeze some guilt feelings... */ 68. if(mon->mtame) { 69. abuse_dog(mon); 70. if (mon->mtame) 71. monflee(mon, (dmg ? rnd(dmg) : 1), FALSE, FALSE); 72. else 73. mon->mflee = 0; 74. } 75. 76. if (dmg > 0) { 77. /* convert potential damage to actual damage */ 78. dmg = rnd(dmg); 79. if (martial()) { 80. if (dmg > 1) kick_skill = P_MARTIAL_ARTS; 81. dmg += rn2(ACURR(A_DEX)/2 + 1); 82. } 83. /* a good kick exercises your dex */ 84. exercise(A_DEX, TRUE); 85. } 86. if (blessed_foot_damage) dmg += rnd(4); 87. if (uarmf) dmg += uarmf->spe; 88. dmg += u.udaminc; /* add ring(s) of increase damage */ 89. if (dmg > 0) 90. mon->mhp -= dmg; 91. if (mon->mhp > 0 && martial() && !bigmonst(mon->data) && !rn2(3) && 92. mon->mcanmove && mon != u.ustuck && !mon->mtrapped) { 93. /* see if the monster has a place to move into */ 94. mdx = mon->mx + u.dx; 95. mdy = mon->my + u.dy; 96. if(goodpos(mdx, mdy, mon, 0)) { 97. pline("%s reels from the blow.", Monnam(mon)); 98. if (m_in_out_region(mon, mdx, mdy)) { 99. remove_monster(mon->mx, mon->my); 100. newsym(mon->mx, mon->my); 101. place_monster(mon, mdx, mdy); 102. newsym(mon->mx, mon->my); 103. set_apparxy(mon); 104. if (mintrap(mon) == 2) trapkilled = TRUE; 105. } 106. } 107. } 108. 109. (void) passive(mon, TRUE, mon->mhp > 0, AT_KICK); 110. if (mon->mhp <= 0 && !trapkilled) killed(mon); 111. 112. /* may bring up a dialog, so put this after all messages */ 113. if (kick_skill != P_NONE) /* exercise proficiency */ 114. use_skill(kick_skill, 1); 115. } 116.
kick_monster[]
117. STATIC_OVL void 118. kick_monster(x, y) 119. register xchar x, y; 120. { 121. register boolean clumsy = FALSE; 122. register struct monst *mon = m_at(x, y); 123. register int i, j; 124. 125. bhitpos.x = x; 126. bhitpos.y = y; 127. if (attack_checks(mon, (struct obj *)0)) return; 128. setmangry(mon); 129. 130. /* Kick attacks by kicking monsters are normal attacks, not special. 131. * This is almost always worthless, since you can either take one turn 132. * and do all your kicks, or else take one turn and attack the monster 133. * normally, getting all your attacks _including_ all your kicks. 134. * If you have >1 kick attack, you get all of them. 135. */ 136. if (Upolyd && attacktype(youmonst.data, AT_KICK)) { 137. struct attack *uattk; 138. int sum; 139. schar tmp = find_roll_to_hit(mon); 140. 141. for (i = 0; i < NATTK; i++) { 142. /* first of two kicks might have provoked counterattack 143. that has incapacitated the hero (ie, floating eye) */ 144. if (multi < 0) break; 145. 146. uattk = &youmonst.data->mattk[i]; 147. /* we only care about kicking attacks here */ 148. if (uattk->aatyp != AT_KICK) continue; 149. 150. if (mon->data == &mons[PM_SHADE] && 151. (!uarmf || !uarmf->blessed)) { 152. /* doesn't matter whether it would have hit or missed, 153. and shades have no passive counterattack */ 154. Your("%s %s.", kick_passes_thru, mon_nam(mon)); 155. break; /* skip any additional kicks */ 156. } else if (tmp > rnd(20)) { 157. You("kick %s.", mon_nam(mon)); 158. sum = damageum(mon, uattk); 159. (void)passive(mon, (boolean)(sum > 0), (sum != 2), AT_KICK); 160. if (sum == 2) 161. break; /* Defender died */ 162. } else { 163. missum(mon, uattk); 164. (void)passive(mon, 0, 1, AT_KICK); 165. } 166. } 167. return; 168. } 169. 170. if(Levitation && !rn2(3) && verysmall(mon->data) && 171. !is_flyer(mon->data)) { 172. pline("Floating in the air, you miss wildly!"); 173. exercise(A_DEX, FALSE); 174. (void) passive(mon, FALSE, 1, AT_KICK); 175. return; 176. } 177. 178. i = -inv_weight(); 179. j = weight_cap(); 180. 181. if(i < (j*3)/10) { 182. if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) { 183. if(martial() && !rn2(2)) goto doit; 184. Your("clumsy kick does no damage."); 185. (void) passive(mon, FALSE, 1, AT_KICK); 186. return; 187. } 188. if(i < j/10) clumsy = TRUE; 189. else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE; 190. } 191. 192. if(Fumbling) clumsy = TRUE; 193. 194. else if(uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25)) 195. clumsy = TRUE; 196. doit: 197. You("kick %s.", mon_nam(mon)); 198. if(!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) && 199. mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) && 200. mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove && 201. !mon->mstun && !mon->mconf && !mon->msleeping && 202. mon->data->mmove >= 12) { 203. if(!nohands(mon->data) && !rn2(martial() ? 5 : 3)) { 204. pline("%s blocks your %skick.", Monnam(mon), 205. clumsy ? "clumsy " : ""); 206. (void) passive(mon, FALSE, 1, AT_KICK); 207. return; 208. } else { 209. mnexto(mon); 210. if(mon->mx != x || mon->my != y) { 211. if(glyph_is_invisible(levl[x][y].glyph)) { 212. unmap_object(x, y); 213. newsym(x, y); 214. } 215. pline("%s %s, %s evading your %skick.", Monnam(mon), 216. (can_teleport(mon->data) ? "teleports" : 217. is_floater(mon->data) ? "floats" : 218. is_flyer(mon->data) ? "swoops" : 219. (nolimbs(mon->data) || slithy(mon->data)) ? 220. "slides" : "jumps"), 221. clumsy ? "easily" : "nimbly", 222. clumsy ? "clumsy " : ""); 223. (void) passive(mon, FALSE, 1, AT_KICK); 224. return; 225. } 226. } 227. } 228. kickdmg(mon, clumsy); 229. } 230.
ghitm[]
231. /* 232. * Return TRUE if caught (the gold taken care of), FALSE otherwise. 233. * The gold object is *not* attached to the fobj chain! 234. */ 235. boolean 236. ghitm(mtmp, gold) 237. register struct monst *mtmp; 238. register struct obj *gold; 239. { 240. boolean msg_given = FALSE; 241. 242. if(!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest 243. && !is_mercenary(mtmp->data)) { 244. wakeup(mtmp); 245. } else if (!mtmp->mcanmove) { 246. /* too light to do real damage */ 247. if (canseemon(mtmp)) { 248. pline_The("%s harmlessly %s %s.", xname(gold), 249. otense(gold, "hit"), mon_nam(mtmp)); 250. msg_given = TRUE; 251. } 252. } else { 253. #ifdef GOLDOBJ 254. long value = gold->quan * objects[gold->otyp].oc_cost; 255. #endif 256. mtmp->msleeping = 0; 257. mtmp->meating = 0; 258. if(!rn2(4)) setmangry(mtmp); /* not always pleasing */ 259. 260. /* greedy monsters catch gold */ 261. if (cansee(mtmp->mx, mtmp->my)) 262. pline("%s catches the gold.", Monnam(mtmp)); 263. #ifndef GOLDOBJ 264. mtmp->mgold += gold->quan; 265. #endif 266. if (mtmp->isshk) { 267. long robbed = ESHK(mtmp)->robbed; 268. 269. if (robbed) { 270. #ifndef GOLDOBJ 271. robbed -= gold->quan; 272. #else 273. robbed -= value; 274. #endif 275. if (robbed < 0) robbed = 0; 276. pline_The("amount %scovers %s recent losses.", 277. !robbed ? "" : "partially ", 278. mhis(mtmp)); 279. ESHK(mtmp)->robbed = robbed; 280. if(!robbed) 281. make_happy_shk(mtmp, FALSE); 282. } else { 283. if(mtmp->mpeaceful) { 284. #ifndef GOLDOBJ 285. ESHK(mtmp)->credit += gold->quan; 286. #else 287. ESHK(mtmp)->credit += value; 288. #endif 289. You("have %ld %s in credit.", 290. ESHK(mtmp)->credit, 291. currency(ESHK(mtmp)->credit)); 292. } else verbalize("Thanks, scum!"); 293. } 294. } else if (mtmp->ispriest) { 295. if (mtmp->mpeaceful) 296. verbalize("Thank you for your contribution."); 297. else verbalize("Thanks, scum!"); 298. } else if (is_mercenary(mtmp->data)) { 299. long goldreqd = 0L; 300. 301. if (rn2(3)) { 302. if (mtmp->data == &mons[PM_SOLDIER]) 303. goldreqd = 100L; 304. else if (mtmp->data == &mons[PM_SERGEANT]) 305. goldreqd = 250L; 306. else if (mtmp->data == &mons[PM_LIEUTENANT]) 307. goldreqd = 500L; 308. else if (mtmp->data == &mons[PM_CAPTAIN]) 309. goldreqd = 750L; 310. 311. if (goldreqd) { 312. #ifndef GOLDOBJ 313. if (gold->quan > goldreqd + 314. (u.ugold + u.ulevel*rn2(5))/ACURR(A_CHA)) 315. #else 316. if (value > goldreqd + 317. (money_cnt(invent) + u.ulevel*rn2(5))/ACURR(A_CHA)) 318. #endif 319. mtmp->mpeaceful = TRUE; 320. } 321. } 322. if (mtmp->mpeaceful) 323. verbalize("That should do. Now beat it!"); 324. else verbalize("That's not enough, coward!"); 325. } 326. 327. #ifndef GOLDOBJ 328. dealloc_obj(gold); 329. #else 330. add_to_minv(mtmp, gold); 331. #endif 332. return TRUE; 333. } 334. 335. if (!msg_given) miss(xname(gold), mtmp); 336. return FALSE; 337. } 338.
container_impact_dmg[]
339. /* container is kicked, dropped, thrown or otherwise impacted by player. 340. * Assumes container is on floor. Checks contents for possible damage. */ 341. void 342. container_impact_dmg(obj) 343. struct obj *obj; 344. { 345. struct monst *shkp; 346. struct obj *otmp, *otmp2; 347. long loss = 0L; 348. boolean costly, insider; 349. xchar x = obj->ox, y = obj->oy; 350. 351. /* only consider normal containers */ 352. if (!Is_container(obj) || Is_mbag(obj)) return; 353. 354. costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) && 355. costly_spot(x, y)); 356. insider = (*u.ushops && inside_shop(u.ux, u.uy) && 357. *in_rooms(x, y, SHOPBASE) == *u.ushops); 358. 359. for (otmp = obj->cobj; otmp; otmp = otmp2) { 360. const char *result = (char *)0; 361. 362. otmp2 = otmp->nobj; 363. if (objects[otmp->otyp].oc_material == GLASS && 364. otmp->oclass != GEM_CLASS && !obj_resists(otmp, 33, 100)) { 365. result = "shatter"; 366. } else if (otmp->otyp == EGG && !rn2(3)) { 367. result = "cracking"; 368. } 369. if (result) { 370. if (otmp->otyp == MIRROR) change_luck(-2); 371. 372. /* eggs laid by you. penalty is -1 per egg, max 5, 373. * but it's always exactly 1 that breaks */ 374. if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM) 375. change_luck(-1); 376. You_hear("a muffled %s.", result); 377. if (costly) 378. loss += stolen_value(otmp, x, y, 379. (boolean)shkp->mpeaceful, TRUE); 380. if (otmp->quan > 1L) 381. useup(otmp); 382. else { 383. obj_extract_self(otmp); 384. obfree(otmp, (struct obj *) 0); 385. } 386. } 387. } 388. if (costly && loss) { 389. if (!insider) { 390. You("caused %ld %s worth of damage!", loss, currency(loss)); 391. make_angry_shk(shkp, x, y); 392. } else { 393. You("owe %s %ld %s for objects destroyed.", 394. mon_nam(shkp), loss, currency(loss)); 395. } 396. } 397. } 398.
kick_object[]
399. STATIC_OVL int 400. kick_object(x, y) 401. xchar x, y; 402. { 403. int range; 404. register struct monst *mon, *shkp; 405. struct trap *trap; 406. char bhitroom; 407. boolean costly, isgold, slide = FALSE; 408. 409. /* if a pile, the "top" object gets kicked */ 410. kickobj = level.objects[x][y]; 411. 412. /* kickobj should always be set due to conditions of call */ 413. if(!kickobj || kickobj->otyp == BOULDER 414. || kickobj == uball || kickobj == uchain) 415. return(0); 416. 417. if ((trap = t_at(x,y)) != 0 && 418. (((trap->ttyp == PIT || 419. trap->ttyp == SPIKED_PIT) && !Passes_walls) || 420. trap->ttyp == WEB)) { 421. if (!trap->tseen) find_trap(trap); 422. You_cant("kick %s that's in a %s!", something, 423. Hallucination ? "tizzy" : 424. (trap->ttyp == WEB) ? "web" : "pit"); 425. return 1; 426. } 427. 428. if(Fumbling && !rn2(3)) { 429. Your("clumsy kick missed."); 430. return(1); 431. } 432. 433. if(kickobj->otyp == CORPSE && touch_petrifies(&mons[kickobj->corpsenm]) 434. && !Stone_resistance && !uarmf) { 435. char kbuf[BUFSZ]; 436. 437. You("kick the %s with your bare %s.", 438. corpse_xname(kickobj, TRUE), makeplural(body_part(FOOT))); 439. if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) { 440. You("turn to stone..."); 441. killer_format = KILLED_BY; 442. /* KMH -- otmp should be kickobj */ 443. Sprintf(kbuf, "kicking %s without boots", 444. an(corpse_xname(kickobj, TRUE))); 445. killer = kbuf; 446. done(STONING); 447. } 448. } 449. 450. /* range < 2 means the object will not move. */ 451. /* maybe dexterity should also figure here. */ 452. range = (int)((ACURRSTR)/2 - kickobj->owt/40); 453. 454. if(martial()) range += rnd(3); 455. 456. if (is_pool(x, y)) { 457. /* you're in the water too; significantly reduce range */ 458. range = range / 3 + 1; /* {1,2}=>1, {3,4,5}=>2, {6,7,8}=>3 */ 459. } else { 460. if (is_ice(x, y)) range += rnd(3), slide = TRUE; 461. if (kickobj->greased) range += rnd(3), slide = TRUE; 462. } 463. 464. /* Mjollnir is magically too heavy to kick */ 465. if(kickobj->oartifact == ART_MJOLLNIR) range = 1; 466. 467. /* see if the object has a place to move into */ 468. if(!ZAP_POS(levl[x+u.dx][y+u.dy].typ) || closed_door(x+u.dx, y+u.dy)) 469. range = 1; 470. 471. costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) && 472. costly_spot(x, y)); 473. isgold = (kickobj->oclass == COIN_CLASS); 474. 475. if (IS_ROCK(levl[x][y].typ) || closed_door(x, y)) { 476. if ((!martial() && rn2(20) > ACURR(A_DEX)) || 477. IS_ROCK(levl[u.ux][u.uy].typ) || closed_door(u.ux, u.uy)) { 478. if (Blind) 479. pline("It doesn't come loose."); 480. else 481. pline("%s %sn't come loose.", 482. The(distant_name(kickobj, xname)), 483. otense(kickobj, "do")); 484. return (!rn2(3) || martial()); 485. } 486. if (Blind) 487. pline("It comes loose."); 488. else 489. pline("%s %s loose.", 490. The(distant_name(kickobj, xname)), 491. otense(kickobj, "come")); 492. obj_extract_self(kickobj); 493. newsym(x, y); 494. if (costly && (!costly_spot(u.ux, u.uy) || 495. !index(u.urooms, *in_rooms(x, y, SHOPBASE)))) 496. addtobill(kickobj, FALSE, FALSE, FALSE); 497. if (!flooreffects(kickobj, u.ux, u.uy, "fall")) { 498. place_object(kickobj, u.ux, u.uy); 499. stackobj(kickobj); 500. newsym(u.ux, u.uy); 501. } 502. return 1; 503. } 504. 505. /* a box gets a chance of breaking open here */ 506. if(Is_box(kickobj)) { 507. boolean otrp = kickobj->otrapped; 508. 509. if(range < 2) pline("THUD!"); 510. 511. container_impact_dmg(kickobj); 512. 513. if (kickobj->olocked) { 514. if (!rn2(5) || (martial() && !rn2(2))) { 515. You("break open the lock!"); 516. kickobj->olocked = 0; 517. kickobj->obroken = 1; 518. if (otrp) (void) chest_trap(kickobj, LEG, FALSE); 519. return(1); 520. } 521. } else { 522. if (!rn2(3) || (martial() && !rn2(2))) { 523. pline_The("lid slams open, then falls shut."); 524. if (otrp) (void) chest_trap(kickobj, LEG, FALSE); 525. return(1); 526. } 527. } 528. if(range < 2) return(1); 529. /* else let it fall through to the next cases... */ 530. } 531. 532. /* fragile objects should not be kicked */ 533. if (hero_breaks(kickobj, kickobj->ox, kickobj->oy, FALSE)) return 1; 534. 535. /* too heavy to move. range is calculated as potential distance from 536. * player, so range == 2 means the object may move up to one square 537. * from its current position 538. */ 539. if(range < 2 || (isgold && kickobj->quan > 300L)) { 540. if(!Is_box(kickobj)) pline("Thump!"); 541. return(!rn2(3) || martial()); 542. } 543. 544. if (kickobj->quan > 1L && !isgold) kickobj = splitobj(kickobj, 1L); 545. 546. if (slide && !Blind) 547. pline("Whee! %s %s across the %s.", Doname2(kickobj), 548. otense(kickobj, "slide"), surface(x,y)); 549. 550. obj_extract_self(kickobj); 551. (void) snuff_candle(kickobj); 552. newsym(x, y); 553. mon = bhit(u.dx, u.dy, range, KICKED_WEAPON, 554. (int FDECL((*),(MONST_P,OBJ_P)))0, 555. (int FDECL((*),(OBJ_P,OBJ_P)))0, 556. kickobj); 557. 558. if(mon) { 559. if (mon->isshk && 560. kickobj->where == OBJ_MINVENT && kickobj->ocarry == mon) 561. return 1; /* alert shk caught it */ 562. notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y); 563. if (isgold ? ghitm(mon, kickobj) : /* caught? */ 564. thitmonst(mon, kickobj)) /* hit && used up? */ 565. return(1); 566. } 567. 568. /* the object might have fallen down a hole */ 569. if (kickobj->where == OBJ_MIGRATING) { 570. if (costly) { 571. if(isgold) 572. costly_gold(x, y, kickobj->quan); 573. else (void)stolen_value(kickobj, x, y, 574. (boolean)shkp->mpeaceful, FALSE); 575. } 576. return 1; 577. } 578. 579. bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE); 580. if (costly && (!costly_spot(bhitpos.x, bhitpos.y) || 581. *in_rooms(x, y, SHOPBASE) != bhitroom)) { 582. if(isgold) 583. costly_gold(x, y, kickobj->quan); 584. else (void)stolen_value(kickobj, x, y, 585. (boolean)shkp->mpeaceful, FALSE); 586. } 587. 588. if(flooreffects(kickobj,bhitpos.x,bhitpos.y,"fall")) return(1); 589. place_object(kickobj, bhitpos.x, bhitpos.y); 590. stackobj(kickobj); 591. newsym(kickobj->ox, kickobj->oy); 592. return(1); 593. } 594.
kickstr[]
595. STATIC_OVL char * 596. kickstr(buf) 597. char *buf; 598. { 599. const char *what; 600. 601. if (kickobj) what = distant_name(kickobj,doname); 602. else if (IS_DOOR(maploc->typ)) what = "a door"; 603. else if (IS_TREE(maploc->typ)) what = "a tree"; 604. else if (IS_STWALL(maploc->typ)) what = "a wall"; 605. else if (IS_ROCK(maploc->typ)) what = "a rock"; 606. else if (IS_THRONE(maploc->typ)) what = "a throne"; 607. else if (IS_FOUNTAIN(maploc->typ)) what = "a fountain"; 608. else if (IS_GRAVE(maploc->typ)) what = "a headstone"; 609. #ifdef SINKS 610. else if (IS_SINK(maploc->typ)) what = "a sink"; 611. #endif 612. else if (IS_ALTAR(maploc->typ)) what = "an altar"; 613. else if (IS_DRAWBRIDGE(maploc->typ)) what = "a drawbridge"; 614. else if (maploc->typ == STAIRS) what = "the stairs"; 615. else if (maploc->typ == LADDER) what = "a ladder"; 616. else if (maploc->typ == IRONBARS) what = "an iron bar"; 617. else what = "something weird"; 618. return strcat(strcpy(buf, "kicking "), what); 619. } 620.
dokick[]
621. int 622. dokick() 623. { 624. int x, y; 625. int avrg_attrib; 626. register struct monst *mtmp; 627. boolean no_kick = FALSE; 628. char buf[BUFSZ]; 629. 630. if (nolimbs(youmonst.data) || slithy(youmonst.data)) { 631. You("have no legs to kick with."); 632. no_kick = TRUE; 633. } else if (verysmall(youmonst.data)) { 634. You("are too small to do any kicking."); 635. no_kick = TRUE; 636. #ifdef STEED 637. } else if (u.usteed) { 638. if (yn_function("Kick your steed?", ynchars, 'y') == 'y') { 639. You("kick %s.", mon_nam(u.usteed)); 640. kick_steed(); 641. return 1; 642. } else { 643. return 0; 644. } 645. #endif 646. } else if (Wounded_legs) { 647. /* note: jump() has similar code */ 648. long wl = (EWounded_legs & BOTH_SIDES); 649. const char *bp = body_part(LEG); 650. 651. if (wl == BOTH_SIDES) bp = makeplural(bp); 652. Your("%s%s %s in no shape for kicking.", 653. (wl == LEFT_SIDE) ? "left " : 654. (wl == RIGHT_SIDE) ? "right " : "", 655. bp, (wl == BOTH_SIDES) ? "are" : "is"); 656. no_kick = TRUE; 657. } else if (near_capacity() > SLT_ENCUMBER) { 658. Your("load is too heavy to balance yourself for a kick."); 659. no_kick = TRUE; 660. } else if (youmonst.data->mlet == S_LIZARD) { 661. Your("legs cannot kick effectively."); 662. no_kick = TRUE; 663. } else if (u.uinwater && !rn2(2)) { 664. Your("slow motion kick doesn't hit anything."); 665. no_kick = TRUE; 666. } else if (u.utrap) { 667. switch (u.utraptype) { 668. case TT_PIT: 669. pline("There's not enough room to kick down here."); 670. break; 671. case TT_WEB: 672. case TT_BEARTRAP: 673. You_cant("move your %s!", body_part(LEG)); 674. break; 675. default: 676. break; 677. } 678. no_kick = TRUE; 679. } 680. 681. if (no_kick) { 682. /* ignore direction typed before player notices kick failed */ 683. display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */ 684. return 0; 685. } 686. 687. if(!getdir((char *)0)) return(0); 688. if(!u.dx && !u.dy) return(0); 689. 690. x = u.ux + u.dx; 691. y = u.uy + u.dy; 692. 693. /* KMH -- Kicking boots always succeed */ 694. if (uarmf && uarmf->otyp == KICKING_BOOTS) 695. avrg_attrib = 99; 696. else 697. avrg_attrib = (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3; 698. 699. if(u.uswallow) { 700. switch(rn2(3)) { 701. case 0: You_cant("move your %s!", body_part(LEG)); 702. break; 703. case 1: if (is_animal(u.ustuck->data)) { 704. pline("%s burps loudly.", Monnam(u.ustuck)); 705. break; 706. } 707. default: Your("feeble kick has no effect."); break; 708. } 709. return(1); 710. } 711. if (Levitation) { 712. int xx, yy; 713. 714. xx = u.ux - u.dx; 715. yy = u.uy - u.dy; 716. /* doors can be opened while levitating, so they must be 717. * reachable for bracing purposes 718. * Possible extension: allow bracing against stuff on the side? 719. */ 720. if (isok(xx,yy) && !IS_ROCK(levl[xx][yy].typ) && 721. !IS_DOOR(levl[xx][yy].typ) && 722. (!Is_airlevel(&u.uz) || !OBJ_AT(xx,yy))) { 723. You("have nothing to brace yourself against."); 724. return(0); 725. } 726. } 727. 728. wake_nearby(); 729. u_wipe_engr(2); 730. 731. maploc = &levl[x][y]; 732. 733. /* The next five tests should stay in */ 734. /* their present order: monsters, pools, */ 735. /* objects, non-doors, doors. */ 736. 737. if(MON_AT(x, y)) { 738. struct permonst *mdat; 739. 740. mtmp = m_at(x, y); 741. mdat = mtmp->data; 742. if (!mtmp->mpeaceful || !canspotmon(mtmp)) 743. flags.forcefight = TRUE; /* attack even if invisible */ 744. kick_monster(x, y); 745. flags.forcefight = FALSE; 746. /* see comment in attack_checks() */ 747. if (!DEADMONSTER(mtmp) && 748. !canspotmon(mtmp) && 749. /* check x and y; a monster that evades your kick by 750. jumping to an unseen square doesn't leave an I behind */ 751. mtmp->mx == x && mtmp->my == y && 752. !glyph_is_invisible(levl[x][y].glyph) && 753. !(u.uswallow && mtmp == u.ustuck)) 754. map_invisible(x, y); 755. if((Is_airlevel(&u.uz) || Levitation) && flags.move) { 756. int range; 757. 758. range = ((int)youmonst.data->cwt + (weight_cap() + inv_weight())); 759. if (range < 1) range = 1; /* divide by zero avoidance */ 760. range = (3*(int)mdat->cwt) / range; 761. 762. if(range < 1) range = 1; 763. hurtle(-u.dx, -u.dy, range, TRUE); 764. } 765. return(1); 766. } 767. if (glyph_is_invisible(levl[x][y].glyph)) { 768. unmap_object(x, y); 769. newsym(x, y); 770. } 771. if (is_pool(x, y) ^ !!u.uinwater) { 772. /* objects normally can't be removed from water by kicking */ 773. You("splash some water around."); 774. return 1; 775. } 776. 777. kickobj = (struct obj *)0; 778. if (OBJ_AT(x, y) && 779. (!Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) 780. || sobj_at(BOULDER,x,y))) { 781. if(kick_object(x, y)) { 782. if(Is_airlevel(&u.uz)) 783. hurtle(-u.dx, -u.dy, 1, TRUE); /* assume it's light */ 784. return(1); 785. } 786. goto ouch; 787. } 788. 789. if(!IS_DOOR(maploc->typ)) { 790. if(maploc->typ == SDOOR) { 791. if(!Levitation && rn2(30) < avrg_attrib) { 792. cvt_sdoor_to_door(maploc); /* ->typ = DOOR */ 793. pline("Crash! %s a secret door!", 794. /* don't "kick open" when it's locked 795. unless it also happens to be trapped */ 796. (maploc->doormask & (D_LOCKED|D_TRAPPED)) == D_LOCKED ? 797. "Your kick uncovers" : "You kick open"); 798. exercise(A_DEX, TRUE); 799. if(maploc->doormask & D_TRAPPED) { 800. maploc->doormask = D_NODOOR; 801. b_trapped("door", FOOT); 802. } else if (maploc->doormask != D_NODOOR && 803. !(maploc->doormask & D_LOCKED)) 804. maploc->doormask = D_ISOPEN; 805. if (Blind) 806. feel_location(x,y); /* we know it's gone */ 807. else 808. newsym(x,y); 809. if (maploc->doormask == D_ISOPEN || 810. maploc->doormask == D_NODOOR) 811. unblock_point(x,y); /* vision */ 812. return(1); 813. } else goto ouch; 814. } 815. if(maploc->typ == SCORR) { 816. if(!Levitation && rn2(30) < avrg_attrib) { 817. pline("Crash! You kick open a secret passage!"); 818. exercise(A_DEX, TRUE); 819. maploc->typ = CORR; 820. if (Blind) 821. feel_location(x,y); /* we know it's gone */ 822. else 823. newsym(x,y); 824. unblock_point(x,y); /* vision */ 825. return(1); 826. } else goto ouch; 827. } 828. if(IS_THRONE(maploc->typ)) { 829. register int i; 830. if(Levitation) goto dumb; 831. if((Luck < 0 || maploc->doormask) && !rn2(3)) { 832. maploc->typ = ROOM; 833. maploc->doormask = 0; /* don't leave loose ends.. */ 834. (void) mkgold((long)rnd(200), x, y); 835. if (Blind) 836. pline("CRASH! You destroy it."); 837. else { 838. pline("CRASH! You destroy the throne."); 839. newsym(x, y); 840. } 841. exercise(A_DEX, TRUE); 842. return(1); 843. } else if(Luck > 0 && !rn2(3) && !maploc->looted) { 844. (void) mkgold((long) rn1(201, 300), x, y); 845. i = Luck + 1; 846. if(i > 6) i = 6; 847. while(i--) 848. (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL, 849. LUCKSTONE-1), x, y, FALSE, TRUE); 850. if (Blind) 851. You("kick %s loose!", something); 852. else { 853. You("kick loose some ornamental coins and gems!"); 854. newsym(x, y); 855. } 856. /* prevent endless milking */ 857. maploc->looted = T_LOOTED; 858. return(1); 859. } else if (!rn2(4)) { 860. if(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) { 861. fall_through(FALSE); 862. return(1); 863. } else goto ouch; 864. } 865. goto ouch; 866. } 867. if(IS_ALTAR(maploc->typ)) { 868. if(Levitation) goto dumb; 869. You("kick %s.",(Blind ? something : "the altar")); 870. if(!rn2(3)) goto ouch; 871. altar_wrath(x, y); 872. exercise(A_DEX, TRUE); 873. return(1); 874. } 875. if(IS_FOUNTAIN(maploc->typ)) { 876. if(Levitation) goto dumb; 877. You("kick %s.",(Blind ? something : "the fountain")); 878. if(!rn2(3)) goto ouch; 879. /* make metal boots rust */ 880. if(uarmf && rn2(3)) 881. if (!rust_dmg(uarmf, "metal boots", 1, FALSE, &youmonst)) { 882. Your("boots get wet."); 883. /* could cause short-lived fumbling here */ 884. } 885. exercise(A_DEX, TRUE); 886. return(1); 887. } 888. if(IS_GRAVE(maploc->typ) || maploc->typ == IRONBARS) 889. goto ouch; 890. if(IS_TREE(maploc->typ)) { 891. struct obj *treefruit; 892. /* nothing, fruit or trouble? 75:23.5:1.5% */ 893. if (rn2(3)) { 894. if ( !rn2(6) && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE) ) 895. You_hear("a low buzzing."); /* a warning */ 896. goto ouch; 897. } 898. if (rn2(15) && !(maploc->looted & TREE_LOOTED) && 899. (treefruit = rnd_treefruit_at(x, y))) { 900. long nfruit = 8L-rnl(7), nfall; 901. short frtype = treefruit->otyp; 902. treefruit->quan = nfruit; 903. if (is_plural(treefruit)) 904. pline("Some %s fall from the tree!", xname(treefruit)); 905. else 906. pline("%s falls from the tree!", An(xname(treefruit))); 907. nfall = scatter(x,y,2,MAY_HIT,treefruit); 908. if (nfall != nfruit) { 909. /* scatter left some in the tree, but treefruit 910. * may not refer to the correct object */ 911. treefruit = mksobj(frtype, TRUE, FALSE); 912. treefruit->quan = nfruit-nfall; 913. pline("%ld %s got caught in the branches.", 914. nfruit-nfall, xname(treefruit)); 915. dealloc_obj(treefruit); 916. } 917. exercise(A_DEX, TRUE); 918. exercise(A_WIS, TRUE); /* discovered a new food source! */ 919. newsym(x, y); 920. maploc->looted |= TREE_LOOTED; 921. return(1); 922. } else if (!(maploc->looted & TREE_SWARM)) { 923. int cnt = rnl(4) + 2; 924. int made = 0; 925. coord mm; 926. mm.x = x; mm.y = y; 927. while (cnt--) { 928. if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE]) 929. && makemon(&mons[PM_KILLER_BEE], 930. mm.x, mm.y, MM_ANGRY)) 931. made++; 932. } 933. if ( made ) 934. pline("You've attracted the tree's former occupants!"); 935. else 936. You("smell stale honey."); 937. maploc->looted |= TREE_SWARM; 938. return(1); 939. } 940. goto ouch; 941. } 942. #ifdef SINKS 943. if(IS_SINK(maploc->typ)) { 944. int gend = poly_gender(); 945. short washerndx = (gend == 1 || (gend == 2 && rn2(2))) ? 946. PM_INCUBUS : PM_SUCCUBUS; 947. 948. if(Levitation) goto dumb; 949. if(rn2(5)) { 950. if(flags.soundok) 951. pline("Klunk! The pipes vibrate noisily."); 952. else pline("Klunk!"); 953. exercise(A_DEX, TRUE); 954. return(1); 955. } else if(!(maploc->looted & S_LPUDDING) && !rn2(3) && 956. !(mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) { 957. if (Blind) 958. You_hear("a gushing sound."); 959. else 960. pline("A %s ooze gushes up from the drain!", 961. hcolor(NH_BLACK)); 962. (void) makemon(&mons[PM_BLACK_PUDDING], 963. x, y, NO_MM_FLAGS); 964. exercise(A_DEX, TRUE); 965. newsym(x,y); 966. maploc->looted |= S_LPUDDING; 967. return(1); 968. } else if(!(maploc->looted & S_LDWASHER) && !rn2(3) && 969. !(mvitals[washerndx].mvflags & G_GONE)) { 970. /* can't resist... */ 971. pline("%s returns!", (Blind ? Something : 972. "The dish washer")); 973. if (makemon(&mons[washerndx], x, y, NO_MM_FLAGS)) 974. newsym(x,y); 975. maploc->looted |= S_LDWASHER; 976. exercise(A_DEX, TRUE); 977. return(1); 978. } else if(!rn2(3)) { 979. pline("Flupp! %s.", (Blind ? 980. "You hear a sloshing sound" : 981. "Muddy waste pops up from the drain")); 982. if(!(maploc->looted & S_LRING)) { /* once per sink */ 983. if (!Blind) 984. You("see a ring shining in its midst."); 985. (void) mkobj_at(RING_CLASS, x, y, TRUE); 986. newsym(x, y); 987. exercise(A_DEX, TRUE); 988. exercise(A_WIS, TRUE); /* a discovery! */ 989. maploc->looted |= S_LRING; 990. } 991. return(1); 992. } 993. goto ouch; 994. } 995. #endif 996. if (maploc->typ == STAIRS || maploc->typ == LADDER || 997. IS_STWALL(maploc->typ)) { 998. if(!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN) 999. goto dumb; 1000. ouch: 1001. pline("Ouch! That hurts!"); 1002. exercise(A_DEX, FALSE); 1003. exercise(A_STR, FALSE); 1004. if (Blind) feel_location(x,y); /* we know we hit it */ 1005. if (is_drawbridge_wall(x,y) >= 0) { 1006. pline_The("drawbridge is unaffected."); 1007. /* update maploc to refer to the drawbridge */ 1008. (void) find_drawbridge(&x,&y); 1009. maploc = &levl[x][y]; 1010. } 1011. if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); 1012. losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(buf), 1013. KILLED_BY); 1014. if(Is_airlevel(&u.uz) || Levitation) 1015. hurtle(-u.dx, -u.dy, rn1(2,4), TRUE); /* assume it's heavy */ 1016. return(1); 1017. } 1018. goto dumb; 1019. } 1020. 1021. if(maploc->doormask == D_ISOPEN || 1022. maploc->doormask == D_BROKEN || 1023. maploc->doormask == D_NODOOR) { 1024. dumb: 1025. exercise(A_DEX, FALSE); 1026. if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) { 1027. You("kick at empty space."); 1028. if (Blind) feel_location(x,y); 1029. } else { 1030. pline("Dumb move! You strain a muscle."); 1031. exercise(A_STR, FALSE); 1032. set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); 1033. } 1034. if ((Is_airlevel(&u.uz) || Levitation) && rn2(2)) { 1035. hurtle(-u.dx, -u.dy, 1, TRUE); 1036. return 1; /* you moved, so use up a turn */ 1037. } 1038. return(0); 1039. } 1040. 1041. /* not enough leverage to kick open doors while levitating */ 1042. if(Levitation) goto ouch; 1043. 1044. exercise(A_DEX, TRUE); 1045. /* door is known to be CLOSED or LOCKED */ 1046. if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) { 1047. boolean shopdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE; 1048. /* break the door */ 1049. if(maploc->doormask & D_TRAPPED) { 1050. if (flags.verbose) You("kick the door."); 1051. exercise(A_STR, FALSE); 1052. maploc->doormask = D_NODOOR; 1053. b_trapped("door", FOOT); 1054. } else if(ACURR(A_STR) > 18 && !rn2(5) && !shopdoor) { 1055. pline("As you kick the door, it shatters to pieces!"); 1056. exercise(A_STR, TRUE); 1057. maploc->doormask = D_NODOOR; 1058. } else { 1059. pline("As you kick the door, it crashes open!"); 1060. exercise(A_STR, TRUE); 1061. maploc->doormask = D_BROKEN; 1062. } 1063. if (Blind) 1064. feel_location(x,y); /* we know we broke it */ 1065. else 1066. newsym(x,y); 1067. unblock_point(x,y); /* vision */ 1068. if (shopdoor) { 1069. add_damage(x, y, 400L); 1070. pay_for_damage("break", FALSE); 1071. } 1072. if (in_town(x, y)) 1073. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1074. if (DEADMONSTER(mtmp)) continue; 1075. if((mtmp->data == &mons[PM_WATCHMAN] || 1076. mtmp->data == &mons[PM_WATCH_CAPTAIN]) && 1077. couldsee(mtmp->mx, mtmp->my) && 1078. mtmp->mpeaceful) { 1079. if (canspotmon(mtmp)) 1080. pline("%s yells:", Amonnam(mtmp)); 1081. else 1082. You_hear("someone yell:"); 1083. verbalize("Halt, thief! You're under arrest!"); 1084. (void) angry_guards(FALSE); 1085. break; 1086. } 1087. } 1088. } else { 1089. if (Blind) feel_location(x,y); /* we know we hit it */ 1090. exercise(A_STR, TRUE); 1091. pline("WHAMMM!!!"); 1092. if (in_town(x, y)) 1093. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1094. if (DEADMONSTER(mtmp)) continue; 1095. if ((mtmp->data == &mons[PM_WATCHMAN] || 1096. mtmp->data == &mons[PM_WATCH_CAPTAIN]) && 1097. mtmp->mpeaceful && couldsee(mtmp->mx, mtmp->my)) { 1098. if (canspotmon(mtmp)) 1099. pline("%s yells:", Amonnam(mtmp)); 1100. else 1101. You_hear("someone yell:"); 1102. if(levl[x][y].looted & D_WARNED) { 1103. verbalize("Halt, vandal! You're under arrest!"); 1104. (void) angry_guards(FALSE); 1105. } else { 1106. verbalize("Hey, stop damaging that door!"); 1107. levl[x][y].looted |= D_WARNED; 1108. } 1109. break; 1110. } 1111. } 1112. } 1113. return(1); 1114. } 1115.
drop_to[]
1116. STATIC_OVL void 1117. drop_to(cc, loc) 1118. coord *cc; 1119. schar loc; 1120. { 1121. /* cover all the MIGR_xxx choices generated by down_gate() */ 1122. switch (loc) { 1123. case MIGR_RANDOM: /* trap door or hole */ 1124. if (Is_stronghold(&u.uz)) { 1125. cc->x = valley_level.dnum; 1126. cc->y = valley_level.dlevel; 1127. break; 1128. } else if (In_endgame(&u.uz) || Is_botlevel(&u.uz)) { 1129. cc->y = cc->x = 0; 1130. break; 1131. } /* else fall to the next cases */ 1132. case MIGR_STAIRS_UP: 1133. case MIGR_LADDER_UP: 1134. cc->x = u.uz.dnum; 1135. cc->y = u.uz.dlevel + 1; 1136. break; 1137. case MIGR_SSTAIRS: 1138. cc->x = sstairs.tolev.dnum; 1139. cc->y = sstairs.tolev.dlevel; 1140. break; 1141. default: 1142. case MIGR_NOWHERE: 1143. /* y==0 means "nowhere", in which case x doesn't matter */ 1144. cc->y = cc->x = 0; 1145. break; 1146. } 1147. } 1148.
impact_drop[]
1149. void 1150. impact_drop(missile, x, y, dlev) 1151. struct obj *missile; 1152. xchar x, y, dlev; 1153. { 1154. schar toloc; 1155. register struct obj *obj, *obj2; 1156. register struct monst *shkp; 1157. long oct, dct, price, debit, robbed; 1158. boolean angry, costly, isrock; 1159. coord cc; 1160. 1161. if(!OBJ_AT(x, y)) return; 1162. 1163. toloc = down_gate(x, y); 1164. drop_to(&cc, toloc); 1165. if (!cc.y) return; 1166. 1167. if (dlev) { 1168. /* send objects next to player falling through trap door. 1169. * checked in obj_delivery(). 1170. */ 1171. toloc = MIGR_NEAR_PLAYER; 1172. cc.y = dlev; 1173. } 1174. 1175. costly = costly_spot(x, y); 1176. price = debit = robbed = 0L; 1177. angry = FALSE; 1178. shkp = (struct monst *) 0; 1179. /* if 'costly', we must keep a record of ESHK(shkp) before 1180. * it undergoes changes through the calls to stolen_value. 1181. * the angry bit must be reset, if needed, in this fn, since 1182. * stolen_value is called under the 'silent' flag to avoid 1183. * unsavory pline repetitions. 1184. */ 1185. if(costly) { 1186. if ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0) { 1187. debit = ESHK(shkp)->debit; 1188. robbed = ESHK(shkp)->robbed; 1189. angry = !shkp->mpeaceful; 1190. } 1191. } 1192. 1193. isrock = (missile && missile->otyp == ROCK); 1194. oct = dct = 0L; 1195. for(obj = level.objects[x][y]; obj; obj = obj2) { 1196. obj2 = obj->nexthere; 1197. if(obj == missile) continue; 1198. /* number of objects in the pile */ 1199. oct += obj->quan; 1200. if(obj == uball || obj == uchain) continue; 1201. /* boulders can fall too, but rarely & never due to rocks */ 1202. if((isrock && obj->otyp == BOULDER) || 1203. rn2(obj->otyp == BOULDER ? 30 : 3)) continue; 1204. obj_extract_self(obj); 1205. 1206. if(costly) { 1207. price += stolen_value(obj, x, y, 1208. (costly_spot(u.ux, u.uy) && 1209. index(u.urooms, *in_rooms(x, y, SHOPBASE))), 1210. TRUE); 1211. /* set obj->no_charge to 0 */ 1212. if (Has_contents(obj)) 1213. picked_container(obj); /* does the right thing */ 1214. if (obj->oclass != COIN_CLASS) 1215. obj->no_charge = 0; 1216. } 1217. 1218. add_to_migration(obj); 1219. obj->ox = cc.x; 1220. obj->oy = cc.y; 1221. obj->owornmask = (long)toloc; 1222. 1223. /* number of fallen objects */ 1224. dct += obj->quan; 1225. } 1226. 1227. if (dct && cansee(x,y)) { /* at least one object fell */ 1228. const char *what = (dct == 1L ? "object falls" : "objects fall"); 1229. 1230. if (missile) 1231. pline("From the impact, %sother %s.", 1232. dct == oct ? "the " : dct == 1L ? "an" : "", what); 1233. else if (oct == dct) 1234. pline("%s adjacent %s %s.", 1235. dct == 1L ? "The" : "All the", what, gate_str); 1236. else 1237. pline("%s adjacent %s %s.", 1238. dct == 1L ? "One of the" : "Some of the", 1239. dct == 1L ? "objects falls" : what, gate_str); 1240. } 1241. 1242. if(costly && shkp && price) { 1243. if(ESHK(shkp)->robbed > robbed) { 1244. You("removed %ld %s worth of goods!", price, currency(price)); 1245. if(cansee(shkp->mx, shkp->my)) { 1246. if(ESHK(shkp)->customer[0] == 0) 1247. (void) strncpy(ESHK(shkp)->customer, 1248. plname, PL_NSIZ); 1249. if(angry) 1250. pline("%s is infuriated!", Monnam(shkp)); 1251. else pline("\"%s, you are a thief!\"", plname); 1252. } else You_hear("a scream, \"Thief!\""); 1253. hot_pursuit(shkp); 1254. (void) angry_guards(FALSE); 1255. return; 1256. } 1257. if(ESHK(shkp)->debit > debit) { 1258. long amt = (ESHK(shkp)->debit - debit); 1259. You("owe %s %ld %s for goods lost.", 1260. Monnam(shkp), 1261. amt, currency(amt)); 1262. } 1263. } 1264. 1265. } 1266.
ship_object[]
1267. /* NOTE: ship_object assumes otmp was FREED from fobj or invent. 1268. * <x,y> is the point of drop. otmp is _not_ an <x,y> resident: 1269. * otmp is either a kicked, dropped, or thrown object. 1270. */ 1271. boolean 1272. ship_object(otmp, x, y, shop_floor_obj) 1273. xchar x, y; 1274. struct obj *otmp; 1275. boolean shop_floor_obj; 1276. { 1277. schar toloc; 1278. xchar ox, oy; 1279. coord cc; 1280. struct obj *obj; 1281. struct trap *t; 1282. boolean nodrop, unpaid, container, impact = FALSE; 1283. long n = 0L; 1284. 1285. if (!otmp) return(FALSE); 1286. if ((toloc = down_gate(x, y)) == MIGR_NOWHERE) return(FALSE); 1287. drop_to(&cc, toloc); 1288. if (!cc.y) return(FALSE); 1289. 1290. /* objects other than attached iron ball always fall down ladder, 1291. but have a chance of staying otherwise */ 1292. nodrop = (otmp == uball) || (otmp == uchain) || 1293. (toloc != MIGR_LADDER_UP && rn2(3)); 1294. 1295. container = Has_contents(otmp); 1296. unpaid = (otmp->unpaid || (container && count_unpaid(otmp->cobj))); 1297. 1298. if(OBJ_AT(x, y)) { 1299. for(obj = level.objects[x][y]; obj; obj = obj->nexthere) 1300. if(obj != otmp) n += obj->quan; 1301. if(n) impact = TRUE; 1302. } 1303. /* boulders never fall through trap doors, but they might knock 1304. other things down before plugging the hole */ 1305. if (otmp->otyp == BOULDER && 1306. ((t = t_at(x, y)) != 0) && 1307. (t->ttyp == TRAPDOOR || t->ttyp == HOLE)) { 1308. if (impact) impact_drop(otmp, x, y, 0); 1309. return FALSE; /* let caller finish the drop */ 1310. } 1311. 1312. if (cansee(x, y)) 1313. otransit_msg(otmp, nodrop, n); 1314. 1315. if (nodrop) { 1316. if (impact) impact_drop(otmp, x, y, 0); 1317. return(FALSE); 1318. } 1319. 1320. if(unpaid || shop_floor_obj) { 1321. if(unpaid) { 1322. subfrombill(otmp, shop_keeper(*u.ushops)); 1323. (void)stolen_value(otmp, u.ux, u.uy, TRUE, FALSE); 1324. } else { 1325. ox = otmp->ox; 1326. oy = otmp->oy; 1327. (void)stolen_value(otmp, ox, oy, 1328. (costly_spot(u.ux, u.uy) && 1329. index(u.urooms, *in_rooms(ox, oy, SHOPBASE))), 1330. FALSE); 1331. } 1332. /* set otmp->no_charge to 0 */ 1333. if(container) 1334. picked_container(otmp); /* happens to do the right thing */ 1335. if(otmp->oclass != COIN_CLASS) 1336. otmp->no_charge = 0; 1337. } 1338. 1339. if (otmp == uwep) setuwep((struct obj *)0); 1340. if (otmp == uquiver) setuqwep((struct obj *)0); 1341. if (otmp == uswapwep) setuswapwep((struct obj *)0); 1342. 1343. /* some things break rather than ship */ 1344. if (breaktest(otmp)) { 1345. const char *result; 1346. 1347. if (objects[otmp->otyp].oc_material == GLASS 1348. #ifdef TOURIST 1349. || otmp->otyp == EXPENSIVE_CAMERA 1350. #endif 1351. ) { 1352. if (otmp->otyp == MIRROR) 1353. change_luck(-2); 1354. result = "crash"; 1355. } else { 1356. /* penalty for breaking eggs laid by you */ 1357. if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM) 1358. change_luck((schar) -min(otmp->quan, 5L)); 1359. result = "splat"; 1360. } 1361. You_hear("a muffled %s.",result); 1362. obj_extract_self(otmp); 1363. obfree(otmp, (struct obj *) 0); 1364. return TRUE; 1365. } 1366. 1367. add_to_migration(otmp); 1368. otmp->ox = cc.x; 1369. otmp->oy = cc.y; 1370. otmp->owornmask = (long)toloc; 1371. /* boulder from rolling boulder trap, no longer part of the trap */ 1372. if (otmp->otyp == BOULDER) otmp->otrapped = 0; 1373. 1374. if(impact) { 1375. /* the objs impacted may be in a shop other than 1376. * the one in which the hero is located. another 1377. * check for a shk is made in impact_drop. it is, e.g., 1378. * possible to kick/throw an object belonging to one 1379. * shop into another shop through a gap in the wall, 1380. * and cause objects belonging to the other shop to 1381. * fall down a trap door--thereby getting two shopkeepers 1382. * angry at the hero in one shot. 1383. */ 1384. impact_drop(otmp, x, y, 0); 1385. newsym(x,y); 1386. } 1387. return(TRUE); 1388. } 1389.
obj_delivery[]
1390. void 1391. obj_delivery() 1392. { 1393. register struct obj *otmp, *otmp2; 1394. register int nx, ny; 1395. long where; 1396. 1397. for (otmp = migrating_objs; otmp; otmp = otmp2) { 1398. otmp2 = otmp->nobj; 1399. if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel) continue; 1400. 1401. obj_extract_self(otmp); 1402. where = otmp->owornmask; /* destination code */ 1403. otmp->owornmask = 0L; 1404. 1405. switch ((int)where) { 1406. case MIGR_STAIRS_UP: nx = xupstair, ny = yupstair; 1407. break; 1408. case MIGR_LADDER_UP: nx = xupladder, ny = yupladder; 1409. break; 1410. case MIGR_SSTAIRS: nx = sstairs.sx, ny = sstairs.sy; 1411. break; 1412. case MIGR_NEAR_PLAYER: nx = u.ux, ny = u.uy; 1413. break; 1414. default: 1415. case MIGR_RANDOM: nx = ny = 0; 1416. break; 1417. } 1418. if (nx > 0) { 1419. place_object(otmp, nx, ny); 1420. stackobj(otmp); 1421. (void)scatter(nx, ny, rnd(2), 0, otmp); 1422. } else { /* random location */ 1423. /* set dummy coordinates because there's no 1424. current position for rloco() to update */ 1425. otmp->ox = otmp->oy = 0; 1426. rloco(otmp); 1427. } 1428. } 1429. } 1430.
otransit_msg[]
1431. STATIC_OVL void 1432. otransit_msg(otmp, nodrop, num) 1433. register struct obj *otmp; 1434. register boolean nodrop; 1435. long num; 1436. { 1437. char obuf[BUFSZ]; 1438. 1439. Sprintf(obuf, "%s%s", 1440. (otmp->otyp == CORPSE && 1441. type_is_pname(&mons[otmp->corpsenm])) ? "" : "The ", 1442. xname(otmp)); 1443. 1444. if(num) { /* means: other objects are impacted */ 1445. Sprintf(eos(obuf), " %s %s object%s", 1446. otense(otmp, "hit"), 1447. num == 1L ? "another" : "other", 1448. num > 1L ? "s" : ""); 1449. if(nodrop) 1450. Sprintf(eos(obuf), "."); 1451. else 1452. Sprintf(eos(obuf), " and %s %s.", 1453. otense(otmp, "fall"), gate_str); 1454. pline("%s", obuf); 1455. } else if(!nodrop) 1456. pline("%s %s %s.", obuf, otense(otmp, "fall"), gate_str); 1457. } 1458.
down_gate[]
1459. /* migration destination for objects which fall down to next level */ 1460. schar 1461. down_gate(x, y) 1462. xchar x, y; 1463. { 1464. struct trap *ttmp; 1465. 1466. gate_str = 0; 1467. /* this matches the player restriction in goto_level() */ 1468. if (on_level(&u.uz, &qstart_level) && !ok_to_quest()) 1469. return MIGR_NOWHERE; 1470. 1471. if ((xdnstair == x && ydnstair == y) || 1472. (sstairs.sx == x && sstairs.sy == y && !sstairs.up)) { 1473. gate_str = "down the stairs"; 1474. return (xdnstair == x && ydnstair == y) ? 1475. MIGR_STAIRS_UP : MIGR_SSTAIRS; 1476. } 1477. if (xdnladder == x && ydnladder == y) { 1478. gate_str = "down the ladder"; 1479. return MIGR_LADDER_UP; 1480. } 1481. 1482. if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen) && 1483. (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)) { 1484. gate_str = (ttmp->ttyp == TRAPDOOR) ? 1485. "through the trap door" : "through the hole"; 1486. return MIGR_RANDOM; 1487. } 1488. return MIGR_NOWHERE; 1489. } 1490. 1491. /*dokick.c*/