1 /* NetHack 3.6 dokick.c $NHDT-Date: 1446955295 2015/11/08 04:01:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.104 $ */
2 /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 #define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH])
14 (martial_bonus() || is_bigfoot(youmonst.data) \
15 || (uarmf && uarmf->otyp == KICKING_BOOTS))
17 static NEARDATA struct rm *maploc, nowhere;
18 static NEARDATA const char *gate_str;
20 /* kickedobj (decl.c) tracks a kicked object until placed or destroyed */
22 extern boolean notonhead; /* for long worms */
24 STATIC_DCL void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
25 STATIC_DCL boolean FDECL(maybe_kick_monster, (struct monst *,
27 STATIC_DCL void FDECL(kick_monster, (struct monst *, XCHAR_P, XCHAR_P));
28 STATIC_DCL int FDECL(kick_object, (XCHAR_P, XCHAR_P));
29 STATIC_DCL int FDECL(really_kick_object, (XCHAR_P, XCHAR_P));
30 STATIC_DCL char *FDECL(kickstr, (char *));
31 STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long));
32 STATIC_DCL void FDECL(drop_to, (coord *, SCHAR_P));
35 static const char kick_passes_thru[] = "kick passes harmlessly through";
37 static const char kick_passes_thru[] = "
\8fR
\82è
\82Í
\83_
\83\81\81[
\83W
\82ð
\97^
\82¦
\82¸
\82É
\82·
\82è
\94²
\82¯
\82½";
41 register struct monst *mon;
42 register boolean clumsy;
44 register int mdx, mdy;
45 register int dmg = (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 15;
46 int kick_skill = P_NONE;
47 int blessed_foot_damage = 0;
48 boolean trapkilled = FALSE;
50 if (uarmf && uarmf->otyp == KICKING_BOOTS)
53 /* excessive wt affects dex, so it affects dmg */
57 /* kicking a dragon or an elephant will not harm it */
58 if (thick_skinned(mon->data))
61 /* attacking a shade is useless */
62 if (mon->data == &mons[PM_SHADE])
65 if ((is_undead(mon->data) || is_demon(mon->data) || is_vampshifter(mon))
66 && uarmf && uarmf->blessed)
67 blessed_foot_damage = 1;
69 if (mon->data == &mons[PM_SHADE] && !blessed_foot_damage) {
71 pline_The("%s.", kick_passes_thru);
73 pline_The("%s
\81D", kick_passes_thru);
74 /* doesn't exercise skill or abuse alignment or frighten pet,
75 and shades have no passive counterattack */
84 /* squeeze some guilt feelings... */
88 monflee(mon, (dmg ? rnd(dmg) : 1), FALSE, FALSE);
94 /* convert potential damage to actual damage */
98 kick_skill = P_MARTIAL_ARTS;
99 dmg += rn2(ACURR(A_DEX) / 2 + 1);
101 /* a good kick exercises your dex */
102 exercise(A_DEX, TRUE);
104 if (blessed_foot_damage)
108 dmg += u.udaminc; /* add ring(s) of increase damage */
111 if (mon->mhp > 0 && martial() && !bigmonst(mon->data) && !rn2(3)
112 && mon->mcanmove && mon != u.ustuck && !mon->mtrapped) {
113 /* see if the monster has a place to move into */
114 mdx = mon->mx + u.dx;
115 mdy = mon->my + u.dy;
116 if (goodpos(mdx, mdy, mon, 0)) {
118 pline("%s reels from the blow.", Monnam(mon));
120 pline("%s
\82Í
\8b
\91Å
\82³
\82ê
\82æ
\82ë
\82ß
\82¢
\82½
\81D", Monnam(mon));
121 if (m_in_out_region(mon, mdx, mdy)) {
122 remove_monster(mon->mx, mon->my);
123 newsym(mon->mx, mon->my);
124 place_monster(mon, mdx, mdy);
125 newsym(mon->mx, mon->my);
127 if (mintrap(mon) == 2)
133 (void) passive(mon, TRUE, mon->mhp > 0, AT_KICK, FALSE);
134 if (mon->mhp <= 0 && !trapkilled)
137 /* may bring up a dialog, so put this after all messages */
138 if (kick_skill != P_NONE) /* exercise proficiency */
139 use_skill(kick_skill, 1);
143 maybe_kick_monster(mon, x, y)
148 boolean save_forcefight = context.forcefight;
152 if (!mon->mpeaceful || !canspotmon(mon))
153 context.forcefight = TRUE; /* attack even if invisible */
154 /* kicking might be halted by discovery of hidden monster,
155 by player declining to attack peaceful monster,
156 or by passing out due to encumbrance */
157 if (attack_checks(mon, (struct obj *) 0) || overexertion())
158 mon = 0; /* don't kick after all */
159 context.forcefight = save_forcefight;
161 return (boolean) (mon != 0);
165 kick_monster(mon, x, y)
169 boolean clumsy = FALSE;
172 /* anger target even if wild miss will occur */
175 if (Levitation && !rn2(3) && verysmall(mon->data)
176 && !is_flyer(mon->data)) {
178 pline("Floating in the air, you miss wildly!");
180 pline("
\8bó
\92\86\82É
\95\82\82¢
\82Ä
\82¢
\82é
\82Ì
\82Å
\81C
\91å
\82«
\82
\8aO
\82µ
\82½
\81I");
181 exercise(A_DEX, FALSE);
182 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
186 /* reveal hidden target even if kick ends up missing (note: being
187 hidden doesn't affect chance to hit so neither does this reveal) */
189 || (mon->m_ap_type && mon->m_ap_type != M_AP_MONSTER)) {
192 mon->mundetected = 0;
193 if (!canspotmon(mon))
198 canspotmon(mon) ? a_monnam(mon) : "something hidden");
201 /* Kick attacks by kicking monsters are normal attacks, not special.
202 * This is almost always worthless, since you can either take one turn
203 * and do all your kicks, or else take one turn and attack the monster
204 * normally, getting all your attacks _including_ all your kicks.
205 * If you have >1 kick attack, you get all of them.
207 if (Upolyd && attacktype(youmonst.data, AT_KICK)) {
208 struct attack *uattk;
209 int sum, kickdieroll, armorpenalty,
211 tmp = find_roll_to_hit(mon, AT_KICK, (struct obj *) 0, &attknum,
214 for (i = 0; i < NATTK; i++) {
215 /* first of two kicks might have provoked counterattack
216 that has incapacitated the hero (ie, floating eye) */
220 uattk = &youmonst.data->mattk[i];
221 /* we only care about kicking attacks here */
222 if (uattk->aatyp != AT_KICK)
225 if (mon->data == &mons[PM_SHADE] && (!uarmf || !uarmf->blessed)) {
226 /* doesn't matter whether it would have hit or missed,
227 and shades have no passive counterattack */
229 Your("%s %s.", kick_passes_thru, mon_nam(mon));
231 You("%s
\82ð
\8fR
\82Á
\82½
\82ª
\81C%s
\81D", mon_nam(mon), kick_passes_thru);
232 break; /* skip any additional kicks */
233 } else if (tmp > (kickdieroll = rnd(20))) {
235 You("kick %s.", mon_nam(mon));
237 You("%s
\82ð
\8fR
\82Á
\82½
\81D", mon_nam(mon));
238 sum = damageum(mon, uattk);
239 (void) passive(mon, (boolean) (sum > 0), (sum != 2), AT_KICK,
242 break; /* Defender died */
244 missum(mon, uattk, (tmp + armorpenalty > kickdieroll));
245 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
254 if (i < (j * 3) / 10) {
255 if (!rn2((i < j / 10) ? 2 : (i < j / 5) ? 3 : 4)) {
256 if (martial() && !rn2(2))
259 Your("clumsy kick does no damage.");
261 Your("
\95s
\8aí
\97p
\82È
\8fR
\82è
\82Å
\83_
\83\81\81[
\83W
\82ð
\97^
\82¦
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D");
262 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
267 else if (!rn2((i < j / 5) ? 2 : 3))
274 else if (uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
278 You("kick %s.", mon_nam(mon));
280 You("%s
\82ð
\8fR
\82Á
\82½
\81D", mon_nam(mon));
281 if (!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data))
282 && mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data)
283 && mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove
284 && !mon->mstun && !mon->mconf && !mon->msleeping
285 && mon->data->mmove >= 12) {
286 if (!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
288 pline("%s blocks your %skick.", Monnam(mon),
289 clumsy ? "clumsy " : "");
291 pline("%s
\82Í
\82 \82È
\82½
\82Ì%s
\8fR
\82è
\82ð
\96h
\82¢
\82¾
\81D", Monnam(mon),
292 clumsy ? "
\95s
\8aí
\97p
\82È" : "");
294 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
298 if (mon->mx != x || mon->my != y) {
299 if (glyph_is_invisible(levl[x][y].glyph)) {
304 pline("%s %s, %s evading your %skick.", Monnam(mon),
305 (!level.flags.noteleport && can_teleport(mon->data))
307 : is_floater(mon->data)
309 : is_flyer(mon->data) ? "swoops"
310 : (nolimbs(mon->data)
311 || slithy(mon->data))
314 clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : "");
316 pline("%s
\82Í%s
\81C%s
\82 \82È
\82½
\82Ì%s
\8fR
\82è
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81D", Monnam(mon),
317 (!level.flags.noteleport && can_teleport(mon->data))
318 ? "
\8fu
\8aÔ
\88Ú
\93®
\82µ"
319 : is_floater(mon->data) ? "
\95\82\82«"
320 : is_flyer(mon->data) ? "
\82Í
\82Î
\82½
\82«"
321 : (nolimbs(mon->data)
322 || slithy(mon->data))
323 ? "
\89¡
\82É
\8a\8a\82è"
325 clumsy ? "
\8ay
\81X
\82Æ" : "
\91f
\91\81\82", clumsy ? "
\95s
\8aí
\97p
\82È" : "");
327 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
332 kickdmg(mon, clumsy);
336 * Return TRUE if caught (the gold taken care of), FALSE otherwise.
337 * The gold object is *not* attached to the fobj chain!
341 register struct monst *mtmp;
342 register struct obj *gold;
344 boolean msg_given = FALSE;
346 if (!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest
347 && !mtmp->isgd && !is_mercenary(mtmp->data)) {
349 } else if (!mtmp->mcanmove) {
350 /* too light to do real damage */
351 if (canseemon(mtmp)) {
353 pline_The("%s harmlessly %s %s.", xname(gold),
354 otense(gold, "hit"), mon_nam(mtmp));
356 pline("%s
\82Í%s
\82É
\96½
\92\86\82µ
\82½
\81D", xname(gold),
362 long umoney, value = gold->quan * objects[gold->otyp].oc_cost;
365 finish_meating(mtmp);
366 if (!mtmp->isgd && !rn2(4)) /* not always pleasing */
368 /* greedy monsters catch gold */
369 if (cansee(mtmp->mx, mtmp->my))
371 pline("%s catches the gold.", Monnam(mtmp));
373 pline("%s
\82Í
\8bà
\89Ý
\82ð
\83L
\83\83\83b
\83`
\82µ
\82½
\81D", Monnam(mtmp));
374 (void) mpickobj(mtmp, gold);
375 gold = (struct obj *) 0; /* obj has been freed */
377 long robbed = ESHK(mtmp)->robbed;
384 pline_The("amount %scovers %s recent losses.",
385 !robbed ? "" : "partially ", mhis(mtmp));
387 pline("%s%s
\91¹
\8e¸
\82ð
\95â
\93U
\82·
\82é
\82Ì
\82É
\8eg
\82í
\82ê
\82½
\81D",
388 !robbed ? "" : "
\8bà
\82Ì
\88ê
\95\94\82Í", mhis(mtmp));
390 ESHK(mtmp)->robbed = robbed;
392 make_happy_shk(mtmp, FALSE);
394 if (mtmp->mpeaceful) {
395 ESHK(mtmp)->credit += value;
397 You("have %ld %s in credit.", ESHK(mtmp)->credit,
398 currency(ESHK(mtmp)->credit));
400 You("%ld%s
\82ð
\91Ý
\82µ
\82É
\82µ
\82½
\81D", ESHK(mtmp)->credit,
401 currency(ESHK(mtmp)->credit));
405 verbalize("Thanks, scum!");
407 verbalize("
\82 \82è
\82ª
\82Æ
\82æ
\81I
\82
\82»
\82Á
\82½
\82ê
\81I");
409 } else if (mtmp->ispriest) {
412 verbalize("Thank you for your contribution.");
414 verbalize("
\8añ
\95t
\82É
\8a´
\8eÓ
\82µ
\82Ü
\82·
\81D");
417 verbalize("Thanks, scum!");
419 verbalize("
\82 \82è
\82ª
\82Æ
\82æ
\81I
\82
\82»
\82Á
\82½
\82ê
\81I");
420 } else if (mtmp->isgd) {
421 umoney = money_cnt(invent);
422 /* Some of these are iffy, because a hostile guard
423 won't become peaceful and resume leading hero
424 out of the vault. If he did do that, player
425 could try fighting, then weasle out of being
426 killed by throwing his/her gold when losing. */
429 ? "Drop the rest and follow me."
431 ? "You still have hidden gold. Drop it now."
433 ? "I'll take care of that; please move along."
434 : "I'll take that; now get moving.");
435 } else if (is_mercenary(mtmp->data)) {
439 if (mtmp->data == &mons[PM_SOLDIER])
441 else if (mtmp->data == &mons[PM_SERGEANT])
443 else if (mtmp->data == &mons[PM_LIEUTENANT])
445 else if (mtmp->data == &mons[PM_CAPTAIN])
449 umoney = money_cnt(invent);
452 + (umoney + u.ulevel * rn2(5)) / ACURR(A_CHA))
453 mtmp->mpeaceful = TRUE;
458 verbalize("That should do. Now beat it!");
460 verbalize("
\82È
\82ñ
\82¾
\82¢
\81H
\82±
\82ê
\82Í
\81H");
463 verbalize("That's not enough, coward!");
465 verbalize("
\82»
\82ñ
\82È
\82à
\82Ì
\82Å
\8dÏ
\82Þ
\82©
\81C
\94Ú
\8b¯
\8eÒ
\81I");
471 miss(xname(gold), mtmp);
475 /* container is kicked, dropped, thrown or otherwise impacted by player.
476 * Assumes container is on floor. Checks contents for possible damage. */
478 container_impact_dmg(obj, x, y)
480 xchar x, y; /* coordinates where object was before the impact, not after */
483 struct obj *otmp, *otmp2;
485 boolean costly, insider, frominv;
487 /* only consider normal containers */
488 if (!Is_container(obj) || !Has_contents(obj) || Is_mbag(obj))
491 costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE)))
492 && costly_spot(x, y));
493 insider = (*u.ushops && inside_shop(u.ux, u.uy)
494 && *in_rooms(x, y, SHOPBASE) == *u.ushops);
495 /* if dropped or thrown, shop ownership flags are set on this obj */
496 frominv = (obj != kickedobj);
498 for (otmp = obj->cobj; otmp; otmp = otmp2) {
499 const char *result = (char *) 0;
502 if (objects[otmp->otyp].oc_material == GLASS
503 && otmp->oclass != GEM_CLASS && !obj_resists(otmp, 33, 100)) {
507 result = "
\83K
\83`
\83\83\83\93";
508 } else if (otmp->otyp == EGG && !rn2(3)) {
512 result = "
\83O
\83V
\83\83\83b";
515 if (otmp->otyp == MIRROR)
518 /* eggs laid by you. penalty is -1 per egg, max 5,
519 * but it's always exactly 1 that breaks */
520 if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
523 You_hear("a muffled %s.", result);
525 You_hear("
\82±
\82à
\82Á
\82½%s
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D", result);
527 if (frominv && !otmp->unpaid)
530 stolen_value(otmp, x, y, (boolean) shkp->mpeaceful, TRUE);
532 if (otmp->quan > 1L) {
535 obj_extract_self(otmp);
536 obfree(otmp, (struct obj *) 0);
538 /* contents of this container are no longer known */
542 if (costly && loss) {
545 You("caused %ld %s worth of damage!", loss, currency(loss));
547 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\82Ð
\82«
\82¨
\82±
\82µ
\82½
\81I", loss, currency(loss));
548 make_angry_shk(shkp, x, y);
551 You("owe %s %ld %s for objects destroyed.", mon_nam(shkp), loss,
554 You("
\8aí
\95¨
\94j
\91¹
\82Å%s
\82É%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", mon_nam(shkp), loss,
561 /* jacket around really_kick_object */
568 /* if a pile, the "top" object gets kicked */
569 kickedobj = level.objects[x][y];
571 /* kick object; if doing is fatal, done() will clean up kickedobj */
572 res = really_kick_object(x, y);
573 kickedobj = (struct obj *) 0;
578 /* guts of kick_object */
580 really_kick_object(x, y)
584 struct monst *mon, *shkp = 0;
587 boolean costly, isgold, slide = FALSE;
589 /* kickedobj should always be set due to conditions of call */
590 if (!kickedobj || kickedobj->otyp == BOULDER || kickedobj == uball
591 || kickedobj == uchain)
594 if ((trap = t_at(x, y)) != 0
595 && (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !Passes_walls)
596 || trap->ttyp == WEB)) {
600 You_cant("kick %s that's in a %s!", something,
601 Hallucination ? "tizzy" : (trap->ttyp == WEB) ? "web"
604 You("%s
\82Å
\82Í%s
\82ð
\8fR
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I",
605 Hallucination ? "
\8d¬
\97\90\82µ
\82½
\8fó
\91Ô"
607 ? "
\82
\82à
\82Ì
\91\83\82Ì
\92\86" : "
\97\8e\82µ
\8c\8a\82Ì
\92\86",
613 if (Fumbling && !rn2(3)) {
615 Your("clumsy kick missed.");
617 Your("
\95s
\8aí
\97p
\82È
\8fR
\82è
\82Í
\8aO
\82ê
\82½
\81D");
621 if (!uarmf && kickedobj->otyp == CORPSE
622 && touch_petrifies(&mons[kickedobj->corpsenm]) && !Stone_resistance) {
624 You("kick %s with your bare %s.",
625 corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE),
626 makeplural(body_part(FOOT)));
628 You("
\91f%s
\82Å%s
\82ð
\8fR
\82Á
\82½
\81D",
630 corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE));
632 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
633 ; /* hero has been transformed but kick continues */
635 /* normalize body shape here; foot, not body_part(FOOT) */
637 Sprintf(killer.name, "kicking %s barefoot",
639 Sprintf(killer.name, "
\8cC
\96³
\82µ
\82Å%s
\82ð
\8fR
\82Á
\82Ä",
640 killer_xname(kickedobj));
641 instapetrify(killer.name);
645 /* range < 2 means the object will not move. */
646 /* maybe dexterity should also figure here. */
647 range = (int) ((ACURRSTR) / 2 - kickedobj->owt / 40);
653 /* you're in the water too; significantly reduce range */
654 range = range / 3 + 1; /* {1,2}=>1, {3,4,5}=>2, {6,7,8}=>3 */
655 } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
656 /* you're in air, since is_pool did not match */
660 range += rnd(3), slide = TRUE;
661 if (kickedobj->greased)
662 range += rnd(3), slide = TRUE;
665 /* Mjollnir is magically too heavy to kick */
666 if (kickedobj->oartifact == ART_MJOLLNIR)
669 /* see if the object has a place to move into */
670 if (!ZAP_POS(levl[x + u.dx][y + u.dy].typ)
671 || closed_door(x + u.dx, y + u.dy))
674 costly = (!(kickedobj->no_charge && !Has_contents(kickedobj))
675 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
676 && costly_spot(x, y));
677 isgold = (kickedobj->oclass == COIN_CLASS);
679 if (IS_ROCK(levl[x][y].typ) || closed_door(x, y)) {
680 if ((!martial() && rn2(20) > ACURR(A_DEX))
681 || IS_ROCK(levl[u.ux][u.uy].typ) || closed_door(u.ux, u.uy)) {
684 pline("It doesn't come loose.");
686 pline("
\82Ñ
\82
\82Æ
\82à
\82µ
\82È
\82¢
\81D");
689 pline("%s %sn't come loose.",
690 The(distant_name(kickedobj, xname)),
691 otense(kickedobj, "do"));
693 pline("%s
\82Í
\82Ñ
\82
\82Æ
\82à
\82µ
\82È
\82¢
\81D",
694 distant_name(kickedobj, xname));
696 return (!rn2(3) || martial());
700 pline("It comes loose.");
702 pline("
\89½
\82©
\82ª
\8aÉ
\82ñ
\82Å
\82Æ
\82ê
\82½
\81D");
705 pline("%s %s loose.", The(distant_name(kickedobj, xname)),
706 otense(kickedobj, "come"));
708 pline("%s
\82Í
\8aÉ
\82ñ
\82Å
\82Æ
\82ê
\82½
\81D", distant_name(kickedobj, xname));
710 obj_extract_self(kickedobj);
712 if (costly && (!costly_spot(u.ux, u.uy)
713 || !index(u.urooms, *in_rooms(x, y, SHOPBASE))))
714 addtobill(kickedobj, FALSE, FALSE, FALSE);
716 if (!flooreffects(kickedobj, u.ux, u.uy, "fall")) {
718 if (!flooreffects(kickedobj, u.ux, u.uy, "
\97\8e\82¿
\82é")) {
719 place_object(kickedobj, u.ux, u.uy);
726 /* a box gets a chance of breaking open here */
727 if (Is_box(kickedobj)) {
728 boolean otrp = kickedobj->otrapped;
734 pline("
\83K
\83\93\81I");
735 container_impact_dmg(kickedobj, x, y);
736 if (kickedobj->olocked) {
737 if (!rn2(5) || (martial() && !rn2(2))) {
739 You("break open the lock!");
741 You("
\8c®
\82ð
\89ó
\82µ
\8aJ
\82¯
\82½
\81I");
742 breakchestlock(kickedobj, FALSE);
744 (void) chest_trap(kickedobj, LEG, FALSE);
748 if (!rn2(3) || (martial() && !rn2(2))) {
750 pline_The("lid slams open, then falls shut.");
752 pline("
\8aW
\82ª
\82Î
\82½
\82ñ
\82Æ
\8aJ
\82«
\81C
\95Â
\82¶
\82½
\81D");
753 kickedobj->lknown = 1;
755 (void) chest_trap(kickedobj, LEG, FALSE);
761 /* else let it fall through to the next cases... */
764 /* fragile objects should not be kicked */
765 if (hero_breaks(kickedobj, kickedobj->ox, kickedobj->oy, FALSE))
768 /* too heavy to move. range is calculated as potential distance from
769 * player, so range == 2 means the object may move up to one square
770 * from its current position
773 if (!Is_box(kickedobj))
777 pline("
\83S
\83c
\83\93\81I");
778 return (!rn2(3) || martial());
781 if (kickedobj->quan > 1L) {
783 kickedobj = splitobj(kickedobj, 1L);
786 static NEARDATA const char *const flyingcoinmsg[] = {
787 "scatter the coins", "knock coins all over the place",
788 "send coins flying in all directions",
792 You("%s!", flyingcoinmsg[rn2(SIZE(flyingcoinmsg))]);
793 (void) scatter(x, y, rn2(3) + 1, VIS_EFFECTS | MAY_HIT,
798 if (kickedobj->quan > 300L) {
800 return (!rn2(3) || martial());
807 pline("Whee! %s %s across the %s.", Doname2(kickedobj),
808 otense(kickedobj, "slide"), surface(x, y));
810 pline("
\83Y
\83\8b\83b
\81I%s
\82Í%s
\82Ì
\8fã
\82ð
\8a\8a\82Á
\82½
\81D", Doname2(kickedobj),
814 if (costly && !isgold)
815 addtobill(kickedobj, FALSE, FALSE, TRUE);
816 obj_extract_self(kickedobj);
817 (void) snuff_candle(kickedobj);
819 mon = bhit(u.dx, u.dy, range, KICKED_WEAPON,
820 (int FDECL((*), (MONST_P, OBJ_P))) 0,
821 (int FDECL((*), (OBJ_P, OBJ_P))) 0, &kickedobj);
823 return 1; /* object broken */
826 if (mon->isshk && kickedobj->where == OBJ_MINVENT
827 && kickedobj->ocarry == mon)
828 return 1; /* alert shk caught it */
829 notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
830 if (isgold ? ghitm(mon, kickedobj) /* caught? */
831 : thitmonst(mon, kickedobj)) /* hit && used up? */
835 /* the object might have fallen down a hole;
836 ship_object() will have taken care of shop billing */
837 if (kickedobj->where == OBJ_MIGRATING)
840 bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE);
841 if (costly && (!costly_spot(bhitpos.x, bhitpos.y)
842 || *in_rooms(x, y, SHOPBASE) != bhitroom)) {
844 costly_gold(x, y, kickedobj->quan);
846 (void) stolen_value(kickedobj, x, y, (boolean) shkp->mpeaceful,
851 if (flooreffects(kickedobj, bhitpos.x, bhitpos.y, "fall"))
853 if(flooreffects(kickedobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é"))
855 if (kickedobj->unpaid)
856 subfrombill(kickedobj, shkp);
857 place_object(kickedobj, bhitpos.x, bhitpos.y);
859 newsym(kickedobj->ox, kickedobj->oy);
863 /* cause of death if kicking kills kicker */
871 what = killer_xname(kickedobj);
872 else if (maploc == &nowhere)
876 what = "
\89½
\82à
\82È
\82¢
\82Æ
\82±
\82ë";
877 else if (IS_DOOR(maploc->typ))
882 else if (IS_TREE(maploc->typ))
887 else if (IS_STWALL(maploc->typ))
892 else if (IS_ROCK(maploc->typ))
897 else if (IS_THRONE(maploc->typ))
902 else if (IS_FOUNTAIN(maploc->typ))
907 else if (IS_GRAVE(maploc->typ))
909 what = "a headstone";
912 else if (IS_SINK(maploc->typ))
916 what = "
\97¬
\82µ
\91ä";
917 else if (IS_ALTAR(maploc->typ))
922 else if (IS_DRAWBRIDGE(maploc->typ))
924 what = "a drawbridge";
926 what = "
\92µ
\82Ë
\8b´";
927 else if (maploc->typ == STAIRS)
932 else if (maploc->typ == LADDER)
936 what = "
\82Í
\82µ
\82²";
937 else if (maploc->typ == IRONBARS)
939 what = "an iron bar";
944 what = "something weird";
946 what = "
\89½
\82©
\96
\82È
\82à
\82Ì";
948 return strcat(strcpy(buf, "kicking "), what);
950 Sprintf(buf, "%s
\82ð
\8fR
\82Á
\82Ä", what);
960 int dmg = 0, glyph, oldglyph = -1;
961 register struct monst *mtmp;
962 boolean no_kick = FALSE;
965 if (nolimbs(youmonst.data) || slithy(youmonst.data)) {
967 You("have no legs to kick with.");
969 You("
\89½
\82©
\82ð
\8fR
\82ë
\82¤
\82É
\82à
\91«
\82ª
\82È
\82¢
\81D");
971 } else if (verysmall(youmonst.data)) {
973 You("are too small to do any kicking.");
975 You("
\89½
\82©
\82ð
\8fR
\82é
\82É
\82Í
\8f¬
\82³
\82·
\82¬
\82é
\81D");
977 } else if (u.usteed) {
979 if (yn_function("Kick your steed?", ynchars, 'y') == 'y') {
981 if (yn_function("
\94n
\82ð
\8fR
\82é
\81H", ynchars, 'y') == 'y') {
983 You("kick %s.", mon_nam(u.usteed));
985 You("%s
\82ð
\8fR
\82Á
\82½
\81D", mon_nam(u.usteed));
991 } else if (Wounded_legs) {
992 /* note: jump() has similar code */
993 long wl = (EWounded_legs & BOTH_SIDES);
994 const char *bp = body_part(LEG);
996 if (wl == BOTH_SIDES)
998 Your("%s%s %s in no shape for kicking.",
999 (wl == LEFT_SIDE) ? "left " : (wl == RIGHT_SIDE) ? "right " : "",
1000 bp, (wl == BOTH_SIDES) ? "are" : "is");
1002 } else if (near_capacity() > SLT_ENCUMBER) {
1004 Your("load is too heavy to balance yourself for a kick.");
1006 You("
\82½
\82
\82³
\82ñ
\82à
\82Ì
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\8fR
\82è
\82Ì
\82½
\82ß
\82Ì
\83o
\83\89\83\93\83X
\82ª
\82Æ
\82ê
\82È
\82¢
\81D");
1008 } else if (youmonst.data->mlet == S_LIZARD) {
1010 Your("legs cannot kick effectively.");
1012 Your("
\91«
\82Å
\82Í
\82¤
\82Ü
\82
\8fR
\82ê
\82È
\82¢
\81D");
1014 } else if (u.uinwater && !rn2(2)) {
1016 Your("slow motion kick doesn't hit anything.");
1018 Your("
\92x
\82¢
\93®
\82«
\82Ì
\8fR
\82è
\82Å
\82Í
\96½
\92\86\82µ
\82æ
\82¤
\82ª
\82È
\82¢
\81D");
1020 } else if (u.utrap) {
1022 switch (u.utraptype) {
1026 pline("There's not enough room to kick down here.");
1028 pline("
\97\8e\82µ
\8c\8a\82É
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\82Ì
\82Å
\81C
\8fR
\82ê
\82È
\82¢
\81D");
1035 You_cant("move your %s!", body_part(LEG));
1037 You("%s
\82ð
\93®
\82©
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", body_part(LEG));
1045 /* ignore direction typed before player notices kick failed */
1046 display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1050 if (!getdir((char *) 0))
1058 /* KMH -- Kicking boots always succeed */
1059 if (uarmf && uarmf->otyp == KICKING_BOOTS)
1062 avrg_attrib = (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3;
1068 You_cant("move your %s!", body_part(LEG));
1070 You("%s
\82ð
\93®
\82©
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", body_part(LEG));
1073 if (is_animal(u.ustuck->data)) {
1075 pline("%s burps loudly.", Monnam(u.ustuck));
1077 pline("%s
\82Í
\91å
\82«
\82È
\83Q
\83b
\83v
\82ð
\82µ
\82½
\81D", Monnam(u.ustuck));
1082 Your("feeble kick has no effect.");
1084 Your("
\8eã
\81X
\82µ
\82¢
\8fR
\82è
\82Í
\8cø
\89Ê
\82ª
\82È
\82¢
\81D"); break;
1088 } else if (u.utrap && u.utraptype == TT_PIT) {
1089 /* must be Passes_walls */
1091 You("kick at the side of the pit.");
1093 You("
\97\8e\82µ
\8c\8a\82Ì
\95Ç
\82ð
\8fR
\82Á
\82½
\81D");
1101 /* doors can be opened while levitating, so they must be
1102 * reachable for bracing purposes
1103 * Possible extension: allow bracing against stuff on the side?
1105 if (isok(xx, yy) && !IS_ROCK(levl[xx][yy].typ)
1106 && !IS_DOOR(levl[xx][yy].typ)
1107 && (!Is_airlevel(&u.uz) || !OBJ_AT(xx, yy))) {
1109 You("have nothing to brace yourself against.");
1111 pline("
\8ex
\82¦
\82É
\82Å
\82«
\82é
\82æ
\82¤
\82È
\82à
\82Ì
\82ª
\96³
\82¢
\81D");
1116 mtmp = isok(x, y) ? m_at(x, y) : 0;
1117 /* might not kick monster if it is hidden and becomes revealed,
1118 if it is peaceful and player declines to attack, or if the
1119 hero passes out due to encumbrance with low hp; context.move
1120 will be 1 unless player declines to kick peaceful monster */
1122 oldglyph = glyph_at(x, y);
1123 if (!maybe_kick_monster(mtmp, x, y))
1124 return context.move;
1134 maploc = &levl[x][y];
1137 * The next five tests should stay in their present order:
1138 * monsters, pools, objects, non-doors, doors.
1140 * [FIXME: Monsters who are hidden underneath objects or
1141 * in pools should lead to hero kicking the concealment
1142 * rather than the monster, probably exposing the hidden
1143 * monster in the process. And monsters who are hidden on
1144 * ceiling shouldn't be kickable (unless hero is flying?);
1145 * kicking toward them should just target whatever is on
1146 * the floor at that spot.]
1150 /* save mtmp->data (for recoil) in case mtmp gets killed */
1151 struct permonst *mdat = mtmp->data;
1153 kick_monster(mtmp, x, y);
1154 glyph = glyph_at(x, y);
1155 /* see comment in attack_checks() */
1156 if (mtmp->mhp <= 0) { /* DEADMONSTER() */
1157 /* if we mapped an invisible monster and immediately
1158 killed it, we don't want to forget what we thought
1159 was there before the kick */
1160 if (glyph != oldglyph && glyph_is_invisible(glyph))
1161 show_glyph(x, y, oldglyph);
1162 } else if (!canspotmon(mtmp)
1163 /* check <x,y>; monster that evades kick by jumping
1164 to an unseen square doesn't leave an I behind */
1165 && mtmp->mx == x && mtmp->my == y
1166 && !glyph_is_invisible(glyph)
1167 && !(u.uswallow && mtmp == u.ustuck)) {
1168 map_invisible(x, y);
1170 /* recoil if floating */
1171 if ((Is_airlevel(&u.uz) || Levitation) && context.move) {
1175 ((int) youmonst.data->cwt + (weight_cap() + inv_weight()));
1177 range = 1; /* divide by zero avoidance */
1178 range = (3 * (int) mdat->cwt) / range;
1182 hurtle(-u.dx, -u.dy, range, TRUE);
1186 if (glyph_is_invisible(levl[x][y].glyph)) {
1190 if (is_pool(x, y) ^ !!u.uinwater) {
1191 /* objects normally can't be removed from water by kicking */
1193 You("splash some water around.");
1195 You("
\90\85\82ð
\89ñ
\82è
\82É
\82Ü
\82«
\82¿
\82ç
\82µ
\82½
\81D");
1199 if (OBJ_AT(x, y) && (!Levitation || Is_airlevel(&u.uz)
1200 || Is_waterlevel(&u.uz) || sobj_at(BOULDER, x, y))) {
1201 if (kick_object(x, y)) {
1202 if (Is_airlevel(&u.uz))
1203 hurtle(-u.dx, -u.dy, 1, TRUE); /* assume it's light */
1209 if (!IS_DOOR(maploc->typ)) {
1210 if (maploc->typ == SDOOR) {
1211 if (!Levitation && rn2(30) < avrg_attrib) {
1212 cvt_sdoor_to_door(maploc); /* ->typ = DOOR */
1214 pline("Crash! %s a secret door!",
1215 /* don't "kick open" when it's locked
1216 unless it also happens to be trapped */
1217 (maploc->doormask & (D_LOCKED | D_TRAPPED)) == D_LOCKED
1218 ? "Your kick uncovers"
1221 pline("
\83K
\83V
\83\83\83\93\81I
\82 \82È
\82½
\82Í
\94é
\96§
\82Ì
\94à
\82ð%s
\82½
\81I",
1222 (maploc->doormask & (D_LOCKED|D_TRAPPED)) == D_LOCKED
1224 : "
\8fR
\82è
\8aJ
\82¯");
1226 exercise(A_DEX, TRUE);
1227 if (maploc->doormask & D_TRAPPED) {
1228 maploc->doormask = D_NODOOR;
1230 b_trapped("door", FOOT);
1232 b_trapped("
\94à", FOOT);
1233 } else if (maploc->doormask != D_NODOOR
1234 && !(maploc->doormask & D_LOCKED))
1235 maploc->doormask = D_ISOPEN;
1236 feel_newsym(x, y); /* we know it's gone */
1237 if (maploc->doormask == D_ISOPEN
1238 || maploc->doormask == D_NODOOR)
1239 unblock_point(x, y); /* vision */
1244 if (maploc->typ == SCORR) {
1245 if (!Levitation && rn2(30) < avrg_attrib) {
1247 pline("Crash! You kick open a secret passage!");
1249 pline("
\83K
\83V
\83\83\83\93\81I
\82 \82È
\82½
\82Í
\94é
\96§
\82Ì
\92Ê
\98H
\82ð
\8fR
\82è
\82â
\82Ô
\82Á
\82½
\81I");
1250 exercise(A_DEX, TRUE);
1252 feel_newsym(x, y); /* we know it's gone */
1253 unblock_point(x, y); /* vision */
1258 if (IS_THRONE(maploc->typ)) {
1262 if ((Luck < 0 || maploc->doormask) && !rn2(3)) {
1264 maploc->doormask = 0; /* don't leave loose ends.. */
1265 (void) mkgold((long) rnd(200), x, y);
1268 pline("CRASH! You destroy it.");
1270 pline("
\83K
\83V
\83\83\83\93\81I
\82 \82È
\82½
\82Í
\89½
\82©
\82ð
\94j
\89ó
\82µ
\82½
\81D");
1273 pline("CRASH! You destroy the throne.");
1275 pline("
\83K
\83V
\83\83\83\93\81I
\82 \82È
\82½
\82Í
\8bÊ
\8dÀ
\82ð
\94j
\89ó
\82µ
\82½
\81D");
1278 exercise(A_DEX, TRUE);
1280 } else if (Luck > 0 && !rn2(3) && !maploc->looted) {
1281 (void) mkgold((long) rn1(201, 300), x, y);
1287 rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE - 1), x, y,
1291 You("kick %s loose!", something);
1293 You("
\82È
\82É
\82©
\82ð
\8fR
\82è
\8eU
\82ç
\82µ
\82½
\81I");
1296 You("kick loose some ornamental coins and gems!");
1298 You("
\91\95\8fü
\97p
\82Ì
\8bà
\89Ý
\82â
\95ó
\90Î
\82ð
\8fR
\82è
\8eU
\82ç
\82µ
\82½
\81I");
1301 /* prevent endless milking */
1302 maploc->looted = T_LOOTED;
1304 } else if (!rn2(4)) {
1305 if (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) {
1306 fall_through(FALSE);
1313 if (IS_ALTAR(maploc->typ)) {
1317 You("kick %s.", (Blind ? something : "the altar"));
1319 You("%s
\82ð
\8fR
\82Á
\82½
\81D", (Blind ? "
\89½
\82©" : "
\8dÕ
\92d"));
1323 exercise(A_DEX, TRUE);
1326 if (IS_FOUNTAIN(maploc->typ)) {
1330 You("kick %s.", (Blind ? something : "the fountain"));
1332 You("%s
\82ð
\8fR
\82Á
\82½
\81D",(Blind ? "
\89½
\82©" : "
\90ò"));
1335 /* make metal boots rust */
1336 if (uarmf && rn2(3))
1338 if (water_damage(uarmf, "metal boots", TRUE) == ER_NOTHING) {
1340 if (water_damage(uarmf, "
\8bà
\91®
\82Ì
\8cC", TRUE) == ER_NOTHING) {
1342 Your("boots get wet.");
1344 Your("
\8cC
\82Í
\94G
\82ê
\82½
\81D");
1345 /* could cause short-lived fumbling here */
1347 exercise(A_DEX, TRUE);
1350 if (IS_GRAVE(maploc->typ)) {
1355 exercise(A_WIS, FALSE);
1356 if (Role_if(PM_ARCHEOLOGIST) || Role_if(PM_SAMURAI)
1357 || ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10))) {
1358 adjalign(-sgn(u.ualign.type));
1361 maploc->doormask = 0;
1362 (void) mksobj_at(ROCK, x, y, TRUE, FALSE);
1365 pline("Crack! %s broke!", Something);
1367 pline_The("headstone topples over and breaks!");
1372 if (maploc->typ == IRONBARS)
1374 if (IS_TREE(maploc->typ)) {
1375 struct obj *treefruit;
1376 /* nothing, fruit or trouble? 75:23.5:1.5% */
1378 if (!rn2(6) && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
1380 You_hear("a low buzzing."); /* a warning */
1382 You_hear("
\82Ô
\81[
\82ñ
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D"); /* a warning */
1386 if (rn2(15) && !(maploc->looted & TREE_LOOTED)
1387 && (treefruit = rnd_treefruit_at(x, y))) {
1388 long nfruit = 8L - rnl(7), nfall;
1389 short frtype = treefruit->otyp;
1390 treefruit->quan = nfruit;
1391 if (is_plural(treefruit))
1393 pline("Some %s fall from the tree!", xname(treefruit));
1395 pline("%s
\82ª
\89½
\8cÂ
\82©
\96Ø
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I", xname(treefruit));
1398 pline("%s falls from the tree!", An(xname(treefruit)));
1400 pline("%s
\82ª
\96Ø
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I", xname(treefruit));
1401 nfall = scatter(x, y, 2, MAY_HIT, treefruit);
1402 if (nfall != nfruit) {
1403 /* scatter left some in the tree, but treefruit
1404 * may not refer to the correct object */
1405 treefruit = mksobj(frtype, TRUE, FALSE);
1406 treefruit->quan = nfruit - nfall;
1408 pline("%ld %s got caught in the branches.",
1409 nfruit - nfall, xname(treefruit));
1411 pline("%ld
\8cÂ
\82Ì%s
\82ª
\8e}
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81D",
1412 nfruit - nfall, xname(treefruit));
1414 dealloc_obj(treefruit);
1416 exercise(A_DEX, TRUE);
1417 exercise(A_WIS, TRUE); /* discovered a new food source! */
1419 maploc->looted |= TREE_LOOTED;
1421 } else if (!(maploc->looted & TREE_SWARM)) {
1422 int cnt = rnl(4) + 2;
1428 if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE])
1429 && makemon(&mons[PM_KILLER_BEE], mm.x, mm.y,
1435 pline("You've attracted the tree's former occupants!");
1437 pline("
\96Ø
\82Ì
\90æ
\8fZ
\96¯
\82ð
\8bN
\82±
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1440 You("smell stale honey.");
1442 pline("
\8cÃ
\82¢
\82Í
\82¿
\82Ý
\82Â
\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
1443 maploc->looted |= TREE_SWARM;
1448 if (IS_SINK(maploc->typ)) {
1449 int gend = poly_gender();
1450 short washerndx = (gend == 1 || (gend == 2 && rn2(2)))
1459 pline("Klunk! The pipes vibrate noisily.");
1461 pline("
\83K
\83\89\83\93\81I
\83p
\83C
\83v
\82Í
\82¤
\82é
\82³
\82
\90U
\93®
\82µ
\82½
\81D");
1466 pline("
\83K
\83\89\83\93\81I");
1467 exercise(A_DEX, TRUE);
1469 } else if (!(maploc->looted & S_LPUDDING) && !rn2(3)
1470 && !(mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) {
1473 You_hear("a gushing sound.");
1475 You_hear("
\82È
\82É
\82©
\82ª
\95¬
\8fo
\82·
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1478 pline("A %s ooze gushes up from the drain!",
1480 pline("%s
\89t
\91Ì
\82ª
\94r
\90\85\8cû
\82©
\82ç
\82É
\82¶
\82Ý
\8fo
\82½
\81I",
1482 (void) makemon(&mons[PM_BLACK_PUDDING], x, y, NO_MM_FLAGS);
1483 exercise(A_DEX, TRUE);
1485 maploc->looted |= S_LPUDDING;
1487 } else if (!(maploc->looted & S_LDWASHER) && !rn2(3)
1488 && !(mvitals[washerndx].mvflags & G_GONE)) {
1489 /* can't resist... */
1491 pline("%s returns!", (Blind ? Something : "The dish washer"));
1493 pline("%s
\82ª
\96ß
\82Á
\82Ä
\82«
\82½
\81I", (Blind ? "
\89½
\82©" : "
\8eM
\90ô
\82¢"));
1494 if (makemon(&mons[washerndx], x, y, NO_MM_FLAGS))
1496 maploc->looted |= S_LDWASHER;
1497 exercise(A_DEX, TRUE);
1499 } else if (!rn2(3)) {
1502 (Blind ? "You hear a sloshing sound"
1503 : "Muddy waste pops up from the drain"));
1505 pline("
\82¤
\82í
\81I%s
\81D",
1506 (Blind ? "
\82 \82È
\82½
\82Í
\81C
\83o
\83`
\83\83\83o
\83`
\83\83\82·
\82é
\89¹
\82ð
\95·
\82¢
\82½"
1507 : "
\94r
\90\85\8cû
\82©
\82ç
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\94p
\8aü
\95¨
\82ª
\8fo
\82Ä
\82
\82é"));
1509 if (!(maploc->looted & S_LRING)) { /* once per sink */
1512 You_see("a ring shining in its midst.");
1514 You("
\82»
\82Ì
\92\86\82É
\8cõ
\82é
\8ew
\97Ö
\82ð
\8c©
\82Â
\82¯
\82½
\81D");
1515 (void) mkobj_at(RING_CLASS, x, y, TRUE);
1517 exercise(A_DEX, TRUE);
1518 exercise(A_WIS, TRUE); /* a discovery! */
1519 maploc->looted |= S_LRING;
1525 if (maploc->typ == STAIRS || maploc->typ == LADDER
1526 || IS_STWALL(maploc->typ)) {
1527 if (!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN)
1531 pline("Ouch! That hurts!");
1533 pline("
\82¢
\82Ä
\82Á
\81I
\89ö
\89ä
\82µ
\82½
\81I");
1534 exercise(A_DEX, FALSE);
1535 exercise(A_STR, FALSE);
1538 feel_location(x, y); /* we know we hit it */
1539 if (is_drawbridge_wall(x, y) >= 0) {
1541 pline_The("drawbridge is unaffected.");
1543 pline("
\92µ
\82Ë
\8b´
\82Í
\82Ñ
\82
\82Æ
\82à
\82µ
\82È
\82¢
\81D");
1544 /* update maploc to refer to the drawbridge */
1545 (void) find_drawbridge(&x, &y);
1546 maploc = &levl[x][y];
1550 set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
1551 dmg = rnd(ACURR(A_CON) > 15 ? 3 : 5);
1552 losehp(Maybe_Half_Phys(dmg), kickstr(buf), KILLED_BY);
1553 if (Is_airlevel(&u.uz) || Levitation)
1554 hurtle(-u.dx, -u.dy, rn1(2, 4), TRUE); /* assume it's heavy */
1560 if (maploc->doormask == D_ISOPEN || maploc->doormask == D_BROKEN
1561 || maploc->doormask == D_NODOOR) {
1563 exercise(A_DEX, FALSE);
1564 if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
1566 You("kick at empty space.");
1568 You("
\89½
\82à
\82È
\82¢
\8bó
\8aÔ
\82ð
\8fR
\82Á
\82½
\81D");
1570 feel_location(x, y);
1573 pline("Dumb move! You strain a muscle.");
1575 pline("
\82Î
\82©
\82°
\82½
\93®
\82«
\82¾
\81I
\8bØ
\93÷
\82ð
\92É
\82ß
\82½
\81D");
1576 exercise(A_STR, FALSE);
1577 set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
1579 if ((Is_airlevel(&u.uz) || Levitation) && rn2(2))
1580 hurtle(-u.dx, -u.dy, 1, TRUE);
1581 return 1; /* uses a turn */
1584 /* not enough leverage to kick open doors while levitating */
1588 exercise(A_DEX, TRUE);
1589 /* door is known to be CLOSED or LOCKED */
1590 if (rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) {
1591 boolean shopdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE;
1592 /* break the door */
1593 if (maploc->doormask & D_TRAPPED) {
1596 You("kick the door.");
1598 You("
\94à
\82ð
\8fR
\82Á
\82½
\81D");
1599 exercise(A_STR, FALSE);
1600 maploc->doormask = D_NODOOR;
1602 b_trapped("door", FOOT);
1604 b_trapped("
\94à", FOOT);
1605 } else if (ACURR(A_STR) > 18 && !rn2(5) && !shopdoor) {
1607 pline("As you kick the door, it shatters to pieces!");
1609 pline("
\94à
\82ð
\8fR
\82é
\82Æ
\81C
\82±
\82È
\82²
\82È
\82É
\82
\82¾
\82¯
\82½
\81I");
1610 exercise(A_STR, TRUE);
1611 maploc->doormask = D_NODOOR;
1614 pline("As you kick the door, it crashes open!");
1616 pline("
\94à
\82ð
\8fR
\82é
\82Æ
\81C
\89ó
\82ê
\82Ä
\8aJ
\82¢
\82½
\81I");
1617 exercise(A_STR, TRUE);
1618 maploc->doormask = D_BROKEN;
1620 feel_newsym(x, y); /* we know we broke it */
1621 unblock_point(x, y); /* vision */
1623 add_damage(x, y, 400L);
1625 pay_for_damage("break", FALSE);
1627 pay_for_damage("
\94j
\89ó
\82·
\82é", FALSE);
1630 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1631 if (DEADMONSTER(mtmp))
1633 if (is_watch(mtmp->data) && couldsee(mtmp->mx, mtmp->my)
1634 && mtmp->mpeaceful) {
1636 mon_yells(mtmp, "Halt, thief! You're under arrest!");
1638 mon_yells(mtmp, "
\8e~
\82Ü
\82ê
\93D
\96_
\81I
\82¨
\82Ü
\82¦
\82ð
\91ß
\95ß
\82·
\82é
\81I");
1639 (void) angry_guards(FALSE);
1645 feel_location(x, y); /* we know we hit it */
1646 exercise(A_STR, TRUE);
1650 pline("
\82®
\82\9f\82\9f\82\9f\82ñ
\81I");
1652 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1653 if (DEADMONSTER(mtmp))
1655 if (is_watch(mtmp->data) && mtmp->mpeaceful
1656 && couldsee(mtmp->mx, mtmp->my)) {
1657 if (levl[x][y].looted & D_WARNED) {
1660 "Halt, vandal! You're under arrest!");
1662 "
\8e~
\82Ü
\82ê
\96ì
\94Ø
\90l
\81I
\82¨
\82Ü
\82¦
\82ð
\91ß
\95ß
\82·
\82é
\81I");
1663 (void) angry_guards(FALSE);
1666 mon_yells(mtmp, "Hey, stop damaging that door!");
1668 mon_yells(mtmp, "
\82¨
\82¢
\81C
\94à
\82ð
\94j
\89ó
\82·
\82é
\82Ì
\82ð
\82â
\82ß
\82ë
\81I");
1669 levl[x][y].looted |= D_WARNED;
1683 /* cover all the MIGR_xxx choices generated by down_gate() */
1685 case MIGR_RANDOM: /* trap door or hole */
1686 if (Is_stronghold(&u.uz)) {
1687 cc->x = valley_level.dnum;
1688 cc->y = valley_level.dlevel;
1690 } else if (In_endgame(&u.uz) || Is_botlevel(&u.uz)) {
1693 } /* else fall to the next cases */
1694 case MIGR_STAIRS_UP:
1695 case MIGR_LADDER_UP:
1697 cc->y = u.uz.dlevel + 1;
1700 cc->x = sstairs.tolev.dnum;
1701 cc->y = sstairs.tolev.dlevel;
1705 /* y==0 means "nowhere", in which case x doesn't matter */
1711 /* player or missile impacts location, causing objects to fall down */
1713 impact_drop(missile, x, y, dlev)
1714 struct obj *missile; /* caused impact, won't drop itself */
1715 xchar x, y; /* location affected */
1716 xchar dlev; /* if !0 send to dlev near player */
1719 register struct obj *obj, *obj2;
1720 register struct monst *shkp;
1721 long oct, dct, price, debit, robbed;
1722 boolean angry, costly, isrock;
1728 toloc = down_gate(x, y);
1729 drop_to(&cc, toloc);
1734 /* send objects next to player falling through trap door.
1735 * checked in obj_delivery().
1737 toloc = MIGR_WITH_HERO;
1741 costly = costly_spot(x, y);
1742 price = debit = robbed = 0L;
1744 shkp = (struct monst *) 0;
1745 /* if 'costly', we must keep a record of ESHK(shkp) before
1746 * it undergoes changes through the calls to stolen_value.
1747 * the angry bit must be reset, if needed, in this fn, since
1748 * stolen_value is called under the 'silent' flag to avoid
1749 * unsavory pline repetitions.
1752 if ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0) {
1753 debit = ESHK(shkp)->debit;
1754 robbed = ESHK(shkp)->robbed;
1755 angry = !shkp->mpeaceful;
1759 isrock = (missile && missile->otyp == ROCK);
1761 for (obj = level.objects[x][y]; obj; obj = obj2) {
1762 obj2 = obj->nexthere;
1765 /* number of objects in the pile */
1767 if (obj == uball || obj == uchain)
1769 /* boulders can fall too, but rarely & never due to rocks */
1770 if ((isrock && obj->otyp == BOULDER)
1771 || rn2(obj->otyp == BOULDER ? 30 : 3))
1773 obj_extract_self(obj);
1776 price += stolen_value(
1777 obj, x, y, (costly_spot(u.ux, u.uy)
1778 && index(u.urooms, *in_rooms(x, y, SHOPBASE))),
1780 /* set obj->no_charge to 0 */
1781 if (Has_contents(obj))
1782 picked_container(obj); /* does the right thing */
1783 if (obj->oclass != COIN_CLASS)
1787 add_to_migration(obj);
1790 obj->owornmask = (long) toloc;
1792 /* number of fallen objects */
1796 if (dct && cansee(x, y)) { /* at least one object fell */
1798 const char *what = (dct == 1L ? "object falls" : "objects fall");
1800 const char *what = "
\95¨";
1804 pline("From the impact, %sother %s.",
1805 dct == oct ? "the " : dct == 1L ? "an" : "", what);
1807 pline("
\8fÕ
\8c\82\82Å
\81C
\91¼
\82Ì%s
\82ª
\97\8e\82¿
\82½
\81D",what);
1809 else if (oct == dct)
1811 pline("%s adjacent %s %s.", dct == 1L ? "The" : "All the", what,
1814 pline("
\8bß
\82
\82É
\82 \82Á
\82½%s
\82ª%s
\97\8e\82¿
\82½
\81D", what, gate_str);
1818 pline("%s adjacent %s %s.",
1819 dct == 1L ? "One of the" : "Some of the",
1820 dct == 1L ? "objects falls" : what, gate_str);
1822 pline("
\8bß
\82
\82É
\82 \82Á
\82½%s%s%s
\97\8e\82¿
\82½
\81D",
1824 dct == 1L ? "
\82ª" : "
\82Ì
\82¢
\82
\82Â
\82©
\82ª",
1829 if (costly && shkp && price) {
1830 if (ESHK(shkp)->robbed > robbed) {
1832 You("removed %ld %s worth of goods!", price, currency(price));
1834 You("%ld%s
\95ª
\82Ì
\95i
\95¨
\82ð
\8eæ
\82è
\82³
\82Á
\82½
\81I", price, currency(price));
1835 if (cansee(shkp->mx, shkp->my)) {
1836 if (ESHK(shkp)->customer[0] == 0)
1837 (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
1840 pline("%s is infuriated!", Monnam(shkp));
1842 pline("%s
\82Í
\8c\83\93{
\82µ
\82½
\81I", Monnam(shkp));
1845 pline("\"%s, you are a thief!\"", plname);
1847 pline("
\81u%s
\82ß
\81C
\82¨
\82Ü
\82¦
\82Í
\93D
\96_
\82¾
\82È
\81I
\81v", plname);
1850 You_hear("a scream, \"Thief!\"");
1852 You_hear("
\8bà
\90Ø
\82è
\90º
\82ð
\95·
\82¢
\82½
\81u
\93D
\96_
\81I
\81v");
1854 (void) angry_guards(FALSE);
1857 if (ESHK(shkp)->debit > debit) {
1858 long amt = (ESHK(shkp)->debit - debit);
1860 You("owe %s %ld %s for goods lost.", Monnam(shkp), amt,
1863 You("
\95i
\95¨
\8fÁ
\8e¸
\82Ì
\82½
\82ß%s
\82É%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", Monnam(shkp), amt,
1870 /* NOTE: ship_object assumes otmp was FREED from fobj or invent.
1871 * <x,y> is the point of drop. otmp is _not_ an <x,y> resident:
1872 * otmp is either a kicked, dropped, or thrown object.
1875 ship_object(otmp, x, y, shop_floor_obj)
1878 boolean shop_floor_obj;
1885 boolean nodrop, unpaid, container, impact = FALSE;
1890 if ((toloc = down_gate(x, y)) == MIGR_NOWHERE)
1892 drop_to(&cc, toloc);
1896 /* objects other than attached iron ball always fall down ladder,
1897 but have a chance of staying otherwise */
1898 nodrop = (otmp == uball) || (otmp == uchain)
1899 || (toloc != MIGR_LADDER_UP && rn2(3));
1901 container = Has_contents(otmp);
1902 unpaid = is_unpaid(otmp);
1905 for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
1911 /* boulders never fall through trap doors, but they might knock
1912 other things down before plugging the hole */
1913 if (otmp->otyp == BOULDER && ((t = t_at(x, y)) != 0)
1914 && (t->ttyp == TRAPDOOR || t->ttyp == HOLE)) {
1916 impact_drop(otmp, x, y, 0);
1917 return FALSE; /* let caller finish the drop */
1921 otransit_msg(otmp, nodrop, n);
1925 impact_drop(otmp, x, y, 0);
1929 if (unpaid || shop_floor_obj) {
1931 (void) stolen_value(otmp, u.ux, u.uy, TRUE, FALSE);
1935 (void) stolen_value(
1937 (costly_spot(u.ux, u.uy)
1938 && index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),
1941 /* set otmp->no_charge to 0 */
1943 picked_container(otmp); /* happens to do the right thing */
1944 if (otmp->oclass != COIN_CLASS)
1945 otmp->no_charge = 0;
1948 if (otmp->owornmask)
1949 remove_worn_item(otmp, TRUE);
1951 /* some things break rather than ship */
1952 if (breaktest(otmp)) {
1955 if (objects[otmp->otyp].oc_material == GLASS
1956 || otmp->otyp == EXPENSIVE_CAMERA) {
1957 if (otmp->otyp == MIRROR)
1962 result = "
\83O
\83V
\83\83\83b";
1964 /* penalty for breaking eggs laid by you */
1965 if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
1966 change_luck((schar) -min(otmp->quan, 5L));
1970 result = "
\83x
\83`
\83\83\83b";
1973 You_hear("a muffled %s.", result);
1975 You_hear("
\82±
\82à
\82Á
\82½%s
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D", result);
1976 obj_extract_self(otmp);
1977 obfree(otmp, (struct obj *) 0);
1981 add_to_migration(otmp);
1984 otmp->owornmask = (long) toloc;
1985 /* boulder from rolling boulder trap, no longer part of the trap */
1986 if (otmp->otyp == BOULDER)
1990 /* the objs impacted may be in a shop other than
1991 * the one in which the hero is located. another
1992 * check for a shk is made in impact_drop. it is, e.g.,
1993 * possible to kick/throw an object belonging to one
1994 * shop into another shop through a gap in the wall,
1995 * and cause objects belonging to the other shop to
1996 * fall down a trap door--thereby getting two shopkeepers
1997 * angry at the hero in one shot.
1999 impact_drop(otmp, x, y, 0);
2006 obj_delivery(near_hero)
2009 register struct obj *otmp, *otmp2;
2010 register int nx, ny;
2012 boolean nobreak, noscatter;
2014 for (otmp = migrating_objs; otmp; otmp = otmp2) {
2016 if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel)
2019 where = (int) (otmp->owornmask & 0x7fffL); /* destination code */
2020 nobreak = (where & MIGR_NOBREAK) != 0;
2021 noscatter = (where & MIGR_WITH_HERO) != 0;
2022 where &= ~(MIGR_NOBREAK | MIGR_NOSCATTER);
2024 if (!near_hero ^ (where == MIGR_WITH_HERO))
2027 obj_extract_self(otmp);
2028 otmp->owornmask = 0L;
2031 case MIGR_STAIRS_UP:
2032 nx = xupstair, ny = yupstair;
2034 case MIGR_LADDER_UP:
2035 nx = xupladder, ny = yupladder;
2038 nx = sstairs.sx, ny = sstairs.sy;
2040 case MIGR_WITH_HERO:
2041 nx = u.ux, ny = u.uy;
2049 place_object(otmp, nx, ny);
2050 if (!nobreak && !IS_SOFT(levl[nx][ny].typ)) {
2051 if (where == MIGR_WITH_HERO) {
2052 if (breaks(otmp, nx, ny))
2054 } else if (breaktest(otmp)) {
2055 /* assume it broke before player arrived, no messages */
2062 (void) scatter(nx, ny, rnd(2), 0, otmp);
2063 } else { /* random location */
2064 /* set dummy coordinates because there's no
2065 current position for rloco() to update */
2066 otmp->ox = otmp->oy = 0;
2067 if (rloco(otmp) && !nobreak && breaktest(otmp)) {
2068 /* assume it broke before player arrived, no messages */
2076 otransit_msg(otmp, nodrop, num)
2077 register struct obj *otmp;
2078 register boolean nodrop;
2084 Sprintf(obuf, "%s%s",
2085 (otmp->otyp == CORPSE && type_is_pname(&mons[otmp->corpsenm]))
2090 Sprintf(obuf, "%s
\82Í", xname(otmp));
2093 if (num) { /* means: other objects are impacted */
2095 Sprintf(eos(obuf), " %s %s object%s", otense(otmp, "hit"),
2096 num == 1L ? "another" : "other", num > 1L ? "s" : "");
2098 Sprintf(eos(obuf), ".");
2100 Sprintf(eos(obuf), " and %s %s.", otense(otmp, "fall"), gate_str);
2102 Sprintf(eos(obuf), "
\91¼
\82Ì
\95¨
\91Ì
\82É
\96½
\92\86\82µ
\82Ä");
2104 Sprintf(eos(obuf), "
\8e~
\82Ü
\82Á
\82½
\81D");
2106 Sprintf(eos(obuf), "%s
\97\8e\82¿
\82½
\81D", gate_str);
2111 pline("%s %s %s.", obuf, otense(otmp, "fall"), gate_str);
2113 pline("%s%s
\97\8e\82¿
\82½
\81D", obuf, gate_str);
2116 /* migration destination for objects which fall down to next level */
2124 /* this matches the player restriction in goto_level() */
2125 if (on_level(&u.uz, &qstart_level) && !ok_to_quest())
2126 return MIGR_NOWHERE;
2128 if ((xdnstair == x && ydnstair == y)
2129 || (sstairs.sx == x && sstairs.sy == y && !sstairs.up)) {
2131 gate_str = "down the stairs";
2133 gate_str = "
\8aK
\92i
\82©
\82ç";
2134 return (xdnstair == x && ydnstair == y) ? MIGR_STAIRS_UP
2137 if (xdnladder == x && ydnladder == y) {
2139 gate_str = "down the ladder";
2141 gate_str = "
\82Í
\82µ
\82²
\82©
\82ç";
2142 return MIGR_LADDER_UP;
2145 if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen)
2146 && (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)) {
2148 gate_str = (ttmp->ttyp == TRAPDOOR) ? "through the trap door"
2149 : "through the hole";
2151 gate_str = (ttmp->ttyp == TRAPDOOR) ? "
\97\8e\82µ
\94à
\82É"
2156 return MIGR_NOWHERE;