OSDN Git Service

update year to 2020
[jnethack/source.git] / src / zap.c
1 /* NetHack 3.6  zap.c   $NHDT-Date: 1573688696 2019/11/13 23:44:56 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.316 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 /* Disintegration rays have special treatment; corpses are never left.
14  * But the routine which calculates the damage is separate from the routine
15  * which kills the monster.  The damage routine returns this cookie to
16  * indicate that the monster should be disintegrated.
17  */
18 #define MAGIC_COOKIE 1000
19
20 static NEARDATA boolean obj_zapped;
21 static NEARDATA int poly_zapped;
22
23 extern boolean notonhead; /* for long worms */
24
25 /* kludge to use mondied instead of killed */
26 extern boolean m_using;
27
28 STATIC_DCL void FDECL(polyuse, (struct obj *, int, int));
29 STATIC_DCL void FDECL(create_polymon, (struct obj *, int));
30 STATIC_DCL int FDECL(stone_to_flesh_obj, (struct obj *));
31 STATIC_DCL boolean FDECL(zap_updown, (struct obj *));
32 STATIC_DCL void FDECL(zhitu, (int, int, const char *, XCHAR_P, XCHAR_P));
33 STATIC_DCL void FDECL(revive_egg, (struct obj *));
34 STATIC_DCL boolean FDECL(zap_steed, (struct obj *));
35 STATIC_DCL void FDECL(skiprange, (int, int *, int *));
36 STATIC_DCL int FDECL(zap_hit, (int, int));
37 STATIC_OVL void FDECL(disintegrate_mon, (struct monst *, int, const char *));
38 STATIC_DCL void FDECL(backfire, (struct obj *));
39 STATIC_DCL int FDECL(spell_hit_bonus, (int));
40 STATIC_DCL void FDECL(destroy_one_item, (struct obj *, int, int));
41 STATIC_DCL void FDECL(wishcmdassist, (int));
42
43 #define ZT_MAGIC_MISSILE (AD_MAGM - 1)
44 #define ZT_FIRE (AD_FIRE - 1)
45 #define ZT_COLD (AD_COLD - 1)
46 #define ZT_SLEEP (AD_SLEE - 1)
47 #define ZT_DEATH (AD_DISN - 1) /* or disintegration */
48 #define ZT_LIGHTNING (AD_ELEC - 1)
49 #define ZT_POISON_GAS (AD_DRST - 1)
50 #define ZT_ACID (AD_ACID - 1)
51 /* 8 and 9 are currently unassigned */
52
53 #define ZT_WAND(x) (x)
54 #define ZT_SPELL(x) (10 + (x))
55 #define ZT_BREATH(x) (20 + (x))
56
57 #define is_hero_spell(type) ((type) >= 10 && (type) < 20)
58
59 #define M_IN_WATER(ptr) \
60     ((ptr)->mlet == S_EEL || amphibious(ptr) || is_swimmer(ptr))
61
62 STATIC_VAR const char are_blinded_by_the_flash[] =
63 /*JP
64     "are blinded by the flash!";
65 */
66     "\82Ü\82Î\82ä\82¢\8cõ\82Å\96Ú\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81I";
67
68 const char *const flash_types[] =       /* also used in buzzmu(mcastu.c) */
69     {
70 #if 0 /*JP:T*/
71         "magic missile", /* Wands must be 0-9 */
72         "bolt of fire", "bolt of cold", "sleep ray", "death ray",
73         "bolt of lightning", "", "", "", "",
74 #else
75         "\96\82\96@\82Ì\96î", /* Wands must be 0-9 */
76         "\89Î\82Ì\91M\8cõ",
77         "\95X\82Ì\91M\8cõ",
78         "\96°\82è\8cõ\90ü",
79         "\8e\80\82Ì\8cõ\90ü",
80         "\88î\8dÈ\82Ì\91M\8cõ",
81         "",
82         "",
83         "",
84         "",
85 #endif
86
87 #if 0 /*JP:T*/
88         "magic missile", /* Spell equivalents must be 10-19 */
89         "fireball", "cone of cold", "sleep ray", "finger of death",
90         "bolt of lightning", /* there is no spell, used for retribution */
91         "", "", "", "",
92 #else
93         "\96\82\96@\82Ì\96î", /* Spell equivalents must be 10-19 */
94         "\89Î\82Ì\8bÊ",
95         "\97â\8bC",
96         "\96°\82è\8cõ\90ü",
97         "\8e\80\82Ì\8ew",
98         "\88î\8dÈ\82Ì\91M\8cõ", /* There is no spell, used for retribution */
99         "",
100         "",
101         "",
102         "",
103 #endif
104
105 #if 0 /*JP:T*/
106         "blast of missiles", /* Dragon breath equivalents 20-29*/
107         "blast of fire", "blast of frost", "blast of sleep gas",
108         "blast of disintegration", "blast of lightning",
109         "blast of poison gas", "blast of acid", "", ""
110 #else
111         "\96\82\96@\82Ì\96î\82Ì\91§", /* Dragon breath equivalents 20-29*/
112         "\89Î\82Ì\91§",
113         "\95X\82Ì\91§",
114         "\90\87\96°\83K\83X\82Ì\91§",
115         "\95ª\89ð\82Ì\91§",
116         "\88î\8dÈ\82Ì\91§",
117         "\93Å\83K\83X\82Ì\91§",
118         "\8e_\82Ì\91§",
119         "",
120         ""
121 #endif
122     };
123
124 /*
125  * Recognizing unseen wands by zapping:  in 3.4.3 and earlier, zapping
126  * most wand types while blind would add that type to the discoveries
127  * list even if it had never been seen (ie, picked up while blinded
128  * and shown in inventory as simply "a wand").  This behavior has been
129  * changed; now such wands won't be discovered.  But if the type is
130  * already discovered, then the individual wand whose effect was just
131  * observed will be flagged as if seen.  [You already know wands of
132  * striking; you zap "a wand" and observe striking effect (presumably
133  * by sound or touch); it'll become shown in inventory as "a wand of
134  * striking".]
135  *
136  * Unfortunately, the new behavior isn't really correct either.  There
137  * should be an `eknown' bit for "effect known" added for wands (and
138  * for potions since quaffing one of a stack is similar) so that the
139  * particular wand which has been zapped would have its type become
140  * known (it would change from "a wand" to "a wand of striking", for
141  * example) without the type becoming discovered or other unknown wands
142  * of that type showing additional information.  When blindness ends,
143  * all objects in inventory with the eknown bit set would be discovered
144  * and other items of the same type would become known as such.
145  */
146
147 /* wand discovery gets special handling when hero is blinded */
148 void
149 learnwand(obj)
150 struct obj *obj;
151 {
152     /* For a wand (or wand-like tool) zapped by the player, if the
153        effect was observable (determined by caller; usually seen, but
154        possibly heard or felt if the hero is blinded) then discover the
155        object type provided that the object itself is known (as more
156        than just "a wand").  If object type is already discovered and
157        we observed the effect, mark the individual wand as having been
158        seen.  Suppress spells (which use fake spellbook object for `obj')
159        so that casting a spell won't re-discover its forgotten book. */
160     if (obj->oclass != SPBOOK_CLASS) {
161         /* if type already discovered, treat this item has having been seen
162            even if hero is currently blinded (skips redundant makeknown) */
163         if (objects[obj->otyp].oc_name_known) {
164             obj->dknown = 1; /* will usually be set already */
165
166         /* otherwise discover it if item itself has been or can be seen */
167         } else {
168             /* in case it was picked up while blind and then zapped without
169                examining inventory after regaining sight (bypassing xname) */
170             if (!Blind)
171                 obj->dknown = 1;
172             /* make the discovery iff we know what we're manipulating */
173             if (obj->dknown)
174                 makeknown(obj->otyp);
175         }
176         update_inventory();
177     }
178 }
179
180 /* Routines for IMMEDIATE wands and spells. */
181 /* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
182 int
183 bhitm(mtmp, otmp)
184 struct monst *mtmp;
185 struct obj *otmp;
186 {
187     boolean wake = TRUE; /* Most 'zaps' should wake monster */
188     boolean reveal_invis = FALSE, learn_it = FALSE;
189     boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart;
190     boolean skilled_spell, helpful_gesture = FALSE;
191     int dmg, otyp = otmp->otyp;
192 /*JP
193     const char *zap_type_text = "spell";
194 */
195     const char *zap_type_text = "\96\82\96@";
196     struct obj *obj;
197     boolean disguised_mimic = (mtmp->data->mlet == S_MIMIC
198                                && M_AP_TYPE(mtmp) != M_AP_NOTHING);
199
200     if (u.uswallow && mtmp == u.ustuck)
201         reveal_invis = FALSE;
202
203     notonhead = (mtmp->mx != bhitpos.x || mtmp->my != bhitpos.y);
204     skilled_spell = (otmp && otmp->oclass == SPBOOK_CLASS && otmp->blessed);
205
206     switch (otyp) {
207     case WAN_STRIKING:
208 /*JP
209         zap_type_text = "wand";
210 */
211         zap_type_text = "\8fñ";
212     /*FALLTHRU*/
213     case SPE_FORCE_BOLT:
214         reveal_invis = TRUE;
215         if (disguised_mimic)
216             seemimic(mtmp);
217         if (resists_magm(mtmp)) { /* match effect on player */
218             shieldeff(mtmp->mx, mtmp->my);
219 /*JP
220             pline("Boing!");
221 */
222             pline("\83{\83C\83\93\81I");
223             break; /* skip makeknown */
224         } else if (u.uswallow || rnd(20) < 10 + find_mac(mtmp)) {
225             dmg = d(2, 12);
226             if (dbldam)
227                 dmg *= 2;
228             if (otyp == SPE_FORCE_BOLT)
229                 dmg = spell_damage_bonus(dmg);
230             hit(zap_type_text, mtmp, exclam(dmg));
231             (void) resist(mtmp, otmp->oclass, dmg, TELL);
232         } else
233             miss(zap_type_text, mtmp);
234         learn_it = TRUE;
235         break;
236     case WAN_SLOW_MONSTER:
237     case SPE_SLOW_MONSTER:
238         if (!resist(mtmp, otmp->oclass, 0, NOTELL)) {
239             if (disguised_mimic)
240                 seemimic(mtmp);
241             mon_adjust_speed(mtmp, -1, otmp);
242             m_dowear(mtmp, FALSE); /* might want speed boots */
243             if (u.uswallow && (mtmp == u.ustuck) && is_whirly(mtmp->data)) {
244 /*JP
245                 You("disrupt %s!", mon_nam(mtmp));
246 */
247                 You("%s\82ð\83o\83\89\83o\83\89\82É\82µ\82½\81I", mon_nam(mtmp));
248 /*JP
249                 pline("A huge hole opens up...");
250 */
251                 pline("\92E\8fo\82Å\82«\82»\82¤\82È\8c\8a\82ª\8aJ\82¢\82½\81D\81D\81D");
252                 expels(mtmp, mtmp->data, TRUE);
253             }
254         }
255         break;
256     case WAN_SPEED_MONSTER:
257         if (!resist(mtmp, otmp->oclass, 0, NOTELL)) {
258             if (disguised_mimic)
259                 seemimic(mtmp);
260             mon_adjust_speed(mtmp, 1, otmp);
261             m_dowear(mtmp, FALSE); /* might want speed boots */
262         }
263         if (mtmp->mtame)
264             helpful_gesture = TRUE;
265         break;
266     case WAN_UNDEAD_TURNING:
267     case SPE_TURN_UNDEAD:
268         wake = FALSE;
269         if (unturn_dead(mtmp))
270             wake = TRUE;
271         if (is_undead(mtmp->data) || is_vampshifter(mtmp)) {
272             reveal_invis = TRUE;
273             wake = TRUE;
274             dmg = rnd(8);
275             if (dbldam)
276                 dmg *= 2;
277             if (otyp == SPE_TURN_UNDEAD)
278                 dmg = spell_damage_bonus(dmg);
279             context.bypasses = TRUE; /* for make_corpse() */
280             if (!resist(mtmp, otmp->oclass, dmg, NOTELL)) {
281                 if (!DEADMONSTER(mtmp))
282                     monflee(mtmp, 0, FALSE, TRUE);
283             }
284         }
285         break;
286     case WAN_POLYMORPH:
287     case SPE_POLYMORPH:
288     case POT_POLYMORPH:
289         if (mtmp->data == &mons[PM_LONG_WORM] && has_mcorpsenm(mtmp)) {
290             /* if a long worm has mcorpsenm set, it was polymophed by
291                the current zap and shouldn't be affected if hit again */
292             ;
293         } else if (resists_magm(mtmp)) {
294             /* magic resistance protects from polymorph traps, so make
295                it guard against involuntary polymorph attacks too... */
296             shieldeff(mtmp->mx, mtmp->my);
297         } else if (!resist(mtmp, otmp->oclass, 0, NOTELL)) {
298             boolean polyspot = (otyp != POT_POLYMORPH),
299                     give_msg = (!Hallucination
300                                 && (canseemon(mtmp)
301                                     || (u.uswallow && mtmp == u.ustuck)));
302
303             /* dropped inventory (due to death by system shock,
304                or loss of wielded weapon and/or worn armor due to
305                limitations of new shape) won't be hit by this zap */
306             if (polyspot)
307                 for (obj = mtmp->minvent; obj; obj = obj->nobj)
308                     bypass_obj(obj);
309
310             /* natural shapechangers aren't affected by system shock
311                (unless protection from shapechangers is interfering
312                with their metabolism...) */
313             if (mtmp->cham == NON_PM && !rn2(25)) {
314                 if (canseemon(mtmp)) {
315 /*JP
316                     pline("%s shudders!", Monnam(mtmp));
317 */
318                     pline("%s\82Í\90g\90k\82¢\82µ\82½\81I", Monnam(mtmp));
319                     learn_it = TRUE;
320                 }
321                 /* context.bypasses = TRUE; ## for make_corpse() */
322                 /* no corpse after system shock */
323                 xkilled(mtmp, XKILL_GIVEMSG | XKILL_NOCORPSE);
324             } else if (newcham(mtmp, (struct permonst *) 0,
325                                polyspot, give_msg) != 0
326                        /* if shapechange failed because there aren't
327                           enough eligible candidates (most likely for
328                           vampshifter), try reverting to original form */
329                        || (mtmp->cham >= LOW_PM
330                            && newcham(mtmp, &mons[mtmp->cham],
331                                       polyspot, give_msg) != 0)) {
332                 if (give_msg && (canspotmon(mtmp)
333                                  || (u.uswallow && mtmp == u.ustuck)))
334                     learn_it = TRUE;
335             }
336
337             /* do this even if polymorphed failed (otherwise using
338                flags.mon_polycontrol prompting to force mtmp to remain
339                'long worm' would prompt again if zap hit another segment) */
340             if (!DEADMONSTER(mtmp) && mtmp->data == &mons[PM_LONG_WORM]) {
341                 if (!has_mcorpsenm(mtmp))
342                     newmcorpsenm(mtmp);
343                 /* flag to indicate that mtmp became a long worm
344                    on current zap, so further hits (on mtmp's new
345                    tail) don't do further transforms */
346                 MCORPSENM(mtmp) = PM_LONG_WORM;
347                 /* flag to indicate that cleanup is needed; object
348                    bypass cleanup also clears mon->mextra->mcorpsenm
349                    for all long worms on the level */
350                 context.bypasses = TRUE;
351             }
352         }
353         break;
354     case WAN_CANCELLATION:
355     case SPE_CANCELLATION:
356         if (disguised_mimic)
357             seemimic(mtmp);
358         (void) cancel_monst(mtmp, otmp, TRUE, TRUE, FALSE);
359         break;
360     case WAN_TELEPORTATION:
361     case SPE_TELEPORT_AWAY:
362         if (disguised_mimic)
363             seemimic(mtmp);
364         reveal_invis = !u_teleport_mon(mtmp, TRUE);
365         break;
366     case WAN_MAKE_INVISIBLE: {
367         int oldinvis = mtmp->minvis;
368         char nambuf[BUFSZ];
369
370         if (disguised_mimic)
371             seemimic(mtmp);
372         /* format monster's name before altering its visibility */
373         Strcpy(nambuf, Monnam(mtmp));
374         mon_set_minvis(mtmp);
375         if (!oldinvis && knowninvisible(mtmp)) {
376 /*JP
377             pline("%s turns transparent!", nambuf);
378 */
379             pline("%s\82Í\93§\96¾\82É\82È\82Á\82½\81I", nambuf);
380             reveal_invis = TRUE;
381             learn_it = TRUE;
382         }
383         break;
384     }
385     case WAN_LOCKING:
386     case SPE_WIZARD_LOCK:
387         wake = closeholdingtrap(mtmp, &learn_it);
388         break;
389     case WAN_PROBING:
390         wake = FALSE;
391         reveal_invis = TRUE;
392         probe_monster(mtmp);
393         learn_it = TRUE;
394         break;
395     case WAN_OPENING:
396     case SPE_KNOCK:
397         wake = FALSE; /* don't want immediate counterattack */
398         if (u.uswallow && mtmp == u.ustuck) {
399             if (is_animal(mtmp->data)) {
400                 if (Blind)
401 /*JP
402                     You_feel("a sudden rush of air!");
403 */
404                     You("\93Ë\91R\8c\83\82µ\82¢\8bó\8bC\82Ì\97¬\82ê\82ð\8a´\82\82½\81I");
405                 else
406 /*JP
407                     pline("%s opens its mouth!", Monnam(mtmp));
408 */
409                     pline("%s\82Í\8cû\82ð\8aJ\82¢\82½\81I", Monnam(mtmp));
410             }
411             expels(mtmp, mtmp->data, TRUE);
412             /* zap which hits steed will only release saddle if it
413                doesn't hit a holding or falling trap; playability
414                here overrides the more logical target ordering */
415         } else if (openholdingtrap(mtmp, &learn_it)) {
416             break;
417         } else if (openfallingtrap(mtmp, TRUE, &learn_it)) {
418             /* mtmp might now be on the migrating monsters list */
419             break;
420         } else if ((obj = which_armor(mtmp, W_SADDLE)) != 0) {
421             char buf[BUFSZ];
422
423 #if 0 /*JP:T*/
424             Sprintf(buf, "%s %s", s_suffix(Monnam(mtmp)),
425                     distant_name(obj, xname));
426 #else
427             Sprintf(buf, "%s\82Ì%s", Monnam(mtmp),
428                     distant_name(obj, xname));
429 #endif
430             if (cansee(mtmp->mx, mtmp->my)) {
431                 if (!canspotmon(mtmp))
432                     Strcpy(buf, An(distant_name(obj, xname)));
433 #if 0 /*JP:T*/
434                 pline("%s falls to the %s.", buf,
435                       surface(mtmp->mx, mtmp->my));
436 #else
437                 pline("%s\82Í%s\82É\97\8e\82¿\82½\81D", buf,
438                       surface(mtmp->mx, mtmp->my));
439 #endif
440             } else if (canspotmon(mtmp)) {
441 /*JP
442                 pline("%s falls off.", buf);
443 */
444                 pline("%s\82ª\97\8e\82¿\82½\81D", buf);
445             }
446             obj_extract_self(obj);
447             mdrop_obj(mtmp, obj, FALSE);
448         }
449         break;
450     case SPE_HEALING:
451     case SPE_EXTRA_HEALING:
452         reveal_invis = TRUE;
453         if (mtmp->data != &mons[PM_PESTILENCE]) {
454             wake = FALSE; /* wakeup() makes the target angry */
455             mtmp->mhp += d(6, otyp == SPE_EXTRA_HEALING ? 8 : 4);
456             if (mtmp->mhp > mtmp->mhpmax)
457                 mtmp->mhp = mtmp->mhpmax;
458             /* plain healing must be blessed to cure blindness; extra
459                healing only needs to not be cursed, so spell always cures
460                [potions quaffed by monsters behave slightly differently;
461                we use the rules for the hero here...] */
462             if (skilled_spell || otyp == SPE_EXTRA_HEALING)
463                 mcureblindness(mtmp, canseemon(mtmp));
464             if (canseemon(mtmp)) {
465                 if (disguised_mimic) {
466                     if (is_obj_mappear(mtmp,STRANGE_OBJECT)) {
467                         /* it can do better now */
468                         set_mimic_sym(mtmp);
469                         newsym(mtmp->mx, mtmp->my);
470                     } else
471                         mimic_hit_msg(mtmp, otyp);
472                 } else
473 #if 0 /*JP:T*/
474                     pline("%s looks%s better.", Monnam(mtmp),
475                           otyp == SPE_EXTRA_HEALING ? " much" : "");
476 #else
477                     pline("%s\82Í%s\8c³\8bC\82É\82È\82Á\82½\82æ\82¤\82¾\81D", Monnam(mtmp),
478                           otyp == SPE_EXTRA_HEALING ? "\82Æ\82Ä\82à" : "" );
479 #endif
480             }
481             if (mtmp->mtame || mtmp->mpeaceful) {
482                 adjalign(Role_if(PM_HEALER) ? 1 : sgn(u.ualign.type));
483             }
484         } else { /* Pestilence */
485             /* Pestilence will always resist; damage is half of 3d{4,8} */
486             (void) resist(mtmp, otmp->oclass,
487                           d(3, otyp == SPE_EXTRA_HEALING ? 8 : 4), TELL);
488         }
489         break;
490     case WAN_LIGHT: /* (broken wand) */
491         if (flash_hits_mon(mtmp, otmp)) {
492             learn_it = TRUE;
493             reveal_invis = TRUE;
494         }
495         break;
496     case WAN_SLEEP: /* (broken wand) */
497         /* [wakeup() doesn't rouse victims of temporary sleep,
498            so it's okay to leave `wake' set to TRUE here] */
499         reveal_invis = TRUE;
500         if (sleep_monst(mtmp, d(1 + otmp->spe, 12), WAND_CLASS))
501             slept_monst(mtmp);
502         if (!Blind)
503             learn_it = TRUE;
504         break;
505     case SPE_STONE_TO_FLESH:
506         if (monsndx(mtmp->data) == PM_STONE_GOLEM) {
507             char *name = Monnam(mtmp);
508
509             /* turn into flesh golem */
510             if (newcham(mtmp, &mons[PM_FLESH_GOLEM], FALSE, FALSE)) {
511                 if (canseemon(mtmp))
512 /*JP
513                     pline("%s turns to flesh!", name);
514 */
515                     pline("%s\82Ì\90Î\89»\82ª\89ð\82¯\82½\81I", name);
516             } else {
517                 if (canseemon(mtmp))
518 /*JP
519                     pline("%s looks rather fleshy for a moment.", name);
520 */
521                     pline("%s\82Í\88ê\8fu\90Î\89»\82ª\89ð\82¯\82½\81D", name);
522             }
523         } else
524             wake = FALSE;
525         break;
526     case SPE_DRAIN_LIFE:
527         if (disguised_mimic)
528             seemimic(mtmp);
529         dmg = monhp_per_lvl(mtmp);
530         if (dbldam)
531             dmg *= 2;
532         if (otyp == SPE_DRAIN_LIFE)
533             dmg = spell_damage_bonus(dmg);
534         if (resists_drli(mtmp)) {
535             shieldeff(mtmp->mx, mtmp->my);
536         } else if (!resist(mtmp, otmp->oclass, dmg, NOTELL)
537                    && !DEADMONSTER(mtmp)) {
538             mtmp->mhp -= dmg;
539             mtmp->mhpmax -= dmg;
540             /* die if already level 0, regardless of hit points */
541             if (DEADMONSTER(mtmp) || mtmp->mhpmax <= 0 || mtmp->m_lev < 1) {
542                 killed(mtmp);
543             } else {
544                 mtmp->m_lev--;
545                 if (canseemon(mtmp))
546 /*JP
547                     pline("%s suddenly seems weaker!", Monnam(mtmp));
548 */
549                     pline("%s\82Í\82Æ\82Â\82º\82ñ\8eã\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I", Monnam(mtmp));
550             }
551         }
552         break;
553     case WAN_NOTHING:
554         wake = FALSE;
555         break;
556     default:
557         impossible("What an interesting effect (%d)", otyp);
558         break;
559     }
560     if (wake) {
561         if (!DEADMONSTER(mtmp)) {
562             wakeup(mtmp, helpful_gesture ? FALSE : TRUE);
563             m_respond(mtmp);
564             if (mtmp->isshk && !*u.ushops)
565                 hot_pursuit(mtmp);
566         } else if (M_AP_TYPE(mtmp))
567             seemimic(mtmp); /* might unblock if mimicing a boulder/door */
568     }
569     /* note: bhitpos won't be set if swallowed, but that's okay since
570      * reveal_invis will be false.  We can't use mtmp->mx, my since it
571      * might be an invisible worm hit on the tail.
572      */
573     if (reveal_invis) {
574         if (!DEADMONSTER(mtmp) && cansee(bhitpos.x, bhitpos.y)
575             && !canspotmon(mtmp))
576             map_invisible(bhitpos.x, bhitpos.y);
577     }
578     /* if effect was observable then discover the wand type provided
579        that the wand itself has been seen */
580     if (learn_it)
581         learnwand(otmp);
582     return 0;
583 }
584
585 void
586 probe_monster(mtmp)
587 struct monst *mtmp;
588 {
589     struct obj *otmp;
590
591     mstatusline(mtmp);
592     if (notonhead)
593         return; /* don't show minvent for long worm tail */
594
595     if (mtmp->minvent) {
596         for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
597             otmp->dknown = 1; /* treat as "seen" */
598             if (Is_container(otmp) || otmp->otyp == STATUE) {
599                 otmp->lknown = 1;
600                 if (!SchroedingersBox(otmp))
601                     otmp->cknown = 1;
602             }
603         }
604         (void) display_minventory(mtmp, MINV_ALL | MINV_NOLET | PICK_NONE,
605                                   (char *) 0);
606     } else {
607 #if 0 /*JP:T*/
608         pline("%s is not carrying anything%s.", noit_Monnam(mtmp),
609               (u.uswallow && mtmp == u.ustuck) ? " besides you" : "");
610 #else
611         pline("%s\82Í%s\89½\82à\8e\9d\82Á\82Ä\82¢\82È\82¢\81D", noit_Monnam(mtmp),
612               (u.uswallow && mtmp == u.ustuck) ? "\82 \82È\82½\88È\8aO\82É" : "");
613 #endif
614     }
615 }
616
617 /*
618  * Return the object's physical location.  This only makes sense for
619  * objects that are currently on the level (i.e. migrating objects
620  * are nowhere).  By default, only things that can be seen (in hero's
621  * inventory, monster's inventory, or on the ground) are reported.
622  * By adding BURIED_TOO and/or CONTAINED_TOO flags, you can also get
623  * the location of buried and contained objects.  Note that if an
624  * object is carried by a monster, its reported position may change
625  * from turn to turn.  This function returns FALSE if the position
626  * is not available or subject to the constraints above.
627  */
628 boolean
629 get_obj_location(obj, xp, yp, locflags)
630 struct obj *obj;
631 xchar *xp, *yp;
632 int locflags;
633 {
634     switch (obj->where) {
635     case OBJ_INVENT:
636         *xp = u.ux;
637         *yp = u.uy;
638         return TRUE;
639     case OBJ_FLOOR:
640         *xp = obj->ox;
641         *yp = obj->oy;
642         return TRUE;
643     case OBJ_MINVENT:
644         if (obj->ocarry->mx) {
645             *xp = obj->ocarry->mx;
646             *yp = obj->ocarry->my;
647             return TRUE;
648         }
649         break; /* !mx => migrating monster */
650     case OBJ_BURIED:
651         if (locflags & BURIED_TOO) {
652             *xp = obj->ox;
653             *yp = obj->oy;
654             return TRUE;
655         }
656         break;
657     case OBJ_CONTAINED:
658         if (locflags & CONTAINED_TOO)
659             return get_obj_location(obj->ocontainer, xp, yp, locflags);
660         break;
661     }
662     *xp = *yp = 0;
663     return FALSE;
664 }
665
666 boolean
667 get_mon_location(mon, xp, yp, locflags)
668 struct monst *mon;
669 xchar *xp, *yp;
670 int locflags; /* non-zero means get location even if monster is buried */
671 {
672     if (mon == &youmonst) {
673         *xp = u.ux;
674         *yp = u.uy;
675         return TRUE;
676     } else if (mon->mx > 0 && (!mon->mburied || locflags)) {
677         *xp = mon->mx;
678         *yp = mon->my;
679         return TRUE;
680     } else { /* migrating or buried */
681         *xp = *yp = 0;
682         return FALSE;
683     }
684 }
685
686 /* used by revive() and animate_statue() */
687 struct monst *
688 montraits(obj, cc, adjacentok)
689 struct obj *obj;
690 coord *cc;
691 boolean adjacentok; /* False: at obj's spot only, True: nearby is allowed */
692 {
693     struct monst *mtmp, *mtmp2 = has_omonst(obj) ? get_mtraits(obj, TRUE) : 0;
694
695     if (mtmp2) {
696         /* save_mtraits() validated mtmp2->mnum */
697         mtmp2->data = &mons[mtmp2->mnum];
698         if (mtmp2->mhpmax <= 0 && !is_rider(mtmp2->data))
699             return (struct monst *) 0;
700         mtmp = makemon(mtmp2->data, cc->x, cc->y,
701                        (NO_MINVENT | MM_NOWAIT | MM_NOCOUNTBIRTH
702                         | (adjacentok ? MM_ADJACENTOK : 0)));
703         if (!mtmp) {
704             /* mtmp2 is a copy of obj's object->oextra->omonst extension
705                and is not on the map or on any monst lists */
706             dealloc_monst(mtmp2);
707             return (struct monst *) 0;
708         }
709
710         /* heal the monster */
711         if (mtmp->mhpmax > mtmp2->mhpmax && is_rider(mtmp2->data))
712             mtmp2->mhpmax = mtmp->mhpmax;
713         mtmp2->mhp = mtmp2->mhpmax;
714         /* Get these ones from mtmp */
715         mtmp2->minvent = mtmp->minvent; /*redundant*/
716         /* monster ID is available if the monster died in the current
717            game, but will be zero if the corpse was in a bones level
718            (we cleared it when loading bones) */
719         if (mtmp->m_id) {
720             mtmp2->m_id = mtmp->m_id;
721             /* might be bringing quest leader back to life */
722             if (quest_status.leader_is_dead
723                 /* leader_is_dead implies leader_m_id is valid */
724                 && mtmp2->m_id == quest_status.leader_m_id)
725                 quest_status.leader_is_dead = FALSE;
726         }
727         mtmp2->mx = mtmp->mx;
728         mtmp2->my = mtmp->my;
729         mtmp2->mux = mtmp->mux;
730         mtmp2->muy = mtmp->muy;
731         mtmp2->mw = mtmp->mw;
732         mtmp2->wormno = mtmp->wormno;
733         mtmp2->misc_worn_check = mtmp->misc_worn_check;
734         mtmp2->weapon_check = mtmp->weapon_check;
735         mtmp2->mtrapseen = mtmp->mtrapseen;
736         mtmp2->mflee = mtmp->mflee;
737         mtmp2->mburied = mtmp->mburied;
738         mtmp2->mundetected = mtmp->mundetected;
739         mtmp2->mfleetim = mtmp->mfleetim;
740         mtmp2->mlstmv = mtmp->mlstmv;
741         mtmp2->m_ap_type = mtmp->m_ap_type;
742         /* set these ones explicitly */
743         mtmp2->mrevived = 1;
744         mtmp2->mavenge = 0;
745         mtmp2->meating = 0;
746         mtmp2->mleashed = 0;
747         mtmp2->mtrapped = 0;
748         mtmp2->msleeping = 0;
749         mtmp2->mfrozen = 0;
750         mtmp2->mcanmove = 1;
751         /* most cancelled monsters return to normal,
752            but some need to stay cancelled */
753         if (!dmgtype(mtmp2->data, AD_SEDU)
754             && (!SYSOPT_SEDUCE || !dmgtype(mtmp2->data, AD_SSEX)))
755             mtmp2->mcan = 0;
756         mtmp2->mcansee = 1; /* set like in makemon */
757         mtmp2->mblinded = 0;
758         mtmp2->mstun = 0;
759         mtmp2->mconf = 0;
760         /* when traits are for a shopeekper, dummy monster 'mtmp' won't
761            have necessary eshk data for replmon() -> replshk() */
762         if (mtmp2->isshk) {
763             neweshk(mtmp);
764             *ESHK(mtmp) = *ESHK(mtmp2);
765             if (ESHK(mtmp2)->bill_p != 0
766                 && ESHK(mtmp2)->bill_p != (struct bill_x *) -1000)
767                 ESHK(mtmp)->bill_p = &(ESHK(mtmp)->bill[0]);
768             mtmp->isshk = 1;
769         }
770         replmon(mtmp, mtmp2);
771         newsym(mtmp2->mx, mtmp2->my); /* Might now be invisible */
772
773         /* in case Protection_from_shape_changers is different
774            now than it was when the traits were stored */
775         restore_cham(mtmp2);
776     }
777     return mtmp2;
778 }
779
780 /*
781  * get_container_location() returns the following information
782  * about the outermost container:
783  * loc argument gets set to:
784  *      OBJ_INVENT      if in hero's inventory; return 0.
785  *      OBJ_FLOOR       if on the floor; return 0.
786  *      OBJ_BURIED      if buried; return 0.
787  *      OBJ_MINVENT     if in monster's inventory; return monster.
788  * container_nesting is updated with the nesting depth of the containers
789  * if applicable.
790  */
791 struct monst *
792 get_container_location(obj, loc, container_nesting)
793 struct obj *obj;
794 int *loc;
795 int *container_nesting;
796 {
797     if (!obj || !loc)
798         return 0;
799
800     if (container_nesting)
801         *container_nesting = 0;
802     while (obj && obj->where == OBJ_CONTAINED) {
803         if (container_nesting)
804             *container_nesting += 1;
805         obj = obj->ocontainer;
806     }
807     if (obj) {
808         *loc = obj->where; /* outermost container's location */
809         if (obj->where == OBJ_MINVENT)
810             return obj->ocarry;
811     }
812     return (struct monst *) 0;
813 }
814
815 /*
816  * Attempt to revive the given corpse, return the revived monster if
817  * successful.  Note: this does NOT use up the corpse if it fails.
818  * If corpse->quan is more than 1, only one corpse will be affected
819  * and only one monster will be resurrected.
820  */
821 struct monst *
822 revive(corpse, by_hero)
823 struct obj *corpse;
824 boolean by_hero;
825 {
826     struct monst *mtmp = 0;
827     struct permonst *mptr;
828     struct obj *container;
829     coord xy;
830     xchar x, y;
831     boolean one_of;
832     int montype, container_nesting = 0;
833
834     if (corpse->otyp != CORPSE) {
835         impossible("Attempting to revive %s?", xname(corpse));
836         return (struct monst *) 0;
837     }
838
839     x = y = 0;
840     if (corpse->where != OBJ_CONTAINED) {
841         /* only for invent, minvent, or floor */
842         container = 0;
843         (void) get_obj_location(corpse, &x, &y, 0);
844     } else {
845         /* deal with corpses in [possibly nested] containers */
846         struct monst *carrier;
847         int holder = OBJ_FREE;
848
849         container = corpse->ocontainer;
850         carrier =
851             get_container_location(container, &holder, &container_nesting);
852         switch (holder) {
853         case OBJ_MINVENT:
854             x = carrier->mx, y = carrier->my;
855             break;
856         case OBJ_INVENT:
857             x = u.ux, y = u.uy;
858             break;
859         case OBJ_FLOOR:
860             (void) get_obj_location(corpse, &x, &y, CONTAINED_TOO);
861             break;
862         default:
863             break; /* x,y are 0 */
864         }
865     }
866     if (!x || !y
867         /* Rules for revival from containers:
868          *  - the container cannot be locked
869          *  - the container cannot be heavily nested (>2 is arbitrary)
870          *  - the container cannot be a statue or bag of holding
871          *    (except in very rare cases for the latter)
872          */
873         || (container && (container->olocked || container_nesting > 2
874                           || container->otyp == STATUE
875                           || (container->otyp == BAG_OF_HOLDING && rn2(40)))))
876         return (struct monst *) 0;
877
878     /* record the object's location now that we're sure where it is */
879     corpse->ox = x, corpse->oy = y;
880
881     /* prepare for the monster */
882     montype = corpse->corpsenm;
883     mptr = &mons[montype];
884     /* [should probably handle recorporealization first; if corpse and
885        ghost are at same location, revived creature shouldn't be bumped
886        to an adjacent spot by ghost which joins with it] */
887     if (MON_AT(x, y)) {
888         if (enexto(&xy, x, y, mptr))
889             x = xy.x, y = xy.y;
890     }
891
892     if ((mons[montype].mlet == S_EEL && !IS_POOL(levl[x][y].typ))
893         || (mons[montype].mlet == S_TROLL
894             && uwep && uwep->oartifact == ART_TROLLSBANE)) {
895         if (by_hero && cansee(x, y))
896 /*JP
897             pline("%s twitches feebly.",
898 */
899             pline("%s\82Í\82í\82¸\82©\82Éáz\9d¹\82µ\82½\81D",
900                 upstart(corpse_xname(corpse, (const char *) 0, CXN_PFX_THE)));
901         return (struct monst *) 0;
902     }
903
904     if (cant_revive(&montype, TRUE, corpse)) {
905         /* make a zombie or doppelganger instead */
906         /* note: montype has changed; mptr keeps old value for newcham() */
907         mtmp = makemon(&mons[montype], x, y, NO_MINVENT | MM_NOWAIT);
908         if (mtmp) {
909             /* skip ghost handling */
910             if (has_omid(corpse))
911                 free_omid(corpse);
912             if (has_omonst(corpse))
913                 free_omonst(corpse);
914             if (mtmp->cham == PM_DOPPELGANGER) {
915                 /* change shape to match the corpse */
916                 (void) newcham(mtmp, mptr, FALSE, FALSE);
917             } else if (mtmp->data->mlet == S_ZOMBIE) {
918                 mtmp->mhp = mtmp->mhpmax = 100;
919                 mon_adjust_speed(mtmp, 2, (struct obj *) 0); /* MFAST */
920             }
921         }
922     } else if (has_omonst(corpse)) {
923         /* use saved traits */
924         xy.x = x, xy.y = y;
925         mtmp = montraits(corpse, &xy, FALSE);
926         if (mtmp && mtmp->mtame && !mtmp->isminion)
927             wary_dog(mtmp, TRUE);
928     } else {
929         /* make a new monster */
930         mtmp = makemon(mptr, x, y, NO_MINVENT | MM_NOWAIT | MM_NOCOUNTBIRTH);
931     }
932     if (!mtmp)
933         return (struct monst *) 0;
934
935     /* hiders shouldn't already be re-hidden when they revive */
936     if (mtmp->mundetected) {
937         mtmp->mundetected = 0;
938         newsym(mtmp->mx, mtmp->my);
939     }
940     if (M_AP_TYPE(mtmp))
941         seemimic(mtmp);
942
943     one_of = (corpse->quan > 1L);
944     if (one_of)
945         corpse = splitobj(corpse, 1L);
946
947     /* if this is caused by the hero there might be a shop charge */
948     if (by_hero) {
949         struct monst *shkp = 0;
950
951         x = corpse->ox, y = corpse->oy;
952         if (costly_spot(x, y)
953             && (carried(corpse) ? corpse->unpaid : !corpse->no_charge))
954             shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
955
956         if (cansee(x, y)) {
957             char buf[BUFSZ];
958
959 #if 1 /*JP*//* \8e\80\91Ì\96¼\82Í\90æ\82É; Strcpy\82É\82È\82é */
960             Strcpy(buf, corpse_xname(corpse, (const char *) 0, CXN_NO_PFX));
961 #endif
962 #if 0 /*JP*/
963             Strcpy(buf, one_of ? "one of " : "");
964 #else /* \8cê\8f\87\82Í\95Ï\82í\82Á\82Ä\82¢\82é */
965             if (one_of) {
966                 Strcat(buf, "\82Ì\88ê\82Â");
967             }
968 #endif
969 #if 0 /*JP*//* \82±\82±\82Å\81u\82 \82È\82½\82Ì\81v\82Í\95s\8e©\91R */
970             /* shk_your: "the " or "your " or "<mon>'s " or "<Shk>'s ".
971                If the result is "Shk's " then it will be ambiguous:
972                is Shk the mon carrying it, or does Shk's shop own it?
973                Let's not worry about that... */
974             (void) shk_your(eos(buf), corpse);
975 #endif
976             if (one_of)
977                 corpse->quan++; /* force plural */
978 #if 0 /*JP*//* \8aù\82É\90Ý\92è\8dÏ\82Ý */
979             Strcat(buf, corpse_xname(corpse, (const char *) 0, CXN_NO_PFX));
980 #endif
981             if (one_of) /* could be simplified to ''corpse->quan = 1L;'' */
982                 corpse->quan--;
983 /*JP
984             pline("%s glows iridescently.", upstart(buf));
985 */
986             pline("%s\82Í\93ø\90F\82É\8bP\82¢\82½\81D", upstart(buf));
987         } else if (shkp) {
988             /* need some prior description of the corpse since
989                stolen_value() will refer to the object as "it" */
990 /*JP
991             pline("A corpse is resuscitated.");
992 */
993             pline("\8e\80\91Ì\82ª\91h\90\82µ\82½\81D");
994         }
995         /* don't charge for shopkeeper's own corpse if we just revived him */
996         if (shkp && mtmp != shkp)
997             (void) stolen_value(corpse, x, y, (boolean) shkp->mpeaceful,
998                                 FALSE);
999
1000         /* [we don't give any comparable message about the corpse for
1001            the !by_hero case because caller might have already done so] */
1002     }
1003
1004     /* handle recorporealization of an active ghost */
1005     if (has_omid(corpse)) {
1006         unsigned m_id;
1007         struct monst *ghost;
1008         struct obj *otmp;
1009
1010         (void) memcpy((genericptr_t) &m_id, (genericptr_t) OMID(corpse),
1011                       sizeof m_id);
1012         ghost = find_mid(m_id, FM_FMON);
1013         if (ghost && ghost->data == &mons[PM_GHOST]) {
1014             if (canseemon(ghost))
1015 #if 0 /*JP:T*/
1016                 pline("%s is suddenly drawn into its former body!",
1017 #else
1018                 pline("%s\82Í\93Ë\91R\82à\82Æ\82Ì\91Ì\82É\88ø\82«\8d\9e\82Ü\82ê\82½\81I",
1019 #endif
1020                       Monnam(ghost));
1021             /* transfer the ghost's inventory along with it */
1022             while ((otmp = ghost->minvent) != 0) {
1023                 obj_extract_self(otmp);
1024                 add_to_minv(mtmp, otmp);
1025             }
1026             /* tame the revived monster if its ghost was tame */
1027             if (ghost->mtame && !mtmp->mtame) {
1028                 if (tamedog(mtmp, (struct obj *) 0)) {
1029                     /* ghost's edog data is ignored */
1030                     mtmp->mtame = ghost->mtame;
1031                 }
1032             }
1033             /* was ghost, now alive, it's all very confusing */
1034             mtmp->mconf = 1;
1035             /* separate ghost monster no longer exists */
1036             mongone(ghost);
1037         }
1038         free_omid(corpse);
1039     }
1040
1041     /* monster retains its name */
1042     if (has_oname(corpse) && !unique_corpstat(mtmp->data))
1043         mtmp = christen_monst(mtmp, ONAME(corpse));
1044     /* partially eaten corpse yields wounded monster */
1045     if (corpse->oeaten)
1046         mtmp->mhp = eaten_stat(mtmp->mhp, corpse);
1047     /* track that this monster was revived at least once */
1048     mtmp->mrevived = 1;
1049
1050     /* finally, get rid of the corpse--it's gone now */
1051     switch (corpse->where) {
1052     case OBJ_INVENT:
1053         useup(corpse);
1054         break;
1055     case OBJ_FLOOR:
1056         /* in case MON_AT+enexto for invisible mon */
1057         x = corpse->ox, y = corpse->oy;
1058         /* not useupf(), which charges */
1059         if (corpse->quan > 1L)
1060             corpse = splitobj(corpse, 1L);
1061         delobj(corpse);
1062         newsym(x, y);
1063         break;
1064     case OBJ_MINVENT:
1065         m_useup(corpse->ocarry, corpse);
1066         break;
1067     case OBJ_CONTAINED:
1068         obj_extract_self(corpse);
1069         obfree(corpse, (struct obj *) 0);
1070         break;
1071     default:
1072         panic("revive");
1073     }
1074
1075     return mtmp;
1076 }
1077
1078 STATIC_OVL void
1079 revive_egg(obj)
1080 struct obj *obj;
1081 {
1082     /*
1083      * Note: generic eggs with corpsenm set to NON_PM will never hatch.
1084      */
1085     if (obj->otyp != EGG)
1086         return;
1087     if (obj->corpsenm != NON_PM && !dead_species(obj->corpsenm, TRUE))
1088         attach_egg_hatch_timeout(obj, 0L);
1089 }
1090
1091 /* try to revive all corpses and eggs carried by `mon' */
1092 int
1093 unturn_dead(mon)
1094 struct monst *mon;
1095 {
1096     struct obj *otmp, *otmp2;
1097     struct monst *mtmp2;
1098     char owner[BUFSZ], corpse[BUFSZ];
1099     boolean youseeit;
1100     int res = 0;
1101
1102     youseeit = (mon == &youmonst) ? TRUE : canseemon(mon);
1103     otmp2 = (mon == &youmonst) ? invent : mon->minvent;
1104     owner[0] = corpse[0] = '\0'; /* lint suppression */
1105
1106     while ((otmp = otmp2) != 0) {
1107         otmp2 = otmp->nobj;
1108         if (otmp->otyp == EGG)
1109             revive_egg(otmp);
1110         if (otmp->otyp != CORPSE)
1111             continue;
1112         /* save the name; the object is liable to go away */
1113         if (youseeit) {
1114             Strcpy(corpse,
1115                    corpse_xname(otmp, (const char *) 0, CXN_SINGULAR));
1116             Shk_Your(owner, otmp); /* includes a trailing space */
1117         }
1118
1119         /* for a stack, only one is revived */
1120         if ((mtmp2 = revive(otmp, !context.mon_moving)) != 0) {
1121             ++res;
1122             if (youseeit)
1123 /*JP
1124                 pline("%s%s suddenly comes alive!", owner, corpse);
1125 */
1126                 pline("%s%s\82Í\93Ë\91R\90\96½\82ð\91Ñ\82Ñ\82½\81I", owner, corpse);
1127             else if (canseemon(mtmp2))
1128 /*JP
1129                 pline("%s suddenly appears!", Amonnam(mtmp2));
1130 */
1131                 pline("%s\82ª\93Ë\91R\8c»\82í\82ê\82½\81I", Amonnam(mtmp2));
1132         }
1133     }
1134     return res;
1135 }
1136
1137 /* cancel obj, possibly carried by you or a monster */
1138 void
1139 cancel_item(obj)
1140 register struct obj *obj;
1141 {
1142     boolean u_ring = (obj == uleft || obj == uright);
1143     int otyp = obj->otyp;
1144
1145     switch (otyp) {
1146     case RIN_GAIN_STRENGTH:
1147         if ((obj->owornmask & W_RING) && u_ring) {
1148             ABON(A_STR) -= obj->spe;
1149             context.botl = 1;
1150         }
1151         break;
1152     case RIN_GAIN_CONSTITUTION:
1153         if ((obj->owornmask & W_RING) && u_ring) {
1154             ABON(A_CON) -= obj->spe;
1155             context.botl = 1;
1156         }
1157         break;
1158     case RIN_ADORNMENT:
1159         if ((obj->owornmask & W_RING) && u_ring) {
1160             ABON(A_CHA) -= obj->spe;
1161             context.botl = 1;
1162         }
1163         break;
1164     case RIN_INCREASE_ACCURACY:
1165         if ((obj->owornmask & W_RING) && u_ring)
1166             u.uhitinc -= obj->spe;
1167         break;
1168     case RIN_INCREASE_DAMAGE:
1169         if ((obj->owornmask & W_RING) && u_ring)
1170             u.udaminc -= obj->spe;
1171         break;
1172     case GAUNTLETS_OF_DEXTERITY:
1173         if ((obj->owornmask & W_ARMG) && (obj == uarmg)) {
1174             ABON(A_DEX) -= obj->spe;
1175             context.botl = 1;
1176         }
1177         break;
1178     case HELM_OF_BRILLIANCE:
1179         if ((obj->owornmask & W_ARMH) && (obj == uarmh)) {
1180             ABON(A_INT) -= obj->spe;
1181             ABON(A_WIS) -= obj->spe;
1182             context.botl = 1;
1183         }
1184         break;
1185         /* case RIN_PROTECTION:  not needed */
1186     }
1187     if (objects[otyp].oc_magic
1188         || (obj->spe && (obj->oclass == ARMOR_CLASS
1189                          || obj->oclass == WEAPON_CLASS || is_weptool(obj)))
1190         || otyp == POT_ACID
1191         || otyp == POT_SICKNESS
1192         || (otyp == POT_WATER && (obj->blessed || obj->cursed))) {
1193         if (obj->spe != ((obj->oclass == WAND_CLASS) ? -1 : 0)
1194             && otyp != WAN_CANCELLATION /* can't cancel cancellation */
1195             && otyp != MAGIC_LAMP /* cancelling doesn't remove djinni */
1196             && otyp != CANDELABRUM_OF_INVOCATION) {
1197             costly_alteration(obj, COST_CANCEL);
1198             obj->spe = (obj->oclass == WAND_CLASS) ? -1 : 0;
1199         }
1200         switch (obj->oclass) {
1201         case SCROLL_CLASS:
1202             costly_alteration(obj, COST_CANCEL);
1203             obj->otyp = SCR_BLANK_PAPER;
1204             obj->spe = 0;
1205             break;
1206         case SPBOOK_CLASS:
1207             if (otyp != SPE_CANCELLATION && otyp != SPE_NOVEL
1208                 && otyp != SPE_BOOK_OF_THE_DEAD) {
1209                 costly_alteration(obj, COST_CANCEL);
1210                 obj->otyp = SPE_BLANK_PAPER;
1211             }
1212             break;
1213         case POTION_CLASS:
1214             costly_alteration(obj,
1215                               (otyp != POT_WATER)
1216                                   ? COST_CANCEL
1217                                   : obj->cursed ? COST_UNCURS : COST_UNBLSS);
1218             if (otyp == POT_SICKNESS || otyp == POT_SEE_INVISIBLE) {
1219                 /* sickness is "biologically contaminated" fruit juice;
1220                    cancel it and it just becomes fruit juice...
1221                    whereas see invisible tastes like "enchanted" fruit
1222                    juice, it similarly cancels */
1223                 obj->otyp = POT_FRUIT_JUICE;
1224             } else {
1225                 obj->otyp = POT_WATER;
1226                 obj->odiluted = 0; /* same as any other water */
1227             }
1228             break;
1229         }
1230     }
1231     unbless(obj);
1232     uncurse(obj);
1233     return;
1234 }
1235
1236 /* Remove a positive enchantment or charge from obj,
1237  * possibly carried by you or a monster
1238  */
1239 boolean
1240 drain_item(obj, by_you)
1241 struct obj *obj;
1242 boolean by_you;
1243 {
1244     boolean u_ring;
1245
1246     /* Is this a charged/enchanted object? */
1247     if (!obj
1248         || (!objects[obj->otyp].oc_charged && obj->oclass != WEAPON_CLASS
1249             && obj->oclass != ARMOR_CLASS && !is_weptool(obj))
1250         || obj->spe <= 0)
1251         return FALSE;
1252     if (defends(AD_DRLI, obj) || defends_when_carried(AD_DRLI, obj)
1253         || obj_resists(obj, 10, 90))
1254         return FALSE;
1255
1256     /* Charge for the cost of the object */
1257     if (by_you)
1258         costly_alteration(obj, COST_DRAIN);
1259
1260     /* Drain the object and any implied effects */
1261     obj->spe--;
1262     u_ring = (obj == uleft) || (obj == uright);
1263     switch (obj->otyp) {
1264     case RIN_GAIN_STRENGTH:
1265         if ((obj->owornmask & W_RING) && u_ring) {
1266             ABON(A_STR)--;
1267             context.botl = 1;
1268         }
1269         break;
1270     case RIN_GAIN_CONSTITUTION:
1271         if ((obj->owornmask & W_RING) && u_ring) {
1272             ABON(A_CON)--;
1273             context.botl = 1;
1274         }
1275         break;
1276     case RIN_ADORNMENT:
1277         if ((obj->owornmask & W_RING) && u_ring) {
1278             ABON(A_CHA)--;
1279             context.botl = 1;
1280         }
1281         break;
1282     case RIN_INCREASE_ACCURACY:
1283         if ((obj->owornmask & W_RING) && u_ring)
1284             u.uhitinc--;
1285         break;
1286     case RIN_INCREASE_DAMAGE:
1287         if ((obj->owornmask & W_RING) && u_ring)
1288             u.udaminc--;
1289         break;
1290     case RIN_PROTECTION:
1291         if (u_ring)
1292             context.botl = 1; /* bot() will recalc u.uac */
1293         break;
1294     case HELM_OF_BRILLIANCE:
1295         if ((obj->owornmask & W_ARMH) && (obj == uarmh)) {
1296             ABON(A_INT)--;
1297             ABON(A_WIS)--;
1298             context.botl = 1;
1299         }
1300         break;
1301     case GAUNTLETS_OF_DEXTERITY:
1302         if ((obj->owornmask & W_ARMG) && (obj == uarmg)) {
1303             ABON(A_DEX)--;
1304             context.botl = 1;
1305         }
1306         break;
1307     default:
1308         break;
1309     }
1310     if (context.botl)
1311         bot();
1312     if (carried(obj))
1313         update_inventory();
1314     return TRUE;
1315 }
1316
1317 boolean
1318 obj_resists(obj, ochance, achance)
1319 struct obj *obj;
1320 int ochance, achance; /* percent chance for ordinary objects, artifacts */
1321 {
1322     if (obj->otyp == AMULET_OF_YENDOR
1323         || obj->otyp == SPE_BOOK_OF_THE_DEAD
1324         || obj->otyp == CANDELABRUM_OF_INVOCATION
1325         || obj->otyp == BELL_OF_OPENING
1326         || (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm]))) {
1327         return TRUE;
1328     } else {
1329         int chance = rn2(100);
1330
1331         return (boolean) (chance < (obj->oartifact ? achance : ochance));
1332     }
1333 }
1334
1335 boolean
1336 obj_shudders(obj)
1337 struct obj *obj;
1338 {
1339     int zap_odds;
1340
1341     if (context.bypasses && obj->bypass)
1342         return FALSE;
1343
1344     if (obj->oclass == WAND_CLASS)
1345         zap_odds = 3; /* half-life = 2 zaps */
1346     else if (obj->cursed)
1347         zap_odds = 3; /* half-life = 2 zaps */
1348     else if (obj->blessed)
1349         zap_odds = 12; /* half-life = 8 zaps */
1350     else
1351         zap_odds = 8; /* half-life = 6 zaps */
1352
1353     /* adjust for "large" quantities of identical things */
1354     if (obj->quan > 4L)
1355         zap_odds /= 2;
1356
1357     return (boolean) !rn2(zap_odds);
1358 }
1359
1360 /* Use up at least minwt number of things made of material mat.
1361  * There's also a chance that other stuff will be used up.  Finally,
1362  * there's a random factor here to keep from always using the stuff
1363  * at the top of the pile.
1364  */
1365 STATIC_OVL void
1366 polyuse(objhdr, mat, minwt)
1367 struct obj *objhdr;
1368 int mat, minwt;
1369 {
1370     register struct obj *otmp, *otmp2;
1371
1372     for (otmp = objhdr; minwt > 0 && otmp; otmp = otmp2) {
1373         otmp2 = otmp->nexthere;
1374         if (context.bypasses && otmp->bypass)
1375             continue;
1376         if (otmp == uball || otmp == uchain)
1377             continue;
1378         if (obj_resists(otmp, 0, 0))
1379             continue; /* preserve unique objects */
1380 #ifdef MAIL
1381         if (otmp->otyp == SCR_MAIL)
1382             continue;
1383 #endif
1384
1385         if (((int) objects[otmp->otyp].oc_material == mat)
1386             == (rn2(minwt + 1) != 0)) {
1387             /* appropriately add damage to bill */
1388             if (costly_spot(otmp->ox, otmp->oy)) {
1389                 if (*u.ushops)
1390                     addtobill(otmp, FALSE, FALSE, FALSE);
1391                 else
1392                     (void) stolen_value(otmp, otmp->ox, otmp->oy, FALSE,
1393                                         FALSE);
1394             }
1395             if (otmp->quan < LARGEST_INT)
1396                 minwt -= (int) otmp->quan;
1397             else
1398                 minwt = 0;
1399             delobj(otmp);
1400         }
1401     }
1402 }
1403
1404 /*
1405  * Polymorph some of the stuff in this pile into a monster, preferably
1406  * a golem of the kind okind.
1407  */
1408 STATIC_OVL void
1409 create_polymon(obj, okind)
1410 struct obj *obj;
1411 int okind;
1412 {
1413     struct permonst *mdat = (struct permonst *) 0;
1414     struct monst *mtmp;
1415     const char *material;
1416     int pm_index;
1417
1418     if (context.bypasses) {
1419         /* this is approximate because the "no golems" !obj->nexthere
1420            check below doesn't understand bypassed objects; but it
1421            should suffice since bypassed objects always end up as a
1422            consecutive group at the top of their pile */
1423         while (obj && obj->bypass)
1424             obj = obj->nexthere;
1425     }
1426
1427     /* no golems if you zap only one object -- not enough stuff */
1428     if (!obj || (!obj->nexthere && obj->quan == 1L))
1429         return;
1430
1431     /* some of these choices are arbitrary */
1432     switch (okind) {
1433     case IRON:
1434     case METAL:
1435     case MITHRIL:
1436         pm_index = PM_IRON_GOLEM;
1437 /*JP
1438         material = "metal ";
1439 */
1440         material = "\8bà\91®";
1441         break;
1442     case COPPER:
1443     case SILVER:
1444     case PLATINUM:
1445     case GEMSTONE:
1446     case MINERAL:
1447         pm_index = rn2(2) ? PM_STONE_GOLEM : PM_CLAY_GOLEM;
1448 /*JP
1449         material = "lithic ";
1450 */
1451         material = "\8dz\95¨";
1452         break;
1453     case 0:
1454     case FLESH:
1455         /* there is no flesh type, but all food is type 0, so we use it */
1456         pm_index = PM_FLESH_GOLEM;
1457 /*JP
1458         material = "organic ";
1459 */
1460         material = "\97L\8b@\95¨";
1461         break;
1462     case WOOD:
1463         pm_index = PM_WOOD_GOLEM;
1464 /*JP
1465         material = "wood ";
1466 */
1467         material = "\96Ø\8dÞ";
1468         break;
1469     case LEATHER:
1470         pm_index = PM_LEATHER_GOLEM;
1471 /*JP
1472         material = "leather ";
1473 */
1474         material = "\8av";
1475         break;
1476     case CLOTH:
1477         pm_index = PM_ROPE_GOLEM;
1478 /*JP
1479         material = "cloth ";
1480 */
1481         material = "\95z";
1482         break;
1483     case BONE:
1484         pm_index = PM_SKELETON; /* nearest thing to "bone golem" */
1485 /*JP
1486         material = "bony ";
1487 */
1488         material = "\8d\9c";
1489         break;
1490     case GOLD:
1491         pm_index = PM_GOLD_GOLEM;
1492 /*JP
1493         material = "gold ";
1494 */
1495         material = "\8bà";
1496         break;
1497     case GLASS:
1498         pm_index = PM_GLASS_GOLEM;
1499 /*JP
1500         material = "glassy ";
1501 */
1502         material = "\83K\83\89\83X";
1503         break;
1504     case PAPER:
1505         pm_index = PM_PAPER_GOLEM;
1506 /*JP
1507         material = "paper ";
1508 */
1509         material = "\8e\86";
1510         break;
1511     default:
1512         /* if all else fails... */
1513         pm_index = PM_STRAW_GOLEM;
1514 #if 0 /*JP:T*/
1515         material = "";
1516 #else
1517         material = "\95¨\91Ì";
1518 #endif
1519         break;
1520     }
1521
1522     if (!(mvitals[pm_index].mvflags & G_GENOD))
1523         mdat = &mons[pm_index];
1524
1525     mtmp = makemon(mdat, obj->ox, obj->oy, NO_MM_FLAGS);
1526     polyuse(obj, okind, (int) mons[pm_index].cwt);
1527
1528     if (mtmp && cansee(mtmp->mx, mtmp->my)) {
1529 #if 0 /*JP:T*/
1530         pline("Some %sobjects meld, and %s arises from the pile!", material,
1531               a_monnam(mtmp));
1532 #else
1533         pline("\82¢\82­\82Â\82©\82Ì%s\82ª\97n\82¯\81C\82»\82Ì\8eR\82©\82ç%s\82ª\8c»\82í\82ê\82½\81I", material,
1534               a_monnam(mtmp));
1535 #endif
1536     }
1537 }
1538
1539 /* Assumes obj is on the floor. */
1540 void
1541 do_osshock(obj)
1542 struct obj *obj;
1543 {
1544     long i;
1545
1546 #ifdef MAIL
1547     if (obj->otyp == SCR_MAIL)
1548         return;
1549 #endif
1550     obj_zapped = TRUE;
1551
1552     if (poly_zapped < 0) {
1553         /* some may metamorphosize */
1554         for (i = obj->quan; i; i--)
1555             if (!rn2(Luck + 45)) {
1556                 poly_zapped = objects[obj->otyp].oc_material;
1557                 break;
1558             }
1559     }
1560
1561     /* if quan > 1 then some will survive intact */
1562     if (obj->quan > 1L) {
1563         if (obj->quan > LARGEST_INT)
1564             obj = splitobj(obj, (long) rnd(30000));
1565         else
1566             obj = splitobj(obj, (long) rnd((int) obj->quan - 1));
1567     }
1568
1569     /* appropriately add damage to bill */
1570     if (costly_spot(obj->ox, obj->oy)) {
1571         if (*u.ushops)
1572             addtobill(obj, FALSE, FALSE, FALSE);
1573         else
1574             (void) stolen_value(obj, obj->ox, obj->oy, FALSE, FALSE);
1575     }
1576
1577     /* zap the object */
1578     delobj(obj);
1579 }
1580
1581 /* classes of items whose current charge count carries over across polymorph
1582  */
1583 static const char charged_objs[] = { WAND_CLASS, WEAPON_CLASS, ARMOR_CLASS,
1584                                      '\0' };
1585
1586 /*
1587  * Polymorph the object to the given object ID.  If the ID is STRANGE_OBJECT
1588  * then pick random object from the source's class (this is the standard
1589  * "polymorph" case).  If ID is set to a specific object, inhibit fusing
1590  * n objects into 1.  This could have been added as a flag, but currently
1591  * it is tied to not being the standard polymorph case. The new polymorphed
1592  * object replaces obj in its link chains.  Return value is a pointer to
1593  * the new object.
1594  *
1595  * This should be safe to call for an object anywhere.
1596  */
1597 struct obj *
1598 poly_obj(obj, id)
1599 struct obj *obj;
1600 int id;
1601 {
1602     struct obj *otmp;
1603     xchar ox = 0, oy = 0;
1604     long old_wornmask, new_wornmask = 0L;
1605     boolean can_merge = (id == STRANGE_OBJECT);
1606     int obj_location = obj->where;
1607
1608     if (obj->otyp == BOULDER)
1609         sokoban_guilt();
1610     if (id == STRANGE_OBJECT) { /* preserve symbol */
1611         int try_limit = 3;
1612         unsigned magic_obj = objects[obj->otyp].oc_magic;
1613
1614         if (obj->otyp == UNICORN_HORN && obj->degraded_horn)
1615             magic_obj = 0;
1616         /* Try up to 3 times to make the magic-or-not status of
1617            the new item be the same as it was for the old one. */
1618         otmp = (struct obj *) 0;
1619         do {
1620             if (otmp)
1621                 delobj(otmp);
1622             otmp = mkobj(obj->oclass, FALSE);
1623         } while (--try_limit > 0
1624                  && objects[otmp->otyp].oc_magic != magic_obj);
1625     } else {
1626         /* literally replace obj with this new thing */
1627         otmp = mksobj(id, FALSE, FALSE);
1628 /* Actually more things use corpsenm but they polymorph differently */
1629 #define USES_CORPSENM(typ) \
1630     ((typ) == CORPSE || (typ) == STATUE || (typ) == FIGURINE)
1631
1632         if (USES_CORPSENM(obj->otyp) && USES_CORPSENM(id))
1633             set_corpsenm(otmp, obj->corpsenm);
1634 #undef USES_CORPSENM
1635     }
1636
1637     /* preserve quantity */
1638     otmp->quan = obj->quan;
1639     /* preserve the shopkeepers (lack of) interest */
1640     otmp->no_charge = obj->no_charge;
1641     /* preserve inventory letter if in inventory */
1642     if (obj_location == OBJ_INVENT)
1643         otmp->invlet = obj->invlet;
1644 #ifdef MAIL
1645     /* You can't send yourself 100 mail messages and then
1646      * polymorph them into useful scrolls
1647      */
1648     if (obj->otyp == SCR_MAIL) {
1649         otmp->otyp = SCR_MAIL;
1650         otmp->spe = 1;
1651     }
1652 #endif
1653
1654     /* avoid abusing eggs laid by you */
1655     if (obj->otyp == EGG && obj->spe) {
1656         int mnum, tryct = 100;
1657
1658         /* first, turn into a generic egg */
1659         if (otmp->otyp == EGG)
1660             kill_egg(otmp);
1661         else {
1662             otmp->otyp = EGG;
1663             otmp->owt = weight(otmp);
1664         }
1665         otmp->corpsenm = NON_PM;
1666         otmp->spe = 0;
1667
1668         /* now change it into something laid by the hero */
1669         while (tryct--) {
1670             mnum = can_be_hatched(random_monster(rn2));
1671             if (mnum != NON_PM && !dead_species(mnum, TRUE)) {
1672                 otmp->spe = 1;            /* laid by hero */
1673                 set_corpsenm(otmp, mnum); /* also sets hatch timer */
1674                 break;
1675             }
1676         }
1677     }
1678
1679     /* keep special fields (including charges on wands) */
1680     if (index(charged_objs, otmp->oclass))
1681         otmp->spe = obj->spe;
1682     otmp->recharged = obj->recharged;
1683
1684     otmp->cursed = obj->cursed;
1685     otmp->blessed = obj->blessed;
1686
1687     if (erosion_matters(otmp)) {
1688         if (is_flammable(otmp) || is_rustprone(otmp))
1689             otmp->oeroded = obj->oeroded;
1690         if (is_corrodeable(otmp) || is_rottable(otmp))
1691             otmp->oeroded2 = obj->oeroded2;
1692         if (is_damageable(otmp))
1693             otmp->oerodeproof = obj->oerodeproof;
1694     }
1695
1696     /* Keep chest/box traps and poisoned ammo if we may */
1697     if (obj->otrapped && Is_box(otmp))
1698         otmp->otrapped = TRUE;
1699
1700     if (obj->opoisoned && is_poisonable(otmp))
1701         otmp->opoisoned = TRUE;
1702
1703     if (id == STRANGE_OBJECT && obj->otyp == CORPSE) {
1704         /* turn crocodile corpses into shoes */
1705         if (obj->corpsenm == PM_CROCODILE) {
1706             otmp->otyp = LOW_BOOTS;
1707             otmp->oclass = ARMOR_CLASS;
1708             otmp->spe = 0;
1709             otmp->oeroded = 0;
1710             otmp->oerodeproof = TRUE;
1711             otmp->quan = 1L;
1712             otmp->cursed = FALSE;
1713         }
1714     }
1715
1716     /* no box contents --KAA */
1717     if (Has_contents(otmp))
1718         delete_contents(otmp);
1719
1720     /* 'n' merged objects may be fused into 1 object */
1721     if (otmp->quan > 1L && (!objects[otmp->otyp].oc_merge
1722                             || (can_merge && otmp->quan > (long) rn2(1000))))
1723         otmp->quan = 1L;
1724
1725     switch (otmp->oclass) {
1726     case TOOL_CLASS:
1727         if (otmp->otyp == MAGIC_LAMP) {
1728             otmp->otyp = OIL_LAMP;
1729             otmp->age = 1500L; /* "best" oil lamp possible */
1730         } else if (otmp->otyp == MAGIC_MARKER) {
1731             otmp->recharged = 1; /* degraded quality */
1732         }
1733         /* don't care about the recharge count of other tools */
1734         break;
1735
1736     case WAND_CLASS:
1737         while (otmp->otyp == WAN_WISHING || otmp->otyp == WAN_POLYMORPH)
1738             otmp->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING);
1739         /* altering the object tends to degrade its quality
1740            (analogous to spellbook `read count' handling) */
1741         if ((int) otmp->recharged < rn2(7)) /* recharge_limit */
1742             otmp->recharged++;
1743         break;
1744
1745     case POTION_CLASS:
1746         while (otmp->otyp == POT_POLYMORPH)
1747             otmp->otyp = rnd_class(POT_GAIN_ABILITY, POT_WATER);
1748         break;
1749
1750     case SPBOOK_CLASS:
1751         while (otmp->otyp == SPE_POLYMORPH)
1752             otmp->otyp = rnd_class(SPE_DIG, SPE_BLANK_PAPER);
1753         /* reduce spellbook abuse; non-blank books degrade */
1754         if (otmp->otyp != SPE_BLANK_PAPER) {
1755             otmp->spestudied = obj->spestudied + 1;
1756             if (otmp->spestudied > MAX_SPELL_STUDY) {
1757                 otmp->otyp = SPE_BLANK_PAPER;
1758                 /* writing a new book over it will yield an unstudied
1759                    one; re-polymorphing this one as-is may or may not
1760                    get something non-blank */
1761                 otmp->spestudied = rn2(otmp->spestudied);
1762             }
1763         }
1764         break;
1765
1766     case GEM_CLASS:
1767         if (otmp->quan > (long) rnd(4)
1768             && objects[obj->otyp].oc_material == MINERAL
1769             && objects[otmp->otyp].oc_material != MINERAL) {
1770             otmp->otyp = ROCK; /* transmutation backfired */
1771             otmp->quan /= 2L;  /* some material has been lost */
1772         }
1773         break;
1774     }
1775
1776     /* update the weight */
1777     otmp->owt = weight(otmp);
1778
1779     /*
1780      * ** we are now done adjusting the object (except possibly wearing it) **
1781      */
1782
1783     (void) get_obj_location(obj, &ox, &oy, BURIED_TOO | CONTAINED_TOO);
1784     old_wornmask = obj->owornmask & ~(W_ART | W_ARTI);
1785     /* swap otmp for obj */
1786     replace_object(obj, otmp);
1787     if (obj_location == OBJ_INVENT) {
1788         /*
1789          * We may need to do extra adjustments for the hero if we're
1790          * messing with the hero's inventory.  The following calls are
1791          * equivalent to calling freeinv on obj and addinv on otmp,
1792          * while doing an in-place swap of the actual objects.
1793          */
1794         freeinv_core(obj);
1795         addinv_core1(otmp);
1796         addinv_core2(otmp);
1797         /*
1798          * Handle polymorph of worn item.  Stone-to-flesh cast on self can
1799          * affect multiple objects at once, but their new forms won't
1800          * produce any side-effects.  A single worn item dipped into potion
1801          * of polymorph can produce side-effects but those won't yield out
1802          * of sequence messages because current polymorph is finished.
1803          */
1804         if (old_wornmask) {
1805             boolean was_twohanded = bimanual(obj), was_twoweap = u.twoweap;
1806
1807             /* wearslot() returns a mask which might have multiple bits set;
1808                narrow that down to the bit(s) currently in use */
1809             new_wornmask = wearslot(otmp) & old_wornmask;
1810             remove_worn_item(obj, TRUE);
1811             /* if the new form can be worn in the same slot, make it so */
1812             if ((new_wornmask & W_WEP) != 0L) {
1813                 if (was_twohanded || !bimanual(otmp) || !uarms)
1814                     setuwep(otmp);
1815                 if (was_twoweap && uwep && !bimanual(uwep))
1816                     u.twoweap = TRUE;
1817             } else if ((new_wornmask & W_SWAPWEP) != 0L) {
1818                 if (was_twohanded || !bimanual(otmp))
1819                     setuswapwep(otmp);
1820                 if (was_twoweap && uswapwep)
1821                     u.twoweap = TRUE;
1822             } else if ((new_wornmask & W_QUIVER) != 0L) {
1823                 setuqwep(otmp);
1824             } else if (new_wornmask) {
1825                 setworn(otmp, new_wornmask);
1826                 /* set_wear() might result in otmp being destroyed if
1827                    worn amulet has been turned into an amulet of change */
1828                 set_wear(otmp);
1829                 otmp = wearmask_to_obj(new_wornmask); /* might be Null */
1830             }
1831         } /* old_wornmask */
1832     } else if (obj_location == OBJ_FLOOR) {
1833         if (obj->otyp == BOULDER && otmp->otyp != BOULDER
1834             && !does_block(ox, oy, &levl[ox][oy]))
1835             unblock_point(ox, oy);
1836         else if (obj->otyp != BOULDER && otmp->otyp == BOULDER)
1837             /* (checking does_block() here would be redundant) */
1838             block_point(ox, oy);
1839     }
1840
1841     /* note: if otmp is gone, billing for it was handled by useup() */
1842     if (((otmp && !carried(otmp)) || obj->unpaid) && costly_spot(ox, oy)) {
1843         struct monst *shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE));
1844
1845         if ((!obj->no_charge
1846              || (Has_contents(obj)
1847                  && (contained_cost(obj, shkp, 0L, FALSE, FALSE) != 0L)))
1848             && inhishop(shkp)) {
1849             if (shkp->mpeaceful) {
1850                 if (*u.ushops
1851                     && (*in_rooms(u.ux, u.uy, 0)
1852                         == *in_rooms(shkp->mx, shkp->my, 0))
1853                     && !costly_spot(u.ux, u.uy)) {
1854                     make_angry_shk(shkp, ox, oy);
1855                 } else {
1856 /*JP
1857                     pline("%s gets angry!", Monnam(shkp));
1858 */
1859                     pline("%s\82Í\8c\83\93{\82µ\82½\81I", Monnam(shkp));
1860                     hot_pursuit(shkp);
1861                 }
1862             } else
1863 /*JP
1864                 Norep("%s is furious!", Monnam(shkp));
1865 */
1866                 Norep("%s\82Í\93{\82Á\82½\81I", Monnam(shkp));
1867         }
1868     }
1869     delobj(obj);
1870     return otmp;
1871 }
1872
1873 /* stone-to-flesh spell hits and maybe transforms or animates obj */
1874 STATIC_OVL int
1875 stone_to_flesh_obj(obj)
1876 struct obj *obj;
1877 {
1878     int res = 1; /* affected object by default */
1879     struct permonst *ptr;
1880     struct monst *mon, *shkp;
1881     struct obj *item;
1882     xchar oox, ooy;
1883     boolean smell = FALSE, golem_xform = FALSE;
1884
1885     if (objects[obj->otyp].oc_material != MINERAL
1886         && objects[obj->otyp].oc_material != GEMSTONE)
1887         return 0;
1888     /* Heart of Ahriman usually resists; ordinary items rarely do */
1889     if (obj_resists(obj, 2, 98))
1890         return 0;
1891
1892     (void) get_obj_location(obj, &oox, &ooy, 0);
1893     /* add more if stone objects are added.. */
1894     switch (objects[obj->otyp].oc_class) {
1895     case ROCK_CLASS: /* boulders and statues */
1896     case TOOL_CLASS: /* figurines */
1897         if (obj->otyp == BOULDER) {
1898             obj = poly_obj(obj, HUGE_CHUNK_OF_MEAT);
1899             smell = TRUE;
1900         } else if (obj->otyp == STATUE || obj->otyp == FIGURINE) {
1901             ptr = &mons[obj->corpsenm];
1902             if (is_golem(ptr)) {
1903                 golem_xform = (ptr != &mons[PM_FLESH_GOLEM]);
1904             } else if (vegetarian(ptr)) {
1905                 /* Don't animate monsters that aren't flesh */
1906                 obj = poly_obj(obj, MEATBALL);
1907                 smell = TRUE;
1908                 break;
1909             }
1910             if (obj->otyp == STATUE) {
1911                 /* animate_statue() forces all golems to become flesh golems */
1912                 mon = animate_statue(obj, oox, ooy, ANIMATE_SPELL, (int *) 0);
1913             } else { /* (obj->otyp == FIGURINE) */
1914                 if (golem_xform)
1915                     ptr = &mons[PM_FLESH_GOLEM];
1916                 mon = makemon(ptr, oox, ooy, NO_MINVENT);
1917                 if (mon) {
1918                     if (costly_spot(oox, ooy)
1919                         && (carried(obj) ? obj->unpaid : !obj->no_charge)) {
1920                         shkp = shop_keeper(*in_rooms(oox, ooy, SHOPBASE));
1921                         stolen_value(obj, oox, ooy,
1922                                      (shkp && shkp->mpeaceful), FALSE);
1923                     }
1924                     if (obj->timed)
1925                         obj_stop_timers(obj);
1926                     if (carried(obj))
1927                         useup(obj);
1928                     else
1929                         delobj(obj);
1930                     if (cansee(mon->mx, mon->my))
1931 #if 0 /*JP:T*/
1932                         pline_The("figurine %sanimates!",
1933                                   golem_xform ? "turns to flesh and " : "");
1934 #else
1935                         pline_The("\90l\8c`\82Í%s\93®\82«\82¾\82µ\82½\81I",
1936                                   golem_xform ? "\90Î\89»\82ª\89ð\82¯\82Ä" : "");
1937 #endif
1938                 }
1939             }
1940             if (mon) {
1941                 ptr = mon->data;
1942                 /* this golem handling is redundant... */
1943                 if (is_golem(ptr) && ptr != &mons[PM_FLESH_GOLEM])
1944                     (void) newcham(mon, &mons[PM_FLESH_GOLEM], TRUE, FALSE);
1945             } else if ((ptr->geno & (G_NOCORPSE | G_UNIQ)) != 0) {
1946                 /* didn't revive but can't leave corpse either */
1947                 res = 0;
1948             } else {
1949                 /* unlikely to get here since genociding monsters also
1950                    sets the G_NOCORPSE flag; drop statue's contents */
1951                 while ((item = obj->cobj) != 0) {
1952                     bypass_obj(item); /* make stone-to-flesh miss it */
1953                     obj_extract_self(item);
1954                     place_object(item, oox, ooy);
1955                 }
1956                 obj = poly_obj(obj, CORPSE);
1957             }
1958         } else { /* miscellaneous tool or unexpected rock... */
1959             res = 0;
1960         }
1961         break;
1962     /* maybe add weird things to become? */
1963     case RING_CLASS: /* some of the rings are stone */
1964         obj = poly_obj(obj, MEAT_RING);
1965         smell = TRUE;
1966         break;
1967     case WAND_CLASS: /* marble wand */
1968         obj = poly_obj(obj, MEAT_STICK);
1969         smell = TRUE;
1970         break;
1971     case GEM_CLASS: /* stones & gems */
1972         obj = poly_obj(obj, MEATBALL);
1973         smell = TRUE;
1974         break;
1975     case WEAPON_CLASS: /* crysknife */
1976         /*FALLTHRU*/
1977     default:
1978         res = 0;
1979         break;
1980     }
1981
1982     if (smell) {
1983         /* non-meat eaters smell meat, meat eaters smell its flavor;
1984            monks are considered non-meat eaters regardless of behavior;
1985            other roles are non-meat eaters if they haven't broken
1986            vegetarian conduct yet (or if poly'd into non-carnivorous/
1987            non-omnivorous form, regardless of whether it's herbivorous,
1988            non-eating, or something stranger) */
1989         if (Role_if(PM_MONK) || !u.uconduct.unvegetarian
1990             || !carnivorous(youmonst.data))
1991 /*JP
1992             Norep("You smell the odor of meat.");
1993 */
1994             Norep("\93÷\82Ì\88«\8fL\82ª\95Y\82Á\82½\81D");
1995         else
1996 /*JP
1997             Norep("You smell a delicious smell.");
1998 */
1999             Norep("\82·\82Î\82ç\82µ\82¢\8d\81\82è\82¾\81I");
2000     }
2001     newsym(oox, ooy);
2002     return res;
2003 }
2004
2005 /*
2006  * Object obj was hit by the effect of the wand/spell otmp.  Return
2007  * non-zero if the wand/spell had any effect.
2008  */
2009 int
2010 bhito(obj, otmp)
2011 struct obj *obj, *otmp;
2012 {
2013     int res = 1; /* affected object by default */
2014     boolean learn_it = FALSE, maybelearnit;
2015
2016     /* fundamental: a wand effect hitting itself doesn't do anything;
2017        otherwise we need to guard against accessing otmp after something
2018        strange has happened to it (along the lines of polymorph or
2019        stone-to-flesh [which aren't good examples since polymorph wands
2020        aren't affected by polymorph zaps and stone-to-flesh isn't
2021        available in wand form, but the concept still applies...]) */
2022     if (obj == otmp)
2023         return 0;
2024
2025     if (obj->bypass) {
2026         /* The bypass bit is currently only used as follows:
2027          *
2028          * POLYMORPH - When a monster being polymorphed drops something
2029          *             from its inventory as a result of the change.
2030          *             If the items fall to the floor, they are not
2031          *             subject to direct subsequent polymorphing
2032          *             themselves on that same zap.  This makes it
2033          *             consistent with items that remain in the monster's
2034          *             inventory.  They are not polymorphed either.
2035          * UNDEAD_TURNING - When an undead creature gets killed via
2036          *             undead turning, prevent its corpse from being
2037          *             immediately revived by the same effect.
2038          * STONE_TO_FLESH - If a statue can't be revived, its
2039          *             contents get dropped before turning it into
2040          *             meat; prevent those contents from being hit.
2041          * retouch_equipment() - bypass flag is used to track which
2042          *             items have been handled (bhito isn't involved).
2043          * menu_drop(), askchain() - inventory traversal where multiple
2044          *             Drop can alter the invent chain while traversal
2045          *             is in progress (bhito isn't involved).
2046          * destroy_item(), destroy_mitem() - inventory traversal where
2047          *             item destruction can trigger drop or destruction of
2048          *             other item(s) and alter the invent or mon->minvent
2049          *             chain, possibly recursively.
2050          *
2051          * The bypass bit on all objects is reset each turn, whenever
2052          * context.bypasses is set.
2053          *
2054          * We check the obj->bypass bit above AND context.bypasses
2055          * as a safeguard against any stray occurrence left in an obj
2056          * struct someplace, although that should never happen.
2057          */
2058         if (context.bypasses) {
2059             return 0;
2060         } else {
2061             debugpline1("%s for a moment.", Tobjnam(obj, "pulsate"));
2062             obj->bypass = 0;
2063         }
2064     }
2065
2066     /*
2067      * Some parts of this function expect the object to be on the floor
2068      * obj->{ox,oy} to be valid.  The exception to this (so far) is
2069      * for the STONE_TO_FLESH spell.
2070      */
2071     if (!(obj->where == OBJ_FLOOR || otmp->otyp == SPE_STONE_TO_FLESH))
2072         impossible("bhito: obj is not floor or Stone To Flesh spell");
2073
2074     if (obj == uball) {
2075         res = 0;
2076     } else if (obj == uchain) {
2077         if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK) {
2078             learn_it = TRUE;
2079             unpunish();
2080         } else
2081             res = 0;
2082     } else
2083         switch (otmp->otyp) {
2084         case WAN_POLYMORPH:
2085         case SPE_POLYMORPH:
2086             if (obj->otyp == WAN_POLYMORPH || obj->otyp == SPE_POLYMORPH
2087                 || obj->otyp == POT_POLYMORPH || obj_resists(obj, 5, 95)) {
2088                 res = 0;
2089                 break;
2090             }
2091             /* KMH, conduct */
2092             u.uconduct.polypiles++;
2093             /* any saved lock context will be dangerously obsolete */
2094             if (Is_box(obj))
2095                 (void) boxlock(obj, otmp);
2096
2097             if (obj_shudders(obj)) {
2098                 boolean cover = ((obj == level.objects[u.ux][u.uy])
2099                                  && u.uundetected
2100                                  && hides_under(youmonst.data));
2101
2102                 if (cansee(obj->ox, obj->oy))
2103                     learn_it = TRUE;
2104                 do_osshock(obj);
2105                 /* eek - your cover might have been blown */
2106                 if (cover)
2107                     (void) hideunder(&youmonst);
2108                 break;
2109             }
2110             obj = poly_obj(obj, STRANGE_OBJECT);
2111             newsym(obj->ox, obj->oy);
2112             break;
2113         case WAN_PROBING:
2114             res = !obj->dknown;
2115             /* target object has now been "seen (up close)" */
2116             obj->dknown = 1;
2117             if (Is_container(obj) || obj->otyp == STATUE) {
2118                 obj->cknown = obj->lknown = 1;
2119                 if (!obj->cobj) {
2120 /*JP
2121                     pline("%s empty.", Tobjnam(obj, "are"));
2122 */
2123                     pline("%s\82Í\8bó\82Á\82Û\82¾\81D", xname(obj));
2124                 } else if (SchroedingersBox(obj)) {
2125                     /* we don't want to force alive vs dead
2126                        determination for Schroedinger's Cat here,
2127                        so just make probing be inconclusive for it */
2128 #if 0 /*JP:T*/
2129                     You("aren't sure whether %s has %s or its corpse inside.",
2130                         the(xname(obj)),
2131                         /* unfortunately, we can't tell whether rndmonnam()
2132                            picks a form which can't leave a corpse */
2133                         an(Hallucination ? rndmonnam((char *) 0) : "cat"));
2134 #else
2135                     pline("%s\82É%s\82ª\93ü\82Á\82Ä\82¢\82é\82Ì\82©\82»\82Ì\8e\80\91Ì\82ª\93ü\82Á\82Ä\82¢\82é\82Ì\82©\82í\82©\82ç\82È\82¢\81D",
2136                         xname(obj),
2137                         /* unfortunately, we can't tell whether rndmonnam()
2138                            picks a form which can't leave a corpse */
2139                         Hallucination ? rndmonnam((char *) 0) : "\94L");
2140 #endif
2141                     obj->cknown = 0;
2142                 } else {
2143                     struct obj *o;
2144
2145                     /* view contents (not recursively) */
2146                     for (o = obj->cobj; o; o = o->nobj)
2147                         o->dknown = 1; /* "seen", even if blind */
2148                     (void) display_cinventory(obj);
2149                 }
2150                 res = 1;
2151             }
2152             if (res)
2153                 learn_it = TRUE;
2154             break;
2155         case WAN_STRIKING:
2156         case SPE_FORCE_BOLT:
2157             /* learn the type if you see or hear something break
2158                (the sound could be implicit) */
2159             maybelearnit = cansee(obj->ox, obj->oy) || !Deaf;
2160             if (obj->otyp == BOULDER) {
2161                 if (cansee(obj->ox, obj->oy))
2162 /*JP
2163                     pline_The("boulder falls apart.");
2164 */
2165                     pline_The("\8aâ\82Í\82Î\82ç\82Î\82ç\82É\82È\82Á\82½\81D");
2166                 else
2167 /*JP
2168                     You_hear("a crumbling sound.");
2169 */
2170                     You_hear("\89½\82©\82ª\8dÓ\82¯\82é\89¹\82ð\95·\82¢\82½\81D");
2171                 fracture_rock(obj);
2172             } else if (obj->otyp == STATUE) {
2173                 if (break_statue(obj)) {
2174                     if (cansee(obj->ox, obj->oy)) {
2175                         if (Hallucination)
2176 /*JP
2177                             pline_The("%s shatters.", rndmonnam(NULL));
2178 */
2179                             pline_The("%s\82Í\95²\81X\82É\82È\82Á\82½\81D", rndmonnam(NULL));
2180                         else
2181 /*JP
2182                             pline_The("statue shatters.");
2183 */
2184                             pline_The("\90Î\91\9c\82Í\95²\81X\82É\82È\82Á\82½\81D");
2185                     } else
2186 /*JP
2187                         You_hear("a crumbling sound.");
2188 */
2189                         You_hear("\89½\82©\82ª\8dÓ\82¯\82é\89¹\82ð\95·\82¢\82½\81D");
2190                 }
2191             } else {
2192                 int oox = obj->ox;
2193                 int ooy = obj->oy;
2194                 if (context.mon_moving
2195                         ? !breaks(obj, obj->ox, obj->oy)
2196                         : !hero_breaks(obj, obj->ox, obj->oy, FALSE))
2197                     maybelearnit = FALSE; /* nothing broke */
2198                 else
2199                     newsym_force(oox,ooy);
2200                 res = 0;
2201             }
2202             if (maybelearnit)
2203                 learn_it = TRUE;
2204             break;
2205         case WAN_CANCELLATION:
2206         case SPE_CANCELLATION:
2207             cancel_item(obj);
2208 #ifdef TEXTCOLOR
2209             newsym(obj->ox, obj->oy); /* might change color */
2210 #endif
2211             break;
2212         case SPE_DRAIN_LIFE:
2213             (void) drain_item(obj, TRUE);
2214             break;
2215         case WAN_TELEPORTATION:
2216         case SPE_TELEPORT_AWAY:
2217             (void) rloco(obj);
2218             break;
2219         case WAN_MAKE_INVISIBLE:
2220             break;
2221         case WAN_UNDEAD_TURNING:
2222         case SPE_TURN_UNDEAD:
2223             if (obj->otyp == EGG) {
2224                 revive_egg(obj);
2225             } else if (obj->otyp == CORPSE) {
2226                 struct monst *mtmp;
2227                 xchar ox, oy;
2228                 int corpsenm = corpse_revive_type(obj);
2229                 char *corpsname = cxname_singular(obj);
2230
2231                 /* get corpse's location before revive() uses it up */
2232                 if (!get_obj_location(obj, &ox, &oy, 0))
2233                     ox = obj->ox, oy = obj->oy; /* won't happen */
2234
2235                 mtmp = revive(obj, TRUE);
2236                 if (!mtmp) {
2237                     res = 0; /* no monster implies corpse was left intact */
2238                 } else {
2239                     if (cansee(ox, oy)) {
2240                         if (canspotmon(mtmp)) {
2241 #if 0 /*JP:T*/
2242                             pline("%s is resurrected!",
2243                                   upstart(noname_monnam(mtmp, ARTICLE_THE)));
2244 #else
2245                             pline("%s\82Í\90\82«\95Ô\82Á\82½\81I",
2246                                   upstart(noname_monnam(mtmp, ARTICLE_THE)));
2247 #endif
2248                             learn_it = TRUE;
2249                         } else {
2250                             /* saw corpse but don't see monster: maybe
2251                                mtmp is invisible, or has been placed at
2252                                a different spot than <ox,oy> */
2253                             if (!type_is_pname(&mons[corpsenm]))
2254                                 corpsname = The(corpsname);
2255 /*JP
2256                             pline("%s disappears.", corpsname);
2257 */
2258                             pline("%s\82Í\8fÁ\82¦\82½\81D", corpsname);
2259                         }
2260                     } else {
2261                         /* couldn't see corpse's location */
2262                         if (Role_if(PM_HEALER) && !Deaf
2263                             && !nonliving(&mons[corpsenm])) {
2264                             if (!type_is_pname(&mons[corpsenm]))
2265                                 corpsname = an(corpsname);
2266                             if (!Hallucination)
2267 /*JP
2268                                 You_hear("%s reviving.", corpsname);
2269 */
2270                                 You_hear("%s\82ª\90\82«\95Ô\82é\89¹\82ð\95·\82¢\82½\81D", corpsname);
2271                             else
2272 /*JP
2273                                 You_hear("a defibrillator.");
2274 */
2275                                 You_hear("\8f\9c\8d×\93®\8aí\82Ì\89¹\82ð\95·\82¢\82½\81D");
2276                             learn_it = TRUE;
2277                         }
2278                         if (canspotmon(mtmp))
2279                             /* didn't see corpse but do see monster: it
2280                                has been placed somewhere other than <ox,oy>
2281                                or blind hero spots it with ESP */
2282 /*JP
2283                             pline("%s appears.", Monnam(mtmp));
2284 */
2285                             pline("%s\82ª\8c»\82ê\82½\81D", Monnam(mtmp));
2286                     }
2287                     if (learn_it)
2288                         exercise(A_WIS, TRUE);
2289                 }
2290             }
2291             break;
2292         case WAN_OPENING:
2293         case SPE_KNOCK:
2294         case WAN_LOCKING:
2295         case SPE_WIZARD_LOCK:
2296             if (Is_box(obj))
2297                 res = boxlock(obj, otmp);
2298             else
2299                 res = 0;
2300             if (res)
2301                 learn_it = TRUE;
2302             break;
2303         case WAN_SLOW_MONSTER: /* no effect on objects */
2304         case SPE_SLOW_MONSTER:
2305         case WAN_SPEED_MONSTER:
2306         case WAN_NOTHING:
2307         case SPE_HEALING:
2308         case SPE_EXTRA_HEALING:
2309             res = 0;
2310             break;
2311         case SPE_STONE_TO_FLESH:
2312             res = stone_to_flesh_obj(obj);
2313             break;
2314         default:
2315             impossible("What an interesting effect (%d)", otmp->otyp);
2316             break;
2317         }
2318     /* if effect was observable then discover the wand type provided
2319        that the wand itself has been seen */
2320     if (learn_it)
2321         learnwand(otmp);
2322     return res;
2323 }
2324
2325 /* returns nonzero if something was hit */
2326 int
2327 bhitpile(obj, fhito, tx, ty, zz)
2328 struct obj *obj;
2329 int FDECL((*fhito), (OBJ_P, OBJ_P));
2330 int tx, ty;
2331 schar zz;
2332 {
2333     int hitanything = 0;
2334     register struct obj *otmp, *next_obj;
2335
2336     if (obj->otyp == SPE_FORCE_BOLT || obj->otyp == WAN_STRIKING) {
2337         struct trap *t = t_at(tx, ty);
2338
2339         /* We can't settle for the default calling sequence of
2340            bhito(otmp) -> break_statue(otmp) -> activate_statue_trap(ox,oy)
2341            because that last call might end up operating on our `next_obj'
2342            (below), rather than on the current object, if it happens to
2343            encounter a statue which mustn't become animated. */
2344         if (t && t->ttyp == STATUE_TRAP
2345             && activate_statue_trap(t, tx, ty, TRUE))
2346             learnwand(obj);
2347     }
2348
2349     poly_zapped = -1;
2350     for (otmp = level.objects[tx][ty]; otmp; otmp = next_obj) {
2351         next_obj = otmp->nexthere;
2352         /* for zap downwards, don't hit object poly'd hero is hiding under */
2353         if (zz > 0 && u.uundetected && otmp == level.objects[u.ux][u.uy]
2354             && hides_under(youmonst.data))
2355             continue;
2356
2357         hitanything += (*fhito)(otmp, obj);
2358     }
2359     if (poly_zapped >= 0)
2360         create_polymon(level.objects[tx][ty], poly_zapped);
2361
2362     return hitanything;
2363 }
2364
2365 /*
2366  * zappable - returns 1 if zap is available, 0 otherwise.
2367  *            it removes a charge from the wand if zappable.
2368  * added by GAN 11/03/86
2369  */
2370 int
2371 zappable(wand)
2372 register struct obj *wand;
2373 {
2374     if (wand->spe < 0 || (wand->spe == 0 && rn2(121)))
2375         return 0;
2376     if (wand->spe == 0)
2377 /*JP
2378         You("wrest one last charge from the worn-out wand.");
2379 */
2380         You("\8eg\82¢\82«\82Á\82½\8fñ\82©\82ç\8dÅ\8cã\82Ì\97Í\82ð\82µ\82Ú\82è\82Æ\82Á\82½\81D");
2381     wand->spe--;
2382     return 1;
2383 }
2384
2385 /*
2386  * zapnodir - zaps a NODIR wand/spell.
2387  * added by GAN 11/03/86
2388  */
2389 void
2390 zapnodir(obj)
2391 register struct obj *obj;
2392 {
2393     boolean known = FALSE;
2394
2395     switch (obj->otyp) {
2396     case WAN_LIGHT:
2397     case SPE_LIGHT:
2398         litroom(TRUE, obj);
2399         if (!Blind)
2400             known = TRUE;
2401         if (lightdamage(obj, TRUE, 5))
2402             known = TRUE;
2403         break;
2404     case WAN_SECRET_DOOR_DETECTION:
2405     case SPE_DETECT_UNSEEN:
2406         if (!findit())
2407             return;
2408         if (!Blind)
2409             known = TRUE;
2410         break;
2411     case WAN_CREATE_MONSTER:
2412         known = create_critters(rn2(23) ? 1 : rn1(7, 2),
2413                                 (struct permonst *) 0, FALSE);
2414         break;
2415     case WAN_WISHING:
2416         known = TRUE;
2417         if (Luck + rn2(5) < 0) {
2418 /*JP
2419             pline("Unfortunately, nothing happens.");
2420 */
2421             pline("\8ec\94O\82È\82ª\82ç\81C\89½\82à\8bN\82«\82È\82©\82Á\82½\81D");
2422             break;
2423         }
2424         makewish();
2425         break;
2426     case WAN_ENLIGHTENMENT:
2427         known = TRUE;
2428 /*JP
2429         You_feel("self-knowledgeable...");
2430 */
2431         You("\8e©\95ª\8e©\90g\82ª\94»\82é\82æ\82¤\82È\8bC\82ª\82µ\82½\81D\81D\81D");
2432         display_nhwindow(WIN_MESSAGE, FALSE);
2433         enlightenment(MAGICENLIGHTENMENT, ENL_GAMEINPROGRESS);
2434 /*JP
2435         pline_The("feeling subsides.");
2436 */
2437         pline("\82»\82Ì\8a´\82\82Í\82È\82­\82È\82Á\82½\81D");
2438         exercise(A_WIS, TRUE);
2439         break;
2440     }
2441     if (known) {
2442         if (!objects[obj->otyp].oc_name_known)
2443             more_experienced(0, 10);
2444         /* effect was observable; discover the wand type provided
2445            that the wand itself has been seen */
2446         learnwand(obj);
2447     }
2448 }
2449
2450 STATIC_OVL void
2451 backfire(otmp)
2452 struct obj *otmp;
2453 {
2454     int dmg;
2455
2456     otmp->in_use = TRUE; /* in case losehp() is fatal */
2457 /*JP
2458     pline("%s suddenly explodes!", The(xname(otmp)));
2459 */
2460     pline("%s\82Í\93Ë\91R\94\9a\94­\82µ\82½\81I", xname(otmp));
2461     dmg = d(otmp->spe + 2, 6);
2462 /*JP
2463     losehp(Maybe_Half_Phys(dmg), "exploding wand", KILLED_BY_AN);
2464 */
2465     losehp(Maybe_Half_Phys(dmg), "\8fñ\82Ì\94\9a\94­\82Å", KILLED_BY_AN);
2466     useup(otmp);
2467 }
2468
2469 static NEARDATA const char zap_syms[] = { WAND_CLASS, 0 };
2470
2471 /* 'z' command (or 'y' if numbed_pad==-1) */
2472 int
2473 dozap()
2474 {
2475     register struct obj *obj;
2476     int damage;
2477
2478     if (check_capacity((char *) 0))
2479         return 0;
2480     obj = getobj(zap_syms, "zap");
2481     if (!obj)
2482         return 0;
2483
2484     check_unpaid(obj);
2485
2486     /* zappable addition done by GAN 11/03/86 */
2487     if (!zappable(obj))
2488         pline1(nothing_happens);
2489     else if (obj->cursed && !rn2(WAND_BACKFIRE_CHANCE)) {
2490         backfire(obj); /* the wand blows up in your face! */
2491         exercise(A_STR, FALSE);
2492         return 1;
2493     } else if (!(objects[obj->otyp].oc_dir == NODIR) && !getdir((char *) 0)) {
2494         if (!Blind)
2495 /*JP
2496             pline("%s glows and fades.", The(xname(obj)));
2497 */
2498             pline("%s\82Í\88ê\8fu\8bP\82¢\82½\81D", The(xname(obj)));
2499         /* make him pay for knowing !NODIR */
2500     } else if (!u.dx && !u.dy && !u.dz
2501                && !(objects[obj->otyp].oc_dir == NODIR)) {
2502         if ((damage = zapyourself(obj, TRUE)) != 0) {
2503 #if 0 /*JP*/
2504             char buf[BUFSZ];
2505
2506             Sprintf(buf, "zapped %sself with a wand", uhim());
2507             losehp(Maybe_Half_Phys(damage), buf, NO_KILLER_PREFIX);
2508 #else
2509             losehp(Maybe_Half_Phys(damage),
2510                 "\8e©\95ª\8e©\90g\82Ì\8fñ\82Ì\97Í\82ð\97\81\82Ñ\82Ä", KILLED_BY);
2511 #endif
2512         }
2513     } else {
2514         /*      Are we having fun yet?
2515          * weffects -> buzz(obj->otyp) -> zhitm (temple priest) ->
2516          * attack -> hitum -> known_hitum -> ghod_hitsu ->
2517          * buzz(AD_ELEC) -> destroy_item(WAND_CLASS) ->
2518          * useup -> obfree -> dealloc_obj -> free(obj)
2519          */
2520         current_wand = obj;
2521         weffects(obj);
2522         obj = current_wand;
2523         current_wand = 0;
2524     }
2525     if (obj && obj->spe < 0) {
2526 /*JP
2527         pline("%s to dust.", Tobjnam(obj, "turn"));
2528 */
2529         pline("%s\82Í\82¿\82è\82Æ\82È\82Á\82½\81D", xname(obj));
2530         useup(obj);
2531     }
2532     update_inventory(); /* maybe used a charge */
2533     return 1;
2534 }
2535
2536 int
2537 zapyourself(obj, ordinary)
2538 struct obj *obj;
2539 boolean ordinary;
2540 {
2541     boolean learn_it = FALSE;
2542     int damage = 0;
2543
2544     switch (obj->otyp) {
2545     case WAN_STRIKING:
2546     case SPE_FORCE_BOLT:
2547         learn_it = TRUE;
2548         if (Antimagic) {
2549             shieldeff(u.ux, u.uy);
2550 /*JP
2551             pline("Boing!");
2552 */
2553             pline("\83{\83C\83\93\81I");
2554         } else {
2555             if (ordinary) {
2556 /*JP
2557                 You("bash yourself!");
2558 */
2559                 You("\8e©\95ª\8e©\90g\82ð\91Å\82¿\82Â\82¯\82½\81I");
2560                 damage = d(2, 12);
2561             } else
2562                 damage = d(1 + obj->spe, 6);
2563             exercise(A_STR, FALSE);
2564         }
2565         break;
2566
2567     case WAN_LIGHTNING:
2568         learn_it = TRUE;
2569         if (!Shock_resistance) {
2570 /*JP
2571             You("shock yourself!");
2572 */
2573             You("\93d\8c\82\82ð\82¤\82¯\82½\81I");
2574             damage = d(12, 6);
2575             exercise(A_CON, FALSE);
2576         } else {
2577             shieldeff(u.ux, u.uy);
2578 /*JP
2579             You("zap yourself, but seem unharmed.");
2580 */
2581             You("\8e©\95ª\82É\8fñ\82ð\82Ó\82è\82©\82´\82µ\82½\82ª\81C\89ö\89ä\82Í\82µ\82È\82©\82Á\82½\82æ\82¤\82¾\81D");
2582             ugolemeffects(AD_ELEC, d(12, 6));
2583         }
2584         destroy_item(WAND_CLASS, AD_ELEC);
2585         destroy_item(RING_CLASS, AD_ELEC);
2586         (void) flashburn((long) rnd(100));
2587         break;
2588
2589     case SPE_FIREBALL:
2590 /*JP
2591         You("explode a fireball on top of yourself!");
2592 */
2593         Your("\93ª\8fã\82Å\89Î\82Ì\8bÊ\82ª\94\9a\94­\82µ\82½\81I");
2594         explode(u.ux, u.uy, 11, d(6, 6), WAND_CLASS, EXPL_FIERY);
2595         break;
2596     case WAN_FIRE:
2597     case FIRE_HORN:
2598         learn_it = TRUE;
2599         if (Fire_resistance) {
2600             shieldeff(u.ux, u.uy);
2601 /*JP
2602             You_feel("rather warm.");
2603 */
2604             You("\82¿\82å\82Á\82Æ\92g\82©\82­\8a´\82\82½\81D");
2605             ugolemeffects(AD_FIRE, d(12, 6));
2606         } else {
2607 /*JP
2608             pline("You've set yourself afire!");
2609 */
2610             You("\89\8a\82É\82Â\82Â\82Ü\82ê\82½\81I");
2611             damage = d(12, 6);
2612         }
2613         burn_away_slime();
2614         (void) burnarmor(&youmonst);
2615         destroy_item(SCROLL_CLASS, AD_FIRE);
2616         destroy_item(POTION_CLASS, AD_FIRE);
2617         destroy_item(SPBOOK_CLASS, AD_FIRE);
2618         destroy_item(FOOD_CLASS, AD_FIRE); /* only slime for now */
2619         break;
2620
2621     case WAN_COLD:
2622     case SPE_CONE_OF_COLD:
2623     case FROST_HORN:
2624         learn_it = TRUE;
2625         if (Cold_resistance) {
2626             shieldeff(u.ux, u.uy);
2627 /*JP
2628             You_feel("a little chill.");
2629 */
2630             You("\82¿\82å\82Á\82Æ\97â\82½\82­\8a´\82\82½\81D");
2631             ugolemeffects(AD_COLD, d(12, 6));
2632         } else {
2633 /*JP
2634             You("imitate a popsicle!");
2635 */
2636             You("\83A\83C\83X\83L\83\83\83\93\83f\81[\82Ì\82æ\82¤\82É\82È\82Á\82½\81I");
2637             damage = d(12, 6);
2638         }
2639         destroy_item(POTION_CLASS, AD_COLD);
2640         break;
2641
2642     case WAN_MAGIC_MISSILE:
2643     case SPE_MAGIC_MISSILE:
2644         learn_it = TRUE;
2645         if (Antimagic) {
2646             shieldeff(u.ux, u.uy);
2647 /*JP
2648             pline_The("missiles bounce!");
2649 */
2650             pline("\96\82\96@\82Ì\96î\82Í\82Í\82Ë\82©\82¦\82Á\82½\81I");
2651         } else {
2652             damage = d(4, 6);
2653 /*JP
2654             pline("Idiot!  You've shot yourself!");
2655 */
2656             pline("\89½\82â\82Á\82Ä\82ñ\82¾\81I\82 \82È\82½\82Í\8e©\95ª\8e©\90g\82ð\8c\82\82Á\82½\81I");
2657         }
2658         break;
2659
2660     case WAN_POLYMORPH:
2661     case SPE_POLYMORPH:
2662         if (!Unchanging) {
2663             learn_it = TRUE;
2664             polyself(0);
2665         }
2666         break;
2667
2668     case WAN_CANCELLATION:
2669     case SPE_CANCELLATION:
2670         (void) cancel_monst(&youmonst, obj, TRUE, TRUE, TRUE);
2671         break;
2672
2673     case SPE_DRAIN_LIFE:
2674         if (!Drain_resistance) {
2675             learn_it = TRUE; /* (no effect for spells...) */
2676 /*JP
2677             losexp("life drainage");
2678 */
2679             losexp("\90\96½\97Í\82ð\8bz\8eû\82³\82ê\82Ä");
2680         }
2681         damage = 0; /* No additional damage */
2682         break;
2683
2684     case WAN_MAKE_INVISIBLE: {
2685         /* have to test before changing HInvis but must change
2686          * HInvis before doing newsym().
2687          */
2688         int msg = !Invis && !Blind && !BInvis;
2689
2690         if (BInvis && uarmc->otyp == MUMMY_WRAPPING) {
2691             /* A mummy wrapping absorbs it and protects you */
2692 /*JP
2693             You_feel("rather itchy under %s.", yname(uarmc));
2694 */
2695             You("%s\82Ì\89º\82ª\83\80\83Y\83\80\83Y\82µ\82½\81D", xname(uarmc));
2696             break;
2697         }
2698         if (ordinary || !rn2(10)) { /* permanent */
2699             HInvis |= FROMOUTSIDE;
2700         } else { /* temporary */
2701             incr_itimeout(&HInvis, d(obj->spe, 250));
2702         }
2703         if (msg) {
2704             learn_it = TRUE;
2705             newsym(u.ux, u.uy);
2706             self_invis_message();
2707         }
2708         break;
2709     }
2710
2711     case WAN_SPEED_MONSTER:
2712         if (!(HFast & INTRINSIC)) {
2713             learn_it = TRUE;
2714             if (!Fast)
2715 /*JP
2716                 You("speed up.");
2717 */
2718                 You("\93®\82«\82ª\91¬\82­\82È\82Á\82½\81D");
2719             else
2720 /*JP
2721                 Your("quickness feels more natural.");
2722 */
2723                 You("\91¬\82³\82É\8aµ\82ê\82Ä\82«\82½\81D");
2724             exercise(A_DEX, TRUE);
2725         }
2726         HFast |= FROMOUTSIDE;
2727         break;
2728
2729     case WAN_SLEEP:
2730     case SPE_SLEEP:
2731         learn_it = TRUE;
2732         if (Sleep_resistance) {
2733             shieldeff(u.ux, u.uy);
2734 /*JP
2735             You("don't feel sleepy!");
2736 */
2737             You("\96°\82­\82È\82ç\82È\82¢\81I");
2738         } else {
2739 /*JP
2740             pline_The("sleep ray hits you!");
2741 */
2742             pline("\96°\82è\8cõ\90ü\82ª\82 \82È\82½\82É\96½\92\86\82µ\82½\81I");
2743             fall_asleep(-rnd(50), TRUE);
2744         }
2745         break;
2746
2747     case WAN_SLOW_MONSTER:
2748     case SPE_SLOW_MONSTER:
2749         if (HFast & (TIMEOUT | INTRINSIC)) {
2750             learn_it = TRUE;
2751             u_slow_down();
2752         }
2753         break;
2754
2755     case WAN_TELEPORTATION:
2756     case SPE_TELEPORT_AWAY:
2757         tele();
2758         /* same criteria as when mounted (zap_steed) */
2759         if ((Teleport_control && !Stunned) || !couldsee(u.ux0, u.uy0)
2760             || distu(u.ux0, u.uy0) >= 16)
2761             learn_it = TRUE;
2762         break;
2763
2764     case WAN_DEATH:
2765     case SPE_FINGER_OF_DEATH:
2766         if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
2767             pline((obj->otyp == WAN_DEATH)
2768 /*JP
2769                       ? "The wand shoots an apparently harmless beam at you."
2770 */
2771                       ? "\8fñ\82Ì\8cõ\90ü\82Í\82Ç\82¤\82â\82ç\82 \82È\82½\82É\89e\8b¿\82ð\97^\82¦\82È\82¢\82à\82Ì\82Ì\82æ\82¤\82¾\81D"
2772 /*JP
2773                       : "You seem no deader than before.");
2774 */
2775                       : "\82 \82È\82½\82Í\82±\82ê\88È\8fã\8e\80\82Ë\82È\82¢\82æ\82¤\82¾\81D");
2776             break;
2777         }
2778         learn_it = TRUE;
2779 #if 0 /*JP*/
2780         Sprintf(killer.name, "shot %sself with a death ray", uhim());
2781         killer.format = NO_KILLER_PREFIX;
2782 #else
2783         Strcpy(killer.name, "\8e©\95ª\82ª\8c\82\82Á\82½\8e\80\82Ì\8cõ\90ü\82É\82æ\82Á\82Ä");
2784         killer.format = KILLED_BY;
2785 #endif
2786 /*JP
2787         You("irradiate yourself with pure energy!");
2788 */
2789         You("\83G\83l\83\8b\83M\81[\82ð\8e©\95ª\8e©\90g\82É\8fÆ\8eË\82µ\82½\81D");
2790 /*JP
2791         You("die.");
2792 */
2793         pline("\82 \82È\82½\82Í\8e\80\82É\82Ü\82µ\82½\81D");
2794         /* They might survive with an amulet of life saving */
2795         done(DIED);
2796         break;
2797     case WAN_UNDEAD_TURNING:
2798     case SPE_TURN_UNDEAD:
2799         learn_it = TRUE;
2800         (void) unturn_dead(&youmonst);
2801         if (is_undead(youmonst.data)) {
2802 #if 0 /*JP:T*/
2803             You_feel("frightened and %sstunned.",
2804                      Stunned ? "even more " : "");
2805 #else
2806             You("\8b°\95|\82µ%s\82­\82ç\82­\82ç\82µ\82½\81D",
2807                 Stunned ? "\82³\82ç\82É" : "");
2808 #endif
2809             make_stunned((HStun & TIMEOUT) + (long) rnd(30), FALSE);
2810         } else
2811 /*JP
2812             You("shudder in dread.");
2813 */
2814             You("\8b°\95|\82Å\90k\82¦\82½\81D");
2815         break;
2816     case SPE_HEALING:
2817     case SPE_EXTRA_HEALING:
2818         learn_it = TRUE; /* (no effect for spells...) */
2819         healup(d(6, obj->otyp == SPE_EXTRA_HEALING ? 8 : 4), 0, FALSE,
2820                (obj->blessed || obj->otyp == SPE_EXTRA_HEALING));
2821 /*JP
2822         You_feel("%sbetter.", obj->otyp == SPE_EXTRA_HEALING ? "much " : "");
2823 */
2824         You("%s\8bC\95ª\82ª\82æ\82­\82È\82Á\82½\81D", obj->otyp == SPE_EXTRA_HEALING ? "\82Æ\82Ä\82à" : "");
2825         break;
2826     case WAN_LIGHT: /* (broken wand) */
2827         /* assert( !ordinary ); */
2828         damage = d(obj->spe, 25);
2829         /*FALLTHRU*/
2830     case EXPENSIVE_CAMERA:
2831         if (!damage)
2832             damage = 5;
2833         damage = lightdamage(obj, ordinary, damage);
2834         damage += rnd(25);
2835         if (flashburn((long) damage))
2836             learn_it = TRUE;
2837         damage = 0; /* reset */
2838         break;
2839     case WAN_OPENING:
2840     case SPE_KNOCK:
2841         if (Punished) {
2842             learn_it = TRUE;
2843             unpunish();
2844         }
2845         /* invent is hit iff hero doesn't escape from a trap */
2846         if (!u.utrap || !openholdingtrap(&youmonst, &learn_it)) {
2847             struct obj *otmp;
2848             boolean boxing = FALSE;
2849
2850             /* unlock carried boxes */
2851             for (otmp = invent; otmp; otmp = otmp->nobj)
2852                 if (Is_box(otmp)) {
2853                     (void) boxlock(otmp, obj);
2854                     boxing = TRUE;
2855                 }
2856             if (boxing)
2857                 update_inventory(); /* in case any box->lknown has changed */
2858
2859             /* trigger previously escaped trapdoor */
2860             (void) openfallingtrap(&youmonst, TRUE, &learn_it);
2861         }
2862         break;
2863     case WAN_LOCKING:
2864     case SPE_WIZARD_LOCK:
2865         /* similar logic to opening; invent is hit iff no trap triggered */
2866         if (u.utrap || !closeholdingtrap(&youmonst, &learn_it)) {
2867             struct obj *otmp;
2868             boolean boxing = FALSE;
2869
2870             /* lock carried boxes */
2871             for (otmp = invent; otmp; otmp = otmp->nobj)
2872                 if (Is_box(otmp)) {
2873                     (void) boxlock(otmp, obj);
2874                     boxing = TRUE;
2875                 }
2876             if (boxing)
2877                 update_inventory(); /* in case any box->lknown has changed */
2878         }
2879         break;
2880     case WAN_DIGGING:
2881     case SPE_DIG:
2882     case SPE_DETECT_UNSEEN:
2883     case WAN_NOTHING:
2884         break;
2885     case WAN_PROBING: {
2886         struct obj *otmp;
2887
2888         for (otmp = invent; otmp; otmp = otmp->nobj) {
2889             otmp->dknown = 1;
2890             if (Is_container(otmp) || otmp->otyp == STATUE) {
2891                 otmp->lknown = 1;
2892                 if (!SchroedingersBox(otmp))
2893                     otmp->cknown = 1;
2894             }
2895         }
2896         update_inventory();
2897         learn_it = TRUE;
2898         ustatusline();
2899         break;
2900     }
2901     case SPE_STONE_TO_FLESH: {
2902         struct obj *otmp, *onxt;
2903         boolean didmerge;
2904
2905         if (u.umonnum == PM_STONE_GOLEM) {
2906             learn_it = TRUE;
2907             (void) polymon(PM_FLESH_GOLEM);
2908         }
2909         if (Stoned) {
2910             learn_it = TRUE;
2911             fix_petrification(); /* saved! */
2912         }
2913         /* but at a cost.. */
2914         for (otmp = invent; otmp; otmp = onxt) {
2915             onxt = otmp->nobj;
2916             if (bhito(otmp, obj))
2917                 learn_it = TRUE;
2918         }
2919         /*
2920          * It is possible that we can now merge some inventory.
2921          * Do a highly paranoid merge.  Restart from the beginning
2922          * until no merges.
2923          */
2924         do {
2925             didmerge = FALSE;
2926             for (otmp = invent; !didmerge && otmp; otmp = otmp->nobj)
2927                 for (onxt = otmp->nobj; onxt; onxt = onxt->nobj)
2928                     if (merged(&otmp, &onxt)) {
2929                         didmerge = TRUE;
2930                         break;
2931                     }
2932         } while (didmerge);
2933         break;
2934     }
2935     default:
2936         impossible("zapyourself: object %d used?", obj->otyp);
2937         break;
2938     }
2939     /* if effect was observable then discover the wand type provided
2940        that the wand itself has been seen */
2941     if (learn_it)
2942         learnwand(obj);
2943     return damage;
2944 }
2945
2946 /* called when poly'd hero uses breath attack against self */
2947 void
2948 ubreatheu(mattk)
2949 struct attack *mattk;
2950 {
2951     int dtyp = 20 + mattk->adtyp - 1;      /* breath by hero */
2952     const char *fltxt = flash_types[dtyp]; /* blast of <something> */
2953
2954     zhitu(dtyp, mattk->damn, fltxt, u.ux, u.uy);
2955 }
2956
2957 /* light damages hero in gremlin form */
2958 int
2959 lightdamage(obj, ordinary, amt)
2960 struct obj *obj;  /* item making light (fake book if spell) */
2961 boolean ordinary; /* wand/camera zap vs wand destruction */
2962 int amt;          /* pseudo-damage used to determine blindness duration */
2963 {
2964     char buf[BUFSZ];
2965     const char *how;
2966     int dmg = amt;
2967
2968     if (dmg && youmonst.data == &mons[PM_GREMLIN]) {
2969         /* reduce high values (from destruction of wand with many charges) */
2970         dmg = rnd(dmg);
2971         if (dmg > 10)
2972             dmg = 10 + rnd(dmg - 10);
2973         if (dmg > 20)
2974             dmg = 20;
2975 /*JP
2976         pline("Ow, that light hurts%c", (dmg > 2 || u.mh <= 5) ? '!' : '.');
2977 */
2978         pline("\82¨\82í\81C\8cõ\82ª\92É\82¢%s", (dmg > 2 || u.mh <= 5) ? "\81I" : "\81D");
2979         /* [composing killer/reason is superfluous here; if fatal, cause
2980            of death will always be "killed while stuck in creature form"] */
2981 #if 0 /*JP*/
2982         if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS)
2983             ordinary = FALSE; /* say blasted rather than zapped */
2984 #endif
2985         how = (obj->oclass != SPBOOK_CLASS)
2986                   ? (const char *) ansimpleoname(obj)
2987 /*JP
2988                   : "spell of light";
2989 */
2990                   : "\8cõ\82Ì\96\82\96@";
2991 #if 0 /*JP*/
2992         Sprintf(buf, "%s %sself with %s", ordinary ? "zapped" : "blasted",
2993                 uhim(), how);
2994 #else
2995         Sprintf(buf, "\8e©\95ª\82Å%s\82ð\97\81\82Ñ\82Ä", how);
2996 #endif
2997         /* might rehumanize(); could be fatal, but only for Unchanging */
2998 #if 0 /*JP*/
2999         losehp(Maybe_Half_Phys(dmg), buf, NO_KILLER_PREFIX);
3000 #else
3001         losehp(Maybe_Half_Phys(dmg), buf, KILLED_BY);
3002 #endif
3003     }
3004     return dmg;
3005 }
3006
3007 /* light[ning] causes blindness */
3008 boolean
3009 flashburn(duration)
3010 long duration;
3011 {
3012     if (!resists_blnd(&youmonst)) {
3013         You(are_blinded_by_the_flash);
3014         make_blinded(duration, FALSE);
3015         if (!Blind)
3016             Your1(vision_clears);
3017         return TRUE;
3018     }
3019     return FALSE;
3020 }
3021
3022 /* you've zapped a wand downwards while riding
3023  * Return TRUE if the steed was hit by the wand.
3024  * Return FALSE if the steed was not hit by the wand.
3025  */
3026 STATIC_OVL boolean
3027 zap_steed(obj)
3028 struct obj *obj; /* wand or spell */
3029 {
3030     int steedhit = FALSE;
3031
3032     bhitpos.x = u.usteed->mx, bhitpos.y = u.usteed->my;
3033     notonhead = FALSE;
3034     switch (obj->otyp) {
3035     /*
3036      * Wands that are allowed to hit the steed
3037      * Carefully test the results of any that are
3038      * moved here from the bottom section.
3039      */
3040     case WAN_PROBING:
3041         probe_monster(u.usteed);
3042         learnwand(obj);
3043         steedhit = TRUE;
3044         break;
3045     case WAN_TELEPORTATION:
3046     case SPE_TELEPORT_AWAY:
3047         /* you go together */
3048         tele();
3049         /* same criteria as when unmounted (zapyourself) */
3050         if ((Teleport_control && !Stunned) || !couldsee(u.ux0, u.uy0)
3051             || distu(u.ux0, u.uy0) >= 16)
3052             learnwand(obj);
3053         steedhit = TRUE;
3054         break;
3055
3056     /* Default processing via bhitm() for these */
3057     case SPE_CURE_SICKNESS:
3058     case WAN_MAKE_INVISIBLE:
3059     case WAN_CANCELLATION:
3060     case SPE_CANCELLATION:
3061     case WAN_POLYMORPH:
3062     case SPE_POLYMORPH:
3063     case WAN_STRIKING:
3064     case SPE_FORCE_BOLT:
3065     case WAN_SLOW_MONSTER:
3066     case SPE_SLOW_MONSTER:
3067     case WAN_SPEED_MONSTER:
3068     case SPE_HEALING:
3069     case SPE_EXTRA_HEALING:
3070     case SPE_DRAIN_LIFE:
3071     case WAN_OPENING:
3072     case SPE_KNOCK:
3073         (void) bhitm(u.usteed, obj);
3074         steedhit = TRUE;
3075         break;
3076
3077     default:
3078         steedhit = FALSE;
3079         break;
3080     }
3081     return steedhit;
3082 }
3083
3084 /*
3085  * cancel a monster (possibly the hero).  inventory is cancelled only
3086  * if the monster is zapping itself directly, since otherwise the
3087  * effect is too strong.  currently non-hero monsters do not zap
3088  * themselves with cancellation.
3089  */
3090 boolean
3091 cancel_monst(mdef, obj, youattack, allow_cancel_kill, self_cancel)
3092 register struct monst *mdef;
3093 register struct obj *obj;
3094 boolean youattack, allow_cancel_kill, self_cancel;
3095 {
3096     boolean youdefend = (mdef == &youmonst);
3097     static const char writing_vanishes[] =
3098 /*JP
3099         "Some writing vanishes from %s head!";
3100 */
3101         "\89½\82©\82Ì\95\8e\9a\82ª%s\82Ì\93ª\82©\82ç\8fÁ\82¦\82½\81I";
3102 #if 0 /*JP:T*/
3103     static const char your[] = "your"; /* should be extern */
3104 #else
3105     static const char your[] = "\82 \82È\82½"; /* should be extern */
3106 #endif
3107
3108     if (youdefend ? (!youattack && Antimagic)
3109                   : resist(mdef, obj->oclass, 0, NOTELL))
3110         return FALSE; /* resisted cancellation */
3111
3112     if (self_cancel) { /* 1st cancel inventory */
3113         struct obj *otmp;
3114
3115         for (otmp = (youdefend ? invent : mdef->minvent); otmp;
3116              otmp = otmp->nobj)
3117             cancel_item(otmp);
3118         if (youdefend) {
3119             context.botl = 1; /* potential AC change */
3120             find_ac();
3121         }
3122     }
3123
3124     /* now handle special cases */
3125     if (youdefend) {
3126         if (Upolyd) { /* includes lycanthrope in creature form */
3127             /*
3128              * Return to normal form unless Unchanging.
3129              * Hero in clay golem form dies if Unchanging.
3130              * Does not cure lycanthropy or stop timed random polymorph.
3131              */
3132             if (u.umonnum == PM_CLAY_GOLEM) {
3133                 if (!Blind)
3134                     pline(writing_vanishes, your);
3135                 else /* note: "dark" rather than "heavy" is intentional... */
3136 #if 0 /*JP*/
3137                     You_feel("%s headed.", Hallucination ? "dark" : "light");
3138 #else /*\82¢\82¢\96ó\8cê\82ð\8ev\82¢\82Â\82©\82È\82¢\82Ì\82Å\8c\8ao\82Å\83\81\83b\83Z\81[\83W\82ð\95Ï\82¦\82È\82¢ */
3139                     You_feel("\8cy\82Í\82¸\82Ý\82¾\82Á\82½\8bC\82ª\82µ\82½\81D");
3140 #endif
3141                 u.mh = 0; /* fatal; death handled by rehumanize() */
3142             }
3143             if (Unchanging && u.mh > 0)
3144 /*JP
3145                 Your("amulet grows hot for a moment, then cools.");
3146 */
3147                 Your("\96\82\8f\9c\82¯\82Í\82µ\82Î\82ç\82­\94M\82­\82È\82è\81C\82â\82ª\82Ä\8c³\82É\96ß\82Á\82½\81D");
3148             else
3149                 rehumanize();
3150         }
3151     } else {
3152         mdef->mcan = 1;
3153         /* force shapeshifter into its base form */
3154         if (M_AP_TYPE(mdef) != M_AP_NOTHING)
3155             seemimic(mdef);
3156         /* [not 'else if'; chameleon might have been hiding as a mimic] */
3157         if (mdef->cham >= LOW_PM) {
3158             /* note: newcham() uncancels shapechangers (resets m->mcan
3159                to 0), but only for shapechangers whose m->cham is already
3160                NON_PM and we just verified that it's LOW_PM or higher */
3161             newcham(mdef, &mons[mdef->cham], FALSE, FALSE);
3162             mdef->cham = NON_PM; /* cancelled shapeshifter can't shift */
3163         }
3164         if (is_were(mdef->data) && !is_human(mdef->data))
3165             were_change(mdef);
3166
3167         if (mdef->data == &mons[PM_CLAY_GOLEM]) {
3168             if (canseemon(mdef))
3169 #if 0 /*JP*/
3170                 pline(writing_vanishes, s_suffix(mon_nam(mdef)));
3171 #else
3172                 pline(writing_vanishes, mon_nam(mdef));
3173 #endif
3174             /* !allow_cancel_kill is for Magicbane, where clay golem
3175                will be killed somewhere back up the call/return chain... */
3176             if (allow_cancel_kill) {
3177                 if (youattack)
3178                     killed(mdef);
3179                 else
3180                     monkilled(mdef, "", AD_SPEL);
3181             }
3182         }
3183     }
3184     return TRUE;
3185 }
3186
3187 /* you've zapped an immediate type wand up or down */
3188 STATIC_OVL boolean
3189 zap_updown(obj)
3190 struct obj *obj; /* wand or spell */
3191 {
3192     boolean striking = FALSE, disclose = FALSE;
3193     int x, y, xx, yy, ptmp;
3194     struct obj *otmp;
3195     struct engr *e;
3196     struct trap *ttmp;
3197     char buf[BUFSZ];
3198
3199     /* some wands have special effects other than normal bhitpile */
3200     /* drawbridge might change <u.ux,u.uy> */
3201     x = xx = u.ux;     /* <x,y> is zap location */
3202     y = yy = u.uy;     /* <xx,yy> is drawbridge (portcullis) position */
3203     ttmp = t_at(x, y); /* trap if there is one */
3204
3205     switch (obj->otyp) {
3206     case WAN_PROBING:
3207         ptmp = 0;
3208         if (u.dz < 0) {
3209 /*JP
3210             You("probe towards the %s.", ceiling(x, y));
3211 */
3212             You("\8fã\95û\82Ì%s\82ð\92²\82×\82½\81D", ceiling(x,y));
3213         } else {
3214             ptmp += bhitpile(obj, bhito, x, y, u.dz);
3215 /*JP
3216             You("probe beneath the %s.", surface(x, y));
3217 */
3218             You("\89º\95û\82Ì%s\82ð\92²\82×\82½\81D", surface(x,y));
3219             ptmp += display_binventory(x, y, TRUE);
3220         }
3221         if (!ptmp)
3222 /*JP
3223             Your("probe reveals nothing.");
3224 */
3225             pline("\92²\8d¸\82Ì\8c\8b\89Ê\89½\82à\82Å\82Ä\82±\82È\82©\82Á\82½\81D");
3226         return TRUE; /* we've done our own bhitpile */
3227     case WAN_OPENING:
3228     case SPE_KNOCK:
3229         /* up or down, but at closed portcullis only */
3230         if (is_db_wall(x, y) && find_drawbridge(&xx, &yy)) {
3231             open_drawbridge(xx, yy);
3232             disclose = TRUE;
3233         } else if (u.dz > 0 && (x == xdnstair && y == ydnstair)
3234                    /* can't use the stairs down to quest level 2 until
3235                       leader "unlocks" them; give feedback if you try */
3236                    && on_level(&u.uz, &qstart_level) && !ok_to_quest()) {
3237 /*JP
3238             pline_The("stairs seem to ripple momentarily.");
3239 */
3240             pline("\8aK\92i\82ª\88ê\8fu\97h\82ê\82½\82æ\82¤\82É\8c©\82¦\82½\81D");
3241             disclose = TRUE;
3242         }
3243         /* down will release you from bear trap or web */
3244         if (u.dz > 0 && u.utrap) {
3245             (void) openholdingtrap(&youmonst, &disclose);
3246             /* down will trigger trapdoor, hole, or [spiked-] pit */
3247         } else if (u.dz > 0 && !u.utrap) {
3248             (void) openfallingtrap(&youmonst, FALSE, &disclose);
3249         }
3250         break;
3251     case WAN_STRIKING:
3252     case SPE_FORCE_BOLT:
3253         striking = TRUE;
3254         /*FALLTHRU*/
3255     case WAN_LOCKING:
3256     case SPE_WIZARD_LOCK:
3257         /* down at open bridge or up or down at open portcullis */
3258         if (((levl[x][y].typ == DRAWBRIDGE_DOWN)
3259                  ? (u.dz > 0)
3260                  : (is_drawbridge_wall(x, y) >= 0 && !is_db_wall(x, y)))
3261             && find_drawbridge(&xx, &yy)) {
3262             if (!striking)
3263                 close_drawbridge(xx, yy);
3264             else
3265                 destroy_drawbridge(xx, yy);
3266             disclose = TRUE;
3267         } else if (striking && u.dz < 0 && rn2(3) && !Is_airlevel(&u.uz)
3268                    && !Is_waterlevel(&u.uz) && !Underwater
3269                    && !Is_qstart(&u.uz)) {
3270             int dmg;
3271             /* similar to zap_dig() */
3272 #if 0 /*JP:T*/
3273             pline("A rock is dislodged from the %s and falls on your %s.",
3274                   ceiling(x, y), body_part(HEAD));
3275 #else
3276             pline("%s\82©\82ç\8aâ\82ª\97\8e\82¿\82Ä\82 \82È\82½\82Ì%s\82É\96½\92\86\82µ\82½\81D",
3277                   ceiling(x, y), body_part(HEAD));
3278 #endif
3279             dmg = rnd((uarmh && is_metallic(uarmh)) ? 2 : 6);
3280 /*JP
3281             losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
3282 */
3283             losehp(Maybe_Half_Phys(dmg), "\97\8e\8aâ\82Å", KILLED_BY_AN);
3284             if ((otmp = mksobj_at(ROCK, x, y, FALSE, FALSE)) != 0) {
3285                 (void) xname(otmp); /* set dknown, maybe bknown */
3286                 stackobj(otmp);
3287             }
3288             newsym(x, y);
3289         } else if (u.dz > 0 && ttmp) {
3290             if (!striking && closeholdingtrap(&youmonst, &disclose)) {
3291                 ; /* now stuck in web or bear trap */
3292             } else if (striking && ttmp->ttyp == TRAPDOOR) {
3293                 /* striking transforms trapdoor into hole */
3294                 if (Blind && !ttmp->tseen) {
3295 /*JP
3296                     pline("%s beneath you shatters.", Something);
3297 */
3298                     pline("\82 \82È\82½\82Ì\89º\82É\82 \82é\89½\82©\82ª\82±\82È\82²\82È\82É\82È\82Á\82½\81D");
3299                 } else if (!ttmp->tseen) { /* => !Blind */
3300 /*JP
3301                     pline("There's a trapdoor beneath you; it shatters.");
3302 */
3303                     pline("\82 \82È\82½\82Ì\89º\82É\82Í\97\8e\82µ\94à\82ª\82 \82Á\82½\81G\82»\82ê\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D");
3304                 } else {
3305 /*JP
3306                     pline("The trapdoor beneath you shatters.");
3307 */
3308                     pline("\82 \82È\82½\82Ì\89º\82É\82 \82é\97\8e\82µ\94à\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D");
3309                     disclose = TRUE;
3310                 }
3311                 ttmp->ttyp = HOLE;
3312                 ttmp->tseen = 1;
3313                 newsym(x, y);
3314                 /* might fall down hole */
3315                 dotrap(ttmp, 0);
3316             } else if (!striking && ttmp->ttyp == HOLE) {
3317                 /* locking transforms hole into trapdoor */
3318                 ttmp->ttyp = TRAPDOOR;
3319                 if (Blind || !ttmp->tseen) {
3320 #if 0 /*JP:T*/
3321                     pline("Some %s swirls beneath you.",
3322                           is_ice(x, y) ? "frost" : "dust");
3323 #else
3324                     pline("\82 \82È\82½\82Ì\89º\82Å%s\82ª\82¤\82¸\82ð\8aª\82­\82Ì\82ª\8c©\82¦\82½\81D",
3325                           is_ice(x,y) ? "\91\9a" : "\82Ù\82±\82è");
3326 #endif
3327                 } else {
3328                     ttmp->tseen = 1;
3329                     newsym(x, y);
3330 /*JP
3331                     pline("A trapdoor appears beneath you.");
3332 */
3333                     pline("\82 \82È\82½\82Ì\89º\82É\97\8e\82µ\94à\82ª\82 \82ç\82í\82ê\82½\81D");
3334                     disclose = TRUE;
3335                 }
3336                 /* hadn't fallen down hole; won't fall now */
3337             }
3338         }
3339         break;
3340     case SPE_STONE_TO_FLESH:
3341         if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) || Underwater
3342             || (Is_qstart(&u.uz) && u.dz < 0)) {
3343             pline1(nothing_happens);
3344         } else if (u.dz < 0) { /* we should do more... */
3345 /*JP
3346             pline("Blood drips on your %s.", body_part(FACE));
3347 */
3348             pline("\8c\8c\82ª\82 \82È\82½\82Ì%s\82Ö\82µ\82½\82½\82è\97\8e\82¿\82Ä\82«\82½\81D", body_part(FACE));
3349         } else if (u.dz > 0 && !OBJ_AT(u.ux, u.uy)) {
3350             /*
3351             Print this message only if there wasn't an engraving
3352             affected here.  If water or ice, act like waterlevel case.
3353             */
3354             e = engr_at(u.ux, u.uy);
3355             if (!(e && e->engr_type == ENGRAVE)) {
3356                 if (is_pool(u.ux, u.uy) || is_ice(u.ux, u.uy))
3357                     pline1(nothing_happens);
3358                 else
3359 #if 0 /*JP:T*/
3360                     pline("Blood %ss %s your %s.",
3361                           is_lava(u.ux, u.uy) ? "boil" : "pool",
3362                           Levitation ? "beneath" : "at",
3363                           makeplural(body_part(FOOT)));
3364 #else
3365                     pline("%s%s%s\81D",
3366                           makeplural(body_part(FOOT)),
3367                           Levitation ? "\82Ì\89º" : "\8c³",
3368                           is_lava(u.ux, u.uy) ?
3369                           "\82Å\8c\8c\82ª\95¦\93«\82µ\82½" : "\82É\8c\8c\82¾\82Ü\82è\82ª\8fo\97\88\82½");
3370 #endif
3371             }
3372         }
3373         break;
3374     default:
3375         break;
3376     }
3377
3378     if (u.dz > 0) {
3379         /* zapping downward */
3380         (void) bhitpile(obj, bhito, x, y, u.dz);
3381
3382         /* subset of engraving effects; none sets `disclose' */
3383         if ((e = engr_at(x, y)) != 0 && e->engr_type != HEADSTONE) {
3384             switch (obj->otyp) {
3385             case WAN_POLYMORPH:
3386             case SPE_POLYMORPH:
3387                 del_engr(e);
3388                 make_engr_at(x, y, random_engraving(buf), moves, (xchar) 0);
3389                 break;
3390             case WAN_CANCELLATION:
3391             case SPE_CANCELLATION:
3392             case WAN_MAKE_INVISIBLE:
3393                 del_engr(e);
3394                 break;
3395             case WAN_TELEPORTATION:
3396             case SPE_TELEPORT_AWAY:
3397                 rloc_engr(e);
3398                 break;
3399             case SPE_STONE_TO_FLESH:
3400                 if (e->engr_type == ENGRAVE) {
3401                     /* only affects things in stone */
3402 #if 0 /*JP:T*/
3403                     pline_The(Hallucination
3404                                   ? "floor runs like butter!"
3405                                   : "edges on the floor get smoother.");
3406 #else
3407                     pline(Hallucination
3408                                   ? "\8f°\82ª\83o\83^\81[\82Ì\82æ\82¤\82É\91\96\82Á\82Ä\82¢\82Á\82½\81I"
3409                                   : "\8f°\82Ì\89\8f\82ª\82È\82ß\82ç\82©\82É\82È\82Á\82½\81D");
3410 #endif
3411                     wipe_engr_at(x, y, d(2, 4), TRUE);
3412                 }
3413                 break;
3414             case WAN_STRIKING:
3415             case SPE_FORCE_BOLT:
3416                 wipe_engr_at(x, y, d(2, 4), TRUE);
3417                 break;
3418             default:
3419                 break;
3420             }
3421         }
3422     } else if (u.dz < 0) {
3423         /* zapping upward */
3424
3425         /* game flavor: if you're hiding under "something"
3426          * a zap upward should hit that "something".
3427          */
3428         if (u.uundetected && hides_under(youmonst.data)) {
3429             int hitit = 0;
3430             otmp = level.objects[u.ux][u.uy];
3431
3432             if (otmp)
3433                 hitit = bhito(otmp, obj);
3434             if (hitit) {
3435                 (void) hideunder(&youmonst);
3436                 disclose = TRUE;
3437             }
3438         }
3439     }
3440
3441     return disclose;
3442 }
3443
3444 /* used by do_break_wand() was well as by weffects() */
3445 void
3446 zapsetup()
3447 {
3448     obj_zapped = FALSE;
3449 }
3450
3451 void
3452 zapwrapup()
3453 {
3454     /* if do_osshock() set obj_zapped while polying, give a message now */
3455     if (obj_zapped)
3456 /*JP
3457         You_feel("shuddering vibrations.");
3458 */
3459         You("\82¼\82Á\82Æ\82·\82é\90U\93®\82ð\8a´\82\82½\81D"); 
3460     obj_zapped = FALSE;
3461 }
3462
3463 /* called for various wand and spell effects - M. Stephenson */
3464 void
3465 weffects(obj)
3466 struct obj *obj;
3467 {
3468     int otyp = obj->otyp;
3469     boolean disclose = FALSE, was_unkn = !objects[otyp].oc_name_known;
3470
3471     exercise(A_WIS, TRUE);
3472     if (u.usteed && (objects[otyp].oc_dir != NODIR) && !u.dx && !u.dy
3473         && (u.dz > 0) && zap_steed(obj)) {
3474         disclose = TRUE;
3475     } else if (objects[otyp].oc_dir == IMMEDIATE) {
3476         zapsetup(); /* reset obj_zapped */
3477         if (u.uswallow) {
3478             (void) bhitm(u.ustuck, obj);
3479             /* [how about `bhitpile(u.ustuck->minvent)' effect?] */
3480         } else if (u.dz) {
3481             disclose = zap_updown(obj);
3482         } else {
3483             (void) bhit(u.dx, u.dy, rn1(8, 6), ZAPPED_WAND, bhitm, bhito,
3484                         &obj);
3485         }
3486         zapwrapup(); /* give feedback for obj_zapped */
3487
3488     } else if (objects[otyp].oc_dir == NODIR) {
3489         zapnodir(obj);
3490
3491     } else {
3492         /* neither immediate nor directionless */
3493
3494         if (otyp == WAN_DIGGING || otyp == SPE_DIG)
3495             zap_dig();
3496         else if (otyp >= SPE_MAGIC_MISSILE && otyp <= SPE_FINGER_OF_DEATH)
3497             buzz(otyp - SPE_MAGIC_MISSILE + 10, u.ulevel / 2 + 1, u.ux, u.uy,
3498                  u.dx, u.dy);
3499         else if (otyp >= WAN_MAGIC_MISSILE && otyp <= WAN_LIGHTNING)
3500             buzz(otyp - WAN_MAGIC_MISSILE,
3501                  (otyp == WAN_MAGIC_MISSILE) ? 2 : 6, u.ux, u.uy, u.dx, u.dy);
3502         else
3503             impossible("weffects: unexpected spell or wand");
3504         disclose = TRUE;
3505     }
3506     if (disclose) {
3507         learnwand(obj);
3508         if (was_unkn)
3509             more_experienced(0, 10);
3510     }
3511     return;
3512 }
3513
3514 /* augment damage for a spell dased on the hero's intelligence (and level) */
3515 int
3516 spell_damage_bonus(dmg)
3517 int dmg; /* base amount to be adjusted by bonus or penalty */
3518 {
3519     int intell = ACURR(A_INT);
3520
3521     /* Punish low intelligence before low level else low intelligence
3522        gets punished only when high level */
3523     if (intell <= 9) {
3524         /* -3 penalty, but never reduce combined amount below 1
3525            (if dmg is 0 for some reason, we're careful to leave it there) */
3526         if (dmg > 1)
3527             dmg = (dmg <= 3) ? 1 : dmg - 3;
3528     } else if (intell <= 13 || u.ulevel < 5)
3529         ; /* no bonus or penalty; dmg remains same */
3530     else if (intell <= 18)
3531         dmg += 1;
3532     else if (intell <= 24 || u.ulevel < 14)
3533         dmg += 2;
3534     else
3535         dmg += 3; /* Int 25 */
3536
3537     return dmg;
3538 }
3539
3540 /*
3541  * Generate the to hit bonus for a spell.  Based on the hero's skill in
3542  * spell class and dexterity.
3543  */
3544 STATIC_OVL int
3545 spell_hit_bonus(skill)
3546 int skill;
3547 {
3548     int hit_bon = 0;
3549     int dex = ACURR(A_DEX);
3550
3551     switch (P_SKILL(spell_skilltype(skill))) {
3552     case P_ISRESTRICTED:
3553     case P_UNSKILLED:
3554         hit_bon = -4;
3555         break;
3556     case P_BASIC:
3557         hit_bon = 0;
3558         break;
3559     case P_SKILLED:
3560         hit_bon = 2;
3561         break;
3562     case P_EXPERT:
3563         hit_bon = 3;
3564         break;
3565     }
3566
3567     if (dex < 4)
3568         hit_bon -= 3;
3569     else if (dex < 6)
3570         hit_bon -= 2;
3571     else if (dex < 8)
3572         hit_bon -= 1;
3573     else if (dex < 14)
3574         /* Will change when print stuff below removed */
3575         hit_bon -= 0;
3576     else
3577         /* Even increment for dextrous heroes (see weapon.c abon) */
3578         hit_bon += dex - 14;
3579
3580     return hit_bon;
3581 }
3582
3583 const char *
3584 exclam(force)
3585 int force;
3586 {
3587     /* force == 0 occurs e.g. with sleep ray */
3588     /* note that large force is usual with wands so that !! would
3589             require information about hand/weapon/wand */
3590 /*JP
3591     return (const char *) ((force < 0) ? "?" : (force <= 4) ? "." : "!");
3592 */
3593     return (const char *) ((force < 0) ? "\81H" : (force <= 4) ? "\81D" : "\81I");
3594 }
3595
3596 void
3597 hit(str, mtmp, force)
3598 const char *str;
3599 struct monst *mtmp;
3600 const char *force; /* usually either "." or "!" */
3601 {
3602     if ((!cansee(bhitpos.x, bhitpos.y) && !canspotmon(mtmp)
3603          && !(u.uswallow && mtmp == u.ustuck)) || !flags.verbose)
3604 /*JP
3605         pline("%s %s it.", The(str), vtense(str, "hit"));
3606 */
3607         pline("%s\82Í\89½\82©\82É\96½\92\86\82µ\82½\81D", str);
3608     else
3609 #if 0 /*JP:T*/
3610         pline("%s %s %s%s", The(str), vtense(str, "hit"),
3611               mon_nam(mtmp), force);
3612 #else
3613         pline("%s\82Í%s\82É\96½\92\86\82µ\82½%s", str,
3614               mon_nam(mtmp), force);
3615 #endif
3616 }
3617
3618 void
3619 miss(str, mtmp)
3620 register const char *str;
3621 register struct monst *mtmp;
3622 {
3623 #if 0 /*JP:T*/
3624     pline(
3625         "%s %s %s.", The(str), vtense(str, "miss"),
3626         ((cansee(bhitpos.x, bhitpos.y) || canspotmon(mtmp)) && flags.verbose)
3627             ? mon_nam(mtmp)
3628             : "it");
3629 #else
3630     pline(
3631         "%s\82Ì%s\82Ö\82Ì\8dU\8c\82\82Í\82Í\82¸\82ê\82½\81D", str,
3632         ((cansee(bhitpos.x,bhitpos.y) || canspotmon(mtmp)) && flags.verbose)
3633             ? mon_nam(mtmp)
3634             : "\89½\8eÒ\82©");
3635 #endif
3636 }
3637
3638 STATIC_OVL void
3639 skiprange(range, skipstart, skipend)
3640 int range, *skipstart, *skipend;
3641 {
3642     int tr = (range / 4);
3643     int tmp = range - ((tr > 0) ? rnd(tr) : 0);
3644
3645     *skipstart = tmp;
3646     *skipend = tmp - ((tmp / 4) * rnd(3));
3647     if (*skipend >= tmp)
3648         *skipend = tmp - 1;
3649 }
3650
3651 /*
3652  *  Called for the following distance effects:
3653  *      when a weapon is thrown (weapon == THROWN_WEAPON)
3654  *      when an object is kicked (KICKED_WEAPON)
3655  *      when an IMMEDIATE wand is zapped (ZAPPED_WAND)
3656  *      when a light beam is flashed (FLASHED_LIGHT)
3657  *      when a mirror is applied (INVIS_BEAM)
3658  *  A thrown/kicked object falls down at end of its range or when a monster
3659  *  is hit.  The variable 'bhitpos' is set to the final position of the weapon
3660  *  thrown/zapped.  The ray of a wand may affect (by calling a provided
3661  *  function) several objects and monsters on its path.  The return value
3662  *  is the monster hit (weapon != ZAPPED_WAND), or a null monster pointer.
3663  *
3664  * Thrown and kicked objects (THROWN_WEAPON or KICKED_WEAPON) may be
3665  * destroyed and *pobj set to NULL to indicate this.
3666  *
3667  *  Check !u.uswallow before calling bhit().
3668  *  This function reveals the absence of a remembered invisible monster in
3669  *  necessary cases (throwing or kicking weapons).  The presence of a real
3670  *  one is revealed for a weapon, but if not a weapon is left up to fhitm().
3671  */
3672 struct monst *
3673 bhit(ddx, ddy, range, weapon, fhitm, fhito, pobj)
3674 register int ddx, ddy, range;          /* direction and range */
3675 enum bhit_call_types weapon;           /* defined in hack.h */
3676 int FDECL((*fhitm), (MONST_P, OBJ_P)), /* fns called when mon/obj hit */
3677     FDECL((*fhito), (OBJ_P, OBJ_P));
3678 struct obj **pobj; /* object tossed/used, set to NULL
3679                     * if object is destroyed */
3680 {
3681     struct monst *mtmp, *result = (struct monst *) 0;
3682     struct obj *obj = *pobj;
3683     uchar typ;
3684     boolean shopdoor = FALSE, point_blank = TRUE;
3685     boolean in_skip = FALSE, allow_skip = FALSE;
3686     boolean tethered_weapon = FALSE;
3687     int skiprange_start = 0, skiprange_end = 0, skipcount = 0;
3688
3689     if (weapon == KICKED_WEAPON) {
3690         /* object starts one square in front of player */
3691         bhitpos.x = u.ux + ddx;
3692         bhitpos.y = u.uy + ddy;
3693         range--;
3694     } else {
3695         bhitpos.x = u.ux;
3696         bhitpos.y = u.uy;
3697     }
3698
3699     if (weapon == THROWN_WEAPON && obj && obj->otyp == ROCK) {
3700         skiprange(range, &skiprange_start, &skiprange_end);
3701         allow_skip = !rn2(3);
3702     }
3703
3704     if (weapon == FLASHED_LIGHT) {
3705         tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam));
3706     } else if (weapon == THROWN_TETHERED_WEAPON && obj) {
3707         tethered_weapon = TRUE;
3708         weapon = THROWN_WEAPON; /* simplify 'if's that follow below */
3709         tmp_at(DISP_TETHER, obj_to_glyph(obj, rn2_on_display_rng));
3710     } else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM)
3711         tmp_at(DISP_FLASH, obj_to_glyph(obj, rn2_on_display_rng));
3712
3713     while (range-- > 0) {
3714         int x, y;
3715
3716         bhitpos.x += ddx;
3717         bhitpos.y += ddy;
3718         x = bhitpos.x;
3719         y = bhitpos.y;
3720
3721         if (!isok(x, y)) {
3722             bhitpos.x -= ddx;
3723             bhitpos.y -= ddy;
3724             break;
3725         }
3726
3727         if (is_pick(obj) && inside_shop(x, y)
3728             && (mtmp = shkcatch(obj, x, y)) != 0) {
3729             tmp_at(DISP_END, 0);
3730             result = mtmp;
3731             goto bhit_done;
3732         }
3733
3734         typ = levl[bhitpos.x][bhitpos.y].typ;
3735
3736         /* iron bars will block anything big enough and break some things */
3737         if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) {
3738             if (typ == IRONBARS
3739                 && hits_bars(pobj, x - ddx, y - ddy, bhitpos.x, bhitpos.y,
3740                              point_blank ? 0 : !rn2(5), 1)) {
3741                 /* caveat: obj might now be null... */
3742                 obj = *pobj;
3743                 bhitpos.x -= ddx;
3744                 bhitpos.y -= ddy;
3745                 break;
3746             } else if (obj->lamplit && !Blind) {
3747                 show_transient_light(obj, bhitpos.x, bhitpos.y);
3748             }
3749         }
3750
3751         if (weapon == ZAPPED_WAND && find_drawbridge(&x, &y)) {
3752             boolean learn_it = FALSE;
3753
3754             switch (obj->otyp) {
3755             case WAN_OPENING:
3756             case SPE_KNOCK:
3757                 if (is_db_wall(bhitpos.x, bhitpos.y)) {
3758                     if (cansee(x, y) || cansee(bhitpos.x, bhitpos.y))
3759                         learn_it = TRUE;
3760                     open_drawbridge(x, y);
3761                 }
3762                 break;
3763             case WAN_LOCKING:
3764             case SPE_WIZARD_LOCK:
3765                 if ((cansee(x, y) || cansee(bhitpos.x, bhitpos.y))
3766                     && levl[x][y].typ == DRAWBRIDGE_DOWN)
3767                     learn_it = TRUE;
3768                 close_drawbridge(x, y);
3769                 break;
3770             case WAN_STRIKING:
3771             case SPE_FORCE_BOLT:
3772                 if (typ != DRAWBRIDGE_UP)
3773                     destroy_drawbridge(x, y);
3774                 learn_it = TRUE;
3775                 break;
3776             }
3777             if (learn_it)
3778                 learnwand(obj);
3779         }
3780
3781         mtmp = m_at(bhitpos.x, bhitpos.y);
3782
3783         /*
3784          * skipping rocks
3785          *
3786          * skiprange_start is only set if this is a thrown rock
3787          */
3788         if (skiprange_start && (range == skiprange_start) && allow_skip) {
3789             if (is_pool(bhitpos.x, bhitpos.y) && !mtmp) {
3790                 in_skip = TRUE;
3791                 if (!Blind)
3792 #if 0 /*JP:T*/
3793                     pline("%s %s%s.", Yname2(obj), otense(obj, "skip"),
3794                           skipcount ? " again" : "");
3795 #else
3796                     pline("%s\82Í%s\92µ\82Ë\82½\81D", Yname2(obj),
3797                           skipcount ? "\8dÄ\82Ñ" : "");
3798 #endif
3799                 else
3800 /*JP
3801                     You_hear("%s skip.", yname(obj));
3802 */
3803                     You_hear("%s\82ª\92µ\82Ë\82é\89¹\82ð\95·\82¢\82½\81D", yname(obj));
3804                 skipcount++;
3805             } else if (skiprange_start > skiprange_end + 1) {
3806                 --skiprange_start;
3807             }
3808         }
3809         if (in_skip) {
3810             if (range <= skiprange_end) {
3811                 in_skip = FALSE;
3812                 if (range > 3) /* another bounce? */
3813                     skiprange(range, &skiprange_start, &skiprange_end);
3814             } else if (mtmp && M_IN_WATER(mtmp->data)) {
3815                 if (!Blind && canspotmon(mtmp))
3816 #if 0 /*JP:T*/
3817                     pline("%s %s over %s.", Yname2(obj), otense(obj, "pass"),
3818                           mon_nam(mtmp));
3819 #else
3820                     pline("%s\82Í%s\82ð\94ò\82Ñ\89z\82¦\82½\81D", Yname2(obj),
3821                           mon_nam(mtmp));
3822 #endif
3823                 mtmp = (struct monst *) 0;
3824             }
3825         }
3826
3827         /* if mtmp is a shade and missile passes harmlessly through it,
3828            give message and skip it in order to keep going */
3829         if (mtmp && (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON)
3830             && shade_miss(&youmonst, mtmp, obj, TRUE, TRUE))
3831             mtmp = (struct monst *) 0;
3832
3833         if (mtmp) {
3834             notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
3835             if (weapon == FLASHED_LIGHT) {
3836                 /* FLASHED_LIGHT hitting invisible monster should
3837                    pass through instead of stop so we call
3838                    flash_hits_mon() directly rather than returning
3839                    mtmp back to caller.  That allows the flash to
3840                    keep on going.  Note that we use mtmp->minvis
3841                    not canspotmon() because it makes no difference
3842                    whether the hero can see the monster or not. */
3843                 if (mtmp->minvis) {
3844                     obj->ox = u.ux, obj->oy = u.uy;
3845                     (void) flash_hits_mon(mtmp, obj);
3846                 } else {
3847                     tmp_at(DISP_END, 0);
3848                     result = mtmp; /* caller will call flash_hits_mon */
3849                     goto bhit_done;
3850                 }
3851             } else if (weapon == INVIS_BEAM) {
3852                 /* Like FLASHED_LIGHT, INVIS_BEAM should continue
3853                    through invisible targets; unlike it, we aren't
3854                    prepared for multiple hits so just get first one
3855                    that's either visible or could see its invisible
3856                    self.  [No tmp_at() cleanup is needed here.] */
3857                 if (!mtmp->minvis || perceives(mtmp->data)) {
3858                     result = mtmp;
3859                     goto bhit_done;
3860                 }
3861             } else if (weapon != ZAPPED_WAND) {
3862
3863                 /* THROWN_WEAPON, KICKED_WEAPON */
3864                 if (!tethered_weapon)
3865                     tmp_at(DISP_END, 0);
3866
3867                 if (cansee(bhitpos.x, bhitpos.y) && !canspotmon(mtmp))
3868                     map_invisible(bhitpos.x, bhitpos.y);
3869                 result = mtmp;
3870                 goto bhit_done;
3871             } else {
3872                 /* ZAPPED_WAND */
3873                 (*fhitm)(mtmp, obj);
3874                 range -= 3;
3875             }
3876         } else {
3877             if (weapon == ZAPPED_WAND && obj->otyp == WAN_PROBING
3878                 && glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph)) {
3879                 unmap_object(bhitpos.x, bhitpos.y);
3880                 newsym(x, y);
3881             }
3882         }
3883         if (fhito) {
3884             if (bhitpile(obj, fhito, bhitpos.x, bhitpos.y, 0))
3885                 range--;
3886         } else {
3887             if (weapon == KICKED_WEAPON
3888                 && ((obj->oclass == COIN_CLASS
3889                      && OBJ_AT(bhitpos.x, bhitpos.y))
3890                     || ship_object(obj, bhitpos.x, bhitpos.y,
3891                                    costly_spot(bhitpos.x, bhitpos.y)))) {
3892                 tmp_at(DISP_END, 0);
3893                 goto bhit_done; /* result == (struct monst *) 0 */
3894             }
3895         }
3896         if (weapon == ZAPPED_WAND && (IS_DOOR(typ) || typ == SDOOR)) {
3897             switch (obj->otyp) {
3898             case WAN_OPENING:
3899             case WAN_LOCKING:
3900             case WAN_STRIKING:
3901             case SPE_KNOCK:
3902             case SPE_WIZARD_LOCK:
3903             case SPE_FORCE_BOLT:
3904                 if (doorlock(obj, bhitpos.x, bhitpos.y)) {
3905                     if (cansee(bhitpos.x, bhitpos.y)
3906                         || (obj->otyp == WAN_STRIKING && !Deaf))
3907                         learnwand(obj);
3908                     if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN
3909                         && *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) {
3910                         shopdoor = TRUE;
3911                         add_damage(bhitpos.x, bhitpos.y, SHOP_DOOR_COST);
3912                     }
3913                 }
3914                 break;
3915             }
3916         }
3917         if (!ZAP_POS(typ) || closed_door(bhitpos.x, bhitpos.y)) {
3918             bhitpos.x -= ddx;
3919             bhitpos.y -= ddy;
3920             break;
3921         }
3922         if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM) {
3923             /* 'I' present but no monster: erase */
3924             /* do this before the tmp_at() */
3925             if (glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph)
3926                 && cansee(x, y)) {
3927                 unmap_object(bhitpos.x, bhitpos.y);
3928                 newsym(x, y);
3929             }
3930             tmp_at(bhitpos.x, bhitpos.y);
3931             delay_output();
3932             /* kicked objects fall in pools */
3933             if ((weapon == KICKED_WEAPON)
3934                 && (is_pool(bhitpos.x, bhitpos.y)
3935                     || is_lava(bhitpos.x, bhitpos.y)))
3936                 break;
3937             if (IS_SINK(typ) && weapon != FLASHED_LIGHT)
3938                 break; /* physical objects fall onto sink */
3939         }
3940         /* limit range of ball so hero won't make an invalid move */
3941         if (weapon == THROWN_WEAPON && range > 0
3942             && obj->otyp == HEAVY_IRON_BALL) {
3943             struct obj *bobj;
3944             struct trap *t;
3945
3946             if ((bobj = sobj_at(BOULDER, x, y)) != 0) {
3947                 if (cansee(x, y))
3948 #if 0 /*JP:T*/
3949                     pline("%s hits %s.", The(distant_name(obj, xname)),
3950                           an(xname(bobj)));
3951 #else
3952                     pline("%s\82Í%s\82É\96½\92\86\82µ\82½\81D", distant_name(obj, xname),
3953                           xname(bobj));
3954 #endif
3955                 range = 0;
3956             } else if (obj == uball) {
3957                 if (!test_move(x - ddx, y - ddy, ddx, ddy, TEST_MOVE)) {
3958                     /* nb: it didn't hit anything directly */
3959                     if (cansee(x, y))
3960 #if 0 /*JP:T*/
3961                         pline("%s jerks to an abrupt halt.",
3962                               The(distant_name(obj, xname))); /* lame */
3963 #else
3964                         pline("%s\82Í\82Æ\82Â\82º\82ñ\83K\83N\83\93\82Æ\8e~\82Ü\82Á\82½\81D",
3965                               distant_name(obj, xname)); /* lame */
3966 #endif
3967                     range = 0;
3968                 } else if (Sokoban && (t = t_at(x, y)) != 0
3969                            && (is_pit(t->ttyp) || is_hole(t->ttyp))) {
3970                     /* hero falls into the trap, so ball stops */
3971                     range = 0;
3972                 }
3973             }
3974         }
3975
3976         /* thrown/kicked missile has moved away from its starting spot */
3977         point_blank = FALSE; /* affects passing through iron bars */
3978     }
3979
3980     if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM && !tethered_weapon)
3981         tmp_at(DISP_END, 0);
3982
3983     if (shopdoor)
3984 /*JP
3985         pay_for_damage("destroy", FALSE);
3986 */
3987         pay_for_damage("\94j\89ó\82·\82é", FALSE);
3988
3989  bhit_done:
3990     if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON)
3991         transient_light_cleanup();
3992
3993     return result;
3994 }
3995
3996 /* process thrown boomerang, which travels a curving path...
3997  * A multi-shot volley ought to have all missiles in flight at once,
3998  * but we're called separately for each one.  We terminate the volley
3999  * early on a failed catch since continuing to throw after being hit
4000  * is too obviously silly.
4001  */
4002 struct monst *
4003 boomhit(obj, dx, dy)
4004 struct obj *obj;
4005 int dx, dy;
4006 {
4007     register int i, ct;
4008     int boom; /* showsym[] index  */
4009     struct monst *mtmp;
4010     boolean counterclockwise = TRUE; /* right-handed throw */
4011
4012     /* counterclockwise traversal patterns:
4013      *  ..........................54.................................
4014      *  ..................43.....6..3....765.........................
4015      *  ..........32.....5..2...7...2...8...4....87..................
4016      *  .........4..1....6..1...8..1....9...3...9..6.....98..........
4017      *  ..21@....5...@...7..@....9@......@12....@...5...@..7.....@9..
4018      *  .3...9....6..9....89.....................1..4...1..6....1..8.
4019      *  .4...8.....78.............................23....2..5...2...7.
4020      *  ..567............................................34....3..6..
4021      *  ........................................................45...
4022      * (invert rows for corresponding clockwise patterns)
4023      */
4024
4025     bhitpos.x = u.ux;
4026     bhitpos.y = u.uy;
4027     boom = counterclockwise ? S_boomleft : S_boomright;
4028     for (i = 0; i < 8; i++)
4029         if (xdir[i] == dx && ydir[i] == dy)
4030             break;
4031     tmp_at(DISP_FLASH, cmap_to_glyph(boom));
4032     for (ct = 0; ct < 10; ct++) {
4033         i = (i + 8) % 8;                          /* 0..7 (8 -> 0, -1 -> 7) */
4034         boom = (S_boomleft + S_boomright - boom); /* toggle */
4035         tmp_at(DISP_CHANGE, cmap_to_glyph(boom)); /* change glyph */
4036         dx = xdir[i];
4037         dy = ydir[i];
4038         bhitpos.x += dx;
4039         bhitpos.y += dy;
4040         if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
4041             m_respond(mtmp);
4042             tmp_at(DISP_END, 0);
4043             return mtmp;
4044         }
4045         if (!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)
4046             || closed_door(bhitpos.x, bhitpos.y)) {
4047             bhitpos.x -= dx;
4048             bhitpos.y -= dy;
4049             break;
4050         }
4051         if (bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
4052             if (Fumbling || rn2(20) >= ACURR(A_DEX)) {
4053                 /* we hit ourselves */
4054                 (void) thitu(10 + obj->spe, dmgval(obj, &youmonst), &obj,
4055 /*JP
4056                              "boomerang");
4057 */
4058                              "\83u\81[\83\81\83\89\83\93");
4059                 endmultishot(TRUE);
4060                 break;
4061             } else { /* we catch it */
4062                 tmp_at(DISP_END, 0);
4063 /*JP
4064                 You("skillfully catch the boomerang.");
4065 */
4066                 You("\8fã\8eè\82É\83u\81[\83\81\83\89\83\93\82ð\92Í\82Ü\82¦\82½\81D");
4067                 return &youmonst;
4068             }
4069         }
4070         tmp_at(bhitpos.x, bhitpos.y);
4071         delay_output();
4072         if (IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) {
4073             if (!Deaf)
4074 /*JP
4075                 pline("Klonk!");
4076 */
4077                 pline("\83J\83\89\83\93\81I");
4078             break; /* boomerang falls on sink */
4079         }
4080         /* ct==0, initial position, we want next delta to be same;
4081            ct==5, opposite position, repeat delta undoes first one */
4082         if (ct % 5 != 0)
4083             i += (counterclockwise ? -1 : 1);
4084     }
4085     tmp_at(DISP_END, 0); /* do not leave last symbol */
4086     return (struct monst *) 0;
4087 }
4088
4089 /* used by buzz(); also used by munslime(muse.c); returns damage applied
4090    to mon; note: caller is responsible for killing mon if damage is fatal */
4091 int
4092 zhitm(mon, type, nd, ootmp)
4093 register struct monst *mon;
4094 register int type, nd;
4095 struct obj **ootmp; /* to return worn armor for caller to disintegrate */
4096 {
4097     register int tmp = 0;
4098     register int abstype = abs(type) % 10;
4099     boolean sho_shieldeff = FALSE;
4100     boolean spellcaster = is_hero_spell(type); /* maybe get a bonus! */
4101
4102     *ootmp = (struct obj *) 0;
4103     switch (abstype) {
4104     case ZT_MAGIC_MISSILE:
4105         if (resists_magm(mon)) {
4106             sho_shieldeff = TRUE;
4107             break;
4108         }
4109         tmp = d(nd, 6);
4110         if (spellcaster)
4111             tmp = spell_damage_bonus(tmp);
4112         break;
4113     case ZT_FIRE:
4114         if (resists_fire(mon)) {
4115             sho_shieldeff = TRUE;
4116             break;
4117         }
4118         tmp = d(nd, 6);
4119         if (resists_cold(mon))
4120             tmp += 7;
4121         if (spellcaster)
4122             tmp = spell_damage_bonus(tmp);
4123         if (burnarmor(mon)) {
4124             if (!rn2(3))
4125                 (void) destroy_mitem(mon, POTION_CLASS, AD_FIRE);
4126             if (!rn2(3))
4127                 (void) destroy_mitem(mon, SCROLL_CLASS, AD_FIRE);
4128             if (!rn2(5))
4129                 (void) destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE);
4130             destroy_mitem(mon, FOOD_CLASS, AD_FIRE); /* carried slime */
4131         }
4132         break;
4133     case ZT_COLD:
4134         if (resists_cold(mon)) {
4135             sho_shieldeff = TRUE;
4136             break;
4137         }
4138         tmp = d(nd, 6);
4139         if (resists_fire(mon))
4140             tmp += d(nd, 3);
4141         if (spellcaster)
4142             tmp = spell_damage_bonus(tmp);
4143         if (!rn2(3))
4144             (void) destroy_mitem(mon, POTION_CLASS, AD_COLD);
4145         break;
4146     case ZT_SLEEP:
4147         tmp = 0;
4148         (void) sleep_monst(mon, d(nd, 25),
4149                            type == ZT_WAND(ZT_SLEEP) ? WAND_CLASS : '\0');
4150         break;
4151     case ZT_DEATH:                              /* death/disintegration */
4152         if (abs(type) != ZT_BREATH(ZT_DEATH)) { /* death */
4153             if (mon->data == &mons[PM_DEATH]) {
4154                 mon->mhpmax += mon->mhpmax / 2;
4155                 if (mon->mhpmax >= MAGIC_COOKIE)
4156                     mon->mhpmax = MAGIC_COOKIE - 1;
4157                 mon->mhp = mon->mhpmax;
4158                 tmp = 0;
4159                 break;
4160             }
4161             if (nonliving(mon->data) || is_demon(mon->data)
4162                 || is_vampshifter(mon) || resists_magm(mon)) {
4163                 /* similar to player */
4164                 sho_shieldeff = TRUE;
4165                 break;
4166             }
4167             type = -1; /* so they don't get saving throws */
4168         } else {
4169             struct obj *otmp2;
4170
4171             if (resists_disint(mon)) {
4172                 sho_shieldeff = TRUE;
4173             } else if (mon->misc_worn_check & W_ARMS) {
4174                 /* destroy shield; victim survives */
4175                 *ootmp = which_armor(mon, W_ARMS);
4176             } else if (mon->misc_worn_check & W_ARM) {
4177                 /* destroy body armor, also cloak if present */
4178                 *ootmp = which_armor(mon, W_ARM);
4179                 if ((otmp2 = which_armor(mon, W_ARMC)) != 0)
4180                     m_useup(mon, otmp2);
4181             } else {
4182                 /* no body armor, victim dies; destroy cloak
4183                    and shirt now in case target gets life-saved */
4184                 tmp = MAGIC_COOKIE;
4185                 if ((otmp2 = which_armor(mon, W_ARMC)) != 0)
4186                     m_useup(mon, otmp2);
4187                 if ((otmp2 = which_armor(mon, W_ARMU)) != 0)
4188                     m_useup(mon, otmp2);
4189             }
4190             type = -1; /* no saving throw wanted */
4191             break;     /* not ordinary damage */
4192         }
4193         tmp = mon->mhp + 1;
4194         break;
4195     case ZT_LIGHTNING:
4196         if (resists_elec(mon)) {
4197             sho_shieldeff = TRUE;
4198             tmp = 0;
4199             /* can still blind the monster */
4200         } else
4201             tmp = d(nd, 6);
4202         if (spellcaster)
4203             tmp = spell_damage_bonus(tmp);
4204         if (!resists_blnd(mon)
4205             && !(type > 0 && u.uswallow && mon == u.ustuck)) {
4206             register unsigned rnd_tmp = rnd(50);
4207             mon->mcansee = 0;
4208             if ((mon->mblinded + rnd_tmp) > 127)
4209                 mon->mblinded = 127;
4210             else
4211                 mon->mblinded += rnd_tmp;
4212         }
4213         if (!rn2(3))
4214             (void) destroy_mitem(mon, WAND_CLASS, AD_ELEC);
4215         /* not actually possible yet */
4216         if (!rn2(3))
4217             (void) destroy_mitem(mon, RING_CLASS, AD_ELEC);
4218         break;
4219     case ZT_POISON_GAS:
4220         if (resists_poison(mon)) {
4221             sho_shieldeff = TRUE;
4222             break;
4223         }
4224         tmp = d(nd, 6);
4225         break;
4226     case ZT_ACID:
4227         if (resists_acid(mon)) {
4228             sho_shieldeff = TRUE;
4229             break;
4230         }
4231         tmp = d(nd, 6);
4232         if (!rn2(6))
4233             acid_damage(MON_WEP(mon));
4234         if (!rn2(6))
4235             erode_armor(mon, ERODE_CORRODE);
4236         break;
4237     }
4238     if (sho_shieldeff)
4239         shieldeff(mon->mx, mon->my);
4240     if (is_hero_spell(type) && (Role_if(PM_KNIGHT) && u.uhave.questart))
4241         tmp *= 2;
4242     if (tmp > 0 && type >= 0
4243         && resist(mon, type < ZT_SPELL(0) ? WAND_CLASS : '\0', 0, NOTELL))
4244         tmp /= 2;
4245     if (tmp < 0)
4246         tmp = 0; /* don't allow negative damage */
4247     debugpline3("zapped monster hp = %d (= %d - %d)", mon->mhp - tmp,
4248                 mon->mhp, tmp);
4249     mon->mhp -= tmp;
4250     return tmp;
4251 }
4252
4253 STATIC_OVL void
4254 zhitu(type, nd, fltxt, sx, sy)
4255 int type, nd;
4256 const char *fltxt;
4257 xchar sx, sy;
4258 {
4259     int dam = 0, abstyp = abs(type);
4260 #if 1 /*JP*/
4261     char buf[BUFSZ];
4262
4263     Sprintf(buf, "%s\82É\82æ\82Á\82Ä", fltxt);
4264     fltxt = buf;
4265 #endif
4266
4267     switch (abstyp % 10) {
4268     case ZT_MAGIC_MISSILE:
4269         if (Antimagic) {
4270             shieldeff(sx, sy);
4271 /*JP
4272             pline_The("missiles bounce off!");
4273 */
4274             pline("\96\82\96@\82Ì\96î\82Í\94½\8eË\82µ\82½\81I");
4275         } else {
4276             dam = d(nd, 6);
4277             exercise(A_STR, FALSE);
4278         }
4279         break;
4280     case ZT_FIRE:
4281         if (Fire_resistance) {
4282             shieldeff(sx, sy);
4283 /*JP
4284             You("don't feel hot!");
4285 */
4286             You("\94M\82³\82ð\8a´\82\82È\82¢\81I");
4287             ugolemeffects(AD_FIRE, d(nd, 6));
4288         } else {
4289             dam = d(nd, 6);
4290         }
4291         burn_away_slime();
4292         if (burnarmor(&youmonst)) { /* "body hit" */
4293             if (!rn2(3))
4294                 destroy_item(POTION_CLASS, AD_FIRE);
4295             if (!rn2(3))
4296                 destroy_item(SCROLL_CLASS, AD_FIRE);
4297             if (!rn2(5))
4298                 destroy_item(SPBOOK_CLASS, AD_FIRE);
4299             destroy_item(FOOD_CLASS, AD_FIRE);
4300         }
4301         break;
4302     case ZT_COLD:
4303         if (Cold_resistance) {
4304             shieldeff(sx, sy);
4305 /*JP
4306             You("don't feel cold.");
4307 */
4308             You("\97â\82½\82³\82ð\8a´\82\82È\82¢\81D");
4309             ugolemeffects(AD_COLD, d(nd, 6));
4310         } else {
4311             dam = d(nd, 6);
4312         }
4313         if (!rn2(3))
4314             destroy_item(POTION_CLASS, AD_COLD);
4315         break;
4316     case ZT_SLEEP:
4317         if (Sleep_resistance) {
4318             shieldeff(u.ux, u.uy);
4319 /*JP
4320             You("don't feel sleepy.");
4321 */
4322             You("\96°\82­\82È\82ç\82È\82¢\81D");
4323         } else {
4324             fall_asleep(-d(nd, 25), TRUE); /* sleep ray */
4325         }
4326         break;
4327     case ZT_DEATH:
4328         if (abstyp == ZT_BREATH(ZT_DEATH)) {
4329             if (Disint_resistance) {
4330 /*JP
4331                 You("are not disintegrated.");
4332 */
4333                 You("\95ª\89ð\82³\82ê\82È\82¢\81D");
4334                 break;
4335             } else if (uarms) {
4336                 /* destroy shield; other possessions are safe */
4337                 (void) destroy_arm(uarms);
4338                 break;
4339             } else if (uarm) {
4340                 /* destroy suit; if present, cloak goes too */
4341                 if (uarmc)
4342                     (void) destroy_arm(uarmc);
4343                 (void) destroy_arm(uarm);
4344                 break;
4345             }
4346             /* no shield or suit, you're dead; wipe out cloak
4347                and/or shirt in case of life-saving or bones */
4348             if (uarmc)
4349                 (void) destroy_arm(uarmc);
4350             if (uarmu)
4351                 (void) destroy_arm(uarmu);
4352         } else if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
4353             shieldeff(sx, sy);
4354 /*JP
4355             You("seem unaffected.");
4356 */
4357             You("\89e\8b¿\82ð\8eó\82¯\82È\82¢\82æ\82¤\82¾\81D");
4358             break;
4359         } else if (Antimagic) {
4360             shieldeff(sx, sy);
4361 /*JP
4362             You("aren't affected.");
4363 */
4364             You("\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D");
4365             break;
4366         }
4367         killer.format = KILLED_BY_AN;
4368         Strcpy(killer.name, fltxt ? fltxt : "");
4369         /* when killed by disintegration breath, don't leave corpse */
4370         u.ugrave_arise = (type == -ZT_BREATH(ZT_DEATH)) ? -3 : NON_PM;
4371         done(DIED);
4372         return; /* lifesaved */
4373     case ZT_LIGHTNING:
4374         if (Shock_resistance) {
4375             shieldeff(sx, sy);
4376 /*JP
4377             You("aren't affected.");
4378 */
4379             You("\89e\8b¿\82ð\8eó\82¯\82È\82¢\81D");
4380             ugolemeffects(AD_ELEC, d(nd, 6));
4381         } else {
4382             dam = d(nd, 6);
4383             exercise(A_CON, FALSE);
4384         }
4385         if (!rn2(3))
4386             destroy_item(WAND_CLASS, AD_ELEC);
4387         if (!rn2(3))
4388             destroy_item(RING_CLASS, AD_ELEC);
4389         break;
4390     case ZT_POISON_GAS:
4391 /*JP
4392         poisoned("blast", A_DEX, "poisoned blast", 15, FALSE);
4393 */
4394         poisoned("\91§", A_DEX, "\93Å\82Ì\91§", 15, FALSE);
4395         break;
4396     case ZT_ACID:
4397         if (Acid_resistance) {
4398 /*JP
4399             pline_The("%s doesn't hurt.", hliquid("acid"));
4400 */
4401             pline_The("%s\82Å\82Í\8f\9d\82Â\82©\82È\82©\82Á\82½\81D", hliquid("\8e_"));
4402             dam = 0;
4403         } else {
4404 /*JP
4405             pline_The("%s burns!", hliquid("acid"));
4406 */
4407             pline_The("%s\82Å\8fÄ\82¯\82½\81I", hliquid("\8e_"));
4408             dam = d(nd, 6);
4409             exercise(A_STR, FALSE);
4410         }
4411         /* using two weapons at once makes both of them more vulnerable */
4412         if (!rn2(u.twoweap ? 3 : 6))
4413             acid_damage(uwep);
4414         if (u.twoweap && !rn2(3))
4415             acid_damage(uswapwep);
4416         if (!rn2(6))
4417             erode_armor(&youmonst, ERODE_CORRODE);
4418         break;
4419     }
4420
4421     /* Half_spell_damage protection yields half-damage for wands & spells,
4422        including hero's own ricochets; breath attacks do full damage */
4423     if (dam && Half_spell_damage && !(abstyp >= 20 && abstyp <= 29))
4424         dam = (dam + 1) / 2;
4425     losehp(dam, fltxt, KILLED_BY_AN);
4426     return;
4427 }
4428
4429 /*
4430  * burn objects (such as scrolls and spellbooks) on floor
4431  * at position x,y; return the number of objects burned
4432  */
4433 int
4434 burn_floor_objects(x, y, give_feedback, u_caused)
4435 int x, y;
4436 boolean give_feedback; /* caller needs to decide about visibility checks */
4437 boolean u_caused;
4438 {
4439     struct obj *obj, *obj2;
4440     long i, scrquan, delquan;
4441     char buf1[BUFSZ], buf2[BUFSZ];
4442     int cnt = 0;
4443
4444     for (obj = level.objects[x][y]; obj; obj = obj2) {
4445         obj2 = obj->nexthere;
4446         if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS
4447             || (obj->oclass == FOOD_CLASS
4448                 && obj->otyp == GLOB_OF_GREEN_SLIME)) {
4449             if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL
4450                 || obj_resists(obj, 2, 100))
4451                 continue;
4452             scrquan = obj->quan; /* number present */
4453             delquan = 0L;        /* number to destroy */
4454             for (i = scrquan; i > 0L; i--)
4455                 if (!rn2(3))
4456                     delquan++;
4457             if (delquan) {
4458                 /* save name before potential delobj() */
4459                 if (give_feedback) {
4460                     obj->quan = 1L;
4461                     Strcpy(buf1, (x == u.ux && y == u.uy)
4462                                      ? xname(obj)
4463                                      : distant_name(obj, xname));
4464                     obj->quan = 2L;
4465                     Strcpy(buf2, (x == u.ux && y == u.uy)
4466                                      ? xname(obj)
4467                                      : distant_name(obj, xname));
4468                     obj->quan = scrquan;
4469                 }
4470                 /* useupf(), which charges, only if hero caused damage */
4471                 if (u_caused)
4472                     useupf(obj, delquan);
4473                 else if (delquan < scrquan)
4474                     obj->quan -= delquan;
4475                 else
4476                     delobj(obj);
4477                 cnt += delquan;
4478                 if (give_feedback) {
4479                     if (delquan > 1L)
4480 #if 0 /*JP*/
4481                         pline("%ld %s burn.", delquan, buf2);
4482 #else
4483                         pline("%ld%s\82Ì%s\82ª\94R\82¦\82½\81D", 
4484                               delquan, 
4485                               obj->oclass == SCROLL_CLASS ? "\96\87" : "\8dû",
4486                               buf2);
4487 #endif
4488                     else
4489 /*JP
4490                         pline("%s burns.", An(buf1));
4491 */
4492                         pline("%s\82Í\94R\82¦\82½\81D", buf1);
4493                 }
4494             }
4495         }
4496     }
4497     return cnt;
4498 }
4499
4500 /* will zap/spell/breath attack score a hit against armor class `ac'? */
4501 STATIC_OVL int
4502 zap_hit(ac, type)
4503 int ac;
4504 int type; /* either hero cast spell type or 0 */
4505 {
4506     int chance = rn2(20);
4507     int spell_bonus = type ? spell_hit_bonus(type) : 0;
4508
4509     /* small chance for naked target to avoid being hit */
4510     if (!chance)
4511         return rnd(10) < ac + spell_bonus;
4512
4513     /* very high armor protection does not achieve invulnerability */
4514     ac = AC_VALUE(ac);
4515
4516     return (3 - chance < ac + spell_bonus);
4517 }
4518
4519 STATIC_OVL void
4520 disintegrate_mon(mon, type, fltxt)
4521 struct monst *mon;
4522 int type; /* hero vs other */
4523 const char *fltxt;
4524 {
4525     struct obj *otmp, *otmp2, *m_amulet = mlifesaver(mon);
4526
4527     if (canseemon(mon)) {
4528         if (!m_amulet)
4529 /*JP
4530             pline("%s is disintegrated!", Monnam(mon));
4531 */
4532             pline("%s\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81I", Monnam(mon));
4533         else
4534 /*JP
4535             hit(fltxt, mon, "!");
4536 */
4537             hit(fltxt, mon, "\81I");
4538     }
4539
4540 /* note: worn amulet of life saving must be preserved in order to operate */
4541 #define oresist_disintegration(obj)                                       \
4542     (objects[obj->otyp].oc_oprop == DISINT_RES || obj_resists(obj, 5, 50) \
4543      || is_quest_artifact(obj) || obj == m_amulet)
4544
4545     for (otmp = mon->minvent; otmp; otmp = otmp2) {
4546         otmp2 = otmp->nobj;
4547         if (!oresist_disintegration(otmp)) {
4548             if (otmp->owornmask) {
4549                 /* in case monster's life gets saved */
4550                 mon->misc_worn_check &= ~otmp->owornmask;
4551                 if (otmp->owornmask & W_WEP)
4552                     setmnotwielded(mon, otmp);
4553                 /* also dismounts hero if this object is steed's saddle */
4554                 update_mon_intrinsics(mon, otmp, FALSE, TRUE);
4555                 otmp->owornmask = 0L;
4556             }
4557             obj_extract_self(otmp);
4558             obfree(otmp, (struct obj *) 0);
4559         }
4560     }
4561
4562 #undef oresist_disintegration
4563
4564     if (type < 0)
4565         monkilled(mon, (char *) 0, -AD_RBRE);
4566     else
4567         xkilled(mon, XKILL_NOMSG | XKILL_NOCORPSE);
4568 }
4569
4570 void
4571 buzz(type, nd, sx, sy, dx, dy)
4572 int type, nd;
4573 xchar sx, sy;
4574 int dx, dy;
4575 {
4576     dobuzz(type, nd, sx, sy, dx, dy, TRUE);
4577 }
4578
4579 /*
4580  * type ==   0 to   9 : you shooting a wand
4581  * type ==  10 to  19 : you casting a spell
4582  * type ==  20 to  29 : you breathing as a monster
4583  * type == -10 to -19 : monster casting spell
4584  * type == -20 to -29 : monster breathing at you
4585  * type == -30 to -39 : monster shooting a wand
4586  * called with dx = dy = 0 with vertical bolts
4587  */
4588 void
4589 dobuzz(type, nd, sx, sy, dx, dy, say)
4590 register int type, nd;
4591 register xchar sx, sy;
4592 register int dx, dy;
4593 boolean say; /* Announce out of sight hit/miss events if true */
4594 {
4595     int range, abstype = abs(type) % 10;
4596     register xchar lsx, lsy;
4597     struct monst *mon;
4598     coord save_bhitpos;
4599     boolean shopdamage = FALSE;
4600     const char *fltxt;
4601     struct obj *otmp;
4602     int spell_type;
4603
4604     /* if its a Hero Spell then get its SPE_TYPE */
4605     spell_type = is_hero_spell(type) ? SPE_MAGIC_MISSILE + abstype : 0;
4606
4607     fltxt = flash_types[(type <= -30) ? abstype : abs(type)];
4608     if (u.uswallow) {
4609         register int tmp;
4610
4611         if (type < 0)
4612             return;
4613         tmp = zhitm(u.ustuck, type, nd, &otmp);
4614         if (!u.ustuck)
4615             u.uswallow = 0;
4616         else
4617 #if 0 /*JP:T*/
4618             pline("%s rips into %s%s", The(fltxt), mon_nam(u.ustuck),
4619                   exclam(tmp));
4620 #else
4621             pline("%s\82Í%s\82ð\82Ð\82«\82³\82¢\82½%s", fltxt, mon_nam(u.ustuck),
4622                   exclam(tmp));
4623 #endif
4624         /* Using disintegration from the inside only makes a hole... */
4625         if (tmp == MAGIC_COOKIE)
4626             u.ustuck->mhp = 0;
4627         if (DEADMONSTER(u.ustuck))
4628             killed(u.ustuck);
4629         return;
4630     }
4631     if (type < 0)
4632         newsym(u.ux, u.uy);
4633     range = rn1(7, 7);
4634     if (dx == 0 && dy == 0)
4635         range = 1;
4636     save_bhitpos = bhitpos;
4637
4638     tmp_at(DISP_BEAM, zapdir_to_glyph(dx, dy, abstype));
4639     while (range-- > 0) {
4640         lsx = sx;
4641         sx += dx;
4642         lsy = sy;
4643         sy += dy;
4644         if (!isok(sx, sy) || levl[sx][sy].typ == STONE)
4645             goto make_bounce;
4646
4647         mon = m_at(sx, sy);
4648         if (cansee(sx, sy)) {
4649             /* reveal/unreveal invisible monsters before tmp_at() */
4650             if (mon && !canspotmon(mon))
4651                 map_invisible(sx, sy);
4652             else if (!mon)
4653                 (void) unmap_invisible(sx, sy);
4654             if (ZAP_POS(levl[sx][sy].typ)
4655                 || (isok(lsx, lsy) && cansee(lsx, lsy)))
4656                 tmp_at(sx, sy);
4657             delay_output(); /* wait a little */
4658         }
4659
4660         /* hit() and miss() need bhitpos to match the target */
4661         bhitpos.x = sx, bhitpos.y = sy;
4662         /* Fireballs only damage when they explode */
4663         if (type != ZT_SPELL(ZT_FIRE)) {
4664             range += zap_over_floor(sx, sy, type, &shopdamage, 0);
4665             /* zap with fire -> melt ice -> drown monster, so monster
4666                found and cached above might not be here any more */
4667             mon = m_at(sx, sy);
4668         }
4669
4670         if (mon) {
4671             if (type == ZT_SPELL(ZT_FIRE))
4672                 break;
4673             if (type >= 0)
4674                 mon->mstrategy &= ~STRAT_WAITMASK;
4675  buzzmonst:
4676             notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
4677             if (zap_hit(find_mac(mon), spell_type)) {
4678                 if (mon_reflects(mon, (char *) 0)) {
4679                     if (cansee(mon->mx, mon->my)) {
4680                         hit(fltxt, mon, exclam(0));
4681                         shieldeff(mon->mx, mon->my);
4682 #if 0 /*JP:T*/
4683                         (void) mon_reflects(mon,
4684                                             "But it reflects from %s %s!");
4685 #else
4686                         (void) mon_reflects(mon,
4687                                             "\82µ\82©\82µ\82»\82ê\82Í%s\82Ì%s\82Å\94½\8eË\82µ\82½\81I");
4688 #endif
4689                     }
4690                     dx = -dx;
4691                     dy = -dy;
4692                 } else {
4693                     boolean mon_could_move = mon->mcanmove;
4694                     int tmp = zhitm(mon, type, nd, &otmp);
4695
4696                     if (is_rider(mon->data)
4697                         && abs(type) == ZT_BREATH(ZT_DEATH)) {
4698                         if (canseemon(mon)) {
4699 /*JP
4700                             hit(fltxt, mon, ".");
4701 */
4702                             hit(fltxt, mon, "\81D");
4703 /*JP
4704                             pline("%s disintegrates.", Monnam(mon));
4705 */
4706                             pline("%s\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D", Monnam(mon));
4707 #if 0 /*JP*/
4708                             pline("%s body reintegrates before your %s!",
4709                                   s_suffix(Monnam(mon)),
4710                                   (eyecount(youmonst.data) == 1)
4711                                       ? body_part(EYE)
4712                                       : makeplural(body_part(EYE)));
4713 #else
4714                             pline("%s\82Ì\91Ì\82Í\82 \82È\82½\82Ì\96Ú\82Ì\91O\82Å\8dÄ\8c\8b\8d\87\82µ\82½\81I",
4715                                   Monnam(mon));
4716 #endif
4717 /*JP
4718                             pline("%s resurrects!", Monnam(mon));
4719 */
4720                             pline("%s\82Í\91h\82Á\82½\81I", Monnam(mon));
4721                         }
4722                         mon->mhp = mon->mhpmax;
4723                         break; /* Out of while loop */
4724                     }
4725                     if (mon->data == &mons[PM_DEATH] && abstype == ZT_DEATH) {
4726                         if (canseemon(mon)) {
4727 /*JP
4728                             hit(fltxt, mon, ".");
4729 */
4730                             hit(fltxt, mon, "\81D");
4731 #if 0 /*JP:T*/
4732                             pline("%s absorbs the deadly %s!", Monnam(mon),
4733                                   type == ZT_BREATH(ZT_DEATH) ? "blast"
4734                                                               : "ray");
4735 #else
4736                             pline("%s\82Í\8e\80\82Ì%s\82ð\8bz\8eû\82µ\82½\81I", Monnam(mon),
4737                                   type == ZT_BREATH(ZT_DEATH) ? "\91§"
4738                                                               : "\8cõ\90ü");
4739 #endif
4740 /*JP
4741                             pline("It seems even stronger than before.");
4742 */
4743                             pline("\82³\82ç\82É\8b­\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82³\82¦\82·\82é\81D");
4744                         }
4745                         break; /* Out of while loop */
4746                     }
4747
4748                     if (tmp == MAGIC_COOKIE) { /* disintegration */
4749                         disintegrate_mon(mon, type, fltxt);
4750                     } else if (DEADMONSTER(mon)) {
4751                         if (type < 0) {
4752                             /* mon has just been killed by another monster */
4753                             monkilled(mon, fltxt, AD_RBRE);
4754                         } else {
4755                             int xkflags = XKILL_GIVEMSG; /* killed(mon); */
4756
4757                             /* killed by hero; we know 'type' isn't negative;
4758                                if it's fire, highly flammable monsters leave
4759                                no corpse; don't bother reporting that they
4760                                "burn completely" -- unnecessary verbosity */
4761                             if ((type % 10 == ZT_FIRE)
4762                                 /* paper golem or straw golem */
4763                                 && completelyburns(mon->data))
4764                                 xkflags |= XKILL_NOCORPSE;
4765                             xkilled(mon, xkflags);
4766                         }
4767                     } else {
4768                         if (!otmp) {
4769                             /* normal non-fatal hit */
4770                             if (say || canseemon(mon))
4771                                 hit(fltxt, mon, exclam(tmp));
4772                         } else {
4773                             /* some armor was destroyed; no damage done */
4774                             if (canseemon(mon))
4775 #if 0 /*JP:T*/
4776                                 pline("%s %s is disintegrated!",
4777                                       s_suffix(Monnam(mon)),
4778                                       distant_name(otmp, xname));
4779 #else
4780                                 pline("%s\82Ì%s\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81I",
4781                                       Monnam(mon),
4782                                       distant_name(otmp, xname));
4783 #endif
4784                             m_useup(mon, otmp);
4785                         }
4786                         if (mon_could_move && !mon->mcanmove) /* ZT_SLEEP */
4787                             slept_monst(mon);
4788                     }
4789                 }
4790                 range -= 2;
4791             } else {
4792                 if (say || canseemon(mon))
4793                     miss(fltxt, mon);
4794             }
4795         } else if (sx == u.ux && sy == u.uy && range >= 0) {
4796             nomul(0);
4797             if (u.usteed && !rn2(3) && !mon_reflects(u.usteed, (char *) 0)) {
4798                 mon = u.usteed;
4799                 goto buzzmonst;
4800             } else if (zap_hit((int) u.uac, 0)) {
4801                 range -= 2;
4802 /*JP
4803                 pline("%s hits you!", The(fltxt));
4804 */
4805                 pline("%s\82Í\82 \82È\82½\82É\96½\92\86\82µ\82½\81I", fltxt);
4806                 if (Reflecting) {
4807                     if (!Blind) {
4808 #if 0 /*JP:T*/
4809                         (void) ureflects("But %s reflects from your %s!",
4810                                          "it");
4811 #else
4812                         (void) ureflects("\82µ\82©\82µ\81C%s\82Í\82 \82È\82½\82Ì%s\82É\82æ\82Á\82Ä\94½\8eË\82µ\82½\81D",
4813                                          "\82»\82ê");
4814 #endif
4815                     } else
4816 /*JP
4817                         pline("For some reason you are not affected.");
4818 */
4819                         pline("\82È\82º\82©\82 \82È\82½\82Í\89e\8b¿\82ð\8eó\82¯\82È\82©\82Á\82½\81D");
4820                     dx = -dx;
4821                     dy = -dy;
4822                     shieldeff(sx, sy);
4823                 } else {
4824                     zhitu(type, nd, fltxt, sx, sy);
4825                 }
4826             } else if (!Blind) {
4827 /*JP
4828                 pline("%s whizzes by you!", The(fltxt));
4829 */
4830                 pline("%s\82Í\82 \82È\82½\82Ì\82»\82Î\82ð\82©\82·\82ß\82½\81I", fltxt);
4831             } else if (abstype == ZT_LIGHTNING) {
4832 /*JP
4833                 Your("%s tingles.", body_part(ARM));
4834 */
4835                 Your("%s\82Í\83q\83\8a\83q\83\8a\82µ\82½\81D", body_part(ARM));
4836             }
4837             if (abstype == ZT_LIGHTNING)
4838                 (void) flashburn((long) d(nd, 50));
4839             stop_occupation();
4840             nomul(0);
4841         }
4842
4843         if (!ZAP_POS(levl[sx][sy].typ)
4844             || (closed_door(sx, sy) && range >= 0)) {
4845             int bounce, bchance;
4846             uchar rmn;
4847             boolean fireball;
4848
4849  make_bounce:
4850             bchance = (levl[sx][sy].typ == STONE) ? 10
4851                 : (In_mines(&u.uz) && IS_WALL(levl[sx][sy].typ)) ? 20
4852                 : 75;
4853             bounce = 0;
4854             fireball = (type == ZT_SPELL(ZT_FIRE));
4855             if ((--range > 0 && isok(lsx, lsy) && cansee(lsx, lsy))
4856                 || fireball) {
4857                 if (Is_airlevel(&u.uz)) { /* nothing to bounce off of */
4858 /*JP
4859                     pline_The("%s vanishes into the aether!", fltxt);
4860 */
4861                     pline_The("%s\82Í\83G\81[\83e\83\8b\8bó\8aÔ\82É\8fÁ\82¦\82½\81I", fltxt);
4862                     if (fireball)
4863                         type = ZT_WAND(ZT_FIRE); /* skip pending fireball */
4864                     break;
4865                 } else if (fireball) {
4866                     sx = lsx;
4867                     sy = lsy;
4868                     break; /* fireballs explode before the obstacle */
4869                 } else
4870 /*JP
4871                     pline_The("%s bounces!", fltxt);
4872 */
4873                     pline_The("%s\82Í\94½\8eË\82µ\82½\81I", fltxt);
4874             }
4875             if (!dx || !dy || !rn2(bchance)) {
4876                 dx = -dx;
4877                 dy = -dy;
4878             } else {
4879                 if (isok(sx, lsy) && ZAP_POS(rmn = levl[sx][lsy].typ)
4880                     && !closed_door(sx, lsy)
4881                     && (IS_ROOM(rmn) || (isok(sx + dx, lsy)
4882                                          && ZAP_POS(levl[sx + dx][lsy].typ))))
4883                     bounce = 1;
4884                 if (isok(lsx, sy) && ZAP_POS(rmn = levl[lsx][sy].typ)
4885                     && !closed_door(lsx, sy)
4886                     && (IS_ROOM(rmn) || (isok(lsx, sy + dy)
4887                                          && ZAP_POS(levl[lsx][sy + dy].typ))))
4888                     if (!bounce || rn2(2))
4889                         bounce = 2;
4890
4891                 switch (bounce) {
4892                 case 0:
4893                     dx = -dx;
4894                     /*FALLTHRU*/
4895                 case 1:
4896                     dy = -dy;
4897                     break;
4898                 case 2:
4899                     dx = -dx;
4900                     break;
4901                 }
4902                 tmp_at(DISP_CHANGE, zapdir_to_glyph(dx, dy, abstype));
4903             }
4904         }
4905     }
4906     tmp_at(DISP_END, 0);
4907     if (type == ZT_SPELL(ZT_FIRE))
4908         explode(sx, sy, type, d(12, 6), 0, EXPL_FIERY);
4909     if (shopdamage)
4910 #if 0 /*JP:T*/
4911         pay_for_damage(abstype == ZT_FIRE
4912                           ? "burn away"
4913                           : abstype == ZT_COLD
4914                              ? "shatter"
4915                              /* "damage" indicates wall rather than door */
4916                              : abstype == ZT_ACID
4917                                 ? "damage"
4918                                 : abstype == ZT_DEATH
4919                                    ? "disintegrate"
4920                                    : "destroy",
4921                        FALSE);
4922 #else
4923         pay_for_damage(abstype == ZT_FIRE
4924                        ? "\94R\82â\82·"
4925                        : abstype == ZT_COLD
4926                           ? "\95²\81X\82É\82·\82é"
4927                           : abstype == ZT_ACID
4928                           ? "\8f\9d\82Â\82¯\82é"
4929                              : abstype == ZT_DEATH
4930                                 ? "\95²\8dÓ\82·\82é"
4931                                 : "\94j\89ó\82·\82é",
4932                        FALSE);
4933 #endif
4934     bhitpos = save_bhitpos;
4935 }
4936
4937 void
4938 melt_ice(x, y, msg)
4939 xchar x, y;
4940 const char *msg;
4941 {
4942     struct rm *lev = &levl[x][y];
4943     struct obj *otmp;
4944     struct monst *mtmp;
4945
4946     if (!msg)
4947 /*JP
4948         msg = "The ice crackles and melts.";
4949 */
4950         msg = "\95X\82Í\83s\83L\83s\83L\96Â\82è\81C\97n\82¯\82½\81D";
4951     if (lev->typ == DRAWBRIDGE_UP || lev->typ == DRAWBRIDGE_DOWN) {
4952         lev->drawbridgemask &= ~DB_ICE; /* revert to DB_MOAT */
4953     } else { /* lev->typ == ICE */
4954 #ifdef STUPID
4955         if (lev->icedpool == ICED_POOL)
4956             lev->typ = POOL;
4957         else
4958             lev->typ = MOAT;
4959 #else
4960         lev->typ = (lev->icedpool == ICED_POOL ? POOL : MOAT);
4961 #endif
4962         lev->icedpool = 0;
4963     }
4964     spot_stop_timers(x, y, MELT_ICE_AWAY); /* no more ice to melt away */
4965     obj_ice_effects(x, y, FALSE);
4966     unearth_objs(x, y);
4967     if (Underwater)
4968         vision_recalc(1);
4969     newsym(x, y);
4970     if (cansee(x, y))
4971         Norep("%s", msg);
4972     if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
4973         if (cansee(x, y))
4974 /*JP
4975             pline("%s settles...", An(xname(otmp)));
4976 */
4977             pline("%s\82Í\82Í\82Ü\82Á\82½\81D\81D\81D", xname(otmp));
4978         do {
4979             obj_extract_self(otmp); /* boulder isn't being pushed */
4980             if (!boulder_hits_pool(otmp, x, y, FALSE))
4981                 impossible("melt_ice: no pool?");
4982             /* try again if there's another boulder and pool didn't fill */
4983         } while (is_pool(x, y) && (otmp = sobj_at(BOULDER, x, y)) != 0);
4984         newsym(x, y);
4985     }
4986     if (x == u.ux && y == u.uy)
4987         spoteffects(TRUE); /* possibly drown, notice objects */
4988     else if (is_pool(x, y) && (mtmp = m_at(x, y)) != 0)
4989         (void) minliquid(mtmp);
4990 }
4991
4992 #define MIN_ICE_TIME 50
4993 #define MAX_ICE_TIME 2000
4994 /*
4995  * Usually start a melt_ice timer; sometimes the ice will become
4996  * permanent instead.
4997  */
4998 void
4999 start_melt_ice_timeout(x, y, min_time)
5000 xchar x, y;
5001 long min_time; /* <x,y>'s old melt timeout (deleted by time we get here) */
5002 {
5003     int when;
5004     long where;
5005
5006     when = (int) min_time;
5007     if (when < MIN_ICE_TIME - 1)
5008         when = MIN_ICE_TIME - 1;
5009
5010     /* random timeout; surrounding ice locations ought to be a factor... */
5011     while (++when <= MAX_ICE_TIME)
5012         if (!rn2((MAX_ICE_TIME - when) + MIN_ICE_TIME))
5013             break;
5014
5015     /* if we're within MAX_ICE_TIME, install a melt timer;
5016        otherwise, omit it to leave this ice permanent */
5017     if (when <= MAX_ICE_TIME) {
5018         where = ((long) x << 16) | (long) y;
5019         (void) start_timer((long) when, TIMER_LEVEL, MELT_ICE_AWAY,
5020                            long_to_any(where));
5021     }
5022 }
5023 #undef MIN_ICE_TIME
5024 #undef MAX_ICE_TIME
5025
5026 /*
5027  * Called when ice has melted completely away.
5028  */
5029 void
5030 melt_ice_away(arg, timeout)
5031 anything *arg;
5032 long timeout UNUSED;
5033 {
5034     xchar x, y;
5035     long where = arg->a_long;
5036     boolean save_mon_moving = context.mon_moving; /* will be False */
5037
5038     /* melt_ice -> minliquid -> mondead|xkilled shouldn't credit/blame hero */
5039     context.mon_moving = TRUE; /* hero isn't causing this ice to melt */
5040     y = (xchar) (where & 0xFFFF);
5041     x = (xchar) ((where >> 16) & 0xFFFF);
5042     /* melt_ice does newsym when appropriate */
5043 /*JP
5044     melt_ice(x, y, "Some ice melts away.");
5045 */
5046     melt_ice(x, y, "\95X\82ª\8f­\82µ\97n\82¯\82½\81D");
5047     context.mon_moving = save_mon_moving;
5048 }
5049
5050 /* Burn floor scrolls, evaporate pools, etc... in a single square.
5051  * Used both for normal bolts of fire, cold, etc... and for fireballs.
5052  * Sets shopdamage to TRUE if a shop door is destroyed, and returns the
5053  * amount by which range is reduced (the latter is just ignored by fireballs)
5054  */
5055 int
5056 zap_over_floor(x, y, type, shopdamage, exploding_wand_typ)
5057 xchar x, y;
5058 int type;
5059 boolean *shopdamage;
5060 short exploding_wand_typ;
5061 {
5062     const char *zapverb;
5063     struct monst *mon;
5064     struct trap *t;
5065     struct rm *lev = &levl[x][y];
5066     boolean see_it = cansee(x, y), yourzap;
5067     int rangemod = 0, abstype = abs(type) % 10;
5068
5069     switch (abstype) {
5070     case ZT_FIRE:
5071         t = t_at(x, y);
5072         if (t && t->ttyp == WEB) {
5073             /* a burning web is too flimsy to notice if you can't see it */
5074             if (see_it)
5075 /*JP
5076                 Norep("A web bursts into flames!");
5077 */
5078                 Norep("\82­\82à\82Ì\91\83\82Í\89\8a\82É\95ï\82Ü\82ê\82½\81I");
5079             (void) delfloortrap(t);
5080             if (see_it)
5081                 newsym(x, y);
5082         }
5083         if (is_ice(x, y)) {
5084             melt_ice(x, y, (char *) 0);
5085         } else if (is_pool(x, y)) {
5086 #if 0 /*JP*/
5087             const char *msgtxt = (!Deaf)
5088                                      ? "You hear hissing gas." /* Deaf-aware */
5089                                      : (type >= 0)
5090                                          ? "That seemed remarkably uneventful."
5091                                          : (const char *) 0;
5092 #else
5093             const char *msgtxt = (!Deaf)
5094                                      ? "\82µ\82ã\81[\82Á\82Æ\82¢\82¤\83K\83X\82Ì\89¹\82ð\95·\82¢\82½\81D" /* Deaf-aware */
5095                                      : (type >= 0)
5096                                          ? "\82±\82ê\82Í\8bÁ\82­\82Ù\82Ç\82È\82ñ\82Å\82à\82È\82³\82»\82¤\82¾\81D"
5097                                          : (const char *) 0;
5098 #endif
5099
5100             if (lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP */
5101                 if (see_it)
5102 /*JP
5103                     msgtxt = "Some water evaporates.";
5104 */
5105                     msgtxt = "\82·\82±\82µ\90\85\82ª\8fö\94­\82µ\82½\81D";
5106             } else {
5107                 rangemod -= 3;
5108                 lev->typ = ROOM, lev->flags = 0;
5109                 t = maketrap(x, y, PIT);
5110                 if (t)
5111                     t->tseen = 1;
5112                 if (see_it)
5113 /*JP
5114                     msgtxt = "The water evaporates.";
5115 */
5116                     msgtxt = "\90\85\82ª\8fö\94­\82µ\82½\81D";
5117             }
5118             if (msgtxt)
5119                 Norep("%s", msgtxt);
5120             if (lev->typ == ROOM)
5121                 newsym(x, y);
5122         } else if (IS_FOUNTAIN(lev->typ)) {
5123             if (see_it)
5124 /*JP
5125                 pline("Steam billows from the fountain.");
5126 */
5127                 pline("\90ò\82©\82ç\8fö\8bC\82ª\97§\82¿\82Ì\82Ú\82Á\82½\81D");
5128             rangemod -= 1;
5129             dryup(x, y, type > 0);
5130         }
5131         break; /* ZT_FIRE */
5132
5133     case ZT_COLD:
5134         if (is_pool(x, y) || is_lava(x, y)) {
5135             boolean lava = is_lava(x, y),
5136                     moat = is_moat(x, y);
5137
5138             if (lev->typ == WATER) {
5139                 /* For now, don't let WATER freeze. */
5140                 if (see_it)
5141 /*JP
5142                     pline_The("%s freezes for a moment.", hliquid("water"));
5143 */
5144                     pline_The("%s\82Í\88ê\8fu\93\80\82Á\82½\81D", hliquid("\90\85"));
5145                 else
5146 /*JP
5147                     You_hear("a soft crackling.");
5148 */
5149                     You_hear("\83s\83L\81I\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
5150                 rangemod -= 1000; /* stop */
5151             } else {
5152                 char buf[BUFSZ];
5153
5154                 Strcpy(buf, waterbody_name(x, y)); /* for MOAT */
5155                 rangemod -= 3;
5156                 if (lev->typ == DRAWBRIDGE_UP) {
5157                     lev->drawbridgemask &= ~DB_UNDER; /* clear lava */
5158                     lev->drawbridgemask |= (lava ? DB_FLOOR : DB_ICE);
5159                 } else {
5160                     lev->icedpool = lava ? 0
5161                                          : (lev->typ == POOL) ? ICED_POOL
5162                                                               : ICED_MOAT;
5163                     lev->typ = lava ? ROOM : ICE;
5164                 }
5165                 bury_objs(x, y);
5166                 if (see_it) {
5167                     if (lava)
5168 /*JP
5169                         Norep("The %s cools and solidifies.", hliquid("lava"));
5170 */
5171                         Norep("%s\82Í\97â\82¦\8cÅ\82Ü\82Á\82½\81D", hliquid("lava"));
5172                     else if (moat)
5173 /*JP
5174                         Norep("The %s is bridged with ice!", buf);
5175 */
5176                         Norep("%s\82É\95X\82Ì\8b´\82ª\82©\82¯\82ç\82ê\82½\81I", buf);
5177                     else
5178 /*JP
5179                         Norep("The %s freezes.", hliquid("water"));
5180 */
5181                         Norep("%s\82Í\93\80\82Á\82½\81D", hliquid("\95X"));
5182                     newsym(x, y);
5183                 } else if (!lava)
5184 /*JP
5185                     You_hear("a crackling sound.");
5186 */
5187                     You_hear("\83s\83L\83s\83L\83b\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
5188
5189                 if (x == u.ux && y == u.uy) {
5190                     if (u.uinwater) { /* not just `if (Underwater)' */
5191                         /* leave the no longer existent water */
5192                         u.uinwater = 0;
5193                         u.uundetected = 0;
5194                         docrt();
5195                         vision_full_recalc = 1;
5196                     } else if (u.utrap && u.utraptype == TT_LAVA) {
5197                         if (Passes_walls) {
5198 /*JP
5199                             You("pass through the now-solid rock.");
5200 */
5201                             You("\82¢\82Ü\8cÅ\82­\82È\82Á\82½\82Î\82©\82è\82Ì\90Î\82Ì\92\86\82ð\82·\82è\94²\82¯\82½\81D");
5202                             reset_utrap(TRUE);
5203                         } else {
5204                             set_utrap(rn1(50, 20), TT_INFLOOR);
5205 /*JP
5206                             You("are firmly stuck in the cooling rock.");
5207 */
5208                             You("\97â\82¦\82½\8aâ\82Ì\82È\82©\82É\82µ\82Á\82©\82è\82Æ\96\84\82Ü\82Á\82½\81D");
5209                         }
5210                     }
5211                 } else if ((mon = m_at(x, y)) != 0) {
5212                     /* probably ought to do some hefty damage to any
5213                        non-ice creature caught in freezing water;
5214                        at a minimum, eels are forced out of hiding */
5215                     if (is_swimmer(mon->data) && mon->mundetected) {
5216                         mon->mundetected = 0;
5217                         newsym(x, y);
5218                     }
5219                 }
5220                 if (!lava) {
5221                     start_melt_ice_timeout(x, y, 0L);
5222                     obj_ice_effects(x, y, TRUE);
5223                 }
5224             } /* ?WATER */
5225
5226         } else if (is_ice(x, y)) {
5227             long melt_time;
5228
5229             /* Already ice here, so just firm it up. */
5230             /* Now ensure that only ice that is already timed is affected */
5231             if ((melt_time = spot_time_left(x, y, MELT_ICE_AWAY)) != 0L) {
5232                 spot_stop_timers(x, y, MELT_ICE_AWAY);
5233                 start_melt_ice_timeout(x, y, melt_time);
5234             }
5235         }
5236         break; /* ZT_COLD */
5237
5238     case ZT_POISON_GAS:
5239         (void) create_gas_cloud(x, y, 1, 8);
5240         break;
5241
5242     case ZT_ACID:
5243         if (lev->typ == IRONBARS) {
5244             if ((lev->wall_info & W_NONDIGGABLE) != 0) {
5245                 if (see_it)
5246 /*JP
5247                     Norep("The %s corrode somewhat but remain intact.",
5248 */
5249                     Norep("%s\82Í\8f­\82µ\92É\82ñ\82¾\82ª\82Ü\82¾\82µ\82Á\82©\82è\82µ\82Ä\82¢\82é\81D",
5250                           defsyms[S_bars].explanation);
5251                 /* but nothing actually happens... */
5252             } else {
5253                 rangemod -= 3;
5254                 if (see_it)
5255 /*JP
5256                     Norep("The %s melt.", defsyms[S_bars].explanation);
5257 */
5258                     Norep("%s\82ª\97n\82¯\82½\81D", defsyms[S_bars].explanation);
5259                 if (*in_rooms(x, y, SHOPBASE)) {
5260                     /* in case we ever have a shop bounded by bars */
5261                     lev->typ = ROOM, lev->flags = 0;
5262                     if (see_it)
5263                         newsym(x, y);
5264                     add_damage(x, y, (type >= 0) ? SHOP_BARS_COST : 0L);
5265                     if (type >= 0)
5266                         *shopdamage = TRUE;
5267                 } else {
5268                     lev->typ = DOOR, lev->doormask = D_NODOOR;
5269                     if (see_it)
5270                         newsym(x, y);
5271                 }
5272             }
5273         }
5274         break; /* ZT_ACID */
5275
5276     default:
5277         break;
5278     }
5279
5280     /* set up zap text for possible door feedback; for exploding wand, we
5281        want "the blast" rather than "your blast" even if hero caused it */
5282     yourzap = (type >= 0 && !exploding_wand_typ);
5283 #if 0 /*JP:T*/
5284     zapverb = "blast"; /* breath attack or wand explosion */
5285 #else
5286     zapverb = "\8fÕ\8c\82"; /* breath attack or wand explosion */
5287 #endif
5288     if (!exploding_wand_typ) {
5289         if (abs(type) < ZT_SPELL(0))
5290 #if 0 /*JP:T*/
5291             zapverb = "bolt"; /* wand zap */
5292 #else
5293             zapverb = "\8cõ\90ü"; /* wand zap */
5294 #endif
5295         else if (abs(type) < ZT_BREATH(0))
5296 /*JP
5297             zapverb = "spell";
5298 */
5299             zapverb = "\8eô\95¶";
5300     }
5301
5302     /* secret door gets revealed, converted into regular door */
5303     if (levl[x][y].typ == SDOOR) {
5304         cvt_sdoor_to_door(&levl[x][y]); /* .typ = DOOR */
5305         /* target spot will now pass closed_door() test below
5306            (except on rogue level) */
5307         newsym(x, y);
5308         if (see_it)
5309 #if 0 /*JP:T*/
5310             pline("%s %s reveals a secret door.",
5311                   yourzap ? "Your" : "The", zapverb);
5312 #else
5313             pline("%s\82Å\89B\82µ\94à\82ª\96¾\82ç\82©\82É\82È\82Á\82½\81D", zapverb);
5314 #endif
5315         else if (Is_rogue_level(&u.uz))
5316             draft_message(FALSE); /* "You feel a draft." (open doorway) */
5317     }
5318
5319     /* regular door absorbs remaining zap range, possibly gets destroyed */
5320     if (closed_door(x, y)) {
5321         int new_doormask = -1;
5322         const char *see_txt = 0, *sense_txt = 0, *hear_txt = 0;
5323
5324         rangemod = -1000;
5325         switch (abstype) {
5326         case ZT_FIRE:
5327             new_doormask = D_NODOOR;
5328 /*JP
5329             see_txt = "The door is consumed in flames!";
5330 */
5331             see_txt = "\94à\82Í\89\8a\82Å\8fÄ\82«\82Â\82­\82³\82ê\82½\81I";
5332 /*JP
5333             sense_txt = "smell smoke.";
5334 */
5335             sense_txt = "\89\8c\82Ì\93õ\82¢\82ª\82µ\82½\81D";
5336             break;
5337         case ZT_COLD:
5338             new_doormask = D_NODOOR;
5339 /*JP
5340             see_txt = "The door freezes and shatters!";
5341 */
5342             see_txt = "\94à\82Í\93\80\82è\81C\82±\82È\82²\82È\82É\82È\82Á\82½\81I";
5343 /*JP
5344             sense_txt = "feel cold.";
5345 */
5346             sense_txt = "\97â\8bC\82ð\8a´\82\82½\81D";
5347             break;
5348         case ZT_DEATH:
5349             /* death spells/wands don't disintegrate */
5350             if (abs(type) != ZT_BREATH(ZT_DEATH))
5351                 goto def_case;
5352             new_doormask = D_NODOOR;
5353 /*JP
5354             see_txt = "The door disintegrates!";
5355 */
5356             see_txt = "\94à\82Í\95²\8dÓ\82³\82ê\82½\81I";
5357 /*JP
5358             hear_txt = "crashing wood.";
5359 */
5360             hear_txt = "\96Ø\82Ì\89ó\82ê\82é\89¹\82ð\95·\82¢\82½\81D";
5361             break;
5362         case ZT_LIGHTNING:
5363             new_doormask = D_BROKEN;
5364 /*JP
5365             see_txt = "The door splinters!";
5366 */
5367             see_txt = "\94à\82Í\82¸\82½\82¸\82½\82É\82È\82Á\82½\81I";
5368 /*JP
5369             hear_txt = "crackling.";
5370 */
5371             hear_txt = "\83s\83L\83s\83L\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D";
5372             break;
5373         default:
5374  def_case:
5375             if (exploding_wand_typ > 0) {
5376                 /* Magical explosion from misc exploding wand */
5377                 if (exploding_wand_typ == WAN_STRIKING) {
5378                     new_doormask = D_BROKEN;
5379 /*JP
5380                     see_txt = "The door crashes open!";
5381 */
5382                     see_txt = "\94à\82Í\89ó\82ê\82Ä\8aJ\82¢\82½\81I";
5383 /*JP
5384                     sense_txt = "feel a burst of cool air.";
5385 */
5386                     sense_txt = "\97â\8bC\82Ì\8f[\96\9e\82ð\8a´\82\82½\81D";
5387                     break;
5388                 }
5389             }
5390             if (see_it) {
5391                 /* "the door absorbs the blast" would be
5392                    inaccurate for an exploding wand since
5393                    other adjacent locations still get hit */
5394                 if (exploding_wand_typ)
5395 /*JP
5396                     pline_The("door remains intact.");
5397 */
5398                     pline_The("\94à\82Í\96³\8f\9d\82¾\81D");
5399                 else
5400 #if 0 /*JP:T*/
5401                     pline_The("door absorbs %s %s!", yourzap ? "your" : "the",
5402                               zapverb);
5403 #else
5404                     pline_The("\94à\82Í%s%s\82ð\8bz\8eû\82µ\82½\81I", yourzap ? "\82 \82È\82½\82ª\95ú\82Á\82½" : "",
5405                               zapverb);
5406 #endif
5407             } else
5408 /*JP
5409                 You_feel("vibrations.");
5410 */
5411                 You("\90U\93®\82ð\8a´\82\82½\81D");
5412             break;
5413         }
5414         if (new_doormask >= 0) { /* door gets broken */
5415             if (*in_rooms(x, y, SHOPBASE)) {
5416                 if (type >= 0) {
5417                     add_damage(x, y, SHOP_DOOR_COST);
5418                     *shopdamage = TRUE;
5419                 } else /* caused by monster */
5420                     add_damage(x, y, 0L);
5421             }
5422             lev->doormask = new_doormask;
5423             unblock_point(x, y); /* vision */
5424             if (see_it) {
5425                 pline1(see_txt);
5426                 newsym(x, y);
5427             } else if (sense_txt) {
5428 #if 0 /*JP*//*\81u\82 \82È\82½\82Í\81v\82ª\95s\93K\90Ø\82È\95\82à\82 \82é*/
5429                 You1(sense_txt);
5430 #else
5431                 pline1(sense_txt);
5432 #endif
5433             } else if (hear_txt)
5434                 You_hear1(hear_txt);
5435             if (picking_at(x, y)) {
5436                 stop_occupation();
5437                 reset_pick();
5438             }
5439         }
5440     }
5441
5442     if (OBJ_AT(x, y) && abstype == ZT_FIRE)
5443         if (burn_floor_objects(x, y, FALSE, type > 0) && couldsee(x, y)) {
5444             newsym(x, y);
5445 /*JP
5446             You("%s of smoke.", !Blind ? "see a puff" : "smell a whiff");
5447 */
5448             pline("%s\81D", !Blind ? "\82Û\82í\82Á\82Æ\89\8c\82ª\82 \82ª\82Á\82½" : "\89\8c\82Ì\83v\83\93\82Æ\82¢\82¤\93õ\82¢\82ª\82µ\82½");
5449         }
5450     if ((mon = m_at(x, y)) != 0) {
5451         wakeup(mon, FALSE);
5452         if (type >= 0) {
5453             setmangry(mon, TRUE);
5454             if (mon->ispriest && *in_rooms(mon->mx, mon->my, TEMPLE))
5455                 ghod_hitsu(mon);
5456             if (mon->isshk && !*u.ushops)
5457                 hot_pursuit(mon);
5458         }
5459     }
5460     return rangemod;
5461 }
5462
5463 /* fractured by pick-axe or wand of striking */
5464 void
5465 fracture_rock(obj)
5466 register struct obj *obj; /* no texts here! */
5467 {
5468     xchar x, y;
5469     boolean by_you = !context.mon_moving;
5470
5471     if (by_you && get_obj_location(obj, &x, &y, 0) && costly_spot(x, y)) {
5472         struct monst *shkp = 0;
5473         char objroom = *in_rooms(x, y, SHOPBASE);
5474
5475         if (billable(&shkp, obj, objroom, FALSE)) {
5476             /* shop message says "you owe <shk> <$> for it!" so we need
5477                to precede that with a message explaining what "it" is */
5478 /*JP
5479             You("fracture %s %s.", s_suffix(shkname(shkp)), xname(obj));
5480 */
5481             You("%s\82Ì%s\82ð\89ó\82µ\82½\81D", shkname(shkp), xname(obj));
5482             breakobj(obj, x, y, TRUE, FALSE); /* charges for shop goods */
5483         }
5484     }
5485     if (by_you && obj->otyp == BOULDER)
5486         sokoban_guilt();
5487
5488     obj->otyp = ROCK;
5489     obj->oclass = GEM_CLASS;
5490     obj->quan = (long) rn1(60, 7);
5491     obj->owt = weight(obj);
5492     obj->dknown = obj->bknown = obj->rknown = 0;
5493     obj->known = objects[obj->otyp].oc_uses_known ? 0 : 1;
5494     dealloc_oextra(obj);
5495
5496     if (obj->where == OBJ_FLOOR) {
5497         obj_extract_self(obj); /* move rocks back on top */
5498         place_object(obj, obj->ox, obj->oy);
5499         if (!does_block(obj->ox, obj->oy, &levl[obj->ox][obj->oy]))
5500             unblock_point(obj->ox, obj->oy);
5501         if (cansee(obj->ox, obj->oy))
5502             newsym(obj->ox, obj->oy);
5503     }
5504 }
5505
5506 /* handle statue hit by striking/force bolt/pick-axe */
5507 boolean
5508 break_statue(obj)
5509 register struct obj *obj;
5510 {
5511     /* [obj is assumed to be on floor, so no get_obj_location() needed] */
5512     struct trap *trap = t_at(obj->ox, obj->oy);
5513     struct obj *item;
5514     boolean by_you = !context.mon_moving;
5515
5516     if (trap && trap->ttyp == STATUE_TRAP
5517         && activate_statue_trap(trap, obj->ox, obj->oy, TRUE))
5518         return FALSE;
5519     /* drop any objects contained inside the statue */
5520     while ((item = obj->cobj) != 0) {
5521         obj_extract_self(item);
5522         place_object(item, obj->ox, obj->oy);
5523     }
5524     if (by_you && Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC)) {
5525 /*JP
5526         You_feel("guilty about damaging such a historic statue.");
5527 */
5528         You_feel("\82±\82Ì\82æ\82¤\82È\97ð\8ej\93I\82È\92¤\91\9c\82É\8f\9d\82ð\82Â\82¯\82é\82Ì\82Í\8dß\90[\82¢\82±\82Æ\82¾\82Æ\8ev\82Á\82½\81D");
5529         adjalign(-1);
5530     }
5531     obj->spe = 0;
5532     fracture_rock(obj);
5533     return TRUE;
5534 }
5535
5536 /*
5537  * destroy_strings[dindx][0:singular,1:plural,2:killer_reason]
5538  *      [0] freezing potion
5539  *      [1] boiling potion other than oil
5540  *      [2] boiling potion of oil
5541  *      [3] burning scroll
5542  *      [4] burning spellbook
5543  *      [5] shocked ring
5544  *      [6] shocked wand
5545  * (books, rings, and wands don't stack so don't need plural form;
5546  *  crumbling ring doesn't do damage so doesn't need killer reason)
5547  */
5548 const char *const destroy_strings[][3] = {
5549     /* also used in trap.c */
5550 /*JP
5551     { "freezes and shatters", "freeze and shatter", "shattered potion" },
5552 */
5553     { "\93\80\8c\8b\82µ\82Ä\8dÓ\82¯\82½", "\93\80\8c\8b\82µ\82Ä\8dÓ\82¯\82½", "\8dÓ\82¯\82½\96ò\95r\82Å" },
5554 /*JP
5555     { "boils and explodes", "boil and explode", "boiling potion" },
5556 */
5557     { "\95¦\93«\82µ\82Ä\94\9a\94­\82µ\82½", "\95¦\93«\82µ\82Ä\94\9a\94­\82µ\82½", "\95¦\93«\82µ\82½\96ò\82Å" },
5558 /*JP
5559     { "ignites and explodes", "ignite and explode", "exploding potion" },
5560 */
5561     { "\89Î\82ª\82Â\82¢\82Ä\94\9a\94­\82µ\82½", "\89Î\82ª\82Â\82¢\82Ä\94\9a\94­\82µ\82½", "\94\9a\94­\82µ\82½\96ò\82Å" },
5562 /*JP
5563     { "catches fire and burns", "catch fire and burn", "burning scroll" },
5564 */
5565     { "\89Î\82ª\82Â\82¢\82Ä\94R\82¦\82½", "\89Î\82ª\82Â\82¢\82Ä\94R\82¦\82½", "\94R\82¦\82½\8aª\95¨\82Å" },
5566 /*JP
5567     { "catches fire and burns", "", "burning book" },
5568 */
5569     { "\89Î\82ª\82Â\82¢\82Ä\94R\82¦\82½", "\89Î\82ª\82Â\82¢\82Ä\94R\82¦\82½", "\94R\82¦\82½\96\82\96@\8f\91\82Å" },
5570 /*JP
5571     { "turns to dust and vanishes", "", "" },
5572 */
5573     { "\90o\82É\82È\82Á\82Ä\8fÁ\82¦\82½", "\90o\82É\82È\82Á\82Ä\8fÁ\82¦\82½", "" },
5574 /*JP
5575     { "breaks apart and explodes", "", "exploding wand" },
5576 */
5577     { "\82Î\82ç\82Î\82ç\82É\89ó\82ê\82Ä\94\9a\94­\82µ\82½", "\82Î\82ç\82Î\82ç\82É\89ó\82ê\82Ä\94\9a\94­\82µ\82½", "\8fñ\82Ì\94\9a\94­\82Å" },
5578 };
5579
5580 /* guts of destroy_item(), which ought to be called maybe_destroy_items();
5581    caller must decide whether obj is eligible */
5582 STATIC_OVL void
5583 destroy_one_item(obj, osym, dmgtyp)
5584 struct obj *obj;
5585 int osym, dmgtyp;
5586 {
5587     long i, cnt, quan;
5588     int dmg, xresist, skip, dindx;
5589     const char *mult;
5590     boolean physical_damage;
5591
5592     physical_damage = FALSE;
5593     xresist = skip = 0;
5594     /* lint suppression */
5595     dmg = dindx = 0;
5596     quan = 0L;
5597
5598     switch (dmgtyp) {
5599     case AD_COLD:
5600         if (osym == POTION_CLASS && obj->otyp != POT_OIL) {
5601             quan = obj->quan;
5602             dindx = 0;
5603             dmg = rnd(4);
5604         } else
5605             skip++;
5606         break;
5607     case AD_FIRE:
5608         xresist = (Fire_resistance && obj->oclass != POTION_CLASS
5609                    && obj->otyp != GLOB_OF_GREEN_SLIME);
5610         if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
5611             skip++;
5612         if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
5613             skip++;
5614             if (!Blind)
5615 #if 0 /*JP:T*/
5616                 pline("%s glows a strange %s, but remains intact.",
5617                       The(xname(obj)), hcolor("dark red"));
5618 #else
5619                 pline("%s\82Í\8aï\96­\82É%s\8bP\82¢\82½\82ª\89½\82à\95Ï\89»\82µ\82È\82©\82Á\82½\81D",
5620                       xname(obj), jconj_adj(hcolor("\88Ã\8a\8c\90F\82Ì")));
5621 #endif
5622         }
5623         quan = obj->quan;
5624         switch (osym) {
5625         case POTION_CLASS:
5626             dindx = (obj->otyp != POT_OIL) ? 1 : 2;
5627             dmg = rnd(6);
5628             break;
5629         case SCROLL_CLASS:
5630             dindx = 3;
5631             dmg = 1;
5632             break;
5633         case SPBOOK_CLASS:
5634             dindx = 4;
5635             dmg = 1;
5636             break;
5637         case FOOD_CLASS:
5638             if (obj->otyp == GLOB_OF_GREEN_SLIME) {
5639                 dindx = 1; /* boil and explode */
5640                 dmg = (obj->owt + 19) / 20;
5641             } else {
5642                 skip++;
5643             }
5644             break;
5645         default:
5646             skip++;
5647             break;
5648         }
5649         break;
5650     case AD_ELEC:
5651         xresist = (Shock_resistance && obj->oclass != RING_CLASS);
5652         quan = obj->quan;
5653         switch (osym) {
5654         case RING_CLASS:
5655             if (obj->otyp == RIN_SHOCK_RESISTANCE) {
5656                 skip++;
5657                 break;
5658             }
5659             dindx = 5;
5660             dmg = 0;
5661             break;
5662         case WAND_CLASS:
5663             if (obj->otyp == WAN_LIGHTNING) {
5664                 skip++;
5665                 break;
5666             }
5667 #if 0
5668             if (obj == current_wand) {  skip++;  break;  }
5669 #endif
5670             dindx = 6;
5671             dmg = rnd(10);
5672             break;
5673         default:
5674             skip++;
5675             break;
5676         }
5677         break;
5678     default:
5679         skip++;
5680         break;
5681     }
5682
5683     if (!skip) {
5684         if (obj->in_use)
5685             --quan; /* one will be used up elsewhere */
5686         for (i = cnt = 0L; i < quan; i++)
5687             if (!rn2(3))
5688                 cnt++;
5689
5690         if (!cnt)
5691             return;
5692 #if 0 /*JP:T*/
5693         mult = (cnt == 1L)
5694                 ? ((quan == 1L) ? "Your"                         /* 1 of 1 */
5695                                 : "One of your")                 /* 1 of N */
5696                 : ((cnt < quan) ? "Some of your"                 /* n of N */
5697                                 : (quan == 2L) ? "Both of your"  /* 2 of 2 */
5698                                                : "All of your"); /* N of N */
5699         pline("%s %s %s!", mult, xname(obj),
5700               destroy_strings[dindx][(cnt > 1L)]);
5701 #else
5702         mult = (cnt == 1L)
5703                 ? ((quan == 1L) ? ""                             /* 1 of 1 */
5704                                 : "\82Ì\82Ð\82Æ\82Â")                    /* 1 of N */
5705                 : ((cnt < quan) ? "\82Ì\82¢\82­\82Â\82©"                   /* n of N */
5706                                 : "\82Ì\91S\82Ä");                     /* N of N */
5707         pline("\82 \82È\82½\82Ì%s%s\82Í%s\81I", xname(obj), mult, 
5708               destroy_strings[dindx][(cnt > 1L)]);
5709 #endif
5710         if (osym == POTION_CLASS && dmgtyp != AD_COLD) {
5711             if (!breathless(youmonst.data) || haseyes(youmonst.data))
5712                 potionbreathe(obj);
5713         }
5714         if (obj->owornmask) {
5715             if (obj->owornmask & W_RING) /* ring being worn */
5716                 Ring_gone(obj);
5717             else
5718                 setnotworn(obj);
5719         }
5720         if (obj == current_wand)
5721             current_wand = 0; /* destroyed */
5722         for (i = 0; i < cnt; i++)
5723             useup(obj);
5724         if (dmg) {
5725             if (xresist) {
5726 /*JP
5727                 You("aren't hurt!");
5728 */
5729                 You("\8f\9d\82Â\82©\82È\82¢\81I");
5730             } else {
5731                 const char *how = destroy_strings[dindx][2];
5732                 boolean one = (cnt == 1L);
5733
5734                 if (dmgtyp == AD_FIRE && osym == FOOD_CLASS)
5735 /*JP
5736                     how = "exploding glob of slime";
5737 */
5738                     how = "\83X\83\89\83C\83\80\82Ì\82Ë\82Î\82Ë\82Î\82Ì\94\9a\94­\82Å";
5739                 if (physical_damage)
5740                     dmg = Maybe_Half_Phys(dmg);
5741                 losehp(dmg, one ? how : (const char *) makeplural(how),
5742                        one ? KILLED_BY_AN : KILLED_BY);
5743                 exercise(A_STR, FALSE);
5744             }
5745         }
5746     }
5747 }
5748
5749 /* target items of specified class for possible destruction */
5750 void
5751 destroy_item(osym, dmgtyp)
5752 int osym, dmgtyp;
5753 {
5754     register struct obj *obj;
5755     int i, deferral_indx = 0;
5756     /* 1+52+1: try to handle a full inventory; it doesn't matter if
5757       inventory actually has more, even if everything should be deferred */
5758     unsigned short deferrals[1 + 52 + 1]; /* +1: gold, overflow */
5759
5760     (void) memset((genericptr_t) deferrals, 0, sizeof deferrals);
5761     /*
5762      * Sometimes destroying an item can change inventory aside from
5763      * the item itself (cited case was a potion of unholy water; when
5764      * boiled, potionbreathe() caused hero to transform into were-beast
5765      * form and that resulted in dropping or destroying some worn armor).
5766      *
5767      * Unlike other uses of the object bybass mechanism, destroy_item()
5768      * can be called multiple times for the same event.  So we have to
5769      * explicitly clear it before each use and hope no other section of
5770      * code expects it to retain previous value.
5771      *
5772      * Destruction of a ring of levitation or form change which pushes
5773      * off levitation boots could drop hero onto a fire trap that
5774      * could destroy other items and we'll get called recursively.  Or
5775      * onto a trap which transports hero elsewhere, which won't disrupt
5776      * traversal but could yield message sequencing issues.  So we
5777      * defer handling such things until after rest of inventory has
5778      * been processed.  If some other combination of items and events
5779      * triggers a recursive call, rest of inventory after the triggering
5780      * item will be skipped by the outer call since the inner one will
5781      * have set the bypass bits of the whole list.
5782      *
5783      * [Unfortunately, death while poly'd into flyer and subsequent
5784      * rehumanization could also drop hero onto a trap, and there's no
5785      * straightforward way to defer that.  Things could be improved by
5786      * redoing this to use two passes, first to collect a list or array
5787      * of o_id and quantity of what is targetted for destruction,
5788      * second pass to handle the destruction.]
5789      */
5790     bypass_objlist(invent, FALSE); /* clear bypass bit for invent */
5791
5792     while ((obj = nxt_unbypassed_obj(invent)) != 0) {
5793         if (obj->oclass != osym)
5794             continue; /* test only objs of type osym */
5795         if (obj->oartifact)
5796             continue; /* don't destroy artifacts */
5797         if (obj->in_use && obj->quan == 1L)
5798             continue; /* not available */
5799
5800         /* if loss of this item might dump us onto a trap, hold off
5801            until later because potential recursive destroy_item() will
5802            result in setting bypass bits on whole chain--we would skip
5803            the rest as already processed once control returns here */
5804         if (deferral_indx < SIZE(deferrals)
5805             && ((obj->owornmask != 0L
5806                  && (objects[obj->otyp].oc_oprop == LEVITATION
5807                      || objects[obj->otyp].oc_oprop == FLYING))
5808                 /* destroyed wands and potions of polymorph don't trigger
5809                    polymorph so don't need to be deferred */
5810                 || (obj->otyp == POT_WATER && u.ulycn >= LOW_PM
5811                     && (Upolyd ? obj->blessed : obj->cursed)))) {
5812             deferrals[deferral_indx++] = obj->o_id;
5813             continue;
5814         }
5815         /* obj is eligible; maybe destroy it */
5816         destroy_one_item(obj, osym, dmgtyp);
5817     }
5818     /* if we saved some items for later (most likely just a worn ring
5819        of levitation) and they're still in inventory, handle them now */
5820     for (i = 0; i < deferral_indx; ++i) {
5821         /* note: obj->nobj is only referenced when obj is skipped;
5822            having obj be dropped or destroyed won't affect traversal */
5823         for (obj = invent; obj; obj = obj->nobj)
5824             if (obj->o_id == deferrals[i]) {
5825                 destroy_one_item(obj, osym, dmgtyp);
5826                 break;
5827             }
5828     }
5829     return;
5830 }
5831
5832 int
5833 destroy_mitem(mtmp, osym, dmgtyp)
5834 struct monst *mtmp;
5835 int osym, dmgtyp;
5836 {
5837     struct obj *obj;
5838     int skip, tmp = 0;
5839     long i, cnt, quan;
5840     int dindx;
5841     boolean vis;
5842
5843     if (mtmp == &youmonst) { /* this simplifies artifact_hit() */
5844         destroy_item(osym, dmgtyp);
5845         return 0; /* arbitrary; value doesn't matter to artifact_hit() */
5846     }
5847
5848     vis = canseemon(mtmp);
5849
5850     /* see destroy_item(); object destruction could disrupt inventory list */
5851     bypass_objlist(mtmp->minvent, FALSE); /* clear bypass bit for minvent */
5852
5853     while ((obj = nxt_unbypassed_obj(mtmp->minvent)) != 0) {
5854         if (obj->oclass != osym)
5855             continue; /* test only objs of type osym */
5856         skip = 0;
5857         quan = 0L;
5858         dindx = 0;
5859
5860         switch (dmgtyp) {
5861         case AD_COLD:
5862             if (osym == POTION_CLASS && obj->otyp != POT_OIL) {
5863                 quan = obj->quan;
5864                 dindx = 0;
5865                 tmp++;
5866             } else
5867                 skip++;
5868             break;
5869         case AD_FIRE:
5870             if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
5871                 skip++;
5872             if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
5873                 skip++;
5874                 if (vis)
5875 #if 0 /*JP:T*/
5876                     pline("%s glows a strange %s, but remains intact.",
5877                           The(distant_name(obj, xname)), hcolor("dark red"));
5878 #else
5879                     pline("%s\82Í\8aï\96­\82É%s\8bP\82¢\82½\82ª\89½\82à\95Ï\89»\82µ\82È\82©\82Á\82½\81D",
5880                           The(distant_name(obj, xname)), jconj_adj(hcolor("\88Ã\8a\8c\90F\82Ì")));
5881 #endif
5882             }
5883             quan = obj->quan;
5884             switch (osym) {
5885             case POTION_CLASS:
5886                 dindx = (obj->otyp != POT_OIL) ? 1 : 2;
5887                 tmp++;
5888                 break;
5889             case SCROLL_CLASS:
5890                 dindx = 3;
5891                 tmp++;
5892                 break;
5893             case SPBOOK_CLASS:
5894                 dindx = 4;
5895                 tmp++;
5896                 break;
5897             case FOOD_CLASS:
5898                 if (obj->otyp == GLOB_OF_GREEN_SLIME) {
5899                     dindx = 1; /* boil and explode */
5900                     tmp += (obj->owt + 19) / 20;
5901                 } else {
5902                     skip++;
5903                 }
5904                 break;
5905             default:
5906                 skip++;
5907                 break;
5908             }
5909             break;
5910         case AD_ELEC:
5911             quan = obj->quan;
5912             switch (osym) {
5913             case RING_CLASS:
5914                 if (obj->otyp == RIN_SHOCK_RESISTANCE) {
5915                     skip++;
5916                     break;
5917                 }
5918                 dindx = 5;
5919                 break;
5920             case WAND_CLASS:
5921                 if (obj->otyp == WAN_LIGHTNING) {
5922                     skip++;
5923                     break;
5924                 }
5925                 dindx = 6;
5926                 tmp++;
5927                 break;
5928             default:
5929                 skip++;
5930                 break;
5931             }
5932             break;
5933         default:
5934             skip++;
5935             break;
5936         }
5937         if (!skip) {
5938             for (i = cnt = 0L; i < quan; i++)
5939                 if (!rn2(3))
5940                     cnt++;
5941
5942             if (!cnt)
5943                 continue;
5944             if (vis)
5945 #if 0 /*JP:T*/
5946                 pline("%s%s %s!",
5947                       (cnt == obj->quan) ? "" : (cnt > 1L) ? "Some of "
5948                                                            : "One of ",
5949                       (cnt == obj->quan) ? Yname2(obj) : yname(obj),
5950                       destroy_strings[dindx][(cnt > 1L)]);
5951 #else
5952                 pline("%s%s\82Í%s\81I",
5953                       (cnt == obj->quan) ? Yname2(obj) : yname(obj),
5954                       (cnt == obj->quan) ? "" : (cnt > 1L) ? "\82Ì\82¢\82­\82Â\82©"
5955                                                            : "\82Ì\82Ð\82Æ\82Â",
5956                       destroy_strings[dindx][(cnt > 1L)]);
5957 #endif
5958             for (i = 0; i < cnt; i++)
5959                 m_useup(mtmp, obj);
5960         }
5961     }
5962     return tmp;
5963 }
5964
5965 int
5966 resist(mtmp, oclass, damage, tell)
5967 struct monst *mtmp;
5968 char oclass;
5969 int damage, tell;
5970 {
5971     int resisted;
5972     int alev, dlev;
5973
5974     /* fake players always pass resistance test against Conflict
5975        (this doesn't guarantee that they're never affected by it) */
5976     if (oclass == RING_CLASS && !damage && !tell && is_mplayer(mtmp->data))
5977         return 1;
5978
5979     /* attack level */
5980     switch (oclass) {
5981     case WAND_CLASS:
5982         alev = 12;
5983         break;
5984     case TOOL_CLASS:
5985         alev = 10;
5986         break; /* instrument */
5987     case WEAPON_CLASS:
5988         alev = 10;
5989         break; /* artifact */
5990     case SCROLL_CLASS:
5991         alev = 9;
5992         break;
5993     case POTION_CLASS:
5994         alev = 6;
5995         break;
5996     case RING_CLASS:
5997         alev = 5;
5998         break;
5999     default:
6000         alev = u.ulevel;
6001         break; /* spell */
6002     }
6003     /* defense level */
6004     dlev = (int) mtmp->m_lev;
6005     if (dlev > 50)
6006         dlev = 50;
6007     else if (dlev < 1)
6008         dlev = is_mplayer(mtmp->data) ? u.ulevel : 1;
6009
6010     resisted = rn2(100 + alev - dlev) < mtmp->data->mr;
6011     if (resisted) {
6012         if (tell) {
6013             shieldeff(mtmp->mx, mtmp->my);
6014 /*JP
6015             pline("%s resists!", Monnam(mtmp));
6016 */
6017             pline("%s\82Í\96h\82¢\82¾\81I", Monnam(mtmp));
6018         }
6019         damage = (damage + 1) / 2;
6020     }
6021
6022     if (damage) {
6023         mtmp->mhp -= damage;
6024         if (DEADMONSTER(mtmp)) {
6025             if (m_using)
6026                 monkilled(mtmp, "", AD_RBRE);
6027             else
6028                 killed(mtmp);
6029         }
6030     }
6031     return resisted;
6032 }
6033
6034 #define MAXWISHTRY 5
6035
6036 STATIC_OVL void
6037 wishcmdassist(triesleft)
6038 int triesleft;
6039 {
6040     static NEARDATA const char *
6041         wishinfo[] = {
6042   "Wish details:",
6043   "",
6044   "Enter the name of an object, such as \"potion of monster detection\",",
6045   "\"scroll labeled README\", \"elven mithril-coat\", or \"Grimtooth\"",
6046   "(without the quotes).",
6047   "",
6048   "For object types which come in stacks, you may specify a plural name",
6049   "such as \"potions of healing\", or specify a count, such as \"1000 gold",
6050   "pieces\", although that aspect of your wish might not be granted.",
6051   "",
6052   "You may also specify various prefix values which might be used to",
6053   "modify the item, such as \"uncursed\" or \"rustproof\" or \"+1\".",
6054   "Most modifiers shown when viewing your inventory can be specified.",
6055   "",
6056   "You may specify 'nothing' to explicitly decline this wish.",
6057   0,
6058     },
6059         preserve_wishless[] = "Doing so will preserve 'wishless' conduct.",
6060         retry_info[] =
6061                     "If you specify an unrecognized object name %s%s time%s,",
6062         retry_too[] = "a randomly chosen item will be granted.",
6063         suppress_cmdassist[] =
6064             "(Suppress this assistance with !cmdassist in your config file.)",
6065         *cardinals[] = { "zero",  "one",  "two", "three", "four", "five" },
6066         too_many[] = "too many";
6067     int i;
6068     winid win;
6069     char buf[BUFSZ];
6070
6071     win = create_nhwindow(NHW_TEXT);
6072     if (!win)
6073         return;
6074     for (i = 0; i < SIZE(wishinfo) - 1; ++i)
6075         putstr(win, 0, wishinfo[i]);
6076     if (!u.uconduct.wishes)
6077         putstr(win, 0, preserve_wishless);
6078     putstr(win, 0, "");
6079     Sprintf(buf, retry_info,
6080             (triesleft >= 0 && triesleft < SIZE(cardinals))
6081                ? cardinals[triesleft]
6082                : too_many,
6083             (triesleft < MAXWISHTRY) ? " more" : "",
6084             plur(triesleft));
6085     putstr(win, 0, buf);
6086     putstr(win, 0, retry_too);
6087     putstr(win, 0, "");
6088     if (iflags.cmdassist)
6089         putstr(win, 0, suppress_cmdassist);
6090     display_nhwindow(win, FALSE);
6091     destroy_nhwindow(win);
6092 }
6093
6094 void
6095 makewish()
6096 {
6097     char buf[BUFSZ] = DUMMY;
6098     char promptbuf[BUFSZ];
6099     struct obj *otmp, nothing;
6100     int tries = 0;
6101
6102     promptbuf[0] = '\0';
6103     nothing = zeroobj; /* lint suppression; only its address matters */
6104     if (flags.verbose)
6105 /*JP
6106         You("may wish for an object.");
6107 */
6108         You("\96]\82Ý\82Ì\82à\82Ì\82ð\8eè\82É\93ü\82ê\82ç\82ê\82é\81D");
6109  retry:
6110 /*JP
6111     Strcpy(promptbuf, "For what do you wish");
6112 */
6113     Strcpy(promptbuf, "(\93ú\96{\8cê\82Å)\89½\82ð\82¨\96]\82Ý");
6114     if (iflags.cmdassist && tries > 0)
6115 /*JP
6116         Strcat(promptbuf, " (enter 'help' for assistance)");
6117 */
6118         Strcat(promptbuf, " (\8f\95\82¯\82ª\95K\97v\82È\82ç 'help' \82Æ\93ü\97Í)");
6119 /*JP
6120     Strcat(promptbuf, "?");
6121 */
6122     Strcat(promptbuf, "\81H");
6123     getlin(promptbuf, buf);
6124     (void) mungspaces(buf);
6125     if (buf[0] == '\033') {
6126         buf[0] = '\0';
6127     } else if (!strcmpi(buf, "help")) {
6128         wishcmdassist(MAXWISHTRY - tries);
6129         buf[0] = '\0'; /* for EDIT_GETLIN */
6130         goto retry;
6131     }
6132     /*
6133      *  Note: if they wished for and got a non-object successfully,
6134      *  otmp == &zeroobj.  That includes gold, or an artifact that
6135      *  has been denied.  Wishing for "nothing" requires a separate
6136      *  value to remain distinct.
6137      */
6138     otmp = readobjnam(buf, &nothing);
6139     if (!otmp) {
6140 /*JP
6141         pline("Nothing fitting that description exists in the game.");
6142 */
6143         pline("\82¤\81[\82ñ\81D\82»\82ñ\82È\82à\82Ì\82Í\91\8dÝ\82µ\82È\82¢\82æ\82¤\82¾\81D");
6144         if (++tries < MAXWISHTRY)
6145             goto retry;
6146         pline1(thats_enough_tries);
6147         otmp = readobjnam((char *) 0, (struct obj *) 0);
6148         if (!otmp)
6149             return; /* for safety; should never happen */
6150     } else if (otmp == &nothing) {
6151         /* explicitly wished for "nothing", presumably attempting
6152            to retain wishless conduct */
6153         return;
6154     }
6155
6156     /* KMH, conduct */
6157     u.uconduct.wishes++;
6158
6159     if (otmp != &zeroobj) {
6160         const char
6161 /*JP
6162             *verb = ((Is_airlevel(&u.uz) || u.uinwater) ? "slip" : "drop"),
6163 */
6164             *verb = ((Is_airlevel(&u.uz) || u.uinwater) ? "\8a\8a\82è\97\8e\82¿\82½" : "\97\8e\82¿\82½"),
6165 #if 0 /*JP*/
6166             *oops_msg = (u.uswallow
6167                          ? "Oops!  %s out of your reach!"
6168                          : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
6169                             || levl[u.ux][u.uy].typ < IRONBARS
6170                             || levl[u.ux][u.uy].typ >= ICE)
6171                             ? "Oops!  %s away from you!"
6172                             : "Oops!  %s to the floor!");
6173
6174         /* The(aobjnam()) is safe since otmp is unidentified -dlc */
6175         (void) hold_another_object(otmp, oops_msg,
6176                                    The(aobjnam(otmp, verb)),
6177                                    (const char *) 0);
6178 #else
6179             *oops_msg = (u.uswallow
6180                          ? "\82¨\82Á\82Æ\81C%%s\82ª\93Í\82©\82È\82¢\82Æ\82±\82ë\82É%s\81I"
6181                          : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
6182                             || levl[u.ux][u.uy].typ < IRONBARS
6183                             || levl[u.ux][u.uy].typ >= ICE)
6184                             ? "\82¨\82Á\82Æ\81C%%s\82ª\8eè\82©\82ç%s\81I"
6185                             : "\82¨\82Á\82Æ\81C%%s\82ª\8f°\82É%s\81I");
6186         char oopsbuf[BUFSZ];
6187         Sprintf(oopsbuf, oops_msg, verb);
6188
6189         (void) hold_another_object(otmp, oopsbuf,
6190                                    xname(otmp),
6191                                    (const char *) 0);
6192 #endif
6193         u.ublesscnt += rn1(100, 50); /* the gods take notice */
6194     }
6195 }
6196
6197 /*zap.c*/