OSDN Git Service

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