OSDN Git Service

update year to 2020
[jnethack/source.git] / src / dothrow.c
1 /* NetHack 3.6  dothrow.c       $NHDT-Date: 1573688688 2019/11/13 23:44:48 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.164 $ */
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-2020            */
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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:T*/
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     int range, urange;
1309     boolean crossbowing, clear_thrownobj = FALSE,
1310             impaired = (Confusion || Stunned || Blind
1311                         || Hallucination || Fumbling),
1312             tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0);
1313
1314     notonhead = FALSE; /* reset potentially stale value */
1315     if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) {
1316         boolean slipok = TRUE;
1317
1318         if (ammo_and_launcher(obj, uwep)) {
1319 /*JP
1320             pline("%s!", Tobjnam(obj, "misfire"));
1321 */
1322             pline("%s\82Í\82Í\82¸\82ê\82½\81I", xname(obj));
1323         } else {
1324             /* only slip if it's greased or meant to be thrown */
1325             if (obj->greased || throwing_weapon(obj))
1326                 /* BUG: this message is grammatically incorrect if obj has
1327                    a plural name; greased gloves or boots for instance. */
1328 /*JP
1329                 pline("%s as you throw it!", Tobjnam(obj, "slip"));
1330 */
1331                 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));
1332             else
1333                 slipok = FALSE;
1334         }
1335         if (slipok) {
1336             u.dx = rn2(3) - 1;
1337             u.dy = rn2(3) - 1;
1338             if (!u.dx && !u.dy)
1339                 u.dz = 1;
1340             impaired = TRUE;
1341         }
1342     }
1343
1344     if ((u.dx || u.dy || (u.dz < 1))
1345         && calc_capacity((int) obj->owt) > SLT_ENCUMBER
1346         && (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
1347                    : (u.uhp < 10 && u.uhp != u.uhpmax))
1348         && obj->owt > (unsigned) ((Upolyd ? u.mh : u.uhp) * 2)
1349         && !Is_airlevel(&u.uz)) {
1350 /*JP
1351         You("have so little stamina, %s drops from your grasp.",
1352 */
1353         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",
1354             the(xname(obj)));
1355         exercise(A_CON, FALSE);
1356         u.dx = u.dy = 0;
1357         u.dz = 1;
1358     }
1359
1360     thrownobj = obj;
1361     thrownobj->was_thrown = 1;
1362     iflags.returning_missile = ((obj->oartifact == ART_MJOLLNIR
1363                                  && Role_if(PM_VALKYRIE))
1364                                 || tethered_weapon) ? (genericptr_t) obj
1365                                                     : (genericptr_t) 0;
1366     /* NOTE:  No early returns after this point or returning_missile
1367        will be left with a stale pointer. */
1368
1369     if (u.uswallow) {
1370         if (obj == uball) {
1371             uball->ox = uchain->ox = u.ux;
1372             uball->oy = uchain->oy = u.uy;
1373         }
1374         mon = u.ustuck;
1375         bhitpos.x = mon->mx;
1376         bhitpos.y = mon->my;
1377         if (tethered_weapon)
1378             tmp_at(DISP_TETHER, obj_to_glyph(obj, rn2_on_display_rng));
1379     } else if (u.dz) {
1380         if (u.dz < 0
1381             /* Mjollnir must we wielded to be thrown--caller verifies this;
1382                aklys must we wielded as primary to return when thrown */
1383             && iflags.returning_missile
1384             && !impaired) {
1385 #if 0 /*JP:T*/
1386             pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
1387                   ceiling(u.ux, u.uy));
1388 #else
1389             pline("%s\82Í%s\82É\96½\92\86\82µ\82 \82È\82½\82Ì\8eè\82É\96ß\82Á\82Ä\82«\82½\81I", xname(obj),
1390                   ceiling(u.ux,u.uy));
1391 #endif
1392             obj = addinv(obj);
1393             (void) encumber_msg();
1394             if (obj->owornmask & W_QUIVER) /* in case addinv() autoquivered */
1395                 setuqwep((struct obj *) 0);
1396             setuwep(obj);
1397             u.twoweap = twoweap;
1398         } else if (u.dz < 0) {
1399             (void) toss_up(obj, rn2(5) && !Underwater);
1400         } else if (u.dz > 0 && u.usteed && obj->oclass == POTION_CLASS
1401                    && rn2(6)) {
1402             /* alternative to prayer or wand of opening/spell of knock
1403                for dealing with cursed saddle:  throw holy water > */
1404             potionhit(u.usteed, obj, POTHIT_HERO_THROW);
1405         } else {
1406             hitfloor(obj, TRUE);
1407         }
1408         clear_thrownobj = TRUE;
1409         goto throwit_return;
1410
1411     } else if (obj->otyp == BOOMERANG && !Underwater) {
1412         if (Is_airlevel(&u.uz) || Levitation)
1413             hurtle(-u.dx, -u.dy, 1, TRUE);
1414         mon = boomhit(obj, u.dx, u.dy);
1415         if (mon == &youmonst) { /* the thing was caught */
1416             exercise(A_DEX, TRUE);
1417             obj = addinv(obj);
1418             (void) encumber_msg();
1419             if (wep_mask && !(obj->owornmask & wep_mask)) {
1420                 setworn(obj, wep_mask);
1421                 u.twoweap = twoweap;
1422             }
1423             clear_thrownobj = TRUE;
1424             goto throwit_return;
1425         }
1426     } else {
1427         /* crossbow range is independent of strength */
1428         crossbowing = (ammo_and_launcher(obj, uwep)
1429                        && weapon_type(uwep) == P_CROSSBOW);
1430         urange = (crossbowing ? 18 : (int) ACURRSTR) / 2;
1431         /* balls are easy to throw or at least roll;
1432          * also, this insures the maximum range of a ball is greater
1433          * than 1, so the effects from throwing attached balls are
1434          * actually possible
1435          */
1436         if (obj->otyp == HEAVY_IRON_BALL)
1437             range = urange - (int) (obj->owt / 100);
1438         else
1439             range = urange - (int) (obj->owt / 40);
1440         if (obj == uball) {
1441             if (u.ustuck)
1442                 range = 1;
1443             else if (range >= 5)
1444                 range = 5;
1445         }
1446         if (range < 1)
1447             range = 1;
1448
1449         if (is_ammo(obj)) {
1450             if (ammo_and_launcher(obj, uwep)) {
1451                 if (crossbowing)
1452                     range = BOLT_LIM;
1453                 else
1454                     range++;
1455             } else if (obj->oclass != GEM_CLASS)
1456                 range /= 2;
1457         }
1458
1459         if (Is_airlevel(&u.uz) || Levitation) {
1460             /* action, reaction... */
1461             urange -= range;
1462             if (urange < 1)
1463                 urange = 1;
1464             range -= urange;
1465             if (range < 1)
1466                 range = 1;
1467         }
1468
1469         if (obj->otyp == BOULDER)
1470             range = 20; /* you must be giant */
1471         else if (obj->oartifact == ART_MJOLLNIR)
1472             range = (range + 1) / 2; /* it's heavy */
1473         else if (tethered_weapon) /* primary weapon is aklys */
1474             /* if an aklys is going to return, range is limited by the
1475                length of the attached cord [implicit aspect of item] */
1476             range = min(range, BOLT_LIM / 2);
1477         else if (obj == uball && u.utrap && u.utraptype == TT_INFLOOR)
1478             range = 1;
1479
1480         if (Underwater)
1481             range = 1;
1482
1483         mon = bhit(u.dx, u.dy, range,
1484                    tethered_weapon ? THROWN_TETHERED_WEAPON : THROWN_WEAPON,
1485                    (int FDECL((*), (MONST_P, OBJ_P))) 0,
1486                    (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
1487         thrownobj = obj; /* obj may be null now */
1488
1489         /* have to do this after bhit() so u.ux & u.uy are correct */
1490         if (Is_airlevel(&u.uz) || Levitation)
1491             hurtle(-u.dx, -u.dy, urange, TRUE);
1492
1493         if (!obj) {
1494             /* bhit display cleanup was left with this caller
1495                for tethered_weapon, but clean it up now since
1496                we're about to return */
1497             if (tethered_weapon)
1498                 tmp_at(DISP_END, 0);
1499             goto throwit_return;
1500         }
1501     }
1502
1503     if (mon) {
1504         boolean obj_gone;
1505
1506         if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) {
1507             clear_thrownobj = TRUE;
1508             goto throwit_return; /* alert shk caught it */
1509         }
1510         (void) snuff_candle(obj);
1511         notonhead = (bhitpos.x != mon->mx || bhitpos.y != mon->my);
1512         obj_gone = thitmonst(mon, obj);
1513         /* Monster may have been tamed; this frees old mon [obsolete] */
1514         mon = m_at(bhitpos.x, bhitpos.y);
1515
1516         /* [perhaps this should be moved into thitmonst or hmon] */
1517         if (mon && mon->isshk
1518             && (!inside_shop(u.ux, u.uy)
1519                 || !index(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops)))
1520             hot_pursuit(mon);
1521
1522         if (obj_gone)
1523             thrownobj = (struct obj *) 0;
1524     }
1525
1526     if (!thrownobj) {
1527         /* missile has already been handled */
1528         if (tethered_weapon)
1529             tmp_at(DISP_END, 0);
1530     } else if (u.uswallow && !iflags.returning_missile) {
1531  swallowit:
1532         if (obj != uball)
1533             (void) mpickobj(u.ustuck, obj); /* clears 'thrownobj' */
1534         else
1535             clear_thrownobj = TRUE;
1536         goto throwit_return;
1537     } else {
1538         /* Mjollnir must be wielded to be thrown--caller verifies this;
1539            aklys must be wielded as primary to return when thrown */
1540         if (iflags.returning_missile) { /* Mjollnir or aklys */
1541             if (rn2(100)) {
1542                 if (tethered_weapon)
1543                     tmp_at(DISP_END, BACKTRACK);
1544                 else
1545                     sho_obj_return_to_u(obj); /* display its flight */
1546
1547                 if (!impaired && rn2(100)) {
1548 /*JP
1549                     pline("%s to your hand!", Tobjnam(obj, "return"));
1550 */
1551                     pline("%s\82Í\82 \82È\82½\82Ì\8eè\82É\96ß\82Á\82Ä\82«\82½\81I", xname(obj));
1552                     obj = addinv(obj);
1553                     (void) encumber_msg();
1554                     /* addinv autoquivers an aklys if quiver is empty;
1555                        if obj is quivered, remove it before wielding */
1556                     if (obj->owornmask & W_QUIVER)
1557                         setuqwep((struct obj *) 0);
1558                     setuwep(obj);
1559                     u.twoweap = twoweap;
1560                     if (cansee(bhitpos.x, bhitpos.y))
1561                         newsym(bhitpos.x, bhitpos.y);
1562                 } else {
1563                     int dmg = rn2(2);
1564
1565                     if (!dmg) {
1566 #if 0 /*JP:T*/
1567                         pline(Blind ? "%s lands %s your %s."
1568                                     : "%s back to you, landing %s your %s.",
1569                               Blind ? Something : Tobjnam(obj, "return"),
1570                               Levitation ? "beneath" : "at",
1571                               makeplural(body_part(FOOT)));
1572 #else
1573                         pline("%s\82Í%s\82 \82È\82½\82Ì%s\82Ì%s\82É\97\8e\82¿\82½\81D",
1574                               xname(obj),
1575                               Blind ? "" : "\96ß\82Á\82Ä\82«\82Ä\81C",
1576                               body_part(FOOT),
1577                               Levitation ? "\89º" : "\82»\82Î");
1578 #endif
1579                     } else {
1580                         dmg += rnd(3);
1581 #if 0 /*JP:T*/
1582                         pline(Blind ? "%s your %s!"
1583                                     : "%s back toward you, hitting your %s!",
1584                               Tobjnam(obj, Blind ? "hit" : "fly"),
1585                               body_part(ARM));
1586 #else
1587                         pline("%s\82Í%s\82 \82È\82½\82Ì%s\82É\96½\92\86\82µ\82½\81I",
1588                               xname(obj),
1589                               Blind ? "" : "\96ß\82Á\82Ä\82«\82Ä\81C",
1590                               body_part(ARM));
1591 #endif
1592                         if (obj->oartifact)
1593                             (void) artifact_hit((struct monst *) 0, &youmonst,
1594                                                 obj, &dmg, 0);
1595 #if 0 /*JP*/
1596                         losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
1597                                KILLED_BY);
1598 #else
1599                         {
1600                             char jbuf[BUFSZ];
1601                             Sprintf(jbuf, "%s\82Å", xname(obj));
1602                             losehp(Maybe_Half_Phys(dmg), jbuf, KILLED_BY);
1603                         }
1604 #endif
1605                     }
1606
1607                     if (u.uswallow)
1608                         goto swallowit;
1609                     if (!ship_object(obj, u.ux, u.uy, FALSE))
1610                         dropy(obj);
1611                 }
1612                 clear_thrownobj = TRUE;
1613                 goto throwit_return;
1614             } else {
1615                 if (tethered_weapon)
1616                     tmp_at(DISP_END, 0);
1617                 /* when this location is stepped on, the weapon will be
1618                    auto-picked up due to 'obj->was_thrown' of 1;
1619                    addinv() prevents thrown Mjollnir from being placed
1620                    into the quiver slot, but an aklys will end up there if
1621                    that slot is empty at the time; since hero will need to
1622                    explicitly rewield the weapon to get throw-and-return
1623                    capability back anyway, quivered or not shouldn't matter */
1624 /*JP
1625                 pline("%s to return!", Tobjnam(obj, "fail"));
1626 */
1627                 pline("%s\82Í\96ß\82é\82Ì\82É\8e¸\94s\82µ\82½\81I", xname(obj));
1628
1629                 if (u.uswallow)
1630                     goto swallowit;
1631                 /* continue below with placing 'obj' at target location */
1632             }
1633         }
1634
1635         if ((!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj))
1636             /* venom [via #monster to spit while poly'd] fails breaktest()
1637                but we want to force breakage even when location IS_SOFT() */
1638             || obj->oclass == VENOM_CLASS) {
1639             tmp_at(DISP_FLASH, obj_to_glyph(obj, rn2_on_display_rng));
1640             tmp_at(bhitpos.x, bhitpos.y);
1641             delay_output();
1642             tmp_at(DISP_END, 0);
1643             breakmsg(obj, cansee(bhitpos.x, bhitpos.y));
1644             breakobj(obj, bhitpos.x, bhitpos.y, TRUE, TRUE);
1645             clear_thrownobj = TRUE;
1646             goto throwit_return;
1647         }
1648 /*JP
1649         if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall")) {
1650 */
1651         if (flooreffects(obj,bhitpos.x, bhitpos.y, "\97\8e\82¿\82é")) {
1652             clear_thrownobj = TRUE;
1653             goto throwit_return;
1654         }
1655         obj_no_longer_held(obj);
1656         if (mon && mon->isshk && is_pick(obj)) {
1657             if (cansee(bhitpos.x, bhitpos.y))
1658 /*JP
1659                 pline("%s snatches up %s.", Monnam(mon), the(xname(obj)));
1660 */
1661                 pline("%s\82Í%s\82ð\92D\82¢\82Æ\82Á\82½\81D", Monnam(mon), xname(obj));
1662             if (*u.ushops || obj->unpaid)
1663                 check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1664             (void) mpickobj(mon, obj); /* may merge and free obj */
1665             clear_thrownobj = TRUE;
1666             goto throwit_return;
1667         }
1668         (void) snuff_candle(obj);
1669         if (!mon && ship_object(obj, bhitpos.x, bhitpos.y, FALSE)) {
1670             clear_thrownobj = TRUE;
1671             goto throwit_return;
1672         }
1673         thrownobj = (struct obj *) 0;
1674         place_object(obj, bhitpos.x, bhitpos.y);
1675         /* container contents might break;
1676            do so before turning ownership of thrownobj over to shk
1677            (container_impact_dmg handles item already owned by shop) */
1678         if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ))
1679             /* <x,y> is spot where you initiated throw, not bhitpos */
1680             container_impact_dmg(obj, u.ux, u.uy);
1681         /* charge for items thrown out of shop;
1682            shk takes possession for items thrown into one */
1683         if ((*u.ushops || obj->unpaid) && obj != uball)
1684             check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1685
1686         stackobj(obj);
1687         if (obj == uball)
1688             drop_ball(bhitpos.x, bhitpos.y);
1689         if (cansee(bhitpos.x, bhitpos.y))
1690             newsym(bhitpos.x, bhitpos.y);
1691         if (obj_sheds_light(obj))
1692             vision_full_recalc = 1;
1693     }
1694
1695  throwit_return:
1696     iflags.returning_missile = (genericptr_t) 0;
1697     if (clear_thrownobj)
1698         thrownobj = (struct obj *) 0;
1699     return;
1700 }
1701
1702 /* an object may hit a monster; various factors adjust chance of hitting */
1703 int
1704 omon_adj(mon, obj, mon_notices)
1705 struct monst *mon;
1706 struct obj *obj;
1707 boolean mon_notices;
1708 {
1709     int tmp = 0;
1710
1711     /* size of target affects the chance of hitting */
1712     tmp += (mon->data->msize - MZ_MEDIUM); /* -2..+5 */
1713     /* sleeping target is more likely to be hit */
1714     if (mon->msleeping) {
1715         tmp += 2;
1716         if (mon_notices)
1717             mon->msleeping = 0;
1718     }
1719     /* ditto for immobilized target */
1720     if (!mon->mcanmove || !mon->data->mmove) {
1721         tmp += 4;
1722         if (mon_notices && mon->data->mmove && !rn2(10)) {
1723             mon->mcanmove = 1;
1724             mon->mfrozen = 0;
1725         }
1726     }
1727     /* some objects are more likely to hit than others */
1728     switch (obj->otyp) {
1729     case HEAVY_IRON_BALL:
1730         if (obj != uball)
1731             tmp += 2;
1732         break;
1733     case BOULDER:
1734         tmp += 6;
1735         break;
1736     default:
1737         if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1738             || obj->oclass == GEM_CLASS)
1739             tmp += hitval(obj, mon);
1740         break;
1741     }
1742     return tmp;
1743 }
1744
1745 /* thrown object misses target monster */
1746 STATIC_OVL void
1747 tmiss(obj, mon, maybe_wakeup)
1748 struct obj *obj;
1749 struct monst *mon;
1750 boolean maybe_wakeup;
1751 {
1752     const char *missile = mshot_xname(obj);
1753
1754     /* If the target can't be seen or doesn't look like a valid target,
1755        avoid "the arrow misses it," or worse, "the arrows misses the mimic."
1756        An attentive player will still notice that this is different from
1757        an arrow just landing short of any target (no message in that case),
1758        so will realize that there is a valid target here anyway. */
1759     if (!canseemon(mon) || (M_AP_TYPE(mon) && M_AP_TYPE(mon) != M_AP_MONSTER))
1760 /*JP
1761         pline("%s %s.", The(missile), otense(obj, "miss"));
1762 */
1763         pline("%s\82Í\82Í\82¸\82ê\82½\81D", missile);
1764     else
1765         miss(missile, mon);
1766     if (maybe_wakeup && !rn2(3))
1767         wakeup(mon, TRUE);
1768     return;
1769 }
1770
1771 #define quest_arti_hits_leader(obj, mon)      \
1772     (obj->oartifact && is_quest_artifact(obj) \
1773      && mon->m_id == quest_status.leader_m_id)
1774
1775 /*
1776  * Object thrown by player arrives at monster's location.
1777  * Return 1 if obj has disappeared or otherwise been taken care of,
1778  * 0 if caller must take care of it.
1779  * Also used for kicked objects and for polearms/grapnel applied at range.
1780  */
1781 int
1782 thitmonst(mon, obj)
1783 register struct monst *mon;
1784 register struct obj *obj; /* thrownobj or kickedobj or uwep */
1785 {
1786     register int tmp;     /* Base chance to hit */
1787     register int disttmp; /* distance modifier */
1788     int otyp = obj->otyp, hmode;
1789     boolean guaranteed_hit = (u.uswallow && mon == u.ustuck);
1790     int dieroll;
1791
1792     hmode = (obj == uwep) ? HMON_APPLIED
1793               : (obj == kickedobj) ? HMON_KICKED
1794                 : HMON_THROWN;
1795
1796     /* Differences from melee weapons:
1797      *
1798      * Dex still gives a bonus, but strength does not.
1799      * Polymorphed players lacking attacks may still throw.
1800      * There's a base -1 to hit.
1801      * No bonuses for fleeing or stunned targets (they don't dodge
1802      *    melee blows as readily, but dodging arrows is hard anyway).
1803      * Not affected by traps, etc.
1804      * Certain items which don't in themselves do damage ignore 'tmp'.
1805      * Distance and monster size affect chance to hit.
1806      */
1807     tmp = -1 + Luck + find_mac(mon) + u.uhitinc
1808           + maybe_polyd(youmonst.data->mlevel, u.ulevel);
1809     if (ACURR(A_DEX) < 4)
1810         tmp -= 3;
1811     else if (ACURR(A_DEX) < 6)
1812         tmp -= 2;
1813     else if (ACURR(A_DEX) < 8)
1814         tmp -= 1;
1815     else if (ACURR(A_DEX) >= 14)
1816         tmp += (ACURR(A_DEX) - 14);
1817
1818     /* Modify to-hit depending on distance; but keep it sane.
1819      * Polearms get a distance penalty even when wielded; it's
1820      * hard to hit at a distance.
1821      */
1822     disttmp = 3 - distmin(u.ux, u.uy, mon->mx, mon->my);
1823     if (disttmp < -4)
1824         disttmp = -4;
1825     tmp += disttmp;
1826
1827     /* gloves are a hindrance to proper use of bows */
1828     if (uarmg && uwep && objects[uwep->otyp].oc_skill == P_BOW) {
1829         switch (uarmg->otyp) {
1830         case GAUNTLETS_OF_POWER: /* metal */
1831             tmp -= 2;
1832             break;
1833         case GAUNTLETS_OF_FUMBLING:
1834             tmp -= 3;
1835             break;
1836         case LEATHER_GLOVES:
1837         case GAUNTLETS_OF_DEXTERITY:
1838             break;
1839         default:
1840             impossible("Unknown type of gloves (%d)", uarmg->otyp);
1841             break;
1842         }
1843     }
1844
1845     tmp += omon_adj(mon, obj, TRUE);
1846     if (is_orc(mon->data)
1847         && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
1848         tmp++;
1849     if (guaranteed_hit) {
1850         tmp += 1000; /* Guaranteed hit */
1851     }
1852
1853     if (obj->oclass == GEM_CLASS && is_unicorn(mon->data)) {
1854         if (mon->msleeping || !mon->mcanmove) {
1855             tmiss(obj, mon, FALSE);
1856             return 0;
1857         } else if (mon->mtame) {
1858 /*JP
1859             pline("%s catches and drops %s.", Monnam(mon), the(xname(obj)));
1860 */
1861             pline("%s\82Í%s\82ð\82­\82í\82¦\82Ä\92u\82¢\82½\81D", Monnam(mon), xname(obj));
1862             return 0;
1863         } else {
1864 /*JP
1865             pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1866 */
1867             pline("%s\82Í%s\82ð\82­\82í\82¦\82½\81D", Monnam(mon), xname(obj));
1868             return gem_accept(mon, obj);
1869         }
1870     }
1871
1872     /* don't make game unwinnable if naive player throws artifact
1873        at leader... (kicked artifact is ok too; HMON_APPLIED could
1874        occur if quest artifact polearm or grapnel ever gets added) */
1875     if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) {
1876         /* AIS: changes to wakeup() means that it's now less inappropriate here
1877            than it used to be, but the manual version works just as well */
1878         mon->msleeping = 0;
1879         mon->mstrategy &= ~STRAT_WAITMASK;
1880
1881         if (mon->mcanmove) {
1882 /*JP
1883             pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1884 */
1885             pline("%s\82Í%s\82ð\92Í\82ñ\82¾\81D", Monnam(mon), xname(obj));
1886             if (mon->mpeaceful) {
1887                 boolean next2u = monnear(mon, u.ux, u.uy);
1888
1889                 finish_quest(obj); /* acknowledge quest completion */
1890 #if 0 /*JP:T*/
1891                 pline("%s %s %s back to you.", Monnam(mon),
1892                       (next2u ? "hands" : "tosses"), the(xname(obj)));
1893 #else
1894                 pline("%s\82Í%s\82ð\82 \82È\82½\82É\95Ô\82µ\82½\81D", Monnam(mon),
1895                       xname(obj));
1896 #endif
1897                 if (!next2u)
1898                     sho_obj_return_to_u(obj);
1899                 obj = addinv(obj); /* back into your inventory */
1900                 (void) encumber_msg();
1901             } else {
1902                 /* angry leader caught it and isn't returning it */
1903                 if (*u.ushops || obj->unpaid) /* not very likely... */
1904                     check_shop_obj(obj, mon->mx, mon->my, FALSE);
1905                 (void) mpickobj(mon, obj);
1906             }
1907             return 1; /* caller doesn't need to place it */
1908         }
1909         return 0;
1910     }
1911
1912     dieroll = rnd(20);
1913
1914     if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1915         || obj->oclass == GEM_CLASS) {
1916         if (hmode == HMON_KICKED) {
1917             /* throwing adjustments and weapon skill bonus don't apply */
1918             tmp -= (is_ammo(obj) ? 5 : 3);
1919         } else if (is_ammo(obj)) {
1920             if (!ammo_and_launcher(obj, uwep)) {
1921                 tmp -= 4;
1922             } else {
1923                 tmp += uwep->spe - greatest_erosion(uwep);
1924                 tmp += weapon_hit_bonus(uwep);
1925                 if (uwep->oartifact)
1926                     tmp += spec_abon(uwep, mon);
1927                 /*
1928                  * Elves and Samurais are highly trained w/bows,
1929                  * especially their own special types of bow.
1930                  * Polymorphing won't make you a bow expert.
1931                  */
1932                 if ((Race_if(PM_ELF) || Role_if(PM_SAMURAI))
1933                     && (!Upolyd || your_race(youmonst.data))
1934                     && objects[uwep->otyp].oc_skill == P_BOW) {
1935                     tmp++;
1936                     if (Race_if(PM_ELF) && uwep->otyp == ELVEN_BOW)
1937                         tmp++;
1938                     else if (Role_if(PM_SAMURAI) && uwep->otyp == YUMI)
1939                         tmp++;
1940                 }
1941             }
1942         } else { /* thrown non-ammo or applied polearm/grapnel */
1943             if (otyp == BOOMERANG) /* arbitrary */
1944                 tmp += 4;
1945             else if (throwing_weapon(obj)) /* meant to be thrown */
1946                 tmp += 2;
1947             else if (obj == thrownobj) /* not meant to be thrown */
1948                 tmp -= 2;
1949             /* we know we're dealing with a weapon or weptool handled
1950                by WEAPON_SKILLS once ammo objects have been excluded */
1951             tmp += weapon_hit_bonus(obj);
1952         }
1953
1954         if (tmp >= dieroll) {
1955             boolean wasthrown = (thrownobj != 0),
1956                     /* remember weapon attribute; hmon() might destroy obj */
1957                     chopper = is_axe(obj);
1958
1959             /* attack hits mon */
1960             if (hmode == HMON_APPLIED)
1961                 u.uconduct.weaphit++;
1962             if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */
1963                 if (mon->wormno)
1964                     cutworm(mon, bhitpos.x, bhitpos.y, chopper);
1965             }
1966             exercise(A_DEX, TRUE);
1967             /* if hero was swallowed and projectile killed the engulfer,
1968                'obj' got added to engulfer's inventory and then dropped,
1969                so we can't safely use that pointer anymore; it escapes
1970                the chance to be used up here... */
1971             if (wasthrown && !thrownobj)
1972                 return 1;
1973
1974             /* projectiles other than magic stones sometimes disappear
1975                when thrown; projectiles aren't among the types of weapon
1976                that hmon() might have destroyed so obj is intact */
1977             if (objects[otyp].oc_skill < P_NONE
1978                 && objects[otyp].oc_skill > -P_BOOMERANG
1979                 && !objects[otyp].oc_magic) {
1980                 /* we were breaking 2/3 of everything unconditionally.
1981                  * we still don't want anything to survive unconditionally,
1982                  * but we need ammo to stay around longer on average.
1983                  */
1984                 int broken, chance;
1985
1986                 chance = 3 + greatest_erosion(obj) - obj->spe;
1987                 if (chance > 1)
1988                     broken = rn2(chance);
1989                 else
1990                     broken = !rn2(4);
1991                 if (obj->blessed && !rnl(4))
1992                     broken = 0;
1993
1994                 if (broken) {
1995                     if (*u.ushops || obj->unpaid)
1996                         check_shop_obj(obj, bhitpos.x, bhitpos.y, TRUE);
1997                     obfree(obj, (struct obj *) 0);
1998                     return 1;
1999                 }
2000             }
2001             passive_obj(mon, obj, (struct attack *) 0);
2002         } else {
2003             tmiss(obj, mon, TRUE);
2004             if (hmode == HMON_APPLIED)
2005                 wakeup(mon, TRUE);
2006         }
2007
2008     } else if (otyp == HEAVY_IRON_BALL) {
2009         exercise(A_STR, TRUE);
2010         if (tmp >= dieroll) {
2011             int was_swallowed = guaranteed_hit;
2012
2013             exercise(A_DEX, TRUE);
2014             if (!hmon(mon, obj, hmode, dieroll)) { /* mon killed */
2015                 if (was_swallowed && !u.uswallow && obj == uball)
2016                     return 1; /* already did placebc() */
2017             }
2018         } else {
2019             tmiss(obj, mon, TRUE);
2020         }
2021
2022     } else if (otyp == BOULDER) {
2023         exercise(A_STR, TRUE);
2024         if (tmp >= dieroll) {
2025             exercise(A_DEX, TRUE);
2026             (void) hmon(mon, obj, hmode, dieroll);
2027         } else {
2028             tmiss(obj, mon, TRUE);
2029         }
2030
2031     } else if ((otyp == EGG || otyp == CREAM_PIE || otyp == BLINDING_VENOM
2032                 || otyp == ACID_VENOM)
2033                && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
2034         (void) hmon(mon, obj, hmode, dieroll);
2035         return 1; /* hmon used it up */
2036
2037     } else if (obj->oclass == POTION_CLASS
2038                && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
2039         potionhit(mon, obj, POTHIT_HERO_THROW);
2040         return 1;
2041
2042     } else if (befriend_with_obj(mon->data, obj)
2043                || (mon->mtame && dogfood(mon, obj) <= ACCFOOD)) {
2044         if (tamedog(mon, obj)) {
2045             return 1; /* obj is gone */
2046         } else {
2047             tmiss(obj, mon, FALSE);
2048             mon->msleeping = 0;
2049             mon->mstrategy &= ~STRAT_WAITMASK;
2050         }
2051     } else if (guaranteed_hit) {
2052         /* this assumes that guaranteed_hit is due to swallowing */
2053         wakeup(mon, TRUE);
2054         if (obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])) {
2055             if (is_animal(u.ustuck->data)) {
2056                 minstapetrify(u.ustuck, TRUE);
2057                 /* Don't leave a cockatrice corpse available in a statue */
2058                 if (!u.uswallow) {
2059                     delobj(obj);
2060                     return 1;
2061                 }
2062             }
2063         }
2064 #if 0 /*JP:T*/
2065         pline("%s into %s %s.", Tobjnam(obj, "vanish"),
2066               s_suffix(mon_nam(mon)),
2067               is_animal(u.ustuck->data) ? "entrails" : "currents");
2068 #else
2069         pline("%s\82Í%s\82Ì%s\82Ö\8fÁ\82¦\82½\81D", xname(obj),
2070               mon_nam(mon),
2071               is_animal(u.ustuck->data) ? "\93à\91\9f\82Ì\92\86" : "\97¬\82ê");
2072 #endif
2073     } else {
2074         tmiss(obj, mon, TRUE);
2075     }
2076
2077     return 0;
2078 }
2079
2080 STATIC_OVL int
2081 gem_accept(mon, obj)
2082 register struct monst *mon;
2083 register struct obj *obj;
2084 {
2085     char buf[BUFSZ];
2086     boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type);
2087     boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE;
2088     int ret = 0;
2089 /*JP
2090     static NEARDATA const char nogood[] = " is not interested in your junk.";
2091 */
2092     static NEARDATA const char nogood[] = "\82 \82È\82½\82Ì\83K\83\89\83N\83^\82É\8b»\96¡\82ð\8e¦\82³\82È\82¢\81D";
2093 /*JP
2094     static NEARDATA const char acceptgift[] = " accepts your gift.";
2095 */
2096     static NEARDATA const char acceptgift[] = "\82 \82È\82½\82Ì\91¡\82è\95¨\82ð\8eó\82¯\82Æ\82Á\82½\81D";
2097 /*JP
2098     static NEARDATA const char maybeluck[] = " hesitatingly";
2099 */
2100     static NEARDATA const char maybeluck[] = "\82½\82ß\82ç\82¢\82È\82ª\82ç";
2101 /*JP
2102     static NEARDATA const char noluck[] = " graciously";
2103 */
2104     static NEARDATA const char noluck[] = "\92\9a\8fd\82É";
2105 /*JP
2106     static NEARDATA const char addluck[] = " gratefully";
2107 */
2108     static NEARDATA const char addluck[] = "\8aì\82ñ\82Å";
2109
2110     Strcpy(buf, Monnam(mon));
2111 #if 1 /*JP*/
2112     Strcat(buf, "\82Í");
2113 #endif
2114     mon->mpeaceful = 1;
2115     mon->mavenge = 0;
2116
2117     /* object properly identified */
2118     if (obj->dknown && objects[obj->otyp].oc_name_known) {
2119         if (is_gem) {
2120             if (is_buddy) {
2121                 Strcat(buf, addluck);
2122                 change_luck(5);
2123             } else {
2124                 Strcat(buf, maybeluck);
2125                 change_luck(rn2(7) - 3);
2126             }
2127         } else {
2128             Strcat(buf, nogood);
2129             goto nopick;
2130         }
2131         /* making guesses */
2132     } else if (has_oname(obj) || objects[obj->otyp].oc_uname) {
2133         if (is_gem) {
2134             if (is_buddy) {
2135                 Strcat(buf, addluck);
2136                 change_luck(2);
2137             } else {
2138                 Strcat(buf, maybeluck);
2139                 change_luck(rn2(3) - 1);
2140             }
2141         } else {
2142             Strcat(buf, nogood);
2143             goto nopick;
2144         }
2145         /* value completely unknown to @ */
2146     } else {
2147         if (is_gem) {
2148             if (is_buddy) {
2149                 Strcat(buf, addluck);
2150                 change_luck(1);
2151             } else {
2152                 Strcat(buf, maybeluck);
2153                 change_luck(rn2(3) - 1);
2154             }
2155         } else {
2156             Strcat(buf, noluck);
2157         }
2158     }
2159     Strcat(buf, acceptgift);
2160     if (*u.ushops || obj->unpaid)
2161         check_shop_obj(obj, mon->mx, mon->my, TRUE);
2162     (void) mpickobj(mon, obj); /* may merge and free obj */
2163     ret = 1;
2164
2165  nopick:
2166     if (!Blind)
2167         pline1(buf);
2168     if (!tele_restrict(mon))
2169         (void) rloc(mon, TRUE);
2170     return ret;
2171 }
2172
2173 /*
2174  * Comments about the restructuring of the old breaks() routine.
2175  *
2176  * There are now three distinct phases to object breaking:
2177  *     breaktest() - which makes the check/decision about whether the
2178  *                   object is going to break.
2179  *     breakmsg()  - which outputs a message about the breakage,
2180  *                   appropriate for that particular object. Should
2181  *                   only be called after a positive breaktest().
2182  *                   on the object and, if it going to be called,
2183  *                   it must be called before calling breakobj().
2184  *                   Calling breakmsg() is optional.
2185  *     breakobj()  - which actually does the breakage and the side-effects
2186  *                   of breaking that particular object. This should
2187  *                   only be called after a positive breaktest() on the
2188  *                   object.
2189  *
2190  * Each of the above routines is currently static to this source module.
2191  * There are two routines callable from outside this source module which
2192  * perform the routines above in the correct sequence.
2193  *
2194  *   hero_breaks() - called when an object is to be broken as a result
2195  *                   of something that the hero has done. (throwing it,
2196  *                   kicking it, etc.)
2197  *   breaks()      - called when an object is to be broken for some
2198  *                   reason other than the hero doing something to it.
2199  */
2200
2201 /*
2202  * The hero causes breakage of an object (throwing, dropping it, etc.)
2203  * Return 0 if the object didn't break, 1 if the object broke.
2204  */
2205 int
2206 hero_breaks(obj, x, y, from_invent)
2207 struct obj *obj;
2208 xchar x, y;          /* object location (ox, oy may not be right) */
2209 boolean from_invent; /* thrown or dropped by player; maybe on shop bill */
2210 {
2211     boolean in_view = Blind ? FALSE : (from_invent || cansee(x, y));
2212
2213     if (!breaktest(obj))
2214         return 0;
2215     breakmsg(obj, in_view);
2216     breakobj(obj, x, y, TRUE, from_invent);
2217     return 1;
2218 }
2219
2220 /*
2221  * The object is going to break for a reason other than the hero doing
2222  * something to it.
2223  * Return 0 if the object doesn't break, 1 if the object broke.
2224  */
2225 int
2226 breaks(obj, x, y)
2227 struct obj *obj;
2228 xchar x, y; /* object location (ox, oy may not be right) */
2229 {
2230     boolean in_view = Blind ? FALSE : cansee(x, y);
2231
2232     if (!breaktest(obj))
2233         return 0;
2234     breakmsg(obj, in_view);
2235     breakobj(obj, x, y, FALSE, FALSE);
2236     return 1;
2237 }
2238
2239 void
2240 release_camera_demon(obj, x, y)
2241 struct obj *obj;
2242 xchar x, y;
2243 {
2244     struct monst *mtmp;
2245     if (!rn2(3)
2246         && (mtmp = makemon(&mons[rn2(3) ? PM_HOMUNCULUS : PM_IMP], x, y,
2247                            NO_MM_FLAGS)) != 0) {
2248         if (canspotmon(mtmp))
2249 #if 0 /*JP:T*/
2250             pline("%s is released!", Hallucination
2251                                          ? An(rndmonnam(NULL))
2252                                          : "The picture-painting demon");
2253 #else
2254             pline("%s\82ª\89ð\95ú\82³\82ê\82½\81I", Hallucination
2255                                          ? rndmonnam(NULL)
2256                                          : "\82¨\8aG\95`\82«\82Ì\88«\96\82");
2257 #endif
2258         mtmp->mpeaceful = !obj->cursed;
2259         set_malign(mtmp);
2260     }
2261 }
2262
2263 /*
2264  * Unconditionally break an object. Assumes all resistance checks
2265  * and break messages have been delivered prior to getting here.
2266  */
2267 void
2268 breakobj(obj, x, y, hero_caused, from_invent)
2269 struct obj *obj;
2270 xchar x, y;          /* object location (ox, oy may not be right) */
2271 boolean hero_caused; /* is this the hero's fault? */
2272 boolean from_invent;
2273 {
2274     boolean fracture = FALSE;
2275
2276     switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2277     case MIRROR:
2278         if (hero_caused)
2279             change_luck(-2);
2280         break;
2281     case POT_WATER:      /* really, all potions */
2282         obj->in_use = 1; /* in case it's fatal */
2283         if (obj->otyp == POT_OIL && obj->lamplit) {
2284             explode_oil(obj, x, y);
2285         } else if (distu(x, y) <= 2) {
2286             if (!breathless(youmonst.data) || haseyes(youmonst.data)) {
2287                 if (obj->otyp != POT_WATER) {
2288                     if (!breathless(youmonst.data)) {
2289                         /* [what about "familiar odor" when known?] */
2290 /*JP
2291                         You("smell a peculiar odor...");
2292 */
2293                         You("\96ò\82Á\82Û\82¢\93õ\82¢\82ª\82µ\82½\81D\81D\81D");
2294                     } else {
2295 #if 0 /*JP:T*/
2296                         const char *eyes = body_part(EYE);
2297
2298                         if (eyecount(youmonst.data) != 1)
2299                             eyes = makeplural(eyes);
2300                         Your("%s %s.", eyes, vtense(eyes, "water"));
2301 #else
2302                         You("\97Ü%s\82É\82È\82Á\82½\81D", body_part(EYE));
2303 #endif
2304                     }
2305                 }
2306                 potionbreathe(obj);
2307             }
2308         }
2309         /* monster breathing isn't handled... [yet?] */
2310         break;
2311     case EXPENSIVE_CAMERA:
2312         release_camera_demon(obj, x, y);
2313         break;
2314     case EGG:
2315         /* breaking your own eggs is bad luck */
2316         if (hero_caused && obj->spe && obj->corpsenm >= LOW_PM)
2317             change_luck((schar) -min(obj->quan, 5L));
2318         break;
2319     case BOULDER:
2320     case STATUE:
2321         /* caller will handle object disposition;
2322            we're just doing the shop theft handling */
2323         fracture = TRUE;
2324         break;
2325     default:
2326         break;
2327     }
2328
2329     if (hero_caused) {
2330         if (from_invent || obj->unpaid) {
2331             if (*u.ushops || obj->unpaid)
2332                 check_shop_obj(obj, x, y, TRUE);
2333         } else if (!obj->no_charge && costly_spot(x, y)) {
2334             /* it is assumed that the obj is a floor-object */
2335             char *o_shop = in_rooms(x, y, SHOPBASE);
2336             struct monst *shkp = shop_keeper(*o_shop);
2337
2338             if (shkp) { /* (implies *o_shop != '\0') */
2339                 static NEARDATA long lastmovetime = 0L;
2340                 static NEARDATA boolean peaceful_shk = FALSE;
2341                 /*  We want to base shk actions on her peacefulness
2342                     at start of this turn, so that "simultaneous"
2343                     multiple breakage isn't drastically worse than
2344                     single breakage.  (ought to be done via ESHK)  */
2345                 if (moves != lastmovetime)
2346                     peaceful_shk = shkp->mpeaceful;
2347                 if (stolen_value(obj, x, y, peaceful_shk, FALSE) > 0L
2348                     && (*o_shop != u.ushops[0] || !inside_shop(u.ux, u.uy))
2349                     && moves != lastmovetime)
2350                     make_angry_shk(shkp, x, y);
2351                 lastmovetime = moves;
2352             }
2353         }
2354     }
2355     if (!fracture)
2356         delobj(obj);
2357 }
2358
2359 /*
2360  * Check to see if obj is going to break, but don't actually break it.
2361  * Return 0 if the object isn't going to break, 1 if it is.
2362  */
2363 boolean
2364 breaktest(obj)
2365 struct obj *obj;
2366 {
2367     if (obj_resists(obj, 1, 99))
2368         return 0;
2369     if (objects[obj->otyp].oc_material == GLASS && !obj->oartifact
2370         && obj->oclass != GEM_CLASS)
2371         return 1;
2372     switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2373     case EXPENSIVE_CAMERA:
2374     case POT_WATER: /* really, all potions */
2375     case EGG:
2376     case CREAM_PIE:
2377     case MELON:
2378     case ACID_VENOM:
2379     case BLINDING_VENOM:
2380         return 1;
2381     default:
2382         return 0;
2383     }
2384 }
2385
2386 STATIC_OVL void
2387 breakmsg(obj, in_view)
2388 struct obj *obj;
2389 boolean in_view;
2390 {
2391     const char *to_pieces;
2392
2393 #if 0 /*JP*/
2394     to_pieces = "";
2395 #else
2396     /* "shatter" \81¨ "\82±\82È\82²\82È\82É\82È\82Á\82½"
2397        "shatter into a thousand pieces" \81¨ "\82­\82¾\82¯\82Ä\82Î\82ç\82Î\82ç\82É\82È\82Á\82½" */
2398     to_pieces = "\82±\82È\82²\82È";
2399 #endif
2400     switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2401     default: /* glass or crystal wand */
2402         if (obj->oclass != WAND_CLASS)
2403             impossible("breaking odd object?");
2404         /*FALLTHRU*/
2405     case CRYSTAL_PLATE_MAIL:
2406     case LENSES:
2407     case MIRROR:
2408     case CRYSTAL_BALL:
2409     case EXPENSIVE_CAMERA:
2410 /*JP
2411         to_pieces = " into a thousand pieces";
2412 */
2413         to_pieces = "\82­\82¾\82¯\82Ä\82Î\82ç\82Î\82ç";
2414     /*FALLTHRU*/
2415     case POT_WATER: /* really, all potions */
2416         if (!in_view)
2417 /*JP
2418             You_hear("%s shatter!", something);
2419 */
2420             You_hear("%s\82ª\89ó\82ê\82é\89¹\82ð\95·\82¢\82½\81I", something);
2421         else
2422 #if 0 /*JP*/
2423             pline("%s shatter%s%s!", Doname2(obj),
2424                   (obj->quan == 1L) ? "s" : "", to_pieces);
2425 #else
2426             pline("%s\82Í%s\82É\82È\82Á\82½\81I", Doname2(obj), to_pieces);
2427 #endif
2428         break;
2429     case EGG:
2430     case MELON:
2431 /*JP
2432         pline("Splat!");
2433 */
2434         pline("\83r\83`\83\83\81I");
2435         break;
2436     case CREAM_PIE:
2437         if (in_view)
2438 /*JP
2439             pline("What a mess!");
2440 */
2441             pline("\82±\82è\82á\82Ð\82Ç\82¢\81I");
2442         break;
2443     case ACID_VENOM:
2444     case BLINDING_VENOM:
2445 /*JP
2446         pline("Splash!");
2447 */
2448         pline("\83r\83`\83\83\81I");
2449         break;
2450     }
2451 }
2452
2453 STATIC_OVL int
2454 throw_gold(obj)
2455 struct obj *obj;
2456 {
2457     int range, odx, ody;
2458     register struct monst *mon;
2459
2460     if (!u.dx && !u.dy && !u.dz) {
2461 /*JP
2462         You("cannot throw gold at yourself.");
2463 */
2464         pline("\8e©\95ª\82É\8bà\89Ý\82ð\93\8a\82°\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
2465         return 0;
2466     }
2467     freeinv(obj);
2468     if (u.uswallow) {
2469 #if 0 /*JP:T*/
2470         pline(is_animal(u.ustuck->data) ? "%s in the %s's entrails."
2471                                         : "%s into %s.",
2472               "The money disappears", mon_nam(u.ustuck));
2473 #else
2474         pline(is_animal(u.ustuck->data) ? "\8bà\89Ý\82Í%s\82Ì\95 \82Ì\92\86\82Ö\8fÁ\82¦\82Ä\82¢\82Á\82½\81D"
2475                                         : "\8bà\89Ý\82Í%s\82Ì\92\86\82Ö\8fÁ\82¦\82Ä\82¢\82Á\82½\81D",
2476               mon_nam(u.ustuck));
2477 #endif
2478         add_to_minv(u.ustuck, obj);
2479         return 1;
2480     }
2481
2482     if (u.dz) {
2483         if (u.dz < 0 && !Is_airlevel(&u.uz) && !Underwater
2484             && !Is_waterlevel(&u.uz)) {
2485 #if 0 /*JP:T*/
2486             pline_The("gold hits the %s, then falls back on top of your %s.",
2487                       ceiling(u.ux, u.uy), body_part(HEAD));
2488 #else
2489             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",
2490                   ceiling(u.ux,u.uy), body_part(HEAD));
2491 #endif
2492             /* some self damage? */
2493             if (uarmh)
2494 /*JP
2495                 pline("Fortunately, you are wearing %s!",
2496 */
2497                 pline("\8dK\89^\82È\82±\82Æ\82É\81C\82 \82È\82½\82Í%s\82ð\90g\82É\82Â\82¯\82Ä\82¢\82é\81I",
2498                       an(helm_simple_name(uarmh)));
2499         }
2500         bhitpos.x = u.ux;
2501         bhitpos.y = u.uy;
2502     } else {
2503         /* consistent with range for normal objects */
2504         range = (int) ((ACURRSTR) / 2 - obj->owt / 40);
2505
2506         /* see if the gold has a place to move into */
2507         odx = u.ux + u.dx;
2508         ody = u.uy + u.dy;
2509         if (!ZAP_POS(levl[odx][ody].typ) || closed_door(odx, ody)) {
2510             bhitpos.x = u.ux;
2511             bhitpos.y = u.uy;
2512         } else {
2513             mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
2514                        (int FDECL((*), (MONST_P, OBJ_P))) 0,
2515                        (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
2516             if (!obj)
2517                 return 1; /* object is gone */
2518             if (mon) {
2519                 if (ghitm(mon, obj)) /* was it caught? */
2520                     return 1;
2521             } else {
2522                 if (ship_object(obj, bhitpos.x, bhitpos.y, FALSE))
2523                     return 1;
2524             }
2525         }
2526     }
2527
2528 /*JP
2529     if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall"))
2530 */
2531     if (flooreffects(obj, bhitpos.x, bhitpos.y, "\97\8e\82¿\82é"))
2532         return 1;
2533     if (u.dz > 0)
2534 /*JP
2535         pline_The("gold hits the %s.", surface(bhitpos.x, bhitpos.y));
2536 */
2537         pline("\8bà\89Ý\82Í%s\82É\96½\92\86\82µ\82½\81D", surface(bhitpos.x, bhitpos.y));
2538     place_object(obj, bhitpos.x, bhitpos.y);
2539     if (*u.ushops)
2540         sellobj(obj, bhitpos.x, bhitpos.y);
2541     stackobj(obj);
2542     newsym(bhitpos.x, bhitpos.y);
2543     return 1;
2544 }
2545
2546 /*dothrow.c*/