OSDN Git Service

de71b5f371d572384ca531e54ee2fce38098de3f
[jnethack/source.git] / src / dokick.c
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. */
4
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. */
9
10 #include "hack.h"
11
12 #define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH])
13 #define martial()                                 \
14     (martial_bonus() || is_bigfoot(youmonst.data) \
15      || (uarmf && uarmf->otyp == KICKING_BOOTS))
16
17 static NEARDATA struct rm *maploc, nowhere;
18 static NEARDATA const char *gate_str;
19
20 /* kickedobj (decl.c) tracks a kicked object until placed or destroyed */
21
22 extern boolean notonhead; /* for long worms */
23
24 STATIC_DCL void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
25 STATIC_DCL boolean FDECL(maybe_kick_monster, (struct monst *,
26                                               XCHAR_P, XCHAR_P));
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));
33
34 /*JP
35 static const char kick_passes_thru[] = "kick passes harmlessly through";
36 */
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½";
38
39 STATIC_OVL void
40 kickdmg(mon, clumsy)
41 register struct monst *mon;
42 register boolean clumsy;
43 {
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;
49
50     if (uarmf && uarmf->otyp == KICKING_BOOTS)
51         dmg += 5;
52
53     /* excessive wt affects dex, so it affects dmg */
54     if (clumsy)
55         dmg /= 2;
56
57     /* kicking a dragon or an elephant will not harm it */
58     if (thick_skinned(mon->data))
59         dmg = 0;
60
61     /* attacking a shade is useless */
62     if (mon->data == &mons[PM_SHADE])
63         dmg = 0;
64
65     if ((is_undead(mon->data) || is_demon(mon->data) || is_vampshifter(mon))
66         && uarmf && uarmf->blessed)
67         blessed_foot_damage = 1;
68
69     if (mon->data == &mons[PM_SHADE] && !blessed_foot_damage) {
70 /*JP
71         pline_The("%s.", kick_passes_thru);
72 */
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 */
76         return;
77     }
78
79     if (mon->m_ap_type)
80         seemimic(mon);
81
82     check_caitiff(mon);
83
84     /* squeeze some guilt feelings... */
85     if (mon->mtame) {
86         abuse_dog(mon);
87         if (mon->mtame)
88             monflee(mon, (dmg ? rnd(dmg) : 1), FALSE, FALSE);
89         else
90             mon->mflee = 0;
91     }
92
93     if (dmg > 0) {
94         /* convert potential damage to actual damage */
95         dmg = rnd(dmg);
96         if (martial()) {
97             if (dmg > 1)
98                 kick_skill = P_MARTIAL_ARTS;
99             dmg += rn2(ACURR(A_DEX) / 2 + 1);
100         }
101         /* a good kick exercises your dex */
102         exercise(A_DEX, TRUE);
103     }
104     if (blessed_foot_damage)
105         dmg += rnd(4);
106     if (uarmf)
107         dmg += uarmf->spe;
108     dmg += u.udaminc; /* add ring(s) of increase damage */
109     if (dmg > 0)
110         mon->mhp -= dmg;
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)) {
117 /*JP
118             pline("%s reels from the blow.", Monnam(mon));
119 */
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);
126                 set_apparxy(mon);
127                 if (mintrap(mon) == 2)
128                     trapkilled = TRUE;
129             }
130         }
131     }
132
133     (void) passive(mon, TRUE, mon->mhp > 0, AT_KICK, FALSE);
134     if (mon->mhp <= 0 && !trapkilled)
135         killed(mon);
136
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);
140 }
141
142 STATIC_OVL boolean
143 maybe_kick_monster(mon, x, y)
144 struct monst *mon;
145 xchar x, y;
146 {
147     if (mon) {
148         boolean save_forcefight = context.forcefight;
149
150         bhitpos.x = x;
151         bhitpos.y = y;
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;
160     }
161     return (boolean) (mon != 0);
162 }
163
164 STATIC_OVL void
165 kick_monster(mon, x, y)
166 struct monst *mon;
167 xchar x, y;
168 {
169     boolean clumsy = FALSE;
170     int i, j;
171
172     /* anger target even if wild miss will occur */
173     setmangry(mon);
174
175     if (Levitation && !rn2(3) && verysmall(mon->data)
176         && !is_flyer(mon->data)) {
177 /*JP
178         pline("Floating in the air, you miss wildly!");
179 */
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);
183         return;
184     }
185
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) */
188     if (mon->mundetected
189         || (mon->m_ap_type && mon->m_ap_type != M_AP_MONSTER)) {
190         if (mon->m_ap_type)
191             seemimic(mon);
192         mon->mundetected = 0;
193         if (!canspotmon(mon))
194             map_invisible(x, y);
195         else
196             newsym(x, y);
197         There("is %s here.",
198               canspotmon(mon) ? a_monnam(mon) : "something hidden");
199     }
200
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.
206      */
207     if (Upolyd && attacktype(youmonst.data, AT_KICK)) {
208         struct attack *uattk;
209         int sum, kickdieroll, armorpenalty,
210             attknum = 0,
211             tmp = find_roll_to_hit(mon, AT_KICK, (struct obj *) 0, &attknum,
212                                    &armorpenalty);
213
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) */
217             if (multi < 0)
218                 break;
219
220             uattk = &youmonst.data->mattk[i];
221             /* we only care about kicking attacks here */
222             if (uattk->aatyp != AT_KICK)
223                 continue;
224
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 */
228 /*JP
229                 Your("%s %s.", kick_passes_thru, mon_nam(mon));
230 */
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))) {
234 /*JP
235                 You("kick %s.", mon_nam(mon));
236 */
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,
240                                FALSE);
241                 if (sum == 2)
242                     break; /* Defender died */
243             } else {
244                 missum(mon, uattk, (tmp + armorpenalty > kickdieroll));
245                 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
246             }
247         }
248         return;
249     }
250
251     i = -inv_weight();
252     j = weight_cap();
253
254     if (i < (j * 3) / 10) {
255         if (!rn2((i < j / 10) ? 2 : (i < j / 5) ? 3 : 4)) {
256             if (martial() && !rn2(2))
257                 goto doit;
258 /*JP
259             Your("clumsy kick does no damage.");
260 */
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);
263             return;
264         }
265         if (i < j / 10)
266             clumsy = TRUE;
267         else if (!rn2((i < j / 5) ? 2 : 3))
268             clumsy = TRUE;
269     }
270
271     if (Fumbling)
272         clumsy = TRUE;
273
274     else if (uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
275         clumsy = TRUE;
276 doit:
277 /*JP
278     You("kick %s.", mon_nam(mon));
279 */
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)) {
287 #if 0 /*JP:T*/
288             pline("%s blocks your %skick.", Monnam(mon),
289                   clumsy ? "clumsy " : "");
290 #else
291             pline("%s\82Í\82 \82È\82½\82Ì%s\8fR\82è\82ð\96h\82¢\82¾\81D", Monnam(mon),
292                   clumsy ? "\95s\8aí\97p\82È" : "");
293 #endif
294             (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
295             return;
296         } else {
297             maybe_mnexto(mon);
298             if (mon->mx != x || mon->my != y) {
299                 if (glyph_is_invisible(levl[x][y].glyph)) {
300                     unmap_object(x, y);
301                     newsym(x, y);
302                 }
303 #if 0 /*JP*/
304                 pline("%s %s, %s evading your %skick.", Monnam(mon),
305                       (!level.flags.noteleport && can_teleport(mon->data))
306                           ? "teleports"
307                           : is_floater(mon->data)
308                                 ? "floats"
309                                 : is_flyer(mon->data) ? "swoops"
310                                                       : (nolimbs(mon->data)
311                                                          || slithy(mon->data))
312                                                             ? "slides"
313                                                             : "jumps",
314                       clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : "");
315 #else
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è"
324                                                             : "\92µ\82Ë",
325                       clumsy ? "\8ay\81X\82Æ" : "\91f\91\81\82­", clumsy ? "\95s\8aí\97p\82È" : "");
326 #endif
327                 (void) passive(mon, FALSE, 1, AT_KICK, FALSE);
328                 return;
329             }
330         }
331     }
332     kickdmg(mon, clumsy);
333 }
334
335 /*
336  *  Return TRUE if caught (the gold taken care of), FALSE otherwise.
337  *  The gold object is *not* attached to the fobj chain!
338  */
339 boolean
340 ghitm(mtmp, gold)
341 register struct monst *mtmp;
342 register struct obj *gold;
343 {
344     boolean msg_given = FALSE;
345
346     if (!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest
347         && !mtmp->isgd && !is_mercenary(mtmp->data)) {
348         wakeup(mtmp);
349     } else if (!mtmp->mcanmove) {
350         /* too light to do real damage */
351         if (canseemon(mtmp)) {
352 #if 0 /*JP:T*/
353             pline_The("%s harmlessly %s %s.", xname(gold),
354                       otense(gold, "hit"), mon_nam(mtmp));
355 #else
356             pline("%s\82Í%s\82É\96½\92\86\82µ\82½\81D", xname(gold),
357                   mon_nam(mtmp));
358 #endif
359             msg_given = TRUE;
360         }
361     } else {
362         long umoney, value = gold->quan * objects[gold->otyp].oc_cost;
363
364         mtmp->msleeping = 0;
365         finish_meating(mtmp);
366         if (!mtmp->isgd && !rn2(4)) /* not always pleasing */
367             setmangry(mtmp);
368         /* greedy monsters catch gold */
369         if (cansee(mtmp->mx, mtmp->my))
370 /*JP
371             pline("%s catches the gold.", Monnam(mtmp));
372 */
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 */
376         if (mtmp->isshk) {
377             long robbed = ESHK(mtmp)->robbed;
378
379             if (robbed) {
380                 robbed -= value;
381                 if (robbed < 0L)
382                     robbed = 0L;
383 #if 0 /*JP*/
384                 pline_The("amount %scovers %s recent losses.",
385                           !robbed ? "" : "partially ", mhis(mtmp));
386 #else
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));
389 #endif
390                 ESHK(mtmp)->robbed = robbed;
391                 if (!robbed)
392                     make_happy_shk(mtmp, FALSE);
393             } else {
394                 if (mtmp->mpeaceful) {
395                     ESHK(mtmp)->credit += value;
396 #if 0 /*JP*/
397                     You("have %ld %s in credit.", ESHK(mtmp)->credit,
398                         currency(ESHK(mtmp)->credit));
399 #else
400                     You("%ld%s\82ð\91Ý\82µ\82É\82µ\82½\81D", ESHK(mtmp)->credit,
401                         currency(ESHK(mtmp)->credit));
402 #endif
403                 } else
404 /*JP
405                     verbalize("Thanks, scum!");
406 */
407                     verbalize("\82 \82è\82ª\82Æ\82æ\81I\82­\82»\82Á\82½\82ê\81I");
408             }
409         } else if (mtmp->ispriest) {
410             if (mtmp->mpeaceful)
411 /*JP
412                 verbalize("Thank you for your contribution.");
413 */
414                 verbalize("\8añ\95t\82É\8a´\8eÓ\82µ\82Ü\82·\81D");
415             else
416 /*JP
417                 verbalize("Thanks, scum!");
418 */
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. */
427             verbalize(
428                 umoney
429                     ? "Drop the rest and follow me."
430                     : hidden_gold()
431                           ? "You still have hidden gold.  Drop it now."
432                           : mtmp->mpeaceful
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)) {
436             long goldreqd = 0L;
437
438             if (rn2(3)) {
439                 if (mtmp->data == &mons[PM_SOLDIER])
440                     goldreqd = 100L;
441                 else if (mtmp->data == &mons[PM_SERGEANT])
442                     goldreqd = 250L;
443                 else if (mtmp->data == &mons[PM_LIEUTENANT])
444                     goldreqd = 500L;
445                 else if (mtmp->data == &mons[PM_CAPTAIN])
446                     goldreqd = 750L;
447
448                 if (goldreqd) {
449                     umoney = money_cnt(invent);
450                     if (value
451                         > goldreqd
452                               + (umoney + u.ulevel * rn2(5)) / ACURR(A_CHA))
453                         mtmp->mpeaceful = TRUE;
454                 }
455             }
456             if (mtmp->mpeaceful)
457 /*JP
458                 verbalize("That should do.  Now beat it!");
459 */
460                 verbalize("\82È\82ñ\82¾\82¢\81H\82±\82ê\82Í\81H");
461             else
462 /*JP
463                 verbalize("That's not enough, coward!");
464 */
465                 verbalize("\82»\82ñ\82È\82à\82Ì\82Å\8dÏ\82Þ\82©\81C\94Ú\8b¯\8eÒ\81I");
466         }
467         return TRUE;
468     }
469
470     if (!msg_given)
471         miss(xname(gold), mtmp);
472     return FALSE;
473 }
474
475 /* container is kicked, dropped, thrown or otherwise impacted by player.
476  * Assumes container is on floor.  Checks contents for possible damage. */
477 void
478 container_impact_dmg(obj, x, y)
479 struct obj *obj;
480 xchar x, y; /* coordinates where object was before the impact, not after */
481 {
482     struct monst *shkp;
483     struct obj *otmp, *otmp2;
484     long loss = 0L;
485     boolean costly, insider, frominv;
486
487     /* only consider normal containers */
488     if (!Is_container(obj) || !Has_contents(obj) || Is_mbag(obj))
489         return;
490
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);
497
498     for (otmp = obj->cobj; otmp; otmp = otmp2) {
499         const char *result = (char *) 0;
500
501         otmp2 = otmp->nobj;
502         if (objects[otmp->otyp].oc_material == GLASS
503             && otmp->oclass != GEM_CLASS && !obj_resists(otmp, 33, 100)) {
504 /*JP
505             result = "shatter";
506 */
507             result = "\83K\83`\83\83\83\93";
508         } else if (otmp->otyp == EGG && !rn2(3)) {
509 /*JP
510             result = "cracking";
511 */
512             result = "\83O\83V\83\83\83b";
513         }
514         if (result) {
515             if (otmp->otyp == MIRROR)
516                 change_luck(-2);
517
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)
521                 change_luck(-1);
522 /*JP
523             You_hear("a muffled %s.", result);
524 */
525             You_hear("\82±\82à\82Á\82½%s\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D", result);
526             if (costly) {
527                 if (frominv && !otmp->unpaid)
528                     otmp->no_charge = 1;
529                 loss +=
530                     stolen_value(otmp, x, y, (boolean) shkp->mpeaceful, TRUE);
531             }
532             if (otmp->quan > 1L) {
533                 useup(otmp);
534             } else {
535                 obj_extract_self(otmp);
536                 obfree(otmp, (struct obj *) 0);
537             }
538             /* contents of this container are no longer known */
539             obj->cknown = 0;
540         }
541     }
542     if (costly && loss) {
543         if (!insider) {
544 /*JP
545             You("caused %ld %s worth of damage!", loss, currency(loss));
546 */
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);
549         } else {
550 #if 0 /*JP*/
551             You("owe %s %ld %s for objects destroyed.", mon_nam(shkp), loss,
552                 currency(loss));
553 #else
554             You("\8aí\95¨\94j\91¹\82Å%s\82É%ld%s\82Ì\8eØ\82è\82ð\82Â\82­\82Á\82½\81D", mon_nam(shkp), loss,
555                 currency(loss));
556 #endif
557         }
558     }
559 }
560
561 /* jacket around really_kick_object */
562 STATIC_OVL int
563 kick_object(x, y)
564 xchar x, y;
565 {
566     int res = 0;
567
568     /* if a pile, the "top" object gets kicked */
569     kickedobj = level.objects[x][y];
570     if (kickedobj) {
571         /* kick object; if doing is fatal, done() will clean up kickedobj */
572         res = really_kick_object(x, y);
573         kickedobj = (struct obj *) 0;
574     }
575     return res;
576 }
577
578 /* guts of kick_object */
579 STATIC_OVL int
580 really_kick_object(x, y)
581 xchar x, y;
582 {
583     int range;
584     struct monst *mon, *shkp = 0;
585     struct trap *trap;
586     char bhitroom;
587     boolean costly, isgold, slide = FALSE;
588
589     /* kickedobj should always be set due to conditions of call */
590     if (!kickedobj || kickedobj->otyp == BOULDER || kickedobj == uball
591         || kickedobj == uchain)
592         return 0;
593
594     if ((trap = t_at(x, y)) != 0
595         && (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !Passes_walls)
596             || trap->ttyp == WEB)) {
597         if (!trap->tseen)
598             find_trap(trap);
599 #if 0 /*JP*/
600         You_cant("kick %s that's in a %s!", something,
601                  Hallucination ? "tizzy" : (trap->ttyp == WEB) ? "web"
602                                                                : "pit");
603 #else
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Ô"
606                           : trap->ttyp == WEB
607                              ? "\82­\82à\82Ì\91\83\82Ì\92\86" : "\97\8e\82µ\8c\8a\82Ì\92\86",
608             something);
609 #endif
610         return 1;
611     }
612
613     if (Fumbling && !rn2(3)) {
614 /*JP
615         Your("clumsy kick missed.");
616 */
617         Your("\95s\8aí\97p\82È\8fR\82è\82Í\8aO\82ê\82½\81D");
618         return 1;
619     }
620
621     if (!uarmf && kickedobj->otyp == CORPSE
622         && touch_petrifies(&mons[kickedobj->corpsenm]) && !Stone_resistance) {
623 #if 0 /*JP*/
624         You("kick %s with your bare %s.",
625             corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE),
626             makeplural(body_part(FOOT)));
627 #else
628         You("\91f%s\82Å%s\82ð\8fR\82Á\82½\81D",
629             body_part(FOOT),
630             corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE));
631 #endif
632         if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
633             ; /* hero has been transformed but kick continues */
634         } else {
635             /* normalize body shape here; foot, not body_part(FOOT) */
636 /*JP
637             Sprintf(killer.name, "kicking %s barefoot",
638 */
639             Sprintf(killer.name, "\8cC\96³\82µ\82Å%s\82ð\8fR\82Á\82Ä",
640                     killer_xname(kickedobj));
641             instapetrify(killer.name);
642         }
643     }
644
645     /* range < 2 means the object will not move.  */
646     /* maybe dexterity should also figure here.   */
647     range = (int) ((ACURRSTR) / 2 - kickedobj->owt / 40);
648
649     if (martial())
650         range += rnd(3);
651
652     if (is_pool(x, y)) {
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 */
657         range += rnd(3);
658     } else {
659         if (is_ice(x, y))
660             range += rnd(3), slide = TRUE;
661         if (kickedobj->greased)
662             range += rnd(3), slide = TRUE;
663     }
664
665     /* Mjollnir is magically too heavy to kick */
666     if (kickedobj->oartifact == ART_MJOLLNIR)
667         range = 1;
668
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))
672         range = 1;
673
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);
678
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)) {
682             if (Blind)
683 /*JP
684                 pline("It doesn't come loose.");
685 */
686                 pline("\82Ñ\82­\82Æ\82à\82µ\82È\82¢\81D");
687             else
688 #if 0 /*JP*/
689                 pline("%s %sn't come loose.",
690                       The(distant_name(kickedobj, xname)),
691                       otense(kickedobj, "do"));
692 #else
693                 pline("%s\82Í\82Ñ\82­\82Æ\82à\82µ\82È\82¢\81D",
694                       distant_name(kickedobj, xname));
695 #endif
696             return (!rn2(3) || martial());
697         }
698         if (Blind)
699 /*JP
700             pline("It comes loose.");
701 */
702             pline("\89½\82©\82ª\8aÉ\82ñ\82Å\82Æ\82ê\82½\81D");
703         else
704 #if 0 /*JP*/
705             pline("%s %s loose.", The(distant_name(kickedobj, xname)),
706                   otense(kickedobj, "come"));
707 #else
708             pline("%s\82Í\8aÉ\82ñ\82Å\82Æ\82ê\82½\81D", distant_name(kickedobj, xname));
709 #endif
710         obj_extract_self(kickedobj);
711         newsym(x, y);
712         if (costly && (!costly_spot(u.ux, u.uy)
713                        || !index(u.urooms, *in_rooms(x, y, SHOPBASE))))
714             addtobill(kickedobj, FALSE, FALSE, FALSE);
715 /*JP
716         if (!flooreffects(kickedobj, u.ux, u.uy, "fall")) {
717 */
718         if (!flooreffects(kickedobj, u.ux, u.uy, "\97\8e\82¿\82é")) {
719             place_object(kickedobj, u.ux, u.uy);
720             stackobj(kickedobj);
721             newsym(u.ux, u.uy);
722         }
723         return 1;
724     }
725
726     /* a box gets a chance of breaking open here */
727     if (Is_box(kickedobj)) {
728         boolean otrp = kickedobj->otrapped;
729
730         if (range < 2)
731 /*JP
732             pline("THUD!");
733 */
734             pline("\83K\83\93\81I");
735         container_impact_dmg(kickedobj, x, y);
736         if (kickedobj->olocked) {
737             if (!rn2(5) || (martial() && !rn2(2))) {
738 /*JP
739                 You("break open the lock!");
740 */
741                 You("\8c®\82ð\89ó\82µ\8aJ\82¯\82½\81I");
742                 breakchestlock(kickedobj, FALSE);
743                 if (otrp)
744                     (void) chest_trap(kickedobj, LEG, FALSE);
745                 return 1;
746             }
747         } else {
748             if (!rn2(3) || (martial() && !rn2(2))) {
749 /*JP
750                 pline_The("lid slams open, then falls shut.");
751 */
752                 pline("\8aW\82ª\82Î\82½\82ñ\82Æ\8aJ\82«\81C\95Â\82\82½\81D");
753                 kickedobj->lknown = 1;
754                 if (otrp)
755                     (void) chest_trap(kickedobj, LEG, FALSE);
756                 return 1;
757             }
758         }
759         if (range < 2)
760             return 1;
761         /* else let it fall through to the next cases... */
762     }
763
764     /* fragile objects should not be kicked */
765     if (hero_breaks(kickedobj, kickedobj->ox, kickedobj->oy, FALSE))
766         return 1;
767
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
771      */
772     if (range < 2) {
773         if (!Is_box(kickedobj))
774 /*JP
775             pline("Thump!");
776 */
777             pline("\83S\83c\83\93\81I");
778         return (!rn2(3) || martial());
779     }
780
781     if (kickedobj->quan > 1L) {
782         if (!isgold) {
783             kickedobj = splitobj(kickedobj, 1L);
784         } else {
785             if (rn2(20)) {
786                 static NEARDATA const char *const flyingcoinmsg[] = {
787                     "scatter the coins", "knock coins all over the place",
788                     "send coins flying in all directions",
789                 };
790
791                 pline("Thwwpingg!");
792                 You("%s!", flyingcoinmsg[rn2(SIZE(flyingcoinmsg))]);
793                 (void) scatter(x, y, rn2(3) + 1, VIS_EFFECTS | MAY_HIT,
794                                kickedobj);
795                 newsym(x, y);
796                 return 1;
797             }
798             if (kickedobj->quan > 300L) {
799                 pline("Thump!");
800                 return (!rn2(3) || martial());
801             }
802         }
803     }
804
805     if (slide && !Blind)
806 #if 0 /*JP*/
807         pline("Whee!  %s %s across the %s.", Doname2(kickedobj),
808               otense(kickedobj, "slide"), surface(x, y));
809 #else
810         pline("\83Y\83\8b\83b\81I%s\82Í%s\82Ì\8fã\82ð\8a\8a\82Á\82½\81D", Doname2(kickedobj),
811               surface(x,y));
812 #endif
813
814     if (costly && !isgold)
815         addtobill(kickedobj, FALSE, FALSE, TRUE);
816     obj_extract_self(kickedobj);
817     (void) snuff_candle(kickedobj);
818     newsym(x, y);
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);
822     if (!kickedobj)
823         return 1; /* object broken */
824
825     if (mon) {
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? */
832             return 1;
833     }
834
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)
838         return 1;
839
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)) {
843         if (isgold)
844             costly_gold(x, y, kickedobj->quan);
845         else
846             (void) stolen_value(kickedobj, x, y, (boolean) shkp->mpeaceful,
847                                 FALSE);
848     }
849
850 /*JP
851     if (flooreffects(kickedobj, bhitpos.x, bhitpos.y, "fall"))
852 */
853     if(flooreffects(kickedobj, bhitpos.x, bhitpos.y, "\97\8e\82¿\82é"))
854         return 1;
855     if (kickedobj->unpaid)
856         subfrombill(kickedobj, shkp);
857     place_object(kickedobj, bhitpos.x, bhitpos.y);
858     stackobj(kickedobj);
859     newsym(kickedobj->ox, kickedobj->oy);
860     return 1;
861 }
862
863 /* cause of death if kicking kills kicker */
864 STATIC_OVL char *
865 kickstr(buf)
866 char *buf;
867 {
868     const char *what;
869
870     if (kickedobj)
871         what = killer_xname(kickedobj);
872     else if (maploc == &nowhere)
873 /*JP
874         what = "nothing";
875 */
876         what = "\89½\82à\82È\82¢\82Æ\82±\82ë";
877     else if (IS_DOOR(maploc->typ))
878 /*JP
879         what = "a door";
880 */
881         what = "\94à";
882     else if (IS_TREE(maploc->typ))
883 /*JP
884         what = "a tree";
885 */
886         what = "\96Ø";
887     else if (IS_STWALL(maploc->typ))
888 /*JP
889         what = "a wall";
890 */
891         what = "\95Ç";
892     else if (IS_ROCK(maploc->typ))
893 /*JP
894         what = "a rock";
895 */
896         what = "\8aâ";
897     else if (IS_THRONE(maploc->typ))
898 /*JP
899         what = "a throne";
900 */
901         what = "\8bÊ\8dÀ";
902     else if (IS_FOUNTAIN(maploc->typ))
903 /*JP
904         what = "a fountain";
905 */
906         what = "\90ò";
907     else if (IS_GRAVE(maploc->typ))
908 /*JP
909         what = "a headstone";
910 */
911         what = "\95æ\90Î";
912     else if (IS_SINK(maploc->typ))
913 /*JP
914         what = "a sink";
915 */
916         what = "\97¬\82µ\91ä";
917     else if (IS_ALTAR(maploc->typ))
918 /*JP
919         what = "an altar";
920 */
921         what = "\8dÕ\92d";
922     else if (IS_DRAWBRIDGE(maploc->typ))
923 /*JP
924         what = "a drawbridge";
925 */
926         what = "\92µ\82Ë\8b´";
927     else if (maploc->typ == STAIRS)
928 /*JP
929         what = "the stairs";
930 */
931         what = "\8aK\92i";
932     else if (maploc->typ == LADDER)
933 /*JP
934         what = "a ladder";
935 */
936         what = "\82Í\82µ\82²";
937     else if (maploc->typ == IRONBARS)
938 /*JP
939         what = "an iron bar";
940 */
941         what = "\93S\96_";
942     else
943 /*JP
944         what = "something weird";
945 */
946         what = "\89½\82©\96­\82È\82à\82Ì";
947 #if 0 /*JP*/
948     return strcat(strcpy(buf, "kicking "), what);
949 #else
950     Sprintf(buf, "%s\82ð\8fR\82Á\82Ä", what);
951     return buf;
952 #endif
953 }
954
955 int
956 dokick()
957 {
958     int x, y;
959     int avrg_attrib;
960     int dmg = 0, glyph, oldglyph = -1;
961     register struct monst *mtmp;
962     boolean no_kick = FALSE;
963     char buf[BUFSZ];
964
965     if (nolimbs(youmonst.data) || slithy(youmonst.data)) {
966 /*JP
967         You("have no legs to kick with.");
968 */
969         You("\89½\82©\82ð\8fR\82ë\82¤\82É\82à\91«\82ª\82È\82¢\81D");
970         no_kick = TRUE;
971     } else if (verysmall(youmonst.data)) {
972 /*JP
973         You("are too small to do any kicking.");
974 */
975         You("\89½\82©\82ð\8fR\82é\82É\82Í\8f¬\82³\82·\82¬\82é\81D");
976         no_kick = TRUE;
977     } else if (u.usteed) {
978 /*JP
979         if (yn_function("Kick your steed?", ynchars, 'y') == 'y') {
980 */
981         if (yn_function("\94n\82ð\8fR\82é\81H", ynchars, 'y') == 'y') {
982 /*JP
983             You("kick %s.", mon_nam(u.usteed));
984 */
985             You("%s\82ð\8fR\82Á\82½\81D", mon_nam(u.usteed));
986             kick_steed();
987             return 1;
988         } else {
989             return 0;
990         }
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);
995
996         if (wl == BOTH_SIDES)
997             bp = makeplural(bp);
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");
1001         no_kick = TRUE;
1002     } else if (near_capacity() > SLT_ENCUMBER) {
1003 /*JP
1004         Your("load is too heavy to balance yourself for a kick.");
1005 */
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");
1007         no_kick = TRUE;
1008     } else if (youmonst.data->mlet == S_LIZARD) {
1009 /*JP
1010         Your("legs cannot kick effectively.");
1011 */
1012         Your("\91«\82Å\82Í\82¤\82Ü\82­\8fR\82ê\82È\82¢\81D");
1013         no_kick = TRUE;
1014     } else if (u.uinwater && !rn2(2)) {
1015 /*JP
1016         Your("slow motion kick doesn't hit anything.");
1017 */
1018         Your("\92x\82¢\93®\82«\82Ì\8fR\82è\82Å\82Í\96½\92\86\82µ\82æ\82¤\82ª\82È\82¢\81D");
1019         no_kick = TRUE;
1020     } else if (u.utrap) {
1021         no_kick = TRUE;
1022         switch (u.utraptype) {
1023         case TT_PIT:
1024             if (!Passes_walls)
1025 /*JP
1026                 pline("There's not enough room to kick down here.");
1027 */
1028                 pline("\97\8e\82µ\8c\8a\82É\82Í\82Ü\82Á\82Ä\82¢\82é\82Ì\82Å\81C\8fR\82ê\82È\82¢\81D");
1029             else
1030                 no_kick = FALSE;
1031             break;
1032         case TT_WEB:
1033         case TT_BEARTRAP:
1034 /*JP
1035             You_cant("move your %s!", body_part(LEG));
1036 */
1037             You("%s\82ð\93®\82©\82·\82±\82Æ\82ª\82Å\82«\82È\82¢\81I", body_part(LEG));
1038             break;
1039         default:
1040             break;
1041         }
1042     }
1043
1044     if (no_kick) {
1045         /* ignore direction typed before player notices kick failed */
1046         display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1047         return 0;
1048     }
1049
1050     if (!getdir((char *) 0))
1051         return 0;
1052     if (!u.dx && !u.dy)
1053         return 0;
1054
1055     x = u.ux + u.dx;
1056     y = u.uy + u.dy;
1057
1058     /* KMH -- Kicking boots always succeed */
1059     if (uarmf && uarmf->otyp == KICKING_BOOTS)
1060         avrg_attrib = 99;
1061     else
1062         avrg_attrib = (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3;
1063
1064     if (u.uswallow) {
1065         switch (rn2(3)) {
1066         case 0:
1067 /*JP
1068             You_cant("move your %s!", body_part(LEG));
1069 */
1070             You("%s\82ð\93®\82©\82·\82±\82Æ\82ª\82Å\82«\82È\82¢\81I", body_part(LEG));
1071             break;
1072         case 1:
1073             if (is_animal(u.ustuck->data)) {
1074 /*JP
1075                 pline("%s burps loudly.", Monnam(u.ustuck));
1076 */
1077                 pline("%s\82Í\91å\82«\82È\83Q\83b\83v\82ð\82µ\82½\81D", Monnam(u.ustuck));
1078                 break;
1079             }
1080         default:
1081 /*JP
1082             Your("feeble kick has no effect.");
1083 */
1084             Your("\8eã\81X\82µ\82¢\8fR\82è\82Í\8cø\89Ê\82ª\82È\82¢\81D"); break;
1085             break;
1086         }
1087         return 1;
1088     } else if (u.utrap && u.utraptype == TT_PIT) {
1089         /* must be Passes_walls */
1090 /*JP
1091         You("kick at the side of the pit.");
1092 */
1093         You("\97\8e\82µ\8c\8a\82Ì\95Ç\82ð\8fR\82Á\82½\81D");
1094         return 1;
1095     }
1096     if (Levitation) {
1097         int xx, yy;
1098
1099         xx = u.ux - u.dx;
1100         yy = u.uy - u.dy;
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?
1104          */
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))) {
1108 /*JP
1109             You("have nothing to brace yourself against.");
1110 */
1111             pline("\8ex\82¦\82É\82Å\82«\82é\82æ\82¤\82È\82à\82Ì\82ª\96³\82¢\81D");
1112             return 0;
1113         }
1114     }
1115
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 */
1121     if (mtmp) {
1122         oldglyph = glyph_at(x, y);
1123         if (!maybe_kick_monster(mtmp, x, y))
1124             return context.move;
1125     }
1126
1127     wake_nearby();
1128     u_wipe_engr(2);
1129
1130     if (!isok(x, y)) {
1131         maploc = &nowhere;
1132         goto ouch;
1133     }
1134     maploc = &levl[x][y];
1135
1136     /*
1137      * The next five tests should stay in their present order:
1138      * monsters, pools, objects, non-doors, doors.
1139      *
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.]
1147      */
1148
1149     if (mtmp) {
1150         /* save mtmp->data (for recoil) in case mtmp gets killed */
1151         struct permonst *mdat = mtmp->data;
1152
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);
1169         }
1170         /* recoil if floating */
1171         if ((Is_airlevel(&u.uz) || Levitation) && context.move) {
1172             int range;
1173
1174             range =
1175                 ((int) youmonst.data->cwt + (weight_cap() + inv_weight()));
1176             if (range < 1)
1177                 range = 1; /* divide by zero avoidance */
1178             range = (3 * (int) mdat->cwt) / range;
1179
1180             if (range < 1)
1181                 range = 1;
1182             hurtle(-u.dx, -u.dy, range, TRUE);
1183         }
1184         return 1;
1185     }
1186     if (glyph_is_invisible(levl[x][y].glyph)) {
1187         unmap_object(x, y);
1188         newsym(x, y);
1189     }
1190     if (is_pool(x, y) ^ !!u.uinwater) {
1191         /* objects normally can't be removed from water by kicking */
1192 /*JP
1193         You("splash some water around.");
1194 */
1195         You("\90\85\82ð\89ñ\82è\82É\82Ü\82«\82¿\82ç\82µ\82½\81D");
1196         return 1;
1197     }
1198
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 */
1204             return 1;
1205         }
1206         goto ouch;
1207     }
1208
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 */
1213 #if 0 /*JP*/
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"
1219                           : "You kick open");
1220 #else
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
1223                           ? "\94­\8c©\82µ"
1224                           : "\8fR\82è\8aJ\82¯");
1225 #endif
1226                 exercise(A_DEX, TRUE);
1227                 if (maploc->doormask & D_TRAPPED) {
1228                     maploc->doormask = D_NODOOR;
1229 /*JP
1230                     b_trapped("door", FOOT);
1231 */
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 */
1240                 return 1;
1241             } else
1242                 goto ouch;
1243         }
1244         if (maploc->typ == SCORR) {
1245             if (!Levitation && rn2(30) < avrg_attrib) {
1246 /*JP
1247                 pline("Crash!  You kick open a secret passage!");
1248 */
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);
1251                 maploc->typ = CORR;
1252                 feel_newsym(x, y); /* we know it's gone */
1253                 unblock_point(x, y); /* vision */
1254                 return 1;
1255             } else
1256                 goto ouch;
1257         }
1258         if (IS_THRONE(maploc->typ)) {
1259             register int i;
1260             if (Levitation)
1261                 goto dumb;
1262             if ((Luck < 0 || maploc->doormask) && !rn2(3)) {
1263                 maploc->typ = ROOM;
1264                 maploc->doormask = 0; /* don't leave loose ends.. */
1265                 (void) mkgold((long) rnd(200), x, y);
1266                 if (Blind)
1267 /*JP
1268                     pline("CRASH!  You destroy it.");
1269 */
1270                     pline("\83K\83V\83\83\83\93\81I\82 \82È\82½\82Í\89½\82©\82ð\94j\89ó\82µ\82½\81D");
1271                 else {
1272 /*JP
1273                     pline("CRASH!  You destroy the throne.");
1274 */
1275                     pline("\83K\83V\83\83\83\93\81I\82 \82È\82½\82Í\8bÊ\8dÀ\82ð\94j\89ó\82µ\82½\81D");
1276                     newsym(x, y);
1277                 }
1278                 exercise(A_DEX, TRUE);
1279                 return 1;
1280             } else if (Luck > 0 && !rn2(3) && !maploc->looted) {
1281                 (void) mkgold((long) rn1(201, 300), x, y);
1282                 i = Luck + 1;
1283                 if (i > 6)
1284                     i = 6;
1285                 while (i--)
1286                     (void) mksobj_at(
1287                         rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE - 1), x, y,
1288                         FALSE, TRUE);
1289                 if (Blind)
1290 /*JP
1291                     You("kick %s loose!", something);
1292 */
1293                     You("\82È\82É\82©\82ð\8fR\82è\8eU\82ç\82µ\82½\81I");
1294                 else {
1295 /*JP
1296                     You("kick loose some ornamental coins and gems!");
1297 */
1298                     You("\91\95\8fü\97p\82Ì\8bà\89Ý\82â\95ó\90Î\82ð\8fR\82è\8eU\82ç\82µ\82½\81I");
1299                     newsym(x, y);
1300                 }
1301                 /* prevent endless milking */
1302                 maploc->looted = T_LOOTED;
1303                 return 1;
1304             } else if (!rn2(4)) {
1305                 if (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) {
1306                     fall_through(FALSE);
1307                     return 1;
1308                 } else
1309                     goto ouch;
1310             }
1311             goto ouch;
1312         }
1313         if (IS_ALTAR(maploc->typ)) {
1314             if (Levitation)
1315                 goto dumb;
1316 /*JP
1317             You("kick %s.", (Blind ? something : "the altar"));
1318 */
1319             You("%s\82ð\8fR\82Á\82½\81D", (Blind ? "\89½\82©" : "\8dÕ\92d"));
1320             if (!rn2(3))
1321                 goto ouch;
1322             altar_wrath(x, y);
1323             exercise(A_DEX, TRUE);
1324             return 1;
1325         }
1326         if (IS_FOUNTAIN(maploc->typ)) {
1327             if (Levitation)
1328                 goto dumb;
1329 /*JP
1330             You("kick %s.", (Blind ? something : "the fountain"));
1331 */
1332             You("%s\82ð\8fR\82Á\82½\81D",(Blind ? "\89½\82©" : "\90ò"));
1333             if (!rn2(3))
1334                 goto ouch;
1335             /* make metal boots rust */
1336             if (uarmf && rn2(3))
1337 /*JP
1338                 if (water_damage(uarmf, "metal boots", TRUE) == ER_NOTHING) {
1339 */
1340                 if (water_damage(uarmf, "\8bà\91®\82Ì\8cC", TRUE) == ER_NOTHING) {
1341 /*JP
1342                     Your("boots get wet.");
1343 */
1344                     Your("\8cC\82Í\94G\82ê\82½\81D");
1345                     /* could cause short-lived fumbling here */
1346                 }
1347             exercise(A_DEX, TRUE);
1348             return 1;
1349         }
1350         if (IS_GRAVE(maploc->typ)) {
1351             if (Levitation)
1352                 goto dumb;
1353             if (rn2(4))
1354                 goto ouch;
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));
1359             }
1360             maploc->typ = ROOM;
1361             maploc->doormask = 0;
1362             (void) mksobj_at(ROCK, x, y, TRUE, FALSE);
1363             del_engr_at(x, y);
1364             if (Blind)
1365                 pline("Crack!  %s broke!", Something);
1366             else {
1367                 pline_The("headstone topples over and breaks!");
1368                 newsym(x, y);
1369             }
1370             return 1;
1371         }
1372         if (maploc->typ == IRONBARS)
1373             goto ouch;
1374         if (IS_TREE(maploc->typ)) {
1375             struct obj *treefruit;
1376             /* nothing, fruit or trouble? 75:23.5:1.5% */
1377             if (rn2(3)) {
1378                 if (!rn2(6) && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
1379 #if 0 /*JP*/
1380                     You_hear("a low buzzing."); /* a warning */
1381 #else
1382                     You_hear("\82Ô\81[\82ñ\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D"); /* a warning */
1383 #endif
1384                 goto ouch;
1385             }
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))
1392 /*JP
1393                     pline("Some %s fall from the tree!", xname(treefruit));
1394 */
1395                     pline("%s\82ª\89½\8cÂ\82©\96Ø\82©\82ç\97\8e\82¿\82Ä\82«\82½\81I", xname(treefruit));
1396                 else
1397 /*JP
1398                     pline("%s falls from the tree!", An(xname(treefruit)));
1399 */
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;
1407 #if 0 /*JP*/
1408                     pline("%ld %s got caught in the branches.",
1409                           nfruit - nfall, xname(treefruit));
1410 #else
1411                     pline("%ld\8cÂ\82Ì%s\82ª\8e}\82É\82Ð\82Á\82©\82©\82Á\82½\81D",
1412                           nfruit - nfall, xname(treefruit));
1413 #endif
1414                     dealloc_obj(treefruit);
1415                 }
1416                 exercise(A_DEX, TRUE);
1417                 exercise(A_WIS, TRUE); /* discovered a new food source! */
1418                 newsym(x, y);
1419                 maploc->looted |= TREE_LOOTED;
1420                 return 1;
1421             } else if (!(maploc->looted & TREE_SWARM)) {
1422                 int cnt = rnl(4) + 2;
1423                 int made = 0;
1424                 coord mm;
1425                 mm.x = x;
1426                 mm.y = y;
1427                 while (cnt--) {
1428                     if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE])
1429                         && makemon(&mons[PM_KILLER_BEE], mm.x, mm.y,
1430                                    MM_ANGRY))
1431                         made++;
1432                 }
1433                 if (made)
1434 /*JP
1435                     pline("You've attracted the tree's former occupants!");
1436 */
1437                     pline("\96Ø\82Ì\90æ\8fZ\96¯\82ð\8bN\82±\82µ\82Ä\82µ\82Ü\82Á\82½\81I");
1438                 else
1439 /*JP
1440                     You("smell stale honey.");
1441 */
1442                     pline("\8cÃ\82¢\82Í\82¿\82Ý\82Â\82Ì\82É\82¨\82¢\82ª\82µ\82½\81D");
1443                 maploc->looted |= TREE_SWARM;
1444                 return 1;
1445             }
1446             goto ouch;
1447         }
1448         if (IS_SINK(maploc->typ)) {
1449             int gend = poly_gender();
1450             short washerndx = (gend == 1 || (gend == 2 && rn2(2)))
1451                                   ? PM_INCUBUS
1452                                   : PM_SUCCUBUS;
1453
1454             if (Levitation)
1455                 goto dumb;
1456             if (rn2(5)) {
1457                 if (!Deaf)
1458 /*JP
1459                     pline("Klunk!  The pipes vibrate noisily.");
1460 */
1461                     pline("\83K\83\89\83\93\81I\83p\83C\83v\82Í\82¤\82é\82³\82­\90U\93®\82µ\82½\81D");
1462                 else
1463 /*JP
1464                     pline("Klunk!");
1465 */
1466                     pline("\83K\83\89\83\93\81I");
1467                 exercise(A_DEX, TRUE);
1468                 return 1;
1469             } else if (!(maploc->looted & S_LPUDDING) && !rn2(3)
1470                        && !(mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) {
1471                 if (Blind)
1472 /*JP
1473                     You_hear("a gushing sound.");
1474 */
1475                     You_hear("\82È\82É\82©\82ª\95¬\8fo\82·\82é\89¹\82ð\95·\82¢\82½\81D");
1476                 else
1477 /*JP
1478                     pline("A %s ooze gushes up from the drain!",
1479 */
1480                     pline("%s\89t\91Ì\82ª\94r\90\85\8cû\82©\82ç\82É\82\82Ý\8fo\82½\81I",
1481                           hcolor(NH_BLACK));
1482                 (void) makemon(&mons[PM_BLACK_PUDDING], x, y, NO_MM_FLAGS);
1483                 exercise(A_DEX, TRUE);
1484                 newsym(x, y);
1485                 maploc->looted |= S_LPUDDING;
1486                 return 1;
1487             } else if (!(maploc->looted & S_LDWASHER) && !rn2(3)
1488                        && !(mvitals[washerndx].mvflags & G_GONE)) {
1489                 /* can't resist... */
1490 /*JP
1491                 pline("%s returns!", (Blind ? Something : "The dish washer"));
1492 */
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))
1495                     newsym(x, y);
1496                 maploc->looted |= S_LDWASHER;
1497                 exercise(A_DEX, TRUE);
1498                 return 1;
1499             } else if (!rn2(3)) {
1500 #if 0 /*JP*/
1501                 pline("Flupp!  %s.",
1502                       (Blind ? "You hear a sloshing sound"
1503                              : "Muddy waste pops up from the drain"));
1504 #else
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é"));
1508 #endif
1509                 if (!(maploc->looted & S_LRING)) { /* once per sink */
1510                     if (!Blind)
1511 /*JP
1512                         You_see("a ring shining in its midst.");
1513 */
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);
1516                     newsym(x, y);
1517                     exercise(A_DEX, TRUE);
1518                     exercise(A_WIS, TRUE); /* a discovery! */
1519                     maploc->looted |= S_LRING;
1520                 }
1521                 return 1;
1522             }
1523             goto ouch;
1524         }
1525         if (maploc->typ == STAIRS || maploc->typ == LADDER
1526             || IS_STWALL(maploc->typ)) {
1527             if (!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN)
1528                 goto dumb;
1529         ouch:
1530 /*JP
1531             pline("Ouch!  That hurts!");
1532 */
1533             pline("\82¢\82Ä\82Á\81I\89ö\89ä\82µ\82½\81I");
1534             exercise(A_DEX, FALSE);
1535             exercise(A_STR, FALSE);
1536             if (isok(x, y)) {
1537                 if (Blind)
1538                     feel_location(x, y); /* we know we hit it */
1539                 if (is_drawbridge_wall(x, y) >= 0) {
1540 /*JP
1541                     pline_The("drawbridge is unaffected.");
1542 */
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];
1547                 }
1548             }
1549             if (!rn2(3))
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 */
1555             return 1;
1556         }
1557         goto dumb;
1558     }
1559
1560     if (maploc->doormask == D_ISOPEN || maploc->doormask == D_BROKEN
1561         || maploc->doormask == D_NODOOR) {
1562     dumb:
1563         exercise(A_DEX, FALSE);
1564         if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
1565 /*JP
1566             You("kick at empty space.");
1567 */
1568             You("\89½\82à\82È\82¢\8bó\8aÔ\82ð\8fR\82Á\82½\81D");
1569             if (Blind)
1570                 feel_location(x, y);
1571         } else {
1572 /*JP
1573             pline("Dumb move!  You strain a muscle.");
1574 */
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));
1578         }
1579         if ((Is_airlevel(&u.uz) || Levitation) && rn2(2))
1580             hurtle(-u.dx, -u.dy, 1, TRUE);
1581         return 1; /* uses a turn */
1582     }
1583
1584     /* not enough leverage to kick open doors while levitating */
1585     if (Levitation)
1586         goto ouch;
1587
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) {
1594             if (flags.verbose)
1595 /*JP
1596                 You("kick the door.");
1597 */
1598                 You("\94à\82ð\8fR\82Á\82½\81D");
1599             exercise(A_STR, FALSE);
1600             maploc->doormask = D_NODOOR;
1601 /*JP
1602             b_trapped("door", FOOT);
1603 */
1604             b_trapped("\94à", FOOT);
1605         } else if (ACURR(A_STR) > 18 && !rn2(5) && !shopdoor) {
1606 /*JP
1607             pline("As you kick the door, it shatters to pieces!");
1608 */
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;
1612         } else {
1613 /*JP
1614             pline("As you kick the door, it crashes open!");
1615 */
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;
1619         }
1620         feel_newsym(x, y); /* we know we broke it */
1621         unblock_point(x, y); /* vision */
1622         if (shopdoor) {
1623             add_damage(x, y, 400L);
1624 /*JP
1625             pay_for_damage("break", FALSE);
1626 */
1627             pay_for_damage("\94j\89ó\82·\82é", FALSE);
1628         }
1629         if (in_town(x, y))
1630             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1631                 if (DEADMONSTER(mtmp))
1632                     continue;
1633                 if (is_watch(mtmp->data) && couldsee(mtmp->mx, mtmp->my)
1634                     && mtmp->mpeaceful) {
1635 /*JP
1636                     mon_yells(mtmp, "Halt, thief!  You're under arrest!");
1637 */
1638                     mon_yells(mtmp, "\8e~\82Ü\82ê\93D\96_\81I\82¨\82Ü\82¦\82ð\91ß\95ß\82·\82é\81I");
1639                     (void) angry_guards(FALSE);
1640                     break;
1641                 }
1642             }
1643     } else {
1644         if (Blind)
1645             feel_location(x, y); /* we know we hit it */
1646         exercise(A_STR, TRUE);
1647 /*JP
1648         pline("WHAMMM!!!");
1649 */
1650         pline("\82®\82\9f\82\9f\82\9f\82ñ\81I");
1651         if (in_town(x, y))
1652             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1653                 if (DEADMONSTER(mtmp))
1654                     continue;
1655                 if (is_watch(mtmp->data) && mtmp->mpeaceful
1656                     && couldsee(mtmp->mx, mtmp->my)) {
1657                     if (levl[x][y].looted & D_WARNED) {
1658                         mon_yells(mtmp,
1659 /*JP
1660                                   "Halt, vandal!  You're under arrest!");
1661 */
1662                                   "\8e~\82Ü\82ê\96ì\94Ø\90l\81I\82¨\82Ü\82¦\82ð\91ß\95ß\82·\82é\81I");
1663                         (void) angry_guards(FALSE);
1664                     } else {
1665 /*JP
1666                         mon_yells(mtmp, "Hey, stop damaging that door!");
1667 */
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;
1670                     }
1671                     break;
1672                 }
1673             }
1674     }
1675     return 1;
1676 }
1677
1678 STATIC_OVL void
1679 drop_to(cc, loc)
1680 coord *cc;
1681 schar loc;
1682 {
1683     /* cover all the MIGR_xxx choices generated by down_gate() */
1684     switch (loc) {
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;
1689             break;
1690         } else if (In_endgame(&u.uz) || Is_botlevel(&u.uz)) {
1691             cc->y = cc->x = 0;
1692             break;
1693         } /* else fall to the next cases */
1694     case MIGR_STAIRS_UP:
1695     case MIGR_LADDER_UP:
1696         cc->x = u.uz.dnum;
1697         cc->y = u.uz.dlevel + 1;
1698         break;
1699     case MIGR_SSTAIRS:
1700         cc->x = sstairs.tolev.dnum;
1701         cc->y = sstairs.tolev.dlevel;
1702         break;
1703     default:
1704     case MIGR_NOWHERE:
1705         /* y==0 means "nowhere", in which case x doesn't matter */
1706         cc->y = cc->x = 0;
1707         break;
1708     }
1709 }
1710
1711 /* player or missile impacts location, causing objects to fall down */
1712 void
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 */
1717 {
1718     schar toloc;
1719     register struct obj *obj, *obj2;
1720     register struct monst *shkp;
1721     long oct, dct, price, debit, robbed;
1722     boolean angry, costly, isrock;
1723     coord cc;
1724
1725     if (!OBJ_AT(x, y))
1726         return;
1727
1728     toloc = down_gate(x, y);
1729     drop_to(&cc, toloc);
1730     if (!cc.y)
1731         return;
1732
1733     if (dlev) {
1734         /* send objects next to player falling through trap door.
1735          * checked in obj_delivery().
1736          */
1737         toloc = MIGR_WITH_HERO;
1738         cc.y = dlev;
1739     }
1740
1741     costly = costly_spot(x, y);
1742     price = debit = robbed = 0L;
1743     angry = FALSE;
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.
1750      */
1751     if (costly) {
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;
1756         }
1757     }
1758
1759     isrock = (missile && missile->otyp == ROCK);
1760     oct = dct = 0L;
1761     for (obj = level.objects[x][y]; obj; obj = obj2) {
1762         obj2 = obj->nexthere;
1763         if (obj == missile)
1764             continue;
1765         /* number of objects in the pile */
1766         oct += obj->quan;
1767         if (obj == uball || obj == uchain)
1768             continue;
1769         /* boulders can fall too, but rarely & never due to rocks */
1770         if ((isrock && obj->otyp == BOULDER)
1771             || rn2(obj->otyp == BOULDER ? 30 : 3))
1772             continue;
1773         obj_extract_self(obj);
1774
1775         if (costly) {
1776             price += stolen_value(
1777                 obj, x, y, (costly_spot(u.ux, u.uy)
1778                             && index(u.urooms, *in_rooms(x, y, SHOPBASE))),
1779                 TRUE);
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)
1784                 obj->no_charge = 0;
1785         }
1786
1787         add_to_migration(obj);
1788         obj->ox = cc.x;
1789         obj->oy = cc.y;
1790         obj->owornmask = (long) toloc;
1791
1792         /* number of fallen objects */
1793         dct += obj->quan;
1794     }
1795
1796     if (dct && cansee(x, y)) { /* at least one object fell */
1797 /*JP
1798         const char *what = (dct == 1L ? "object falls" : "objects fall");
1799 */
1800         const char *what = "\95¨";
1801
1802         if (missile)
1803 #if 0 /*JP:T*/
1804             pline("From the impact, %sother %s.",
1805                   dct == oct ? "the " : dct == 1L ? "an" : "", what);
1806 #else
1807             pline("\8fÕ\8c\82\82Å\81C\91¼\82Ì%s\82ª\97\8e\82¿\82½\81D",what);
1808 #endif
1809         else if (oct == dct)
1810 #if 0 /*JP:T*/
1811             pline("%s adjacent %s %s.", dct == 1L ? "The" : "All the", what,
1812                   gate_str);
1813 #else
1814             pline("\8bß\82­\82É\82 \82Á\82½%s\82ª%s\97\8e\82¿\82½\81D", what, gate_str);
1815 #endif
1816         else
1817 #if 0 /*JP*/
1818             pline("%s adjacent %s %s.",
1819                   dct == 1L ? "One of the" : "Some of the",
1820                   dct == 1L ? "objects falls" : what, gate_str);
1821 #else
1822             pline("\8bß\82­\82É\82 \82Á\82½%s%s%s\97\8e\82¿\82½\81D",
1823                   what,
1824                   dct == 1L ? "\82ª" : "\82Ì\82¢\82­\82Â\82©\82ª",
1825                   gate_str);
1826 #endif
1827     }
1828
1829     if (costly && shkp && price) {
1830         if (ESHK(shkp)->robbed > robbed) {
1831 /*JP
1832             You("removed %ld %s worth of goods!", price, currency(price));
1833 */
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);
1838                 if (angry)
1839 /*JP
1840                     pline("%s is infuriated!", Monnam(shkp));
1841 */
1842                     pline("%s\82Í\8c\83\93{\82µ\82½\81I", Monnam(shkp));
1843                 else
1844 /*JP
1845                     pline("\"%s, you are a thief!\"", plname);
1846 */
1847                     pline("\81u%s\82ß\81C\82¨\82Ü\82¦\82Í\93D\96_\82¾\82È\81I\81v", plname);
1848             } else
1849 /*JP
1850                 You_hear("a scream, \"Thief!\"");
1851 */
1852                 You_hear("\8bà\90Ø\82è\90º\82ð\95·\82¢\82½\81u\93D\96_\81I\81v");
1853             hot_pursuit(shkp);
1854             (void) angry_guards(FALSE);
1855             return;
1856         }
1857         if (ESHK(shkp)->debit > debit) {
1858             long amt = (ESHK(shkp)->debit - debit);
1859 #if 0 /*JP*/
1860             You("owe %s %ld %s for goods lost.", Monnam(shkp), amt,
1861                 currency(amt));
1862 #else
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,
1864                 currency(amt));
1865 #endif
1866         }
1867     }
1868 }
1869
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.
1873  */
1874 boolean
1875 ship_object(otmp, x, y, shop_floor_obj)
1876 xchar x, y;
1877 struct obj *otmp;
1878 boolean shop_floor_obj;
1879 {
1880     schar toloc;
1881     xchar ox, oy;
1882     coord cc;
1883     struct obj *obj;
1884     struct trap *t;
1885     boolean nodrop, unpaid, container, impact = FALSE;
1886     long n = 0L;
1887
1888     if (!otmp)
1889         return FALSE;
1890     if ((toloc = down_gate(x, y)) == MIGR_NOWHERE)
1891         return FALSE;
1892     drop_to(&cc, toloc);
1893     if (!cc.y)
1894         return FALSE;
1895
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));
1900
1901     container = Has_contents(otmp);
1902     unpaid = is_unpaid(otmp);
1903
1904     if (OBJ_AT(x, y)) {
1905         for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
1906             if (obj != otmp)
1907                 n += obj->quan;
1908         if (n)
1909             impact = TRUE;
1910     }
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)) {
1915         if (impact)
1916             impact_drop(otmp, x, y, 0);
1917         return FALSE; /* let caller finish the drop */
1918     }
1919
1920     if (cansee(x, y))
1921         otransit_msg(otmp, nodrop, n);
1922
1923     if (nodrop) {
1924         if (impact)
1925             impact_drop(otmp, x, y, 0);
1926         return FALSE;
1927     }
1928
1929     if (unpaid || shop_floor_obj) {
1930         if (unpaid) {
1931             (void) stolen_value(otmp, u.ux, u.uy, TRUE, FALSE);
1932         } else {
1933             ox = otmp->ox;
1934             oy = otmp->oy;
1935             (void) stolen_value(
1936                 otmp, ox, oy,
1937                 (costly_spot(u.ux, u.uy)
1938                  && index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),
1939                 FALSE);
1940         }
1941         /* set otmp->no_charge to 0 */
1942         if (container)
1943             picked_container(otmp); /* happens to do the right thing */
1944         if (otmp->oclass != COIN_CLASS)
1945             otmp->no_charge = 0;
1946     }
1947
1948     if (otmp->owornmask)
1949         remove_worn_item(otmp, TRUE);
1950
1951     /* some things break rather than ship */
1952     if (breaktest(otmp)) {
1953         const char *result;
1954
1955         if (objects[otmp->otyp].oc_material == GLASS
1956             || otmp->otyp == EXPENSIVE_CAMERA) {
1957             if (otmp->otyp == MIRROR)
1958                 change_luck(-2);
1959 /*JP
1960             result = "crash";
1961 */
1962             result = "\83O\83V\83\83\83b";
1963         } else {
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));
1967 /*JP
1968             result = "splat";
1969 */
1970             result = "\83x\83`\83\83\83b";
1971         }
1972 /*JP
1973         You_hear("a muffled %s.", result);
1974 */
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);
1978         return TRUE;
1979     }
1980
1981     add_to_migration(otmp);
1982     otmp->ox = cc.x;
1983     otmp->oy = cc.y;
1984     otmp->owornmask = (long) toloc;
1985     /* boulder from rolling boulder trap, no longer part of the trap */
1986     if (otmp->otyp == BOULDER)
1987         otmp->otrapped = 0;
1988
1989     if (impact) {
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.
1998          */
1999         impact_drop(otmp, x, y, 0);
2000         newsym(x, y);
2001     }
2002     return TRUE;
2003 }
2004
2005 void
2006 obj_delivery(near_hero)
2007 boolean near_hero;
2008 {
2009     register struct obj *otmp, *otmp2;
2010     register int nx, ny;
2011     int where;
2012     boolean nobreak, noscatter;
2013
2014     for (otmp = migrating_objs; otmp; otmp = otmp2) {
2015         otmp2 = otmp->nobj;
2016         if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel)
2017             continue;
2018
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);
2023
2024         if (!near_hero ^ (where == MIGR_WITH_HERO))
2025             continue;
2026
2027         obj_extract_self(otmp);
2028         otmp->owornmask = 0L;
2029
2030         switch (where) {
2031         case MIGR_STAIRS_UP:
2032             nx = xupstair, ny = yupstair;
2033             break;
2034         case MIGR_LADDER_UP:
2035             nx = xupladder, ny = yupladder;
2036             break;
2037         case MIGR_SSTAIRS:
2038             nx = sstairs.sx, ny = sstairs.sy;
2039             break;
2040         case MIGR_WITH_HERO:
2041             nx = u.ux, ny = u.uy;
2042             break;
2043         default:
2044         case MIGR_RANDOM:
2045             nx = ny = 0;
2046             break;
2047         }
2048         if (nx > 0) {
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))
2053                         continue;
2054                 } else if (breaktest(otmp)) {
2055                     /* assume it broke before player arrived, no messages */
2056                     delobj(otmp);
2057                     continue;
2058                 }
2059             }
2060             stackobj(otmp);
2061             if (!noscatter)
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 */
2069                 delobj(otmp);
2070             }
2071         }
2072     }
2073 }
2074
2075 STATIC_OVL void
2076 otransit_msg(otmp, nodrop, num)
2077 register struct obj *otmp;
2078 register boolean nodrop;
2079 long num;
2080 {
2081     char obuf[BUFSZ];
2082
2083 #if 0 /*JP*/
2084     Sprintf(obuf, "%s%s",
2085             (otmp->otyp == CORPSE && type_is_pname(&mons[otmp->corpsenm]))
2086                 ? ""
2087                 : "The ",
2088             cxname(otmp));
2089 #else
2090     Sprintf(obuf, "%s\82Í", xname(otmp));
2091 #endif
2092
2093     if (num) { /* means: other objects are impacted */
2094 #if 0 /*JP*/
2095         Sprintf(eos(obuf), " %s %s object%s", otense(otmp, "hit"),
2096                 num == 1L ? "another" : "other", num > 1L ? "s" : "");
2097         if (nodrop)
2098             Sprintf(eos(obuf), ".");
2099         else
2100             Sprintf(eos(obuf), " and %s %s.", otense(otmp, "fall"), gate_str);
2101 #else
2102         Sprintf(eos(obuf), "\91¼\82Ì\95¨\91Ì\82É\96½\92\86\82µ\82Ä");
2103         if(nodrop)
2104             Sprintf(eos(obuf), "\8e~\82Ü\82Á\82½\81D");
2105         else
2106             Sprintf(eos(obuf), "%s\97\8e\82¿\82½\81D", gate_str);
2107 #endif
2108         pline1(obuf);
2109     } else if (!nodrop)
2110 /*JP
2111         pline("%s %s %s.", obuf, otense(otmp, "fall"), gate_str);
2112 */
2113         pline("%s%s\97\8e\82¿\82½\81D", obuf, gate_str);
2114 }
2115
2116 /* migration destination for objects which fall down to next level */
2117 schar
2118 down_gate(x, y)
2119 xchar x, y;
2120 {
2121     struct trap *ttmp;
2122
2123     gate_str = 0;
2124     /* this matches the player restriction in goto_level() */
2125     if (on_level(&u.uz, &qstart_level) && !ok_to_quest())
2126         return MIGR_NOWHERE;
2127
2128     if ((xdnstair == x && ydnstair == y)
2129         || (sstairs.sx == x && sstairs.sy == y && !sstairs.up)) {
2130 /*JP
2131         gate_str = "down the stairs";
2132 */
2133         gate_str = "\8aK\92i\82©\82ç";
2134         return (xdnstair == x && ydnstair == y) ? MIGR_STAIRS_UP
2135                                                 : MIGR_SSTAIRS;
2136     }
2137     if (xdnladder == x && ydnladder == y) {
2138 /*JP
2139         gate_str = "down the ladder";
2140 */
2141         gate_str = "\82Í\82µ\82²\82©\82ç";
2142         return MIGR_LADDER_UP;
2143     }
2144
2145     if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen)
2146         && (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)) {
2147 #if 0 /*JP*/
2148         gate_str = (ttmp->ttyp == TRAPDOOR) ? "through the trap door"
2149                                             : "through the hole";
2150 #else
2151         gate_str = (ttmp->ttyp == TRAPDOOR) ? "\97\8e\82µ\94à\82É"
2152                                             : "\8c\8a\82É";
2153 #endif
2154         return MIGR_RANDOM;
2155     }
2156     return MIGR_NOWHERE;
2157 }
2158
2159 /*dokick.c*/