OSDN Git Service

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