1 /* NetHack 3.6 dothrow.c $NHDT-Date: 1522967321 2018/04/05 22:28:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.135 $ */
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. */
6 /* Contains code for 't' (throw) */
8 /* JNetHack Copyright */
9 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
10 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
11 /* JNetHack may be freely redistributed. See license for details. */
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,
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));
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,
34 /* thrownobj (decl.c) tracks an object until it lands */
36 extern boolean notonhead; /* for long worms */
38 /* Throw the selected object, asking for direction */
40 throw_obj(obj, shotlimit)
48 boolean twoweap, weakmultishot;
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.
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 */
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.
70 * If the money is in quiver, throw one coin at a time,
71 * possibly using a sling.
73 if (obj->oclass == COIN_CLASS && obj != uquiver)
74 return throw_gold(obj);
77 if (!canletgo(obj, "throw"))
79 if (!canletgo(obj, "
\93\8a\82°
\82é"))
81 if (obj->oartifact == ART_MJOLLNIR && obj != uwep) {
83 pline("%s must be wielded before it can be thrown.", The(xname(obj)));
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));
88 if ((obj->oartifact == ART_MJOLLNIR && ACURR(A_STR) < STR19(25))
89 || (obj->otyp == BOULDER && !throws_rocks(youmonst.data))) {
91 pline("It's too heavy.");
93 pline("
\8fd
\82·
\82¬
\82Ä
\93\8a\82°
\82ç
\82ê
\82È
\82¢
\81D");
96 if (!u.dx && !u.dy && !u.dz) {
98 You("cannot throw an object at yourself.");
100 pline("
\8e©
\95ª
\82É
\8cü
\82©
\82Á
\82Ä
\82Í
\93\8a\82°
\82ç
\82ê
\82È
\82¢
\81D");
104 if (!uarmg && obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])
105 && !Stone_resistance) {
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)));
113 You("
\91f%s
\82Å%s
\82Ì
\8e\80\91Ì
\82ð
\93\8a\82°
\82½
\81D",
115 corpse_xname(obj, (const char *) 0, CXN_PFX_THE));
118 Sprintf(killer.name, "throwing %s bare-handed", killer_xname(obj));
120 Sprintf(killer.name, "%s
\82Ì
\8e\80\91Ì
\82ð
\91f
\8eè
\82Å
\93\8a\82°
\82Ä", killer_xname(obj));
121 instapetrify(killer.name);
127 if (is_wet_towel(obj))
128 dry_a_towel(obj, -1, FALSE);
130 /* Multishot calculations
131 * (potential volley of up to N missiles; default for N is 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);
148 /* Bonus if the player is proficient in this weapon... */
149 switch (P_SKILL(weapon_type(obj))) {
157 default: /* basic or unskilled: no bonus */
160 /* ...or is using a special weapon for their role... */
161 switch (Role_switch) {
163 /* give bonus for low-tech gear */
164 if (skill == -P_SLING || skill == P_SPEAR)
168 /* allow higher volley count despite skill limitation */
169 if (skill == -P_SHURIKEN)
173 /* arbitrary; encourage use of other missiles beside daggers */
174 if (skill != P_DAGGER)
178 /* possibly should add knives... */
179 if (skill == P_DAGGER)
183 /* role-specific launcher and its ammo */
184 if (obj->otyp == YA && uwep && uwep->otyp == YUMI)
188 break; /* No bonus */
190 /* ...or using their race's special bow; no bonus for spears */
192 switch (Race_switch) {
194 if (obj->otyp == ELVEN_ARROW && uwep
195 && uwep->otyp == ELVEN_BOW)
199 if (obj->otyp == ORCISH_ARROW && uwep
200 && uwep->otyp == ORCISH_BOW)
204 /* arbitrary; there isn't any gnome-specific gear */
205 if (skill == -P_CROSSBOW)
211 break; /* No bonus */
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);
222 multishot = rnd(multishot);
223 if ((long) multishot > obj->quan)
224 multishot = (int) obj->quan;
225 if (shotlimit > 0 && multishot > shotlimit)
226 multishot = shotlimit;
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." */
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));
239 You("%d%s
\82Ì%s
\82ð%s
\81D",
241 numeral(obj), xname(obj),
242 m_shot.s ? "
\8c\82\82Á
\82½" : "
\93\8a\82°
\82½");
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++) {
251 /* split this object off from its slot if necessary */
252 if (obj->quan > 1L) {
253 otmp = splitobj(obj, 1L);
257 remove_worn_item(otmp, FALSE);
260 throwit(otmp, wep_mask, twoweap);
262 m_shot.n = m_shot.i = 0;
263 m_shot.o = STRANGE_OBJECT;
269 /* common to dothrow() and dofire() */
271 ok_to_throw(shotlimit_p)
272 int *shotlimit_p; /* (see dothrow()) */
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 */
278 if (notake(youmonst.data)) {
280 You("are physically incapable of throwing or shooting anything.");
282 You("
\89½
\82©
\82ð
\93\8a\82°
\82é
\82Ì
\82Í
\95¨
\97\9d\93I
\82É
\96³
\97\9d\82¾
\81D");
284 } else if (nohands(youmonst.data)) {
286 You_cant("throw or shoot without hands."); /* not body_part(HAND) */
288 You("
\8eè
\82ª
\82È
\82¢
\81D"); /* not body_part(HAND) */
291 /*[what about !freehand(), aside from cursed missile launcher?]*/
293 if (check_capacity((char *) 0))
298 /* t command - throw */
302 register struct obj *obj;
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).
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)''.
314 * [3.6.0: shot count setup has been moved into ok_to_throw().]
316 if (!ok_to_throw(&shotlimit))
319 obj = getobj(uslinging() ? bullets : toss_objs, "throw");
320 /* it is also possible to throw food */
321 /* (or jewels, or iron balls... ) */
323 return obj ? throw_obj(obj, shotlimit) : 0;
326 /* KMH -- Automatically fill quiver */
327 /* Suggested by Jeffrey Bay <jbay@convex.hp.com> */
331 struct obj *otmp, *oammo = 0, *omissile = 0, *omisc = 0, *altammo = 0;
336 /* Scan through the inventory */
337 for (otmp = invent; otmp; otmp = otmp->nobj) {
338 if (otmp->owornmask || otmp->oartifact || !otmp->dknown) {
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)) {
349 else if (ammo_and_launcher(otmp, uswapwep))
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) */
360 else if (ammo_and_launcher(otmp, uswapwep))
363 /* Mismatched ammo (no better than an ordinary weapon) */
365 } else if (is_missile(otmp)) {
366 /* Missile (dart, shuriken, etc.) */
368 } else if (otmp->oclass == WEAPON_CLASS && throwing_weapon(otmp)) {
369 /* Ordinary weapon */
370 if (objects[otmp->otyp].oc_skill == P_DAGGER && !omissile)
377 /* Pick the best choice */
390 /* f command -- fire: throw from the quiver */
398 * Same as dothrow(), except we use quivered missile instead
399 * of asking what to throw/shoot.
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.]
413 if (!ok_to_throw(&shotlimit))
416 if ((obj = uquiver) == 0) {
417 if (!flags.autoquiver) {
419 You("have no ammunition readied.");
421 You("
\94
\8eË
\8f\80\94õ
\82ª
\90®
\82Á
\82Ä
\82¢
\82È
\82¢
\81I");
424 if ((obj = uquiver) == 0)
426 You("have nothing appropriate for your quiver.");
428 You("
\94
\8eË
\82·
\82é
\82à
\82Ì
\82ª
\82È
\82¢
\81D");
430 /* if autoquiver is disabled or has failed, prompt for missile;
431 fill quiver with it if it's not wielded */
433 obj = getobj(uslinging() ? bullets : toss_objs, "throw");
434 /* Q command doesn't allow gold in quiver */
435 if (obj && !obj->owornmask && obj->oclass != COIN_CLASS)
436 setuqwep(obj); /* demi-autoquiver */
438 /* give feedback if quiver has now been filled */
440 uquiver->owornmask &= ~W_QUIVER; /* less verbose */
442 prinv("You ready:", uquiver, 0L);
444 prinv("
\8f\80\94õ
\81F", uquiver, 0L);
445 uquiver->owornmask |= W_QUIVER;
449 return obj ? throw_obj(obj, shotlimit) : 0;
452 /* if in midst of multishot shooting/throwing, stop early */
454 endmultishot(verbose)
457 if (m_shot.i < m_shot.n) {
458 if (verbose && !context.mon_moving) {
460 You("stop %s after the %d%s %s.",
461 m_shot.s ? "firing" : "throwing", m_shot.i, ordin(m_shot.i),
462 m_shot.s ? "shot" : "toss");
464 You("%d
\94
\96Ú
\82ð%s
\82Æ
\82±
\82ë
\82Å
\8ec
\82è
\82ð%s
\82Ì
\82ð
\82â
\82ß
\82½
\81D", m_shot.i,
465 m_shot.s ? "
\8c\82\82Á
\82½" : "
\93\8a\82°
\82½",
466 m_shot.s ? "
\8c\82\82Â" : "
\93\8a\82°
\82é");
469 m_shot.n = m_shot.i; /* make current shot be the last */
474 * Object hits floor at hero's feet. Called from drop() and throwit().
478 register struct obj *obj;
480 if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater) {
484 if (IS_ALTAR(levl[u.ux][u.uy].typ))
488 pline("%s hit%s the %s.", Doname2(obj), (obj->quan == 1L) ? "s" : "",
489 surface(u.ux, u.uy));
491 pline("%s
\82Í%s
\82É
\96½
\92\86\82µ
\82½
\81D", Doname2(obj),
495 if (hero_breaks(obj, u.ux, u.uy, TRUE))
497 if (ship_object(obj, u.ux, u.uy, FALSE))
503 * Walk a path from src_cc to dest_cc, calling a proc for each location
504 * except the starting one. If the proc returns FALSE, stop walking
505 * and return FALSE. If stopped early, dest_cc will be the location
506 * before the failed callback.
509 walk_path(src_cc, dest_cc, check_proc, arg)
512 boolean FDECL((*check_proc), (genericptr_t, int, int));
515 int x, y, dx, dy, x_change, y_change, err, i, prev_x, prev_y;
516 boolean keep_going = TRUE;
518 /* Use Bresenham's Line Algorithm to walk from src to dest.
520 * This should be replaced with a more versatile algorithm
521 * since it handles slanted moves in a suboptimal way.
522 * Going from 'x' to 'y' needs to pass through 'z', and will
523 * fail if there's an obstable there, but it could choose to
524 * pass through 'Z' instead if that way imposes no obstacle.
527 * Perhaps we should check both paths and accept whichever
528 * one isn't blocked. But then multiple zigs and zags could
529 * potentially produce a meandering path rather than the best
530 * attempt at a straight line. And (*check_proc)() would
531 * need to work more like 'travel', distinguishing between
532 * testing a possible move and actually attempting that move.
534 dx = dest_cc->x - src_cc->x;
535 dy = dest_cc->y - src_cc->y;
536 prev_x = x = src_cc->x;
537 prev_y = y = src_cc->y;
561 /* check for early exit condition */
562 if (!(keep_going = (*check_proc)(arg, x, y)))
575 /* check for early exit condition */
576 if (!(keep_going = (*check_proc)(arg, x, y)))
582 return TRUE; /* successful */
589 /* hack for hurtle_step() -- it ought to be changed to take an argument
590 indicating lev/fly-to-dest vs lev/fly-to-dest-minus-one-land-on-dest
591 vs drag-to-dest; original callers use first mode, jumping wants second,
592 grappling hook backfire and thrown chained ball need third */
594 hurtle_jump(arg, x, y)
599 long save_EWwalking = EWwalking;
601 /* prevent jumping over water from being placed in that water */
602 EWwalking |= I_SPECIAL;
603 res = hurtle_step(arg, x, y);
604 EWwalking = save_EWwalking;
609 * Single step for the hero flying through the air from jumping, flying,
610 * etc. Called from hurtle() and jump() via walk_path(). We expect the
611 * argument to be a pointer to an integer -- the range -- which is
612 * used in the calculation of points off if we hit something.
614 * Bumping into monsters won't cause damage but will wake them and make
615 * them angry. Auto-pickup isn't done, since you don't have control over
616 * your movements at the time.
618 * Possible additions/changes:
619 * o really attack monster if we hit one
620 * o set stunned if we hit a wall or door
621 * o reset nomul when we stop
622 * o creepy feeling if pass through monster (if ever implemented...)
624 * o let jumps go over boulders
627 hurtle_step(arg, x, y)
631 int ox, oy, *range = (int *) arg;
634 boolean may_pass = TRUE;
640 You_feel("the spirits holding you back.");
642 You_feel("
\82 \82È
\82½
\82ð
\95ß
\82Ü
\82¦
\82Ä
\82¢
\82½
\8d°
\82ª
\96ß
\82Á
\82½
\8bC
\82ª
\82µ
\82½
\81D");
644 } else if (!in_out_region(x, y)) {
646 } else if (*range == 0) {
647 return FALSE; /* previous step wants to stop now */
650 if (!Passes_walls || !(may_pass = may_passwall(x, y))) {
651 boolean odoor_diag = (IS_DOOR(levl[x][y].typ)
652 && (levl[x][y].doormask & D_ISOPEN)
653 && (u.ux - x) && (u.uy - y));
655 if (IS_ROCK(levl[x][y].typ) || closed_door(x, y) || odoor_diag) {
659 You("hit the door edge!");
663 pline("
\82¢
\82Ä
\82Á
\81I");
664 if (IS_TREE(levl[x][y].typ))
666 s = "bumping into a tree";
668 s = "
\96Ø
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä";
669 else if (IS_ROCK(levl[x][y].typ))
671 s = "bumping into a wall";
673 s = "
\95Ç
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä";
676 s = "bumping into a door";
678 s = "
\94à
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä";
679 dmg = rnd(2 + *range);
680 losehp(Maybe_Half_Phys(dmg), s, KILLED_BY);
681 wake_nearto(x,y, 10);
684 if (levl[x][y].typ == IRONBARS) {
686 You("crash into some iron bars. Ouch!");
688 You("
\93S
\82Ì
\96_
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81D
\82¢
\82Ä
\82Á
\81I");
689 dmg = rnd(2 + *range);
691 losehp(Maybe_Half_Phys(dmg), "crashing into iron bars",
694 losehp(Maybe_Half_Phys(dmg), "
\93S
\82Ì
\96_
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä",
697 wake_nearto(x,y, 20);
700 if ((obj = sobj_at(BOULDER, x, y)) != 0) {
702 You("bump into a %s. Ouch!", xname(obj));
704 You("%s
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81D
\82¢
\82Ä
\82Á
\81I", xname(obj));
705 dmg = rnd(2 + *range);
707 losehp(Maybe_Half_Phys(dmg), "bumping into a boulder", KILLED_BY);
709 losehp(Maybe_Half_Phys(dmg), "
\8aâ
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä", KILLED_BY);
710 wake_nearto(x,y, 10);
714 /* did we hit a no-dig non-wall position? */
716 You("smack into something!");
718 You("
\89½
\82©
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81I");
719 dmg = rnd(2 + *range);
721 losehp(Maybe_Half_Phys(dmg), "touching the edge of the universe",
724 losehp(Maybe_Half_Phys(dmg), "
\90¢
\8aE
\82Ì
\89Ê
\82Ä
\82É
\90G
\82ê
\82Ä",
727 wake_nearto(x,y, 10);
730 if ((u.ux - x) && (u.uy - y) && bad_rock(youmonst.data, u.ux, y)
731 && bad_rock(youmonst.data, x, u.uy)) {
732 boolean too_much = (invent && (inv_weight() + weight_cap() > 600));
734 /* Move at a diagonal. */
735 if (bigmonst(youmonst.data) || too_much) {
737 You("%sget forcefully wedged into a crevice.",
738 too_much ? "and all your belongings " : "");
740 You("%s
\82Í
\82Þ
\82è
\82â
\82è
\82·
\82«
\8aÔ
\82É
\89\9f\82µ
\8d\9e\82ß
\82ç
\82ê
\82½
\81D",
741 too_much ? "
\82Æ
\91S
\95\94\82Ì
\89×
\95¨" : "");
743 dmg = rnd(2 + *range);
745 losehp(Maybe_Half_Phys(dmg), "wedging into a narrow crevice",
748 losehp(Maybe_Half_Phys(dmg), "
\8b·
\82¢
\82·
\82«
\8aÔ
\82É
\89\9f\82µ
\8d\9e\82ß
\82ç
\82ê
\82Ä",
751 wake_nearto(x,y, 10);
757 if ((mon = m_at(x, y)) != 0
758 #if 0 /* we can't include these two exceptions unless we know we're
759 * going to end up past the current spot rather than on it;
760 * for that, we need to know that the range is not exhausted
761 * and also that the next spot doesn't contain an obstacle */
762 && !(mon->mundetected && hides_under(mon) && (Flying || Levitation))
763 && !(mon->mundetected && mon->data->mlet == S_EEL
764 && (Flying || Levitation || Wwalking))
767 const char *mnam, *pronoun;
768 int glyph = glyph_at(x, y);
770 mon->mundetected = 0; /* wakeup() will handle mimic */
771 mnam = a_monnam(mon); /* after unhiding */
773 if (!strcmp(mnam, "it")) {
774 /* mhim() uses pronoun_gender() which forces neuter if monster
775 can't be seen; we want him/her for humanoid sensed by touch */
776 if (!strcmp(pronoun, "it") && humanoid(mon->data))
777 pronoun = genders[mon->female].him;
778 mnam = !strcmp(pronoun, "it") ? "something" : "someone";
780 if (!glyph_is_monster(glyph) && !glyph_is_invisible(glyph))
781 You("find %s by bumping into %s.", mnam, pronoun);
784 You("bump into %s.", mnam);
786 You("%s
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81D", mnam);
788 if (!canspotmon(mon))
789 map_invisible(mon->mx, mon->my);
790 setmangry(mon, FALSE);
791 wake_nearto(x, y, 10);
795 if ((u.ux - x) && (u.uy - y)
796 && bad_rock(youmonst.data, u.ux, y)
797 && bad_rock(youmonst.data, x, u.uy)) {
798 /* Move at a diagonal. */
801 You("come to an abrupt halt!");
803 You("
\82Æ
\82Â
\82º
\82ñ
\92â
\8e~
\82µ
\82½
\81I");
808 /* Caller has already determined that dragging the ball is allowed */
809 if (Punished && uball->where == OBJ_FLOOR) {
811 xchar ballx, bally, chainx, chainy;
814 if (drag_ball(x, y, &bc_control, &ballx, &bally, &chainx,
815 &chainy, &cause_delay, TRUE))
816 move_bc(0, bc_control, ballx, bally, chainx, chainy);
821 u_on_newpos(x, y); /* set u.<ux,uy>, u.usteed-><mx,my>; cliparound(); */
822 newsym(ox, oy); /* update old position */
823 vision_recalc(1); /* update for new position */
826 if (is_pool(x, y) && !u.uinwater
827 && ((Is_waterlevel(&u.uz) && levl[x][y].typ == WATER)
828 || !(Levitation || Flying || Wwalking))) {
829 multi = 0; /* can move, so drown() allows crawling out of water */
835 * Each trap should really trigger on the recoil if
836 * it would trigger during normal movement. However,
837 * not all the possible side-effects of this are
838 * tested [as of 3.4.0] so we trigger those that
839 * we have tested, and offer a message for the
840 * ones that we have not yet tested.
842 if ((ttmp = t_at(x, y)) != 0) {
843 if (ttmp->ttyp == MAGIC_PORTAL) {
846 } else if (ttmp->ttyp == VIBRATING_SQUARE) {
847 pline("The ground vibrates as you pass it.");
848 dotrap(ttmp, 0); /* doesn't print messages */
849 } else if (ttmp->ttyp == FIRE_TRAP) {
851 } else if ((ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT
852 || ttmp->ttyp == HOLE || ttmp->ttyp == TRAPDOOR)
854 /* Air currents overcome the recoil */
861 You("pass right over %s.",
862 an(defsyms[trap_to_defsym(ttmp->ttyp)].explanation));
864 You("%s
\82Ì
\90^
\8fã
\82ð
\92Ê
\89ß
\82µ
\82½
\81D",
865 defsyms[trap_to_defsym(ttmp->ttyp)].explanation);
869 if (--*range < 0) /* make sure our range never goes negative */
877 mhurtle_step(arg, x, y)
881 struct monst *mon = (struct monst *) arg;
883 /* TODO: Treat walls, doors, iron bars, pools, lava, etc. specially
884 * rather than just stopping before.
886 if (goodpos(x, y, mon, 0) && m_in_out_region(mon, x, y)) {
887 remove_monster(mon->mx, mon->my);
888 newsym(mon->mx, mon->my);
889 place_monster(mon, x, y);
890 newsym(mon->mx, mon->my);
899 * The player moves through the air for a few squares as a result of
900 * throwing or kicking something.
902 * dx and dy should be the direction of the hurtle, not of the original
903 * kick or throw and be only.
906 hurtle(dx, dy, range, verbose)
912 /* The chain is stretched vertically, so you shouldn't be able to move
913 * very far diagonally. The premise that you should be able to move one
914 * spot leads to calculations that allow you to only move one spot away
915 * from the ball, if you are levitating over the ball, or one spot
916 * towards the ball, if you are at the end of the chain. Rather than
917 * bother with all of that, assume that there is no slack in the chain
918 * for diagonal movement, give the player a message and return.
920 if (Punished && !carried(uball)) {
922 You_feel("a tug from the iron ball.");
924 You_feel("
\93S
\8b\85\82É
\82Ð
\82Á
\82Ï
\82ç
\82ê
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
927 } else if (u.utrap) {
929 You("are anchored by the %s.",
930 u.utraptype == TT_WEB
932 : u.utraptype == TT_LAVA
934 : u.utraptype == TT_INFLOOR
935 ? surface(u.ux, u.uy)
936 : u.utraptype == TT_BURIEDBALL ? "buried ball"
939 You("%s
\82É
\90\98\82¦
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é
\81D",
940 u.utraptype == TT_WEB
941 ? "
\82
\82à
\82Ì
\91\83"
942 : u.utraptype == TT_LAVA
944 : u.utraptype == TT_INFLOOR
946 : u.utraptype == TT_BURIEDBALL ? "
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\8b\85"
953 /* make sure dx and dy are [-1,0,1] */
957 if (!range || (!dx && !dy) || u.ustuck)
958 return; /* paranoia */
962 multi_reason = "moving through the air";
964 multi_reason = "
\8bó
\92\86\82ð
\88Ú
\93®
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
965 nomovemsg = ""; /* it just happens */
968 You("%s in the opposite direction.", range > 1 ? "hurtle" : "float");
970 You("
\8bt
\95û
\8cü
\82É
\94ò
\82Î
\82³
\82ê
\82½
\81D");
971 /* if we're in the midst of shooting multiple projectiles, stop */
976 /* this setting of cc is only correct if dx and dy are [-1,0,1] only */
977 cc.x = u.ux + (dx * range);
978 cc.y = u.uy + (dy * range);
979 (void) walk_path(&uc, &cc, hurtle_step, (genericptr_t) &range);
982 /* Move a monster through the air for a few squares. */
984 mhurtle(mon, dx, dy, range)
990 /* At the very least, debilitate the monster */
994 /* Is the monster stuck or too heavy to push?
995 * (very large monsters have too much inertia, even floaters and flyers)
997 if (mon->data->msize >= MZ_HUGE || mon == u.ustuck || mon->mtrapped)
1000 /* Make sure dx and dy are [-1,0,1] */
1003 if (!range || (!dx && !dy))
1004 return; /* paranoia */
1005 /* don't let grid bugs be hurtled diagonally */
1006 if (dx && dy && NODIAG(monsndx(mon->data)))
1009 /* Send the monster along the path */
1012 cc.x = mon->mx + (dx * range);
1013 cc.y = mon->my + (dy * range);
1014 (void) walk_path(&mc, &cc, mhurtle_step, (genericptr_t) mon);
1019 check_shop_obj(obj, x, y, broken)
1024 struct monst *shkp = shop_keeper(*u.ushops);
1029 if (broken || !costly_spot(x, y)
1030 || *in_rooms(x, y, SHOPBASE) != *u.ushops) {
1031 /* thrown out of a shop or into a different shop */
1033 (void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful,
1038 if (costly_spot(u.ux, u.uy) && costly_spot(x, y)) {
1040 subfrombill(obj, shkp);
1041 else if (x != shkp->mx || y != shkp->my)
1048 * Hero tosses an object upwards with appropriate consequences.
1050 * Returns FALSE if the object is gone.
1053 toss_up(obj, hitsroof)
1058 boolean petrifier = ((obj->otyp == EGG || obj->otyp == CORPSE)
1059 && touch_petrifies(&mons[obj->corpsenm]));
1060 /* note: obj->quan == 1 */
1062 if (!has_ceiling(&u.uz)) {
1064 action = "flies up into"; /* into "the sky" or "the water above" */
1066 action = "
\82Ì
\92\86\82ð
\94ò
\82ñ
\82¾"; /* into "the sky" or "the water above" */
1068 } else if (hitsroof) {
1069 if (breaktest(obj)) {
1071 pline("%s hits the %s.", Doname2(obj), ceiling(u.ux, u.uy));
1073 pline("%s
\82Í%s
\82É
\96½
\92\86\82µ
\82½
\81D", Doname2(obj), ceiling(u.ux, u.uy));
1074 breakmsg(obj, !Blind);
1075 breakobj(obj, u.ux, u.uy, TRUE, TRUE);
1081 action = "
\82É
\96½
\92\86\82µ
\82½";
1084 action = "almost hits";
1086 action = "
\82É
\82à
\82¤
\8f
\82µ
\82Å
\96½
\92\86\82·
\82é
\82Æ
\82±
\82ë
\82¾
\82Á
\82½";
1089 pline("%s %s the %s, then falls back on top of your %s.", Doname2(obj),
1090 action, ceiling(u.ux, u.uy), body_part(HEAD));
1092 pline("%s
\82Í%s%s
\81C
\82»
\82µ
\82Ä%s
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä
\82«
\82½
\81D", Doname2(obj),
1093 ceiling(u.ux, u.uy), action, body_part(HEAD));
1096 /* object now hits you */
1098 if (obj->oclass == POTION_CLASS) {
1099 potionhit(&youmonst, obj, POTHIT_HERO_THROW);
1100 } else if (breaktest(obj)) {
1101 int otyp = obj->otyp;
1104 /* need to check for blindness result prior to destroying obj */
1105 blindinc = ((otyp == CREAM_PIE || otyp == BLINDING_VENOM)
1106 /* AT_WEAP is ok here even if attack type was AT_SPIT */
1107 && can_blnd(&youmonst, &youmonst, AT_WEAP, obj))
1110 breakmsg(obj, !Blind);
1111 breakobj(obj, u.ux, u.uy, TRUE, TRUE);
1112 obj = 0; /* it's now gone */
1115 if (petrifier && !Stone_resistance
1116 && !(poly_when_stoned(youmonst.data)
1117 && polymon(PM_STONE_GOLEM))) {
1118 /* egg ends up "all over your face"; perhaps
1119 visored helmet should still save you here */
1122 Your("%s fails to protect you.", helm_simple_name(uarmh));
1124 Your("%s
\82Í
\82 \82È
\82½
\82ð
\8eç
\82ê
\82È
\82©
\82Á
\82½
\81D", helm_simple_name(uarmh));
1129 case BLINDING_VENOM:
1131 pline("You've got it all over your %s!", body_part(FACE));
1133 pline("
\82»
\82ê
\82Í%s
\82ð
\82×
\82Á
\82Æ
\82è
\82Æ
\95¢
\82Á
\82½
\81I", body_part(FACE));
1135 if (otyp == BLINDING_VENOM && !Blind)
1137 pline("It blinds you!");
1139 pline("
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I");
1140 u.ucreamed += blindinc;
1141 make_blinded(Blinded + (long) blindinc, FALSE);
1143 Your1(vision_clears);
1150 } else { /* neither potion nor other breaking object */
1151 boolean less_damage = uarmh && is_metallic(uarmh), artimsg = FALSE;
1152 int dmg = dmgval(obj, &youmonst);
1155 /* need a fake die roll here; rn1(18,2) avoids 1 and 20 */
1156 artimsg = artifact_hit((struct monst *) 0, &youmonst, obj, &dmg,
1159 if (!dmg) { /* probably wasn't a weapon; base damage on weight */
1160 dmg = (int) obj->owt / 100;
1165 if (youmonst.data == &mons[PM_SHADE]
1166 && objects[obj->otyp].oc_material != SILVER)
1169 if (dmg > 1 && less_damage)
1174 dmg = 0; /* beware negative rings of increase damage */
1175 dmg = Maybe_Half_Phys(dmg);
1178 if (less_damage && dmg < (Upolyd ? u.mh : u.uhp)) {
1181 pline("Fortunately, you are wearing a hard helmet.");
1183 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1184 /* helmet definitely protects you when it blocks petrification
1186 } else if (!petrifier) {
1189 Your("%s does not protect you.", helm_simple_name(uarmh));
1191 Your("%s
\82Å
\82Í
\96h
\82¬
\82«
\82ê
\82È
\82©
\82Á
\82½
\81D", helm_simple_name(uarmh));
1193 } else if (petrifier && !Stone_resistance
1194 && !(poly_when_stoned(youmonst.data)
1195 && polymon(PM_STONE_GOLEM))) {
1197 killer.format = KILLED_BY;
1199 Strcpy(killer.name, "elementary physics"); /* "what goes up..." */
1201 Strcpy(killer.name, "
\8f\89\93\99\95¨
\97\9d\82É
\82æ
\82è"); /* "what goes up..." */
1204 You("turn to stone.");
1206 You("
\90Î
\82É
\82È
\82Á
\82½
\81D");
1208 dropy(obj); /* bypass most of hitfloor() */
1209 thrownobj = 0; /* now either gone or on floor */
1211 return obj ? TRUE : FALSE;
1216 losehp(Maybe_Half_Phys(dmg), "falling object", KILLED_BY_AN);
1218 losehp(Maybe_Half_Phys(dmg), "
\97\8e\89º
\95¨
\82Å", KILLED_BY_AN);
1224 /* return true for weapon meant to be thrown; excludes ammo */
1226 throwing_weapon(obj)
1229 return (boolean) (is_missile(obj) || is_spear(obj)
1230 /* daggers and knife (excludes scalpel) */
1231 || (is_blade(obj) && !is_sword(obj)
1232 && (objects[obj->otyp].oc_dir & PIERCE))
1233 /* special cases [might want to add AXE] */
1234 || obj->otyp == WAR_HAMMER || obj->otyp == AKLYS);
1237 /* the currently thrown object is returning to you (not for boomerangs) */
1239 sho_obj_return_to_u(obj)
1242 /* might already be our location (bounced off a wall) */
1243 if ((u.dx || u.dy) && (bhitpos.x != u.ux || bhitpos.y != u.uy)) {
1244 int x = bhitpos.x - u.dx, y = bhitpos.y - u.dy;
1246 tmp_at(DISP_FLASH, obj_to_glyph(obj));
1247 while (isok(x,y) && (x != u.ux || y != u.uy)) {
1253 tmp_at(DISP_END, 0);
1257 /* throw an object, NB: obj may be consumed in the process */
1259 throwit(obj, wep_mask, twoweap)
1261 long wep_mask; /* used to re-equip returning boomerang */
1262 boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
1264 register struct monst *mon;
1265 register int range, urange;
1266 boolean crossbowing, impaired = (Confusion || Stunned || Blind
1267 || Hallucination || Fumbling);
1269 notonhead = FALSE; /* reset potentially stale value */
1270 if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) {
1271 boolean slipok = TRUE;
1273 if (ammo_and_launcher(obj, uwep))
1275 pline("%s!", Tobjnam(obj, "misfire"));
1277 pline("%s
\82Í
\82Í
\82¸
\82ê
\82½
\81I", xname(obj));
1279 /* only slip if it's greased or meant to be thrown */
1280 if (obj->greased || throwing_weapon(obj))
1281 /* BUG: this message is grammatically incorrect if obj has
1282 a plural name; greased gloves or boots for instance. */
1284 pline("%s as you throw it!", Tobjnam(obj, "slip"));
1286 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));
1299 if ((u.dx || u.dy || (u.dz < 1))
1300 && calc_capacity((int) obj->owt) > SLT_ENCUMBER
1301 && (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
1302 : (u.uhp < 10 && u.uhp != u.uhpmax))
1303 && obj->owt > (unsigned) ((Upolyd ? u.mh : u.uhp) * 2)
1304 && !Is_airlevel(&u.uz)) {
1306 You("have so little stamina, %s drops from your grasp.",
1308 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",
1310 exercise(A_CON, FALSE);
1316 thrownobj->was_thrown = 1;
1320 bhitpos.x = mon->mx;
1321 bhitpos.y = mon->my;
1324 /* Mjollnir must we wielded to be thrown--caller verifies this;
1325 aklys must we wielded as primary to return when thrown */
1326 && ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR)
1327 || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0))
1330 pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
1331 ceiling(u.ux, u.uy));
1333 pline("%s
\82Í%s
\82É
\96½
\92\86\82µ
\82 \82È
\82½
\82Ì
\8eè
\82É
\96ß
\82Á
\82Ä
\82«
\82½
\81I", xname(obj),
1334 ceiling(u.ux,u.uy));
1337 (void) encumber_msg();
1338 if (obj->owornmask & W_QUIVER) /* in case addinv() autoquivered */
1339 setuqwep((struct obj *) 0);
1341 u.twoweap = twoweap;
1342 } else if (u.dz < 0) {
1343 (void) toss_up(obj, rn2(5) && !Underwater);
1344 } else if (u.dz > 0 && u.usteed && obj->oclass == POTION_CLASS
1346 /* alternative to prayer or wand of opening/spell of knock
1347 for dealing with cursed saddle: throw holy water > */
1348 potionhit(u.usteed, obj, POTHIT_HERO_THROW);
1352 thrownobj = (struct obj *) 0;
1355 } else if (obj->otyp == BOOMERANG && !Underwater) {
1356 if (Is_airlevel(&u.uz) || Levitation)
1357 hurtle(-u.dx, -u.dy, 1, TRUE);
1358 mon = boomhit(obj, u.dx, u.dy);
1359 if (mon == &youmonst) { /* the thing was caught */
1360 exercise(A_DEX, TRUE);
1362 (void) encumber_msg();
1363 if (wep_mask && !(obj->owornmask & wep_mask)) {
1364 setworn(obj, wep_mask);
1365 u.twoweap = twoweap;
1367 thrownobj = (struct obj *) 0;
1371 /* crossbow range is independent of strength */
1373 (ammo_and_launcher(obj, uwep) && weapon_type(uwep) == P_CROSSBOW);
1374 urange = (crossbowing ? 18 : (int) ACURRSTR) / 2;
1375 /* balls are easy to throw or at least roll;
1376 * also, this insures the maximum range of a ball is greater
1377 * than 1, so the effects from throwing attached balls are
1380 if (obj->otyp == HEAVY_IRON_BALL)
1381 range = urange - (int) (obj->owt / 100);
1383 range = urange - (int) (obj->owt / 40);
1387 else if (range >= 5)
1394 if (ammo_and_launcher(obj, uwep)) {
1399 } else if (obj->oclass != GEM_CLASS)
1403 if (Is_airlevel(&u.uz) || Levitation) {
1404 /* action, reaction... */
1413 if (obj->otyp == BOULDER)
1414 range = 20; /* you must be giant */
1415 else if (obj->oartifact == ART_MJOLLNIR)
1416 range = (range + 1) / 2; /* it's heavy */
1417 else if (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)
1418 /* if an aklys is going to return, range is limited by the
1419 length of the attached cord [implicit aspect of item] */
1420 range = min(range, BOLT_LIM / 2);
1421 else if (obj == uball && u.utrap && u.utraptype == TT_INFLOOR)
1427 mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
1428 (int FDECL((*), (MONST_P, OBJ_P))) 0,
1429 (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
1430 thrownobj = obj; /* obj may be null now */
1432 /* have to do this after bhit() so u.ux & u.uy are correct */
1433 if (Is_airlevel(&u.uz) || Levitation)
1434 hurtle(-u.dx, -u.dy, urange, TRUE);
1443 if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) {
1444 thrownobj = (struct obj *) 0;
1445 return; /* alert shk caught it */
1447 (void) snuff_candle(obj);
1448 notonhead = (bhitpos.x != mon->mx || bhitpos.y != mon->my);
1449 obj_gone = thitmonst(mon, obj);
1450 /* Monster may have been tamed; this frees old mon */
1451 mon = m_at(bhitpos.x, bhitpos.y);
1453 /* [perhaps this should be moved into thitmonst or hmon] */
1454 if (mon && mon->isshk
1455 && (!inside_shop(u.ux, u.uy)
1456 || !index(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops)))
1464 ; /* missile has already been handled */
1465 } else if (u.uswallow) {
1466 /* ball is not picked up by monster */
1468 (void) mpickobj(u.ustuck, obj);
1469 thrownobj = (struct obj *) 0;
1471 /* Mjollnir must we wielded to be thrown--caller verifies this;
1472 aklys must we wielded as primary to return when thrown */
1473 if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE))
1474 || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) {
1476 sho_obj_return_to_u(obj); /* display its flight */
1478 if (!impaired && rn2(100)) {
1480 pline("%s to your hand!", Tobjnam(obj, "return"));
1482 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\96ß
\82Á
\82Ä
\82«
\82½
\81I", xname(obj));
1484 (void) encumber_msg();
1485 /* addinv autoquivers an aklys if quiver is empty;
1486 if obj is quivered, remove it before wielding */
1487 if (obj->owornmask & W_QUIVER)
1488 setuqwep((struct obj *) 0);
1490 u.twoweap = twoweap;
1491 if (cansee(bhitpos.x, bhitpos.y))
1492 newsym(bhitpos.x, bhitpos.y);
1498 pline(Blind ? "%s lands %s your %s."
1499 : "%s back to you, landing %s your %s.",
1500 Blind ? Something : Tobjnam(obj, "return"),
1501 Levitation ? "beneath" : "at",
1502 makeplural(body_part(FOOT)));
1504 pline("%s
\82Í%s
\82 \82È
\82½
\82Ì%s
\82Ì%s
\82É
\97\8e\82¿
\82½
\81D",
1506 Blind ? "" : "
\96ß
\82Á
\82Ä
\82«
\82Ä
\81C",
1508 Levitation ? "
\89º" : "
\82»
\82Î");
1513 pline(Blind ? "%s your %s!"
1514 : "%s back toward you, hitting your %s!",
1515 Tobjnam(obj, Blind ? "hit" : "fly"),
1518 pline("%s
\82Í%s
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
1520 Blind ? "" : "
\96ß
\82Á
\82Ä
\82«
\82Ä
\81C",
1524 (void) artifact_hit((struct monst *) 0, &youmonst,
1527 losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
1532 Sprintf(jbuf, "%s
\82Å", xname(obj));
1533 losehp(Maybe_Half_Phys(dmg), jbuf, KILLED_BY);
1537 if (ship_object(obj, u.ux, u.uy, FALSE)) {
1538 thrownobj = (struct obj *) 0;
1543 thrownobj = (struct obj *) 0;
1546 /* when this location is stepped on, the weapon will be
1547 auto-picked up due to 'obj->was_thrown' of 1;
1548 addinv() prevents thrown Mjollnir from being placed
1549 into the quiver slot, but an aklys will end up there if
1550 that slot is empty at the time; since hero will need to
1551 explicitly rewield the weapon to get throw-and-return
1552 capability back anyway, quivered or not shouldn't matter */
1553 pline("%s to return!", Tobjnam(obj, "fail"));
1554 /* continue below with placing 'obj' at target location */
1558 if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj)) {
1559 tmp_at(DISP_FLASH, obj_to_glyph(obj));
1560 tmp_at(bhitpos.x, bhitpos.y);
1562 tmp_at(DISP_END, 0);
1563 breakmsg(obj, cansee(bhitpos.x, bhitpos.y));
1564 breakobj(obj, bhitpos.x, bhitpos.y, TRUE, TRUE);
1565 thrownobj = (struct obj *) 0;
1569 if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall")) {
1571 if (flooreffects(obj,bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
1572 thrownobj = (struct obj *) 0;
1575 obj_no_longer_held(obj);
1576 if (mon && mon->isshk && is_pick(obj)) {
1577 if (cansee(bhitpos.x, bhitpos.y))
1579 pline("%s snatches up %s.", Monnam(mon), the(xname(obj)));
1581 pline("%s
\82Í%s
\82ð
\92D
\82¢
\82Æ
\82Á
\82½
\81D", Monnam(mon), xname(obj));
1582 if (*u.ushops || obj->unpaid)
1583 check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1584 (void) mpickobj(mon, obj); /* may merge and free obj */
1585 thrownobj = (struct obj *) 0;
1588 (void) snuff_candle(obj);
1589 if (!mon && ship_object(obj, bhitpos.x, bhitpos.y, FALSE)) {
1590 thrownobj = (struct obj *) 0;
1593 thrownobj = (struct obj *) 0;
1594 place_object(obj, bhitpos.x, bhitpos.y);
1595 /* container contents might break;
1596 do so before turning ownership of thrownobj over to shk
1597 (container_impact_dmg handles item already owned by shop) */
1598 if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ))
1599 /* <x,y> is spot where you initiated throw, not bhitpos */
1600 container_impact_dmg(obj, u.ux, u.uy);
1601 /* charge for items thrown out of shop;
1602 shk takes possession for items thrown into one */
1603 if ((*u.ushops || obj->unpaid) && obj != uball)
1604 check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1608 drop_ball(bhitpos.x, bhitpos.y);
1609 if (cansee(bhitpos.x, bhitpos.y))
1610 newsym(bhitpos.x, bhitpos.y);
1611 if (obj_sheds_light(obj))
1612 vision_full_recalc = 1;
1616 /* an object may hit a monster; various factors adjust the chance of hitting
1619 omon_adj(mon, obj, mon_notices)
1622 boolean mon_notices;
1626 /* size of target affects the chance of hitting */
1627 tmp += (mon->data->msize - MZ_MEDIUM); /* -2..+5 */
1628 /* sleeping target is more likely to be hit */
1629 if (mon->msleeping) {
1634 /* ditto for immobilized target */
1635 if (!mon->mcanmove || !mon->data->mmove) {
1637 if (mon_notices && mon->data->mmove && !rn2(10)) {
1642 /* some objects are more likely to hit than others */
1643 switch (obj->otyp) {
1644 case HEAVY_IRON_BALL:
1652 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1653 || obj->oclass == GEM_CLASS)
1654 tmp += hitval(obj, mon);
1660 /* thrown object misses target monster */
1662 tmiss(obj, mon, maybe_wakeup)
1665 boolean maybe_wakeup;
1667 const char *missile = mshot_xname(obj);
1669 /* If the target can't be seen or doesn't look like a valid target,
1670 avoid "the arrow misses it," or worse, "the arrows misses the mimic."
1671 An attentive player will still notice that this is different from
1672 an arrow just landing short of any target (no message in that case),
1673 so will realize that there is a valid target here anyway. */
1674 if (!canseemon(mon) || (mon->m_ap_type && mon->m_ap_type != M_AP_MONSTER))
1676 pline("%s %s.", The(missile), otense(obj, "miss"));
1678 pline("%s
\82Í
\82Í
\82¸
\82ê
\82½
\81D", missile);
1681 if (maybe_wakeup && !rn2(3))
1686 #define quest_arti_hits_leader(obj, mon) \
1687 (obj->oartifact && is_quest_artifact(obj) \
1688 && mon->m_id == quest_status.leader_m_id)
1691 * Object thrown by player arrives at monster's location.
1692 * Return 1 if obj has disappeared or otherwise been taken care of,
1693 * 0 if caller must take care of it.
1694 * Also used for kicked objects and for polearms/grapnel applied at range.
1698 register struct monst *mon;
1699 register struct obj *obj; /* thrownobj or kickedobj or uwep */
1701 register int tmp; /* Base chance to hit */
1702 register int disttmp; /* distance modifier */
1703 int otyp = obj->otyp, hmode;
1704 boolean guaranteed_hit = (u.uswallow && mon == u.ustuck);
1707 hmode = (obj == uwep) ? HMON_APPLIED
1708 : (obj == kickedobj) ? HMON_KICKED
1711 /* Differences from melee weapons:
1713 * Dex still gives a bonus, but strength does not.
1714 * Polymorphed players lacking attacks may still throw.
1715 * There's a base -1 to hit.
1716 * No bonuses for fleeing or stunned targets (they don't dodge
1717 * melee blows as readily, but dodging arrows is hard anyway).
1718 * Not affected by traps, etc.
1719 * Certain items which don't in themselves do damage ignore tmp.
1720 * Distance and monster size affect chance to hit.
1722 tmp = -1 + Luck + find_mac(mon) + u.uhitinc
1723 + maybe_polyd(youmonst.data->mlevel, u.ulevel);
1724 if (ACURR(A_DEX) < 4)
1726 else if (ACURR(A_DEX) < 6)
1728 else if (ACURR(A_DEX) < 8)
1730 else if (ACURR(A_DEX) >= 14)
1731 tmp += (ACURR(A_DEX) - 14);
1733 /* Modify to-hit depending on distance; but keep it sane.
1734 * Polearms get a distance penalty even when wielded; it's
1735 * hard to hit at a distance.
1737 disttmp = 3 - distmin(u.ux, u.uy, mon->mx, mon->my);
1742 /* gloves are a hindrance to proper use of bows */
1743 if (uarmg && uwep && objects[uwep->otyp].oc_skill == P_BOW) {
1744 switch (uarmg->otyp) {
1745 case GAUNTLETS_OF_POWER: /* metal */
1748 case GAUNTLETS_OF_FUMBLING:
1751 case LEATHER_GLOVES:
1752 case GAUNTLETS_OF_DEXTERITY:
1755 impossible("Unknown type of gloves (%d)", uarmg->otyp);
1760 tmp += omon_adj(mon, obj, TRUE);
1761 if (is_orc(mon->data)
1762 && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
1764 if (guaranteed_hit) {
1765 tmp += 1000; /* Guaranteed hit */
1768 if (obj->oclass == GEM_CLASS && is_unicorn(mon->data)) {
1769 if (mon->msleeping || !mon->mcanmove) {
1770 tmiss(obj, mon, FALSE);
1772 } else if (mon->mtame) {
1774 pline("%s catches and drops %s.", Monnam(mon), the(xname(obj)));
1776 pline("%s
\82Í%s
\82ð
\82
\82í
\82¦
\82Ä
\92u
\82¢
\82½
\81D", Monnam(mon), xname(obj));
1780 pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1782 pline("%s
\82Í%s
\82ð
\82
\82í
\82¦
\82½
\81D", Monnam(mon), xname(obj));
1783 return gem_accept(mon, obj);
1787 /* don't make game unwinnable if naive player throws artifact
1788 at leader... (kicked artifact is ok too; HMON_APPLIED could
1789 occur if quest artifact polearm or grapnel ever gets added) */
1790 if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) {
1791 /* AIS: changes to wakeup() means that it's now less inappropriate here
1792 than it used to be, but the manual version works just as well */
1794 mon->mstrategy &= ~STRAT_WAITMASK;
1796 if (mon->mcanmove) {
1798 pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1800 pline("%s
\82Í%s
\82ð
\92Í
\82ñ
\82¾
\81D", Monnam(mon), xname(obj));
1801 if (mon->mpeaceful) {
1802 boolean next2u = monnear(mon, u.ux, u.uy);
1804 finish_quest(obj); /* acknowledge quest completion */
1806 pline("%s %s %s back to you.", Monnam(mon),
1807 (next2u ? "hands" : "tosses"), the(xname(obj)));
1809 pline("%s
\82Í%s
\82ð
\82 \82È
\82½
\82É
\95Ô
\82µ
\82½
\81D", Monnam(mon),
1813 sho_obj_return_to_u(obj);
1814 obj = addinv(obj); /* back into your inventory */
1815 (void) encumber_msg();
1817 /* angry leader caught it and isn't returning it */
1818 if (*u.ushops || obj->unpaid) /* not very likely... */
1819 check_shop_obj(obj, mon->mx, mon->my, FALSE);
1820 (void) mpickobj(mon, obj);
1822 return 1; /* caller doesn't need to place it */
1829 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1830 || obj->oclass == GEM_CLASS) {
1831 if (hmode == HMON_KICKED) {
1832 /* throwing adjustments and weapon skill bonus don't apply */
1833 tmp -= (is_ammo(obj) ? 5 : 3);
1834 } else if (is_ammo(obj)) {
1835 if (!ammo_and_launcher(obj, uwep)) {
1838 tmp += uwep->spe - greatest_erosion(uwep);
1839 tmp += weapon_hit_bonus(uwep);
1840 if (uwep->oartifact)
1841 tmp += spec_abon(uwep, mon);
1843 * Elves and Samurais are highly trained w/bows,
1844 * especially their own special types of bow.
1845 * Polymorphing won't make you a bow expert.
1847 if ((Race_if(PM_ELF) || Role_if(PM_SAMURAI))
1848 && (!Upolyd || your_race(youmonst.data))
1849 && objects[uwep->otyp].oc_skill == P_BOW) {
1851 if (Race_if(PM_ELF) && uwep->otyp == ELVEN_BOW)
1853 else if (Role_if(PM_SAMURAI) && uwep->otyp == YUMI)
1857 } else { /* thrown non-ammo or applied polearm/grapnel */
1858 if (otyp == BOOMERANG) /* arbitrary */
1860 else if (throwing_weapon(obj)) /* meant to be thrown */
1862 else if (obj == thrownobj) /* not meant to be thrown */
1864 /* we know we're dealing with a weapon or weptool handled
1865 by WEAPON_SKILLS once ammo objects have been excluded */
1866 tmp += weapon_hit_bonus(obj);
1869 if (tmp >= dieroll) {
1870 boolean wasthrown = (thrownobj != 0);
1872 /* attack hits mon */
1873 if (hmode == HMON_APPLIED)
1874 u.uconduct.weaphit++;
1875 if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */
1876 cutworm(mon, bhitpos.x, bhitpos.y, obj);
1878 exercise(A_DEX, TRUE);
1879 /* if hero was swallowed and projectile killed the engulfer,
1880 'obj' got added to engulfer's inventory and then dropped,
1881 so we can't safely use that pointer anymore; it escapes
1882 the chance to be used up here... */
1883 if (wasthrown && !thrownobj)
1886 /* projectiles other than magic stones
1887 sometimes disappear when thrown */
1888 if (objects[otyp].oc_skill < P_NONE
1889 && objects[otyp].oc_skill > -P_BOOMERANG
1890 && !objects[otyp].oc_magic) {
1891 /* we were breaking 2/3 of everything unconditionally.
1892 * we still don't want anything to survive unconditionally,
1893 * but we need ammo to stay around longer on average.
1897 chance = 3 + greatest_erosion(obj) - obj->spe;
1899 broken = rn2(chance);
1902 if (obj->blessed && !rnl(4))
1906 if (*u.ushops || obj->unpaid)
1907 check_shop_obj(obj, bhitpos.x, bhitpos.y, TRUE);
1908 obfree(obj, (struct obj *) 0);
1912 passive_obj(mon, obj, (struct attack *) 0);
1914 tmiss(obj, mon, TRUE);
1915 if (hmode == HMON_APPLIED)
1919 } else if (otyp == HEAVY_IRON_BALL) {
1920 exercise(A_STR, TRUE);
1921 if (tmp >= dieroll) {
1922 int was_swallowed = guaranteed_hit;
1924 exercise(A_DEX, TRUE);
1925 if (!hmon(mon, obj, hmode, dieroll)) { /* mon killed */
1926 if (was_swallowed && !u.uswallow && obj == uball)
1927 return 1; /* already did placebc() */
1930 tmiss(obj, mon, TRUE);
1933 } else if (otyp == BOULDER) {
1934 exercise(A_STR, TRUE);
1935 if (tmp >= dieroll) {
1936 exercise(A_DEX, TRUE);
1937 (void) hmon(mon, obj, hmode, dieroll);
1939 tmiss(obj, mon, TRUE);
1942 } else if ((otyp == EGG || otyp == CREAM_PIE || otyp == BLINDING_VENOM
1943 || otyp == ACID_VENOM)
1944 && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
1945 (void) hmon(mon, obj, hmode, dieroll);
1946 return 1; /* hmon used it up */
1948 } else if (obj->oclass == POTION_CLASS
1949 && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
1950 potionhit(mon, obj, POTHIT_HERO_THROW);
1953 } else if (befriend_with_obj(mon->data, obj)
1954 || (mon->mtame && dogfood(mon, obj) <= ACCFOOD)) {
1955 if (tamedog(mon, obj)) {
1956 return 1; /* obj is gone */
1958 tmiss(obj, mon, FALSE);
1960 mon->mstrategy &= ~STRAT_WAITMASK;
1962 } else if (guaranteed_hit) {
1963 /* this assumes that guaranteed_hit is due to swallowing */
1965 if (obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])) {
1966 if (is_animal(u.ustuck->data)) {
1967 minstapetrify(u.ustuck, TRUE);
1968 /* Don't leave a cockatrice corpse available in a statue */
1976 pline("%s into %s %s.", Tobjnam(obj, "vanish"),
1977 s_suffix(mon_nam(mon)),
1978 is_animal(u.ustuck->data) ? "entrails" : "currents");
1980 pline("%s
\82Í%s
\82Ì%s
\82Ö
\8fÁ
\82¦
\82½
\81D", xname(obj),
1982 is_animal(u.ustuck->data) ? "
\93à
\91\9f\82Ì
\92\86" : "
\97¬
\82ê");
1985 tmiss(obj, mon, TRUE);
1992 gem_accept(mon, obj)
1993 register struct monst *mon;
1994 register struct obj *obj;
1997 boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type);
1998 boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE;
2001 static NEARDATA const char nogood[] = " is not interested in your junk.";
2003 static NEARDATA const char nogood[] = "
\82 \82È
\82½
\82Ì
\83K
\83\89\83N
\83^
\82É
\8b»
\96¡
\82ð
\8e¦
\82³
\82È
\82¢
\81D";
2005 static NEARDATA const char acceptgift[] = " accepts your gift.";
2007 static NEARDATA const char acceptgift[] = "
\82 \82È
\82½
\82Ì
\91¡
\82è
\95¨
\82ð
\8eó
\82¯
\82Æ
\82Á
\82½
\81D";
2009 static NEARDATA const char maybeluck[] = " hesitatingly";
2011 static NEARDATA const char maybeluck[] = "
\82½
\82ß
\82ç
\82¢
\82È
\82ª
\82ç";
2013 static NEARDATA const char noluck[] = " graciously";
2015 static NEARDATA const char noluck[] = "
\92\9a\8fd
\82É";
2017 static NEARDATA const char addluck[] = " gratefully";
2019 static NEARDATA const char addluck[] = "
\8aì
\82ñ
\82Å";
2021 Strcpy(buf, Monnam(mon));
2023 Strcat(buf, "
\82Í");
2028 /* object properly identified */
2029 if (obj->dknown && objects[obj->otyp].oc_name_known) {
2032 Strcat(buf, addluck);
2035 Strcat(buf, maybeluck);
2036 change_luck(rn2(7) - 3);
2039 Strcat(buf, nogood);
2042 /* making guesses */
2043 } else if (has_oname(obj) || objects[obj->otyp].oc_uname) {
2046 Strcat(buf, addluck);
2049 Strcat(buf, maybeluck);
2050 change_luck(rn2(3) - 1);
2053 Strcat(buf, nogood);
2056 /* value completely unknown to @ */
2060 Strcat(buf, addluck);
2063 Strcat(buf, maybeluck);
2064 change_luck(rn2(3) - 1);
2067 Strcat(buf, noluck);
2070 Strcat(buf, acceptgift);
2071 if (*u.ushops || obj->unpaid)
2072 check_shop_obj(obj, mon->mx, mon->my, TRUE);
2073 (void) mpickobj(mon, obj); /* may merge and free obj */
2079 if (!tele_restrict(mon))
2080 (void) rloc(mon, TRUE);
2085 * Comments about the restructuring of the old breaks() routine.
2087 * There are now three distinct phases to object breaking:
2088 * breaktest() - which makes the check/decision about whether the
2089 * object is going to break.
2090 * breakmsg() - which outputs a message about the breakage,
2091 * appropriate for that particular object. Should
2092 * only be called after a positive breaktest().
2093 * on the object and, if it going to be called,
2094 * it must be called before calling breakobj().
2095 * Calling breakmsg() is optional.
2096 * breakobj() - which actually does the breakage and the side-effects
2097 * of breaking that particular object. This should
2098 * only be called after a positive breaktest() on the
2101 * Each of the above routines is currently static to this source module.
2102 * There are two routines callable from outside this source module which
2103 * perform the routines above in the correct sequence.
2105 * hero_breaks() - called when an object is to be broken as a result
2106 * of something that the hero has done. (throwing it,
2108 * breaks() - called when an object is to be broken for some
2109 * reason other than the hero doing something to it.
2113 * The hero causes breakage of an object (throwing, dropping it, etc.)
2114 * Return 0 if the object didn't break, 1 if the object broke.
2117 hero_breaks(obj, x, y, from_invent)
2119 xchar x, y; /* object location (ox, oy may not be right) */
2120 boolean from_invent; /* thrown or dropped by player; maybe on shop bill */
2122 boolean in_view = Blind ? FALSE : (from_invent || cansee(x, y));
2123 if (!breaktest(obj))
2125 breakmsg(obj, in_view);
2126 breakobj(obj, x, y, TRUE, from_invent);
2131 * The object is going to break for a reason other than the hero doing
2133 * Return 0 if the object doesn't break, 1 if the object broke.
2138 xchar x, y; /* object location (ox, oy may not be right) */
2140 boolean in_view = Blind ? FALSE : cansee(x, y);
2142 if (!breaktest(obj))
2144 breakmsg(obj, in_view);
2145 breakobj(obj, x, y, FALSE, FALSE);
2150 release_camera_demon(obj, x, y)
2156 && (mtmp = makemon(&mons[rn2(3) ? PM_HOMUNCULUS : PM_IMP], x, y,
2157 NO_MM_FLAGS)) != 0) {
2158 if (canspotmon(mtmp))
2160 pline("%s is released!", Hallucination
2161 ? An(rndmonnam(NULL))
2162 : "The picture-painting demon");
2164 pline("%s
\82ª
\89ð
\95ú
\82³
\82ê
\82½
\81I", Hallucination
2166 : "
\82¨
\8aG
\95`
\82«
\82Ì
\88«
\96\82");
2168 mtmp->mpeaceful = !obj->cursed;
2174 * Unconditionally break an object. Assumes all resistance checks
2175 * and break messages have been delivered prior to getting here.
2178 breakobj(obj, x, y, hero_caused, from_invent)
2180 xchar x, y; /* object location (ox, oy may not be right) */
2181 boolean hero_caused; /* is this the hero's fault? */
2182 boolean from_invent;
2184 boolean fracture = FALSE;
2186 switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2191 case POT_WATER: /* really, all potions */
2192 obj->in_use = 1; /* in case it's fatal */
2193 if (obj->otyp == POT_OIL && obj->lamplit) {
2194 explode_oil(obj, x, y);
2195 } else if (distu(x, y) <= 2) {
2196 if (!breathless(youmonst.data) || haseyes(youmonst.data)) {
2197 if (obj->otyp != POT_WATER) {
2198 if (!breathless(youmonst.data)) {
2199 /* [what about "familiar odor" when known?] */
2201 You("smell a peculiar odor...");
2203 You("
\96ò
\82Á
\82Û
\82¢
\93õ
\82¢
\82ª
\82µ
\82½
\81D
\81D
\81D");
2206 const char *eyes = body_part(EYE);
2208 if (eyecount(youmonst.data) != 1)
2209 eyes = makeplural(eyes);
2210 Your("%s %s.", eyes, vtense(eyes, "water"));
2212 You("
\97Ü%s
\82É
\82È
\82Á
\82½
\81D", body_part(EYE));
2219 /* monster breathing isn't handled... [yet?] */
2221 case EXPENSIVE_CAMERA:
2222 release_camera_demon(obj, x, y);
2225 /* breaking your own eggs is bad luck */
2226 if (hero_caused && obj->spe && obj->corpsenm >= LOW_PM)
2227 change_luck((schar) -min(obj->quan, 5L));
2231 /* caller will handle object disposition;
2232 we're just doing the shop theft handling */
2240 if (from_invent || obj->unpaid) {
2241 if (*u.ushops || obj->unpaid)
2242 check_shop_obj(obj, x, y, TRUE);
2243 } else if (!obj->no_charge && costly_spot(x, y)) {
2244 /* it is assumed that the obj is a floor-object */
2245 char *o_shop = in_rooms(x, y, SHOPBASE);
2246 struct monst *shkp = shop_keeper(*o_shop);
2248 if (shkp) { /* (implies *o_shop != '\0') */
2249 static NEARDATA long lastmovetime = 0L;
2250 static NEARDATA boolean peaceful_shk = FALSE;
2251 /* We want to base shk actions on her peacefulness
2252 at start of this turn, so that "simultaneous"
2253 multiple breakage isn't drastically worse than
2254 single breakage. (ought to be done via ESHK) */
2255 if (moves != lastmovetime)
2256 peaceful_shk = shkp->mpeaceful;
2257 if (stolen_value(obj, x, y, peaceful_shk, FALSE) > 0L
2258 && (*o_shop != u.ushops[0] || !inside_shop(u.ux, u.uy))
2259 && moves != lastmovetime)
2260 make_angry_shk(shkp, x, y);
2261 lastmovetime = moves;
2270 * Check to see if obj is going to break, but don't actually break it.
2271 * Return 0 if the object isn't going to break, 1 if it is.
2277 if (obj_resists(obj, 1, 99))
2279 if (objects[obj->otyp].oc_material == GLASS && !obj->oartifact
2280 && obj->oclass != GEM_CLASS)
2282 switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2283 case EXPENSIVE_CAMERA:
2284 case POT_WATER: /* really, all potions */
2289 case BLINDING_VENOM:
2297 breakmsg(obj, in_view)
2301 const char *to_pieces;
2306 /* "shatter"
\81¨ "
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½"
2307 "shatter into a thousand pieces"
\81¨ "
\82
\82¾
\82¯
\82Ä
\82Î
\82ç
\82Î
\82ç
\82É
\82È
\82Á
\82½" */
2308 to_pieces = "
\82±
\82È
\82²
\82È";
2310 switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2311 default: /* glass or crystal wand */
2312 if (obj->oclass != WAND_CLASS)
2313 impossible("breaking odd object?");
2315 case CRYSTAL_PLATE_MAIL:
2319 case EXPENSIVE_CAMERA:
2321 to_pieces = " into a thousand pieces";
2323 to_pieces = "
\82
\82¾
\82¯
\82Ä
\82Î
\82ç
\82Î
\82ç";
2325 case POT_WATER: /* really, all potions */
2328 You_hear("%s shatter!", something);
2330 You_hear("%s
\82ª
\89ó
\82ê
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81I", something);
2333 pline("%s shatter%s%s!", Doname2(obj),
2334 (obj->quan == 1L) ? "s" : "", to_pieces);
2336 pline("%s
\82Í%s
\82É
\82È
\82Á
\82½
\81I", Doname2(obj), to_pieces);
2344 pline("
\83r
\83`
\83\83\81I");
2349 pline("What a mess!");
2351 pline("
\82±
\82è
\82á
\82Ð
\82Ç
\82¢
\81I");
2354 case BLINDING_VENOM:
2358 pline("
\83r
\83`
\83\83\81I");
2367 int range, odx, ody;
2368 register struct monst *mon;
2370 if (!u.dx && !u.dy && !u.dz) {
2372 You("cannot throw gold at yourself.");
2374 pline("
\8e©
\95ª
\82É
\8bà
\89Ý
\82ð
\93\8a\82°
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D");
2380 pline(is_animal(u.ustuck->data) ? "%s in the %s's entrails."
2382 "The money disappears", mon_nam(u.ustuck));
2384 pline(is_animal(u.ustuck->data) ? "
\8bà
\89Ý
\82Í%s
\82Ì
\95 \82Ì
\92\86\82Ö
\8fÁ
\82¦
\82Ä
\82¢
\82Á
\82½
\81D"
2385 : "
\8bà
\89Ý
\82Í%s
\82Ì
\92\86\82Ö
\8fÁ
\82¦
\82Ä
\82¢
\82Á
\82½
\81D",
2388 add_to_minv(u.ustuck, obj);
2393 if (u.dz < 0 && !Is_airlevel(&u.uz) && !Underwater
2394 && !Is_waterlevel(&u.uz)) {
2396 pline_The("gold hits the %s, then falls back on top of your %s.",
2397 ceiling(u.ux, u.uy), body_part(HEAD));
2399 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",
2400 ceiling(u.ux,u.uy), body_part(HEAD));
2402 /* some self damage? */
2405 pline("Fortunately, you are wearing %s!",
2407 pline("
\8dK
\89^
\82È
\82±
\82Æ
\82É
\81C
\82 \82È
\82½
\82Í%s
\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\81I",
2408 an(helm_simple_name(uarmh)));
2413 /* consistent with range for normal objects */
2414 range = (int) ((ACURRSTR) / 2 - obj->owt / 40);
2416 /* see if the gold has a place to move into */
2419 if (!ZAP_POS(levl[odx][ody].typ) || closed_door(odx, ody)) {
2423 mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
2424 (int FDECL((*), (MONST_P, OBJ_P))) 0,
2425 (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
2427 return 1; /* object is gone */
2429 if (ghitm(mon, obj)) /* was it caught? */
2432 if (ship_object(obj, bhitpos.x, bhitpos.y, FALSE))
2439 if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall"))
2441 if (flooreffects(obj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é"))
2445 pline_The("gold hits the %s.", surface(bhitpos.x, bhitpos.y));
2447 pline("
\8bà
\89Ý
\82Í%s
\82É
\96½
\92\86\82µ
\82½
\81D", surface(bhitpos.x, bhitpos.y));
2448 place_object(obj, bhitpos.x, bhitpos.y);
2450 sellobj(obj, bhitpos.x, bhitpos.y);
2452 newsym(bhitpos.x, bhitpos.y);