OSDN Git Service

patch src/
[jnethack/source.git] / src / artifact.c
1 /* NetHack 3.6  artifact.c      $NHDT-Date: 1446369462 2015/11/01 09:17:42 $  $NHDT-Branch: master $:$NHDT-Revision: 1.96 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11 #include "artifact.h"
12 #include "artilist.h"
13
14 /*
15  * Note:  both artilist[] and artiexist[] have a dummy element #0,
16  *        so loops over them should normally start at #1.  The primary
17  *        exception is the save & restore code, which doesn't care about
18  *        the contents, just the total size.
19  */
20
21 extern boolean notonhead; /* for long worms */
22
23 #define get_artifact(o) \
24     (((o) && (o)->oartifact) ? &artilist[(int) (o)->oartifact] : 0)
25
26 STATIC_DCL boolean
27 FDECL(bane_applies, (const struct artifact *, struct monst *));
28 STATIC_DCL int FDECL(spec_applies, (const struct artifact *, struct monst *));
29 STATIC_DCL int FDECL(arti_invoke, (struct obj *));
30 STATIC_DCL boolean
31 FDECL(Mb_hit, (struct monst * magr, struct monst *mdef, struct obj *, int *,
32                int, BOOLEAN_P, char *));
33 STATIC_DCL unsigned long FDECL(abil_to_spfx, (long *));
34 STATIC_DCL uchar FDECL(abil_to_adtyp, (long *));
35 STATIC_DCL boolean FDECL(untouchable, (struct obj *, BOOLEAN_P));
36
37 /* The amount added to the victim's total hit points to insure that the
38    victim will be killed even after damage bonus/penalty adjustments.
39    Most such penalties are small, and 200 is plenty; the exception is
40    half physical damage.  3.3.1 and previous versions tried to use a very
41    large number to account for this case; now, we just compute the fatal
42    damage by adding it to 2 times the total hit points instead of 1 time.
43    Note: this will still break if they have more than about half the number
44    of hit points that will fit in a 15 bit integer. */
45 #define FATAL_DAMAGE_MODIFIER 200
46
47 /* coordinate effects from spec_dbon() with messages in artifact_hit() */
48 STATIC_OVL int spec_dbon_applies = 0;
49
50 /* flags including which artifacts have already been created */
51 static boolean artiexist[1 + NROFARTIFACTS + 1];
52 /* and a discovery list for them (no dummy first entry here) */
53 STATIC_OVL xchar artidisco[NROFARTIFACTS];
54
55 STATIC_DCL void NDECL(hack_artifacts);
56 STATIC_DCL boolean FDECL(attacks, (int, struct obj *));
57
58 /* handle some special cases; must be called after u_init() */
59 STATIC_OVL void
60 hack_artifacts()
61 {
62     struct artifact *art;
63     int alignmnt = aligns[flags.initalign].value;
64
65     /* Fix up the alignments of "gift" artifacts */
66     for (art = artilist + 1; art->otyp; art++)
67         if (art->role == Role_switch && art->alignment != A_NONE)
68             art->alignment = alignmnt;
69
70     /* Excalibur can be used by any lawful character, not just knights */
71     if (!Role_if(PM_KNIGHT))
72         artilist[ART_EXCALIBUR].role = NON_PM;
73
74     /* Fix up the quest artifact */
75     if (urole.questarti) {
76         artilist[urole.questarti].alignment = alignmnt;
77         artilist[urole.questarti].role = Role_switch;
78     }
79     return;
80 }
81
82 /* zero out the artifact existence list */
83 void
84 init_artifacts()
85 {
86     (void) memset((genericptr_t) artiexist, 0, sizeof artiexist);
87     (void) memset((genericptr_t) artidisco, 0, sizeof artidisco);
88     hack_artifacts();
89 }
90
91 void
92 save_artifacts(fd)
93 int fd;
94 {
95     bwrite(fd, (genericptr_t) artiexist, sizeof artiexist);
96     bwrite(fd, (genericptr_t) artidisco, sizeof artidisco);
97 }
98
99 void
100 restore_artifacts(fd)
101 int fd;
102 {
103     mread(fd, (genericptr_t) artiexist, sizeof artiexist);
104     mread(fd, (genericptr_t) artidisco, sizeof artidisco);
105     hack_artifacts(); /* redo non-saved special cases */
106 }
107
108 const char *
109 artiname(artinum)
110 int artinum;
111 {
112     if (artinum <= 0 || artinum > NROFARTIFACTS)
113         return "";
114     return artilist[artinum].name;
115 }
116
117 /*
118    Make an artifact.  If a specific alignment is specified, then an object of
119    the appropriate alignment is created from scratch, or 0 is returned if
120    none is available.  (If at least one aligned artifact has already been
121    given, then unaligned ones also become eligible for this.)
122    If no alignment is given, then 'otmp' is converted
123    into an artifact of matching type, or returned as-is if that's not
124    possible.
125    For the 2nd case, caller should use ``obj = mk_artifact(obj, A_NONE);''
126    for the 1st, ``obj = mk_artifact((struct obj *)0, some_alignment);''.
127  */
128 struct obj *
129 mk_artifact(otmp, alignment)
130 struct obj *otmp;   /* existing object; ignored if alignment specified */
131 aligntyp alignment; /* target alignment, or A_NONE */
132 {
133     const struct artifact *a;
134     int m, n, altn;
135     boolean by_align = (alignment != A_NONE);
136     short o_typ = (by_align || !otmp) ? 0 : otmp->otyp;
137     boolean unique = !by_align && otmp && objects[o_typ].oc_unique;
138     short eligible[NROFARTIFACTS];
139
140     n = altn = 0;    /* no candidates found yet */
141     eligible[0] = 0; /* lint suppression */
142     /* gather eligible artifacts */
143     for (m = 1, a = &artilist[m]; a->otyp; a++, m++) {
144         if (artiexist[m])
145             continue;
146         if ((a->spfx & SPFX_NOGEN) || unique)
147             continue;
148
149         if (!by_align) {
150             /* looking for a particular type of item; not producing a
151                divine gift so we don't care about role's first choice */
152             if (a->otyp == o_typ)
153                 eligible[n++] = m;
154             continue; /* move on to next possibility */
155         }
156
157         /* we're looking for an alignment-specific item
158            suitable for hero's role+race */
159         if ((a->alignment == alignment || a->alignment == A_NONE)
160             /* avoid enemies' equipment */
161             && (a->race == NON_PM || !race_hostile(&mons[a->race]))) {
162             /* when a role-specific first choice is available, use it */
163             if (Role_if(a->role)) {
164                 /* make this be the only possibility in the list */
165                 eligible[0] = m;
166                 n = 1;
167                 break; /* skip all other candidates */
168             }
169             /* found something to consider for random selection */
170             if (a->alignment != A_NONE || u.ugifts > 0) {
171                 /* right alignment, or non-aligned with at least 1
172                    previous gift bestowed, makes this one viable */
173                 eligible[n++] = m;
174             } else {
175                 /* non-aligned with no previous gifts;
176                    if no candidates have been found yet, record
177                    this one as a[nother] fallback possibility in
178                    case all aligned candidates have been used up
179                    (via wishing, naming, bones, random generation) */
180                 if (!n)
181                     eligible[altn++] = m;
182                 /* [once a regular candidate is found, the list
183                    is overwritten and `altn' becomes irrelevant] */
184             }
185         }
186     }
187
188     /* resort to fallback list if main list was empty */
189     if (!n)
190         n = altn;
191
192     if (n) {
193         /* found at least one candidate; pick one at random */
194         m = eligible[rn2(n)]; /* [0..n-1] */
195         a = &artilist[m];
196
197         /* make an appropriate object if necessary, then christen it */
198         if (by_align)
199             otmp = mksobj((int) a->otyp, TRUE, FALSE);
200
201         if (otmp) {
202             otmp = oname(otmp, a->name);
203             otmp->oartifact = m;
204             artiexist[m] = TRUE;
205         }
206     } else {
207         /* nothing appropriate could be found; return original object */
208         if (by_align)
209             otmp = 0; /* (there was no original object) */
210     }
211     return otmp;
212 }
213
214 /*
215  * Returns the full name (with articles and correct capitalization) of an
216  * artifact named "name" if one exists, or NULL, it not.
217  * The given name must be rather close to the real name for it to match.
218  * The object type of the artifact is returned in otyp if the return value
219  * is non-NULL.
220  */
221 const char *
222 artifact_name(name, otyp)
223 const char *name;
224 short *otyp;
225 {
226     register const struct artifact *a;
227     register const char *aname;
228
229     if (!strncmpi(name, "the ", 4))
230         name += 4;
231
232     for (a = artilist + 1; a->otyp; a++) {
233         aname = a->name;
234         if (!strncmpi(aname, "the ", 4))
235             aname += 4;
236         if (!strcmpi(name, aname)) {
237             *otyp = a->otyp;
238             return a->name;
239         }
240     }
241
242     return (char *) 0;
243 }
244
245 boolean
246 exist_artifact(otyp, name)
247 int otyp;
248 const char *name;
249 {
250     register const struct artifact *a;
251     boolean *arex;
252
253     if (otyp && *name)
254         for (a = artilist + 1, arex = artiexist + 1; a->otyp; a++, arex++)
255             if ((int) a->otyp == otyp && !strcmp(a->name, name))
256                 return *arex;
257     return FALSE;
258 }
259
260 void
261 artifact_exists(otmp, name, mod)
262 struct obj *otmp;
263 const char *name;
264 boolean mod;
265 {
266     register const struct artifact *a;
267
268     if (otmp && *name)
269         for (a = artilist + 1; a->otyp; a++)
270             if (a->otyp == otmp->otyp && !strcmp(a->name, name)) {
271                 register int m = (int) (a - artilist);
272                 otmp->oartifact = (char) (mod ? m : 0);
273                 otmp->age = 0;
274                 if (otmp->otyp == RIN_INCREASE_DAMAGE)
275                     otmp->spe = 0;
276                 artiexist[m] = mod;
277                 break;
278             }
279     return;
280 }
281
282 int
283 nartifact_exist()
284 {
285     int a = 0;
286     int n = SIZE(artiexist);
287
288     while (n > 1)
289         if (artiexist[--n])
290             a++;
291
292     return a;
293 }
294
295 boolean
296 spec_ability(otmp, abil)
297 struct obj *otmp;
298 unsigned long abil;
299 {
300     const struct artifact *arti = get_artifact(otmp);
301
302     return (boolean) (arti && (arti->spfx & abil) != 0L);
303 }
304
305 /* used so that callers don't need to known about SPFX_ codes */
306 boolean
307 confers_luck(obj)
308 struct obj *obj;
309 {
310     /* might as well check for this too */
311     if (obj->otyp == LUCKSTONE)
312         return TRUE;
313
314     return (boolean) (obj->oartifact && spec_ability(obj, SPFX_LUCK));
315 }
316
317 /* used to check whether a monster is getting reflection from an artifact */
318 boolean
319 arti_reflects(obj)
320 struct obj *obj;
321 {
322     const struct artifact *arti = get_artifact(obj);
323
324     if (arti) {
325         /* while being worn */
326         if ((obj->owornmask & ~W_ART) && (arti->spfx & SPFX_REFLECT))
327             return TRUE;
328         /* just being carried */
329         if (arti->cspfx & SPFX_REFLECT)
330             return TRUE;
331     }
332     return FALSE;
333 }
334
335 /* decide whether this obj is effective when attacking against shades;
336    does not consider the bonus for blessed objects versus undead */
337 boolean
338 shade_glare(obj)
339 struct obj *obj;
340 {
341     const struct artifact *arti;
342
343     /* any silver object is effective */
344     if (objects[obj->otyp].oc_material == SILVER)
345         return TRUE;
346     /* non-silver artifacts with bonus against undead also are effective */
347     arti = get_artifact(obj);
348     if (arti && (arti->spfx & SPFX_DFLAG2) && arti->mtype == M2_UNDEAD)
349         return TRUE;
350     /* [if there was anything with special bonus against noncorporeals,
351        it would be effective too] */
352     /* otherwise, harmless to shades */
353     return FALSE;
354 }
355
356 /* returns 1 if name is restricted for otmp->otyp */
357 boolean
358 restrict_name(otmp, name)
359 struct obj *otmp;
360 const char *name;
361 {
362     register const struct artifact *a;
363     const char *aname, *odesc, *other;
364     boolean sametype[NUM_OBJECTS];
365     int i, lo, hi, otyp = otmp->otyp, ocls = objects[otyp].oc_class;
366
367     if (!*name)
368         return FALSE;
369     if (!strncmpi(name, "the ", 4))
370         name += 4;
371
372     /* decide what types of objects are the same as otyp;
373        if it's been discovered, then only itself matches;
374        otherwise, include all other undiscovered objects
375        of the same class which have the same description
376        or share the same pool of shuffled descriptions */
377     (void) memset((genericptr_t) sametype, 0, sizeof sametype); /* FALSE */
378     sametype[otyp] = TRUE;
379     if (!objects[otyp].oc_name_known
380         && (odesc = OBJ_DESCR(objects[otyp])) != 0) {
381         obj_shuffle_range(otyp, &lo, &hi);
382         for (i = bases[ocls]; i < NUM_OBJECTS; i++) {
383             if (objects[i].oc_class != ocls)
384                 break;
385             if (!objects[i].oc_name_known
386                 && (other = OBJ_DESCR(objects[i])) != 0
387                 && (!strcmp(odesc, other) || (i >= lo && i <= hi)))
388                 sametype[i] = TRUE;
389         }
390     }
391
392     /* Since almost every artifact is SPFX_RESTR, it doesn't cost
393        us much to do the string comparison before the spfx check.
394        Bug fix:  don't name multiple elven daggers "Sting".
395      */
396     for (a = artilist + 1; a->otyp; a++) {
397         if (!sametype[a->otyp])
398             continue;
399         aname = a->name;
400         if (!strncmpi(aname, "the ", 4))
401             aname += 4;
402         if (!strcmp(aname, name))
403             return (boolean) ((a->spfx & (SPFX_NOGEN | SPFX_RESTR)) != 0
404                               || otmp->quan > 1L);
405     }
406
407     return FALSE;
408 }
409
410 STATIC_OVL boolean
411 attacks(adtyp, otmp)
412 int adtyp;
413 struct obj *otmp;
414 {
415     register const struct artifact *weap;
416
417     if ((weap = get_artifact(otmp)) != 0)
418         return (boolean) (weap->attk.adtyp == adtyp);
419     return FALSE;
420 }
421
422 boolean
423 defends(adtyp, otmp)
424 int adtyp;
425 struct obj *otmp;
426 {
427     register const struct artifact *weap;
428
429     if ((weap = get_artifact(otmp)) != 0)
430         return (boolean) (weap->defn.adtyp == adtyp);
431     return FALSE;
432 }
433
434 /* used for monsters */
435 boolean
436 defends_when_carried(adtyp, otmp)
437 int adtyp;
438 struct obj *otmp;
439 {
440     register const struct artifact *weap;
441
442     if ((weap = get_artifact(otmp)) != 0)
443         return (boolean) (weap->cary.adtyp == adtyp);
444     return FALSE;
445 }
446
447 /* determine whether an item confers Protection */
448 boolean
449 protects(otmp, being_worn)
450 struct obj *otmp;
451 boolean being_worn;
452 {
453     const struct artifact *arti;
454
455     if (being_worn && objects[otmp->otyp].oc_oprop == PROTECTION)
456         return TRUE;
457     arti = get_artifact(otmp);
458     if (!arti)
459         return FALSE;
460     return (boolean) ((arti->cspfx & SPFX_PROTECT) != 0
461                       || (being_worn && (arti->spfx & SPFX_PROTECT) != 0));
462 }
463
464 /*
465  * a potential artifact has just been worn/wielded/picked-up or
466  * unworn/unwielded/dropped.  Pickup/drop only set/reset the W_ART mask.
467  */
468 void
469 set_artifact_intrinsic(otmp, on, wp_mask)
470 register struct obj *otmp;
471 boolean on;
472 long wp_mask;
473 {
474     long *mask = 0;
475     register const struct artifact *oart = get_artifact(otmp);
476     register uchar dtyp;
477     register long spfx;
478
479     if (!oart)
480         return;
481
482     /* effects from the defn field */
483     dtyp = (wp_mask != W_ART) ? oart->defn.adtyp : oart->cary.adtyp;
484
485     if (dtyp == AD_FIRE)
486         mask = &EFire_resistance;
487     else if (dtyp == AD_COLD)
488         mask = &ECold_resistance;
489     else if (dtyp == AD_ELEC)
490         mask = &EShock_resistance;
491     else if (dtyp == AD_MAGM)
492         mask = &EAntimagic;
493     else if (dtyp == AD_DISN)
494         mask = &EDisint_resistance;
495     else if (dtyp == AD_DRST)
496         mask = &EPoison_resistance;
497
498     if (mask && wp_mask == W_ART && !on) {
499         /* find out if some other artifact also confers this intrinsic */
500         /* if so, leave the mask alone */
501         register struct obj *obj;
502         for (obj = invent; obj; obj = obj->nobj)
503             if (obj != otmp && obj->oartifact) {
504                 register const struct artifact *art = get_artifact(obj);
505                 if (art->cary.adtyp == dtyp) {
506                     mask = (long *) 0;
507                     break;
508                 }
509             }
510     }
511     if (mask) {
512         if (on)
513             *mask |= wp_mask;
514         else
515             *mask &= ~wp_mask;
516     }
517
518     /* intrinsics from the spfx field; there could be more than one */
519     spfx = (wp_mask != W_ART) ? oart->spfx : oart->cspfx;
520     if (spfx && wp_mask == W_ART && !on) {
521         /* don't change any spfx also conferred by other artifacts */
522         register struct obj *obj;
523         for (obj = invent; obj; obj = obj->nobj)
524             if (obj != otmp && obj->oartifact) {
525                 register const struct artifact *art = get_artifact(obj);
526                 spfx &= ~art->cspfx;
527             }
528     }
529
530     if (spfx & SPFX_SEARCH) {
531         if (on)
532             ESearching |= wp_mask;
533         else
534             ESearching &= ~wp_mask;
535     }
536     if (spfx & SPFX_HALRES) {
537         /* make_hallucinated must (re)set the mask itself to get
538          * the display right */
539         /* restoring needed because this is the only artifact intrinsic
540          * that can print a message--need to guard against being printed
541          * when restoring a game
542          */
543         (void) make_hallucinated((long) !on, restoring ? FALSE : TRUE,
544                                  wp_mask);
545     }
546     if (spfx & SPFX_ESP) {
547         if (on)
548             ETelepat |= wp_mask;
549         else
550             ETelepat &= ~wp_mask;
551         see_monsters();
552     }
553     if (spfx & SPFX_STLTH) {
554         if (on)
555             EStealth |= wp_mask;
556         else
557             EStealth &= ~wp_mask;
558     }
559     if (spfx & SPFX_REGEN) {
560         if (on)
561             ERegeneration |= wp_mask;
562         else
563             ERegeneration &= ~wp_mask;
564     }
565     if (spfx & SPFX_TCTRL) {
566         if (on)
567             ETeleport_control |= wp_mask;
568         else
569             ETeleport_control &= ~wp_mask;
570     }
571     if (spfx & SPFX_WARN) {
572         if (spec_m2(otmp)) {
573             if (on) {
574                 EWarn_of_mon |= wp_mask;
575                 context.warntype.obj |= spec_m2(otmp);
576             } else {
577                 EWarn_of_mon &= ~wp_mask;
578                 context.warntype.obj &= ~spec_m2(otmp);
579             }
580             see_monsters();
581         } else {
582             if (on)
583                 EWarning |= wp_mask;
584             else
585                 EWarning &= ~wp_mask;
586         }
587     }
588     if (spfx & SPFX_EREGEN) {
589         if (on)
590             EEnergy_regeneration |= wp_mask;
591         else
592             EEnergy_regeneration &= ~wp_mask;
593     }
594     if (spfx & SPFX_HSPDAM) {
595         if (on)
596             EHalf_spell_damage |= wp_mask;
597         else
598             EHalf_spell_damage &= ~wp_mask;
599     }
600     if (spfx & SPFX_HPHDAM) {
601         if (on)
602             EHalf_physical_damage |= wp_mask;
603         else
604             EHalf_physical_damage &= ~wp_mask;
605     }
606     if (spfx & SPFX_XRAY) {
607         /* this assumes that no one else is using xray_range */
608         if (on)
609             u.xray_range = 3;
610         else
611             u.xray_range = -1;
612         vision_full_recalc = 1;
613     }
614     if ((spfx & SPFX_REFLECT) && (wp_mask & W_WEP)) {
615         if (on)
616             EReflecting |= wp_mask;
617         else
618             EReflecting &= ~wp_mask;
619     }
620     if (spfx & SPFX_PROTECT) {
621         if (on)
622             EProtection |= wp_mask;
623         else
624             EProtection &= ~wp_mask;
625     }
626
627     if (wp_mask == W_ART && !on && oart->inv_prop) {
628         /* might have to turn off invoked power too */
629         if (oart->inv_prop <= LAST_PROP
630             && (u.uprops[oart->inv_prop].extrinsic & W_ARTI))
631             (void) arti_invoke(otmp);
632     }
633 }
634
635 /* touch_artifact()'s return value isn't sufficient to tell whether it
636    dished out damage, and tracking changes to u.uhp, u.mh, Lifesaved
637    when trying to avoid second wounding is too cumbersome */
638 STATIC_VAR boolean touch_blasted; /* for retouch_object() */
639
640 /*
641  * creature (usually hero) tries to touch (pick up or wield) an artifact obj.
642  * Returns 0 if the object refuses to be touched.
643  * This routine does not change any object chains.
644  * Ignores such things as gauntlets, assuming the artifact is not
645  * fooled by such trappings.
646  */
647 int
648 touch_artifact(obj, mon)
649 struct obj *obj;
650 struct monst *mon;
651 {
652     register const struct artifact *oart = get_artifact(obj);
653     boolean badclass, badalign, self_willed, yours;
654
655     touch_blasted = FALSE;
656     if (!oart)
657         return 1;
658
659     yours = (mon == &youmonst);
660     /* all quest artifacts are self-willed; it this ever changes, `badclass'
661        will have to be extended to explicitly include quest artifacts */
662     self_willed = ((oart->spfx & SPFX_INTEL) != 0);
663     if (yours) {
664         badclass = self_willed
665                    && ((oart->role != NON_PM && !Role_if(oart->role))
666                        || (oart->race != NON_PM && !Race_if(oart->race)));
667         badalign =
668             (oart->spfx & SPFX_RESTR) && oart->alignment != A_NONE
669             && (oart->alignment != u.ualign.type || u.ualign.record < 0);
670     } else if (!is_covetous(mon->data) && !is_mplayer(mon->data)) {
671         badclass = self_willed && oart->role != NON_PM
672                    && oart != &artilist[ART_EXCALIBUR];
673         badalign = (oart->spfx & SPFX_RESTR) && oart->alignment != A_NONE
674                    && (oart->alignment != mon_aligntyp(mon));
675     } else { /* an M3_WANTSxxx monster or a fake player */
676         /* special monsters trying to take the Amulet, invocation tools or
677            quest item can touch anything except `spec_applies' artifacts */
678         badclass = badalign = FALSE;
679     }
680     /* weapons which attack specific categories of monsters are
681        bad for them even if their alignments happen to match */
682     if (!badalign)
683         badalign = bane_applies(oart, mon);
684
685     if (((badclass || badalign) && self_willed)
686         || (badalign && (!yours || !rn2(4)))) {
687         int dmg, tmp;
688         char buf[BUFSZ];
689
690         if (!yours)
691             return 0;
692 /*JP
693         You("are blasted by %s power!", s_suffix(the(xname(obj))));
694 */
695         You("%s\82Ì\97Í\82ð\97\81\82Ñ\82½\81I", xname(obj));
696         touch_blasted = TRUE;
697         dmg = d((Antimagic ? 2 : 4), (self_willed ? 10 : 4));
698         /* add half (maybe quarter) of the usual silver damage bonus */
699         if (objects[obj->otyp].oc_material == SILVER && Hate_silver)
700             tmp = rnd(10), dmg += Maybe_Half_Phys(tmp);
701 /*JP
702         Sprintf(buf, "touching %s", oart->name);
703 */
704         Sprintf(buf, "%s\82É\90G\82ê\82Ä", oart->name);
705         losehp(dmg, buf, KILLED_BY); /* magic damage, not physical */
706         exercise(A_WIS, FALSE);
707     }
708
709     /* can pick it up unless you're totally non-synch'd with the artifact */
710     if (badclass && badalign && self_willed) {
711         if (yours) {
712             if (!carried(obj))
713 /*JP
714                 pline("%s your grasp!", Tobjnam(obj, "evade"));
715 */
716                 pline("%s\82Í\88¬\82ë\82¤\82Æ\82·\82é\82Æ\82·\82é\82è\82Æ\94²\82¯\82½\81I", xname(obj));
717             else
718 /*JP
719                 pline("%s beyond your control!", Tobjnam(obj, "are"));
720 */
721                 pline("%s\82Í\90§\8cä\82Å\82«\82È\82¢\81I", xname(obj));
722         }
723         return 0;
724     }
725
726     return 1;
727 }
728
729 /* decide whether an artifact itself is vulnerable to a particular type
730    of erosion damage, independent of the properties of its bearer */
731 boolean
732 arti_immune(obj, dtyp)
733 struct obj *obj;
734 int dtyp;
735 {
736     register const struct artifact *weap = get_artifact(obj);
737
738     if (!weap)
739         return FALSE;
740     if (dtyp == AD_PHYS)
741         return FALSE; /* nothing is immune to phys dmg */
742     return (boolean) (weap->attk.adtyp == dtyp
743                       || weap->defn.adtyp == dtyp
744                       || weap->cary.adtyp == dtyp);
745 }
746
747 STATIC_OVL boolean
748 bane_applies(oart, mon)
749 const struct artifact *oart;
750 struct monst *mon;
751 {
752     struct artifact atmp;
753
754     if (oart && (oart->spfx & SPFX_DBONUS) != 0) {
755         atmp = *oart;
756         atmp.spfx &= SPFX_DBONUS; /* clear other spfx fields */
757         if (spec_applies(&atmp, mon))
758             return TRUE;
759     }
760     return FALSE;
761 }
762
763 /* decide whether an artifact's special attacks apply against mtmp */
764 STATIC_OVL int
765 spec_applies(weap, mtmp)
766 register const struct artifact *weap;
767 struct monst *mtmp;
768 {
769     struct permonst *ptr;
770     boolean yours;
771
772     if (!(weap->spfx & (SPFX_DBONUS | SPFX_ATTK)))
773         return (weap->attk.adtyp == AD_PHYS);
774
775     yours = (mtmp == &youmonst);
776     ptr = mtmp->data;
777
778     if (weap->spfx & SPFX_DMONS) {
779         return (ptr == &mons[(int) weap->mtype]);
780     } else if (weap->spfx & SPFX_DCLAS) {
781         return (weap->mtype == (unsigned long) ptr->mlet);
782     } else if (weap->spfx & SPFX_DFLAG1) {
783         return ((ptr->mflags1 & weap->mtype) != 0L);
784     } else if (weap->spfx & SPFX_DFLAG2) {
785         return ((ptr->mflags2 & weap->mtype)
786                 || (yours
787                     && ((!Upolyd && (urace.selfmask & weap->mtype))
788                         || ((weap->mtype & M2_WERE) && u.ulycn >= LOW_PM))));
789     } else if (weap->spfx & SPFX_DALIGN) {
790         return yours ? (u.ualign.type != weap->alignment)
791                      : (ptr->maligntyp == A_NONE
792                         || sgn(ptr->maligntyp) != weap->alignment);
793     } else if (weap->spfx & SPFX_ATTK) {
794         struct obj *defending_weapon = (yours ? uwep : MON_WEP(mtmp));
795
796         if (defending_weapon && defending_weapon->oartifact
797             && defends((int) weap->attk.adtyp, defending_weapon))
798             return FALSE;
799         switch (weap->attk.adtyp) {
800         case AD_FIRE:
801             return !(yours ? Fire_resistance : resists_fire(mtmp));
802         case AD_COLD:
803             return !(yours ? Cold_resistance : resists_cold(mtmp));
804         case AD_ELEC:
805             return !(yours ? Shock_resistance : resists_elec(mtmp));
806         case AD_MAGM:
807         case AD_STUN:
808             return !(yours ? Antimagic : (rn2(100) < ptr->mr));
809         case AD_DRST:
810             return !(yours ? Poison_resistance : resists_poison(mtmp));
811         case AD_DRLI:
812             return !(yours ? Drain_resistance : resists_drli(mtmp));
813         case AD_STON:
814             return !(yours ? Stone_resistance : resists_ston(mtmp));
815         default:
816             impossible("Weird weapon special attack.");
817         }
818     }
819     return 0;
820 }
821
822 /* return the M2 flags of monster that an artifact's special attacks apply
823  * against */
824 long
825 spec_m2(otmp)
826 struct obj *otmp;
827 {
828     const struct artifact *artifact = get_artifact(otmp);
829
830     if (artifact)
831         return artifact->mtype;
832     return 0L;
833 }
834
835 /* special attack bonus */
836 int
837 spec_abon(otmp, mon)
838 struct obj *otmp;
839 struct monst *mon;
840 {
841     const struct artifact *weap = get_artifact(otmp);
842
843     /* no need for an extra check for `NO_ATTK' because this will
844        always return 0 for any artifact which has that attribute */
845
846     if (weap && weap->attk.damn && spec_applies(weap, mon))
847         return rnd((int) weap->attk.damn);
848     return 0;
849 }
850
851 /* special damage bonus */
852 int
853 spec_dbon(otmp, mon, tmp)
854 struct obj *otmp;
855 struct monst *mon;
856 int tmp;
857 {
858     register const struct artifact *weap = get_artifact(otmp);
859
860     if (!weap || (weap->attk.adtyp == AD_PHYS /* check for `NO_ATTK' */
861                   && weap->attk.damn == 0 && weap->attk.damd == 0))
862         spec_dbon_applies = FALSE;
863     else if (otmp->oartifact == ART_GRIMTOOTH)
864         /* Grimtooth has SPFX settings to warn against elves but we want its
865            damage bonus to apply to all targets, so bypass spec_applies() */
866         spec_dbon_applies = TRUE;
867     else
868         spec_dbon_applies = spec_applies(weap, mon);
869
870     if (spec_dbon_applies)
871         return weap->attk.damd ? rnd((int) weap->attk.damd) : max(tmp, 1);
872     return 0;
873 }
874
875 /* add identified artifact to discoveries list */
876 void
877 discover_artifact(m)
878 xchar m;
879 {
880     int i;
881
882     /* look for this artifact in the discoveries list;
883        if we hit an empty slot then it's not present, so add it */
884     for (i = 0; i < NROFARTIFACTS; i++)
885         if (artidisco[i] == 0 || artidisco[i] == m) {
886             artidisco[i] = m;
887             return;
888         }
889     /* there is one slot per artifact, so we should never reach the
890        end without either finding the artifact or an empty slot... */
891     impossible("couldn't discover artifact (%d)", (int) m);
892 }
893
894 /* used to decide whether an artifact has been fully identified */
895 boolean
896 undiscovered_artifact(m)
897 xchar m;
898 {
899     int i;
900
901     /* look for this artifact in the discoveries list;
902        if we hit an empty slot then it's undiscovered */
903     for (i = 0; i < NROFARTIFACTS; i++)
904         if (artidisco[i] == m)
905             return FALSE;
906         else if (artidisco[i] == 0)
907             break;
908     return TRUE;
909 }
910
911 /* display a list of discovered artifacts; return their count */
912 int
913 disp_artifact_discoveries(tmpwin)
914 winid tmpwin; /* supplied by dodiscover() */
915 {
916     int i, m, otyp;
917     char buf[BUFSZ];
918
919     for (i = 0; i < NROFARTIFACTS; i++) {
920         if (artidisco[i] == 0)
921             break; /* empty slot implies end of list */
922         if (tmpwin == WIN_ERR)
923             continue; /* for WIN_ERR, we just count */
924
925         if (i == 0)
926 /*JP
927             putstr(tmpwin, iflags.menu_headings, "Artifacts");
928 */
929             putstr(tmpwin, iflags.menu_headings, "\90¹\8aí");
930         m = artidisco[i];
931         otyp = artilist[m].otyp;
932         Sprintf(buf, "  %s [%s %s]", artiname(m),
933                 align_str(artilist[m].alignment), simple_typename(otyp));
934         putstr(tmpwin, 0, buf);
935     }
936     return i;
937 }
938
939 /*
940  * Magicbane's intrinsic magic is incompatible with normal
941  * enchantment magic.  Thus, its effects have a negative
942  * dependence on spe.  Against low mr victims, it typically
943  * does "double athame" damage, 2d4.  Occasionally, it will
944  * cast unbalancing magic which effectively averages out to
945  * 4d4 damage (3d4 against high mr victims), for spe = 0.
946  *
947  * Prior to 3.4.1, the cancel (aka purge) effect always
948  * included the scare effect too; now it's one or the other.
949  * Likewise, the stun effect won't be combined with either
950  * of those two; it will be chosen separately or possibly
951  * used as a fallback when scare or cancel fails.
952  *
953  * [Historical note: a change to artifact_hit() for 3.4.0
954  * unintentionally made all of Magicbane's special effects
955  * be blocked if the defender successfully saved against a
956  * stun attack.  As of 3.4.1, those effects can occur but
957  * will be slightly less likely than they were in 3.3.x.]
958  */
959 #define MB_MAX_DIEROLL 8 /* rolls above this aren't magical */
960 static const char *const mb_verb[2][4] = {
961 #if 0 /*JP*/
962     { "probe", "stun", "scare", "cancel" },
963     { "prod", "amaze", "tickle", "purge" },
964 #else
965     /* Mb_hit() \82Å "%s\82½"\82Ì\8c`\82Å\97\98\97p */
966     {"\92²\8d¸\82µ", "\82­\82ç\82­\82ç\82³\82¹", "\8b¯\82¦\82³\82¹", "\8fò\89»\82µ"},
967     { "\97ã\82Ü\82µ", "\8bÁ\82©\82¹", "\82­\82·\82®\82Á", "\90´\82ß" },
968 #endif
969 };
970 #define MB_INDEX_PROBE 0
971 #define MB_INDEX_STUN 1
972 #define MB_INDEX_SCARE 2
973 #define MB_INDEX_CANCEL 3
974
975 /* called when someone is being hit by Magicbane */
976 STATIC_OVL boolean
977 Mb_hit(magr, mdef, mb, dmgptr, dieroll, vis, hittee)
978 struct monst *magr, *mdef; /* attacker and defender */
979 struct obj *mb;            /* Magicbane */
980 int *dmgptr;               /* extra damage target will suffer */
981 int dieroll;               /* d20 that has already scored a hit */
982 boolean vis;               /* whether the action can be seen */
983 char *hittee;              /* target's name: "you" or mon_nam(mdef) */
984 {
985     struct permonst *old_uasmon;
986     const char *verb, *fakename;
987     boolean youattack = (magr == &youmonst), youdefend = (mdef == &youmonst),
988             resisted = FALSE, do_stun, do_confuse, result;
989     int attack_indx, scare_dieroll = MB_MAX_DIEROLL / 2;
990
991     result = FALSE; /* no message given yet */
992     /* the most severe effects are less likely at higher enchantment */
993     if (mb->spe >= 3)
994         scare_dieroll /= (1 << (mb->spe / 3));
995     /* if target successfully resisted the artifact damage bonus,
996        reduce overall likelihood of the assorted special effects */
997     if (!spec_dbon_applies)
998         dieroll += 1;
999
1000     /* might stun even when attempting a more severe effect, but
1001        in that case it will only happen if the other effect fails;
1002        extra damage will apply regardless; 3.4.1: sometimes might
1003        just probe even when it hasn't been enchanted */
1004     do_stun = (max(mb->spe, 0) < rn2(spec_dbon_applies ? 11 : 7));
1005
1006     /* the special effects also boost physical damage; increments are
1007        generally cumulative, but since the stun effect is based on a
1008        different criterium its damage might not be included; the base
1009        damage is either 1d4 (athame) or 2d4 (athame+spec_dbon) depending
1010        on target's resistance check against AD_STUN (handled by caller)
1011        [note that a successful save against AD_STUN doesn't actually
1012        prevent the target from ending up stunned] */
1013     attack_indx = MB_INDEX_PROBE;
1014     *dmgptr += rnd(4); /* (2..3)d4 */
1015     if (do_stun) {
1016         attack_indx = MB_INDEX_STUN;
1017         *dmgptr += rnd(4); /* (3..4)d4 */
1018     }
1019     if (dieroll <= scare_dieroll) {
1020         attack_indx = MB_INDEX_SCARE;
1021         *dmgptr += rnd(4); /* (3..5)d4 */
1022     }
1023     if (dieroll <= (scare_dieroll / 2)) {
1024         attack_indx = MB_INDEX_CANCEL;
1025         *dmgptr += rnd(4); /* (4..6)d4 */
1026     }
1027
1028     /* give the hit message prior to inflicting the effects */
1029     verb = mb_verb[!!Hallucination][attack_indx];
1030     if (youattack || youdefend || vis) {
1031         result = TRUE;
1032 #if 0 /*JP*/
1033         pline_The("magic-absorbing blade %s %s!",
1034                   vtense((const char *) 0, verb), hittee);
1035 #else
1036         pline("\96\82\97Í\82ð\8bz\82¢\82Æ\82é\90n\82ª%s\82ð%s\82½\81I",
1037                   hittee, verb);
1038 #endif
1039         /* assume probing has some sort of noticeable feedback
1040            even if it is being done by one monster to another */
1041         if (attack_indx == MB_INDEX_PROBE && !canspotmon(mdef))
1042             map_invisible(mdef->mx, mdef->my);
1043     }
1044
1045     /* now perform special effects */
1046     switch (attack_indx) {
1047     case MB_INDEX_CANCEL:
1048         old_uasmon = youmonst.data;
1049         /* No mdef->mcan check: even a cancelled monster can be polymorphed
1050          * into a golem, and the "cancel" effect acts as if some magical
1051          * energy remains in spellcasting defenders to be absorbed later.
1052          */
1053         if (!cancel_monst(mdef, mb, youattack, FALSE, FALSE)) {
1054             resisted = TRUE;
1055         } else {
1056             do_stun = FALSE;
1057             if (youdefend) {
1058                 if (youmonst.data != old_uasmon)
1059                     *dmgptr = 0; /* rehumanized, so no more damage */
1060                 if (u.uenmax > 0) {
1061 /*JP
1062                     You("lose magical energy!");
1063 */
1064                     You("\96\82\96@\82Ì\83G\83l\83\8b\83M\81[\82ð\8e¸\82Á\82½\81I");
1065                     u.uenmax--;
1066                     if (u.uen > 0)
1067                         u.uen--;
1068                     context.botl = 1;
1069                 }
1070             } else {
1071                 if (mdef->data == &mons[PM_CLAY_GOLEM])
1072                     mdef->mhp = 1; /* cancelled clay golems will die */
1073                 if (youattack && attacktype(mdef->data, AT_MAGC)) {
1074 /*JP
1075                     You("absorb magical energy!");
1076 */
1077                     You("\96\82\96@\82Ì\83G\83l\83\8b\83M\81[\82ð\8bz\82¢\82Æ\82Á\82½\81I");
1078                     u.uenmax++;
1079                     u.uen++;
1080                     context.botl = 1;
1081                 }
1082             }
1083         }
1084         break;
1085
1086     case MB_INDEX_SCARE:
1087         if (youdefend) {
1088             if (Antimagic) {
1089                 resisted = TRUE;
1090             } else {
1091                 nomul(-3);
1092                 multi_reason = "being scared stiff";
1093                 nomovemsg = "";
1094                 if (magr && magr == u.ustuck && sticks(youmonst.data)) {
1095                     u.ustuck = (struct monst *) 0;
1096 /*JP
1097                     You("release %s!", mon_nam(magr));
1098 */
1099                     You("%s\82ð\89ð\95ú\82µ\82½\81I", mon_nam(magr));
1100                 }
1101             }
1102         } else {
1103             if (rn2(2) && resist(mdef, WEAPON_CLASS, 0, NOTELL))
1104                 resisted = TRUE;
1105             else
1106                 monflee(mdef, 3, FALSE, (mdef->mhp > *dmgptr));
1107         }
1108         if (!resisted)
1109             do_stun = FALSE;
1110         break;
1111
1112     case MB_INDEX_STUN:
1113         do_stun = TRUE; /* (this is redundant...) */
1114         break;
1115
1116     case MB_INDEX_PROBE:
1117         if (youattack && (mb->spe == 0 || !rn2(3 * abs(mb->spe)))) {
1118 /*JP
1119             pline_The("%s is insightful.", verb);
1120 */
1121             pline("\91\8a\8eè\82ð%s\82½\81D", verb);
1122             /* pre-damage status */
1123             probe_monster(mdef);
1124         }
1125         break;
1126     }
1127     /* stun if that was selected and a worse effect didn't occur */
1128     if (do_stun) {
1129         if (youdefend)
1130             make_stunned(((HStun & TIMEOUT) + 3L), FALSE);
1131         else
1132             mdef->mstun = 1;
1133         /* avoid extra stun message below if we used mb_verb["stun"] above */
1134         if (attack_indx == MB_INDEX_STUN)
1135             do_stun = FALSE;
1136     }
1137     /* lastly, all this magic can be confusing... */
1138     do_confuse = !rn2(12);
1139     if (do_confuse) {
1140         if (youdefend)
1141             make_confused((HConfusion & TIMEOUT) + 4L, FALSE);
1142         else
1143             mdef->mconf = 1;
1144     }
1145
1146     /* now give message(s) describing side-effects;
1147        don't let vtense() be fooled by assigned name ending in 's' */
1148     fakename = youdefend ? "you" : "mon";
1149     if (youattack || youdefend || vis) {
1150         (void) upstart(hittee); /* capitalize */
1151         if (resisted) {
1152 /*JP
1153             pline("%s %s!", hittee, vtense(fakename, "resist"));
1154 */
1155             pline("%s\82Í\96h\82¢\82¾\81I", hittee);
1156             shieldeff(youdefend ? u.ux : mdef->mx,
1157                       youdefend ? u.uy : mdef->my);
1158         }
1159         if ((do_stun || do_confuse) && flags.verbose) {
1160             char buf[BUFSZ];
1161
1162             buf[0] = '\0';
1163 #if 0 /*JP:T*/
1164             if (do_stun)
1165                 Strcat(buf, "stunned");
1166             if (do_stun && do_confuse)
1167                 Strcat(buf, " and ");
1168             if (do_confuse)
1169                 Strcat(buf, "confused");
1170             pline("%s %s %s%c", hittee, vtense(fakename, "are"), buf,
1171                   (do_stun && do_confuse) ? '!' : '.');
1172 #else
1173             if (do_stun && do_confuse)
1174                 Strcat(buf, "\82æ\82ë\82ß\82¢\82Ä");
1175             else if (do_stun)
1176                 Strcat(buf, "\82æ\82ë\82ß\82¢\82½");
1177             if (do_confuse)
1178                 Strcat(buf, "\8d¬\97\90\82µ\82½");
1179             pline("%s\82Í%s%s", hittee,
1180                   buf, (do_stun && do_confuse) ? "\81I" : "\81D");
1181 #endif
1182         }
1183     }
1184
1185     return result;
1186 }
1187
1188 /* Function used when someone attacks someone else with an artifact
1189  * weapon.  Only adds the special (artifact) damage, and returns a 1 if it
1190  * did something special (in which case the caller won't print the normal
1191  * hit message).  This should be called once upon every artifact attack;
1192  * dmgval() no longer takes artifact bonuses into account.  Possible
1193  * extension: change the killer so that when an orc kills you with
1194  * Stormbringer it's "killed by Stormbringer" instead of "killed by an orc".
1195  */
1196 boolean
1197 artifact_hit(magr, mdef, otmp, dmgptr, dieroll)
1198 struct monst *magr, *mdef;
1199 struct obj *otmp;
1200 int *dmgptr;
1201 int dieroll; /* needed for Magicbane and vorpal blades */
1202 {
1203     boolean youattack = (magr == &youmonst);
1204     boolean youdefend = (mdef == &youmonst);
1205     boolean vis = (!youattack && magr && cansee(magr->mx, magr->my))
1206                   || (!youdefend && cansee(mdef->mx, mdef->my))
1207                   || (youattack && u.uswallow && mdef == u.ustuck && !Blind);
1208     boolean realizes_damage;
1209     const char *wepdesc;
1210 /*JP
1211     static const char you[] = "you";
1212 */
1213     static const char you[] = "\82 \82È\82½";
1214     char hittee[BUFSZ];
1215
1216     Strcpy(hittee, youdefend ? you : mon_nam(mdef));
1217
1218     /* The following takes care of most of the damage, but not all--
1219      * the exception being for level draining, which is specially
1220      * handled.  Messages are done in this function, however.
1221      */
1222     *dmgptr += spec_dbon(otmp, mdef, *dmgptr);
1223
1224     if (youattack && youdefend) {
1225         impossible("attacking yourself with weapon?");
1226         return FALSE;
1227     }
1228
1229     realizes_damage = (youdefend || vis
1230                        /* feel the effect even if not seen */
1231                        || (youattack && mdef == u.ustuck));
1232
1233     /* the four basic attacks: fire, cold, shock and missiles */
1234     if (attacks(AD_FIRE, otmp)) {
1235         if (realizes_damage)
1236 #if 0 /*JP*/
1237             pline_The("fiery blade %s %s%c",
1238                       !spec_dbon_applies
1239                           ? "hits"
1240                           : (mdef->data == &mons[PM_WATER_ELEMENTAL])
1241                                 ? "vaporizes part of"
1242                                 : "burns",
1243                       hittee, !spec_dbon_applies ? '.' : '!');
1244 #else
1245             pline_The("\96Ò\89Î\82ª%s%s",
1246                       hittee,
1247                       !spec_dbon_applies
1248                           ? "\82É\96½\92\86\82µ\82½\81D"
1249                           : (mdef->data == &mons[PM_WATER_ELEMENTAL])
1250                                 ? "\82Ì\88ê\95\94\82ð\8fÁ\96Å\82³\82¹\82½\81I"
1251                                 : "\82ð\8fÄ\82¢\82½\81I");
1252 #endif
1253         if (!rn2(4))
1254             (void) destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
1255         if (!rn2(4))
1256             (void) destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
1257         if (!rn2(7))
1258             (void) destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
1259         if (youdefend && Slimed)
1260             burn_away_slime();
1261         return realizes_damage;
1262     }
1263     if (attacks(AD_COLD, otmp)) {
1264         if (realizes_damage)
1265 #if 0 /*JP*/
1266             pline_The("ice-cold blade %s %s%c",
1267                       !spec_dbon_applies ? "hits" : "freezes", hittee,
1268                       !spec_dbon_applies ? '.' : '!');
1269 #else
1270             pline_The("\96Ò\90\81\90á\82ª%s%s",
1271                       hittee,
1272                       !spec_dbon_applies ? "\82É\96½\92\86\82µ\82½\81D" : "\82ð\8fP\82Á\82½\81I");
1273 #endif
1274         if (!rn2(4))
1275             (void) destroy_mitem(mdef, POTION_CLASS, AD_COLD);
1276         return realizes_damage;
1277     }
1278     if (attacks(AD_ELEC, otmp)) {
1279         if (realizes_damage)
1280 #if 0 /*JP*/
1281             pline_The("massive hammer hits%s %s%c",
1282                       !spec_dbon_applies ? "" : "!  Lightning strikes",
1283                       hittee, !spec_dbon_applies ? '.' : '!');
1284 #else
1285             pline("\8b\90\91å\82È\83n\83\93\83}\81[\82Í%s\82É\96½\92\86\82µ\82½%s", hittee,
1286                       !spec_dbon_applies ? "\81D" : "\81I\93d\8c\82\82ª\8fP\82Á\82½\81I");
1287 #endif
1288         if (!rn2(5))
1289             (void) destroy_mitem(mdef, RING_CLASS, AD_ELEC);
1290         if (!rn2(5))
1291             (void) destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
1292         return realizes_damage;
1293     }
1294     if (attacks(AD_MAGM, otmp)) {
1295         if (realizes_damage)
1296 #if 0 /*JP*/
1297             pline_The("imaginary widget hits%s %s%c",
1298                       !spec_dbon_applies
1299                           ? ""
1300                           : "!  A hail of magic missiles strikes",
1301                       hittee, !spec_dbon_applies ? '.' : '!');
1302 #else
1303             pline("\8eÀ\91Ì\82ð\8e\9d\82½\82È\82¢\95¨\91Ì\82ª%s\82ð\8dU\8c\82\82µ\82½%s",
1304                       hittee,
1305                       !spec_dbon_applies ? "\81D" :
1306                       "\81I\96\82\96@\82Ì\96î\82ª\89J\82 \82ç\82ê\82Æ\96½\92\86\82µ\82½\81I");
1307 #endif
1308         return realizes_damage;
1309     }
1310
1311     if (attacks(AD_STUN, otmp) && dieroll <= MB_MAX_DIEROLL) {
1312         /* Magicbane's special attacks (possibly modifies hittee[]) */
1313         return Mb_hit(magr, mdef, otmp, dmgptr, dieroll, vis, hittee);
1314     }
1315
1316     if (!spec_dbon_applies) {
1317         /* since damage bonus didn't apply, nothing more to do;
1318            no further attacks have side-effects on inventory */
1319         return FALSE;
1320     }
1321
1322     /* We really want "on a natural 20" but Nethack does it in */
1323     /* reverse from AD&D. */
1324     if (spec_ability(otmp, SPFX_BEHEAD)) {
1325         if (otmp->oartifact == ART_TSURUGI_OF_MURAMASA && dieroll == 1) {
1326 /*JP
1327             wepdesc = "The razor-sharp blade";
1328 */
1329             wepdesc = "\8ea\93S\8c\95";
1330             /* not really beheading, but so close, why add another SPFX */
1331             if (youattack && u.uswallow && mdef == u.ustuck) {
1332 /*JP
1333                 You("slice %s wide open!", mon_nam(mdef));
1334 */
1335                 You("%s\82ð\97Ö\90Ø\82è\82É\82µ\82½\81I", mon_nam(mdef));
1336                 *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
1337                 return TRUE;
1338             }
1339             if (!youdefend) {
1340                 /* allow normal cutworm() call to add extra damage */
1341                 if (notonhead)
1342                     return FALSE;
1343
1344                 if (bigmonst(mdef->data)) {
1345                     if (youattack)
1346 /*JP
1347                         You("slice deeply into %s!", mon_nam(mdef));
1348 */
1349                         You("%s\82É\90[\82­\8ea\82è\82Â\82¯\82½\81I",mon_nam(mdef));
1350                     else if (vis)
1351                         pline("%s cuts deeply into %s!", Monnam(magr),
1352                               hittee);
1353                     *dmgptr *= 2;
1354                     return TRUE;
1355                 }
1356                 *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
1357 /*JP
1358                 pline("%s cuts %s in half!", wepdesc, mon_nam(mdef));
1359 */
1360                 pline("%s\82ª%s\82ð\90^\82Á\93ñ\82Â\82É\82µ\82½\81I", wepdesc, mon_nam(mdef));
1361                 otmp->dknown = TRUE;
1362                 return TRUE;
1363             } else {
1364                 if (bigmonst(youmonst.data)) {
1365 /*JP
1366                     pline("%s cuts deeply into you!",
1367 */
1368                     pline("%s\82Í\82 \82È\82½\82É\90[\82­\8ea\82è\82Â\82¯\82½\81I",
1369                           magr ? Monnam(magr) : wepdesc);
1370                     *dmgptr *= 2;
1371                     return TRUE;
1372                 }
1373
1374                 /* Players with negative AC's take less damage instead
1375                  * of just not getting hit.  We must add a large enough
1376                  * value to the damage so that this reduction in
1377                  * damage does not prevent death.
1378                  */
1379                 *dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER;
1380 /*JP
1381                 pline("%s cuts you in half!", wepdesc);
1382 */
1383                 pline("%s\82ª\82 \82È\82½\82ð\90^\82Á\93ñ\82Â\82É\82µ\82½\81I", wepdesc);
1384                 otmp->dknown = TRUE;
1385                 return TRUE;
1386             }
1387         } else if (otmp->oartifact == ART_VORPAL_BLADE
1388                    && (dieroll == 1 || mdef->data == &mons[PM_JABBERWOCK])) {
1389 #if 0 /*JP*/
1390             static const char *const behead_msg[2] = { "%s beheads %s!",
1391                                                        "%s decapitates %s!" };
1392 #else
1393             static const char *const behead_msg[2] = { "%s\82Í%s\82Ì\8eñ\82ð\90Ø\82Á\82½\81I",
1394                                                        "%s\82Í%s\82Ì\8eñ\82ð\90Ø\82è\97\8e\82µ\82½\81I" };
1395 #endif
1396
1397             if (youattack && u.uswallow && mdef == u.ustuck)
1398                 return FALSE;
1399             wepdesc = artilist[ART_VORPAL_BLADE].name;
1400             if (!youdefend) {
1401                 if (!has_head(mdef->data) || notonhead || u.uswallow) {
1402                     if (youattack)
1403 /*JP
1404                         pline("Somehow, you miss %s wildly.", mon_nam(mdef));
1405 */
1406                         pline("\82È\82º\82©\81C%s\82Ö\82Ì\8dU\8c\82\82Í\91å\82«\82­\82Í\82¸\82ê\82½\81D", mon_nam(mdef));
1407                     else if (vis)
1408 /*JP
1409                         pline("Somehow, %s misses wildly.", mon_nam(magr));
1410 */
1411                         pline("\82È\82º\82©\81C%s\82Ì\8dU\8c\82\82Í\91å\82«\82­\82Í\82¸\82ê\82½\81D", mon_nam(magr));
1412                     *dmgptr = 0;
1413                     return (boolean) (youattack || vis);
1414                 }
1415                 if (noncorporeal(mdef->data) || amorphous(mdef->data)) {
1416 /*JP
1417                     pline("%s slices through %s %s.", wepdesc,
1418 */
1419                     pline("%s\82Í%s\82Ì%s\82ð\90Ø\82è\97\8e\82µ\82½\81D", wepdesc,
1420                           s_suffix(mon_nam(mdef)), mbodypart(mdef, NECK));
1421                     return TRUE;
1422                 }
1423                 *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
1424                 pline(behead_msg[rn2(SIZE(behead_msg))], wepdesc,
1425                       mon_nam(mdef));
1426                 if (Hallucination && !flags.female)
1427 /*JP
1428                     pline("Good job Henry, but that wasn't Anne.");
1429 */
1430                     pline("\83w\83\93\83\8a\81[\82æ\82­\82â\82Á\82½\81C\82¾\82ª\82»\82¢\82Â\82Í\83A\83\93\82\82á\82È\82¢\81D");
1431                 otmp->dknown = TRUE;
1432                 return TRUE;
1433             } else {
1434                 if (!has_head(youmonst.data)) {
1435 /*JP
1436                     pline("Somehow, %s misses you wildly.",
1437 */
1438                     pline("\82È\82º\82©\81C%s\82Ì\8dU\8c\82\82Í\91å\82«\82­\82Í\82¸\82ê\82½\81D",
1439                           magr ? mon_nam(magr) : wepdesc);
1440                     *dmgptr = 0;
1441                     return TRUE;
1442                 }
1443                 if (noncorporeal(youmonst.data) || amorphous(youmonst.data)) {
1444 /*JP
1445                     pline("%s slices through your %s.", wepdesc,
1446 */
1447                     pline("%s\82Í\82 \82È\82½\82Ì%s\82ð\90Ø\82è\97\8e\82µ\82½\81D", wepdesc,
1448                           body_part(NECK));
1449                     return TRUE;
1450                 }
1451                 *dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER;
1452 /*JP
1453                 pline(behead_msg[rn2(SIZE(behead_msg))], wepdesc, "you");
1454 */
1455                 pline(behead_msg[rn2(SIZE(behead_msg))], wepdesc, "\82 \82È\82½");
1456                 otmp->dknown = TRUE;
1457                 /* Should amulets fall off? */
1458                 return TRUE;
1459             }
1460         }
1461     }
1462     if (spec_ability(otmp, SPFX_DRLI)) {
1463         /* some non-living creatures (golems, vortices) are
1464            vulnerable to life drain effects */
1465 /*JP
1466         const char *life = nonliving(mdef->data) ? "animating force" : "life";
1467 */
1468         const char *life = nonliving(mdef->data) ? "\93®\8dì\97Í" : "\90\96½\97Í";
1469
1470         if (!youdefend) {
1471             if (vis) {
1472                 if (otmp->oartifact == ART_STORMBRINGER)
1473 #if 0 /*JP*/
1474                     pline_The("%s blade draws the %s from %s!",
1475                               hcolor(NH_BLACK), life, mon_nam(mdef));
1476 #else
1477                     pline("%s\90n\82ª%s\82Ì%s\82ð\92D\82Á\82½\81I",
1478                               hcolor(NH_BLACK), mon_nam(mdef), life);
1479 #endif
1480                 else
1481 #if 0 /*JP*/
1482                     pline("%s draws the %s from %s!",
1483                           The(distant_name(otmp, xname)), life,
1484                           mon_nam(mdef));
1485 #else
1486                     pline("%s\82Í%s\82Ì%s\82ð\92D\82Á\82½\81I",
1487                           The(distant_name(otmp, xname)),
1488                           mon_nam(mdef), life);
1489 #endif
1490             }
1491             if (mdef->m_lev == 0) {
1492                 *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
1493             } else {
1494                 int drain = monhp_per_lvl(mdef);
1495
1496                 *dmgptr += drain;
1497                 mdef->mhpmax -= drain;
1498                 mdef->m_lev--;
1499                 drain /= 2;
1500                 if (drain)
1501                     healup(drain, 0, FALSE, FALSE);
1502             }
1503             return vis;
1504         } else { /* youdefend */
1505             int oldhpmax = u.uhpmax;
1506
1507             if (Blind)
1508 #if 0 /*JP*/
1509                 You_feel("an %s drain your %s!",
1510                          (otmp->oartifact == ART_STORMBRINGER)
1511                             ? "unholy blade"
1512                             : "object",
1513                          life);
1514 #else
1515                 pline("%s\82É%s\82ð\92D\82í\82ê\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I",
1516                          (otmp->oartifact == ART_STORMBRINGER)
1517                             ? "\95s\8fò\82È\90n"
1518                             : "\89½\82©",
1519                          life);
1520 #endif
1521             else if (otmp->oartifact == ART_STORMBRINGER)
1522 /*JP
1523                 pline_The("%s blade drains your %s!", hcolor(NH_BLACK), life);
1524 */
1525                 pline("%s\90n\82ª\82 \82È\82½\82Ì%s\82ð\92D\82Á\82½\81I", hcolor(NH_BLACK), life);
1526             else
1527 #if 0 /*JP*/
1528                 pline("%s drains your %s!", The(distant_name(otmp, xname)),
1529                       life);
1530 #else
1531                 pline("%s\82ª\82 \82È\82½\82Ì%s\82ð\92D\82Á\82½\81I", The(distant_name(otmp, xname)),
1532                       life);
1533 #endif
1534 /*JP
1535             losexp("life drainage");
1536 */
1537             losexp("\90\96½\97Í\82ð\8bz\8eû\82³\82ê\82Ä");
1538             if (magr && magr->mhp < magr->mhpmax) {
1539                 magr->mhp += (oldhpmax - u.uhpmax) / 2;
1540                 if (magr->mhp > magr->mhpmax)
1541                     magr->mhp = magr->mhpmax;
1542             }
1543             return TRUE;
1544         }
1545     }
1546     return FALSE;
1547 }
1548
1549 static NEARDATA const char recharge_type[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
1550 static NEARDATA const char invoke_types[] = { ALL_CLASSES, 0 };
1551 /* #invoke: an "ugly check" filters out most objects */
1552
1553 /* the #invoke command */
1554 int
1555 doinvoke()
1556 {
1557     struct obj *obj;
1558
1559     obj = getobj(invoke_types, "invoke");
1560     if (!obj)
1561         return 0;
1562     if (!retouch_object(&obj, FALSE))
1563         return 1;
1564     return arti_invoke(obj);
1565 }
1566
1567 STATIC_OVL int
1568 arti_invoke(obj)
1569 struct obj *obj;
1570 {
1571     register const struct artifact *oart = get_artifact(obj);
1572     if (!obj) {
1573         impossible("arti_invoke without obj");
1574         return 0;
1575     }
1576     if (!oart || !oart->inv_prop) {
1577         if (obj->otyp == CRYSTAL_BALL)
1578             use_crystal_ball(&obj);
1579         else
1580             pline1(nothing_happens);
1581         return 1;
1582     }
1583
1584     if (oart->inv_prop > LAST_PROP) {
1585         /* It's a special power, not "just" a property */
1586         if (obj->age > monstermoves) {
1587             /* the artifact is tired :-) */
1588 #if 0 /*JP:T*/
1589             You_feel("that %s %s ignoring you.", the(xname(obj)),
1590                      otense(obj, "are"));
1591 #else
1592             You_feel("%s\82ª\96³\8e\8b\82µ\82Ä\82¢\82é\82æ\82¤\82É\8a´\82\82½\81D", xname(obj));
1593 #endif
1594             /* and just got more so; patience is essential... */
1595             obj->age += (long) d(3, 10);
1596             return 1;
1597         }
1598         obj->age = monstermoves + rnz(100);
1599
1600         switch (oart->inv_prop) {
1601         case TAMING: {
1602             struct obj pseudo;
1603
1604             pseudo =
1605                 zeroobj; /* neither cursed nor blessed, zero oextra too */
1606             pseudo.otyp = SCR_TAMING;
1607             (void) seffects(&pseudo);
1608             break;
1609         }
1610         case HEALING: {
1611             int healamt = (u.uhpmax + 1 - u.uhp) / 2;
1612             long creamed = (long) u.ucreamed;
1613
1614             if (Upolyd)
1615                 healamt = (u.mhmax + 1 - u.mh) / 2;
1616             if (healamt || Sick || Slimed || Blinded > creamed)
1617 /*JP
1618                 You_feel("better.");
1619 */
1620                 You_feel("\8bC\95ª\82ª\82æ\82­\82È\82Á\82½\81D");
1621             else
1622                 goto nothing_special;
1623             if (healamt > 0) {
1624                 if (Upolyd)
1625                     u.mh += healamt;
1626                 else
1627                     u.uhp += healamt;
1628             }
1629             if (Sick)
1630                 make_sick(0L, (char *) 0, FALSE, SICK_ALL);
1631             if (Slimed)
1632                 make_slimed(0L, (char *) 0);
1633             if (Blinded > creamed)
1634                 make_blinded(creamed, FALSE);
1635             context.botl = 1;
1636             break;
1637         }
1638         case ENERGY_BOOST: {
1639             int epboost = (u.uenmax + 1 - u.uen) / 2;
1640             if (epboost > 120)
1641                 epboost = 120; /* arbitrary */
1642             else if (epboost < 12)
1643                 epboost = u.uenmax - u.uen;
1644             if (epboost) {
1645 /*JP
1646                 You_feel("re-energized.");
1647 */
1648                 You("\83G\83l\83\8b\83M\81[\82Å\96\9e\82½\82³\82ê\82½\81D");
1649                 u.uen += epboost;
1650                 context.botl = 1;
1651             } else
1652                 goto nothing_special;
1653             break;
1654         }
1655         case UNTRAP: {
1656             if (!untrap(TRUE)) {
1657                 obj->age = 0; /* don't charge for changing their mind */
1658                 return 0;
1659             }
1660             break;
1661         }
1662         case CHARGE_OBJ: {
1663             struct obj *otmp = getobj(recharge_type, "charge");
1664             boolean b_effect;
1665
1666             if (!otmp) {
1667                 obj->age = 0;
1668                 return 0;
1669             }
1670             b_effect =
1671                 obj->blessed && (Role_switch == oart->role || !oart->role);
1672             recharge(otmp, b_effect ? 1 : obj->cursed ? -1 : 0);
1673             update_inventory();
1674             break;
1675         }
1676         case LEV_TELE:
1677             level_tele();
1678             break;
1679         case CREATE_PORTAL: {
1680             int i, num_ok_dungeons, last_ok_dungeon = 0;
1681             d_level newlev;
1682             extern int n_dgns; /* from dungeon.c */
1683             winid tmpwin = create_nhwindow(NHW_MENU);
1684             anything any;
1685
1686             any = zeroany; /* set all bits to zero */
1687             start_menu(tmpwin);
1688             /* use index+1 (cant use 0) as identifier */
1689             for (i = num_ok_dungeons = 0; i < n_dgns; i++) {
1690                 if (!dungeons[i].dunlev_ureached)
1691                     continue;
1692                 any.a_int = i + 1;
1693                 add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
1694                          dungeons[i].dname, MENU_UNSELECTED);
1695                 num_ok_dungeons++;
1696                 last_ok_dungeon = i;
1697             }
1698 /*JP
1699             end_menu(tmpwin, "Open a portal to which dungeon?");
1700 */
1701             end_menu(tmpwin, "\82Ç\82Ì\96À\8b{\82Ö\82Ì\96\82\96@\82Ì\93ü\8cû\82ð\8aJ\82«\82Ü\82·\82©\81H");
1702             if (num_ok_dungeons > 1) {
1703                 /* more than one entry; display menu for choices */
1704                 menu_item *selected;
1705                 int n;
1706
1707                 n = select_menu(tmpwin, PICK_ONE, &selected);
1708                 if (n <= 0) {
1709                     destroy_nhwindow(tmpwin);
1710                     goto nothing_special;
1711                 }
1712                 i = selected[0].item.a_int - 1;
1713                 free((genericptr_t) selected);
1714             } else
1715                 i = last_ok_dungeon; /* also first & only OK dungeon */
1716             destroy_nhwindow(tmpwin);
1717
1718             /*
1719              * i is now index into dungeon structure for the new dungeon.
1720              * Find the closest level in the given dungeon, open
1721              * a use-once portal to that dungeon and go there.
1722              * The closest level is either the entry or dunlev_ureached.
1723              */
1724             newlev.dnum = i;
1725             if (dungeons[i].depth_start >= depth(&u.uz))
1726                 newlev.dlevel = dungeons[i].entry_lev;
1727             else
1728                 newlev.dlevel = dungeons[i].dunlev_ureached;
1729
1730             if (u.uhave.amulet || In_endgame(&u.uz) || In_endgame(&newlev)
1731                 || newlev.dnum == u.uz.dnum || !next_to_u()) {
1732 /*JP
1733                 You_feel("very disoriented for a moment.");
1734 */
1735                 You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\81D");
1736             } else {
1737                 if (!Blind)
1738 /*JP
1739                     You("are surrounded by a shimmering sphere!");
1740 */
1741                     You("\83`\83J\83`\83J\8cõ\82é\8b\85\91Ì\82É\95¢\82í\82ê\82½\81I");
1742                 else
1743 /*JP
1744                     You_feel("weightless for a moment.");
1745 */
1746                     You_feel("\88ê\8fu\81C\96³\8fd\97Í\8a´\82ð\8a´\82\82½\81D");
1747                 goto_level(&newlev, FALSE, FALSE, FALSE);
1748             }
1749             break;
1750         }
1751         case ENLIGHTENING:
1752             enlightenment(MAGICENLIGHTENMENT, ENL_GAMEINPROGRESS);
1753             break;
1754         case CREATE_AMMO: {
1755             struct obj *otmp = mksobj(ARROW, TRUE, FALSE);
1756
1757             if (!otmp)
1758                 goto nothing_special;
1759             otmp->blessed = obj->blessed;
1760             otmp->cursed = obj->cursed;
1761             otmp->bknown = obj->bknown;
1762             if (obj->blessed) {
1763                 if (otmp->spe < 0)
1764                     otmp->spe = 0;
1765                 otmp->quan += rnd(10);
1766             } else if (obj->cursed) {
1767                 if (otmp->spe > 0)
1768                     otmp->spe = 0;
1769             } else
1770                 otmp->quan += rnd(5);
1771             otmp->owt = weight(otmp);
1772             otmp =
1773 #if 0 /*JP*/
1774                 hold_another_object(otmp, "Suddenly %s out.",
1775                                     aobjnam(otmp, "fall"), (const char *) 0);
1776 #else
1777                 hold_another_object(otmp, "\93Ë\91R%s\82ª\97\8e\82¿\82½\81D",
1778                                     xname(otmp), 0);
1779 #endif
1780             break;
1781         }
1782         }
1783     } else {
1784         long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI),
1785              iprop = u.uprops[oart->inv_prop].intrinsic;
1786         boolean on = (eprop & W_ARTI) != 0; /* true if prop just set */
1787
1788         if (on && obj->age > monstermoves) {
1789             /* the artifact is tired :-) */
1790             u.uprops[oart->inv_prop].extrinsic ^= W_ARTI;
1791 #if 0 /*JP:T*/
1792             You_feel("that %s %s ignoring you.", the(xname(obj)),
1793                      otense(obj, "are"));
1794 #else
1795             You_feel("%s\82ª\96³\8e\8b\82µ\82Ä\82¢\82é\82æ\82¤\82É\8a´\82\82½\81D", xname(obj));
1796 #endif
1797             /* can't just keep repeatedly trying */
1798             obj->age += (long) d(3, 10);
1799             return 1;
1800         } else if (!on) {
1801             /* when turning off property, determine downtime */
1802             /* arbitrary for now until we can tune this -dlc */
1803             obj->age = monstermoves + rnz(100);
1804         }
1805
1806         if ((eprop & ~W_ARTI) || iprop) {
1807         nothing_special:
1808             /* you had the property from some other source too */
1809             if (carried(obj))
1810 /*JP
1811                 You_feel("a surge of power, but nothing seems to happen.");
1812 */
1813                 You("\97Í\82Ì\8d\82\82Ü\82è\82ð\8a´\82\82½\82ª\81C\89½\82à\8bN\82«\82È\82©\82Á\82½\82æ\82¤\82¾\81D");
1814             return 1;
1815         }
1816         switch (oart->inv_prop) {
1817         case CONFLICT:
1818             if (on)
1819 /*JP
1820                 You_feel("like a rabble-rouser.");
1821 */
1822                 You("\96¯\8fO\90î\93®\89Æ\82Ì\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1823             else
1824 /*JP
1825                 You_feel("the tension decrease around you.");
1826 */
1827                 pline("\82Ü\82í\82è\82Ì\8bÙ\92£\8a´\82ª\82È\82­\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
1828             break;
1829         case LEVITATION:
1830             if (on) {
1831                 float_up();
1832                 spoteffects(FALSE);
1833             } else
1834                 (void) float_down(I_SPECIAL | TIMEOUT, W_ARTI);
1835             break;
1836         case INVIS:
1837             if (BInvis || Blind)
1838                 goto nothing_special;
1839             newsym(u.ux, u.uy);
1840             if (on)
1841 #if 0 /*JP*/
1842                 Your("body takes on a %s transparency...",
1843                      Hallucination ? "normal" : "strange");
1844 #else
1845                 pline("%s\81C\91Ì\82Í\93§\89ß\90«\82ð\82à\82Á\82½\81D\81D\81D",
1846                       Hallucination ? "\82 \82½\82è\82Ü\82¦\82Ì\82±\82Æ\82¾\82ª" : "\8aï\96­\82È\82±\82Æ\82É");
1847 #endif
1848             else
1849 /*JP
1850                 Your("body seems to unfade...");
1851 */
1852                 Your("\91Ì\82Í\8e\9f\91æ\82É\8c©\82¦\82é\82æ\82¤\82É\82È\82Á\82Ä\82«\82½\81D\81D\81D");
1853             break;
1854         }
1855     }
1856
1857     return 1;
1858 }
1859
1860 /* will freeing this object from inventory cause levitation to end? */
1861 boolean
1862 finesse_ahriman(obj)
1863 struct obj *obj;
1864 {
1865     const struct artifact *oart;
1866     struct prop save_Lev;
1867     boolean result;
1868
1869     /* if we aren't levitating or this isn't an artifact which confers
1870        levitation via #invoke then freeinv() won't toggle levitation */
1871     if (!Levitation || (oart = get_artifact(obj)) == 0
1872         || oart->inv_prop != LEVITATION || !(ELevitation & W_ARTI))
1873         return FALSE;
1874
1875     /* arti_invoke(off) -> float_down() clears I_SPECIAL|TIMEOUT & W_ARTI;
1876        probe ahead to see whether that actually results in floating down;
1877        (this assumes that there aren't two simultaneously invoked artifacts
1878        both conferring levitation--safe, since if there were two of them,
1879        invoking the 2nd would negate the 1st rather than stack with it) */
1880     save_Lev = u.uprops[LEVITATION];
1881     HLevitation &= ~(I_SPECIAL | TIMEOUT);
1882     ELevitation &= ~W_ARTI;
1883     result = (boolean) !Levitation;
1884     u.uprops[LEVITATION] = save_Lev;
1885     return result;
1886 }
1887
1888 /* WAC return TRUE if artifact is always lit */
1889 boolean
1890 artifact_light(obj)
1891 struct obj *obj;
1892 {
1893     return (boolean) (get_artifact(obj) && obj->oartifact == ART_SUNSWORD);
1894 }
1895
1896 /* KMH -- Talking artifacts are finally implemented */
1897 void
1898 arti_speak(obj)
1899 struct obj *obj;
1900 {
1901     register const struct artifact *oart = get_artifact(obj);
1902     const char *line;
1903     char buf[BUFSZ];
1904
1905     /* Is this a speaking artifact? */
1906     if (!oart || !(oart->spfx & SPFX_SPEAK))
1907         return;
1908
1909     line = getrumor(bcsign(obj), buf, TRUE);
1910     if (!*line)
1911 /*JP
1912         line = "NetHack rumors file closed for renovation.";
1913 */
1914         line = "\89\\82Ì\90^\91\8a\82Í\90V\91\95\82Ì\82½\82ß\88ê\8e\9e\95Â\93X\81D";
1915 /*JP
1916     pline("%s:", Tobjnam(obj, "whisper"));
1917 */
1918     pline("%s\82Í\82³\82³\82â\82¢\82½\81F", xname(obj));
1919     verbalize1(line);
1920     return;
1921 }
1922
1923 boolean
1924 artifact_has_invprop(otmp, inv_prop)
1925 struct obj *otmp;
1926 uchar inv_prop;
1927 {
1928     const struct artifact *arti = get_artifact(otmp);
1929
1930     return (boolean) (arti && (arti->inv_prop == inv_prop));
1931 }
1932
1933 /* Return the price sold to the hero of a given artifact or unique item */
1934 long
1935 arti_cost(otmp)
1936 struct obj *otmp;
1937 {
1938     if (!otmp->oartifact)
1939         return (long) objects[otmp->otyp].oc_cost;
1940     else if (artilist[(int) otmp->oartifact].cost)
1941         return artilist[(int) otmp->oartifact].cost;
1942     else
1943         return (100L * (long) objects[otmp->otyp].oc_cost);
1944 }
1945
1946 STATIC_OVL uchar
1947 abil_to_adtyp(abil)
1948 long *abil;
1949 {
1950     struct abil2adtyp_tag {
1951         long *abil;
1952         uchar adtyp;
1953     } abil2adtyp[] = {
1954         { &EFire_resistance, AD_FIRE },
1955         { &ECold_resistance, AD_COLD },
1956         { &EShock_resistance, AD_ELEC },
1957         { &EAntimagic, AD_MAGM },
1958         { &EDisint_resistance, AD_DISN },
1959         { &EPoison_resistance, AD_DRST },
1960     };
1961     int k;
1962
1963     for (k = 0; k < SIZE(abil2adtyp); k++) {
1964         if (abil2adtyp[k].abil == abil)
1965             return abil2adtyp[k].adtyp;
1966     }
1967     return 0;
1968 }
1969
1970 STATIC_OVL unsigned long
1971 abil_to_spfx(abil)
1972 long *abil;
1973 {
1974     static const struct abil2spfx_tag {
1975         long *abil;
1976         unsigned long spfx;
1977     } abil2spfx[] = {
1978         { &ESearching, SPFX_SEARCH },
1979         { &EHalluc_resistance, SPFX_HALRES },
1980         { &ETelepat, SPFX_ESP },
1981         { &EStealth, SPFX_STLTH },
1982         { &ERegeneration, SPFX_REGEN },
1983         { &ETeleport_control, SPFX_TCTRL },
1984         { &EWarn_of_mon, SPFX_WARN },
1985         { &EWarning, SPFX_WARN },
1986         { &EEnergy_regeneration, SPFX_EREGEN },
1987         { &EHalf_spell_damage, SPFX_HSPDAM },
1988         { &EHalf_physical_damage, SPFX_HPHDAM },
1989         { &EReflecting, SPFX_REFLECT },
1990     };
1991     int k;
1992
1993     for (k = 0; k < SIZE(abil2spfx); k++) {
1994         if (abil2spfx[k].abil == abil)
1995             return abil2spfx[k].spfx;
1996     }
1997     return 0L;
1998 }
1999
2000 /*
2001  * Return the first item that is conveying a particular intrinsic.
2002  */
2003 struct obj *
2004 what_gives(abil)
2005 long *abil;
2006 {
2007     struct obj *obj;
2008     uchar dtyp;
2009     unsigned long spfx;
2010     long wornbits;
2011     long wornmask = (W_ARM | W_ARMC | W_ARMH | W_ARMS
2012                      | W_ARMG | W_ARMF | W_ARMU
2013                      | W_AMUL | W_RINGL | W_RINGR | W_TOOL
2014                      /* [do W_ART and W_ARTI actually belong here?] */
2015                      | W_ART | W_ARTI);
2016
2017     if (u.twoweap)
2018         wornmask |= W_SWAPWEP;
2019     dtyp = abil_to_adtyp(abil);
2020     spfx = abil_to_spfx(abil);
2021     wornbits = (wornmask & *abil);
2022
2023     for (obj = invent; obj; obj = obj->nobj) {
2024         if (obj->oartifact
2025             && (abil != &EWarn_of_mon || context.warntype.obj)) {
2026             const struct artifact *art = get_artifact(obj);
2027
2028             if (art) {
2029                 if (dtyp) {
2030                     if (art->cary.adtyp == dtyp || art->defn.adtyp == dtyp)
2031                         return obj;
2032                 }
2033                 if (spfx) {
2034                     /* property conferred when carried */
2035                     if ((art->cspfx & spfx) == spfx)
2036                         return obj;
2037                     /* property conferred when wielded or worn */
2038                     if ((art->spfx & spfx) == spfx && obj->owornmask)
2039                         return obj;
2040                 }
2041             }
2042         } else {
2043             if (wornbits && wornbits == (wornmask & obj->owornmask))
2044                 return obj;
2045         }
2046     }
2047     return (struct obj *) 0;
2048 }
2049
2050 const char *
2051 glow_color(arti_indx)
2052 int arti_indx;
2053 {
2054     int colornum = artilist[arti_indx].acolor;
2055     const char *colorstr = clr2colorname(colornum);
2056
2057     return hcolor(colorstr);
2058 }
2059
2060 /* use for warning "glow" for Sting, Orcrist, and Grimtooth */
2061 void
2062 Sting_effects(orc_count)
2063 int orc_count; /* new count (warn_obj_cnt is old count); -1 is a flag value */
2064 {
2065     if (uwep
2066         && (uwep->oartifact == ART_STING
2067             || uwep->oartifact == ART_ORCRIST
2068             || uwep->oartifact == ART_GRIMTOOTH)) {
2069         if (orc_count == -1 && warn_obj_cnt > 0) {
2070             /* -1 means that blindness has just been toggled; give a
2071                'continue' message that eventual 'stop' message will match */
2072             pline("%s is %s.", bare_artifactname(uwep),
2073                   !Blind ? "glowing" : "quivering");
2074         } else if (orc_count > 0 && warn_obj_cnt == 0) {
2075             /* 'start' message */
2076             if (!Blind)
2077                 pline("%s %s %s!", bare_artifactname(uwep),
2078                       otense(uwep, "glow"), glow_color(uwep->oartifact));
2079             else
2080                 pline("%s quivers slightly.", bare_artifactname(uwep));
2081         } else if (orc_count == 0 && warn_obj_cnt > 0) {
2082             /* 'stop' message */
2083             pline("%s stops %s.", bare_artifactname(uwep),
2084                   !Blind ? "glowing" : "quivering");
2085         }
2086     }
2087 }
2088
2089 /* called when hero is wielding/applying/invoking a carried item, or
2090    after undergoing a transformation (alignment change, lycanthropy,
2091    polymorph) which might affect item access */
2092 int
2093 retouch_object(objp, loseit)
2094 struct obj **objp; /* might be destroyed or unintentionally dropped */
2095 boolean loseit;    /* whether to drop it if hero can longer touch it */
2096 {
2097     struct obj *obj = *objp;
2098
2099     if (touch_artifact(obj, &youmonst)) {
2100         char buf[BUFSZ];
2101         int dmg = 0, tmp;
2102         boolean ag =
2103                     (objects[obj->otyp].oc_material == SILVER && Hate_silver),
2104                 bane = bane_applies(get_artifact(obj), &youmonst);
2105
2106         /* nothing else to do if hero can successfully handle this object */
2107         if (!ag && !bane)
2108             return 1;
2109
2110         /* hero can't handle this object, but didn't get touch_artifact()'s
2111            "<obj> evades your grasp|control" message; give an alternate one */
2112         You_cant("handle %s%s!", yname(obj),
2113                  obj->owornmask ? " anymore" : "");
2114         /* also inflict damage unless touch_artifact() already did so */
2115         if (!touch_blasted) {
2116             /* damage is somewhat arbitrary; half the usual 1d20 physical
2117                for silver, 1d10 magical for <foo>bane, potentially both */
2118             if (ag)
2119                 tmp = rnd(10), dmg += Maybe_Half_Phys(tmp);
2120             if (bane)
2121                 dmg += rnd(10);
2122             Sprintf(buf, "handling %s", killer_xname(obj));
2123             losehp(dmg, buf, KILLED_BY);
2124             exercise(A_CON, FALSE);
2125         }
2126     }
2127
2128     /* removing a worn item might result in loss of levitation,
2129        dropping the hero onto a polymorph trap or into water or
2130        lava and potentially dropping or destroying the item */
2131     if (obj->owornmask) {
2132         struct obj *otmp;
2133
2134         remove_worn_item(obj, FALSE);
2135         for (otmp = invent; otmp; otmp = otmp->nobj)
2136             if (otmp == obj)
2137                 break;
2138         if (!otmp)
2139             *objp = obj = 0;
2140     }
2141
2142     /* if we still have it and caller wants us to drop it, do so now */
2143     if (loseit && obj) {
2144         if (Levitation) {
2145             freeinv(obj);
2146             hitfloor(obj);
2147         } else {
2148             /* dropx gives a message iff item lands on an altar */
2149             if (!IS_ALTAR(levl[u.ux][u.uy].typ))
2150                 pline("%s to the %s.", Tobjnam(obj, "fall"),
2151                       surface(u.ux, u.uy));
2152             dropx(obj);
2153         }
2154         *objp = obj = 0; /* no longer in inventory */
2155     }
2156     return 0;
2157 }
2158
2159 /* an item which is worn/wielded or an artifact which conveys
2160    something via being carried or which has an #invoke effect
2161    currently in operation undergoes a touch test; if it fails,
2162    it will be unworn/unwielded and revoked but not dropped */
2163 STATIC_OVL boolean
2164 untouchable(obj, drop_untouchable)
2165 struct obj *obj;
2166 boolean drop_untouchable;
2167 {
2168     struct artifact *art;
2169     boolean beingworn, carryeffect, invoked;
2170     long wearmask = ~(W_QUIVER | (u.twoweap ? 0L : W_SWAPWEP) | W_BALL);
2171
2172     beingworn = ((obj->owornmask & wearmask) != 0L
2173                  /* some items in use don't have any wornmask setting */
2174                  || (obj->oclass == TOOL_CLASS
2175                      && (obj->lamplit || (obj->otyp == LEASH && obj->leashmon)
2176                          || (Is_container(obj) && Has_contents(obj)))));
2177
2178     if ((art = get_artifact(obj)) != 0) {
2179         carryeffect = (art->cary.adtyp || art->cspfx);
2180         invoked = (art->inv_prop > 0 && art->inv_prop <= LAST_PROP
2181                    && (u.uprops[art->inv_prop].extrinsic & W_ARTI) != 0L);
2182     } else {
2183         carryeffect = invoked = FALSE;
2184     }
2185
2186     if (beingworn || carryeffect || invoked) {
2187         if (!retouch_object(&obj, drop_untouchable)) {
2188             /* "<artifact> is beyond your control" or "you can't handle
2189                <object>" has been given and it is now unworn/unwielded
2190                and possibly dropped (depending upon caller); if dropped,
2191                carried effect was turned off, else we leave that alone;
2192                we turn off invocation property here if still carried */
2193             if (invoked && obj)
2194                 arti_invoke(obj); /* reverse #invoke */
2195             return TRUE;
2196         }
2197     }
2198     return FALSE;
2199 }
2200
2201 /* check all items currently in use (mostly worn) for touchability */
2202 void
2203 retouch_equipment(dropflag)
2204 int dropflag; /* 0==don't drop, 1==drop all, 2==drop weapon */
2205 {
2206     static int nesting = 0; /* recursion control */
2207     struct obj *obj;
2208     boolean dropit, had_gloves = (uarmg != 0);
2209     int had_rings = (!!uleft + !!uright);
2210
2211     /*
2212      * We can potentially be called recursively if losing/unwearing
2213      * an item causes worn helm of opposite alignment to come off or
2214      * be destroyed.
2215      *
2216      * BUG: if the initial call was due to putting on a helm of
2217      * opposite alignment and it does come off to trigger recursion,
2218      * after the inner call executes, the outer call will finish
2219      * using the non-helm alignment rather than the helm alignment
2220      * which triggered this in the first place.
2221      */
2222     if (!nesting++)
2223         clear_bypasses(); /* init upon initial entry */
2224
2225     dropit = (dropflag > 0); /* drop all or drop weapon */
2226     /* check secondary weapon first, before possibly unwielding primary */
2227     if (u.twoweap)
2228         (void) untouchable(uswapwep, dropit);
2229     /* check primary weapon next so that they're handled together */
2230     if (uwep)
2231         (void) untouchable(uwep, dropit);
2232
2233     /* in case someone is daft enough to add artifact or silver saddle */
2234     if (u.usteed && (obj = which_armor(u.usteed, W_SADDLE)) != 0) {
2235         /* untouchable() calls retouch_object() which expects an object in
2236            hero's inventory, but remove_worn_item() will be harmless for
2237            saddle and we're suppressing drop, so this works as intended */
2238         if (untouchable(obj, FALSE))
2239             dismount_steed(DISMOUNT_THROWN);
2240     }
2241     /*
2242      * TODO?  Force off gloves if either or both rings are going to
2243      * become unworn; force off cloak [suit] before suit [shirt].
2244      * The torso handling is hypothetical; the case for gloves is
2245      * not, due to the possibility of unwearing silver rings.
2246      */
2247
2248     dropit = (dropflag == 1); /* all untouchable items */
2249     /* loss of levitation (silver ring, or Heart of Ahriman invocation)
2250        might cause hero to lose inventory items (by dropping into lava,
2251        for instance), so inventory traversal needs to rescan the whole
2252        invent chain each time it moves on to another object; we use bypass
2253        handling to keep track of which items have already been processed */
2254     while ((obj = nxt_unbypassed_obj(invent)) != 0)
2255         (void) untouchable(obj, dropit);
2256
2257     if (had_rings != (!!uleft + !!uright) && uarmg && uarmg->cursed)
2258         uncurse(uarmg); /* temporary? hack for ring removal plausibility */
2259     if (had_gloves && !uarmg)
2260         selftouch("After losing your gloves, you");
2261
2262     if (!--nesting)
2263         clear_bypasses(); /* reset upon final exit */
2264 }
2265
2266 /*artifact.c*/