1 /* NetHack 3.6 dokick.c $NHDT-Date: 1517128663 2018/01/28 08:37:43 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.113 $ */
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-2018 */
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, char *));
29 STATIC_DCL int FDECL(really_kick_object, (XCHAR_P, XCHAR_P));
30 STATIC_DCL char *FDECL(kickstr, (char *, const 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, uarmf, 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 */
173 setmangry(mon, TRUE);
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, uarmf, 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))
199 canspotmon(mon) ? a_monnam(mon) : "something hidden");
201 There("%s
\82ª
\82¢
\82é
\81D",
202 canspotmon(mon) ? a_monnam(mon) : "
\89½
\82©
\89B
\82ê
\82Ä
\82¢
\82é
\82à
\82Ì");
206 /* Kick attacks by kicking monsters are normal attacks, not special.
207 * This is almost always worthless, since you can either take one turn
208 * and do all your kicks, or else take one turn and attack the monster
209 * normally, getting all your attacks _including_ all your kicks.
210 * If you have >1 kick attack, you get all of them.
212 if (Upolyd && attacktype(youmonst.data, AT_KICK)) {
213 struct attack *uattk;
214 int sum, kickdieroll, armorpenalty,
216 tmp = find_roll_to_hit(mon, AT_KICK, (struct obj *) 0, &attknum,
219 for (i = 0; i < NATTK; i++) {
220 /* first of two kicks might have provoked counterattack
221 that has incapacitated the hero (ie, floating eye) */
225 uattk = &youmonst.data->mattk[i];
226 /* we only care about kicking attacks here */
227 if (uattk->aatyp != AT_KICK)
230 if (mon->data == &mons[PM_SHADE] && (!uarmf || !uarmf->blessed)) {
231 /* doesn't matter whether it would have hit or missed,
232 and shades have no passive counterattack */
234 Your("%s %s.", kick_passes_thru, mon_nam(mon));
236 You("%s
\82ð
\8fR
\82Á
\82½
\82ª
\81C%s
\81D", mon_nam(mon), kick_passes_thru);
237 break; /* skip any additional kicks */
238 } else if (tmp > (kickdieroll = rnd(20))) {
240 You("kick %s.", mon_nam(mon));
242 You("%s
\82ð
\8fR
\82Á
\82½
\81D", mon_nam(mon));
243 sum = damageum(mon, uattk);
244 (void) passive(mon, uarmf, (boolean) (sum > 0),
245 (sum != 2), AT_KICK, FALSE);
247 break; /* Defender died */
249 missum(mon, uattk, (tmp + armorpenalty > kickdieroll));
250 (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
259 if (i < (j * 3) / 10) {
260 if (!rn2((i < j / 10) ? 2 : (i < j / 5) ? 3 : 4)) {
261 if (martial() && !rn2(2))
264 Your("clumsy kick does no damage.");
266 Your("
\95s
\8aí
\97p
\82È
\8fR
\82è
\82Å
\83_
\83\81\81[
\83W
\82ð
\97^
\82¦
\82ç
\82ê
\82È
\82©
\82Á
\82½
\81D");
267 (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
272 else if (!rn2((i < j / 5) ? 2 : 3))
279 else if (uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
283 You("kick %s.", mon_nam(mon));
285 You("%s
\82ð
\8fR
\82Á
\82½
\81D", mon_nam(mon));
286 if (!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data))
287 && mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data)
288 && mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove
289 && !mon->mstun && !mon->mconf && !mon->msleeping
290 && mon->data->mmove >= 12) {
291 if (!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
293 pline("%s blocks your %skick.", Monnam(mon),
294 clumsy ? "clumsy " : "");
296 pline("%s
\82Í
\82 \82È
\82½
\82Ì%s
\8fR
\82è
\82ð
\96h
\82¢
\82¾
\81D", Monnam(mon),
297 clumsy ? "
\95s
\8aí
\97p
\82È" : "");
299 (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
303 if (mon->mx != x || mon->my != y) {
304 (void) unmap_invisible(x, y);
306 pline("%s %s, %s evading your %skick.", Monnam(mon),
307 (!level.flags.noteleport && can_teleport(mon->data))
309 : is_floater(mon->data)
311 : is_flyer(mon->data) ? "swoops"
312 : (nolimbs(mon->data)
313 || slithy(mon->data))
316 clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : "");
318 pline("%s
\82Í%s
\81C%s
\82 \82È
\82½
\82Ì%s
\8fR
\82è
\82ð
\82½
\82
\82Ý
\82É
\94ð
\82¯
\82½
\81D", Monnam(mon),
319 (!level.flags.noteleport && can_teleport(mon->data))
320 ? "
\8fu
\8aÔ
\88Ú
\93®
\82µ"
321 : is_floater(mon->data)
323 : is_flyer(mon->data) ? "
\82Í
\82Î
\82½
\82«"
324 : (nolimbs(mon->data)
325 || slithy(mon->data))
326 ? "
\89¡
\82É
\8a\8a\82è"
328 clumsy ? "
\8ay
\81X
\82Æ" : "
\91f
\91\81\82", clumsy ? "
\95s
\8aí
\97p
\82È" : "");
330 (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
335 kickdmg(mon, clumsy);
339 * Return TRUE if caught (the gold taken care of), FALSE otherwise.
340 * The gold object is *not* attached to the fobj chain!
344 register struct monst *mtmp;
345 register struct obj *gold;
347 boolean msg_given = FALSE;
349 if (!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest
350 && !mtmp->isgd && !is_mercenary(mtmp->data)) {
352 } else if (!mtmp->mcanmove) {
353 /* too light to do real damage */
354 if (canseemon(mtmp)) {
356 pline_The("%s harmlessly %s %s.", xname(gold),
357 otense(gold, "hit"), mon_nam(mtmp));
359 pline("%s
\82Í%s
\82É
\96½
\92\86\82µ
\82½
\81D", xname(gold),
365 long umoney, value = gold->quan * objects[gold->otyp].oc_cost;
368 finish_meating(mtmp);
369 if (!mtmp->isgd && !rn2(4)) /* not always pleasing */
370 setmangry(mtmp, TRUE);
371 /* greedy monsters catch gold */
372 if (cansee(mtmp->mx, mtmp->my))
374 pline("%s catches the gold.", Monnam(mtmp));
376 pline("%s
\82Í
\8bà
\89Ý
\82ð
\83L
\83\83\83b
\83`
\82µ
\82½
\81D", Monnam(mtmp));
377 (void) mpickobj(mtmp, gold);
378 gold = (struct obj *) 0; /* obj has been freed */
380 long robbed = ESHK(mtmp)->robbed;
387 pline_The("amount %scovers %s recent losses.",
388 !robbed ? "" : "partially ", mhis(mtmp));
390 pline("%s%s
\91¹
\8e¸
\82ð
\95â
\93U
\82·
\82é
\82Ì
\82É
\8eg
\82í
\82ê
\82½
\81D",
391 !robbed ? "" : "
\8bà
\82Ì
\88ê
\95\94\82Í", mhis(mtmp));
393 ESHK(mtmp)->robbed = robbed;
395 make_happy_shk(mtmp, FALSE);
397 if (mtmp->mpeaceful) {
398 ESHK(mtmp)->credit += value;
400 You("have %ld %s in credit.", ESHK(mtmp)->credit,
401 currency(ESHK(mtmp)->credit));
403 You("%ld%s
\82ð
\91Ý
\82µ
\82É
\82µ
\82½
\81D", ESHK(mtmp)->credit,
404 currency(ESHK(mtmp)->credit));
408 verbalize("Thanks, scum!");
410 verbalize("
\82 \82è
\82ª
\82Æ
\82æ
\81I
\82
\82»
\82Á
\82½
\82ê
\81I");
412 } else if (mtmp->ispriest) {
415 verbalize("Thank you for your contribution.");
417 verbalize("
\8añ
\95t
\82É
\8a´
\8eÓ
\82µ
\82Ü
\82·
\81D");
420 verbalize("Thanks, scum!");
422 verbalize("
\82 \82è
\82ª
\82Æ
\82æ
\81I
\82
\82»
\82Á
\82½
\82ê
\81I");
423 } else if (mtmp->isgd) {
424 umoney = money_cnt(invent);
425 /* Some of these are iffy, because a hostile guard
426 won't become peaceful and resume leading hero
427 out of the vault. If he did do that, player
428 could try fighting, then weasle out of being
429 killed by throwing his/her gold when losing. */
433 ? "Drop the rest and follow me."
435 ? "You still have hidden gold. Drop it now."
437 ? "I'll take care of that; please move along."
438 : "I'll take that; now get moving.");
442 ? "
\8ec
\82è
\82ð
\92u
\82¢
\82Ä
\82Â
\82¢
\82Ä
\82«
\82È
\82³
\82¢
\81D"
444 ? "
\82Ü
\82¾
\8bà
\82ð
\89B
\82µ
\82Ä
\82¢
\82é
\82È
\81D
\92u
\82«
\82È
\82³
\82¢
\81D"
446 ? "
\82»
\82ê
\82Í
\8e\84\82ª
\8fE
\82Á
\82Ä
\82¨
\82«
\82Ü
\82·
\82©
\82ç
\82Â
\82¢
\82Ä
\82«
\82Ä
\82
\82¾
\82³
\82¢
\81D"
447 : "
\82»
\82ê
\82Í
\8fE
\82Á
\82Ä
\82¨
\82
\81D
\97\88\82È
\82³
\82¢
\81D");
449 } else if (is_mercenary(mtmp->data)) {
453 if (mtmp->data == &mons[PM_SOLDIER])
455 else if (mtmp->data == &mons[PM_SERGEANT])
457 else if (mtmp->data == &mons[PM_LIEUTENANT])
459 else if (mtmp->data == &mons[PM_CAPTAIN])
463 umoney = money_cnt(invent);
466 + (umoney + u.ulevel * rn2(5)) / ACURR(A_CHA))
467 mtmp->mpeaceful = TRUE;
472 verbalize("That should do. Now beat it!");
474 verbalize("
\82È
\82ñ
\82¾
\82¢
\81H
\82±
\82ê
\82Í
\81H");
477 verbalize("That's not enough, coward!");
479 verbalize("
\82»
\82ñ
\82È
\82à
\82Ì
\82Å
\8dÏ
\82Þ
\82©
\81C
\94Ú
\8b¯
\8eÒ
\81I");
485 miss(xname(gold), mtmp);
489 /* container is kicked, dropped, thrown or otherwise impacted by player.
490 * Assumes container is on floor. Checks contents for possible damage. */
492 container_impact_dmg(obj, x, y)
494 xchar x, y; /* coordinates where object was before the impact, not after */
497 struct obj *otmp, *otmp2;
499 boolean costly, insider, frominv;
501 /* only consider normal containers */
502 if (!Is_container(obj) || !Has_contents(obj) || Is_mbag(obj))
505 costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE)))
506 && costly_spot(x, y));
507 insider = (*u.ushops && inside_shop(u.ux, u.uy)
508 && *in_rooms(x, y, SHOPBASE) == *u.ushops);
509 /* if dropped or thrown, shop ownership flags are set on this obj */
510 frominv = (obj != kickedobj);
512 for (otmp = obj->cobj; otmp; otmp = otmp2) {
513 const char *result = (char *) 0;
516 if (objects[otmp->otyp].oc_material == GLASS
517 && otmp->oclass != GEM_CLASS && !obj_resists(otmp, 33, 100)) {
521 result = "
\83K
\83`
\83\83\83\93";
522 } else if (otmp->otyp == EGG && !rn2(3)) {
526 result = "
\83O
\83V
\83\83\83b";
529 if (otmp->otyp == MIRROR)
532 /* eggs laid by you. penalty is -1 per egg, max 5,
533 * but it's always exactly 1 that breaks */
534 if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
537 You_hear("a muffled %s.", result);
539 You_hear("
\82±
\82à
\82Á
\82½%s
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D", result);
541 if (frominv && !otmp->unpaid)
544 stolen_value(otmp, x, y, (boolean) shkp->mpeaceful, TRUE);
546 if (otmp->quan > 1L) {
549 obj_extract_self(otmp);
550 obfree(otmp, (struct obj *) 0);
552 /* contents of this container are no longer known */
556 if (costly && loss) {
559 You("caused %ld %s worth of damage!", loss, currency(loss));
561 You("%ld%s
\95ª
\82Ì
\91¹
\8aQ
\82ð
\82Ð
\82«
\82¨
\82±
\82µ
\82½
\81I", loss, currency(loss));
562 make_angry_shk(shkp, x, y);
565 You("owe %s %ld %s for objects destroyed.", mon_nam(shkp), loss,
568 You("
\8aí
\95¨
\94j
\91¹
\82Å%s
\82É%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", mon_nam(shkp), loss,
575 /* jacket around really_kick_object */
577 kick_object(x, y, kickobjnam)
584 /* if a pile, the "top" object gets kicked */
585 kickedobj = level.objects[x][y];
587 /* kick object; if doing is fatal, done() will clean up kickedobj */
588 Strcpy(kickobjnam, killer_xname(kickedobj)); /* matters iff res==0 */
589 res = really_kick_object(x, y);
590 kickedobj = (struct obj *) 0;
595 /* guts of kick_object */
597 really_kick_object(x, y)
601 struct monst *mon, *shkp = 0;
604 boolean costly, isgold, slide = FALSE;
606 /* kickedobj should always be set due to conditions of call */
607 if (!kickedobj || kickedobj->otyp == BOULDER || kickedobj == uball
608 || kickedobj == uchain)
611 if ((trap = t_at(x, y)) != 0) {
612 if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !Passes_walls)
613 || trap->ttyp == WEB) {
617 You_cant("kick %s that's in a %s!", something,
618 Hallucination ? "tizzy" :
619 (trap->ttyp == WEB) ? "web" : "pit");
621 You("%s
\82Å
\82Í%s
\82ð
\8fR
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I",
622 Hallucination ? "
\8d¬
\97\90\82µ
\82½
\8fó
\91Ô" :
623 (trap->ttyp == WEB) ? "
\82
\82à
\82Ì
\91\83\82Ì
\92\86" : "
\97\8e\82µ
\8c\8a\82Ì
\92\86",
628 if (trap->ttyp == STATUE_TRAP) {
629 activate_statue_trap(trap, x,y, FALSE);
634 if (Fumbling && !rn2(3)) {
636 Your("clumsy kick missed.");
638 Your("
\95s
\8aí
\97p
\82È
\8fR
\82è
\82Í
\8aO
\82ê
\82½
\81D");
642 if (!uarmf && kickedobj->otyp == CORPSE
643 && touch_petrifies(&mons[kickedobj->corpsenm]) && !Stone_resistance) {
645 You("kick %s with your bare %s.",
646 corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE),
647 makeplural(body_part(FOOT)));
649 You("
\91f%s
\82Å%s
\82ð
\8fR
\82Á
\82½
\81D",
651 corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE));
653 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
654 ; /* hero has been transformed but kick continues */
656 /* normalize body shape here; foot, not body_part(FOOT) */
658 Sprintf(killer.name, "kicking %s barefoot",
660 Sprintf(killer.name, "
\8cC
\96³
\82µ
\82Å%s
\82ð
\8fR
\82Á
\82Ä",
661 killer_xname(kickedobj));
662 instapetrify(killer.name);
666 /* range < 2 means the object will not move. */
667 /* maybe dexterity should also figure here. */
668 range = (int) ((ACURRSTR) / 2 - kickedobj->owt / 40);
674 /* you're in the water too; significantly reduce range */
675 range = range / 3 + 1; /* {1,2}=>1, {3,4,5}=>2, {6,7,8}=>3 */
676 } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
677 /* you're in air, since is_pool did not match */
681 range += rnd(3), slide = TRUE;
682 if (kickedobj->greased)
683 range += rnd(3), slide = TRUE;
686 /* Mjollnir is magically too heavy to kick */
687 if (kickedobj->oartifact == ART_MJOLLNIR)
690 /* see if the object has a place to move into */
691 if (!ZAP_POS(levl[x + u.dx][y + u.dy].typ)
692 || closed_door(x + u.dx, y + u.dy))
695 costly = (!(kickedobj->no_charge && !Has_contents(kickedobj))
696 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
697 && costly_spot(x, y));
698 isgold = (kickedobj->oclass == COIN_CLASS);
700 if (IS_ROCK(levl[x][y].typ) || closed_door(x, y)) {
701 if ((!martial() && rn2(20) > ACURR(A_DEX))
702 || IS_ROCK(levl[u.ux][u.uy].typ) || closed_door(u.ux, u.uy)) {
705 pline("It doesn't come loose.");
707 pline("
\82Ñ
\82
\82Æ
\82à
\82µ
\82È
\82¢
\81D");
710 pline("%s %sn't come loose.",
711 The(distant_name(kickedobj, xname)),
712 otense(kickedobj, "do"));
714 pline("%s
\82Í
\82Ñ
\82
\82Æ
\82à
\82µ
\82È
\82¢
\81D",
715 distant_name(kickedobj, xname));
717 return (!rn2(3) || martial());
721 pline("It comes loose.");
723 pline("
\89½
\82©
\82ª
\8aÉ
\82ñ
\82Å
\82Æ
\82ê
\82½
\81D");
726 pline("%s %s loose.", The(distant_name(kickedobj, xname)),
727 otense(kickedobj, "come"));
729 pline("%s
\82Í
\8aÉ
\82ñ
\82Å
\82Æ
\82ê
\82½
\81D", distant_name(kickedobj, xname));
731 obj_extract_self(kickedobj);
733 if (costly && (!costly_spot(u.ux, u.uy)
734 || !index(u.urooms, *in_rooms(x, y, SHOPBASE))))
735 addtobill(kickedobj, FALSE, FALSE, FALSE);
737 if (!flooreffects(kickedobj, u.ux, u.uy, "fall")) {
739 if (!flooreffects(kickedobj, u.ux, u.uy, "
\97\8e\82¿
\82é")) {
740 place_object(kickedobj, u.ux, u.uy);
747 /* a box gets a chance of breaking open here */
748 if (Is_box(kickedobj)) {
749 boolean otrp = kickedobj->otrapped;
755 pline("
\83K
\83\93\81I");
756 container_impact_dmg(kickedobj, x, y);
757 if (kickedobj->olocked) {
758 if (!rn2(5) || (martial() && !rn2(2))) {
760 You("break open the lock!");
762 You("
\8c®
\82ð
\89ó
\82µ
\8aJ
\82¯
\82½
\81I");
763 breakchestlock(kickedobj, FALSE);
765 (void) chest_trap(kickedobj, LEG, FALSE);
769 if (!rn2(3) || (martial() && !rn2(2))) {
771 pline_The("lid slams open, then falls shut.");
773 pline("
\8aW
\82ª
\82Î
\82½
\82ñ
\82Æ
\8aJ
\82«
\81C
\95Â
\82¶
\82½
\81D");
774 kickedobj->lknown = 1;
776 (void) chest_trap(kickedobj, LEG, FALSE);
782 /* else let it fall through to the next cases... */
785 /* fragile objects should not be kicked */
786 if (hero_breaks(kickedobj, kickedobj->ox, kickedobj->oy, FALSE))
789 /* too heavy to move. range is calculated as potential distance from
790 * player, so range == 2 means the object may move up to one square
791 * from its current position
794 if (!Is_box(kickedobj))
798 pline("
\83S
\83c
\83\93\81I");
799 return (!rn2(3) || martial());
802 if (kickedobj->quan > 1L) {
804 kickedobj = splitobj(kickedobj, 1L);
808 static NEARDATA const char *const flyingcoinmsg[] = {
809 "scatter the coins", "knock coins all over the place",
810 "send coins flying in all directions",
813 static NEARDATA const char *const flyingcoinmsg[] = {
814 "
\8bà
\89Ý
\82ð
\82Ü
\82«
\8eU
\82ç
\82µ
\82½", "
\8bà
\89Ý
\82ð
\82Î
\82ç
\82Ü
\82¢
\82½",
815 "
\8bà
\89Ý
\82ð
\82 \82¿
\82±
\82¿
\82É
\94ò
\82Î
\82µ
\82½",
822 pline("
\83K
\83V
\83\83\81[
\83\93\81I");
824 You("%s!", flyingcoinmsg[rn2(SIZE(flyingcoinmsg))]);
826 You("%s
\81I", flyingcoinmsg[rn2(SIZE(flyingcoinmsg))]);
827 (void) scatter(x, y, rn2(3) + 1, VIS_EFFECTS | MAY_HIT,
832 if (kickedobj->quan > 300L) {
836 pline("
\83S
\83c
\83\93\81I");
837 return (!rn2(3) || martial());
844 pline("Whee! %s %s across the %s.", Doname2(kickedobj),
845 otense(kickedobj, "slide"), surface(x, y));
847 pline("
\83Y
\83\8b\83b
\81I%s
\82Í%s
\82Ì
\8fã
\82ð
\8a\8a\82Á
\82½
\81D", Doname2(kickedobj),
851 if (costly && !isgold)
852 addtobill(kickedobj, FALSE, FALSE, TRUE);
853 obj_extract_self(kickedobj);
854 (void) snuff_candle(kickedobj);
856 mon = bhit(u.dx, u.dy, range, KICKED_WEAPON,
857 (int FDECL((*), (MONST_P, OBJ_P))) 0,
858 (int FDECL((*), (OBJ_P, OBJ_P))) 0, &kickedobj);
860 return 1; /* object broken */
863 if (mon->isshk && kickedobj->where == OBJ_MINVENT
864 && kickedobj->ocarry == mon)
865 return 1; /* alert shk caught it */
866 notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
867 if (isgold ? ghitm(mon, kickedobj) /* caught? */
868 : thitmonst(mon, kickedobj)) /* hit && used up? */
872 /* the object might have fallen down a hole;
873 ship_object() will have taken care of shop billing */
874 if (kickedobj->where == OBJ_MIGRATING)
877 bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE);
878 if (costly && (!costly_spot(bhitpos.x, bhitpos.y)
879 || *in_rooms(x, y, SHOPBASE) != bhitroom)) {
881 costly_gold(x, y, kickedobj->quan);
883 (void) stolen_value(kickedobj, x, y, (boolean) shkp->mpeaceful,
888 if (flooreffects(kickedobj, bhitpos.x, bhitpos.y, "fall"))
890 if(flooreffects(kickedobj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é"))
892 if (kickedobj->unpaid)
893 subfrombill(kickedobj, shkp);
894 place_object(kickedobj, bhitpos.x, bhitpos.y);
896 newsym(kickedobj->ox, kickedobj->oy);
900 /* cause of death if kicking kills kicker */
902 kickstr(buf, kickobjnam)
904 const char *kickobjnam;
910 else if (maploc == &nowhere)
914 what = "
\89½
\82à
\82È
\82¢
\82Æ
\82±
\82ë";
915 else if (IS_DOOR(maploc->typ))
920 else if (IS_TREE(maploc->typ))
925 else if (IS_STWALL(maploc->typ))
930 else if (IS_ROCK(maploc->typ))
935 else if (IS_THRONE(maploc->typ))
940 else if (IS_FOUNTAIN(maploc->typ))
945 else if (IS_GRAVE(maploc->typ))
947 what = "a headstone";
950 else if (IS_SINK(maploc->typ))
954 what = "
\97¬
\82µ
\91ä";
955 else if (IS_ALTAR(maploc->typ))
960 else if (IS_DRAWBRIDGE(maploc->typ))
962 what = "a drawbridge";
964 what = "
\92µ
\82Ë
\8b´";
965 else if (maploc->typ == STAIRS)
970 else if (maploc->typ == LADDER)
974 what = "
\82Í
\82µ
\82²";
975 else if (maploc->typ == IRONBARS)
977 what = "an iron bar";
982 what = "something weird";
984 what = "
\89½
\82©
\96
\82È
\82à
\82Ì";
986 return strcat(strcpy(buf, "kicking "), what);
988 Sprintf(buf, "%s
\82ð
\8fR
\82Á
\82Ä", what);
998 int dmg = 0, glyph, oldglyph = -1;
999 register struct monst *mtmp;
1000 boolean no_kick = FALSE;
1001 char buf[BUFSZ], kickobjnam[BUFSZ];
1003 kickobjnam[0] = '\0';
1004 if (nolimbs(youmonst.data) || slithy(youmonst.data)) {
1006 You("have no legs to kick with.");
1008 You("
\89½
\82©
\82ð
\8fR
\82ë
\82¤
\82É
\82à
\91«
\82ª
\82È
\82¢
\81D");
1010 } else if (verysmall(youmonst.data)) {
1012 You("are too small to do any kicking.");
1014 You("
\89½
\82©
\82ð
\8fR
\82é
\82É
\82Í
\8f¬
\82³
\82·
\82¬
\82é
\81D");
1016 } else if (u.usteed) {
1018 if (yn_function("Kick your steed?", ynchars, 'y') == 'y') {
1020 if (yn_function("
\94n
\82ð
\8fR
\82é
\81H", ynchars, 'y') == 'y') {
1022 You("kick %s.", mon_nam(u.usteed));
1024 You("%s
\82ð
\8fR
\82Á
\82½
\81D", mon_nam(u.usteed));
1030 } else if (Wounded_legs) {
1031 /* note: jump() has similar code */
1032 long wl = (EWounded_legs & BOTH_SIDES);
1033 const char *bp = body_part(LEG);
1035 if (wl == BOTH_SIDES)
1036 bp = makeplural(bp);
1038 Your("%s%s %s in no shape for kicking.",
1039 (wl == LEFT_SIDE) ? "left " : (wl == RIGHT_SIDE) ? "right " : "",
1040 bp, (wl == BOTH_SIDES) ? "are" : "is");
1042 Your("%s%s
\82Í
\8fR
\82è
\82ª
\82Å
\82«
\82é
\8fó
\91Ô
\82¶
\82á
\82È
\82¢
\81D",
1043 (wl == LEFT_SIDE) ? "
\8d¶" : (wl == RIGHT_SIDE) ? "
\89E" : "",
1047 } else if (near_capacity() > SLT_ENCUMBER) {
1049 Your("load is too heavy to balance yourself for a kick.");
1051 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");
1053 } else if (youmonst.data->mlet == S_LIZARD) {
1055 Your("legs cannot kick effectively.");
1057 Your("
\91«
\82Å
\82Í
\82¤
\82Ü
\82
\8fR
\82ê
\82È
\82¢
\81D");
1059 } else if (u.uinwater && !rn2(2)) {
1061 Your("slow motion kick doesn't hit anything.");
1063 Your("
\92x
\82¢
\93®
\82«
\82Ì
\8fR
\82è
\82Å
\82Í
\96½
\92\86\82µ
\82æ
\82¤
\82ª
\82È
\82¢
\81D");
1065 } else if (u.utrap) {
1067 switch (u.utraptype) {
1071 pline("There's not enough room to kick down here.");
1073 pline("
\97\8e\82µ
\8c\8a\82É
\82Í
\82Ü
\82Á
\82Ä
\82¢
\82é
\82Ì
\82Å
\81C
\8fR
\82ê
\82È
\82¢
\81D");
1080 You_cant("move your %s!", body_part(LEG));
1082 You("%s
\82ð
\93®
\82©
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", body_part(LEG));
1090 /* ignore direction typed before player notices kick failed */
1091 display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1095 if (!getdir((char *) 0))
1103 /* KMH -- Kicking boots always succeed */
1104 if (uarmf && uarmf->otyp == KICKING_BOOTS)
1107 avrg_attrib = (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3;
1113 You_cant("move your %s!", body_part(LEG));
1115 You("%s
\82ð
\93®
\82©
\82·
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", body_part(LEG));
1118 if (is_animal(u.ustuck->data)) {
1120 pline("%s burps loudly.", Monnam(u.ustuck));
1122 pline("%s
\82Í
\91å
\82«
\82È
\83Q
\83b
\83v
\82ð
\82µ
\82½
\81D", Monnam(u.ustuck));
1128 Your("feeble kick has no effect.");
1130 Your("
\8eã
\81X
\82µ
\82¢
\8fR
\82è
\82Í
\8cø
\89Ê
\82ª
\82È
\82¢
\81D"); break;
1134 } else if (u.utrap && u.utraptype == TT_PIT) {
1135 /* must be Passes_walls */
1137 You("kick at the side of the pit.");
1139 You("
\97\8e\82µ
\8c\8a\82Ì
\95Ç
\82ð
\8fR
\82Á
\82½
\81D");
1147 /* doors can be opened while levitating, so they must be
1148 * reachable for bracing purposes
1149 * Possible extension: allow bracing against stuff on the side?
1151 if (isok(xx, yy) && !IS_ROCK(levl[xx][yy].typ)
1152 && !IS_DOOR(levl[xx][yy].typ)
1153 && (!Is_airlevel(&u.uz) || !OBJ_AT(xx, yy))) {
1155 You("have nothing to brace yourself against.");
1157 pline("
\8ex
\82¦
\82É
\82Å
\82«
\82é
\82æ
\82¤
\82È
\82à
\82Ì
\82ª
\96³
\82¢
\81D");
1162 mtmp = isok(x, y) ? m_at(x, y) : 0;
1163 /* might not kick monster if it is hidden and becomes revealed,
1164 if it is peaceful and player declines to attack, or if the
1165 hero passes out due to encumbrance with low hp; context.move
1166 will be 1 unless player declines to kick peaceful monster */
1168 oldglyph = glyph_at(x, y);
1169 if (!maybe_kick_monster(mtmp, x, y))
1170 return context.move;
1180 maploc = &levl[x][y];
1183 * The next five tests should stay in their present order:
1184 * monsters, pools, objects, non-doors, doors.
1186 * [FIXME: Monsters who are hidden underneath objects or
1187 * in pools should lead to hero kicking the concealment
1188 * rather than the monster, probably exposing the hidden
1189 * monster in the process. And monsters who are hidden on
1190 * ceiling shouldn't be kickable (unless hero is flying?);
1191 * kicking toward them should just target whatever is on
1192 * the floor at that spot.]
1196 /* save mtmp->data (for recoil) in case mtmp gets killed */
1197 struct permonst *mdat = mtmp->data;
1199 kick_monster(mtmp, x, y);
1200 glyph = glyph_at(x, y);
1201 /* see comment in attack_checks() */
1202 if (mtmp->mhp <= 0) { /* DEADMONSTER() */
1203 /* if we mapped an invisible monster and immediately
1204 killed it, we don't want to forget what we thought
1205 was there before the kick */
1206 if (glyph != oldglyph && glyph_is_invisible(glyph))
1207 show_glyph(x, y, oldglyph);
1208 } else if (!canspotmon(mtmp)
1209 /* check <x,y>; monster that evades kick by jumping
1210 to an unseen square doesn't leave an I behind */
1211 && mtmp->mx == x && mtmp->my == y
1212 && !glyph_is_invisible(glyph)
1213 && !(u.uswallow && mtmp == u.ustuck)) {
1214 map_invisible(x, y);
1216 /* recoil if floating */
1217 if ((Is_airlevel(&u.uz) || Levitation) && context.move) {
1221 ((int) youmonst.data->cwt + (weight_cap() + inv_weight()));
1223 range = 1; /* divide by zero avoidance */
1224 range = (3 * (int) mdat->cwt) / range;
1228 hurtle(-u.dx, -u.dy, range, TRUE);
1232 (void) unmap_invisible(x, y);
1233 if (is_pool(x, y) ^ !!u.uinwater) {
1234 /* objects normally can't be removed from water by kicking */
1236 You("splash some %s around.", hliquid("water"));
1238 You("%s
\82ð
\89ñ
\82è
\82É
\82Ü
\82«
\82¿
\82ç
\82µ
\82½
\81D", hliquid("water"));
1242 if (OBJ_AT(x, y) && (!Levitation || Is_airlevel(&u.uz)
1243 || Is_waterlevel(&u.uz) || sobj_at(BOULDER, x, y))) {
1244 if (kick_object(x, y, kickobjnam)) {
1245 if (Is_airlevel(&u.uz))
1246 hurtle(-u.dx, -u.dy, 1, TRUE); /* assume it's light */
1252 if (!IS_DOOR(maploc->typ)) {
1253 if (maploc->typ == SDOOR) {
1254 if (!Levitation && rn2(30) < avrg_attrib) {
1255 cvt_sdoor_to_door(maploc); /* ->typ = DOOR */
1257 pline("Crash! %s a secret door!",
1258 /* don't "kick open" when it's locked
1259 unless it also happens to be trapped */
1260 (maploc->doormask & (D_LOCKED | D_TRAPPED)) == D_LOCKED
1261 ? "Your kick uncovers"
1264 pline("
\83K
\83V
\83\83\83\93\81I
\82 \82È
\82½
\82Í
\94é
\96§
\82Ì
\94à
\82ð%s
\82½
\81I",
1265 (maploc->doormask & (D_LOCKED|D_TRAPPED)) == D_LOCKED
1267 : "
\8fR
\82è
\8aJ
\82¯");
1269 exercise(A_DEX, TRUE);
1270 if (maploc->doormask & D_TRAPPED) {
1271 maploc->doormask = D_NODOOR;
1273 b_trapped("door", FOOT);
1275 b_trapped("
\94à", FOOT);
1276 } else if (maploc->doormask != D_NODOOR
1277 && !(maploc->doormask & D_LOCKED))
1278 maploc->doormask = D_ISOPEN;
1279 feel_newsym(x, y); /* we know it's gone */
1280 if (maploc->doormask == D_ISOPEN
1281 || maploc->doormask == D_NODOOR)
1282 unblock_point(x, y); /* vision */
1287 if (maploc->typ == SCORR) {
1288 if (!Levitation && rn2(30) < avrg_attrib) {
1290 pline("Crash! You kick open a secret passage!");
1292 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");
1293 exercise(A_DEX, TRUE);
1295 feel_newsym(x, y); /* we know it's gone */
1296 unblock_point(x, y); /* vision */
1301 if (IS_THRONE(maploc->typ)) {
1305 if ((Luck < 0 || maploc->doormask) && !rn2(3)) {
1307 maploc->doormask = 0; /* don't leave loose ends.. */
1308 (void) mkgold((long) rnd(200), x, y);
1311 pline("CRASH! You destroy it.");
1313 pline("
\83K
\83V
\83\83\83\93\81I
\82 \82È
\82½
\82Í
\89½
\82©
\82ð
\94j
\89ó
\82µ
\82½
\81D");
1316 pline("CRASH! You destroy the throne.");
1318 pline("
\83K
\83V
\83\83\83\93\81I
\82 \82È
\82½
\82Í
\8bÊ
\8dÀ
\82ð
\94j
\89ó
\82µ
\82½
\81D");
1321 exercise(A_DEX, TRUE);
1323 } else if (Luck > 0 && !rn2(3) && !maploc->looted) {
1324 (void) mkgold((long) rn1(201, 300), x, y);
1330 rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE - 1), x, y,
1334 You("kick %s loose!", something);
1336 You("
\82È
\82É
\82©
\82ð
\8fR
\82è
\8eU
\82ç
\82µ
\82½
\81I");
1339 You("kick loose some ornamental coins and gems!");
1341 You("
\91\95\8fü
\97p
\82Ì
\8bà
\89Ý
\82â
\95ó
\90Î
\82ð
\8fR
\82è
\8eU
\82ç
\82µ
\82½
\81I");
1344 /* prevent endless milking */
1345 maploc->looted = T_LOOTED;
1347 } else if (!rn2(4)) {
1348 if (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) {
1349 fall_through(FALSE);
1356 if (IS_ALTAR(maploc->typ)) {
1360 You("kick %s.", (Blind ? something : "the altar"));
1362 You("%s
\82ð
\8fR
\82Á
\82½
\81D", (Blind ? "
\89½
\82©" : "
\8dÕ
\92d"));
1366 exercise(A_DEX, TRUE);
1369 if (IS_FOUNTAIN(maploc->typ)) {
1373 You("kick %s.", (Blind ? something : "the fountain"));
1375 You("%s
\82ð
\8fR
\82Á
\82½
\81D",(Blind ? "
\89½
\82©" : "
\90ò"));
1378 /* make metal boots rust */
1379 if (uarmf && rn2(3))
1381 if (water_damage(uarmf, "metal boots", TRUE) == ER_NOTHING) {
1383 if (water_damage(uarmf, "
\8bà
\91®
\82Ì
\8cC", TRUE) == ER_NOTHING) {
1385 Your("boots get wet.");
1387 Your("
\8cC
\82Í
\94G
\82ê
\82½
\81D");
1388 /* could cause short-lived fumbling here */
1390 exercise(A_DEX, TRUE);
1393 if (IS_GRAVE(maploc->typ)) {
1398 exercise(A_WIS, FALSE);
1399 if (Role_if(PM_ARCHEOLOGIST) || Role_if(PM_SAMURAI)
1400 || ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10))) {
1401 adjalign(-sgn(u.ualign.type));
1404 maploc->doormask = 0;
1405 (void) mksobj_at(ROCK, x, y, TRUE, FALSE);
1409 pline("Crack! %s broke!", Something);
1411 pline("
\83S
\83c
\83\93\81I
\89½
\82©
\82ª
\89ó
\82ê
\82½
\81I");
1415 pline_The("headstone topples over and breaks!");
1417 pline("
\95æ
\90Î
\82Í
\93|
\82ê
\82Ä
\89ó
\82ê
\82½
\81I");
1422 if (maploc->typ == IRONBARS)
1424 if (IS_TREE(maploc->typ)) {
1425 struct obj *treefruit;
1427 /* nothing, fruit or trouble? 75:23.5:1.5% */
1429 if (!rn2(6) && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
1431 You_hear("a low buzzing."); /* a warning */
1433 You_hear("
\82Ô
\81[
\82ñ
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D"); /* a warning */
1437 if (rn2(15) && !(maploc->looted & TREE_LOOTED)
1438 && (treefruit = rnd_treefruit_at(x, y))) {
1439 long nfruit = 8L - rnl(7), nfall;
1440 short frtype = treefruit->otyp;
1442 treefruit->quan = nfruit;
1443 treefruit->owt = weight(treefruit);
1444 if (is_plural(treefruit))
1446 pline("Some %s fall from the tree!", xname(treefruit));
1448 pline("%s
\82ª
\89½
\8cÂ
\82©
\96Ø
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I", xname(treefruit));
1451 pline("%s falls from the tree!", An(xname(treefruit)));
1453 pline("%s
\82ª
\96Ø
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I", xname(treefruit));
1454 nfall = scatter(x, y, 2, MAY_HIT, treefruit);
1455 if (nfall != nfruit) {
1456 /* scatter left some in the tree, but treefruit
1457 * may not refer to the correct object */
1458 treefruit = mksobj(frtype, TRUE, FALSE);
1459 treefruit->quan = nfruit - nfall;
1461 pline("%ld %s got caught in the branches.",
1462 nfruit - nfall, xname(treefruit));
1464 pline("%ld
\8cÂ
\82Ì%s
\82ª
\8e}
\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½
\81D",
1465 nfruit - nfall, xname(treefruit));
1467 dealloc_obj(treefruit);
1469 exercise(A_DEX, TRUE);
1470 exercise(A_WIS, TRUE); /* discovered a new food source! */
1472 maploc->looted |= TREE_LOOTED;
1474 } else if (!(maploc->looted & TREE_SWARM)) {
1475 int cnt = rnl(4) + 2;
1482 if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE])
1483 && makemon(&mons[PM_KILLER_BEE], mm.x, mm.y,
1489 pline("You've attracted the tree's former occupants!");
1491 pline("
\96Ø
\82Ì
\90æ
\8fZ
\96¯
\82ð
\8bN
\82±
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1494 You("smell stale honey.");
1496 pline("
\8cÃ
\82¢
\82Í
\82¿
\82Ý
\82Â
\82Ì
\82É
\82¨
\82¢
\82ª
\82µ
\82½
\81D");
1497 maploc->looted |= TREE_SWARM;
1502 if (IS_SINK(maploc->typ)) {
1503 int gend = poly_gender();
1504 short washerndx = (gend == 1 || (gend == 2 && rn2(2)))
1513 pline("Klunk! The pipes vibrate noisily.");
1515 pline("
\83K
\83\89\83\93\81I
\83p
\83C
\83v
\82Í
\82¤
\82é
\82³
\82
\90U
\93®
\82µ
\82½
\81D");
1520 pline("
\83K
\83\89\83\93\81I");
1521 exercise(A_DEX, TRUE);
1523 } else if (!(maploc->looted & S_LPUDDING) && !rn2(3)
1524 && !(mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) {
1527 You_hear("a gushing sound.");
1529 You_hear("
\82È
\82É
\82©
\82ª
\95¬
\8fo
\82·
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1532 pline("A %s ooze gushes up from the drain!",
1534 pline("%s
\89t
\91Ì
\82ª
\94r
\90\85\8cû
\82©
\82ç
\82É
\82¶
\82Ý
\8fo
\82½
\81I",
1536 (void) makemon(&mons[PM_BLACK_PUDDING], x, y, NO_MM_FLAGS);
1537 exercise(A_DEX, TRUE);
1539 maploc->looted |= S_LPUDDING;
1541 } else if (!(maploc->looted & S_LDWASHER) && !rn2(3)
1542 && !(mvitals[washerndx].mvflags & G_GONE)) {
1543 /* can't resist... */
1545 pline("%s returns!", (Blind ? Something : "The dish washer"));
1547 pline("%s
\82ª
\96ß
\82Á
\82Ä
\82«
\82½
\81I", (Blind ? "
\89½
\82©" : "
\8eM
\90ô
\82¢"));
1548 if (makemon(&mons[washerndx], x, y, NO_MM_FLAGS))
1550 maploc->looted |= S_LDWASHER;
1551 exercise(A_DEX, TRUE);
1553 } else if (!rn2(3)) {
1556 (Blind ? "You hear a sloshing sound"
1557 : "Muddy waste pops up from the drain"));
1559 pline("
\82¤
\82í
\81I%s
\81D",
1560 (Blind ? "
\82 \82È
\82½
\82Í
\81C
\83o
\83`
\83\83\83o
\83`
\83\83\82·
\82é
\89¹
\82ð
\95·
\82¢
\82½"
1561 : "
\94r
\90\85\8cû
\82©
\82ç
\82Ç
\82ë
\82Ç
\82ë
\82Ì
\94p
\8aü
\95¨
\82ª
\8fo
\82Ä
\82
\82é"));
1563 if (!(maploc->looted & S_LRING)) { /* once per sink */
1566 You_see("a ring shining in its midst.");
1568 You("
\82»
\82Ì
\92\86\82É
\8cõ
\82é
\8ew
\97Ö
\82ð
\8c©
\82Â
\82¯
\82½
\81D");
1569 (void) mkobj_at(RING_CLASS, x, y, TRUE);
1571 exercise(A_DEX, TRUE);
1572 exercise(A_WIS, TRUE); /* a discovery! */
1573 maploc->looted |= S_LRING;
1579 if (maploc->typ == STAIRS || maploc->typ == LADDER
1580 || IS_STWALL(maploc->typ)) {
1581 if (!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN)
1585 pline("Ouch! That hurts!");
1587 pline("
\82¢
\82Ä
\82Á
\81I
\89ö
\89ä
\82µ
\82½
\81I");
1588 exercise(A_DEX, FALSE);
1589 exercise(A_STR, FALSE);
1592 feel_location(x, y); /* we know we hit it */
1593 if (is_drawbridge_wall(x, y) >= 0) {
1595 pline_The("drawbridge is unaffected.");
1597 pline("
\92µ
\82Ë
\8b´
\82Í
\82Ñ
\82
\82Æ
\82à
\82µ
\82È
\82¢
\81D");
1598 /* update maploc to refer to the drawbridge */
1599 (void) find_drawbridge(&x, &y);
1600 maploc = &levl[x][y];
1604 set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
1605 dmg = rnd(ACURR(A_CON) > 15 ? 3 : 5);
1606 losehp(Maybe_Half_Phys(dmg), kickstr(buf, kickobjnam), KILLED_BY);
1607 if (Is_airlevel(&u.uz) || Levitation)
1608 hurtle(-u.dx, -u.dy, rn1(2, 4), TRUE); /* assume it's heavy */
1614 if (maploc->doormask == D_ISOPEN || maploc->doormask == D_BROKEN
1615 || maploc->doormask == D_NODOOR) {
1617 exercise(A_DEX, FALSE);
1618 if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
1620 You("kick at empty space.");
1622 You("
\89½
\82à
\82È
\82¢
\8bó
\8aÔ
\82ð
\8fR
\82Á
\82½
\81D");
1624 feel_location(x, y);
1627 pline("Dumb move! You strain a muscle.");
1629 pline("
\82Î
\82©
\82°
\82½
\93®
\82«
\82¾
\81I
\8bØ
\93÷
\82ð
\92É
\82ß
\82½
\81D");
1630 exercise(A_STR, FALSE);
1631 set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
1633 if ((Is_airlevel(&u.uz) || Levitation) && rn2(2))
1634 hurtle(-u.dx, -u.dy, 1, TRUE);
1635 return 1; /* uses a turn */
1638 /* not enough leverage to kick open doors while levitating */
1642 exercise(A_DEX, TRUE);
1643 /* door is known to be CLOSED or LOCKED */
1644 if (rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) {
1645 boolean shopdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE;
1646 /* break the door */
1647 if (maploc->doormask & D_TRAPPED) {
1650 You("kick the door.");
1652 You("
\94à
\82ð
\8fR
\82Á
\82½
\81D");
1653 exercise(A_STR, FALSE);
1654 maploc->doormask = D_NODOOR;
1656 b_trapped("door", FOOT);
1658 b_trapped("
\94à", FOOT);
1659 } else if (ACURR(A_STR) > 18 && !rn2(5) && !shopdoor) {
1661 pline("As you kick the door, it shatters to pieces!");
1663 pline("
\94à
\82ð
\8fR
\82é
\82Æ
\81C
\82±
\82È
\82²
\82È
\82É
\82
\82¾
\82¯
\82½
\81I");
1664 exercise(A_STR, TRUE);
1665 maploc->doormask = D_NODOOR;
1668 pline("As you kick the door, it crashes open!");
1670 pline("
\94à
\82ð
\8fR
\82é
\82Æ
\81C
\89ó
\82ê
\82Ä
\8aJ
\82¢
\82½
\81I");
1671 exercise(A_STR, TRUE);
1672 maploc->doormask = D_BROKEN;
1674 feel_newsym(x, y); /* we know we broke it */
1675 unblock_point(x, y); /* vision */
1677 add_damage(x, y, SHOP_DOOR_COST);
1679 pay_for_damage("break", FALSE);
1681 pay_for_damage("
\94j
\89ó
\82·
\82é", FALSE);
1684 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1685 if (DEADMONSTER(mtmp))
1687 if (is_watch(mtmp->data) && couldsee(mtmp->mx, mtmp->my)
1688 && mtmp->mpeaceful) {
1690 mon_yells(mtmp, "Halt, thief! You're under arrest!");
1692 mon_yells(mtmp, "
\8e~
\82Ü
\82ê
\93D
\96_
\81I
\82¨
\82Ü
\82¦
\82ð
\91ß
\95ß
\82·
\82é
\81I");
1693 (void) angry_guards(FALSE);
1699 feel_location(x, y); /* we know we hit it */
1700 exercise(A_STR, TRUE);
1704 pline("
\82®
\82\9f\82\9f\82\9f\82ñ
\81I");
1706 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1707 if (DEADMONSTER(mtmp))
1709 if (is_watch(mtmp->data) && mtmp->mpeaceful
1710 && couldsee(mtmp->mx, mtmp->my)) {
1711 if (levl[x][y].looted & D_WARNED) {
1714 "Halt, vandal! You're under arrest!");
1716 "
\8e~
\82Ü
\82ê
\96ì
\94Ø
\90l
\81I
\82¨
\82Ü
\82¦
\82ð
\91ß
\95ß
\82·
\82é
\81I");
1717 (void) angry_guards(FALSE);
1720 mon_yells(mtmp, "Hey, stop damaging that door!");
1722 mon_yells(mtmp, "
\82¨
\82¢
\81C
\94à
\82ð
\94j
\89ó
\82·
\82é
\82Ì
\82ð
\82â
\82ß
\82ë
\81I");
1723 levl[x][y].looted |= D_WARNED;
1737 /* cover all the MIGR_xxx choices generated by down_gate() */
1739 case MIGR_RANDOM: /* trap door or hole */
1740 if (Is_stronghold(&u.uz)) {
1741 cc->x = valley_level.dnum;
1742 cc->y = valley_level.dlevel;
1744 } else if (In_endgame(&u.uz) || Is_botlevel(&u.uz)) {
1749 case MIGR_STAIRS_UP:
1750 case MIGR_LADDER_UP:
1752 cc->y = u.uz.dlevel + 1;
1755 cc->x = sstairs.tolev.dnum;
1756 cc->y = sstairs.tolev.dlevel;
1760 /* y==0 means "nowhere", in which case x doesn't matter */
1766 /* player or missile impacts location, causing objects to fall down */
1768 impact_drop(missile, x, y, dlev)
1769 struct obj *missile; /* caused impact, won't drop itself */
1770 xchar x, y; /* location affected */
1771 xchar dlev; /* if !0 send to dlev near player */
1774 register struct obj *obj, *obj2;
1775 register struct monst *shkp;
1776 long oct, dct, price, debit, robbed;
1777 boolean angry, costly, isrock;
1783 toloc = down_gate(x, y);
1784 drop_to(&cc, toloc);
1789 /* send objects next to player falling through trap door.
1790 * checked in obj_delivery().
1792 toloc = MIGR_WITH_HERO;
1796 costly = costly_spot(x, y);
1797 price = debit = robbed = 0L;
1799 shkp = (struct monst *) 0;
1800 /* if 'costly', we must keep a record of ESHK(shkp) before
1801 * it undergoes changes through the calls to stolen_value.
1802 * the angry bit must be reset, if needed, in this fn, since
1803 * stolen_value is called under the 'silent' flag to avoid
1804 * unsavory pline repetitions.
1807 if ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0) {
1808 debit = ESHK(shkp)->debit;
1809 robbed = ESHK(shkp)->robbed;
1810 angry = !shkp->mpeaceful;
1814 isrock = (missile && missile->otyp == ROCK);
1816 for (obj = level.objects[x][y]; obj; obj = obj2) {
1817 obj2 = obj->nexthere;
1820 /* number of objects in the pile */
1822 if (obj == uball || obj == uchain)
1824 /* boulders can fall too, but rarely & never due to rocks */
1825 if ((isrock && obj->otyp == BOULDER)
1826 || rn2(obj->otyp == BOULDER ? 30 : 3))
1828 obj_extract_self(obj);
1831 price += stolen_value(
1832 obj, x, y, (costly_spot(u.ux, u.uy)
1833 && index(u.urooms, *in_rooms(x, y, SHOPBASE))),
1835 /* set obj->no_charge to 0 */
1836 if (Has_contents(obj))
1837 picked_container(obj); /* does the right thing */
1838 if (obj->oclass != COIN_CLASS)
1842 add_to_migration(obj);
1845 obj->owornmask = (long) toloc;
1847 /* number of fallen objects */
1851 if (dct && cansee(x, y)) { /* at least one object fell */
1853 const char *what = (dct == 1L ? "object falls" : "objects fall");
1855 const char *what = "
\95¨";
1859 pline("From the impact, %sother %s.",
1860 dct == oct ? "the " : dct == 1L ? "an" : "", what);
1862 pline("
\8fÕ
\8c\82\82Å
\81C
\91¼
\82Ì%s
\82ª
\97\8e\82¿
\82½
\81D",what);
1864 else if (oct == dct)
1866 pline("%s adjacent %s %s.", dct == 1L ? "The" : "All the", what,
1869 pline("
\8bß
\82
\82É
\82 \82Á
\82½%s
\82ª%s
\97\8e\82¿
\82½
\81D", what, gate_str);
1873 pline("%s adjacent %s %s.",
1874 dct == 1L ? "One of the" : "Some of the",
1875 dct == 1L ? "objects falls" : what, gate_str);
1877 pline("
\8bß
\82
\82É
\82 \82Á
\82½%s%s%s
\97\8e\82¿
\82½
\81D",
1879 dct == 1L ? "
\82ª" : "
\82Ì
\82¢
\82
\82Â
\82©
\82ª",
1884 if (costly && shkp && price) {
1885 if (ESHK(shkp)->robbed > robbed) {
1887 You("removed %ld %s worth of goods!", price, currency(price));
1889 You("%ld%s
\95ª
\82Ì
\95i
\95¨
\82ð
\8eæ
\82è
\82³
\82Á
\82½
\81I", price, currency(price));
1890 if (cansee(shkp->mx, shkp->my)) {
1891 if (ESHK(shkp)->customer[0] == 0)
1892 (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
1895 pline("%s is infuriated!", Monnam(shkp));
1897 pline("%s
\82Í
\8c\83\93{
\82µ
\82½
\81I", Monnam(shkp));
1900 pline("\"%s, you are a thief!\"", plname);
1902 pline("
\81u%s
\82ß
\81C
\82¨
\82Ü
\82¦
\82Í
\93D
\96_
\82¾
\82È
\81I
\81v", plname);
1905 You_hear("a scream, \"Thief!\"");
1907 You_hear("
\8bà
\90Ø
\82è
\90º
\82ð
\95·
\82¢
\82½
\81u
\93D
\96_
\81I
\81v");
1909 (void) angry_guards(FALSE);
1912 if (ESHK(shkp)->debit > debit) {
1913 long amt = (ESHK(shkp)->debit - debit);
1915 You("owe %s %ld %s for goods lost.", Monnam(shkp), amt,
1918 You("
\95i
\95¨
\8fÁ
\8e¸
\82Ì
\82½
\82ß%s
\82É%ld%s
\82Ì
\8eØ
\82è
\82ð
\82Â
\82
\82Á
\82½
\81D", Monnam(shkp), amt,
1925 /* NOTE: ship_object assumes otmp was FREED from fobj or invent.
1926 * <x,y> is the point of drop. otmp is _not_ an <x,y> resident:
1927 * otmp is either a kicked, dropped, or thrown object.
1930 ship_object(otmp, x, y, shop_floor_obj)
1933 boolean shop_floor_obj;
1940 boolean nodrop, unpaid, container, impact = FALSE;
1945 if ((toloc = down_gate(x, y)) == MIGR_NOWHERE)
1947 drop_to(&cc, toloc);
1951 /* objects other than attached iron ball always fall down ladder,
1952 but have a chance of staying otherwise */
1953 nodrop = (otmp == uball) || (otmp == uchain)
1954 || (toloc != MIGR_LADDER_UP && rn2(3));
1956 container = Has_contents(otmp);
1957 unpaid = is_unpaid(otmp);
1960 for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
1966 /* boulders never fall through trap doors, but they might knock
1967 other things down before plugging the hole */
1968 if (otmp->otyp == BOULDER && ((t = t_at(x, y)) != 0)
1969 && (t->ttyp == TRAPDOOR || t->ttyp == HOLE)) {
1971 impact_drop(otmp, x, y, 0);
1972 return FALSE; /* let caller finish the drop */
1976 otransit_msg(otmp, nodrop, n);
1980 impact_drop(otmp, x, y, 0);
1984 if (unpaid || shop_floor_obj) {
1986 (void) stolen_value(otmp, u.ux, u.uy, TRUE, FALSE);
1990 (void) stolen_value(
1992 (costly_spot(u.ux, u.uy)
1993 && index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),
1996 /* set otmp->no_charge to 0 */
1998 picked_container(otmp); /* happens to do the right thing */
1999 if (otmp->oclass != COIN_CLASS)
2000 otmp->no_charge = 0;
2003 if (otmp->owornmask)
2004 remove_worn_item(otmp, TRUE);
2006 /* some things break rather than ship */
2007 if (breaktest(otmp)) {
2010 if (objects[otmp->otyp].oc_material == GLASS
2011 || otmp->otyp == EXPENSIVE_CAMERA) {
2012 if (otmp->otyp == MIRROR)
2017 result = "
\83O
\83V
\83\83\83b";
2019 /* penalty for breaking eggs laid by you */
2020 if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM)
2021 change_luck((schar) -min(otmp->quan, 5L));
2025 result = "
\83x
\83`
\83\83\83b";
2028 You_hear("a muffled %s.", result);
2030 You_hear("
\82±
\82à
\82Á
\82½%s
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D", result);
2031 obj_extract_self(otmp);
2032 obfree(otmp, (struct obj *) 0);
2036 add_to_migration(otmp);
2039 otmp->owornmask = (long) toloc;
2040 /* boulder from rolling boulder trap, no longer part of the trap */
2041 if (otmp->otyp == BOULDER)
2045 /* the objs impacted may be in a shop other than
2046 * the one in which the hero is located. another
2047 * check for a shk is made in impact_drop. it is, e.g.,
2048 * possible to kick/throw an object belonging to one
2049 * shop into another shop through a gap in the wall,
2050 * and cause objects belonging to the other shop to
2051 * fall down a trap door--thereby getting two shopkeepers
2052 * angry at the hero in one shot.
2054 impact_drop(otmp, x, y, 0);
2061 obj_delivery(near_hero)
2064 register struct obj *otmp, *otmp2;
2065 register int nx, ny;
2067 boolean nobreak, noscatter;
2069 for (otmp = migrating_objs; otmp; otmp = otmp2) {
2071 if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel)
2074 where = (int) (otmp->owornmask & 0x7fffL); /* destination code */
2075 nobreak = (where & MIGR_NOBREAK) != 0;
2076 noscatter = (where & MIGR_WITH_HERO) != 0;
2077 where &= ~(MIGR_NOBREAK | MIGR_NOSCATTER);
2079 if (!near_hero ^ (where == MIGR_WITH_HERO))
2082 obj_extract_self(otmp);
2083 otmp->owornmask = 0L;
2086 case MIGR_STAIRS_UP:
2087 nx = xupstair, ny = yupstair;
2089 case MIGR_LADDER_UP:
2090 nx = xupladder, ny = yupladder;
2093 nx = sstairs.sx, ny = sstairs.sy;
2095 case MIGR_WITH_HERO:
2096 nx = u.ux, ny = u.uy;
2104 place_object(otmp, nx, ny);
2105 if (!nobreak && !IS_SOFT(levl[nx][ny].typ)) {
2106 if (where == MIGR_WITH_HERO) {
2107 if (breaks(otmp, nx, ny))
2109 } else if (breaktest(otmp)) {
2110 /* assume it broke before player arrived, no messages */
2117 (void) scatter(nx, ny, rnd(2), 0, otmp);
2118 } else { /* random location */
2119 /* set dummy coordinates because there's no
2120 current position for rloco() to update */
2121 otmp->ox = otmp->oy = 0;
2122 if (rloco(otmp) && !nobreak && breaktest(otmp)) {
2123 /* assume it broke before player arrived, no messages */
2131 otransit_msg(otmp, nodrop, num)
2132 register struct obj *otmp;
2133 register boolean nodrop;
2139 Sprintf(obuf, "%s%s",
2140 (otmp->otyp == CORPSE && type_is_pname(&mons[otmp->corpsenm]))
2145 Sprintf(obuf, "%s
\82Í", xname(otmp));
2148 if (num) { /* means: other objects are impacted */
2150 Sprintf(eos(obuf), " %s %s object%s", otense(otmp, "hit"),
2151 num == 1L ? "another" : "other", num > 1L ? "s" : "");
2153 Sprintf(eos(obuf), ".");
2155 Sprintf(eos(obuf), " and %s %s.", otense(otmp, "fall"), gate_str);
2157 Sprintf(eos(obuf), "
\91¼
\82Ì
\95¨
\91Ì
\82É
\96½
\92\86\82µ
\82Ä");
2159 Sprintf(eos(obuf), "
\8e~
\82Ü
\82Á
\82½
\81D");
2161 Sprintf(eos(obuf), "%s
\97\8e\82¿
\82½
\81D", gate_str);
2166 pline("%s %s %s.", obuf, otense(otmp, "fall"), gate_str);
2168 pline("%s%s
\97\8e\82¿
\82½
\81D", obuf, gate_str);
2171 /* migration destination for objects which fall down to next level */
2179 /* this matches the player restriction in goto_level() */
2180 if (on_level(&u.uz, &qstart_level) && !ok_to_quest())
2181 return MIGR_NOWHERE;
2183 if ((xdnstair == x && ydnstair == y)
2184 || (sstairs.sx == x && sstairs.sy == y && !sstairs.up)) {
2186 gate_str = "down the stairs";
2188 gate_str = "
\8aK
\92i
\82©
\82ç";
2189 return (xdnstair == x && ydnstair == y) ? MIGR_STAIRS_UP
2192 if (xdnladder == x && ydnladder == y) {
2194 gate_str = "down the ladder";
2196 gate_str = "
\82Í
\82µ
\82²
\82©
\82ç";
2197 return MIGR_LADDER_UP;
2200 if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen)
2201 && (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)) {
2203 gate_str = (ttmp->ttyp == TRAPDOOR) ? "through the trap door"
2204 : "through the hole";
2206 gate_str = (ttmp->ttyp == TRAPDOOR) ? "
\97\8e\82µ
\94à
\82É"
2211 return MIGR_NOWHERE;