OSDN Git Service

use const
[jnethack/source.git] / src / dokick.c
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. */
4
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. */
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, 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));
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, uarmf, 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, TRUE);
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, uarmf, 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 #if 0 /*JP*/
198         There("is %s here.",
199               canspotmon(mon) ? a_monnam(mon) : "something hidden");
200 #else
201         There("%s\82ª\82¢\82é\81D",
202               canspotmon(mon) ? a_monnam(mon) : "\89½\82©\89B\82ê\82Ä\82¢\82é\82à\82Ì");
203 #endif
204     }
205
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.
211      */
212     if (Upolyd && attacktype(youmonst.data, AT_KICK)) {
213         struct attack *uattk;
214         int sum, kickdieroll, armorpenalty,
215             attknum = 0,
216             tmp = find_roll_to_hit(mon, AT_KICK, (struct obj *) 0, &attknum,
217                                    &armorpenalty);
218
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) */
222             if (multi < 0)
223                 break;
224
225             uattk = &youmonst.data->mattk[i];
226             /* we only care about kicking attacks here */
227             if (uattk->aatyp != AT_KICK)
228                 continue;
229
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 */
233 /*JP
234                 Your("%s %s.", kick_passes_thru, mon_nam(mon));
235 */
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))) {
239 /*JP
240                 You("kick %s.", mon_nam(mon));
241 */
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);
246                 if (sum == 2)
247                     break; /* Defender died */
248             } else {
249                 missum(mon, uattk, (tmp + armorpenalty > kickdieroll));
250                 (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
251             }
252         }
253         return;
254     }
255
256     i = -inv_weight();
257     j = weight_cap();
258
259     if (i < (j * 3) / 10) {
260         if (!rn2((i < j / 10) ? 2 : (i < j / 5) ? 3 : 4)) {
261             if (martial() && !rn2(2))
262                 goto doit;
263 /*JP
264             Your("clumsy kick does no damage.");
265 */
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);
268             return;
269         }
270         if (i < j / 10)
271             clumsy = TRUE;
272         else if (!rn2((i < j / 5) ? 2 : 3))
273             clumsy = TRUE;
274     }
275
276     if (Fumbling)
277         clumsy = TRUE;
278
279     else if (uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
280         clumsy = TRUE;
281 doit:
282 /*JP
283     You("kick %s.", mon_nam(mon));
284 */
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)) {
292 #if 0 /*JP:T*/
293             pline("%s blocks your %skick.", Monnam(mon),
294                   clumsy ? "clumsy " : "");
295 #else
296             pline("%s\82Í\82 \82È\82½\82Ì%s\8fR\82è\82ð\96h\82¢\82¾\81D", Monnam(mon),
297                   clumsy ? "\95s\8aí\97p\82È" : "");
298 #endif
299             (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
300             return;
301         } else {
302             maybe_mnexto(mon);
303             if (mon->mx != x || mon->my != y) {
304                 (void) unmap_invisible(x, y);
305 #if 0 /*JP:T*/
306                 pline("%s %s, %s evading your %skick.", Monnam(mon),
307                       (!level.flags.noteleport && can_teleport(mon->data))
308                           ? "teleports"
309                           : is_floater(mon->data)
310                                 ? "floats"
311                                 : is_flyer(mon->data) ? "swoops"
312                                                       : (nolimbs(mon->data)
313                                                          || slithy(mon->data))
314                                                             ? "slides"
315                                                             : "jumps",
316                       clumsy ? "easily" : "nimbly", clumsy ? "clumsy " : "");
317 #else
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)
322                                 ? "\95\82\82«"
323                                 : is_flyer(mon->data) ? "\82Í\82Î\82½\82«"
324                                                       : (nolimbs(mon->data)
325                                                          || slithy(mon->data))
326                                                             ? "\89¡\82É\8a\8a\82è"
327                                                             : "\92µ\82Ë",
328                       clumsy ? "\8ay\81X\82Æ" : "\91f\91\81\82­", clumsy ? "\95s\8aí\97p\82È" : "");
329 #endif
330                 (void) passive(mon, uarmf, FALSE, 1, AT_KICK, FALSE);
331                 return;
332             }
333         }
334     }
335     kickdmg(mon, clumsy);
336 }
337
338 /*
339  *  Return TRUE if caught (the gold taken care of), FALSE otherwise.
340  *  The gold object is *not* attached to the fobj chain!
341  */
342 boolean
343 ghitm(mtmp, gold)
344 register struct monst *mtmp;
345 register struct obj *gold;
346 {
347     boolean msg_given = FALSE;
348
349     if (!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest
350         && !mtmp->isgd && !is_mercenary(mtmp->data)) {
351         wakeup(mtmp, TRUE);
352     } else if (!mtmp->mcanmove) {
353         /* too light to do real damage */
354         if (canseemon(mtmp)) {
355 #if 0 /*JP:T*/
356             pline_The("%s harmlessly %s %s.", xname(gold),
357                       otense(gold, "hit"), mon_nam(mtmp));
358 #else
359             pline("%s\82Í%s\82É\96½\92\86\82µ\82½\81D", xname(gold),
360                   mon_nam(mtmp));
361 #endif
362             msg_given = TRUE;
363         }
364     } else {
365         long umoney, value = gold->quan * objects[gold->otyp].oc_cost;
366
367         mtmp->msleeping = 0;
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))
373 /*JP
374             pline("%s catches the gold.", Monnam(mtmp));
375 */
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 */
379         if (mtmp->isshk) {
380             long robbed = ESHK(mtmp)->robbed;
381
382             if (robbed) {
383                 robbed -= value;
384                 if (robbed < 0L)
385                     robbed = 0L;
386 #if 0 /*JP*/
387                 pline_The("amount %scovers %s recent losses.",
388                           !robbed ? "" : "partially ", mhis(mtmp));
389 #else
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));
392 #endif
393                 ESHK(mtmp)->robbed = robbed;
394                 if (!robbed)
395                     make_happy_shk(mtmp, FALSE);
396             } else {
397                 if (mtmp->mpeaceful) {
398                     ESHK(mtmp)->credit += value;
399 #if 0 /*JP*/
400                     You("have %ld %s in credit.", ESHK(mtmp)->credit,
401                         currency(ESHK(mtmp)->credit));
402 #else
403                     You("%ld%s\82ð\91Ý\82µ\82É\82µ\82½\81D", ESHK(mtmp)->credit,
404                         currency(ESHK(mtmp)->credit));
405 #endif
406                 } else
407 /*JP
408                     verbalize("Thanks, scum!");
409 */
410                     verbalize("\82 \82è\82ª\82Æ\82æ\81I\82­\82»\82Á\82½\82ê\81I");
411             }
412         } else if (mtmp->ispriest) {
413             if (mtmp->mpeaceful)
414 /*JP
415                 verbalize("Thank you for your contribution.");
416 */
417                 verbalize("\8añ\95t\82É\8a´\8eÓ\82µ\82Ü\82·\81D");
418             else
419 /*JP
420                 verbalize("Thanks, scum!");
421 */
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. */
430 #if 0 /*JP*/
431             verbalize(
432                 umoney
433                     ? "Drop the rest and follow me."
434                     : hidden_gold()
435                           ? "You still have hidden gold.  Drop it now."
436                           : mtmp->mpeaceful
437                                 ? "I'll take care of that; please move along."
438                                 : "I'll take that; now get moving.");
439 #else
440             verbalize(
441                 umoney
442                     ? "\8ec\82è\82ð\92u\82¢\82Ä\82Â\82¢\82Ä\82«\82È\82³\82¢\81D"
443                     : hidden_gold()
444                           ? "\82Ü\82¾\8bà\82ð\89B\82µ\82Ä\82¢\82é\82È\81D\92u\82«\82È\82³\82¢\81D"
445                           : mtmp->mpeaceful
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");
448 #endif
449         } else if (is_mercenary(mtmp->data)) {
450             long goldreqd = 0L;
451
452             if (rn2(3)) {
453                 if (mtmp->data == &mons[PM_SOLDIER])
454                     goldreqd = 100L;
455                 else if (mtmp->data == &mons[PM_SERGEANT])
456                     goldreqd = 250L;
457                 else if (mtmp->data == &mons[PM_LIEUTENANT])
458                     goldreqd = 500L;
459                 else if (mtmp->data == &mons[PM_CAPTAIN])
460                     goldreqd = 750L;
461
462                 if (goldreqd) {
463                     umoney = money_cnt(invent);
464                     if (value
465                         > goldreqd
466                               + (umoney + u.ulevel * rn2(5)) / ACURR(A_CHA))
467                         mtmp->mpeaceful = TRUE;
468                 }
469             }
470             if (mtmp->mpeaceful)
471 /*JP
472                 verbalize("That should do.  Now beat it!");
473 */
474                 verbalize("\82È\82ñ\82¾\82¢\81H\82±\82ê\82Í\81H");
475             else
476 /*JP
477                 verbalize("That's not enough, coward!");
478 */
479                 verbalize("\82»\82ñ\82È\82à\82Ì\82Å\8dÏ\82Þ\82©\81C\94Ú\8b¯\8eÒ\81I");
480         }
481         return TRUE;
482     }
483
484     if (!msg_given)
485         miss(xname(gold), mtmp);
486     return FALSE;
487 }
488
489 /* container is kicked, dropped, thrown or otherwise impacted by player.
490  * Assumes container is on floor.  Checks contents for possible damage. */
491 void
492 container_impact_dmg(obj, x, y)
493 struct obj *obj;
494 xchar x, y; /* coordinates where object was before the impact, not after */
495 {
496     struct monst *shkp;
497     struct obj *otmp, *otmp2;
498     long loss = 0L;
499     boolean costly, insider, frominv;
500
501     /* only consider normal containers */
502     if (!Is_container(obj) || !Has_contents(obj) || Is_mbag(obj))
503         return;
504
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);
511
512     for (otmp = obj->cobj; otmp; otmp = otmp2) {
513         const char *result = (char *) 0;
514
515         otmp2 = otmp->nobj;
516         if (objects[otmp->otyp].oc_material == GLASS
517             && otmp->oclass != GEM_CLASS && !obj_resists(otmp, 33, 100)) {
518 /*JP
519             result = "shatter";
520 */
521             result = "\83K\83`\83\83\83\93";
522         } else if (otmp->otyp == EGG && !rn2(3)) {
523 /*JP
524             result = "cracking";
525 */
526             result = "\83O\83V\83\83\83b";
527         }
528         if (result) {
529             if (otmp->otyp == MIRROR)
530                 change_luck(-2);
531
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)
535                 change_luck(-1);
536 /*JP
537             You_hear("a muffled %s.", result);
538 */
539             You_hear("\82±\82à\82Á\82½%s\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D", result);
540             if (costly) {
541                 if (frominv && !otmp->unpaid)
542                     otmp->no_charge = 1;
543                 loss +=
544                     stolen_value(otmp, x, y, (boolean) shkp->mpeaceful, TRUE);
545             }
546             if (otmp->quan > 1L) {
547                 useup(otmp);
548             } else {
549                 obj_extract_self(otmp);
550                 obfree(otmp, (struct obj *) 0);
551             }
552             /* contents of this container are no longer known */
553             obj->cknown = 0;
554         }
555     }
556     if (costly && loss) {
557         if (!insider) {
558 /*JP
559             You("caused %ld %s worth of damage!", loss, currency(loss));
560 */
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);
563         } else {
564 #if 0 /*JP*/
565             You("owe %s %ld %s for objects destroyed.", mon_nam(shkp), loss,
566                 currency(loss));
567 #else
568             You("\8aí\95¨\94j\91¹\82Å%s\82É%ld%s\82Ì\8eØ\82è\82ð\82Â\82­\82Á\82½\81D", mon_nam(shkp), loss,
569                 currency(loss));
570 #endif
571         }
572     }
573 }
574
575 /* jacket around really_kick_object */
576 STATIC_OVL int
577 kick_object(x, y, kickobjnam)
578 xchar x, y;
579 char *kickobjnam;
580 {
581     int res = 0;
582
583     *kickobjnam = '\0';
584     /* if a pile, the "top" object gets kicked */
585     kickedobj = level.objects[x][y];
586     if (kickedobj) {
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;
591     }
592     return res;
593 }
594
595 /* guts of kick_object */
596 STATIC_OVL int
597 really_kick_object(x, y)
598 xchar x, y;
599 {
600     int range;
601     struct monst *mon, *shkp = 0;
602     struct trap *trap;
603     char bhitroom;
604     boolean costly, isgold, slide = FALSE;
605
606     /* kickedobj should always be set due to conditions of call */
607     if (!kickedobj || kickedobj->otyp == BOULDER || kickedobj == uball
608         || kickedobj == uchain)
609         return 0;
610
611     if ((trap = t_at(x, y)) != 0) {
612         if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !Passes_walls)
613             || trap->ttyp == WEB) {
614             if (!trap->tseen)
615                 find_trap(trap);
616 #if 0 /*JP:T*/
617             You_cant("kick %s that's in a %s!", something,
618                      Hallucination ? "tizzy" :
619                      (trap->ttyp == WEB) ? "web" : "pit");
620 #else
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",
624                 something);
625 #endif
626             return 1;
627         }
628         if (trap->ttyp == STATUE_TRAP) {
629             activate_statue_trap(trap, x,y, FALSE);
630             return 1;
631         }
632     }
633
634     if (Fumbling && !rn2(3)) {
635 /*JP
636         Your("clumsy kick missed.");
637 */
638         Your("\95s\8aí\97p\82È\8fR\82è\82Í\8aO\82ê\82½\81D");
639         return 1;
640     }
641
642     if (!uarmf && kickedobj->otyp == CORPSE
643         && touch_petrifies(&mons[kickedobj->corpsenm]) && !Stone_resistance) {
644 #if 0 /*JP*/
645         You("kick %s with your bare %s.",
646             corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE),
647             makeplural(body_part(FOOT)));
648 #else
649         You("\91f%s\82Å%s\82ð\8fR\82Á\82½\81D",
650             body_part(FOOT),
651             corpse_xname(kickedobj, (const char *) 0, CXN_PFX_THE));
652 #endif
653         if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
654             ; /* hero has been transformed but kick continues */
655         } else {
656             /* normalize body shape here; foot, not body_part(FOOT) */
657 /*JP
658             Sprintf(killer.name, "kicking %s barefoot",
659 */
660             Sprintf(killer.name, "\8cC\96³\82µ\82Å%s\82ð\8fR\82Á\82Ä",
661                     killer_xname(kickedobj));
662             instapetrify(killer.name);
663         }
664     }
665
666     /* range < 2 means the object will not move.  */
667     /* maybe dexterity should also figure here.   */
668     range = (int) ((ACURRSTR) / 2 - kickedobj->owt / 40);
669
670     if (martial())
671         range += rnd(3);
672
673     if (is_pool(x, y)) {
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 */
678         range += rnd(3);
679     } else {
680         if (is_ice(x, y))
681             range += rnd(3), slide = TRUE;
682         if (kickedobj->greased)
683             range += rnd(3), slide = TRUE;
684     }
685
686     /* Mjollnir is magically too heavy to kick */
687     if (kickedobj->oartifact == ART_MJOLLNIR)
688         range = 1;
689
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))
693         range = 1;
694
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);
699
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)) {
703             if (Blind)
704 /*JP
705                 pline("It doesn't come loose.");
706 */
707                 pline("\82Ñ\82­\82Æ\82à\82µ\82È\82¢\81D");
708             else
709 #if 0 /*JP*/
710                 pline("%s %sn't come loose.",
711                       The(distant_name(kickedobj, xname)),
712                       otense(kickedobj, "do"));
713 #else
714                 pline("%s\82Í\82Ñ\82­\82Æ\82à\82µ\82È\82¢\81D",
715                       distant_name(kickedobj, xname));
716 #endif
717             return (!rn2(3) || martial());
718         }
719         if (Blind)
720 /*JP
721             pline("It comes loose.");
722 */
723             pline("\89½\82©\82ª\8aÉ\82ñ\82Å\82Æ\82ê\82½\81D");
724         else
725 #if 0 /*JP*/
726             pline("%s %s loose.", The(distant_name(kickedobj, xname)),
727                   otense(kickedobj, "come"));
728 #else
729             pline("%s\82Í\8aÉ\82ñ\82Å\82Æ\82ê\82½\81D", distant_name(kickedobj, xname));
730 #endif
731         obj_extract_self(kickedobj);
732         newsym(x, y);
733         if (costly && (!costly_spot(u.ux, u.uy)
734                        || !index(u.urooms, *in_rooms(x, y, SHOPBASE))))
735             addtobill(kickedobj, FALSE, FALSE, FALSE);
736 /*JP
737         if (!flooreffects(kickedobj, u.ux, u.uy, "fall")) {
738 */
739         if (!flooreffects(kickedobj, u.ux, u.uy, "\97\8e\82¿\82é")) {
740             place_object(kickedobj, u.ux, u.uy);
741             stackobj(kickedobj);
742             newsym(u.ux, u.uy);
743         }
744         return 1;
745     }
746
747     /* a box gets a chance of breaking open here */
748     if (Is_box(kickedobj)) {
749         boolean otrp = kickedobj->otrapped;
750
751         if (range < 2)
752 /*JP
753             pline("THUD!");
754 */
755             pline("\83K\83\93\81I");
756         container_impact_dmg(kickedobj, x, y);
757         if (kickedobj->olocked) {
758             if (!rn2(5) || (martial() && !rn2(2))) {
759 /*JP
760                 You("break open the lock!");
761 */
762                 You("\8c®\82ð\89ó\82µ\8aJ\82¯\82½\81I");
763                 breakchestlock(kickedobj, FALSE);
764                 if (otrp)
765                     (void) chest_trap(kickedobj, LEG, FALSE);
766                 return 1;
767             }
768         } else {
769             if (!rn2(3) || (martial() && !rn2(2))) {
770 /*JP
771                 pline_The("lid slams open, then falls shut.");
772 */
773                 pline("\8aW\82ª\82Î\82½\82ñ\82Æ\8aJ\82«\81C\95Â\82\82½\81D");
774                 kickedobj->lknown = 1;
775                 if (otrp)
776                     (void) chest_trap(kickedobj, LEG, FALSE);
777                 return 1;
778             }
779         }
780         if (range < 2)
781             return 1;
782         /* else let it fall through to the next cases... */
783     }
784
785     /* fragile objects should not be kicked */
786     if (hero_breaks(kickedobj, kickedobj->ox, kickedobj->oy, FALSE))
787         return 1;
788
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
792      */
793     if (range < 2) {
794         if (!Is_box(kickedobj))
795 /*JP
796             pline("Thump!");
797 */
798             pline("\83S\83c\83\93\81I");
799         return (!rn2(3) || martial());
800     }
801
802     if (kickedobj->quan > 1L) {
803         if (!isgold) {
804             kickedobj = splitobj(kickedobj, 1L);
805         } else {
806             if (rn2(20)) {
807 #if 0 /*JP*/
808                 static NEARDATA const char *const flyingcoinmsg[] = {
809                     "scatter the coins", "knock coins all over the place",
810                     "send coins flying in all directions",
811                 };
812 #else
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½",
816                 };
817 #endif
818
819 /*JP
820                 pline("Thwwpingg!");
821 */
822                 pline("\83K\83V\83\83\81[\83\93\81I");
823 /*JP
824                 You("%s!", flyingcoinmsg[rn2(SIZE(flyingcoinmsg))]);
825 */
826                 You("%s\81I", flyingcoinmsg[rn2(SIZE(flyingcoinmsg))]);
827                 (void) scatter(x, y, rn2(3) + 1, VIS_EFFECTS | MAY_HIT,
828                                kickedobj);
829                 newsym(x, y);
830                 return 1;
831             }
832             if (kickedobj->quan > 300L) {
833 /*JP
834                 pline("Thump!");
835 */
836                 pline("\83S\83c\83\93\81I");
837                 return (!rn2(3) || martial());
838             }
839         }
840     }
841
842     if (slide && !Blind)
843 #if 0 /*JP*/
844         pline("Whee!  %s %s across the %s.", Doname2(kickedobj),
845               otense(kickedobj, "slide"), surface(x, y));
846 #else
847         pline("\83Y\83\8b\83b\81I%s\82Í%s\82Ì\8fã\82ð\8a\8a\82Á\82½\81D", Doname2(kickedobj),
848               surface(x,y));
849 #endif
850
851     if (costly && !isgold)
852         addtobill(kickedobj, FALSE, FALSE, TRUE);
853     obj_extract_self(kickedobj);
854     (void) snuff_candle(kickedobj);
855     newsym(x, y);
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);
859     if (!kickedobj)
860         return 1; /* object broken */
861
862     if (mon) {
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? */
869             return 1;
870     }
871
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)
875         return 1;
876
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)) {
880         if (isgold)
881             costly_gold(x, y, kickedobj->quan);
882         else
883             (void) stolen_value(kickedobj, x, y, (boolean) shkp->mpeaceful,
884                                 FALSE);
885     }
886
887 /*JP
888     if (flooreffects(kickedobj, bhitpos.x, bhitpos.y, "fall"))
889 */
890     if(flooreffects(kickedobj, bhitpos.x, bhitpos.y, "\97\8e\82¿\82é"))
891         return 1;
892     if (kickedobj->unpaid)
893         subfrombill(kickedobj, shkp);
894     place_object(kickedobj, bhitpos.x, bhitpos.y);
895     stackobj(kickedobj);
896     newsym(kickedobj->ox, kickedobj->oy);
897     return 1;
898 }
899
900 /* cause of death if kicking kills kicker */
901 STATIC_OVL char *
902 kickstr(buf, kickobjnam)
903 char *buf;
904 const char *kickobjnam;
905 {
906     const char *what;
907
908     if (*kickobjnam)
909         what = kickobjnam;
910     else if (maploc == &nowhere)
911 /*JP
912         what = "nothing";
913 */
914         what = "\89½\82à\82È\82¢\82Æ\82±\82ë";
915     else if (IS_DOOR(maploc->typ))
916 /*JP
917         what = "a door";
918 */
919         what = "\94à";
920     else if (IS_TREE(maploc->typ))
921 /*JP
922         what = "a tree";
923 */
924         what = "\96Ø";
925     else if (IS_STWALL(maploc->typ))
926 /*JP
927         what = "a wall";
928 */
929         what = "\95Ç";
930     else if (IS_ROCK(maploc->typ))
931 /*JP
932         what = "a rock";
933 */
934         what = "\8aâ";
935     else if (IS_THRONE(maploc->typ))
936 /*JP
937         what = "a throne";
938 */
939         what = "\8bÊ\8dÀ";
940     else if (IS_FOUNTAIN(maploc->typ))
941 /*JP
942         what = "a fountain";
943 */
944         what = "\90ò";
945     else if (IS_GRAVE(maploc->typ))
946 /*JP
947         what = "a headstone";
948 */
949         what = "\95æ\90Î";
950     else if (IS_SINK(maploc->typ))
951 /*JP
952         what = "a sink";
953 */
954         what = "\97¬\82µ\91ä";
955     else if (IS_ALTAR(maploc->typ))
956 /*JP
957         what = "an altar";
958 */
959         what = "\8dÕ\92d";
960     else if (IS_DRAWBRIDGE(maploc->typ))
961 /*JP
962         what = "a drawbridge";
963 */
964         what = "\92µ\82Ë\8b´";
965     else if (maploc->typ == STAIRS)
966 /*JP
967         what = "the stairs";
968 */
969         what = "\8aK\92i";
970     else if (maploc->typ == LADDER)
971 /*JP
972         what = "a ladder";
973 */
974         what = "\82Í\82µ\82²";
975     else if (maploc->typ == IRONBARS)
976 /*JP
977         what = "an iron bar";
978 */
979         what = "\93S\96_";
980     else
981 /*JP
982         what = "something weird";
983 */
984         what = "\89½\82©\96­\82È\82à\82Ì";
985 #if 0 /*JP*/
986     return strcat(strcpy(buf, "kicking "), what);
987 #else
988     Sprintf(buf, "%s\82ð\8fR\82Á\82Ä", what);
989     return buf;
990 #endif
991 }
992
993 int
994 dokick()
995 {
996     int x, y;
997     int avrg_attrib;
998     int dmg = 0, glyph, oldglyph = -1;
999     register struct monst *mtmp;
1000     boolean no_kick = FALSE;
1001     char buf[BUFSZ], kickobjnam[BUFSZ];
1002
1003     kickobjnam[0] = '\0';
1004     if (nolimbs(youmonst.data) || slithy(youmonst.data)) {
1005 /*JP
1006         You("have no legs to kick with.");
1007 */
1008         You("\89½\82©\82ð\8fR\82ë\82¤\82É\82à\91«\82ª\82È\82¢\81D");
1009         no_kick = TRUE;
1010     } else if (verysmall(youmonst.data)) {
1011 /*JP
1012         You("are too small to do any kicking.");
1013 */
1014         You("\89½\82©\82ð\8fR\82é\82É\82Í\8f¬\82³\82·\82¬\82é\81D");
1015         no_kick = TRUE;
1016     } else if (u.usteed) {
1017 /*JP
1018         if (yn_function("Kick your steed?", ynchars, 'y') == 'y') {
1019 */
1020         if (yn_function("\94n\82ð\8fR\82é\81H", ynchars, 'y') == 'y') {
1021 /*JP
1022             You("kick %s.", mon_nam(u.usteed));
1023 */
1024             You("%s\82ð\8fR\82Á\82½\81D", mon_nam(u.usteed));
1025             kick_steed();
1026             return 1;
1027         } else {
1028             return 0;
1029         }
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);
1034
1035         if (wl == BOTH_SIDES)
1036             bp = makeplural(bp);
1037 #if 0 /*JP*/
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");
1041 #else
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" : "",
1044              bp);
1045 #endif
1046         no_kick = TRUE;
1047     } else if (near_capacity() > SLT_ENCUMBER) {
1048 /*JP
1049         Your("load is too heavy to balance yourself for a kick.");
1050 */
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");
1052         no_kick = TRUE;
1053     } else if (youmonst.data->mlet == S_LIZARD) {
1054 /*JP
1055         Your("legs cannot kick effectively.");
1056 */
1057         Your("\91«\82Å\82Í\82¤\82Ü\82­\8fR\82ê\82È\82¢\81D");
1058         no_kick = TRUE;
1059     } else if (u.uinwater && !rn2(2)) {
1060 /*JP
1061         Your("slow motion kick doesn't hit anything.");
1062 */
1063         Your("\92x\82¢\93®\82«\82Ì\8fR\82è\82Å\82Í\96½\92\86\82µ\82æ\82¤\82ª\82È\82¢\81D");
1064         no_kick = TRUE;
1065     } else if (u.utrap) {
1066         no_kick = TRUE;
1067         switch (u.utraptype) {
1068         case TT_PIT:
1069             if (!Passes_walls)
1070 /*JP
1071                 pline("There's not enough room to kick down here.");
1072 */
1073                 pline("\97\8e\82µ\8c\8a\82É\82Í\82Ü\82Á\82Ä\82¢\82é\82Ì\82Å\81C\8fR\82ê\82È\82¢\81D");
1074             else
1075                 no_kick = FALSE;
1076             break;
1077         case TT_WEB:
1078         case TT_BEARTRAP:
1079 /*JP
1080             You_cant("move your %s!", body_part(LEG));
1081 */
1082             You("%s\82ð\93®\82©\82·\82±\82Æ\82ª\82Å\82«\82È\82¢\81I", body_part(LEG));
1083             break;
1084         default:
1085             break;
1086         }
1087     }
1088
1089     if (no_kick) {
1090         /* ignore direction typed before player notices kick failed */
1091         display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1092         return 0;
1093     }
1094
1095     if (!getdir((char *) 0))
1096         return 0;
1097     if (!u.dx && !u.dy)
1098         return 0;
1099
1100     x = u.ux + u.dx;
1101     y = u.uy + u.dy;
1102
1103     /* KMH -- Kicking boots always succeed */
1104     if (uarmf && uarmf->otyp == KICKING_BOOTS)
1105         avrg_attrib = 99;
1106     else
1107         avrg_attrib = (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3;
1108
1109     if (u.uswallow) {
1110         switch (rn2(3)) {
1111         case 0:
1112 /*JP
1113             You_cant("move your %s!", body_part(LEG));
1114 */
1115             You("%s\82ð\93®\82©\82·\82±\82Æ\82ª\82Å\82«\82È\82¢\81I", body_part(LEG));
1116             break;
1117         case 1:
1118             if (is_animal(u.ustuck->data)) {
1119 /*JP
1120                 pline("%s burps loudly.", Monnam(u.ustuck));
1121 */
1122                 pline("%s\82Í\91å\82«\82È\83Q\83b\83v\82ð\82µ\82½\81D", Monnam(u.ustuck));
1123                 break;
1124             }
1125             /*FALLTHRU*/
1126         default:
1127 /*JP
1128             Your("feeble kick has no effect.");
1129 */
1130             Your("\8eã\81X\82µ\82¢\8fR\82è\82Í\8cø\89Ê\82ª\82È\82¢\81D"); break;
1131             break;
1132         }
1133         return 1;
1134     } else if (u.utrap && u.utraptype == TT_PIT) {
1135         /* must be Passes_walls */
1136 /*JP
1137         You("kick at the side of the pit.");
1138 */
1139         You("\97\8e\82µ\8c\8a\82Ì\95Ç\82ð\8fR\82Á\82½\81D");
1140         return 1;
1141     }
1142     if (Levitation) {
1143         int xx, yy;
1144
1145         xx = u.ux - u.dx;
1146         yy = u.uy - u.dy;
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?
1150          */
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))) {
1154 /*JP
1155             You("have nothing to brace yourself against.");
1156 */
1157             pline("\8ex\82¦\82É\82Å\82«\82é\82æ\82¤\82È\82à\82Ì\82ª\96³\82¢\81D");
1158             return 0;
1159         }
1160     }
1161
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 */
1167     if (mtmp) {
1168         oldglyph = glyph_at(x, y);
1169         if (!maybe_kick_monster(mtmp, x, y))
1170             return context.move;
1171     }
1172
1173     wake_nearby();
1174     u_wipe_engr(2);
1175
1176     if (!isok(x, y)) {
1177         maploc = &nowhere;
1178         goto ouch;
1179     }
1180     maploc = &levl[x][y];
1181
1182     /*
1183      * The next five tests should stay in their present order:
1184      * monsters, pools, objects, non-doors, doors.
1185      *
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.]
1193      */
1194
1195     if (mtmp) {
1196         /* save mtmp->data (for recoil) in case mtmp gets killed */
1197         struct permonst *mdat = mtmp->data;
1198
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);
1215         }
1216         /* recoil if floating */
1217         if ((Is_airlevel(&u.uz) || Levitation) && context.move) {
1218             int range;
1219
1220             range =
1221                 ((int) youmonst.data->cwt + (weight_cap() + inv_weight()));
1222             if (range < 1)
1223                 range = 1; /* divide by zero avoidance */
1224             range = (3 * (int) mdat->cwt) / range;
1225
1226             if (range < 1)
1227                 range = 1;
1228             hurtle(-u.dx, -u.dy, range, TRUE);
1229         }
1230         return 1;
1231     }
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 */
1235 /*JP
1236         You("splash some %s around.", hliquid("water"));
1237 */
1238         You("%s\82ð\89ñ\82è\82É\82Ü\82«\82¿\82ç\82µ\82½\81D", hliquid("water"));
1239         return 1;
1240     }
1241
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 */
1247             return 1;
1248         }
1249         goto ouch;
1250     }
1251
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 */
1256 #if 0 /*JP*/
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"
1262                           : "You kick open");
1263 #else
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
1266                           ? "\94­\8c©\82µ"
1267                           : "\8fR\82è\8aJ\82¯");
1268 #endif
1269                 exercise(A_DEX, TRUE);
1270                 if (maploc->doormask & D_TRAPPED) {
1271                     maploc->doormask = D_NODOOR;
1272 /*JP
1273                     b_trapped("door", FOOT);
1274 */
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 */
1283                 return 1;
1284             } else
1285                 goto ouch;
1286         }
1287         if (maploc->typ == SCORR) {
1288             if (!Levitation && rn2(30) < avrg_attrib) {
1289 /*JP
1290                 pline("Crash!  You kick open a secret passage!");
1291 */
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);
1294                 maploc->typ = CORR;
1295                 feel_newsym(x, y); /* we know it's gone */
1296                 unblock_point(x, y); /* vision */
1297                 return 1;
1298             } else
1299                 goto ouch;
1300         }
1301         if (IS_THRONE(maploc->typ)) {
1302             register int i;
1303             if (Levitation)
1304                 goto dumb;
1305             if ((Luck < 0 || maploc->doormask) && !rn2(3)) {
1306                 maploc->typ = ROOM;
1307                 maploc->doormask = 0; /* don't leave loose ends.. */
1308                 (void) mkgold((long) rnd(200), x, y);
1309                 if (Blind)
1310 /*JP
1311                     pline("CRASH!  You destroy it.");
1312 */
1313                     pline("\83K\83V\83\83\83\93\81I\82 \82È\82½\82Í\89½\82©\82ð\94j\89ó\82µ\82½\81D");
1314                 else {
1315 /*JP
1316                     pline("CRASH!  You destroy the throne.");
1317 */
1318                     pline("\83K\83V\83\83\83\93\81I\82 \82È\82½\82Í\8bÊ\8dÀ\82ð\94j\89ó\82µ\82½\81D");
1319                     newsym(x, y);
1320                 }
1321                 exercise(A_DEX, TRUE);
1322                 return 1;
1323             } else if (Luck > 0 && !rn2(3) && !maploc->looted) {
1324                 (void) mkgold((long) rn1(201, 300), x, y);
1325                 i = Luck + 1;
1326                 if (i > 6)
1327                     i = 6;
1328                 while (i--)
1329                     (void) mksobj_at(
1330                         rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE - 1), x, y,
1331                         FALSE, TRUE);
1332                 if (Blind)
1333 /*JP
1334                     You("kick %s loose!", something);
1335 */
1336                     You("\82È\82É\82©\82ð\8fR\82è\8eU\82ç\82µ\82½\81I");
1337                 else {
1338 /*JP
1339                     You("kick loose some ornamental coins and gems!");
1340 */
1341                     You("\91\95\8fü\97p\82Ì\8bà\89Ý\82â\95ó\90Î\82ð\8fR\82è\8eU\82ç\82µ\82½\81I");
1342                     newsym(x, y);
1343                 }
1344                 /* prevent endless milking */
1345                 maploc->looted = T_LOOTED;
1346                 return 1;
1347             } else if (!rn2(4)) {
1348                 if (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) {
1349                     fall_through(FALSE);
1350                     return 1;
1351                 } else
1352                     goto ouch;
1353             }
1354             goto ouch;
1355         }
1356         if (IS_ALTAR(maploc->typ)) {
1357             if (Levitation)
1358                 goto dumb;
1359 /*JP
1360             You("kick %s.", (Blind ? something : "the altar"));
1361 */
1362             You("%s\82ð\8fR\82Á\82½\81D", (Blind ? "\89½\82©" : "\8dÕ\92d"));
1363             if (!rn2(3))
1364                 goto ouch;
1365             altar_wrath(x, y);
1366             exercise(A_DEX, TRUE);
1367             return 1;
1368         }
1369         if (IS_FOUNTAIN(maploc->typ)) {
1370             if (Levitation)
1371                 goto dumb;
1372 /*JP
1373             You("kick %s.", (Blind ? something : "the fountain"));
1374 */
1375             You("%s\82ð\8fR\82Á\82½\81D",(Blind ? "\89½\82©" : "\90ò"));
1376             if (!rn2(3))
1377                 goto ouch;
1378             /* make metal boots rust */
1379             if (uarmf && rn2(3))
1380 /*JP
1381                 if (water_damage(uarmf, "metal boots", TRUE) == ER_NOTHING) {
1382 */
1383                 if (water_damage(uarmf, "\8bà\91®\82Ì\8cC", TRUE) == ER_NOTHING) {
1384 /*JP
1385                     Your("boots get wet.");
1386 */
1387                     Your("\8cC\82Í\94G\82ê\82½\81D");
1388                     /* could cause short-lived fumbling here */
1389                 }
1390             exercise(A_DEX, TRUE);
1391             return 1;
1392         }
1393         if (IS_GRAVE(maploc->typ)) {
1394             if (Levitation)
1395                 goto dumb;
1396             if (rn2(4))
1397                 goto ouch;
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));
1402             }
1403             maploc->typ = ROOM;
1404             maploc->doormask = 0;
1405             (void) mksobj_at(ROCK, x, y, TRUE, FALSE);
1406             del_engr_at(x, y);
1407             if (Blind)
1408 #if 0 /*JP*/
1409                 pline("Crack!  %s broke!", Something);
1410 #else
1411                 pline("\83S\83c\83\93\81I\89½\82©\82ª\89ó\82ê\82½\81I");
1412 #endif
1413             else {
1414 /*JP
1415                 pline_The("headstone topples over and breaks!");
1416 */
1417                 pline("\95æ\90Î\82Í\93|\82ê\82Ä\89ó\82ê\82½\81I");
1418                 newsym(x, y);
1419             }
1420             return 1;
1421         }
1422         if (maploc->typ == IRONBARS)
1423             goto ouch;
1424         if (IS_TREE(maploc->typ)) {
1425             struct obj *treefruit;
1426
1427             /* nothing, fruit or trouble? 75:23.5:1.5% */
1428             if (rn2(3)) {
1429                 if (!rn2(6) && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
1430 #if 0 /*JP*/
1431                     You_hear("a low buzzing."); /* a warning */
1432 #else
1433                     You_hear("\82Ô\81[\82ñ\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D"); /* a warning */
1434 #endif
1435                 goto ouch;
1436             }
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;
1441
1442                 treefruit->quan = nfruit;
1443                 treefruit->owt = weight(treefruit);
1444                 if (is_plural(treefruit))
1445 /*JP
1446                     pline("Some %s fall from the tree!", xname(treefruit));
1447 */
1448                     pline("%s\82ª\89½\8cÂ\82©\96Ø\82©\82ç\97\8e\82¿\82Ä\82«\82½\81I", xname(treefruit));
1449                 else
1450 /*JP
1451                     pline("%s falls from the tree!", An(xname(treefruit)));
1452 */
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;
1460 #if 0 /*JP*/
1461                     pline("%ld %s got caught in the branches.",
1462                           nfruit - nfall, xname(treefruit));
1463 #else
1464                     pline("%ld\8cÂ\82Ì%s\82ª\8e}\82É\82Ð\82Á\82©\82©\82Á\82½\81D",
1465                           nfruit - nfall, xname(treefruit));
1466 #endif
1467                     dealloc_obj(treefruit);
1468                 }
1469                 exercise(A_DEX, TRUE);
1470                 exercise(A_WIS, TRUE); /* discovered a new food source! */
1471                 newsym(x, y);
1472                 maploc->looted |= TREE_LOOTED;
1473                 return 1;
1474             } else if (!(maploc->looted & TREE_SWARM)) {
1475                 int cnt = rnl(4) + 2;
1476                 int made = 0;
1477                 coord mm;
1478
1479                 mm.x = x;
1480                 mm.y = y;
1481                 while (cnt--) {
1482                     if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE])
1483                         && makemon(&mons[PM_KILLER_BEE], mm.x, mm.y,
1484                                    MM_ANGRY))
1485                         made++;
1486                 }
1487                 if (made)
1488 /*JP
1489                     pline("You've attracted the tree's former occupants!");
1490 */
1491                     pline("\96Ø\82Ì\90æ\8fZ\96¯\82ð\8bN\82±\82µ\82Ä\82µ\82Ü\82Á\82½\81I");
1492                 else
1493 /*JP
1494                     You("smell stale honey.");
1495 */
1496                     pline("\8cÃ\82¢\82Í\82¿\82Ý\82Â\82Ì\82É\82¨\82¢\82ª\82µ\82½\81D");
1497                 maploc->looted |= TREE_SWARM;
1498                 return 1;
1499             }
1500             goto ouch;
1501         }
1502         if (IS_SINK(maploc->typ)) {
1503             int gend = poly_gender();
1504             short washerndx = (gend == 1 || (gend == 2 && rn2(2)))
1505                                   ? PM_INCUBUS
1506                                   : PM_SUCCUBUS;
1507
1508             if (Levitation)
1509                 goto dumb;
1510             if (rn2(5)) {
1511                 if (!Deaf)
1512 /*JP
1513                     pline("Klunk!  The pipes vibrate noisily.");
1514 */
1515                     pline("\83K\83\89\83\93\81I\83p\83C\83v\82Í\82¤\82é\82³\82­\90U\93®\82µ\82½\81D");
1516                 else
1517 /*JP
1518                     pline("Klunk!");
1519 */
1520                     pline("\83K\83\89\83\93\81I");
1521                 exercise(A_DEX, TRUE);
1522                 return 1;
1523             } else if (!(maploc->looted & S_LPUDDING) && !rn2(3)
1524                        && !(mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) {
1525                 if (Blind)
1526 /*JP
1527                     You_hear("a gushing sound.");
1528 */
1529                     You_hear("\82È\82É\82©\82ª\95¬\8fo\82·\82é\89¹\82ð\95·\82¢\82½\81D");
1530                 else
1531 /*JP
1532                     pline("A %s ooze gushes up from the drain!",
1533 */
1534                     pline("%s\89t\91Ì\82ª\94r\90\85\8cû\82©\82ç\82É\82\82Ý\8fo\82½\81I",
1535                           hcolor(NH_BLACK));
1536                 (void) makemon(&mons[PM_BLACK_PUDDING], x, y, NO_MM_FLAGS);
1537                 exercise(A_DEX, TRUE);
1538                 newsym(x, y);
1539                 maploc->looted |= S_LPUDDING;
1540                 return 1;
1541             } else if (!(maploc->looted & S_LDWASHER) && !rn2(3)
1542                        && !(mvitals[washerndx].mvflags & G_GONE)) {
1543                 /* can't resist... */
1544 /*JP
1545                 pline("%s returns!", (Blind ? Something : "The dish washer"));
1546 */
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))
1549                     newsym(x, y);
1550                 maploc->looted |= S_LDWASHER;
1551                 exercise(A_DEX, TRUE);
1552                 return 1;
1553             } else if (!rn2(3)) {
1554 #if 0 /*JP*/
1555                 pline("Flupp!  %s.",
1556                       (Blind ? "You hear a sloshing sound"
1557                              : "Muddy waste pops up from the drain"));
1558 #else
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é"));
1562 #endif
1563                 if (!(maploc->looted & S_LRING)) { /* once per sink */
1564                     if (!Blind)
1565 /*JP
1566                         You_see("a ring shining in its midst.");
1567 */
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);
1570                     newsym(x, y);
1571                     exercise(A_DEX, TRUE);
1572                     exercise(A_WIS, TRUE); /* a discovery! */
1573                     maploc->looted |= S_LRING;
1574                 }
1575                 return 1;
1576             }
1577             goto ouch;
1578         }
1579         if (maploc->typ == STAIRS || maploc->typ == LADDER
1580             || IS_STWALL(maploc->typ)) {
1581             if (!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN)
1582                 goto dumb;
1583         ouch:
1584 /*JP
1585             pline("Ouch!  That hurts!");
1586 */
1587             pline("\82¢\82Ä\82Á\81I\89ö\89ä\82µ\82½\81I");
1588             exercise(A_DEX, FALSE);
1589             exercise(A_STR, FALSE);
1590             if (isok(x, y)) {
1591                 if (Blind)
1592                     feel_location(x, y); /* we know we hit it */
1593                 if (is_drawbridge_wall(x, y) >= 0) {
1594 /*JP
1595                     pline_The("drawbridge is unaffected.");
1596 */
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];
1601                 }
1602             }
1603             if (!rn2(3))
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 */
1609             return 1;
1610         }
1611         goto dumb;
1612     }
1613
1614     if (maploc->doormask == D_ISOPEN || maploc->doormask == D_BROKEN
1615         || maploc->doormask == D_NODOOR) {
1616     dumb:
1617         exercise(A_DEX, FALSE);
1618         if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
1619 /*JP
1620             You("kick at empty space.");
1621 */
1622             You("\89½\82à\82È\82¢\8bó\8aÔ\82ð\8fR\82Á\82½\81D");
1623             if (Blind)
1624                 feel_location(x, y);
1625         } else {
1626 /*JP
1627             pline("Dumb move!  You strain a muscle.");
1628 */
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));
1632         }
1633         if ((Is_airlevel(&u.uz) || Levitation) && rn2(2))
1634             hurtle(-u.dx, -u.dy, 1, TRUE);
1635         return 1; /* uses a turn */
1636     }
1637
1638     /* not enough leverage to kick open doors while levitating */
1639     if (Levitation)
1640         goto ouch;
1641
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) {
1648             if (flags.verbose)
1649 /*JP
1650                 You("kick the door.");
1651 */
1652                 You("\94à\82ð\8fR\82Á\82½\81D");
1653             exercise(A_STR, FALSE);
1654             maploc->doormask = D_NODOOR;
1655 /*JP
1656             b_trapped("door", FOOT);
1657 */
1658             b_trapped("\94à", FOOT);
1659         } else if (ACURR(A_STR) > 18 && !rn2(5) && !shopdoor) {
1660 /*JP
1661             pline("As you kick the door, it shatters to pieces!");
1662 */
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;
1666         } else {
1667 /*JP
1668             pline("As you kick the door, it crashes open!");
1669 */
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;
1673         }
1674         feel_newsym(x, y); /* we know we broke it */
1675         unblock_point(x, y); /* vision */
1676         if (shopdoor) {
1677             add_damage(x, y, SHOP_DOOR_COST);
1678 /*JP
1679             pay_for_damage("break", FALSE);
1680 */
1681             pay_for_damage("\94j\89ó\82·\82é", FALSE);
1682         }
1683         if (in_town(x, y))
1684             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1685                 if (DEADMONSTER(mtmp))
1686                     continue;
1687                 if (is_watch(mtmp->data) && couldsee(mtmp->mx, mtmp->my)
1688                     && mtmp->mpeaceful) {
1689 /*JP
1690                     mon_yells(mtmp, "Halt, thief!  You're under arrest!");
1691 */
1692                     mon_yells(mtmp, "\8e~\82Ü\82ê\93D\96_\81I\82¨\82Ü\82¦\82ð\91ß\95ß\82·\82é\81I");
1693                     (void) angry_guards(FALSE);
1694                     break;
1695                 }
1696             }
1697     } else {
1698         if (Blind)
1699             feel_location(x, y); /* we know we hit it */
1700         exercise(A_STR, TRUE);
1701 /*JP
1702         pline("WHAMMM!!!");
1703 */
1704         pline("\82®\82\9f\82\9f\82\9f\82ñ\81I");
1705         if (in_town(x, y))
1706             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1707                 if (DEADMONSTER(mtmp))
1708                     continue;
1709                 if (is_watch(mtmp->data) && mtmp->mpeaceful
1710                     && couldsee(mtmp->mx, mtmp->my)) {
1711                     if (levl[x][y].looted & D_WARNED) {
1712                         mon_yells(mtmp,
1713 /*JP
1714                                   "Halt, vandal!  You're under arrest!");
1715 */
1716                                   "\8e~\82Ü\82ê\96ì\94Ø\90l\81I\82¨\82Ü\82¦\82ð\91ß\95ß\82·\82é\81I");
1717                         (void) angry_guards(FALSE);
1718                     } else {
1719 /*JP
1720                         mon_yells(mtmp, "Hey, stop damaging that door!");
1721 */
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;
1724                     }
1725                     break;
1726                 }
1727             }
1728     }
1729     return 1;
1730 }
1731
1732 STATIC_OVL void
1733 drop_to(cc, loc)
1734 coord *cc;
1735 schar loc;
1736 {
1737     /* cover all the MIGR_xxx choices generated by down_gate() */
1738     switch (loc) {
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;
1743             break;
1744         } else if (In_endgame(&u.uz) || Is_botlevel(&u.uz)) {
1745             cc->y = cc->x = 0;
1746             break;
1747         }
1748         /*FALLTHRU*/
1749     case MIGR_STAIRS_UP:
1750     case MIGR_LADDER_UP:
1751         cc->x = u.uz.dnum;
1752         cc->y = u.uz.dlevel + 1;
1753         break;
1754     case MIGR_SSTAIRS:
1755         cc->x = sstairs.tolev.dnum;
1756         cc->y = sstairs.tolev.dlevel;
1757         break;
1758     default:
1759     case MIGR_NOWHERE:
1760         /* y==0 means "nowhere", in which case x doesn't matter */
1761         cc->y = cc->x = 0;
1762         break;
1763     }
1764 }
1765
1766 /* player or missile impacts location, causing objects to fall down */
1767 void
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 */
1772 {
1773     schar toloc;
1774     register struct obj *obj, *obj2;
1775     register struct monst *shkp;
1776     long oct, dct, price, debit, robbed;
1777     boolean angry, costly, isrock;
1778     coord cc;
1779
1780     if (!OBJ_AT(x, y))
1781         return;
1782
1783     toloc = down_gate(x, y);
1784     drop_to(&cc, toloc);
1785     if (!cc.y)
1786         return;
1787
1788     if (dlev) {
1789         /* send objects next to player falling through trap door.
1790          * checked in obj_delivery().
1791          */
1792         toloc = MIGR_WITH_HERO;
1793         cc.y = dlev;
1794     }
1795
1796     costly = costly_spot(x, y);
1797     price = debit = robbed = 0L;
1798     angry = FALSE;
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.
1805      */
1806     if (costly) {
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;
1811         }
1812     }
1813
1814     isrock = (missile && missile->otyp == ROCK);
1815     oct = dct = 0L;
1816     for (obj = level.objects[x][y]; obj; obj = obj2) {
1817         obj2 = obj->nexthere;
1818         if (obj == missile)
1819             continue;
1820         /* number of objects in the pile */
1821         oct += obj->quan;
1822         if (obj == uball || obj == uchain)
1823             continue;
1824         /* boulders can fall too, but rarely & never due to rocks */
1825         if ((isrock && obj->otyp == BOULDER)
1826             || rn2(obj->otyp == BOULDER ? 30 : 3))
1827             continue;
1828         obj_extract_self(obj);
1829
1830         if (costly) {
1831             price += stolen_value(
1832                 obj, x, y, (costly_spot(u.ux, u.uy)
1833                             && index(u.urooms, *in_rooms(x, y, SHOPBASE))),
1834                 TRUE);
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)
1839                 obj->no_charge = 0;
1840         }
1841
1842         add_to_migration(obj);
1843         obj->ox = cc.x;
1844         obj->oy = cc.y;
1845         obj->owornmask = (long) toloc;
1846
1847         /* number of fallen objects */
1848         dct += obj->quan;
1849     }
1850
1851     if (dct && cansee(x, y)) { /* at least one object fell */
1852 /*JP
1853         const char *what = (dct == 1L ? "object falls" : "objects fall");
1854 */
1855         const char *what = "\95¨";
1856
1857         if (missile)
1858 #if 0 /*JP:T*/
1859             pline("From the impact, %sother %s.",
1860                   dct == oct ? "the " : dct == 1L ? "an" : "", what);
1861 #else
1862             pline("\8fÕ\8c\82\82Å\81C\91¼\82Ì%s\82ª\97\8e\82¿\82½\81D",what);
1863 #endif
1864         else if (oct == dct)
1865 #if 0 /*JP:T*/
1866             pline("%s adjacent %s %s.", dct == 1L ? "The" : "All the", what,
1867                   gate_str);
1868 #else
1869             pline("\8bß\82­\82É\82 \82Á\82½%s\82ª%s\97\8e\82¿\82½\81D", what, gate_str);
1870 #endif
1871         else
1872 #if 0 /*JP*/
1873             pline("%s adjacent %s %s.",
1874                   dct == 1L ? "One of the" : "Some of the",
1875                   dct == 1L ? "objects falls" : what, gate_str);
1876 #else
1877             pline("\8bß\82­\82É\82 \82Á\82½%s%s%s\97\8e\82¿\82½\81D",
1878                   what,
1879                   dct == 1L ? "\82ª" : "\82Ì\82¢\82­\82Â\82©\82ª",
1880                   gate_str);
1881 #endif
1882     }
1883
1884     if (costly && shkp && price) {
1885         if (ESHK(shkp)->robbed > robbed) {
1886 /*JP
1887             You("removed %ld %s worth of goods!", price, currency(price));
1888 */
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);
1893                 if (angry)
1894 /*JP
1895                     pline("%s is infuriated!", Monnam(shkp));
1896 */
1897                     pline("%s\82Í\8c\83\93{\82µ\82½\81I", Monnam(shkp));
1898                 else
1899 /*JP
1900                     pline("\"%s, you are a thief!\"", plname);
1901 */
1902                     pline("\81u%s\82ß\81C\82¨\82Ü\82¦\82Í\93D\96_\82¾\82È\81I\81v", plname);
1903             } else
1904 /*JP
1905                 You_hear("a scream, \"Thief!\"");
1906 */
1907                 You_hear("\8bà\90Ø\82è\90º\82ð\95·\82¢\82½\81u\93D\96_\81I\81v");
1908             hot_pursuit(shkp);
1909             (void) angry_guards(FALSE);
1910             return;
1911         }
1912         if (ESHK(shkp)->debit > debit) {
1913             long amt = (ESHK(shkp)->debit - debit);
1914 #if 0 /*JP*/
1915             You("owe %s %ld %s for goods lost.", Monnam(shkp), amt,
1916                 currency(amt));
1917 #else
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,
1919                 currency(amt));
1920 #endif
1921         }
1922     }
1923 }
1924
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.
1928  */
1929 boolean
1930 ship_object(otmp, x, y, shop_floor_obj)
1931 xchar x, y;
1932 struct obj *otmp;
1933 boolean shop_floor_obj;
1934 {
1935     schar toloc;
1936     xchar ox, oy;
1937     coord cc;
1938     struct obj *obj;
1939     struct trap *t;
1940     boolean nodrop, unpaid, container, impact = FALSE;
1941     long n = 0L;
1942
1943     if (!otmp)
1944         return FALSE;
1945     if ((toloc = down_gate(x, y)) == MIGR_NOWHERE)
1946         return FALSE;
1947     drop_to(&cc, toloc);
1948     if (!cc.y)
1949         return FALSE;
1950
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));
1955
1956     container = Has_contents(otmp);
1957     unpaid = is_unpaid(otmp);
1958
1959     if (OBJ_AT(x, y)) {
1960         for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
1961             if (obj != otmp)
1962                 n += obj->quan;
1963         if (n)
1964             impact = TRUE;
1965     }
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)) {
1970         if (impact)
1971             impact_drop(otmp, x, y, 0);
1972         return FALSE; /* let caller finish the drop */
1973     }
1974
1975     if (cansee(x, y))
1976         otransit_msg(otmp, nodrop, n);
1977
1978     if (nodrop) {
1979         if (impact)
1980             impact_drop(otmp, x, y, 0);
1981         return FALSE;
1982     }
1983
1984     if (unpaid || shop_floor_obj) {
1985         if (unpaid) {
1986             (void) stolen_value(otmp, u.ux, u.uy, TRUE, FALSE);
1987         } else {
1988             ox = otmp->ox;
1989             oy = otmp->oy;
1990             (void) stolen_value(
1991                 otmp, ox, oy,
1992                 (costly_spot(u.ux, u.uy)
1993                  && index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),
1994                 FALSE);
1995         }
1996         /* set otmp->no_charge to 0 */
1997         if (container)
1998             picked_container(otmp); /* happens to do the right thing */
1999         if (otmp->oclass != COIN_CLASS)
2000             otmp->no_charge = 0;
2001     }
2002
2003     if (otmp->owornmask)
2004         remove_worn_item(otmp, TRUE);
2005
2006     /* some things break rather than ship */
2007     if (breaktest(otmp)) {
2008         const char *result;
2009
2010         if (objects[otmp->otyp].oc_material == GLASS
2011             || otmp->otyp == EXPENSIVE_CAMERA) {
2012             if (otmp->otyp == MIRROR)
2013                 change_luck(-2);
2014 /*JP
2015             result = "crash";
2016 */
2017             result = "\83O\83V\83\83\83b";
2018         } else {
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));
2022 /*JP
2023             result = "splat";
2024 */
2025             result = "\83x\83`\83\83\83b";
2026         }
2027 /*JP
2028         You_hear("a muffled %s.", result);
2029 */
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);
2033         return TRUE;
2034     }
2035
2036     add_to_migration(otmp);
2037     otmp->ox = cc.x;
2038     otmp->oy = cc.y;
2039     otmp->owornmask = (long) toloc;
2040     /* boulder from rolling boulder trap, no longer part of the trap */
2041     if (otmp->otyp == BOULDER)
2042         otmp->otrapped = 0;
2043
2044     if (impact) {
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.
2053          */
2054         impact_drop(otmp, x, y, 0);
2055         newsym(x, y);
2056     }
2057     return TRUE;
2058 }
2059
2060 void
2061 obj_delivery(near_hero)
2062 boolean near_hero;
2063 {
2064     register struct obj *otmp, *otmp2;
2065     register int nx, ny;
2066     int where;
2067     boolean nobreak, noscatter;
2068
2069     for (otmp = migrating_objs; otmp; otmp = otmp2) {
2070         otmp2 = otmp->nobj;
2071         if (otmp->ox != u.uz.dnum || otmp->oy != u.uz.dlevel)
2072             continue;
2073
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);
2078
2079         if (!near_hero ^ (where == MIGR_WITH_HERO))
2080             continue;
2081
2082         obj_extract_self(otmp);
2083         otmp->owornmask = 0L;
2084
2085         switch (where) {
2086         case MIGR_STAIRS_UP:
2087             nx = xupstair, ny = yupstair;
2088             break;
2089         case MIGR_LADDER_UP:
2090             nx = xupladder, ny = yupladder;
2091             break;
2092         case MIGR_SSTAIRS:
2093             nx = sstairs.sx, ny = sstairs.sy;
2094             break;
2095         case MIGR_WITH_HERO:
2096             nx = u.ux, ny = u.uy;
2097             break;
2098         default:
2099         case MIGR_RANDOM:
2100             nx = ny = 0;
2101             break;
2102         }
2103         if (nx > 0) {
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))
2108                         continue;
2109                 } else if (breaktest(otmp)) {
2110                     /* assume it broke before player arrived, no messages */
2111                     delobj(otmp);
2112                     continue;
2113                 }
2114             }
2115             stackobj(otmp);
2116             if (!noscatter)
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 */
2124                 delobj(otmp);
2125             }
2126         }
2127     }
2128 }
2129
2130 STATIC_OVL void
2131 otransit_msg(otmp, nodrop, num)
2132 register struct obj *otmp;
2133 register boolean nodrop;
2134 long num;
2135 {
2136     char obuf[BUFSZ];
2137
2138 #if 0 /*JP*/
2139     Sprintf(obuf, "%s%s",
2140             (otmp->otyp == CORPSE && type_is_pname(&mons[otmp->corpsenm]))
2141                 ? ""
2142                 : "The ",
2143             cxname(otmp));
2144 #else
2145     Sprintf(obuf, "%s\82Í", xname(otmp));
2146 #endif
2147
2148     if (num) { /* means: other objects are impacted */
2149 #if 0 /*JP*/
2150         Sprintf(eos(obuf), " %s %s object%s", otense(otmp, "hit"),
2151                 num == 1L ? "another" : "other", num > 1L ? "s" : "");
2152         if (nodrop)
2153             Sprintf(eos(obuf), ".");
2154         else
2155             Sprintf(eos(obuf), " and %s %s.", otense(otmp, "fall"), gate_str);
2156 #else
2157         Sprintf(eos(obuf), "\91¼\82Ì\95¨\91Ì\82É\96½\92\86\82µ\82Ä");
2158         if(nodrop)
2159             Sprintf(eos(obuf), "\8e~\82Ü\82Á\82½\81D");
2160         else
2161             Sprintf(eos(obuf), "%s\97\8e\82¿\82½\81D", gate_str);
2162 #endif
2163         pline1(obuf);
2164     } else if (!nodrop)
2165 /*JP
2166         pline("%s %s %s.", obuf, otense(otmp, "fall"), gate_str);
2167 */
2168         pline("%s%s\97\8e\82¿\82½\81D", obuf, gate_str);
2169 }
2170
2171 /* migration destination for objects which fall down to next level */
2172 schar
2173 down_gate(x, y)
2174 xchar x, y;
2175 {
2176     struct trap *ttmp;
2177
2178     gate_str = 0;
2179     /* this matches the player restriction in goto_level() */
2180     if (on_level(&u.uz, &qstart_level) && !ok_to_quest())
2181         return MIGR_NOWHERE;
2182
2183     if ((xdnstair == x && ydnstair == y)
2184         || (sstairs.sx == x && sstairs.sy == y && !sstairs.up)) {
2185 /*JP
2186         gate_str = "down the stairs";
2187 */
2188         gate_str = "\8aK\92i\82©\82ç";
2189         return (xdnstair == x && ydnstair == y) ? MIGR_STAIRS_UP
2190                                                 : MIGR_SSTAIRS;
2191     }
2192     if (xdnladder == x && ydnladder == y) {
2193 /*JP
2194         gate_str = "down the ladder";
2195 */
2196         gate_str = "\82Í\82µ\82²\82©\82ç";
2197         return MIGR_LADDER_UP;
2198     }
2199
2200     if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen)
2201         && (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)) {
2202 #if 0 /*JP*/
2203         gate_str = (ttmp->ttyp == TRAPDOOR) ? "through the trap door"
2204                                             : "through the hole";
2205 #else
2206         gate_str = (ttmp->ttyp == TRAPDOOR) ? "\97\8e\82µ\94à\82É"
2207                                             : "\8c\8a\82É";
2208 #endif
2209         return MIGR_RANDOM;
2210     }
2211     return MIGR_NOWHERE;
2212 }
2213
2214 /*dokick.c*/