OSDN Git Service

fix indent
[jnethack/source.git] / src / dothrow.c
1 /* NetHack 3.6  dothrow.c       $NHDT-Date: 1556201496 2019/04/25 14:11:36 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.160 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* Contains code for 't' (throw) */
7
8 /* JNetHack Copyright */
9 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
10 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
11 /* JNetHack may be freely redistributed.  See license for details. */
12
13 #include "hack.h"
14
15 STATIC_DCL int FDECL(throw_obj, (struct obj *, int));
16 STATIC_DCL boolean FDECL(ok_to_throw, (int *));
17 STATIC_DCL void NDECL(autoquiver);
18 STATIC_DCL int FDECL(gem_accept, (struct monst *, struct obj *));
19 STATIC_DCL void FDECL(tmiss, (struct obj *, struct monst *, BOOLEAN_P));
20 STATIC_DCL int FDECL(throw_gold, (struct obj *));
21 STATIC_DCL void FDECL(check_shop_obj, (struct obj *, XCHAR_P, XCHAR_P,
22                                        BOOLEAN_P));
23 STATIC_DCL void FDECL(breakmsg, (struct obj *, BOOLEAN_P));
24 STATIC_DCL boolean FDECL(toss_up, (struct obj *, BOOLEAN_P));
25 STATIC_DCL void FDECL(sho_obj_return_to_u, (struct obj * obj));
26 STATIC_DCL boolean FDECL(mhurtle_step, (genericptr_t, int, int));
27
28 static NEARDATA const char toss_objs[] = { ALLOW_COUNT, COIN_CLASS,
29                                            ALL_CLASSES, WEAPON_CLASS, 0 };
30 /* different default choices when wielding a sling (gold must be included) */
31 static NEARDATA const char bullets[] = { ALLOW_COUNT, COIN_CLASS, ALL_CLASSES,
32                                          GEM_CLASS, 0 };
33
34 /* thrownobj (decl.c) tracks an object until it lands */
35
36 extern boolean notonhead; /* for long worms */
37
38 /* Throw the selected object, asking for direction */
39 STATIC_OVL int
40 throw_obj(obj, shotlimit)
41 struct obj *obj;
42 int shotlimit;
43 {
44     struct obj *otmp;
45     int multishot;
46     schar skill;
47     long wep_mask;
48     boolean twoweap, weakmultishot;
49
50     /* ask "in what direction?" */
51     if (!getdir((char *) 0)) {
52         /* No direction specified, so cancel the throw;
53          * might need to undo an object split.
54          * We used to use freeinv(obj),addinv(obj) here, but that can
55          * merge obj into another stack--usually quiver--even if it hadn't
56          * been split from there (possibly triggering a panic in addinv),
57          * and freeinv+addinv potentially has other side-effects.
58          */
59         if (obj->o_id == context.objsplit.parent_oid
60             || obj->o_id == context.objsplit.child_oid)
61             (void) unsplitobj(obj);
62         return 0; /* no time passes */
63     }
64
65     /*
66      * Throwing money is usually for getting rid of it when
67      * a leprechaun approaches, or for bribing an oncoming
68      * angry monster.  So throw the whole object.
69      *
70      * If the money is in quiver, throw one coin at a time,
71      * possibly using a sling.
72      */
73     if (obj->oclass == COIN_CLASS && obj != uquiver)
74         return throw_gold(obj);
75
76 /*JP
77     if (!canletgo(obj, "throw"))
78 */
79     if (!canletgo(obj, "\93\8a\82°\82é"))
80         return 0;
81     if (obj->oartifact == ART_MJOLLNIR && obj != uwep) {
82 /*JP
83         pline("%s must be wielded before it can be thrown.", The(xname(obj)));
84 */
85         pline("\93\8a\82°\82é\91O\82É%s\82ð\91\95\94õ\82µ\82È\82­\82Ä\82Í\82È\82ç\82È\82¢\81D", xname(obj));
86         return 0;
87     }
88     if ((obj->oartifact == ART_MJOLLNIR && ACURR(A_STR) < STR19(25))
89         || (obj->otyp == BOULDER && !throws_rocks(youmonst.data))) {
90 /*JP
91         pline("It's too heavy.");
92 */
93         pline("\8fd\82·\82¬\82Ä\93\8a\82°\82ç\82ê\82È\82¢\81D");
94         return 1;
95     }
96     if (!u.dx && !u.dy && !u.dz) {
97 /*JP
98         You("cannot throw an object at yourself.");
99 */
100         pline("\8e©\95ª\82É\8cü\82©\82Á\82Ä\82Í\93\8a\82°\82ç\82ê\82È\82¢\81D");
101         return 0;
102     }
103     u_wipe_engr(2);
104     if (!uarmg && obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])
105         && !Stone_resistance) {
106 #if 0 /*JP*/
107         You("throw %s with your bare %s.",
108             corpse_xname(obj, (const char *) 0, CXN_PFX_THE),
109             /* throwing with one hand, but pluralize since the
110                expression "with your bare hands" sounds better */
111             makeplural(body_part(HAND)));
112 #else
113         You("\91f%s\82Å%s\82Ì\8e\80\91Ì\82ð\93\8a\82°\82½\81D",
114             body_part(HAND),
115             corpse_xname(obj, (const char *) 0, CXN_PFX_THE));
116 #endif
117 /*JP
118         Sprintf(killer.name, "throwing %s bare-handed", killer_xname(obj));
119 */
120         Sprintf(killer.name, "%s\82Ì\8e\80\91Ì\82ð\91f\8eè\82Å\93\8a\82°\82Ä", killer_xname(obj));
121         instapetrify(killer.name);
122     }
123     if (welded(obj)) {
124         weldmsg(obj);
125         return 1;
126     }
127     if (is_wet_towel(obj))
128         dry_a_towel(obj, -1, FALSE);
129
130     /* Multishot calculations
131      * (potential volley of up to N missiles; default for N is 1)
132      */
133     multishot = 1;
134     skill = objects[obj->otyp].oc_skill;
135     if (obj->quan > 1L /* no point checking if there's only 1 */
136         /* ammo requires corresponding launcher be wielded */
137         && (is_ammo(obj) ? matching_launcher(obj, uwep)
138                          /* otherwise any stackable (non-ammo) weapon */
139                          : obj->oclass == WEAPON_CLASS)
140         && !(Confusion || Stunned)) {
141         /* some roles don't get a volley bonus until becoming expert */
142         weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_PRIEST)
143                          || (Role_if(PM_HEALER) && skill != P_KNIFE)
144                          || (Role_if(PM_TOURIST) && skill != -P_DART)
145                          /* poor dexterity also inhibits multishot */
146                          || Fumbling || ACURR(A_DEX) <= 6);
147
148         /* Bonus if the player is proficient in this weapon... */
149         switch (P_SKILL(weapon_type(obj))) {
150         case P_EXPERT:
151             multishot++;
152         /*FALLTHRU*/
153         case P_SKILLED:
154             if (!weakmultishot)
155                 multishot++;
156             break;
157         default: /* basic or unskilled: no bonus */
158             break;
159         }
160         /* ...or is using a special weapon for their role... */
161         switch (Role_switch) {
162         case PM_CAVEMAN:
163             /* give bonus for low-tech gear */
164             if (skill == -P_SLING || skill == P_SPEAR)
165                 multishot++;
166             break;
167         case PM_MONK:
168             /* allow higher volley count despite skill limitation */
169             if (skill == -P_SHURIKEN)
170                 multishot++;
171             break;
172         case PM_RANGER:
173             /* arbitrary; encourage use of other missiles beside daggers */
174             if (skill != P_DAGGER)
175                 multishot++;
176             break;
177         case PM_ROGUE:
178             /* possibly should add knives... */
179             if (skill == P_DAGGER)
180                 multishot++;
181             break;
182         case PM_SAMURAI:
183             /* role-specific launcher and its ammo */
184             if (obj->otyp == YA && uwep && uwep->otyp == YUMI)
185                 multishot++;
186             break;
187         default:
188             break; /* No bonus */
189         }
190         /* ...or using their race's special bow; no bonus for spears */
191         if (!weakmultishot)
192             switch (Race_switch) {
193             case PM_ELF:
194                 if (obj->otyp == ELVEN_ARROW && uwep
195                     && uwep->otyp == ELVEN_BOW)
196                     multishot++;
197                 break;
198             case PM_ORC:
199                 if (obj->otyp == ORCISH_ARROW && uwep
200                     && uwep->otyp == ORCISH_BOW)
201                     multishot++;
202                 break;
203             case PM_GNOME:
204                 /* arbitrary; there isn't any gnome-specific gear */
205                 if (skill == -P_CROSSBOW)
206                     multishot++;
207                 break;
208             case PM_HUMAN:
209             case PM_DWARF:
210             default:
211                 break; /* No bonus */
212             }
213
214         /* crossbows are slow to load and probably shouldn't allow multiple
215            shots at all, but that would result in players never using them;
216            instead, high strength is necessary to load and shoot quickly */
217         if (multishot > 1 && skill == -P_CROSSBOW
218             && ammo_and_launcher(obj, uwep)
219             && (int) ACURRSTR < (Race_if(PM_GNOME) ? 16 : 18))
220             multishot = rnd(multishot);
221
222         multishot = rnd(multishot);
223         if ((long) multishot > obj->quan)
224             multishot = (int) obj->quan;
225         if (shotlimit > 0 && multishot > shotlimit)
226             multishot = shotlimit;
227     }
228
229     m_shot.s = ammo_and_launcher(obj, uwep) ? TRUE : FALSE;
230     /* give a message if shooting more than one, or if player
231        attempted to specify a count */
232     if (multishot > 1 || shotlimit > 0) {
233         /* "You shoot N arrows." or "You throw N daggers." */
234 #if 0 /*JP*/
235         You("%s %d %s.", m_shot.s ? "shoot" : "throw",
236             multishot, /* (might be 1 if player gave shotlimit) */
237             (multishot == 1) ? singular(obj, xname) : xname(obj));
238 #else
239         You("%d%s\82Ì%s\82ð%s\81D",
240             multishot,
241             numeral(obj), xname(obj),
242             m_shot.s ? "\8c\82\82Á\82½" : "\93\8a\82°\82½");
243 #endif
244     }
245
246     wep_mask = obj->owornmask;
247     m_shot.o = obj->otyp;
248     m_shot.n = multishot;
249     for (m_shot.i = 1; m_shot.i <= m_shot.n; m_shot.i++) {
250         twoweap = u.twoweap;
251         /* split this object off from its slot if necessary */
252         if (obj->quan > 1L) {
253             otmp = splitobj(obj, 1L);
254         } else {
255             otmp = obj;
256             if (otmp->owornmask)
257                 remove_worn_item(otmp, FALSE);
258         }
259         freeinv(otmp);
260         throwit(otmp, wep_mask, twoweap);
261     }
262     m_shot.n = m_shot.i = 0;
263     m_shot.o = STRANGE_OBJECT;
264     m_shot.s = FALSE;
265
266     return 1;
267 }
268
269 /* common to dothrow() and dofire() */
270 STATIC_OVL boolean
271 ok_to_throw(shotlimit_p)
272 int *shotlimit_p; /* (see dothrow()) */
273 {
274     /* kludge to work around parse()'s pre-decrement of `multi' */
275     *shotlimit_p = (multi || save_cm) ? multi + 1 : 0;
276     multi = 0; /* reset; it's been used up */
277
278     if (notake(youmonst.data)) {
279 /*JP
280         You("are physically incapable of throwing or shooting anything.");
281 */
282         You("\89½\82©\82ð\93\8a\82°\82é\82Ì\82Í\95¨\97\9d\93I\82É\96³\97\9d\82¾\81D");
283         return FALSE;
284     } else if (nohands(youmonst.data)) {
285 #if 0 /*JP*/
286         You_cant("throw or shoot without hands."); /* not body_part(HAND) */
287 #else
288         You("\8eè\82ª\82È\82¢\81D"); /* not body_part(HAND) */
289 #endif
290         return FALSE;
291         /*[what about !freehand(), aside from cursed missile launcher?]*/
292     }
293     if (check_capacity((char *) 0))
294         return FALSE;
295     return TRUE;
296 }
297
298 /* t command - throw */
299 int
300 dothrow()
301 {
302     register struct obj *obj;
303     int shotlimit;
304
305     /*
306      * Since some characters shoot multiple missiles at one time,
307      * allow user to specify a count prefix for 'f' or 't' to limit
308      * number of items thrown (to avoid possibly hitting something
309      * behind target after killing it, or perhaps to conserve ammo).
310      *
311      * Prior to 3.3.0, command ``3t'' meant ``t(shoot) t(shoot) t(shoot)''
312      * and took 3 turns.  Now it means ``t(shoot at most 3 missiles)''.
313      *
314      * [3.6.0:  shot count setup has been moved into ok_to_throw().]
315      */
316     if (!ok_to_throw(&shotlimit))
317         return 0;
318
319     obj = getobj(uslinging() ? bullets : toss_objs, "throw");
320     /* it is also possible to throw food */
321     /* (or jewels, or iron balls... ) */
322
323     return obj ? throw_obj(obj, shotlimit) : 0;
324 }
325
326 /* KMH -- Automatically fill quiver */
327 /* Suggested by Jeffrey Bay <jbay@convex.hp.com> */
328 static void
329 autoquiver()
330 {
331     struct obj *otmp, *oammo = 0, *omissile = 0, *omisc = 0, *altammo = 0;
332
333     if (uquiver)
334         return;
335
336     /* Scan through the inventory */
337     for (otmp = invent; otmp; otmp = otmp->nobj) {
338         if (otmp->owornmask || otmp->oartifact || !otmp->dknown) {
339             ; /* Skip it */
340         } else if (otmp->otyp == ROCK
341                    /* seen rocks or known flint or known glass */
342                    || (otmp->otyp == FLINT
343                        && objects[otmp->otyp].oc_name_known)
344                    || (otmp->oclass == GEM_CLASS
345                        && objects[otmp->otyp].oc_material == GLASS
346                        && objects[otmp->otyp].oc_name_known)) {
347             if (uslinging())
348                 oammo = otmp;
349             else if (ammo_and_launcher(otmp, uswapwep))
350                 altammo = otmp;
351             else if (!omisc)
352                 omisc = otmp;
353         } else if (otmp->oclass == GEM_CLASS) {
354             ; /* skip non-rock gems--they're ammo but
355                  player has to select them explicitly */
356         } else if (is_ammo(otmp)) {
357             if (ammo_and_launcher(otmp, uwep))
358                 /* Ammo matched with launcher (bow+arrow, crossbow+bolt) */
359                 oammo = otmp;
360             else if (ammo_and_launcher(otmp, uswapwep))
361                 altammo = otmp;
362             else
363                 /* Mismatched ammo (no better than an ordinary weapon) */
364                 omisc = otmp;
365         } else if (is_missile(otmp)) {
366             /* Missile (dart, shuriken, etc.) */
367             omissile = otmp;
368         } else if (otmp->oclass == WEAPON_CLASS && throwing_weapon(otmp)) {
369             /* Ordinary weapon */
370             if (objects[otmp->otyp].oc_skill == P_DAGGER && !omissile)
371                 omissile = otmp;
372             else
373                 omisc = otmp;
374         }
375     }
376
377     /* Pick the best choice */
378     if (oammo)
379         setuqwep(oammo);
380     else if (omissile)
381         setuqwep(omissile);
382     else if (altammo)
383         setuqwep(altammo);
384     else if (omisc)
385         setuqwep(omisc);
386
387     return;
388 }
389
390 /* f command -- fire: throw from the quiver */
391 int
392 dofire()
393 {
394     int shotlimit;
395     struct obj *obj;
396
397     /*
398      * Same as dothrow(), except we use quivered missile instead
399      * of asking what to throw/shoot.
400      *
401      * If quiver is empty, we use autoquiver to fill it when the
402      * corresponding option is on.  If the option is off or if
403      * autoquiver doesn't select anything, we ask what to throw.
404      * Then we put the chosen item into the quiver slot unless
405      * it is already in another slot.  [Matters most if it is a
406      * stack but also matters for single item if this throw gets
407      * aborted (ESC at the direction prompt).  Already wielded
408      * item is excluded because wielding might be necessary
409      * (Mjollnir) or make the throw behave differently (aklys),
410      * and alt-wielded item is excluded because switching slots
411      * would end two-weapon combat even if throw gets aborted.]
412      */
413     if (!ok_to_throw(&shotlimit))
414         return 0;
415
416     if ((obj = uquiver) == 0) {
417         if (!flags.autoquiver) {
418 /*JP
419             You("have no ammunition readied.");
420 */
421             You("\94­\8eË\8f\80\94õ\82ª\90®\82Á\82Ä\82¢\82È\82¢\81I");
422         } else {
423             autoquiver();
424             if ((obj = uquiver) == 0)
425 /*JP
426                 You("have nothing appropriate for your quiver.");
427 */
428                 You("\94­\8eË\82·\82é\82à\82Ì\82ª\82È\82¢\81D");
429         }
430         /* if autoquiver is disabled or has failed, prompt for missile;
431            fill quiver with it if it's not wielded or worn */
432         if (!obj) {
433             /* in case we're using ^A to repeat prior 'f' command, don't
434                use direction of previous throw as getobj()'s choice here */
435             in_doagain = 0;
436             /* choose something from inventory, then usually quiver it */
437             obj = getobj(uslinging() ? bullets : toss_objs, "throw");
438             /* Q command doesn't allow gold in quiver */
439             if (obj && !obj->owornmask && obj->oclass != COIN_CLASS)
440                 setuqwep(obj); /* demi-autoquiver */
441         }
442         /* give feedback if quiver has now been filled */
443         if (uquiver) {
444             uquiver->owornmask &= ~W_QUIVER; /* less verbose */
445 /*JP
446             prinv("You ready:", uquiver, 0L);
447 */
448             prinv("\8f\80\94õ\81F", uquiver, 0L);
449             uquiver->owornmask |= W_QUIVER;
450         }
451     }
452
453     return obj ? throw_obj(obj, shotlimit) : 0;
454 }
455
456 /* if in midst of multishot shooting/throwing, stop early */
457 void
458 endmultishot(verbose)
459 boolean verbose;
460 {
461     if (m_shot.i < m_shot.n) {
462         if (verbose && !context.mon_moving) {
463 #if 0 /*JP*/
464             You("stop %s after the %d%s %s.",
465                 m_shot.s ? "firing" : "throwing", m_shot.i, ordin(m_shot.i),
466                 m_shot.s ? "shot" : "toss");
467 #else
468             You("%d\94­\96Ú\82ð%s\82Æ\82±\82ë\82Å\8ec\82è\82ð%s\82Ì\82ð\82â\82ß\82½\81D", m_shot.i,
469                 m_shot.s ? "\8c\82\82Á\82½" : "\93\8a\82°\82½",
470                 m_shot.s ? "\8c\82\82Â" : "\93\8a\82°\82é");
471 #endif
472         }
473         m_shot.n = m_shot.i; /* make current shot be the last */
474     }
475 }
476
477 /* Object hits floor at hero's feet.
478    Called from drop(), throwit(), hold_another_object(). */
479 void
480 hitfloor(obj, verbosely)
481 struct obj *obj;
482 boolean verbosely; /* usually True; False if caller has given drop message */
483 {
484     if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater || u.uswallow) {
485         dropy(obj);
486         return;
487     }
488     if (IS_ALTAR(levl[u.ux][u.uy].typ))
489         doaltarobj(obj);
490     else if (verbosely)
491 #if 0 /*JP*/
492         pline("%s %s the %s.", Doname2(obj), otense(obj, "hit"),
493               surface(u.ux, u.uy));
494 #else
495         pline("%s\82Í%s\82É\96½\92\86\82µ\82½\81D", Doname2(obj),
496               surface(u.ux, u.uy));
497 #endif
498
499     if (hero_breaks(obj, u.ux, u.uy, TRUE))
500         return;
501     if (ship_object(obj, u.ux, u.uy, FALSE))
502         return;
503     dropz(obj, TRUE);
504 }
505
506 /*
507  * Walk a path from src_cc to dest_cc, calling a proc for each location
508  * except the starting one.  If the proc returns FALSE, stop walking
509  * and return FALSE.  If stopped early, dest_cc will be the location
510  * before the failed callback.
511  */
512 boolean
513 walk_path(src_cc, dest_cc, check_proc, arg)
514 coord *src_cc;
515 coord *dest_cc;
516 boolean FDECL((*check_proc), (genericptr_t, int, int));
517 genericptr_t arg;
518 {
519     int x, y, dx, dy, x_change, y_change, err, i, prev_x, prev_y;
520     boolean keep_going = TRUE;
521
522     /* Use Bresenham's Line Algorithm to walk from src to dest.
523      *
524      * This should be replaced with a more versatile algorithm
525      * since it handles slanted moves in a suboptimal way.
526      * Going from 'x' to 'y' needs to pass through 'z', and will
527      * fail if there's an obstable there, but it could choose to
528      * pass through 'Z' instead if that way imposes no obstacle.
529      *     ..y          .Zy
530      *     xz.    vs    x..
531      * Perhaps we should check both paths and accept whichever
532      * one isn't blocked.  But then multiple zigs and zags could
533      * potentially produce a meandering path rather than the best
534      * attempt at a straight line.  And (*check_proc)() would
535      * need to work more like 'travel', distinguishing between
536      * testing a possible move and actually attempting that move.
537      */
538     dx = dest_cc->x - src_cc->x;
539     dy = dest_cc->y - src_cc->y;
540     prev_x = x = src_cc->x;
541     prev_y = y = src_cc->y;
542
543     if (dx < 0) {
544         x_change = -1;
545         dx = -dx;
546     } else
547         x_change = 1;
548     if (dy < 0) {
549         y_change = -1;
550         dy = -dy;
551     } else
552         y_change = 1;
553
554     i = err = 0;
555     if (dx < dy) {
556         while (i++ < dy) {
557             prev_x = x;
558             prev_y = y;
559             y += y_change;
560             err += dx << 1;
561             if (err > dy) {
562                 x += x_change;
563                 err -= dy << 1;
564             }
565             /* check for early exit condition */
566             if (!(keep_going = (*check_proc)(arg, x, y)))
567                 break;
568         }
569     } else {
570         while (i++ < dx) {
571             prev_x = x;
572             prev_y = y;
573             x += x_change;
574             err += dy << 1;
575             if (err > dx) {
576                 y += y_change;
577                 err -= dx << 1;
578             }
579             /* check for early exit condition */
580             if (!(keep_going = (*check_proc)(arg, x, y)))
581                 break;
582         }
583     }
584
585     if (keep_going)
586         return TRUE; /* successful */
587
588     dest_cc->x = prev_x;
589     dest_cc->y = prev_y;
590     return FALSE;
591 }
592
593 /* hack for hurtle_step() -- it ought to be changed to take an argument
594    indicating lev/fly-to-dest vs lev/fly-to-dest-minus-one-land-on-dest
595    vs drag-to-dest; original callers use first mode, jumping wants second,
596    grappling hook backfire and thrown chained ball need third */
597 boolean
598 hurtle_jump(arg, x, y)
599 genericptr_t arg;
600 int x, y;
601 {
602     boolean res;
603     long save_EWwalking = EWwalking;
604
605     /* prevent jumping over water from being placed in that water */
606     EWwalking |= I_SPECIAL;
607     res = hurtle_step(arg, x, y);
608     EWwalking = save_EWwalking;
609     return res;
610 }
611
612 /*
613  * Single step for the hero flying through the air from jumping, flying,
614  * etc.  Called from hurtle() and jump() via walk_path().  We expect the
615  * argument to be a pointer to an integer -- the range -- which is
616  * used in the calculation of points off if we hit something.
617  *
618  * Bumping into monsters won't cause damage but will wake them and make
619  * them angry.  Auto-pickup isn't done, since you don't have control over
620  * your movements at the time.
621  *
622  * Possible additions/changes:
623  *      o really attack monster if we hit one
624  *      o set stunned if we hit a wall or door
625  *      o reset nomul when we stop
626  *      o creepy feeling if pass through monster (if ever implemented...)
627  *      o bounce off walls
628  *      o let jumps go over boulders
629  */
630 boolean
631 hurtle_step(arg, x, y)
632 genericptr_t arg;
633 int x, y;
634 {
635     int ox, oy, *range = (int *) arg;
636     struct obj *obj;
637     struct monst *mon;
638     boolean may_pass = TRUE, via_jumping, stopping_short;
639     struct trap *ttmp;
640     int dmg = 0;
641
642     if (!isok(x, y)) {
643 /*JP
644         You_feel("the spirits holding you back.");
645 */
646         You_feel("\82 \82È\82½\82ð\95ß\82Ü\82¦\82Ä\82¢\82½\8d°\82ª\96ß\82Á\82½\8bC\82ª\82µ\82½\81D");
647         return FALSE;
648     } else if (!in_out_region(x, y)) {
649         return FALSE;
650     } else if (*range == 0) {
651         return FALSE; /* previous step wants to stop now */
652     }
653     via_jumping = (EWwalking & I_SPECIAL) != 0L;
654     stopping_short = (via_jumping && *range < 2);
655
656     if (!Passes_walls || !(may_pass = may_passwall(x, y))) {
657         boolean odoor_diag = (IS_DOOR(levl[x][y].typ)
658                               && (levl[x][y].doormask & D_ISOPEN)
659                               && (u.ux - x) && (u.uy - y));
660
661         if (IS_ROCK(levl[x][y].typ) || closed_door(x, y) || odoor_diag) {
662             const char *s;
663
664             if (odoor_diag)
665 /*JP
666                 You("hit the door edge!");
667 */
668                 You("\94à\82Ì\92[\82É\93\96\82½\82Á\82½\81I");
669 /*JP
670             pline("Ouch!");
671 */
672             pline("\82¢\82Ä\82Á\81I");
673             if (IS_TREE(levl[x][y].typ))
674 /*JP
675                 s = "bumping into a tree";
676 */
677                 s = "\96Ø\82É\82Ô\82¿\82 \82½\82Á\82Ä";
678             else if (IS_ROCK(levl[x][y].typ))
679 /*JP
680                 s = "bumping into a wall";
681 */
682                 s = "\95Ç\82É\82Ô\82¿\82 \82½\82Á\82Ä";
683             else
684 /*JP
685                 s = "bumping into a door";
686 */
687                 s = "\94à\82É\82Ô\82¿\82 \82½\82Á\82Ä";
688             dmg = rnd(2 + *range);
689             losehp(Maybe_Half_Phys(dmg), s, KILLED_BY);
690             wake_nearto(x,y, 10);
691             return FALSE;
692         }
693         if (levl[x][y].typ == IRONBARS) {
694 /*JP
695             You("crash into some iron bars.  Ouch!");
696 */
697             You("\93S\82Ì\96_\82É\82Ô\82¿\82 \82½\82Á\82½\81D\82¢\82Ä\82Á\81I");
698             dmg = rnd(2 + *range);
699 #if 0 /*JP*/
700             losehp(Maybe_Half_Phys(dmg), "crashing into iron bars",
701                    KILLED_BY);
702 #else
703             losehp(Maybe_Half_Phys(dmg), "\93S\82Ì\96_\82É\82Ô\82¿\82 \82½\82Á\82Ä",
704                    KILLED_BY);
705 #endif
706             wake_nearto(x,y, 20);
707             return FALSE;
708         }
709         if ((obj = sobj_at(BOULDER, x, y)) != 0) {
710 /*JP
711             You("bump into a %s.  Ouch!", xname(obj));
712 */
713             You("%s\82É\82Ô\82¿\82 \82½\82Á\82½\81D\82¢\82Ä\82Á\81I", xname(obj));
714             dmg = rnd(2 + *range);
715 /*JP
716             losehp(Maybe_Half_Phys(dmg), "bumping into a boulder", KILLED_BY);
717 */
718             losehp(Maybe_Half_Phys(dmg), "\8aâ\82É\82Ô\82¿\82 \82½\82Á\82Ä", KILLED_BY);
719             wake_nearto(x,y, 10);
720             return FALSE;
721         }
722         if (!may_pass) {
723             /* did we hit a no-dig non-wall position? */
724 /*JP
725             You("smack into something!");
726 */
727             You("\89½\82©\82É\82Ô\82¿\82 \82½\82Á\82½\81I");
728             dmg = rnd(2 + *range);
729 #if 0 /*JP*/
730             losehp(Maybe_Half_Phys(dmg), "touching the edge of the universe",
731                    KILLED_BY);
732 #else
733             losehp(Maybe_Half_Phys(dmg), "\90¢\8aE\82Ì\89Ê\82Ä\82É\90G\82ê\82Ä",
734                    KILLED_BY);
735 #endif
736             wake_nearto(x,y, 10);
737             return FALSE;
738         }
739         if ((u.ux - x) && (u.uy - y) && bad_rock(youmonst.data, u.ux, y)
740             && bad_rock(youmonst.data, x, u.uy)) {
741             boolean too_much = (invent && (inv_weight() + weight_cap() > 600));
742
743             /* Move at a diagonal. */
744             if (bigmonst(youmonst.data) || too_much) {
745 #if 0 /*JP*/
746                 You("%sget forcefully wedged into a crevice.",
747                     too_much ? "and all your belongings " : "");
748 #else
749                 You("%s\82Í\82Þ\82è\82â\82è\82·\82«\8aÔ\82É\89\9f\82µ\8d\9e\82ß\82ç\82ê\82½\81D",
750                     too_much ? "\82Æ\91S\95\94\82Ì\89×\95¨" : "");
751 #endif
752                 dmg = rnd(2 + *range);
753 #if 0 /*JP*/
754                 losehp(Maybe_Half_Phys(dmg), "wedging into a narrow crevice",
755                        KILLED_BY);
756 #else
757                 losehp(Maybe_Half_Phys(dmg), "\8b·\82¢\82·\82«\8aÔ\82É\89\9f\82µ\8d\9e\82ß\82ç\82ê\82Ä",
758                        KILLED_BY);
759 #endif
760                 wake_nearto(x,y, 10);
761                 return FALSE;
762             }
763         }
764     }
765
766     if ((mon = m_at(x, y)) != 0
767 #if 0   /* we can't include these two exceptions unless we know we're
768          * going to end up past the current spot rather than on it;
769          * for that, we need to know that the range is not exhausted
770          * and also that the next spot doesn't contain an obstacle */
771         && !(mon->mundetected && hides_under(mon) && (Flying || Levitation))
772         && !(mon->mundetected && mon->data->mlet == S_EEL
773              && (Flying || Levitation || Wwalking))
774 #endif
775         ) {
776         const char *mnam, *pronoun;
777         int glyph = glyph_at(x, y);
778
779         mon->mundetected = 0; /* wakeup() will handle mimic */
780         mnam = a_monnam(mon); /* after unhiding */
781         pronoun = noit_mhim(mon);
782 #if 0 /*JP*/
783         if (!strcmp(mnam, "it")) {
784 #else
785         if (!strcmp(mnam, "\89½\8eÒ\82©")) {
786 #endif
787 #if 0 /*JP*/
788             mnam = !strcmp(pronoun, "it") ? "something" : "someone";
789 #else
790             mnam = !strcmp(pronoun, "\89½\8eÒ\82©") ? "\89½\82©" : "\89½\8eÒ\82©";
791 #endif
792         }
793         if (!glyph_is_monster(glyph) && !glyph_is_invisible(glyph))
794 #if 0 /*JP*/
795             You("find %s by bumping into %s.", mnam, pronoun);
796 #else
797             You("\82Ô\82¿\82 \82½\82Á\82½\82±\82Æ\82Å%s\82ð\8c©\82Â\82¯\82½\81D", mnam);
798 #endif
799         else
800 /*JP
801             You("bump into %s.", mnam);
802 */
803             You("%s\82É\82Ô\82¿\82 \82½\82Á\82½\81D", mnam);
804         wakeup(mon, FALSE);
805         if (!canspotmon(mon))
806             map_invisible(mon->mx, mon->my);
807         setmangry(mon, FALSE);
808         wake_nearto(x, y, 10);
809         return FALSE;
810     }
811
812     if ((u.ux - x) && (u.uy - y)
813         && bad_rock(youmonst.data, u.ux, y)
814         && bad_rock(youmonst.data, x, u.uy)) {
815         /* Move at a diagonal. */
816         if (Sokoban) {
817 /*JP
818             You("come to an abrupt halt!");
819 */
820             You("\82Æ\82Â\82º\82ñ\92â\8e~\82µ\82½\81I");
821             return FALSE;
822         }
823     }
824
825     /* Caller has already determined that dragging the ball is allowed */
826     if (Punished && uball->where == OBJ_FLOOR) {
827         int bc_control;
828         xchar ballx, bally, chainx, chainy;
829         boolean cause_delay;
830
831         if (drag_ball(x, y, &bc_control, &ballx, &bally, &chainx,
832                       &chainy, &cause_delay, TRUE))
833             move_bc(0, bc_control, ballx, bally, chainx, chainy);
834     }
835
836     ox = u.ux;
837     oy = u.uy;
838     u_on_newpos(x, y); /* set u.<ux,uy>, u.usteed-><mx,my>; cliparound(); */
839     newsym(ox, oy);    /* update old position */
840     vision_recalc(1);  /* update for new position */
841     flush_screen(1);
842     /* if terrain type changes, levitation or flying might become blocked
843        or unblocked; might issue message, so do this after map+vision has
844        been updated for new location instead of right after u_on_newpos() */
845     if (levl[u.ux][u.uy].typ != levl[ox][oy].typ)
846         switch_terrain();
847
848     if (is_pool(x, y) && !u.uinwater) {
849         if ((Is_waterlevel(&u.uz) && levl[x][y].typ == WATER)
850             || !(Levitation || Flying || Wwalking)) {
851             multi = 0; /* can move, so drown() allows crawling out of water */
852             (void) drown();
853             return FALSE;
854         } else if (!Is_waterlevel(&u.uz) && !stopping_short) {
855 /*JP
856             Norep("You move over %s.", an(is_moat(x, y) ? "moat" : "pool"));
857 */
858             Norep("\82 \82È\82½\82Í%s\82Ì\8fã\82ð\88Ú\93®\82µ\82½\81D", is_moat(x, y) ? "\96x" : "\90\85\82½\82Ü\82è");
859        }
860     } else if (is_lava(x, y) && !stopping_short) {
861 /*JP
862         Norep("You move over some lava.");
863 */
864         Norep("\82 \82È\82½\82Í\97n\8aâ\82Ì\8fã\82ð\88Ú\93®\82µ\82½\81D");
865     }
866
867     /* FIXME:
868      * Each trap should really trigger on the recoil if it would
869      * trigger during normal movement. However, not all the possible
870      * side-effects of this are tested [as of 3.4.0] so we trigger
871      * those that we have tested, and offer a message for the ones
872      * that we have not yet tested.
873      */
874     if ((ttmp = t_at(x, y)) != 0) {
875         if (stopping_short) {
876             ; /* see the comment above hurtle_jump() */
877         } else if (ttmp->ttyp == MAGIC_PORTAL) {
878             dotrap(ttmp, 0);
879             return FALSE;
880         } else if (ttmp->ttyp == VIBRATING_SQUARE) {
881 /*JP
882             pline("The ground vibrates as you pass it.");
883 */
884             pline("\82 \82È\82½\82ª\92Ê\89ß\82·\82é\82Æ\92n\96Ê\82ª\90k\93®\82µ\82½\81D");
885             dotrap(ttmp, 0); /* doesn't print messages */
886         } else if (ttmp->ttyp == FIRE_TRAP) {
887             dotrap(ttmp, 0);
888         } else if ((is_pit(ttmp->ttyp) || is_hole(ttmp->ttyp))
889                    && Sokoban) {
890             /* air currents overcome the recoil in Sokoban;
891                when jumping, caller performs last step and enters trap */
892             if (!via_jumping)
893                 dotrap(ttmp, 0);
894             *range = 0;
895             return TRUE;
896         } else {
897             if (ttmp->tseen)
898 #if 0 /*JP*/
899                 You("pass right over %s.",
900                     an(defsyms[trap_to_defsym(ttmp->ttyp)].explanation));
901 #else
902                 You("%s\82Ì\90^\8fã\82ð\92Ê\89ß\82µ\82½\81D",
903                     defsyms[trap_to_defsym(ttmp->ttyp)].explanation);
904 #endif
905         }
906     }
907     if (--*range < 0) /* make sure our range never goes negative */
908         *range = 0;
909     if (*range != 0)
910         delay_output();
911     return TRUE;
912 }
913
914 STATIC_OVL boolean
915 mhurtle_step(arg, x, y)
916 genericptr_t arg;
917 int x, y;
918 {
919     struct monst *mon = (struct monst *) arg;
920
921     /* TODO: Treat walls, doors, iron bars, pools, lava, etc. specially
922      * rather than just stopping before.
923      */
924     if (goodpos(x, y, mon, 0) && m_in_out_region(mon, x, y)) {
925         remove_monster(mon->mx, mon->my);
926         newsym(mon->mx, mon->my);
927         place_monster(mon, x, y);
928         newsym(mon->mx, mon->my);
929         set_apparxy(mon);
930         (void) mintrap(mon);
931         return TRUE;
932     }
933     return FALSE;
934 }
935
936 /*
937  * The player moves through the air for a few squares as a result of
938  * throwing or kicking something.
939  *
940  * dx and dy should be the direction of the hurtle, not of the original
941  * kick or throw and be only.
942  */
943 void
944 hurtle(dx, dy, range, verbose)
945 int dx, dy, range;
946 boolean verbose;
947 {
948     coord uc, cc;
949
950     /* The chain is stretched vertically, so you shouldn't be able to move
951      * very far diagonally.  The premise that you should be able to move one
952      * spot leads to calculations that allow you to only move one spot away
953      * from the ball, if you are levitating over the ball, or one spot
954      * towards the ball, if you are at the end of the chain.  Rather than
955      * bother with all of that, assume that there is no slack in the chain
956      * for diagonal movement, give the player a message and return.
957      */
958     if (Punished && !carried(uball)) {
959 /*JP
960         You_feel("a tug from the iron ball.");
961 */
962         You_feel("\93S\8b\85\82É\82Ð\82Á\82Ï\82ç\82ê\82Ä\82¢\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
963         nomul(0);
964         return;
965     } else if (u.utrap) {
966 #if 0 /*JP*/
967         You("are anchored by the %s.",
968             u.utraptype == TT_WEB
969                 ? "web"
970                 : u.utraptype == TT_LAVA
971                       ? hliquid("lava")
972                       : u.utraptype == TT_INFLOOR
973                             ? surface(u.ux, u.uy)
974                             : u.utraptype == TT_BURIEDBALL ? "buried ball"
975                                                            : "trap");
976 #else
977         You("%s\82É\90\98\82¦\82Â\82¯\82ç\82ê\82Ä\82¢\82é\81D",
978             u.utraptype == TT_WEB
979                 ? "\82­\82à\82Ì\91\83"
980                 : u.utraptype == TT_LAVA
981                       ? "\97n\8aâ"
982                       : u.utraptype == TT_INFLOOR
983                             ? surface(u.ux,u.uy)
984                             : u.utraptype == TT_BURIEDBALL ? "\96\84\82Ü\82Á\82Ä\82¢\82é\8b\85"
985                                                            : "ã©");
986 #endif
987         nomul(0);
988         return;
989     }
990
991     /* make sure dx and dy are [-1,0,1] */
992     dx = sgn(dx);
993     dy = sgn(dy);
994
995     if (!range || (!dx && !dy) || u.ustuck)
996         return; /* paranoia */
997
998     nomul(-range);
999 /*JP
1000     multi_reason = "moving through the air";
1001 */
1002     multi_reason = "\8bó\92\86\82ð\88Ú\93®\82µ\82Ä\82¢\82é\8e\9e\82É";
1003     nomovemsg = ""; /* it just happens */
1004     if (verbose)
1005 /*JP
1006         You("%s in the opposite direction.", range > 1 ? "hurtle" : "float");
1007 */
1008         You("\8bt\95û\8cü\82É\94ò\82Î\82³\82ê\82½\81D");
1009     /* if we're in the midst of shooting multiple projectiles, stop */
1010     endmultishot(TRUE);
1011     sokoban_guilt();
1012     uc.x = u.ux;
1013     uc.y = u.uy;
1014     /* this setting of cc is only correct if dx and dy are [-1,0,1] only */
1015     cc.x = u.ux + (dx * range);
1016     cc.y = u.uy + (dy * range);
1017     (void) walk_path(&uc, &cc, hurtle_step, (genericptr_t) &range);
1018 }
1019
1020 /* Move a monster through the air for a few squares. */
1021 void
1022 mhurtle(mon, dx, dy, range)
1023 struct monst *mon;
1024 int dx, dy, range;
1025 {
1026     coord mc, cc;
1027
1028     /* At the very least, debilitate the monster */
1029     mon->movement = 0;
1030     mon->mstun = 1;
1031
1032     /* Is the monster stuck or too heavy to push?
1033      * (very large monsters have too much inertia, even floaters and flyers)
1034      */
1035     if (mon->data->msize >= MZ_HUGE || mon == u.ustuck || mon->mtrapped)
1036         return;
1037
1038     /* Make sure dx and dy are [-1,0,1] */
1039     dx = sgn(dx);
1040     dy = sgn(dy);
1041     if (!range || (!dx && !dy))
1042         return; /* paranoia */
1043     /* don't let grid bugs be hurtled diagonally */
1044     if (dx && dy && NODIAG(monsndx(mon->data)))
1045         return;
1046
1047     /* Send the monster along the path */
1048     mc.x = mon->mx;
1049     mc.y = mon->my;
1050     cc.x = mon->mx + (dx * range);
1051     cc.y = mon->my + (dy * range);
1052     (void) walk_path(&mc, &cc, mhurtle_step, (genericptr_t) mon);
1053     return;
1054 }
1055
1056 STATIC_OVL void
1057 check_shop_obj(obj, x, y, broken)
1058 struct obj *obj;
1059 xchar x, y;
1060 boolean broken;
1061 {
1062     boolean costly_xy;
1063     struct monst *shkp = shop_keeper(*u.ushops);
1064
1065     if (!shkp)
1066         return;
1067
1068     costly_xy = costly_spot(x, y);
1069     if (broken || !costly_xy || *in_rooms(x, y, SHOPBASE) != *u.ushops) {
1070         /* thrown out of a shop or into a different shop */
1071         if (is_unpaid(obj))
1072             (void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful,
1073                                 FALSE);
1074         if (broken)
1075             obj->no_charge = 1;
1076     } else if (costly_xy) {
1077         char *oshops = in_rooms(x, y, SHOPBASE);
1078
1079         /* ushops0: in case we threw while levitating and recoiled
1080            out of shop (most likely to the shk's spot in front of door) */
1081         if (*oshops == *u.ushops || *oshops == *u.ushops0) {
1082             if (is_unpaid(obj))
1083                 subfrombill(obj, shkp);
1084             else if (x != shkp->mx || y != shkp->my)
1085                 sellobj(obj, x, y);
1086         }
1087     }
1088 }
1089
1090 /*
1091  * Hero tosses an object upwards with appropriate consequences.
1092  *
1093  * Returns FALSE if the object is gone.
1094  */
1095 STATIC_OVL boolean
1096 toss_up(obj, hitsroof)
1097 struct obj *obj;
1098 boolean hitsroof;
1099 {
1100     const char *action;
1101     boolean petrifier = ((obj->otyp == EGG || obj->otyp == CORPSE)
1102                          && touch_petrifies(&mons[obj->corpsenm]));
1103     /* note: obj->quan == 1 */
1104
1105     if (!has_ceiling(&u.uz)) {
1106 #if 0 /*JP*/
1107         action = "flies up into"; /* into "the sky" or "the water above" */
1108 #else
1109         action = "\82Ì\92\86\82ð\94ò\82ñ\82¾"; /* into "the sky" or "the water above" */
1110 #endif
1111     } else if (hitsroof) {
1112         if (breaktest(obj)) {
1113 /*JP
1114             pline("%s hits the %s.", Doname2(obj), ceiling(u.ux, u.uy));
1115 */
1116             pline("%s\82Í%s\82É\96½\92\86\82µ\82½\81D", Doname2(obj), ceiling(u.ux, u.uy));
1117             breakmsg(obj, !Blind);
1118             breakobj(obj, u.ux, u.uy, TRUE, TRUE);
1119             return FALSE;
1120         }
1121 /*JP
1122         action = "hits";
1123 */
1124         action = "\82É\96½\92\86\82µ\82½";
1125     } else {
1126 /*JP
1127         action = "almost hits";
1128 */
1129         action = "\82É\82à\82¤\8f­\82µ\82Å\96½\92\86\82·\82é\82Æ\82±\82ë\82¾\82Á\82½";
1130     }
1131 #if 0 /*JP*/
1132     pline("%s %s the %s, then falls back on top of your %s.", Doname2(obj),
1133           action, ceiling(u.ux, u.uy), body_part(HEAD));
1134 #else
1135     pline("%s\82Í%s%s\81C\82»\82µ\82Ä%s\82Ì\8fã\82É\97\8e\82¿\82Ä\82«\82½\81D", Doname2(obj),
1136           ceiling(u.ux, u.uy), action, body_part(HEAD));
1137 #endif
1138
1139     /* object now hits you */
1140
1141     if (obj->oclass == POTION_CLASS) {
1142         potionhit(&youmonst, obj, POTHIT_HERO_THROW);
1143     } else if (breaktest(obj)) {
1144         int otyp = obj->otyp;
1145         int blindinc;
1146
1147         /* need to check for blindness result prior to destroying obj */
1148         blindinc = ((otyp == CREAM_PIE || otyp == BLINDING_VENOM)
1149                     /* AT_WEAP is ok here even if attack type was AT_SPIT */
1150                     && can_blnd(&youmonst, &youmonst, AT_WEAP, obj))
1151                        ? rnd(25)
1152                        : 0;
1153         breakmsg(obj, !Blind);
1154         breakobj(obj, u.ux, u.uy, TRUE, TRUE);
1155         obj = 0; /* it's now gone */
1156         switch (otyp) {
1157         case EGG:
1158             if (petrifier && !Stone_resistance
1159                 && !(poly_when_stoned(youmonst.data)
1160                      && polymon(PM_STONE_GOLEM))) {
1161                 /* egg ends up "all over your face"; perhaps
1162                    visored helmet should still save you here */
1163                 if (uarmh)
1164 /*JP
1165                     Your("%s fails to protect you.", helm_simple_name(uarmh));
1166 */
1167                     Your("%s\82Í\82 \82È\82½\82ð\8eç\82ê\82È\82©\82Á\82½\81D", helm_simple_name(uarmh));
1168                 goto petrify;
1169             }
1170             /*FALLTHRU*/
1171         case CREAM_PIE:
1172         case BLINDING_VENOM:
1173 /*JP
1174             pline("You've got it all over your %s!", body_part(FACE));
1175 */
1176             pline("\82»\82ê\82Í%s\82ð\82×\82Á\82Æ\82è\82Æ\95¢\82Á\82½\81I", body_part(FACE));
1177             if (blindinc) {
1178                 if (otyp == BLINDING_VENOM && !Blind)
1179 /*JP
1180                     pline("It blinds you!");
1181 */
1182                     pline("\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I");
1183                 u.ucreamed += blindinc;
1184                 make_blinded(Blinded + (long) blindinc, FALSE);
1185                 if (!Blind)
1186                     Your1(vision_clears);
1187             }
1188             break;
1189         default:
1190             break;
1191         }
1192         return FALSE;
1193     } else { /* neither potion nor other breaking object */
1194         boolean less_damage = uarmh && is_metallic(uarmh), artimsg = FALSE;
1195         int dmg = dmgval(obj, &youmonst);
1196
1197         if (obj->oartifact)
1198             /* need a fake die roll here; rn1(18,2) avoids 1 and 20 */
1199             artimsg = artifact_hit((struct monst *) 0, &youmonst, obj, &dmg,
1200                                    rn1(18, 2));
1201
1202         if (!dmg) { /* probably wasn't a weapon; base damage on weight */
1203             dmg = (int) obj->owt / 100;
1204             if (dmg < 1)
1205                 dmg = 1;
1206             else if (dmg > 6)
1207                 dmg = 6;
1208             if (youmonst.data == &mons[PM_SHADE]
1209                 && objects[obj->otyp].oc_material != SILVER)
1210                 dmg = 0;
1211         }
1212         if (dmg > 1 && less_damage)
1213             dmg = 1;
1214         if (dmg > 0)
1215             dmg += u.udaminc;
1216         if (dmg < 0)
1217             dmg = 0; /* beware negative rings of increase damage */
1218         dmg = Maybe_Half_Phys(dmg);
1219
1220         if (uarmh) {
1221             if (less_damage && dmg < (Upolyd ? u.mh : u.uhp)) {
1222                 if (!artimsg)
1223 /*JP
1224                     pline("Fortunately, you are wearing a hard helmet.");
1225 */
1226                     pline("\8dK\89^\82É\82à\81C\82 \82È\82½\82Í\8cÅ\82¢\8a\95\82ð\90g\82É\82Â\82¯\82Ä\82¢\82½\81D");
1227                 /* helmet definitely protects you when it blocks petrification
1228                  */
1229             } else if (!petrifier) {
1230                 if (flags.verbose)
1231 /*JP
1232                     Your("%s does not protect you.", helm_simple_name(uarmh));
1233 */
1234                     Your("%s\82Å\82Í\96h\82¬\82«\82ê\82È\82©\82Á\82½\81D", helm_simple_name(uarmh));
1235             }
1236         } else if (petrifier && !Stone_resistance
1237                    && !(poly_when_stoned(youmonst.data)
1238                         && polymon(PM_STONE_GOLEM))) {
1239  petrify:
1240             killer.format = KILLED_BY;
1241 #if 0 /*JP*/
1242             Strcpy(killer.name, "elementary physics"); /* "what goes up..." */
1243 #else
1244             Strcpy(killer.name, "\8f\89\93\99\95¨\97\9d\82É\82æ\82è"); /* "what goes up..." */
1245 #endif
1246 /*JP
1247             You("turn to stone.");
1248 */
1249             You("\90Î\82É\82È\82Á\82½\81D");
1250             if (obj)
1251                 dropy(obj); /* bypass most of hitfloor() */
1252             thrownobj = 0;  /* now either gone or on floor */
1253             done(STONING);
1254             return obj ? TRUE : FALSE;
1255         }
1256         hitfloor(obj, TRUE);
1257         thrownobj = 0;
1258 #if 0 /*JP*/
1259         losehp(Maybe_Half_Phys(dmg), "falling object", KILLED_BY_AN);
1260 #else
1261         losehp(Maybe_Half_Phys(dmg), "\97\8e\89º\95¨\82Å", KILLED_BY_AN);
1262 #endif
1263     }
1264     return TRUE;
1265 }
1266
1267 /* return true for weapon meant to be thrown; excludes ammo */
1268 boolean
1269 throwing_weapon(obj)
1270 struct obj *obj;
1271 {
1272     return (boolean) (is_missile(obj) || is_spear(obj)
1273                       /* daggers and knife (excludes scalpel) */
1274                       || (is_blade(obj) && !is_sword(obj)
1275                           && (objects[obj->otyp].oc_dir & PIERCE))
1276                       /* special cases [might want to add AXE] */
1277                       || obj->otyp == WAR_HAMMER || obj->otyp == AKLYS);
1278 }
1279
1280 /* the currently thrown object is returning to you (not for boomerangs) */
1281 STATIC_OVL void
1282 sho_obj_return_to_u(obj)
1283 struct obj *obj;
1284 {
1285     /* might already be our location (bounced off a wall) */
1286     if ((u.dx || u.dy) && (bhitpos.x != u.ux || bhitpos.y != u.uy)) {
1287         int x = bhitpos.x - u.dx, y = bhitpos.y - u.dy;
1288
1289         tmp_at(DISP_FLASH, obj_to_glyph(obj, rn2_on_display_rng));
1290         while (isok(x,y) && (x != u.ux || y != u.uy)) {
1291             tmp_at(x, y);
1292             delay_output();
1293             x -= u.dx;
1294             y -= u.dy;
1295         }
1296         tmp_at(DISP_END, 0);
1297     }
1298 }
1299
1300 /* throw an object, NB: obj may be consumed in the process */
1301 void
1302 throwit(obj, wep_mask, twoweap)
1303 struct obj *obj;
1304 long wep_mask; /* used to re-equip returning boomerang */
1305 boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
1306 {
1307     register struct monst *mon;
1308     register int range, urange;
1309     boolean crossbowing, impaired = (Confusion || Stunned || Blind
1310                                      || Hallucination || Fumbling);
1311     boolean tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0);
1312
1313     notonhead = FALSE; /* reset potentially stale value */
1314     if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) {
1315         boolean slipok = TRUE;
1316
1317         if (ammo_and_launcher(obj, uwep)) {
1318 /*JP
1319             pline("%s!", Tobjnam(obj, "misfire"));
1320 */
1321             pline("%s\82Í\82Í\82¸\82ê\82½\81I", xname(obj));
1322         } else {
1323             /* only slip if it's greased or meant to be thrown */
1324             if (obj->greased || throwing_weapon(obj))
1325                 /* BUG: this message is grammatically incorrect if obj has
1326                    a plural name; greased gloves or boots for instance. */
1327 /*JP
1328                 pline("%s as you throw it!", Tobjnam(obj, "slip"));
1329 */
1330                 pline("%s\82ð\93\8a\82°\82æ\82¤\82Æ\82µ\82½\82ª\81C\82¸\82è\97\8e\82¿\82Ä\82µ\82Ü\82Á\82½\81I", xname(obj));
1331             else
1332                 slipok = FALSE;
1333         }
1334         if (slipok) {
1335             u.dx = rn2(3) - 1;
1336             u.dy = rn2(3) - 1;
1337             if (!u.dx && !u.dy)
1338                 u.dz = 1;
1339             impaired = TRUE;
1340         }
1341     }
1342
1343     if ((u.dx || u.dy || (u.dz < 1))
1344         && calc_capacity((int) obj->owt) > SLT_ENCUMBER
1345         && (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
1346                    : (u.uhp < 10 && u.uhp != u.uhpmax))
1347         && obj->owt > (unsigned) ((Upolyd ? u.mh : u.uhp) * 2)
1348         && !Is_airlevel(&u.uz)) {
1349 /*JP
1350         You("have so little stamina, %s drops from your grasp.",
1351 */
1352         You("\88¬\97Í\82ª\82È\82­\82È\82Á\82Ä\82¢\82½\82Ì\82Å\81C%s\82ð\88¬\82è\82»\82±\82Ë\82Ä\97\8e\82Æ\82µ\82½\81D",
1353             the(xname(obj)));
1354         exercise(A_CON, FALSE);
1355         u.dx = u.dy = 0;
1356         u.dz = 1;
1357     }
1358
1359     thrownobj = obj;
1360     thrownobj->was_thrown = 1;
1361
1362     if (u.uswallow) {
1363         mon = u.ustuck;
1364         bhitpos.x = mon->mx;
1365         bhitpos.y = mon->my;
1366         if (tethered_weapon)
1367             tmp_at(DISP_TETHER, obj_to_glyph(obj, rn2_on_display_rng));
1368     } else if (u.dz) {
1369         if (u.dz < 0
1370             /* Mjollnir must we wielded to be thrown--caller verifies this;
1371                aklys must we wielded as primary to return when thrown */
1372             && ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR)
1373                 || tethered_weapon)
1374             && !impaired) {
1375 #if 0 /*JP*/
1376             pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
1377                   ceiling(u.ux, u.uy));
1378 #else
1379             pline("%s\82Í%s\82É\96½\92\86\82µ\82 \82È\82½\82Ì\8eè\82É\96ß\82Á\82Ä\82«\82½\81I", xname(obj),
1380                   ceiling(u.ux,u.uy));
1381 #endif
1382             obj = addinv(obj);
1383             (void) encumber_msg();
1384             if (obj->owornmask & W_QUIVER) /* in case addinv() autoquivered */
1385                 setuqwep((struct obj *) 0);
1386             setuwep(obj);
1387             u.twoweap = twoweap;
1388         } else if (u.dz < 0) {
1389             (void) toss_up(obj, rn2(5) && !Underwater);
1390         } else if (u.dz > 0 && u.usteed && obj->oclass == POTION_CLASS
1391                    && rn2(6)) {
1392             /* alternative to prayer or wand of opening/spell of knock
1393                for dealing with cursed saddle:  throw holy water > */
1394             potionhit(u.usteed, obj, POTHIT_HERO_THROW);
1395         } else {
1396             hitfloor(obj, TRUE);
1397         }
1398         thrownobj = (struct obj *) 0;
1399         return;
1400
1401     } else if (obj->otyp == BOOMERANG && !Underwater) {
1402         if (Is_airlevel(&u.uz) || Levitation)
1403             hurtle(-u.dx, -u.dy, 1, TRUE);
1404         mon = boomhit(obj, u.dx, u.dy);
1405         if (mon == &youmonst) { /* the thing was caught */
1406             exercise(A_DEX, TRUE);
1407             obj = addinv(obj);
1408             (void) encumber_msg();
1409             if (wep_mask && !(obj->owornmask & wep_mask)) {
1410                 setworn(obj, wep_mask);
1411                 u.twoweap = twoweap;
1412             }
1413             thrownobj = (struct obj *) 0;
1414             return;
1415         }
1416     } else {
1417         /* crossbow range is independent of strength */
1418         crossbowing = (ammo_and_launcher(obj, uwep)
1419                        && weapon_type(uwep) == P_CROSSBOW);
1420         urange = (crossbowing ? 18 : (int) ACURRSTR) / 2;
1421         /* balls are easy to throw or at least roll;
1422          * also, this insures the maximum range of a ball is greater
1423          * than 1, so the effects from throwing attached balls are
1424          * actually possible
1425          */
1426         if (obj->otyp == HEAVY_IRON_BALL)
1427             range = urange - (int) (obj->owt / 100);
1428         else
1429             range = urange - (int) (obj->owt / 40);
1430         if (obj == uball) {
1431             if (u.ustuck)
1432                 range = 1;
1433             else if (range >= 5)
1434                 range = 5;
1435         }
1436         if (range < 1)
1437             range = 1;
1438
1439         if (is_ammo(obj)) {
1440             if (ammo_and_launcher(obj, uwep)) {
1441                 if (crossbowing)
1442                     range = BOLT_LIM;
1443                 else
1444                     range++;
1445             } else if (obj->oclass != GEM_CLASS)
1446                 range /= 2;
1447         }
1448
1449         if (Is_airlevel(&u.uz) || Levitation) {
1450             /* action, reaction... */
1451             urange -= range;
1452             if (urange < 1)
1453                 urange = 1;
1454             range -= urange;
1455             if (range < 1)
1456                 range = 1;
1457         }
1458
1459         if (obj->otyp == BOULDER)
1460             range = 20; /* you must be giant */
1461         else if (obj->oartifact == ART_MJOLLNIR)
1462             range = (range + 1) / 2; /* it's heavy */
1463         else if (tethered_weapon) /* primary weapon is aklys */
1464             /* if an aklys is going to return, range is limited by the
1465                length of the attached cord [implicit aspect of item] */
1466             range = min(range, BOLT_LIM / 2);
1467         else if (obj == uball && u.utrap && u.utraptype == TT_INFLOOR)
1468             range = 1;
1469
1470         if (Underwater)
1471             range = 1;
1472
1473         mon = bhit(u.dx, u.dy, range,
1474                    tethered_weapon ? THROWN_TETHERED_WEAPON : THROWN_WEAPON,
1475                    (int FDECL((*), (MONST_P, OBJ_P))) 0,
1476                    (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
1477         thrownobj = obj; /* obj may be null now */
1478
1479         /* have to do this after bhit() so u.ux & u.uy are correct */
1480         if (Is_airlevel(&u.uz) || Levitation)
1481             hurtle(-u.dx, -u.dy, urange, TRUE);
1482
1483         if (!obj) {
1484             /* bhit display cleanup was left with this caller
1485                for tethered_weapon, but clean it up now since
1486                we're about to return */
1487             if (tethered_weapon)
1488                 tmp_at(DISP_END, 0);
1489             return;
1490         }
1491     }
1492
1493     if (mon) {
1494         boolean obj_gone;
1495
1496         if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) {
1497             thrownobj = (struct obj *) 0;
1498             return; /* alert shk caught it */
1499         }
1500         (void) snuff_candle(obj);
1501         notonhead = (bhitpos.x != mon->mx || bhitpos.y != mon->my);
1502         obj_gone = thitmonst(mon, obj);
1503         /* Monster may have been tamed; this frees old mon */
1504         mon = m_at(bhitpos.x, bhitpos.y);
1505
1506         /* [perhaps this should be moved into thitmonst or hmon] */
1507         if (mon && mon->isshk
1508             && (!inside_shop(u.ux, u.uy)
1509                 || !index(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops)))
1510             hot_pursuit(mon);
1511
1512         if (obj_gone)
1513             thrownobj = 0;
1514     }
1515
1516     if (!thrownobj) {
1517         /* missile has already been handled */
1518         if (tethered_weapon) tmp_at(DISP_END, 0);
1519     } else if (u.uswallow) {
1520         if (tethered_weapon) {
1521             tmp_at(DISP_END, 0);
1522 /*JP
1523             pline("%s returns to your hand!", The(xname(thrownobj)));
1524 */
1525             pline("%s\82Í\82 \82È\82½\82Ì\8eè\82É\96ß\82Á\82Ä\82«\82½\81I", The(xname(thrownobj)));
1526             thrownobj = addinv(thrownobj);
1527             (void) encumber_msg();
1528             /* in case addinv() autoquivered */
1529             if (thrownobj->owornmask & W_QUIVER)
1530                 setuqwep((struct obj *) 0);
1531             setuwep(thrownobj);
1532         } else {
1533             /* ball is not picked up by monster */
1534             if (obj != uball)
1535                 (void) mpickobj(u.ustuck, obj);
1536             thrownobj = (struct obj *) 0;
1537         }
1538     } else {
1539         /* Mjollnir must we wielded to be thrown--caller verifies this;
1540            aklys must we wielded as primary to return when thrown */
1541         if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE))
1542             || tethered_weapon) {
1543             if (rn2(100)) {
1544                 if (tethered_weapon)
1545                     tmp_at(DISP_END, BACKTRACK);
1546                 else
1547                     sho_obj_return_to_u(obj); /* display its flight */
1548
1549                 if (!impaired && rn2(100)) {
1550 /*JP
1551                     pline("%s to your hand!", Tobjnam(obj, "return"));
1552 */
1553                     pline("%s\82Í\82 \82È\82½\82Ì\8eè\82É\96ß\82Á\82Ä\82«\82½\81I", xname(obj));
1554                     obj = addinv(obj);
1555                     (void) encumber_msg();
1556                     /* addinv autoquivers an aklys if quiver is empty;
1557                        if obj is quivered, remove it before wielding */
1558                     if (obj->owornmask & W_QUIVER)
1559                         setuqwep((struct obj *) 0);
1560                     setuwep(obj);
1561                     u.twoweap = twoweap;
1562                     if (cansee(bhitpos.x, bhitpos.y))
1563                         newsym(bhitpos.x, bhitpos.y);
1564                 } else {
1565                     int dmg = rn2(2);
1566
1567                     if (!dmg) {
1568 #if 0 /*JP:T*/
1569                         pline(Blind ? "%s lands %s your %s."
1570                                     : "%s back to you, landing %s your %s.",
1571                               Blind ? Something : Tobjnam(obj, "return"),
1572                               Levitation ? "beneath" : "at",
1573                               makeplural(body_part(FOOT)));
1574 #else
1575                         pline("%s\82Í%s\82 \82È\82½\82Ì%s\82Ì%s\82É\97\8e\82¿\82½\81D",
1576                               xname(obj),
1577                               Blind ? "" : "\96ß\82Á\82Ä\82«\82Ä\81C",
1578                               body_part(FOOT),
1579                               Levitation ? "\89º" : "\82»\82Î");
1580 #endif
1581                     } else {
1582                         dmg += rnd(3);
1583 #if 0 /*JP:T*/
1584                         pline(Blind ? "%s your %s!"
1585                                     : "%s back toward you, hitting your %s!",
1586                               Tobjnam(obj, Blind ? "hit" : "fly"),
1587                               body_part(ARM));
1588 #else
1589                         pline("%s\82Í%s\82 \82È\82½\82Ì%s\82É\96½\92\86\82µ\82½\81I",
1590                               xname(obj),
1591                               Blind ? "" : "\96ß\82Á\82Ä\82«\82Ä\81C",
1592                               body_part(ARM));
1593 #endif
1594                         if (obj->oartifact)
1595                             (void) artifact_hit((struct monst *) 0, &youmonst,
1596                                                 obj, &dmg, 0);
1597 #if 0 /*JP*/
1598                         losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
1599                                KILLED_BY);
1600 #else
1601                         {
1602                             char jbuf[BUFSZ];
1603                             Sprintf(jbuf, "%s\82Å", xname(obj));
1604                             losehp(Maybe_Half_Phys(dmg), jbuf, KILLED_BY);
1605                         }
1606 #endif
1607                     }
1608                     if (ship_object(obj, u.ux, u.uy, FALSE)) {
1609                         thrownobj = (struct obj *) 0;
1610                         return;
1611                     }
1612                     dropy(obj);
1613                 }
1614                 thrownobj = (struct obj *) 0;
1615                 return;
1616             } else {
1617                 if (tethered_weapon)
1618                     tmp_at(DISP_END, 0);
1619                 /* when this location is stepped on, the weapon will be
1620                    auto-picked up due to 'obj->was_thrown' of 1;
1621                    addinv() prevents thrown Mjollnir from being placed
1622                    into the quiver slot, but an aklys will end up there if
1623                    that slot is empty at the time; since hero will need to
1624                    explicitly rewield the weapon to get throw-and-return
1625                    capability back anyway, quivered or not shouldn't matter */
1626 /*JP
1627                 pline("%s to return!", Tobjnam(obj, "fail"));
1628 */
1629                 pline("%s\82Í\96ß\82é\82Ì\82É\8e¸\94s\82µ\82½\81I", xname(obj));
1630                 /* continue below with placing 'obj' at target location */
1631             }
1632         }
1633
1634         if ((!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj))
1635             /* venom [via #monster to spit while poly'd] fails breaktest()
1636                but we want to force breakage even when location IS_SOFT() */
1637             || obj->oclass == VENOM_CLASS) {
1638             tmp_at(DISP_FLASH, obj_to_glyph(obj, rn2_on_display_rng));
1639             tmp_at(bhitpos.x, bhitpos.y);
1640             delay_output();
1641             tmp_at(DISP_END, 0);
1642             breakmsg(obj, cansee(bhitpos.x, bhitpos.y));
1643             breakobj(obj, bhitpos.x, bhitpos.y, TRUE, TRUE);
1644             thrownobj = (struct obj *) 0;
1645             return;
1646         }
1647 /*JP
1648         if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall")) {
1649 */
1650         if (flooreffects(obj,bhitpos.x, bhitpos.y, "\97\8e\82¿\82é")) {
1651             thrownobj = (struct obj *) 0;
1652             return;
1653         }
1654         obj_no_longer_held(obj);
1655         if (mon && mon->isshk && is_pick(obj)) {
1656             if (cansee(bhitpos.x, bhitpos.y))
1657 /*JP
1658                 pline("%s snatches up %s.", Monnam(mon), the(xname(obj)));
1659 */
1660                 pline("%s\82Í%s\82ð\92D\82¢\82Æ\82Á\82½\81D", Monnam(mon), xname(obj));
1661             if (*u.ushops || obj->unpaid)
1662                 check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1663             (void) mpickobj(mon, obj); /* may merge and free obj */
1664             thrownobj = (struct obj *) 0;
1665             return;
1666         }
1667         (void) snuff_candle(obj);
1668         if (!mon && ship_object(obj, bhitpos.x, bhitpos.y, FALSE)) {
1669             thrownobj = (struct obj *) 0;
1670             return;
1671         }
1672         thrownobj = (struct obj *) 0;
1673         place_object(obj, bhitpos.x, bhitpos.y);
1674         /* container contents might break;
1675            do so before turning ownership of thrownobj over to shk
1676            (container_impact_dmg handles item already owned by shop) */
1677         if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ))
1678             /* <x,y> is spot where you initiated throw, not bhitpos */
1679             container_impact_dmg(obj, u.ux, u.uy);
1680         /* charge for items thrown out of shop;
1681            shk takes possession for items thrown into one */
1682         if ((*u.ushops || obj->unpaid) && obj != uball)
1683             check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1684
1685         stackobj(obj);
1686         if (obj == uball)
1687             drop_ball(bhitpos.x, bhitpos.y);
1688         if (cansee(bhitpos.x, bhitpos.y))
1689             newsym(bhitpos.x, bhitpos.y);
1690         if (obj_sheds_light(obj))
1691             vision_full_recalc = 1;
1692     }
1693 }
1694
1695 /* an object may hit a monster; various factors adjust chance of hitting */
1696 int
1697 omon_adj(mon, obj, mon_notices)
1698 struct monst *mon;
1699 struct obj *obj;
1700 boolean mon_notices;
1701 {
1702     int tmp = 0;
1703
1704     /* size of target affects the chance of hitting */
1705     tmp += (mon->data->msize - MZ_MEDIUM); /* -2..+5 */
1706     /* sleeping target is more likely to be hit */
1707     if (mon->msleeping) {
1708         tmp += 2;
1709         if (mon_notices)
1710             mon->msleeping = 0;
1711     }
1712     /* ditto for immobilized target */
1713     if (!mon->mcanmove || !mon->data->mmove) {
1714         tmp += 4;
1715         if (mon_notices && mon->data->mmove && !rn2(10)) {
1716             mon->mcanmove = 1;
1717             mon->mfrozen = 0;
1718         }
1719     }
1720     /* some objects are more likely to hit than others */
1721     switch (obj->otyp) {
1722     case HEAVY_IRON_BALL:
1723         if (obj != uball)
1724             tmp += 2;
1725         break;
1726     case BOULDER:
1727         tmp += 6;
1728         break;
1729     default:
1730         if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1731             || obj->oclass == GEM_CLASS)
1732             tmp += hitval(obj, mon);
1733         break;
1734     }
1735     return tmp;
1736 }
1737
1738 /* thrown object misses target monster */
1739 STATIC_OVL void
1740 tmiss(obj, mon, maybe_wakeup)
1741 struct obj *obj;
1742 struct monst *mon;
1743 boolean maybe_wakeup;
1744 {
1745     const char *missile = mshot_xname(obj);
1746
1747     /* If the target can't be seen or doesn't look like a valid target,
1748        avoid "the arrow misses it," or worse, "the arrows misses the mimic."
1749        An attentive player will still notice that this is different from
1750        an arrow just landing short of any target (no message in that case),
1751        so will realize that there is a valid target here anyway. */
1752     if (!canseemon(mon) || (M_AP_TYPE(mon) && M_AP_TYPE(mon) != M_AP_MONSTER))
1753 /*JP
1754         pline("%s %s.", The(missile), otense(obj, "miss"));
1755 */
1756         pline("%s\82Í\82Í\82¸\82ê\82½\81D", missile);
1757     else
1758         miss(missile, mon);
1759     if (maybe_wakeup && !rn2(3))
1760         wakeup(mon, TRUE);
1761     return;
1762 }
1763
1764 #define quest_arti_hits_leader(obj, mon)      \
1765     (obj->oartifact && is_quest_artifact(obj) \
1766      && mon->m_id == quest_status.leader_m_id)
1767
1768 /*
1769  * Object thrown by player arrives at monster's location.
1770  * Return 1 if obj has disappeared or otherwise been taken care of,
1771  * 0 if caller must take care of it.
1772  * Also used for kicked objects and for polearms/grapnel applied at range.
1773  */
1774 int
1775 thitmonst(mon, obj)
1776 register struct monst *mon;
1777 register struct obj *obj; /* thrownobj or kickedobj or uwep */
1778 {
1779     register int tmp;     /* Base chance to hit */
1780     register int disttmp; /* distance modifier */
1781     int otyp = obj->otyp, hmode;
1782     boolean guaranteed_hit = (u.uswallow && mon == u.ustuck);
1783     int dieroll;
1784
1785     hmode = (obj == uwep) ? HMON_APPLIED
1786               : (obj == kickedobj) ? HMON_KICKED
1787                 : HMON_THROWN;
1788
1789     /* Differences from melee weapons:
1790      *
1791      * Dex still gives a bonus, but strength does not.
1792      * Polymorphed players lacking attacks may still throw.
1793      * There's a base -1 to hit.
1794      * No bonuses for fleeing or stunned targets (they don't dodge
1795      *    melee blows as readily, but dodging arrows is hard anyway).
1796      * Not affected by traps, etc.
1797      * Certain items which don't in themselves do damage ignore 'tmp'.
1798      * Distance and monster size affect chance to hit.
1799      */
1800     tmp = -1 + Luck + find_mac(mon) + u.uhitinc
1801           + maybe_polyd(youmonst.data->mlevel, u.ulevel);
1802     if (ACURR(A_DEX) < 4)
1803         tmp -= 3;
1804     else if (ACURR(A_DEX) < 6)
1805         tmp -= 2;
1806     else if (ACURR(A_DEX) < 8)
1807         tmp -= 1;
1808     else if (ACURR(A_DEX) >= 14)
1809         tmp += (ACURR(A_DEX) - 14);
1810
1811     /* Modify to-hit depending on distance; but keep it sane.
1812      * Polearms get a distance penalty even when wielded; it's
1813      * hard to hit at a distance.
1814      */
1815     disttmp = 3 - distmin(u.ux, u.uy, mon->mx, mon->my);
1816     if (disttmp < -4)
1817         disttmp = -4;
1818     tmp += disttmp;
1819
1820     /* gloves are a hindrance to proper use of bows */
1821     if (uarmg && uwep && objects[uwep->otyp].oc_skill == P_BOW) {
1822         switch (uarmg->otyp) {
1823         case GAUNTLETS_OF_POWER: /* metal */
1824             tmp -= 2;
1825             break;
1826         case GAUNTLETS_OF_FUMBLING:
1827             tmp -= 3;
1828             break;
1829         case LEATHER_GLOVES:
1830         case GAUNTLETS_OF_DEXTERITY:
1831             break;
1832         default:
1833             impossible("Unknown type of gloves (%d)", uarmg->otyp);
1834             break;
1835         }
1836     }
1837
1838     tmp += omon_adj(mon, obj, TRUE);
1839     if (is_orc(mon->data)
1840         && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
1841         tmp++;
1842     if (guaranteed_hit) {
1843         tmp += 1000; /* Guaranteed hit */
1844     }
1845
1846     if (obj->oclass == GEM_CLASS && is_unicorn(mon->data)) {
1847         if (mon->msleeping || !mon->mcanmove) {
1848             tmiss(obj, mon, FALSE);
1849             return 0;
1850         } else if (mon->mtame) {
1851 /*JP
1852             pline("%s catches and drops %s.", Monnam(mon), the(xname(obj)));
1853 */
1854             pline("%s\82Í%s\82ð\82­\82í\82¦\82Ä\92u\82¢\82½\81D", Monnam(mon), xname(obj));
1855             return 0;
1856         } else {
1857 /*JP
1858             pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1859 */
1860             pline("%s\82Í%s\82ð\82­\82í\82¦\82½\81D", Monnam(mon), xname(obj));
1861             return gem_accept(mon, obj);
1862         }
1863     }
1864
1865     /* don't make game unwinnable if naive player throws artifact
1866        at leader... (kicked artifact is ok too; HMON_APPLIED could
1867        occur if quest artifact polearm or grapnel ever gets added) */
1868     if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) {
1869         /* AIS: changes to wakeup() means that it's now less inappropriate here
1870            than it used to be, but the manual version works just as well */
1871         mon->msleeping = 0;
1872         mon->mstrategy &= ~STRAT_WAITMASK;
1873
1874         if (mon->mcanmove) {
1875 /*JP
1876             pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1877 */
1878             pline("%s\82Í%s\82ð\92Í\82ñ\82¾\81D", Monnam(mon), xname(obj));
1879             if (mon->mpeaceful) {
1880                 boolean next2u = monnear(mon, u.ux, u.uy);
1881
1882                 finish_quest(obj); /* acknowledge quest completion */
1883 #if 0 /*JP*/
1884                 pline("%s %s %s back to you.", Monnam(mon),
1885                       (next2u ? "hands" : "tosses"), the(xname(obj)));
1886 #else
1887                 pline("%s\82Í%s\82ð\82 \82È\82½\82É\95Ô\82µ\82½\81D", Monnam(mon),
1888                       xname(obj));
1889 #endif
1890                 if (!next2u)
1891                     sho_obj_return_to_u(obj);
1892                 obj = addinv(obj); /* back into your inventory */
1893                 (void) encumber_msg();
1894             } else {
1895                 /* angry leader caught it and isn't returning it */
1896                 if (*u.ushops || obj->unpaid) /* not very likely... */
1897                     check_shop_obj(obj, mon->mx, mon->my, FALSE);
1898                 (void) mpickobj(mon, obj);
1899             }
1900             return 1; /* caller doesn't need to place it */
1901         }
1902         return 0;
1903     }
1904
1905     dieroll = rnd(20);
1906
1907     if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1908         || obj->oclass == GEM_CLASS) {
1909         if (hmode == HMON_KICKED) {
1910             /* throwing adjustments and weapon skill bonus don't apply */
1911             tmp -= (is_ammo(obj) ? 5 : 3);
1912         } else if (is_ammo(obj)) {
1913             if (!ammo_and_launcher(obj, uwep)) {
1914                 tmp -= 4;
1915             } else {
1916                 tmp += uwep->spe - greatest_erosion(uwep);
1917                 tmp += weapon_hit_bonus(uwep);
1918                 if (uwep->oartifact)
1919                     tmp += spec_abon(uwep, mon);
1920                 /*
1921                  * Elves and Samurais are highly trained w/bows,
1922                  * especially their own special types of bow.
1923                  * Polymorphing won't make you a bow expert.
1924                  */
1925                 if ((Race_if(PM_ELF) || Role_if(PM_SAMURAI))
1926                     && (!Upolyd || your_race(youmonst.data))
1927                     && objects[uwep->otyp].oc_skill == P_BOW) {
1928                     tmp++;
1929                     if (Race_if(PM_ELF) && uwep->otyp == ELVEN_BOW)
1930                         tmp++;
1931                     else if (Role_if(PM_SAMURAI) && uwep->otyp == YUMI)
1932                         tmp++;
1933                 }
1934             }
1935         } else { /* thrown non-ammo or applied polearm/grapnel */
1936             if (otyp == BOOMERANG) /* arbitrary */
1937                 tmp += 4;
1938             else if (throwing_weapon(obj)) /* meant to be thrown */
1939                 tmp += 2;
1940             else if (obj == thrownobj) /* not meant to be thrown */
1941                 tmp -= 2;
1942             /* we know we're dealing with a weapon or weptool handled
1943                by WEAPON_SKILLS once ammo objects have been excluded */
1944             tmp += weapon_hit_bonus(obj);
1945         }
1946
1947         if (tmp >= dieroll) {
1948             boolean wasthrown = (thrownobj != 0),
1949                     /* remember weapon attribute; hmon() might destroy obj */
1950                     chopper = is_axe(obj);
1951
1952             /* attack hits mon */
1953             if (hmode == HMON_APPLIED)
1954                 u.uconduct.weaphit++;
1955             if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */
1956                 if (mon->wormno)
1957                     cutworm(mon, bhitpos.x, bhitpos.y, chopper);
1958             }
1959             exercise(A_DEX, TRUE);
1960             /* if hero was swallowed and projectile killed the engulfer,
1961                'obj' got added to engulfer's inventory and then dropped,
1962                so we can't safely use that pointer anymore; it escapes
1963                the chance to be used up here... */
1964             if (wasthrown && !thrownobj)
1965                 return 1;
1966
1967             /* projectiles other than magic stones sometimes disappear
1968                when thrown; projectiles aren't among the types of weapon
1969                that hmon() might have destroyed so obj is intact */
1970             if (objects[otyp].oc_skill < P_NONE
1971                 && objects[otyp].oc_skill > -P_BOOMERANG
1972                 && !objects[otyp].oc_magic) {
1973                 /* we were breaking 2/3 of everything unconditionally.
1974                  * we still don't want anything to survive unconditionally,
1975                  * but we need ammo to stay around longer on average.
1976                  */
1977                 int broken, chance;
1978
1979                 chance = 3 + greatest_erosion(obj) - obj->spe;
1980                 if (chance > 1)
1981                     broken = rn2(chance);
1982                 else
1983                     broken = !rn2(4);
1984                 if (obj->blessed && !rnl(4))
1985                     broken = 0;
1986
1987                 if (broken) {
1988                     if (*u.ushops || obj->unpaid)
1989                         check_shop_obj(obj, bhitpos.x, bhitpos.y, TRUE);
1990                     obfree(obj, (struct obj *) 0);
1991                     return 1;
1992                 }
1993             }
1994             passive_obj(mon, obj, (struct attack *) 0);
1995         } else {
1996             tmiss(obj, mon, TRUE);
1997             if (hmode == HMON_APPLIED)
1998                 wakeup(mon, TRUE);
1999         }
2000
2001     } else if (otyp == HEAVY_IRON_BALL) {
2002         exercise(A_STR, TRUE);
2003         if (tmp >= dieroll) {
2004             int was_swallowed = guaranteed_hit;
2005
2006             exercise(A_DEX, TRUE);
2007             if (!hmon(mon, obj, hmode, dieroll)) { /* mon killed */
2008                 if (was_swallowed && !u.uswallow && obj == uball)
2009                     return 1; /* already did placebc() */
2010             }
2011         } else {
2012             tmiss(obj, mon, TRUE);
2013         }
2014
2015     } else if (otyp == BOULDER) {
2016         exercise(A_STR, TRUE);
2017         if (tmp >= dieroll) {
2018             exercise(A_DEX, TRUE);
2019             (void) hmon(mon, obj, hmode, dieroll);
2020         } else {
2021             tmiss(obj, mon, TRUE);
2022         }
2023
2024     } else if ((otyp == EGG || otyp == CREAM_PIE || otyp == BLINDING_VENOM
2025                 || otyp == ACID_VENOM)
2026                && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
2027         (void) hmon(mon, obj, hmode, dieroll);
2028         return 1; /* hmon used it up */
2029
2030     } else if (obj->oclass == POTION_CLASS
2031                && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
2032         potionhit(mon, obj, POTHIT_HERO_THROW);
2033         return 1;
2034
2035     } else if (befriend_with_obj(mon->data, obj)
2036                || (mon->mtame && dogfood(mon, obj) <= ACCFOOD)) {
2037         if (tamedog(mon, obj)) {
2038             return 1; /* obj is gone */
2039         } else {
2040             tmiss(obj, mon, FALSE);
2041             mon->msleeping = 0;
2042             mon->mstrategy &= ~STRAT_WAITMASK;
2043         }
2044     } else if (guaranteed_hit) {
2045         /* this assumes that guaranteed_hit is due to swallowing */
2046         wakeup(mon, TRUE);
2047         if (obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])) {
2048             if (is_animal(u.ustuck->data)) {
2049                 minstapetrify(u.ustuck, TRUE);
2050                 /* Don't leave a cockatrice corpse available in a statue */
2051                 if (!u.uswallow) {
2052                     delobj(obj);
2053                     return 1;
2054                 }
2055             }
2056         }
2057 #if 0 /*JP*/
2058         pline("%s into %s %s.", Tobjnam(obj, "vanish"),
2059               s_suffix(mon_nam(mon)),
2060               is_animal(u.ustuck->data) ? "entrails" : "currents");
2061 #else
2062         pline("%s\82Í%s\82Ì%s\82Ö\8fÁ\82¦\82½\81D", xname(obj),
2063               mon_nam(mon),
2064               is_animal(u.ustuck->data) ? "\93à\91\9f\82Ì\92\86" : "\97¬\82ê");
2065 #endif
2066     } else {
2067         tmiss(obj, mon, TRUE);
2068     }
2069
2070     return 0;
2071 }
2072
2073 STATIC_OVL int
2074 gem_accept(mon, obj)
2075 register struct monst *mon;
2076 register struct obj *obj;
2077 {
2078     char buf[BUFSZ];
2079     boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type);
2080     boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE;
2081     int ret = 0;
2082 /*JP
2083     static NEARDATA const char nogood[] = " is not interested in your junk.";
2084 */
2085     static NEARDATA const char nogood[] = "\82 \82È\82½\82Ì\83K\83\89\83N\83^\82É\8b»\96¡\82ð\8e¦\82³\82È\82¢\81D";
2086 /*JP
2087     static NEARDATA const char acceptgift[] = " accepts your gift.";
2088 */
2089     static NEARDATA const char acceptgift[] = "\82 \82È\82½\82Ì\91¡\82è\95¨\82ð\8eó\82¯\82Æ\82Á\82½\81D";
2090 /*JP
2091     static NEARDATA const char maybeluck[] = " hesitatingly";
2092 */
2093     static NEARDATA const char maybeluck[] = "\82½\82ß\82ç\82¢\82È\82ª\82ç";
2094 /*JP
2095     static NEARDATA const char noluck[] = " graciously";
2096 */
2097     static NEARDATA const char noluck[] = "\92\9a\8fd\82É";
2098 /*JP
2099     static NEARDATA const char addluck[] = " gratefully";
2100 */
2101     static NEARDATA const char addluck[] = "\8aì\82ñ\82Å";
2102
2103     Strcpy(buf, Monnam(mon));
2104 #if 1 /*JP*/
2105     Strcat(buf, "\82Í");
2106 #endif
2107     mon->mpeaceful = 1;
2108     mon->mavenge = 0;
2109
2110     /* object properly identified */
2111     if (obj->dknown && objects[obj->otyp].oc_name_known) {
2112         if (is_gem) {
2113             if (is_buddy) {
2114                 Strcat(buf, addluck);
2115                 change_luck(5);
2116             } else {
2117                 Strcat(buf, maybeluck);
2118                 change_luck(rn2(7) - 3);
2119             }
2120         } else {
2121             Strcat(buf, nogood);
2122             goto nopick;
2123         }
2124         /* making guesses */
2125     } else if (has_oname(obj) || objects[obj->otyp].oc_uname) {
2126         if (is_gem) {
2127             if (is_buddy) {
2128                 Strcat(buf, addluck);
2129                 change_luck(2);
2130             } else {
2131                 Strcat(buf, maybeluck);
2132                 change_luck(rn2(3) - 1);
2133             }
2134         } else {
2135             Strcat(buf, nogood);
2136             goto nopick;
2137         }
2138         /* value completely unknown to @ */
2139     } else {
2140         if (is_gem) {
2141             if (is_buddy) {
2142                 Strcat(buf, addluck);
2143                 change_luck(1);
2144             } else {
2145                 Strcat(buf, maybeluck);
2146                 change_luck(rn2(3) - 1);
2147             }
2148         } else {
2149             Strcat(buf, noluck);
2150         }
2151     }
2152     Strcat(buf, acceptgift);
2153     if (*u.ushops || obj->unpaid)
2154         check_shop_obj(obj, mon->mx, mon->my, TRUE);
2155     (void) mpickobj(mon, obj); /* may merge and free obj */
2156     ret = 1;
2157
2158  nopick:
2159     if (!Blind)
2160         pline1(buf);
2161     if (!tele_restrict(mon))
2162         (void) rloc(mon, TRUE);
2163     return ret;
2164 }
2165
2166 /*
2167  * Comments about the restructuring of the old breaks() routine.
2168  *
2169  * There are now three distinct phases to object breaking:
2170  *     breaktest() - which makes the check/decision about whether the
2171  *                   object is going to break.
2172  *     breakmsg()  - which outputs a message about the breakage,
2173  *                   appropriate for that particular object. Should
2174  *                   only be called after a positive breaktest().
2175  *                   on the object and, if it going to be called,
2176  *                   it must be called before calling breakobj().
2177  *                   Calling breakmsg() is optional.
2178  *     breakobj()  - which actually does the breakage and the side-effects
2179  *                   of breaking that particular object. This should
2180  *                   only be called after a positive breaktest() on the
2181  *                   object.
2182  *
2183  * Each of the above routines is currently static to this source module.
2184  * There are two routines callable from outside this source module which
2185  * perform the routines above in the correct sequence.
2186  *
2187  *   hero_breaks() - called when an object is to be broken as a result
2188  *                   of something that the hero has done. (throwing it,
2189  *                   kicking it, etc.)
2190  *   breaks()      - called when an object is to be broken for some
2191  *                   reason other than the hero doing something to it.
2192  */
2193
2194 /*
2195  * The hero causes breakage of an object (throwing, dropping it, etc.)
2196  * Return 0 if the object didn't break, 1 if the object broke.
2197  */
2198 int
2199 hero_breaks(obj, x, y, from_invent)
2200 struct obj *obj;
2201 xchar x, y;          /* object location (ox, oy may not be right) */
2202 boolean from_invent; /* thrown or dropped by player; maybe on shop bill */
2203 {
2204     boolean in_view = Blind ? FALSE : (from_invent || cansee(x, y));
2205
2206     if (!breaktest(obj))
2207         return 0;
2208     breakmsg(obj, in_view);
2209     breakobj(obj, x, y, TRUE, from_invent);
2210     return 1;
2211 }
2212
2213 /*
2214  * The object is going to break for a reason other than the hero doing
2215  * something to it.
2216  * Return 0 if the object doesn't break, 1 if the object broke.
2217  */
2218 int
2219 breaks(obj, x, y)
2220 struct obj *obj;
2221 xchar x, y; /* object location (ox, oy may not be right) */
2222 {
2223     boolean in_view = Blind ? FALSE : cansee(x, y);
2224
2225     if (!breaktest(obj))
2226         return 0;
2227     breakmsg(obj, in_view);
2228     breakobj(obj, x, y, FALSE, FALSE);
2229     return 1;
2230 }
2231
2232 void
2233 release_camera_demon(obj, x, y)
2234 struct obj *obj;
2235 xchar x, y;
2236 {
2237     struct monst *mtmp;
2238     if (!rn2(3)
2239         && (mtmp = makemon(&mons[rn2(3) ? PM_HOMUNCULUS : PM_IMP], x, y,
2240                            NO_MM_FLAGS)) != 0) {
2241         if (canspotmon(mtmp))
2242 #if 0 /*JP*/
2243             pline("%s is released!", Hallucination
2244                                          ? An(rndmonnam(NULL))
2245                                          : "The picture-painting demon");
2246 #else
2247             pline("%s\82ª\89ð\95ú\82³\82ê\82½\81I", Hallucination
2248                                          ? rndmonnam(NULL)
2249                                          : "\82¨\8aG\95`\82«\82Ì\88«\96\82");
2250 #endif
2251         mtmp->mpeaceful = !obj->cursed;
2252         set_malign(mtmp);
2253     }
2254 }
2255
2256 /*
2257  * Unconditionally break an object. Assumes all resistance checks
2258  * and break messages have been delivered prior to getting here.
2259  */
2260 void
2261 breakobj(obj, x, y, hero_caused, from_invent)
2262 struct obj *obj;
2263 xchar x, y;          /* object location (ox, oy may not be right) */
2264 boolean hero_caused; /* is this the hero's fault? */
2265 boolean from_invent;
2266 {
2267     boolean fracture = FALSE;
2268
2269     switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2270     case MIRROR:
2271         if (hero_caused)
2272             change_luck(-2);
2273         break;
2274     case POT_WATER:      /* really, all potions */
2275         obj->in_use = 1; /* in case it's fatal */
2276         if (obj->otyp == POT_OIL && obj->lamplit) {
2277             explode_oil(obj, x, y);
2278         } else if (distu(x, y) <= 2) {
2279             if (!breathless(youmonst.data) || haseyes(youmonst.data)) {
2280                 if (obj->otyp != POT_WATER) {
2281                     if (!breathless(youmonst.data)) {
2282                         /* [what about "familiar odor" when known?] */
2283 /*JP
2284                         You("smell a peculiar odor...");
2285 */
2286                         You("\96ò\82Á\82Û\82¢\93õ\82¢\82ª\82µ\82½\81D\81D\81D");
2287                     } else {
2288 #if 0 /*JP*/
2289                         const char *eyes = body_part(EYE);
2290
2291                         if (eyecount(youmonst.data) != 1)
2292                             eyes = makeplural(eyes);
2293                         Your("%s %s.", eyes, vtense(eyes, "water"));
2294 #else
2295                         You("\97Ü%s\82É\82È\82Á\82½\81D", body_part(EYE));
2296 #endif
2297                     }
2298                 }
2299                 potionbreathe(obj);
2300             }
2301         }
2302         /* monster breathing isn't handled... [yet?] */
2303         break;
2304     case EXPENSIVE_CAMERA:
2305         release_camera_demon(obj, x, y);
2306         break;
2307     case EGG:
2308         /* breaking your own eggs is bad luck */
2309         if (hero_caused && obj->spe && obj->corpsenm >= LOW_PM)
2310             change_luck((schar) -min(obj->quan, 5L));
2311         break;
2312     case BOULDER:
2313     case STATUE:
2314         /* caller will handle object disposition;
2315            we're just doing the shop theft handling */
2316         fracture = TRUE;
2317         break;
2318     default:
2319         break;
2320     }
2321
2322     if (hero_caused) {
2323         if (from_invent || obj->unpaid) {
2324             if (*u.ushops || obj->unpaid)
2325                 check_shop_obj(obj, x, y, TRUE);
2326         } else if (!obj->no_charge && costly_spot(x, y)) {
2327             /* it is assumed that the obj is a floor-object */
2328             char *o_shop = in_rooms(x, y, SHOPBASE);
2329             struct monst *shkp = shop_keeper(*o_shop);
2330
2331             if (shkp) { /* (implies *o_shop != '\0') */
2332                 static NEARDATA long lastmovetime = 0L;
2333                 static NEARDATA boolean peaceful_shk = FALSE;
2334                 /*  We want to base shk actions on her peacefulness
2335                     at start of this turn, so that "simultaneous"
2336                     multiple breakage isn't drastically worse than
2337                     single breakage.  (ought to be done via ESHK)  */
2338                 if (moves != lastmovetime)
2339                     peaceful_shk = shkp->mpeaceful;
2340                 if (stolen_value(obj, x, y, peaceful_shk, FALSE) > 0L
2341                     && (*o_shop != u.ushops[0] || !inside_shop(u.ux, u.uy))
2342                     && moves != lastmovetime)
2343                     make_angry_shk(shkp, x, y);
2344                 lastmovetime = moves;
2345             }
2346         }
2347     }
2348     if (!fracture)
2349         delobj(obj);
2350 }
2351
2352 /*
2353  * Check to see if obj is going to break, but don't actually break it.
2354  * Return 0 if the object isn't going to break, 1 if it is.
2355  */
2356 boolean
2357 breaktest(obj)
2358 struct obj *obj;
2359 {
2360     if (obj_resists(obj, 1, 99))
2361         return 0;
2362     if (objects[obj->otyp].oc_material == GLASS && !obj->oartifact
2363         && obj->oclass != GEM_CLASS)
2364         return 1;
2365     switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2366     case EXPENSIVE_CAMERA:
2367     case POT_WATER: /* really, all potions */
2368     case EGG:
2369     case CREAM_PIE:
2370     case MELON:
2371     case ACID_VENOM:
2372     case BLINDING_VENOM:
2373         return 1;
2374     default:
2375         return 0;
2376     }
2377 }
2378
2379 STATIC_OVL void
2380 breakmsg(obj, in_view)
2381 struct obj *obj;
2382 boolean in_view;
2383 {
2384     const char *to_pieces;
2385
2386 #if 0 /*JP*/
2387     to_pieces = "";
2388 #else
2389     /* "shatter" \81¨ "\82±\82È\82²\82È\82É\82È\82Á\82½"
2390        "shatter into a thousand pieces" \81¨ "\82­\82¾\82¯\82Ä\82Î\82ç\82Î\82ç\82É\82È\82Á\82½" */
2391     to_pieces = "\82±\82È\82²\82È";
2392 #endif
2393     switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2394     default: /* glass or crystal wand */
2395         if (obj->oclass != WAND_CLASS)
2396             impossible("breaking odd object?");
2397         /*FALLTHRU*/
2398     case CRYSTAL_PLATE_MAIL:
2399     case LENSES:
2400     case MIRROR:
2401     case CRYSTAL_BALL:
2402     case EXPENSIVE_CAMERA:
2403 /*JP
2404         to_pieces = " into a thousand pieces";
2405 */
2406         to_pieces = "\82­\82¾\82¯\82Ä\82Î\82ç\82Î\82ç";
2407     /*FALLTHRU*/
2408     case POT_WATER: /* really, all potions */
2409         if (!in_view)
2410 /*JP
2411             You_hear("%s shatter!", something);
2412 */
2413             You_hear("%s\82ª\89ó\82ê\82é\89¹\82ð\95·\82¢\82½\81I", something);
2414         else
2415 #if 0 /*JP*/
2416             pline("%s shatter%s%s!", Doname2(obj),
2417                   (obj->quan == 1L) ? "s" : "", to_pieces);
2418 #else
2419             pline("%s\82Í%s\82É\82È\82Á\82½\81I", Doname2(obj), to_pieces);
2420 #endif
2421         break;
2422     case EGG:
2423     case MELON:
2424 /*JP
2425         pline("Splat!");
2426 */
2427         pline("\83r\83`\83\83\81I");
2428         break;
2429     case CREAM_PIE:
2430         if (in_view)
2431 /*JP
2432             pline("What a mess!");
2433 */
2434             pline("\82±\82è\82á\82Ð\82Ç\82¢\81I");
2435         break;
2436     case ACID_VENOM:
2437     case BLINDING_VENOM:
2438 /*JP
2439         pline("Splash!");
2440 */
2441         pline("\83r\83`\83\83\81I");
2442         break;
2443     }
2444 }
2445
2446 STATIC_OVL int
2447 throw_gold(obj)
2448 struct obj *obj;
2449 {
2450     int range, odx, ody;
2451     register struct monst *mon;
2452
2453     if (!u.dx && !u.dy && !u.dz) {
2454 /*JP
2455         You("cannot throw gold at yourself.");
2456 */
2457         pline("\8e©\95ª\82É\8bà\89Ý\82ð\93\8a\82°\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
2458         return 0;
2459     }
2460     freeinv(obj);
2461     if (u.uswallow) {
2462 #if 0 /*JP*/
2463         pline(is_animal(u.ustuck->data) ? "%s in the %s's entrails."
2464                                         : "%s into %s.",
2465               "The money disappears", mon_nam(u.ustuck));
2466 #else
2467         pline(is_animal(u.ustuck->data) ? "\8bà\89Ý\82Í%s\82Ì\95 \82Ì\92\86\82Ö\8fÁ\82¦\82Ä\82¢\82Á\82½\81D"
2468                                         : "\8bà\89Ý\82Í%s\82Ì\92\86\82Ö\8fÁ\82¦\82Ä\82¢\82Á\82½\81D",
2469               mon_nam(u.ustuck));
2470 #endif
2471         add_to_minv(u.ustuck, obj);
2472         return 1;
2473     }
2474
2475     if (u.dz) {
2476         if (u.dz < 0 && !Is_airlevel(&u.uz) && !Underwater
2477             && !Is_waterlevel(&u.uz)) {
2478 #if 0 /*JP*/
2479             pline_The("gold hits the %s, then falls back on top of your %s.",
2480                       ceiling(u.ux, u.uy), body_part(HEAD));
2481 #else
2482             pline("\8bà\89Ý\82Í%s\82É\96½\92\86\82µ\81C\82 \82È\82½\82Ì%s\82Ì\90^\8fã\82É\97\8e\82¿\82Ä\82«\82½\81D",
2483                   ceiling(u.ux,u.uy), body_part(HEAD));
2484 #endif
2485             /* some self damage? */
2486             if (uarmh)
2487 /*JP
2488                 pline("Fortunately, you are wearing %s!",
2489 */
2490                 pline("\8dK\89^\82È\82±\82Æ\82É\81C\82 \82È\82½\82Í%s\82ð\90g\82É\82Â\82¯\82Ä\82¢\82é\81I",
2491                       an(helm_simple_name(uarmh)));
2492         }
2493         bhitpos.x = u.ux;
2494         bhitpos.y = u.uy;
2495     } else {
2496         /* consistent with range for normal objects */
2497         range = (int) ((ACURRSTR) / 2 - obj->owt / 40);
2498
2499         /* see if the gold has a place to move into */
2500         odx = u.ux + u.dx;
2501         ody = u.uy + u.dy;
2502         if (!ZAP_POS(levl[odx][ody].typ) || closed_door(odx, ody)) {
2503             bhitpos.x = u.ux;
2504             bhitpos.y = u.uy;
2505         } else {
2506             mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
2507                        (int FDECL((*), (MONST_P, OBJ_P))) 0,
2508                        (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
2509             if (!obj)
2510                 return 1; /* object is gone */
2511             if (mon) {
2512                 if (ghitm(mon, obj)) /* was it caught? */
2513                     return 1;
2514             } else {
2515                 if (ship_object(obj, bhitpos.x, bhitpos.y, FALSE))
2516                     return 1;
2517             }
2518         }
2519     }
2520
2521 /*JP
2522     if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall"))
2523 */
2524     if (flooreffects(obj, bhitpos.x, bhitpos.y, "\97\8e\82¿\82é"))
2525         return 1;
2526     if (u.dz > 0)
2527 /*JP
2528         pline_The("gold hits the %s.", surface(bhitpos.x, bhitpos.y));
2529 */
2530         pline("\8bà\89Ý\82Í%s\82É\96½\92\86\82µ\82½\81D", surface(bhitpos.x, bhitpos.y));
2531     place_object(obj, bhitpos.x, bhitpos.y);
2532     if (*u.ushops)
2533         sellobj(obj, bhitpos.x, bhitpos.y);
2534     stackobj(obj);
2535     newsym(bhitpos.x, bhitpos.y);
2536     return 1;
2537 }
2538
2539 /*dothrow.c*/