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-2019 */
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) {
660 You("hit the door edge!");
662 You("
\94à
\82Ì
\92[
\82É
\93\96\82½
\82Á
\82½
\81I");
666 pline("
\82¢
\82Ä
\82Á
\81I");
667 if (IS_TREE(levl[x][y].typ))
669 s = "bumping into a tree";
671 s = "
\96Ø
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä";
672 else if (IS_ROCK(levl[x][y].typ))
674 s = "bumping into a wall";
676 s = "
\95Ç
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä";
679 s = "bumping into a door";
681 s = "
\94à
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä";
682 dmg = rnd(2 + *range);
683 losehp(Maybe_Half_Phys(dmg), s, KILLED_BY);
684 wake_nearto(x,y, 10);
687 if (levl[x][y].typ == IRONBARS) {
689 You("crash into some iron bars. Ouch!");
691 You("
\93S
\82Ì
\96_
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81D
\82¢
\82Ä
\82Á
\81I");
692 dmg = rnd(2 + *range);
694 losehp(Maybe_Half_Phys(dmg), "crashing into iron bars",
697 losehp(Maybe_Half_Phys(dmg), "
\93S
\82Ì
\96_
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä",
700 wake_nearto(x,y, 20);
703 if ((obj = sobj_at(BOULDER, x, y)) != 0) {
705 You("bump into a %s. Ouch!", xname(obj));
707 You("%s
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81D
\82¢
\82Ä
\82Á
\81I", xname(obj));
708 dmg = rnd(2 + *range);
710 losehp(Maybe_Half_Phys(dmg), "bumping into a boulder", KILLED_BY);
712 losehp(Maybe_Half_Phys(dmg), "
\8aâ
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82Ä", KILLED_BY);
713 wake_nearto(x,y, 10);
717 /* did we hit a no-dig non-wall position? */
719 You("smack into something!");
721 You("
\89½
\82©
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81I");
722 dmg = rnd(2 + *range);
724 losehp(Maybe_Half_Phys(dmg), "touching the edge of the universe",
727 losehp(Maybe_Half_Phys(dmg), "
\90¢
\8aE
\82Ì
\89Ê
\82Ä
\82É
\90G
\82ê
\82Ä",
730 wake_nearto(x,y, 10);
733 if ((u.ux - x) && (u.uy - y) && bad_rock(youmonst.data, u.ux, y)
734 && bad_rock(youmonst.data, x, u.uy)) {
735 boolean too_much = (invent && (inv_weight() + weight_cap() > 600));
737 /* Move at a diagonal. */
738 if (bigmonst(youmonst.data) || too_much) {
740 You("%sget forcefully wedged into a crevice.",
741 too_much ? "and all your belongings " : "");
743 You("%s
\82Í
\82Þ
\82è
\82â
\82è
\82·
\82«
\8aÔ
\82É
\89\9f\82µ
\8d\9e\82ß
\82ç
\82ê
\82½
\81D",
744 too_much ? "
\82Æ
\91S
\95\94\82Ì
\89×
\95¨" : "");
746 dmg = rnd(2 + *range);
748 losehp(Maybe_Half_Phys(dmg), "wedging into a narrow crevice",
751 losehp(Maybe_Half_Phys(dmg), "
\8b·
\82¢
\82·
\82«
\8aÔ
\82É
\89\9f\82µ
\8d\9e\82ß
\82ç
\82ê
\82Ä",
754 wake_nearto(x,y, 10);
760 if ((mon = m_at(x, y)) != 0
761 #if 0 /* we can't include these two exceptions unless we know we're
762 * going to end up past the current spot rather than on it;
763 * for that, we need to know that the range is not exhausted
764 * and also that the next spot doesn't contain an obstacle */
765 && !(mon->mundetected && hides_under(mon) && (Flying || Levitation))
766 && !(mon->mundetected && mon->data->mlet == S_EEL
767 && (Flying || Levitation || Wwalking))
770 const char *mnam, *pronoun;
771 int glyph = glyph_at(x, y);
773 mon->mundetected = 0; /* wakeup() will handle mimic */
774 mnam = a_monnam(mon); /* after unhiding */
777 if (!strcmp(mnam, "it")) {
779 if (!strcmp(mnam, "
\89½
\8eÒ
\82©")) {
781 /* mhim() uses pronoun_gender() which forces neuter if monster
782 can't be seen; we want him/her for humanoid sensed by touch */
784 if (!strcmp(pronoun, "it") && humanoid(mon->data))
786 if (!strcmp(pronoun, "
\89½
\8eÒ
\82©") && humanoid(mon->data))
788 pronoun = genders[mon->female].him;
790 mnam = !strcmp(pronoun, "it") ? "something" : "someone";
792 mnam = !strcmp(pronoun, "
\89½
\8eÒ
\82©") ? "
\89½
\82©" : "
\89½
\8eÒ
\82©";
795 if (!glyph_is_monster(glyph) && !glyph_is_invisible(glyph))
797 You("find %s by bumping into %s.", mnam, pronoun);
799 You("
\82Ô
\82¿
\82 \82½
\82Á
\82½
\82±
\82Æ
\82Å%s
\82ð
\8c©
\82Â
\82¯
\82½
\81D", mnam);
803 You("bump into %s.", mnam);
805 You("%s
\82É
\82Ô
\82¿
\82 \82½
\82Á
\82½
\81D", mnam);
807 if (!canspotmon(mon))
808 map_invisible(mon->mx, mon->my);
809 setmangry(mon, FALSE);
810 wake_nearto(x, y, 10);
814 if ((u.ux - x) && (u.uy - y)
815 && bad_rock(youmonst.data, u.ux, y)
816 && bad_rock(youmonst.data, x, u.uy)) {
817 /* Move at a diagonal. */
820 You("come to an abrupt halt!");
822 You("
\82Æ
\82Â
\82º
\82ñ
\92â
\8e~
\82µ
\82½
\81I");
827 /* Caller has already determined that dragging the ball is allowed */
828 if (Punished && uball->where == OBJ_FLOOR) {
830 xchar ballx, bally, chainx, chainy;
833 if (drag_ball(x, y, &bc_control, &ballx, &bally, &chainx,
834 &chainy, &cause_delay, TRUE))
835 move_bc(0, bc_control, ballx, bally, chainx, chainy);
840 u_on_newpos(x, y); /* set u.<ux,uy>, u.usteed-><mx,my>; cliparound(); */
841 newsym(ox, oy); /* update old position */
842 vision_recalc(1); /* update for new position */
845 if (is_pool(x, y) && !u.uinwater
846 && ((Is_waterlevel(&u.uz) && levl[x][y].typ == WATER)
847 || !(Levitation || Flying || Wwalking))) {
848 multi = 0; /* can move, so drown() allows crawling out of water */
854 * Each trap should really trigger on the recoil if
855 * it would trigger during normal movement. However,
856 * not all the possible side-effects of this are
857 * tested [as of 3.4.0] so we trigger those that
858 * we have tested, and offer a message for the
859 * ones that we have not yet tested.
861 if ((ttmp = t_at(x, y)) != 0) {
862 if (ttmp->ttyp == MAGIC_PORTAL) {
865 } else if (ttmp->ttyp == VIBRATING_SQUARE) {
867 pline("The ground vibrates as you pass it.");
869 pline("
\82 \82È
\82½
\82ª
\92Ê
\89ß
\82·
\82é
\82Æ
\92n
\96Ê
\82ª
\90k
\93®
\82µ
\82½
\81D");
870 dotrap(ttmp, 0); /* doesn't print messages */
871 } else if (ttmp->ttyp == FIRE_TRAP) {
873 } else if ((ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT
874 || ttmp->ttyp == HOLE || ttmp->ttyp == TRAPDOOR)
876 /* Air currents overcome the recoil */
883 You("pass right over %s.",
884 an(defsyms[trap_to_defsym(ttmp->ttyp)].explanation));
886 You("%s
\82Ì
\90^
\8fã
\82ð
\92Ê
\89ß
\82µ
\82½
\81D",
887 defsyms[trap_to_defsym(ttmp->ttyp)].explanation);
891 if (--*range < 0) /* make sure our range never goes negative */
899 mhurtle_step(arg, x, y)
903 struct monst *mon = (struct monst *) arg;
905 /* TODO: Treat walls, doors, iron bars, pools, lava, etc. specially
906 * rather than just stopping before.
908 if (goodpos(x, y, mon, 0) && m_in_out_region(mon, x, y)) {
909 remove_monster(mon->mx, mon->my);
910 newsym(mon->mx, mon->my);
911 place_monster(mon, x, y);
912 newsym(mon->mx, mon->my);
921 * The player moves through the air for a few squares as a result of
922 * throwing or kicking something.
924 * dx and dy should be the direction of the hurtle, not of the original
925 * kick or throw and be only.
928 hurtle(dx, dy, range, verbose)
934 /* The chain is stretched vertically, so you shouldn't be able to move
935 * very far diagonally. The premise that you should be able to move one
936 * spot leads to calculations that allow you to only move one spot away
937 * from the ball, if you are levitating over the ball, or one spot
938 * towards the ball, if you are at the end of the chain. Rather than
939 * bother with all of that, assume that there is no slack in the chain
940 * for diagonal movement, give the player a message and return.
942 if (Punished && !carried(uball)) {
944 You_feel("a tug from the iron ball.");
946 You_feel("
\93S
\8b\85\82É
\82Ð
\82Á
\82Ï
\82ç
\82ê
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
949 } else if (u.utrap) {
951 You("are anchored by the %s.",
952 u.utraptype == TT_WEB
954 : u.utraptype == TT_LAVA
956 : u.utraptype == TT_INFLOOR
957 ? surface(u.ux, u.uy)
958 : u.utraptype == TT_BURIEDBALL ? "buried ball"
961 You("%s
\82É
\90\98\82¦
\82Â
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é
\81D",
962 u.utraptype == TT_WEB
963 ? "
\82
\82à
\82Ì
\91\83"
964 : u.utraptype == TT_LAVA
966 : u.utraptype == TT_INFLOOR
968 : u.utraptype == TT_BURIEDBALL ? "
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\8b\85"
975 /* make sure dx and dy are [-1,0,1] */
979 if (!range || (!dx && !dy) || u.ustuck)
980 return; /* paranoia */
984 multi_reason = "moving through the air";
986 multi_reason = "
\8bó
\92\86\82ð
\88Ú
\93®
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
987 nomovemsg = ""; /* it just happens */
990 You("%s in the opposite direction.", range > 1 ? "hurtle" : "float");
992 You("
\8bt
\95û
\8cü
\82É
\94ò
\82Î
\82³
\82ê
\82½
\81D");
993 /* if we're in the midst of shooting multiple projectiles, stop */
998 /* this setting of cc is only correct if dx and dy are [-1,0,1] only */
999 cc.x = u.ux + (dx * range);
1000 cc.y = u.uy + (dy * range);
1001 (void) walk_path(&uc, &cc, hurtle_step, (genericptr_t) &range);
1004 /* Move a monster through the air for a few squares. */
1006 mhurtle(mon, dx, dy, range)
1012 /* At the very least, debilitate the monster */
1016 /* Is the monster stuck or too heavy to push?
1017 * (very large monsters have too much inertia, even floaters and flyers)
1019 if (mon->data->msize >= MZ_HUGE || mon == u.ustuck || mon->mtrapped)
1022 /* Make sure dx and dy are [-1,0,1] */
1025 if (!range || (!dx && !dy))
1026 return; /* paranoia */
1027 /* don't let grid bugs be hurtled diagonally */
1028 if (dx && dy && NODIAG(monsndx(mon->data)))
1031 /* Send the monster along the path */
1034 cc.x = mon->mx + (dx * range);
1035 cc.y = mon->my + (dy * range);
1036 (void) walk_path(&mc, &cc, mhurtle_step, (genericptr_t) mon);
1041 check_shop_obj(obj, x, y, broken)
1046 struct monst *shkp = shop_keeper(*u.ushops);
1051 if (broken || !costly_spot(x, y)
1052 || *in_rooms(x, y, SHOPBASE) != *u.ushops) {
1053 /* thrown out of a shop or into a different shop */
1055 (void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful,
1060 if (costly_spot(u.ux, u.uy) && costly_spot(x, y)) {
1062 subfrombill(obj, shkp);
1063 else if (x != shkp->mx || y != shkp->my)
1070 * Hero tosses an object upwards with appropriate consequences.
1072 * Returns FALSE if the object is gone.
1075 toss_up(obj, hitsroof)
1080 boolean petrifier = ((obj->otyp == EGG || obj->otyp == CORPSE)
1081 && touch_petrifies(&mons[obj->corpsenm]));
1082 /* note: obj->quan == 1 */
1084 if (!has_ceiling(&u.uz)) {
1086 action = "flies up into"; /* into "the sky" or "the water above" */
1088 action = "
\82Ì
\92\86\82ð
\94ò
\82ñ
\82¾"; /* into "the sky" or "the water above" */
1090 } else if (hitsroof) {
1091 if (breaktest(obj)) {
1093 pline("%s hits the %s.", Doname2(obj), ceiling(u.ux, u.uy));
1095 pline("%s
\82Í%s
\82É
\96½
\92\86\82µ
\82½
\81D", Doname2(obj), ceiling(u.ux, u.uy));
1096 breakmsg(obj, !Blind);
1097 breakobj(obj, u.ux, u.uy, TRUE, TRUE);
1103 action = "
\82É
\96½
\92\86\82µ
\82½";
1106 action = "almost hits";
1108 action = "
\82É
\82à
\82¤
\8f
\82µ
\82Å
\96½
\92\86\82·
\82é
\82Æ
\82±
\82ë
\82¾
\82Á
\82½";
1111 pline("%s %s the %s, then falls back on top of your %s.", Doname2(obj),
1112 action, ceiling(u.ux, u.uy), body_part(HEAD));
1114 pline("%s
\82Í%s%s
\81C
\82»
\82µ
\82Ä%s
\82Ì
\8fã
\82É
\97\8e\82¿
\82Ä
\82«
\82½
\81D", Doname2(obj),
1115 ceiling(u.ux, u.uy), action, body_part(HEAD));
1118 /* object now hits you */
1120 if (obj->oclass == POTION_CLASS) {
1121 potionhit(&youmonst, obj, POTHIT_HERO_THROW);
1122 } else if (breaktest(obj)) {
1123 int otyp = obj->otyp;
1126 /* need to check for blindness result prior to destroying obj */
1127 blindinc = ((otyp == CREAM_PIE || otyp == BLINDING_VENOM)
1128 /* AT_WEAP is ok here even if attack type was AT_SPIT */
1129 && can_blnd(&youmonst, &youmonst, AT_WEAP, obj))
1132 breakmsg(obj, !Blind);
1133 breakobj(obj, u.ux, u.uy, TRUE, TRUE);
1134 obj = 0; /* it's now gone */
1137 if (petrifier && !Stone_resistance
1138 && !(poly_when_stoned(youmonst.data)
1139 && polymon(PM_STONE_GOLEM))) {
1140 /* egg ends up "all over your face"; perhaps
1141 visored helmet should still save you here */
1144 Your("%s fails to protect you.", helm_simple_name(uarmh));
1146 Your("%s
\82Í
\82 \82È
\82½
\82ð
\8eç
\82ê
\82È
\82©
\82Á
\82½
\81D", helm_simple_name(uarmh));
1151 case BLINDING_VENOM:
1153 pline("You've got it all over your %s!", body_part(FACE));
1155 pline("
\82»
\82ê
\82Í%s
\82ð
\82×
\82Á
\82Æ
\82è
\82Æ
\95¢
\82Á
\82½
\81I", body_part(FACE));
1157 if (otyp == BLINDING_VENOM && !Blind)
1159 pline("It blinds you!");
1161 pline("
\96Ú
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I");
1162 u.ucreamed += blindinc;
1163 make_blinded(Blinded + (long) blindinc, FALSE);
1165 Your1(vision_clears);
1172 } else { /* neither potion nor other breaking object */
1173 boolean less_damage = uarmh && is_metallic(uarmh), artimsg = FALSE;
1174 int dmg = dmgval(obj, &youmonst);
1177 /* need a fake die roll here; rn1(18,2) avoids 1 and 20 */
1178 artimsg = artifact_hit((struct monst *) 0, &youmonst, obj, &dmg,
1181 if (!dmg) { /* probably wasn't a weapon; base damage on weight */
1182 dmg = (int) obj->owt / 100;
1187 if (youmonst.data == &mons[PM_SHADE]
1188 && objects[obj->otyp].oc_material != SILVER)
1191 if (dmg > 1 && less_damage)
1196 dmg = 0; /* beware negative rings of increase damage */
1197 dmg = Maybe_Half_Phys(dmg);
1200 if (less_damage && dmg < (Upolyd ? u.mh : u.uhp)) {
1203 pline("Fortunately, you are wearing a hard helmet.");
1205 pline("
\8dK
\89^
\82É
\82à
\81C
\82 \82È
\82½
\82Í
\8cÅ
\82¢
\8a\95\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82½
\81D");
1206 /* helmet definitely protects you when it blocks petrification
1208 } else if (!petrifier) {
1211 Your("%s does not protect you.", helm_simple_name(uarmh));
1213 Your("%s
\82Å
\82Í
\96h
\82¬
\82«
\82ê
\82È
\82©
\82Á
\82½
\81D", helm_simple_name(uarmh));
1215 } else if (petrifier && !Stone_resistance
1216 && !(poly_when_stoned(youmonst.data)
1217 && polymon(PM_STONE_GOLEM))) {
1219 killer.format = KILLED_BY;
1221 Strcpy(killer.name, "elementary physics"); /* "what goes up..." */
1223 Strcpy(killer.name, "
\8f\89\93\99\95¨
\97\9d\82É
\82æ
\82è"); /* "what goes up..." */
1226 You("turn to stone.");
1228 You("
\90Î
\82É
\82È
\82Á
\82½
\81D");
1230 dropy(obj); /* bypass most of hitfloor() */
1231 thrownobj = 0; /* now either gone or on floor */
1233 return obj ? TRUE : FALSE;
1238 losehp(Maybe_Half_Phys(dmg), "falling object", KILLED_BY_AN);
1240 losehp(Maybe_Half_Phys(dmg), "
\97\8e\89º
\95¨
\82Å", KILLED_BY_AN);
1246 /* return true for weapon meant to be thrown; excludes ammo */
1248 throwing_weapon(obj)
1251 return (boolean) (is_missile(obj) || is_spear(obj)
1252 /* daggers and knife (excludes scalpel) */
1253 || (is_blade(obj) && !is_sword(obj)
1254 && (objects[obj->otyp].oc_dir & PIERCE))
1255 /* special cases [might want to add AXE] */
1256 || obj->otyp == WAR_HAMMER || obj->otyp == AKLYS);
1259 /* the currently thrown object is returning to you (not for boomerangs) */
1261 sho_obj_return_to_u(obj)
1264 /* might already be our location (bounced off a wall) */
1265 if ((u.dx || u.dy) && (bhitpos.x != u.ux || bhitpos.y != u.uy)) {
1266 int x = bhitpos.x - u.dx, y = bhitpos.y - u.dy;
1268 tmp_at(DISP_FLASH, obj_to_glyph(obj));
1269 while (isok(x,y) && (x != u.ux || y != u.uy)) {
1275 tmp_at(DISP_END, 0);
1279 /* throw an object, NB: obj may be consumed in the process */
1281 throwit(obj, wep_mask, twoweap)
1283 long wep_mask; /* used to re-equip returning boomerang */
1284 boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
1286 register struct monst *mon;
1287 register int range, urange;
1288 boolean crossbowing, impaired = (Confusion || Stunned || Blind
1289 || Hallucination || Fumbling);
1291 notonhead = FALSE; /* reset potentially stale value */
1292 if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) {
1293 boolean slipok = TRUE;
1295 if (ammo_and_launcher(obj, uwep))
1297 pline("%s!", Tobjnam(obj, "misfire"));
1299 pline("%s
\82Í
\82Í
\82¸
\82ê
\82½
\81I", xname(obj));
1301 /* only slip if it's greased or meant to be thrown */
1302 if (obj->greased || throwing_weapon(obj))
1303 /* BUG: this message is grammatically incorrect if obj has
1304 a plural name; greased gloves or boots for instance. */
1306 pline("%s as you throw it!", Tobjnam(obj, "slip"));
1308 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));
1321 if ((u.dx || u.dy || (u.dz < 1))
1322 && calc_capacity((int) obj->owt) > SLT_ENCUMBER
1323 && (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
1324 : (u.uhp < 10 && u.uhp != u.uhpmax))
1325 && obj->owt > (unsigned) ((Upolyd ? u.mh : u.uhp) * 2)
1326 && !Is_airlevel(&u.uz)) {
1328 You("have so little stamina, %s drops from your grasp.",
1330 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",
1332 exercise(A_CON, FALSE);
1338 thrownobj->was_thrown = 1;
1342 bhitpos.x = mon->mx;
1343 bhitpos.y = mon->my;
1346 /* Mjollnir must we wielded to be thrown--caller verifies this;
1347 aklys must we wielded as primary to return when thrown */
1348 && ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR)
1349 || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0))
1352 pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
1353 ceiling(u.ux, u.uy));
1355 pline("%s
\82Í%s
\82É
\96½
\92\86\82µ
\82 \82È
\82½
\82Ì
\8eè
\82É
\96ß
\82Á
\82Ä
\82«
\82½
\81I", xname(obj),
1356 ceiling(u.ux,u.uy));
1359 (void) encumber_msg();
1360 if (obj->owornmask & W_QUIVER) /* in case addinv() autoquivered */
1361 setuqwep((struct obj *) 0);
1363 u.twoweap = twoweap;
1364 } else if (u.dz < 0) {
1365 (void) toss_up(obj, rn2(5) && !Underwater);
1366 } else if (u.dz > 0 && u.usteed && obj->oclass == POTION_CLASS
1368 /* alternative to prayer or wand of opening/spell of knock
1369 for dealing with cursed saddle: throw holy water > */
1370 potionhit(u.usteed, obj, POTHIT_HERO_THROW);
1374 thrownobj = (struct obj *) 0;
1377 } else if (obj->otyp == BOOMERANG && !Underwater) {
1378 if (Is_airlevel(&u.uz) || Levitation)
1379 hurtle(-u.dx, -u.dy, 1, TRUE);
1380 mon = boomhit(obj, u.dx, u.dy);
1381 if (mon == &youmonst) { /* the thing was caught */
1382 exercise(A_DEX, TRUE);
1384 (void) encumber_msg();
1385 if (wep_mask && !(obj->owornmask & wep_mask)) {
1386 setworn(obj, wep_mask);
1387 u.twoweap = twoweap;
1389 thrownobj = (struct obj *) 0;
1393 /* crossbow range is independent of strength */
1395 (ammo_and_launcher(obj, uwep) && weapon_type(uwep) == P_CROSSBOW);
1396 urange = (crossbowing ? 18 : (int) ACURRSTR) / 2;
1397 /* balls are easy to throw or at least roll;
1398 * also, this insures the maximum range of a ball is greater
1399 * than 1, so the effects from throwing attached balls are
1402 if (obj->otyp == HEAVY_IRON_BALL)
1403 range = urange - (int) (obj->owt / 100);
1405 range = urange - (int) (obj->owt / 40);
1409 else if (range >= 5)
1416 if (ammo_and_launcher(obj, uwep)) {
1421 } else if (obj->oclass != GEM_CLASS)
1425 if (Is_airlevel(&u.uz) || Levitation) {
1426 /* action, reaction... */
1435 if (obj->otyp == BOULDER)
1436 range = 20; /* you must be giant */
1437 else if (obj->oartifact == ART_MJOLLNIR)
1438 range = (range + 1) / 2; /* it's heavy */
1439 else if (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)
1440 /* if an aklys is going to return, range is limited by the
1441 length of the attached cord [implicit aspect of item] */
1442 range = min(range, BOLT_LIM / 2);
1443 else if (obj == uball && u.utrap && u.utraptype == TT_INFLOOR)
1449 mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
1450 (int FDECL((*), (MONST_P, OBJ_P))) 0,
1451 (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
1452 thrownobj = obj; /* obj may be null now */
1454 /* have to do this after bhit() so u.ux & u.uy are correct */
1455 if (Is_airlevel(&u.uz) || Levitation)
1456 hurtle(-u.dx, -u.dy, urange, TRUE);
1465 if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) {
1466 thrownobj = (struct obj *) 0;
1467 return; /* alert shk caught it */
1469 (void) snuff_candle(obj);
1470 notonhead = (bhitpos.x != mon->mx || bhitpos.y != mon->my);
1471 obj_gone = thitmonst(mon, obj);
1472 /* Monster may have been tamed; this frees old mon */
1473 mon = m_at(bhitpos.x, bhitpos.y);
1475 /* [perhaps this should be moved into thitmonst or hmon] */
1476 if (mon && mon->isshk
1477 && (!inside_shop(u.ux, u.uy)
1478 || !index(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops)))
1486 ; /* missile has already been handled */
1487 } else if (u.uswallow) {
1488 /* ball is not picked up by monster */
1490 (void) mpickobj(u.ustuck, obj);
1491 thrownobj = (struct obj *) 0;
1493 /* Mjollnir must we wielded to be thrown--caller verifies this;
1494 aklys must we wielded as primary to return when thrown */
1495 if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE))
1496 || (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0)) {
1498 sho_obj_return_to_u(obj); /* display its flight */
1500 if (!impaired && rn2(100)) {
1502 pline("%s to your hand!", Tobjnam(obj, "return"));
1504 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8eè
\82É
\96ß
\82Á
\82Ä
\82«
\82½
\81I", xname(obj));
1506 (void) encumber_msg();
1507 /* addinv autoquivers an aklys if quiver is empty;
1508 if obj is quivered, remove it before wielding */
1509 if (obj->owornmask & W_QUIVER)
1510 setuqwep((struct obj *) 0);
1512 u.twoweap = twoweap;
1513 if (cansee(bhitpos.x, bhitpos.y))
1514 newsym(bhitpos.x, bhitpos.y);
1520 pline(Blind ? "%s lands %s your %s."
1521 : "%s back to you, landing %s your %s.",
1522 Blind ? Something : Tobjnam(obj, "return"),
1523 Levitation ? "beneath" : "at",
1524 makeplural(body_part(FOOT)));
1526 pline("%s
\82Í%s
\82 \82È
\82½
\82Ì%s
\82Ì%s
\82É
\97\8e\82¿
\82½
\81D",
1528 Blind ? "" : "
\96ß
\82Á
\82Ä
\82«
\82Ä
\81C",
1530 Levitation ? "
\89º" : "
\82»
\82Î");
1535 pline(Blind ? "%s your %s!"
1536 : "%s back toward you, hitting your %s!",
1537 Tobjnam(obj, Blind ? "hit" : "fly"),
1540 pline("%s
\82Í%s
\82 \82È
\82½
\82Ì%s
\82É
\96½
\92\86\82µ
\82½
\81I",
1542 Blind ? "" : "
\96ß
\82Á
\82Ä
\82«
\82Ä
\81C",
1546 (void) artifact_hit((struct monst *) 0, &youmonst,
1549 losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
1554 Sprintf(jbuf, "%s
\82Å", xname(obj));
1555 losehp(Maybe_Half_Phys(dmg), jbuf, KILLED_BY);
1559 if (ship_object(obj, u.ux, u.uy, FALSE)) {
1560 thrownobj = (struct obj *) 0;
1565 thrownobj = (struct obj *) 0;
1568 /* when this location is stepped on, the weapon will be
1569 auto-picked up due to 'obj->was_thrown' of 1;
1570 addinv() prevents thrown Mjollnir from being placed
1571 into the quiver slot, but an aklys will end up there if
1572 that slot is empty at the time; since hero will need to
1573 explicitly rewield the weapon to get throw-and-return
1574 capability back anyway, quivered or not shouldn't matter */
1576 pline("%s to return!", Tobjnam(obj, "fail"));
1578 pline("%s
\82Í
\96ß
\82é
\82Ì
\82É
\8e¸
\94s
\82µ
\82½
\81I", xname(obj));
1579 /* continue below with placing 'obj' at target location */
1583 if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj)) {
1584 tmp_at(DISP_FLASH, obj_to_glyph(obj));
1585 tmp_at(bhitpos.x, bhitpos.y);
1587 tmp_at(DISP_END, 0);
1588 breakmsg(obj, cansee(bhitpos.x, bhitpos.y));
1589 breakobj(obj, bhitpos.x, bhitpos.y, TRUE, TRUE);
1590 thrownobj = (struct obj *) 0;
1594 if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall")) {
1596 if (flooreffects(obj,bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é")) {
1597 thrownobj = (struct obj *) 0;
1600 obj_no_longer_held(obj);
1601 if (mon && mon->isshk && is_pick(obj)) {
1602 if (cansee(bhitpos.x, bhitpos.y))
1604 pline("%s snatches up %s.", Monnam(mon), the(xname(obj)));
1606 pline("%s
\82Í%s
\82ð
\92D
\82¢
\82Æ
\82Á
\82½
\81D", Monnam(mon), xname(obj));
1607 if (*u.ushops || obj->unpaid)
1608 check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1609 (void) mpickobj(mon, obj); /* may merge and free obj */
1610 thrownobj = (struct obj *) 0;
1613 (void) snuff_candle(obj);
1614 if (!mon && ship_object(obj, bhitpos.x, bhitpos.y, FALSE)) {
1615 thrownobj = (struct obj *) 0;
1618 thrownobj = (struct obj *) 0;
1619 place_object(obj, bhitpos.x, bhitpos.y);
1620 /* container contents might break;
1621 do so before turning ownership of thrownobj over to shk
1622 (container_impact_dmg handles item already owned by shop) */
1623 if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ))
1624 /* <x,y> is spot where you initiated throw, not bhitpos */
1625 container_impact_dmg(obj, u.ux, u.uy);
1626 /* charge for items thrown out of shop;
1627 shk takes possession for items thrown into one */
1628 if ((*u.ushops || obj->unpaid) && obj != uball)
1629 check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE);
1633 drop_ball(bhitpos.x, bhitpos.y);
1634 if (cansee(bhitpos.x, bhitpos.y))
1635 newsym(bhitpos.x, bhitpos.y);
1636 if (obj_sheds_light(obj))
1637 vision_full_recalc = 1;
1641 /* an object may hit a monster; various factors adjust the chance of hitting
1644 omon_adj(mon, obj, mon_notices)
1647 boolean mon_notices;
1651 /* size of target affects the chance of hitting */
1652 tmp += (mon->data->msize - MZ_MEDIUM); /* -2..+5 */
1653 /* sleeping target is more likely to be hit */
1654 if (mon->msleeping) {
1659 /* ditto for immobilized target */
1660 if (!mon->mcanmove || !mon->data->mmove) {
1662 if (mon_notices && mon->data->mmove && !rn2(10)) {
1667 /* some objects are more likely to hit than others */
1668 switch (obj->otyp) {
1669 case HEAVY_IRON_BALL:
1677 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1678 || obj->oclass == GEM_CLASS)
1679 tmp += hitval(obj, mon);
1685 /* thrown object misses target monster */
1687 tmiss(obj, mon, maybe_wakeup)
1690 boolean maybe_wakeup;
1692 const char *missile = mshot_xname(obj);
1694 /* If the target can't be seen or doesn't look like a valid target,
1695 avoid "the arrow misses it," or worse, "the arrows misses the mimic."
1696 An attentive player will still notice that this is different from
1697 an arrow just landing short of any target (no message in that case),
1698 so will realize that there is a valid target here anyway. */
1699 if (!canseemon(mon) || (mon->m_ap_type && mon->m_ap_type != M_AP_MONSTER))
1701 pline("%s %s.", The(missile), otense(obj, "miss"));
1703 pline("%s
\82Í
\82Í
\82¸
\82ê
\82½
\81D", missile);
1706 if (maybe_wakeup && !rn2(3))
1711 #define quest_arti_hits_leader(obj, mon) \
1712 (obj->oartifact && is_quest_artifact(obj) \
1713 && mon->m_id == quest_status.leader_m_id)
1716 * Object thrown by player arrives at monster's location.
1717 * Return 1 if obj has disappeared or otherwise been taken care of,
1718 * 0 if caller must take care of it.
1719 * Also used for kicked objects and for polearms/grapnel applied at range.
1723 register struct monst *mon;
1724 register struct obj *obj; /* thrownobj or kickedobj or uwep */
1726 register int tmp; /* Base chance to hit */
1727 register int disttmp; /* distance modifier */
1728 int otyp = obj->otyp, hmode;
1729 boolean guaranteed_hit = (u.uswallow && mon == u.ustuck);
1732 hmode = (obj == uwep) ? HMON_APPLIED
1733 : (obj == kickedobj) ? HMON_KICKED
1736 /* Differences from melee weapons:
1738 * Dex still gives a bonus, but strength does not.
1739 * Polymorphed players lacking attacks may still throw.
1740 * There's a base -1 to hit.
1741 * No bonuses for fleeing or stunned targets (they don't dodge
1742 * melee blows as readily, but dodging arrows is hard anyway).
1743 * Not affected by traps, etc.
1744 * Certain items which don't in themselves do damage ignore tmp.
1745 * Distance and monster size affect chance to hit.
1747 tmp = -1 + Luck + find_mac(mon) + u.uhitinc
1748 + maybe_polyd(youmonst.data->mlevel, u.ulevel);
1749 if (ACURR(A_DEX) < 4)
1751 else if (ACURR(A_DEX) < 6)
1753 else if (ACURR(A_DEX) < 8)
1755 else if (ACURR(A_DEX) >= 14)
1756 tmp += (ACURR(A_DEX) - 14);
1758 /* Modify to-hit depending on distance; but keep it sane.
1759 * Polearms get a distance penalty even when wielded; it's
1760 * hard to hit at a distance.
1762 disttmp = 3 - distmin(u.ux, u.uy, mon->mx, mon->my);
1767 /* gloves are a hindrance to proper use of bows */
1768 if (uarmg && uwep && objects[uwep->otyp].oc_skill == P_BOW) {
1769 switch (uarmg->otyp) {
1770 case GAUNTLETS_OF_POWER: /* metal */
1773 case GAUNTLETS_OF_FUMBLING:
1776 case LEATHER_GLOVES:
1777 case GAUNTLETS_OF_DEXTERITY:
1780 impossible("Unknown type of gloves (%d)", uarmg->otyp);
1785 tmp += omon_adj(mon, obj, TRUE);
1786 if (is_orc(mon->data)
1787 && maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
1789 if (guaranteed_hit) {
1790 tmp += 1000; /* Guaranteed hit */
1793 if (obj->oclass == GEM_CLASS && is_unicorn(mon->data)) {
1794 if (mon->msleeping || !mon->mcanmove) {
1795 tmiss(obj, mon, FALSE);
1797 } else if (mon->mtame) {
1799 pline("%s catches and drops %s.", Monnam(mon), the(xname(obj)));
1801 pline("%s
\82Í%s
\82ð
\82
\82í
\82¦
\82Ä
\92u
\82¢
\82½
\81D", Monnam(mon), xname(obj));
1805 pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1807 pline("%s
\82Í%s
\82ð
\82
\82í
\82¦
\82½
\81D", Monnam(mon), xname(obj));
1808 return gem_accept(mon, obj);
1812 /* don't make game unwinnable if naive player throws artifact
1813 at leader... (kicked artifact is ok too; HMON_APPLIED could
1814 occur if quest artifact polearm or grapnel ever gets added) */
1815 if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) {
1816 /* AIS: changes to wakeup() means that it's now less inappropriate here
1817 than it used to be, but the manual version works just as well */
1819 mon->mstrategy &= ~STRAT_WAITMASK;
1821 if (mon->mcanmove) {
1823 pline("%s catches %s.", Monnam(mon), the(xname(obj)));
1825 pline("%s
\82Í%s
\82ð
\92Í
\82ñ
\82¾
\81D", Monnam(mon), xname(obj));
1826 if (mon->mpeaceful) {
1827 boolean next2u = monnear(mon, u.ux, u.uy);
1829 finish_quest(obj); /* acknowledge quest completion */
1831 pline("%s %s %s back to you.", Monnam(mon),
1832 (next2u ? "hands" : "tosses"), the(xname(obj)));
1834 pline("%s
\82Í%s
\82ð
\82 \82È
\82½
\82É
\95Ô
\82µ
\82½
\81D", Monnam(mon),
1838 sho_obj_return_to_u(obj);
1839 obj = addinv(obj); /* back into your inventory */
1840 (void) encumber_msg();
1842 /* angry leader caught it and isn't returning it */
1843 if (*u.ushops || obj->unpaid) /* not very likely... */
1844 check_shop_obj(obj, mon->mx, mon->my, FALSE);
1845 (void) mpickobj(mon, obj);
1847 return 1; /* caller doesn't need to place it */
1854 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
1855 || obj->oclass == GEM_CLASS) {
1856 if (hmode == HMON_KICKED) {
1857 /* throwing adjustments and weapon skill bonus don't apply */
1858 tmp -= (is_ammo(obj) ? 5 : 3);
1859 } else if (is_ammo(obj)) {
1860 if (!ammo_and_launcher(obj, uwep)) {
1863 tmp += uwep->spe - greatest_erosion(uwep);
1864 tmp += weapon_hit_bonus(uwep);
1865 if (uwep->oartifact)
1866 tmp += spec_abon(uwep, mon);
1868 * Elves and Samurais are highly trained w/bows,
1869 * especially their own special types of bow.
1870 * Polymorphing won't make you a bow expert.
1872 if ((Race_if(PM_ELF) || Role_if(PM_SAMURAI))
1873 && (!Upolyd || your_race(youmonst.data))
1874 && objects[uwep->otyp].oc_skill == P_BOW) {
1876 if (Race_if(PM_ELF) && uwep->otyp == ELVEN_BOW)
1878 else if (Role_if(PM_SAMURAI) && uwep->otyp == YUMI)
1882 } else { /* thrown non-ammo or applied polearm/grapnel */
1883 if (otyp == BOOMERANG) /* arbitrary */
1885 else if (throwing_weapon(obj)) /* meant to be thrown */
1887 else if (obj == thrownobj) /* not meant to be thrown */
1889 /* we know we're dealing with a weapon or weptool handled
1890 by WEAPON_SKILLS once ammo objects have been excluded */
1891 tmp += weapon_hit_bonus(obj);
1894 if (tmp >= dieroll) {
1895 boolean wasthrown = (thrownobj != 0);
1897 /* attack hits mon */
1898 if (hmode == HMON_APPLIED)
1899 u.uconduct.weaphit++;
1900 if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */
1901 cutworm(mon, bhitpos.x, bhitpos.y, obj);
1903 exercise(A_DEX, TRUE);
1904 /* if hero was swallowed and projectile killed the engulfer,
1905 'obj' got added to engulfer's inventory and then dropped,
1906 so we can't safely use that pointer anymore; it escapes
1907 the chance to be used up here... */
1908 if (wasthrown && !thrownobj)
1911 /* projectiles other than magic stones
1912 sometimes disappear when thrown */
1913 if (objects[otyp].oc_skill < P_NONE
1914 && objects[otyp].oc_skill > -P_BOOMERANG
1915 && !objects[otyp].oc_magic) {
1916 /* we were breaking 2/3 of everything unconditionally.
1917 * we still don't want anything to survive unconditionally,
1918 * but we need ammo to stay around longer on average.
1922 chance = 3 + greatest_erosion(obj) - obj->spe;
1924 broken = rn2(chance);
1927 if (obj->blessed && !rnl(4))
1931 if (*u.ushops || obj->unpaid)
1932 check_shop_obj(obj, bhitpos.x, bhitpos.y, TRUE);
1933 obfree(obj, (struct obj *) 0);
1937 passive_obj(mon, obj, (struct attack *) 0);
1939 tmiss(obj, mon, TRUE);
1940 if (hmode == HMON_APPLIED)
1944 } else if (otyp == HEAVY_IRON_BALL) {
1945 exercise(A_STR, TRUE);
1946 if (tmp >= dieroll) {
1947 int was_swallowed = guaranteed_hit;
1949 exercise(A_DEX, TRUE);
1950 if (!hmon(mon, obj, hmode, dieroll)) { /* mon killed */
1951 if (was_swallowed && !u.uswallow && obj == uball)
1952 return 1; /* already did placebc() */
1955 tmiss(obj, mon, TRUE);
1958 } else if (otyp == BOULDER) {
1959 exercise(A_STR, TRUE);
1960 if (tmp >= dieroll) {
1961 exercise(A_DEX, TRUE);
1962 (void) hmon(mon, obj, hmode, dieroll);
1964 tmiss(obj, mon, TRUE);
1967 } else if ((otyp == EGG || otyp == CREAM_PIE || otyp == BLINDING_VENOM
1968 || otyp == ACID_VENOM)
1969 && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
1970 (void) hmon(mon, obj, hmode, dieroll);
1971 return 1; /* hmon used it up */
1973 } else if (obj->oclass == POTION_CLASS
1974 && (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
1975 potionhit(mon, obj, POTHIT_HERO_THROW);
1978 } else if (befriend_with_obj(mon->data, obj)
1979 || (mon->mtame && dogfood(mon, obj) <= ACCFOOD)) {
1980 if (tamedog(mon, obj)) {
1981 return 1; /* obj is gone */
1983 tmiss(obj, mon, FALSE);
1985 mon->mstrategy &= ~STRAT_WAITMASK;
1987 } else if (guaranteed_hit) {
1988 /* this assumes that guaranteed_hit is due to swallowing */
1990 if (obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])) {
1991 if (is_animal(u.ustuck->data)) {
1992 minstapetrify(u.ustuck, TRUE);
1993 /* Don't leave a cockatrice corpse available in a statue */
2001 pline("%s into %s %s.", Tobjnam(obj, "vanish"),
2002 s_suffix(mon_nam(mon)),
2003 is_animal(u.ustuck->data) ? "entrails" : "currents");
2005 pline("%s
\82Í%s
\82Ì%s
\82Ö
\8fÁ
\82¦
\82½
\81D", xname(obj),
2007 is_animal(u.ustuck->data) ? "
\93à
\91\9f\82Ì
\92\86" : "
\97¬
\82ê");
2010 tmiss(obj, mon, TRUE);
2017 gem_accept(mon, obj)
2018 register struct monst *mon;
2019 register struct obj *obj;
2022 boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type);
2023 boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE;
2026 static NEARDATA const char nogood[] = " is not interested in your junk.";
2028 static NEARDATA const char nogood[] = "
\82 \82È
\82½
\82Ì
\83K
\83\89\83N
\83^
\82É
\8b»
\96¡
\82ð
\8e¦
\82³
\82È
\82¢
\81D";
2030 static NEARDATA const char acceptgift[] = " accepts your gift.";
2032 static NEARDATA const char acceptgift[] = "
\82 \82È
\82½
\82Ì
\91¡
\82è
\95¨
\82ð
\8eó
\82¯
\82Æ
\82Á
\82½
\81D";
2034 static NEARDATA const char maybeluck[] = " hesitatingly";
2036 static NEARDATA const char maybeluck[] = "
\82½
\82ß
\82ç
\82¢
\82È
\82ª
\82ç";
2038 static NEARDATA const char noluck[] = " graciously";
2040 static NEARDATA const char noluck[] = "
\92\9a\8fd
\82É";
2042 static NEARDATA const char addluck[] = " gratefully";
2044 static NEARDATA const char addluck[] = "
\8aì
\82ñ
\82Å";
2046 Strcpy(buf, Monnam(mon));
2048 Strcat(buf, "
\82Í");
2053 /* object properly identified */
2054 if (obj->dknown && objects[obj->otyp].oc_name_known) {
2057 Strcat(buf, addluck);
2060 Strcat(buf, maybeluck);
2061 change_luck(rn2(7) - 3);
2064 Strcat(buf, nogood);
2067 /* making guesses */
2068 } else if (has_oname(obj) || objects[obj->otyp].oc_uname) {
2071 Strcat(buf, addluck);
2074 Strcat(buf, maybeluck);
2075 change_luck(rn2(3) - 1);
2078 Strcat(buf, nogood);
2081 /* value completely unknown to @ */
2085 Strcat(buf, addluck);
2088 Strcat(buf, maybeluck);
2089 change_luck(rn2(3) - 1);
2092 Strcat(buf, noluck);
2095 Strcat(buf, acceptgift);
2096 if (*u.ushops || obj->unpaid)
2097 check_shop_obj(obj, mon->mx, mon->my, TRUE);
2098 (void) mpickobj(mon, obj); /* may merge and free obj */
2104 if (!tele_restrict(mon))
2105 (void) rloc(mon, TRUE);
2110 * Comments about the restructuring of the old breaks() routine.
2112 * There are now three distinct phases to object breaking:
2113 * breaktest() - which makes the check/decision about whether the
2114 * object is going to break.
2115 * breakmsg() - which outputs a message about the breakage,
2116 * appropriate for that particular object. Should
2117 * only be called after a positive breaktest().
2118 * on the object and, if it going to be called,
2119 * it must be called before calling breakobj().
2120 * Calling breakmsg() is optional.
2121 * breakobj() - which actually does the breakage and the side-effects
2122 * of breaking that particular object. This should
2123 * only be called after a positive breaktest() on the
2126 * Each of the above routines is currently static to this source module.
2127 * There are two routines callable from outside this source module which
2128 * perform the routines above in the correct sequence.
2130 * hero_breaks() - called when an object is to be broken as a result
2131 * of something that the hero has done. (throwing it,
2133 * breaks() - called when an object is to be broken for some
2134 * reason other than the hero doing something to it.
2138 * The hero causes breakage of an object (throwing, dropping it, etc.)
2139 * Return 0 if the object didn't break, 1 if the object broke.
2142 hero_breaks(obj, x, y, from_invent)
2144 xchar x, y; /* object location (ox, oy may not be right) */
2145 boolean from_invent; /* thrown or dropped by player; maybe on shop bill */
2147 boolean in_view = Blind ? FALSE : (from_invent || cansee(x, y));
2148 if (!breaktest(obj))
2150 breakmsg(obj, in_view);
2151 breakobj(obj, x, y, TRUE, from_invent);
2156 * The object is going to break for a reason other than the hero doing
2158 * Return 0 if the object doesn't break, 1 if the object broke.
2163 xchar x, y; /* object location (ox, oy may not be right) */
2165 boolean in_view = Blind ? FALSE : cansee(x, y);
2167 if (!breaktest(obj))
2169 breakmsg(obj, in_view);
2170 breakobj(obj, x, y, FALSE, FALSE);
2175 release_camera_demon(obj, x, y)
2181 && (mtmp = makemon(&mons[rn2(3) ? PM_HOMUNCULUS : PM_IMP], x, y,
2182 NO_MM_FLAGS)) != 0) {
2183 if (canspotmon(mtmp))
2185 pline("%s is released!", Hallucination
2186 ? An(rndmonnam(NULL))
2187 : "The picture-painting demon");
2189 pline("%s
\82ª
\89ð
\95ú
\82³
\82ê
\82½
\81I", Hallucination
2191 : "
\82¨
\8aG
\95`
\82«
\82Ì
\88«
\96\82");
2193 mtmp->mpeaceful = !obj->cursed;
2199 * Unconditionally break an object. Assumes all resistance checks
2200 * and break messages have been delivered prior to getting here.
2203 breakobj(obj, x, y, hero_caused, from_invent)
2205 xchar x, y; /* object location (ox, oy may not be right) */
2206 boolean hero_caused; /* is this the hero's fault? */
2207 boolean from_invent;
2209 boolean fracture = FALSE;
2211 switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2216 case POT_WATER: /* really, all potions */
2217 obj->in_use = 1; /* in case it's fatal */
2218 if (obj->otyp == POT_OIL && obj->lamplit) {
2219 explode_oil(obj, x, y);
2220 } else if (distu(x, y) <= 2) {
2221 if (!breathless(youmonst.data) || haseyes(youmonst.data)) {
2222 if (obj->otyp != POT_WATER) {
2223 if (!breathless(youmonst.data)) {
2224 /* [what about "familiar odor" when known?] */
2226 You("smell a peculiar odor...");
2228 You("
\96ò
\82Á
\82Û
\82¢
\93õ
\82¢
\82ª
\82µ
\82½
\81D
\81D
\81D");
2231 const char *eyes = body_part(EYE);
2233 if (eyecount(youmonst.data) != 1)
2234 eyes = makeplural(eyes);
2235 Your("%s %s.", eyes, vtense(eyes, "water"));
2237 You("
\97Ü%s
\82É
\82È
\82Á
\82½
\81D", body_part(EYE));
2244 /* monster breathing isn't handled... [yet?] */
2246 case EXPENSIVE_CAMERA:
2247 release_camera_demon(obj, x, y);
2250 /* breaking your own eggs is bad luck */
2251 if (hero_caused && obj->spe && obj->corpsenm >= LOW_PM)
2252 change_luck((schar) -min(obj->quan, 5L));
2256 /* caller will handle object disposition;
2257 we're just doing the shop theft handling */
2265 if (from_invent || obj->unpaid) {
2266 if (*u.ushops || obj->unpaid)
2267 check_shop_obj(obj, x, y, TRUE);
2268 } else if (!obj->no_charge && costly_spot(x, y)) {
2269 /* it is assumed that the obj is a floor-object */
2270 char *o_shop = in_rooms(x, y, SHOPBASE);
2271 struct monst *shkp = shop_keeper(*o_shop);
2273 if (shkp) { /* (implies *o_shop != '\0') */
2274 static NEARDATA long lastmovetime = 0L;
2275 static NEARDATA boolean peaceful_shk = FALSE;
2276 /* We want to base shk actions on her peacefulness
2277 at start of this turn, so that "simultaneous"
2278 multiple breakage isn't drastically worse than
2279 single breakage. (ought to be done via ESHK) */
2280 if (moves != lastmovetime)
2281 peaceful_shk = shkp->mpeaceful;
2282 if (stolen_value(obj, x, y, peaceful_shk, FALSE) > 0L
2283 && (*o_shop != u.ushops[0] || !inside_shop(u.ux, u.uy))
2284 && moves != lastmovetime)
2285 make_angry_shk(shkp, x, y);
2286 lastmovetime = moves;
2295 * Check to see if obj is going to break, but don't actually break it.
2296 * Return 0 if the object isn't going to break, 1 if it is.
2302 if (obj_resists(obj, 1, 99))
2304 if (objects[obj->otyp].oc_material == GLASS && !obj->oartifact
2305 && obj->oclass != GEM_CLASS)
2307 switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2308 case EXPENSIVE_CAMERA:
2309 case POT_WATER: /* really, all potions */
2314 case BLINDING_VENOM:
2322 breakmsg(obj, in_view)
2326 const char *to_pieces;
2331 /* "shatter"
\81¨ "
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½"
2332 "shatter into a thousand pieces"
\81¨ "
\82
\82¾
\82¯
\82Ä
\82Î
\82ç
\82Î
\82ç
\82É
\82È
\82Á
\82½" */
2333 to_pieces = "
\82±
\82È
\82²
\82È";
2335 switch (obj->oclass == POTION_CLASS ? POT_WATER : obj->otyp) {
2336 default: /* glass or crystal wand */
2337 if (obj->oclass != WAND_CLASS)
2338 impossible("breaking odd object?");
2340 case CRYSTAL_PLATE_MAIL:
2344 case EXPENSIVE_CAMERA:
2346 to_pieces = " into a thousand pieces";
2348 to_pieces = "
\82
\82¾
\82¯
\82Ä
\82Î
\82ç
\82Î
\82ç";
2350 case POT_WATER: /* really, all potions */
2353 You_hear("%s shatter!", something);
2355 You_hear("%s
\82ª
\89ó
\82ê
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81I", something);
2358 pline("%s shatter%s%s!", Doname2(obj),
2359 (obj->quan == 1L) ? "s" : "", to_pieces);
2361 pline("%s
\82Í%s
\82É
\82È
\82Á
\82½
\81I", Doname2(obj), to_pieces);
2369 pline("
\83r
\83`
\83\83\81I");
2374 pline("What a mess!");
2376 pline("
\82±
\82è
\82á
\82Ð
\82Ç
\82¢
\81I");
2379 case BLINDING_VENOM:
2383 pline("
\83r
\83`
\83\83\81I");
2392 int range, odx, ody;
2393 register struct monst *mon;
2395 if (!u.dx && !u.dy && !u.dz) {
2397 You("cannot throw gold at yourself.");
2399 pline("
\8e©
\95ª
\82É
\8bà
\89Ý
\82ð
\93\8a\82°
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D");
2405 pline(is_animal(u.ustuck->data) ? "%s in the %s's entrails."
2407 "The money disappears", mon_nam(u.ustuck));
2409 pline(is_animal(u.ustuck->data) ? "
\8bà
\89Ý
\82Í%s
\82Ì
\95 \82Ì
\92\86\82Ö
\8fÁ
\82¦
\82Ä
\82¢
\82Á
\82½
\81D"
2410 : "
\8bà
\89Ý
\82Í%s
\82Ì
\92\86\82Ö
\8fÁ
\82¦
\82Ä
\82¢
\82Á
\82½
\81D",
2413 add_to_minv(u.ustuck, obj);
2418 if (u.dz < 0 && !Is_airlevel(&u.uz) && !Underwater
2419 && !Is_waterlevel(&u.uz)) {
2421 pline_The("gold hits the %s, then falls back on top of your %s.",
2422 ceiling(u.ux, u.uy), body_part(HEAD));
2424 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",
2425 ceiling(u.ux,u.uy), body_part(HEAD));
2427 /* some self damage? */
2430 pline("Fortunately, you are wearing %s!",
2432 pline("
\8dK
\89^
\82È
\82±
\82Æ
\82É
\81C
\82 \82È
\82½
\82Í%s
\82ð
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\81I",
2433 an(helm_simple_name(uarmh)));
2438 /* consistent with range for normal objects */
2439 range = (int) ((ACURRSTR) / 2 - obj->owt / 40);
2441 /* see if the gold has a place to move into */
2444 if (!ZAP_POS(levl[odx][ody].typ) || closed_door(odx, ody)) {
2448 mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,
2449 (int FDECL((*), (MONST_P, OBJ_P))) 0,
2450 (int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
2452 return 1; /* object is gone */
2454 if (ghitm(mon, obj)) /* was it caught? */
2457 if (ship_object(obj, bhitpos.x, bhitpos.y, FALSE))
2464 if (flooreffects(obj, bhitpos.x, bhitpos.y, "fall"))
2466 if (flooreffects(obj, bhitpos.x, bhitpos.y, "
\97\8e\82¿
\82é"))
2470 pline_The("gold hits the %s.", surface(bhitpos.x, bhitpos.y));
2472 pline("
\8bà
\89Ý
\82Í%s
\82É
\96½
\92\86\82µ
\82½
\81D", surface(bhitpos.x, bhitpos.y));
2473 place_object(obj, bhitpos.x, bhitpos.y);
2475 sellobj(obj, bhitpos.x, bhitpos.y);
2477 newsym(bhitpos.x, bhitpos.y);