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