OSDN Git Service

update year to 2018
[jnethack/source.git] / src / worn.c
1 /* NetHack 3.6  worn.c  $NHDT-Date: 1496959481 2017/06/08 22:04:41 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 STATIC_DCL void FDECL(m_lose_armor, (struct monst *, struct obj *));
14 STATIC_DCL void FDECL(m_dowear_type,
15                       (struct monst *, long, BOOLEAN_P, BOOLEAN_P));
16 STATIC_DCL int FDECL(extra_pref, (struct monst *, struct obj *));
17
18 const struct worn {
19     long w_mask;
20     struct obj **w_obj;
21 } worn[] = { { W_ARM, &uarm },
22              { W_ARMC, &uarmc },
23              { W_ARMH, &uarmh },
24              { W_ARMS, &uarms },
25              { W_ARMG, &uarmg },
26              { W_ARMF, &uarmf },
27              { W_ARMU, &uarmu },
28              { W_RINGL, &uleft },
29              { W_RINGR, &uright },
30              { W_WEP, &uwep },
31              { W_SWAPWEP, &uswapwep },
32              { W_QUIVER, &uquiver },
33              { W_AMUL, &uamul },
34              { W_TOOL, &ublindf },
35              { W_BALL, &uball },
36              { W_CHAIN, &uchain },
37              { 0, 0 } };
38
39 /* This only allows for one blocking item per property */
40 #define w_blocks(o, m) \
41     ((o->otyp == MUMMY_WRAPPING && ((m) & W_ARMC))                          \
42          ? INVIS                                                            \
43          : (o->otyp == CORNUTHAUM && ((m) & W_ARMH) && !Role_if(PM_WIZARD)) \
44                ? CLAIRVOYANT                                                \
45                : 0)
46 /* note: monsters don't have clairvoyance, so your role
47    has no significant effect on their use of w_blocks() */
48
49 /* Updated to use the extrinsic and blocked fields. */
50 void
51 setworn(obj, mask)
52 register struct obj *obj;
53 long mask;
54 {
55     register const struct worn *wp;
56     register struct obj *oobj;
57     register int p;
58
59     if ((mask & (W_ARM | I_SPECIAL)) == (W_ARM | I_SPECIAL)) {
60         /* restoring saved game; no properties are conferred via skin */
61         uskin = obj;
62         /* assert( !uarm ); */
63     } else {
64         if ((mask & W_ARMOR))
65             u.uroleplay.nudist = FALSE;
66         for (wp = worn; wp->w_mask; wp++)
67             if (wp->w_mask & mask) {
68                 oobj = *(wp->w_obj);
69                 if (oobj && !(oobj->owornmask & wp->w_mask))
70                     impossible("Setworn: mask = %ld.", wp->w_mask);
71                 if (oobj) {
72                     if (u.twoweap && (oobj->owornmask & (W_WEP | W_SWAPWEP)))
73                         u.twoweap = 0;
74                     oobj->owornmask &= ~wp->w_mask;
75                     if (wp->w_mask & ~(W_SWAPWEP | W_QUIVER)) {
76                         /* leave as "x = x <op> y", here and below, for broken
77                          * compilers */
78                         p = objects[oobj->otyp].oc_oprop;
79                         u.uprops[p].extrinsic =
80                             u.uprops[p].extrinsic & ~wp->w_mask;
81                         if ((p = w_blocks(oobj, mask)) != 0)
82                             u.uprops[p].blocked &= ~wp->w_mask;
83                         if (oobj->oartifact)
84                             set_artifact_intrinsic(oobj, 0, mask);
85                     }
86                     /* in case wearing or removal is in progress or removal
87                        is pending (via 'A' command for multiple items) */
88                     cancel_doff(oobj, wp->w_mask);
89                 }
90                 *(wp->w_obj) = obj;
91                 if (obj) {
92                     obj->owornmask |= wp->w_mask;
93                     /* Prevent getting/blocking intrinsics from wielding
94                      * potions, through the quiver, etc.
95                      * Allow weapon-tools, too.
96                      * wp_mask should be same as mask at this point.
97                      */
98                     if (wp->w_mask & ~(W_SWAPWEP | W_QUIVER)) {
99                         if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
100                             || mask != W_WEP) {
101                             p = objects[obj->otyp].oc_oprop;
102                             u.uprops[p].extrinsic =
103                                 u.uprops[p].extrinsic | wp->w_mask;
104                             if ((p = w_blocks(obj, mask)) != 0)
105                                 u.uprops[p].blocked |= wp->w_mask;
106                         }
107                         if (obj->oartifact)
108                             set_artifact_intrinsic(obj, 1, mask);
109                     }
110                 }
111             }
112     }
113     update_inventory();
114 }
115
116 /* called e.g. when obj is destroyed */
117 /* Updated to use the extrinsic and blocked fields. */
118 void
119 setnotworn(obj)
120 register struct obj *obj;
121 {
122     register const struct worn *wp;
123     register int p;
124
125     if (!obj)
126         return;
127     if (obj == uwep || obj == uswapwep)
128         u.twoweap = 0;
129     for (wp = worn; wp->w_mask; wp++)
130         if (obj == *(wp->w_obj)) {
131             /* in case wearing or removal is in progress or removal
132                is pending (via 'A' command for multiple items) */
133             cancel_doff(obj, wp->w_mask);
134
135             *(wp->w_obj) = 0;
136             p = objects[obj->otyp].oc_oprop;
137             u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask;
138             obj->owornmask &= ~wp->w_mask;
139             if (obj->oartifact)
140                 set_artifact_intrinsic(obj, 0, wp->w_mask);
141             if ((p = w_blocks(obj, wp->w_mask)) != 0)
142                 u.uprops[p].blocked &= ~wp->w_mask;
143         }
144     update_inventory();
145 }
146
147 /* return a bitmask of the equipment slot(s) a given item might be worn in */
148 long
149 wearslot(obj)
150 struct obj *obj;
151 {
152     int otyp = obj->otyp;
153     /* practically any item can be wielded or quivered; it's up to
154        our caller to handle such things--we assume "normal" usage */
155     long res = 0L; /* default: can't be worn anywhere */
156
157     switch (obj->oclass) {
158     case AMULET_CLASS:
159         res = W_AMUL; /* WORN_AMUL */
160         break;
161     case RING_CLASS:
162         res = W_RINGL | W_RINGR; /* W_RING, BOTH_SIDES */
163         break;
164     case ARMOR_CLASS:
165         switch (objects[otyp].oc_armcat) {
166         case ARM_SUIT:
167             res = W_ARM;
168             break; /* WORN_ARMOR */
169         case ARM_SHIELD:
170             res = W_ARMS;
171             break; /* WORN_SHIELD */
172         case ARM_HELM:
173             res = W_ARMH;
174             break; /* WORN_HELMET */
175         case ARM_GLOVES:
176             res = W_ARMG;
177             break; /* WORN_GLOVES */
178         case ARM_BOOTS:
179             res = W_ARMF;
180             break; /* WORN_BOOTS */
181         case ARM_CLOAK:
182             res = W_ARMC;
183             break; /* WORN_CLOAK */
184         case ARM_SHIRT:
185             res = W_ARMU;
186             break; /* WORN_SHIRT */
187         }
188         break;
189     case WEAPON_CLASS:
190         res = W_WEP | W_SWAPWEP;
191         if (objects[otyp].oc_merge)
192             res |= W_QUIVER;
193         break;
194     case TOOL_CLASS:
195         if (otyp == BLINDFOLD || otyp == TOWEL || otyp == LENSES)
196             res = W_TOOL; /* WORN_BLINDF */
197         else if (is_weptool(obj) || otyp == TIN_OPENER)
198             res = W_WEP | W_SWAPWEP;
199         else if (otyp == SADDLE)
200             res = W_SADDLE;
201         break;
202     case FOOD_CLASS:
203         if (obj->otyp == MEAT_RING)
204             res = W_RINGL | W_RINGR;
205         break;
206     case GEM_CLASS:
207         res = W_QUIVER;
208         break;
209     case BALL_CLASS:
210         res = W_BALL;
211         break;
212     case CHAIN_CLASS:
213         res = W_CHAIN;
214         break;
215     default:
216         break;
217     }
218     return res;
219 }
220
221 void
222 mon_set_minvis(mon)
223 struct monst *mon;
224 {
225     mon->perminvis = 1;
226     if (!mon->invis_blkd) {
227         mon->minvis = 1;
228         newsym(mon->mx, mon->my); /* make it disappear */
229         if (mon->wormno)
230             see_wsegs(mon); /* and any tail too */
231     }
232 }
233
234 void
235 mon_adjust_speed(mon, adjust, obj)
236 struct monst *mon;
237 int adjust;      /* positive => increase speed, negative => decrease */
238 struct obj *obj; /* item to make known if effect can be seen */
239 {
240     struct obj *otmp;
241     boolean give_msg = !in_mklev, petrify = FALSE;
242     unsigned int oldspeed = mon->mspeed;
243
244     switch (adjust) {
245     case 2:
246         mon->permspeed = MFAST;
247         give_msg = FALSE; /* special case monster creation */
248         break;
249     case 1:
250         if (mon->permspeed == MSLOW)
251             mon->permspeed = 0;
252         else
253             mon->permspeed = MFAST;
254         break;
255     case 0: /* just check for worn speed boots */
256         break;
257     case -1:
258         if (mon->permspeed == MFAST)
259             mon->permspeed = 0;
260         else
261             mon->permspeed = MSLOW;
262         break;
263     case -2:
264         mon->permspeed = MSLOW;
265         give_msg = FALSE; /* (not currently used) */
266         break;
267     case -3: /* petrification */
268         /* take away intrinsic speed but don't reduce normal speed */
269         if (mon->permspeed == MFAST)
270             mon->permspeed = 0;
271         petrify = TRUE;
272         break;
273     case -4: /* green slime */
274         if (mon->permspeed == MFAST)
275             mon->permspeed = 0;
276         give_msg = FALSE;
277         break;
278     }
279
280     for (otmp = mon->minvent; otmp; otmp = otmp->nobj)
281         if (otmp->owornmask && objects[otmp->otyp].oc_oprop == FAST)
282             break;
283     if (otmp) /* speed boots */
284         mon->mspeed = MFAST;
285     else
286         mon->mspeed = mon->permspeed;
287
288     /* no message if monster is immobile (temp or perm) or unseen */
289     if (give_msg && (mon->mspeed != oldspeed || petrify) && mon->data->mmove
290         && !(mon->mfrozen || mon->msleeping) && canseemon(mon)) {
291         /* fast to slow (skipping intermediate state) or vice versa */
292         const char *howmuch =
293 /*JP
294             (mon->mspeed + oldspeed == MFAST + MSLOW) ? "much " : "";
295 */
296             (mon->mspeed + oldspeed == MFAST + MSLOW) ? "\82·\82²\82­" : "";
297
298         if (petrify) {
299             /* mimic the player's petrification countdown; "slowing down"
300                even if fast movement rate retained via worn speed boots */
301             if (flags.verbose)
302 /*JP
303                 pline("%s is slowing down.", Monnam(mon));
304 */
305                 pline("%s\82Í\82Ì\82ë\82­\82È\82Á\82½\81D", Monnam(mon));
306         } else if (adjust > 0 || mon->mspeed == MFAST)
307 /*JP
308             pline("%s is suddenly moving %sfaster.", Monnam(mon), howmuch);
309 */
310             pline("%s\82Ì\93®\82«\82Í\93Ë\91R%s\82·\82Î\82â\82­\82È\82Á\82½\81D", Monnam(mon), howmuch);
311         else
312 /*JP
313             pline("%s seems to be moving %sslower.", Monnam(mon), howmuch);
314 */
315             pline("%s\82Ì\93®\82«\82Í%s\82Ì\82ë\82­\82È\82Á\82½\82æ\82¤\82É\8c©\82¦\82é\81D", Monnam(mon), howmuch);
316
317         /* might discover an object if we see the speed change happen */
318         if (obj != 0)
319             learnwand(obj);
320     }
321 }
322
323 /* armor put on or taken off; might be magical variety */
324 void
325 update_mon_intrinsics(mon, obj, on, silently)
326 struct monst *mon;
327 struct obj *obj;
328 boolean on, silently;
329 {
330     int unseen;
331     uchar mask;
332     struct obj *otmp;
333     int which = (int) objects[obj->otyp].oc_oprop;
334
335     unseen = !canseemon(mon);
336     if (!which)
337         goto maybe_blocks;
338
339     if (on) {
340         switch (which) {
341         case INVIS:
342             mon->minvis = !mon->invis_blkd;
343             break;
344         case FAST: {
345             boolean save_in_mklev = in_mklev;
346             if (silently)
347                 in_mklev = TRUE;
348             mon_adjust_speed(mon, 0, obj);
349             in_mklev = save_in_mklev;
350             break;
351         }
352         /* properties handled elsewhere */
353         case ANTIMAGIC:
354         case REFLECTING:
355             break;
356         /* properties which have no effect for monsters */
357         case CLAIRVOYANT:
358         case STEALTH:
359         case TELEPAT:
360             break;
361         /* properties which should have an effect but aren't implemented */
362         case LEVITATION:
363         case WWALKING:
364             break;
365         /* properties which maybe should have an effect but don't */
366         case DISPLACED:
367         case FUMBLING:
368         case JUMPING:
369         case PROTECTION:
370             break;
371         default:
372             if (which <= 8) { /* 1 thru 8 correspond to MR_xxx mask values */
373                 /* FIRE,COLD,SLEEP,DISINT,SHOCK,POISON,ACID,STONE */
374                 mask = (uchar) (1 << (which - 1));
375                 mon->mintrinsics |= (unsigned short) mask;
376             }
377             break;
378         }
379     } else { /* off */
380         switch (which) {
381         case INVIS:
382             mon->minvis = mon->perminvis;
383             break;
384         case FAST: {
385             boolean save_in_mklev = in_mklev;
386             if (silently)
387                 in_mklev = TRUE;
388             mon_adjust_speed(mon, 0, obj);
389             in_mklev = save_in_mklev;
390             break;
391         }
392         case FIRE_RES:
393         case COLD_RES:
394         case SLEEP_RES:
395         case DISINT_RES:
396         case SHOCK_RES:
397         case POISON_RES:
398         case ACID_RES:
399         case STONE_RES:
400             mask = (uchar) (1 << (which - 1));
401             /* If the monster doesn't have this resistance intrinsically,
402                check whether any other worn item confers it.  Note that
403                we don't currently check for anything conferred via simply
404                carrying an object. */
405             if (!(mon->data->mresists & mask)) {
406                 for (otmp = mon->minvent; otmp; otmp = otmp->nobj)
407                     if (otmp->owornmask
408                         && (int) objects[otmp->otyp].oc_oprop == which)
409                         break;
410                 if (!otmp)
411                     mon->mintrinsics &= ~((unsigned short) mask);
412             }
413             break;
414         default:
415             break;
416         }
417     }
418
419 maybe_blocks:
420     /* obj->owornmask has been cleared by this point, so we can't use it.
421        However, since monsters don't wield armor, we don't have to guard
422        against that and can get away with a blanket worn-mask value. */
423     switch (w_blocks(obj, ~0L)) {
424     case INVIS:
425         mon->invis_blkd = on ? 1 : 0;
426         mon->minvis = on ? 0 : mon->perminvis;
427         break;
428     default:
429         break;
430     }
431
432     if (!on && mon == u.usteed && obj->otyp == SADDLE)
433         dismount_steed(DISMOUNT_FELL);
434
435     /* if couldn't see it but now can, or vice versa, update display */
436     if (!silently && (unseen ^ !canseemon(mon)))
437         newsym(mon->mx, mon->my);
438 }
439
440 int
441 find_mac(mon)
442 register struct monst *mon;
443 {
444     register struct obj *obj;
445     int base = mon->data->ac;
446     long mwflags = mon->misc_worn_check;
447
448     for (obj = mon->minvent; obj; obj = obj->nobj) {
449         if (obj->owornmask & mwflags)
450             base -= ARM_BONUS(obj);
451         /* since ARM_BONUS is positive, subtracting it increases AC */
452     }
453     return base;
454 }
455
456 /*
457  * weapons are handled separately;
458  * rings and eyewear aren't used by monsters
459  */
460
461 /* Wear the best object of each type that the monster has.  During creation,
462  * the monster can put everything on at once; otherwise, wearing takes time.
463  * This doesn't affect monster searching for objects--a monster may very well
464  * search for objects it would not want to wear, because we don't want to
465  * check which_armor() each round.
466  *
467  * We'll let monsters put on shirts and/or suits under worn cloaks, but
468  * not shirts under worn suits.  This is somewhat arbitrary, but it's
469  * too tedious to have them remove and later replace outer garments,
470  * and preventing suits under cloaks makes it a little bit too easy for
471  * players to influence what gets worn.  Putting on a shirt underneath
472  * already worn body armor is too obviously buggy...
473  */
474 void
475 m_dowear(mon, creation)
476 register struct monst *mon;
477 boolean creation;
478 {
479 #define RACE_EXCEPTION TRUE
480     /* Note the restrictions here are the same as in dowear in do_wear.c
481      * except for the additional restriction on intelligence.  (Players
482      * are always intelligent, even if polymorphed).
483      */
484     if (verysmall(mon->data) || nohands(mon->data) || is_animal(mon->data))
485         return;
486     /* give mummies a chance to wear their wrappings
487      * and let skeletons wear their initial armor */
488     if (mindless(mon->data)
489         && (!creation || (mon->data->mlet != S_MUMMY
490                           && mon->data != &mons[PM_SKELETON])))
491         return;
492
493     m_dowear_type(mon, W_AMUL, creation, FALSE);
494     /* can't put on shirt if already wearing suit */
495     if (!cantweararm(mon->data) && !(mon->misc_worn_check & W_ARM))
496         m_dowear_type(mon, W_ARMU, creation, FALSE);
497     /* treating small as a special case allows
498        hobbits, gnomes, and kobolds to wear cloaks */
499     if (!cantweararm(mon->data) || mon->data->msize == MZ_SMALL)
500         m_dowear_type(mon, W_ARMC, creation, FALSE);
501     m_dowear_type(mon, W_ARMH, creation, FALSE);
502     if (!MON_WEP(mon) || !bimanual(MON_WEP(mon)))
503         m_dowear_type(mon, W_ARMS, creation, FALSE);
504     m_dowear_type(mon, W_ARMG, creation, FALSE);
505     if (!slithy(mon->data) && mon->data->mlet != S_CENTAUR)
506         m_dowear_type(mon, W_ARMF, creation, FALSE);
507     if (!cantweararm(mon->data))
508         m_dowear_type(mon, W_ARM, creation, FALSE);
509     else
510         m_dowear_type(mon, W_ARM, creation, RACE_EXCEPTION);
511 }
512
513 STATIC_OVL void
514 m_dowear_type(mon, flag, creation, racialexception)
515 struct monst *mon;
516 long flag;
517 boolean creation;
518 boolean racialexception;
519 {
520     struct obj *old, *best, *obj;
521     int m_delay = 0;
522     int unseen = !canseemon(mon);
523     boolean autocurse;
524     char nambuf[BUFSZ];
525
526     if (mon->mfrozen)
527         return; /* probably putting previous item on */
528
529     /* Get a copy of monster's name before altering its visibility */
530     Strcpy(nambuf, See_invisible ? Monnam(mon) : mon_nam(mon));
531
532     old = which_armor(mon, flag);
533     if (old && old->cursed)
534         return;
535     if (old && flag == W_AMUL)
536         return; /* no such thing as better amulets */
537     best = old;
538
539     for (obj = mon->minvent; obj; obj = obj->nobj) {
540         switch (flag) {
541         case W_AMUL:
542             if (obj->oclass != AMULET_CLASS
543                 || (obj->otyp != AMULET_OF_LIFE_SAVING
544                     && obj->otyp != AMULET_OF_REFLECTION))
545                 continue;
546             best = obj;
547             goto outer_break; /* no such thing as better amulets */
548         case W_ARMU:
549             if (!is_shirt(obj))
550                 continue;
551             break;
552         case W_ARMC:
553             if (!is_cloak(obj))
554                 continue;
555             break;
556         case W_ARMH:
557             if (!is_helmet(obj))
558                 continue;
559             /* changing alignment is not implemented for monsters;
560                priests and minions could change alignment but wouldn't
561                want to, so they reject helms of opposite alignment */
562             if (obj->otyp == HELM_OF_OPPOSITE_ALIGNMENT
563                 && (mon->ispriest || mon->isminion))
564                 continue;
565             /* (flimsy exception matches polyself handling) */
566             if (has_horns(mon->data) && !is_flimsy(obj))
567                 continue;
568             break;
569         case W_ARMS:
570             if (!is_shield(obj))
571                 continue;
572             break;
573         case W_ARMG:
574             if (!is_gloves(obj))
575                 continue;
576             break;
577         case W_ARMF:
578             if (!is_boots(obj))
579                 continue;
580             break;
581         case W_ARM:
582             if (!is_suit(obj))
583                 continue;
584             if (racialexception && (racial_exception(mon, obj) < 1))
585                 continue;
586             break;
587         }
588         if (obj->owornmask)
589             continue;
590         /* I'd like to define a VISIBLE_ARM_BONUS which doesn't assume the
591          * monster knows obj->spe, but if I did that, a monster would keep
592          * switching forever between two -2 caps since when it took off one
593          * it would forget spe and once again think the object is better
594          * than what it already has.
595          */
596         if (best && (ARM_BONUS(best) + extra_pref(mon, best)
597                      >= ARM_BONUS(obj) + extra_pref(mon, obj)))
598             continue;
599         best = obj;
600     }
601 outer_break:
602     if (!best || best == old)
603         return;
604
605     /* same auto-cursing behavior as for hero */
606     autocurse = ((best->otyp == HELM_OF_OPPOSITE_ALIGNMENT
607                   || best->otyp == DUNCE_CAP) && !best->cursed);
608     /* if wearing a cloak, account for the time spent removing
609        and re-wearing it when putting on a suit or shirt */
610     if ((flag == W_ARM || flag == W_ARMU) && (mon->misc_worn_check & W_ARMC))
611         m_delay += 2;
612     /* when upgrading a piece of armor, account for time spent
613        taking off current one */
614     if (old)
615         m_delay += objects[old->otyp].oc_delay;
616
617     if (old) /* do this first to avoid "(being worn)" */
618         old->owornmask = 0L;
619     if (!creation) {
620         if (canseemon(mon)) {
621             char buf[BUFSZ];
622
623             if (old)
624 /*JP
625                 Sprintf(buf, " removes %s and", distant_name(old, doname));
626 */
627                 Sprintf(buf, "%s\82ð\82Í\82¸\82µ\82Ä", distant_name(old, doname));
628             else
629                 buf[0] = '\0';
630 #if 0 /*JP*/
631             pline("%s%s puts on %s.", Monnam(mon), buf,
632                   distant_name(best, doname));
633 #else
634             pline("%s\82Í%s%s\82ð\90g\82É\82Â\82¯\82½\81D", Monnam(mon), buf,
635                   distant_name(best,doname));
636 #endif
637             if (autocurse)
638 #if 0 /*JP*/
639                 pline("%s %s %s %s for a moment.", s_suffix(Monnam(mon)),
640                       simpleonames(best), otense(best, "glow"),
641                       hcolor(NH_BLACK));
642 #else
643                 pline("%s\82Ì%s\82Í\82µ\82Î\82ç\82­%s\8bP\82¢\82½\81D", Monnam(mon),
644                       simpleonames(best),
645                       jconj_adj(hcolor(NH_BLACK)));
646 #endif
647         } /* can see it */
648         m_delay += objects[best->otyp].oc_delay;
649         mon->mfrozen = m_delay;
650         if (mon->mfrozen)
651             mon->mcanmove = 0;
652     }
653     if (old)
654         update_mon_intrinsics(mon, old, FALSE, creation);
655     mon->misc_worn_check |= flag;
656     best->owornmask |= flag;
657     if (autocurse)
658         curse(best);
659     update_mon_intrinsics(mon, best, TRUE, creation);
660     /* if couldn't see it but now can, or vice versa, */
661     if (!creation && (unseen ^ !canseemon(mon))) {
662         if (mon->minvis && !See_invisible) {
663 /*JP
664             pline("Suddenly you cannot see %s.", nambuf);
665 */
666             pline("\93Ë\91R%s\82ª\8c©\82¦\82È\82­\82È\82Á\82½\81D", nambuf);
667             makeknown(best->otyp);
668         } /* else if (!mon->minvis) pline("%s suddenly appears!",
669              Amonnam(mon)); */
670     }
671 }
672 #undef RACE_EXCEPTION
673
674 struct obj *
675 which_armor(mon, flag)
676 struct monst *mon;
677 long flag;
678 {
679     if (mon == &youmonst) {
680         switch (flag) {
681         case W_ARM:
682             return uarm;
683         case W_ARMC:
684             return uarmc;
685         case W_ARMH:
686             return uarmh;
687         case W_ARMS:
688             return uarms;
689         case W_ARMG:
690             return uarmg;
691         case W_ARMF:
692             return uarmf;
693         case W_ARMU:
694             return uarmu;
695         default:
696             impossible("bad flag in which_armor");
697             return 0;
698         }
699     } else {
700         register struct obj *obj;
701
702         for (obj = mon->minvent; obj; obj = obj->nobj)
703             if (obj->owornmask & flag)
704                 return obj;
705         return (struct obj *) 0;
706     }
707 }
708
709 /* remove an item of armor and then drop it */
710 STATIC_OVL void
711 m_lose_armor(mon, obj)
712 struct monst *mon;
713 struct obj *obj;
714 {
715     mon->misc_worn_check &= ~obj->owornmask;
716     if (obj->owornmask)
717         update_mon_intrinsics(mon, obj, FALSE, FALSE);
718     obj->owornmask = 0L;
719
720     obj_extract_self(obj);
721     place_object(obj, mon->mx, mon->my);
722     /* call stackobj() if we ever drop anything that can merge */
723     newsym(mon->mx, mon->my);
724 }
725
726 /* all objects with their bypass bit set should now be reset to normal */
727 void
728 clear_bypasses()
729 {
730     struct obj *otmp, *nobj;
731     struct monst *mtmp;
732
733     for (otmp = fobj; otmp; otmp = nobj) {
734         nobj = otmp->nobj;
735         if (otmp->bypass) {
736             otmp->bypass = 0;
737
738             /* bypass will have inhibited any stacking, but since it's
739              * used for polymorph handling, the objects here probably
740              * have been transformed and won't be stacked in the usual
741              * manner afterwards; so don't bother with this.
742              * [Changing the fobj chain mid-traversal would also be risky.]
743              */
744 #if 0
745             if (objects[otmp->otyp].oc_merge) {
746                 xchar ox, oy;
747
748                 (void) get_obj_location(otmp, &ox, &oy, 0);
749                 stack_object(otmp);
750                 newsym(ox, oy);
751             }
752 #endif /*0*/
753         }
754     }
755     for (otmp = invent; otmp; otmp = otmp->nobj)
756         otmp->bypass = 0;
757     for (otmp = migrating_objs; otmp; otmp = otmp->nobj)
758         otmp->bypass = 0;
759     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
760         if (DEADMONSTER(mtmp))
761             continue;
762         for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
763             otmp->bypass = 0;
764     }
765     for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
766         for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
767             otmp->bypass = 0;
768     }
769     /* billobjs and mydogs chains don't matter here */
770     context.bypasses = FALSE;
771 }
772
773 void
774 bypass_obj(obj)
775 struct obj *obj;
776 {
777     obj->bypass = 1;
778     context.bypasses = TRUE;
779 }
780
781 /* set or clear the bypass bit in a list of objects */
782 void
783 bypass_objlist(objchain, on)
784 struct obj *objchain;
785 boolean on; /* TRUE => set, FALSE => clear */
786 {
787     if (on && objchain)
788         context.bypasses = TRUE;
789     while (objchain) {
790         objchain->bypass = on ? 1 : 0;
791         objchain = objchain->nobj;
792     }
793 }
794
795 /* return the first object without its bypass bit set; set that bit
796    before returning so that successive calls will find further objects */
797 struct obj *
798 nxt_unbypassed_obj(objchain)
799 struct obj *objchain;
800 {
801     while (objchain) {
802         if (!objchain->bypass) {
803             bypass_obj(objchain);
804             break;
805         }
806         objchain = objchain->nobj;
807     }
808     return objchain;
809 }
810
811 void
812 mon_break_armor(mon, polyspot)
813 struct monst *mon;
814 boolean polyspot;
815 {
816     register struct obj *otmp;
817     struct permonst *mdat = mon->data;
818     boolean vis = cansee(mon->mx, mon->my);
819     boolean handless_or_tiny = (nohands(mdat) || verysmall(mdat));
820 #if 0 /*JP*//*\8eg\82í\82È\82¢*/
821     const char *pronoun = mhim(mon), *ppronoun = mhis(mon);
822 #endif
823
824     if (breakarm(mdat)) {
825         if ((otmp = which_armor(mon, W_ARM)) != 0) {
826             if ((Is_dragon_scales(otmp) && mdat == Dragon_scales_to_pm(otmp))
827                 || (Is_dragon_mail(otmp) && mdat == Dragon_mail_to_pm(otmp)))
828                 ; /* no message here;
829                      "the dragon merges with his scaly armor" is odd
830                      and the monster's previous form is already gone */
831             else if (vis)
832 /*JP
833                 pline("%s breaks out of %s armor!", Monnam(mon), ppronoun);
834 */
835                 pline("%s\82Í\8aZ\82ð\82â\82Ô\82è\8fo\82½\81I", Monnam(mon));
836             else
837 /*JP
838                 You_hear("a cracking sound.");
839 */
840                 You_hear("\83o\83\8a\83o\83\8a\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
841             m_useup(mon, otmp);
842         }
843         if ((otmp = which_armor(mon, W_ARMC)) != 0) {
844             if (otmp->oartifact) {
845                 if (vis)
846 #if 0 /*JP*/
847                     pline("%s %s falls off!", s_suffix(Monnam(mon)),
848                           cloak_simple_name(otmp));
849 #else
850                     pline("%s\82Ì%s\82Í\97\8e\82¿\82½\81I", Monnam(mon),
851                           cloak_simple_name(otmp));
852 #endif
853                 if (polyspot)
854                     bypass_obj(otmp);
855                 m_lose_armor(mon, otmp);
856             } else {
857                 if (vis)
858 #if 0 /*JP*/
859                     pline("%s %s tears apart!", s_suffix(Monnam(mon)),
860                           cloak_simple_name(otmp));
861 #else
862                     pline("%s\82Ì%s\82Í\82¸\82½\82¸\82½\82É\82È\82Á\82½\81I", Monnam(mon),
863                           cloak_simple_name(otmp));
864 #endif
865                 else
866 /*JP
867                     You_hear("a ripping sound.");
868 */
869                     You_hear("\83r\83\8a\83b\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
870                 m_useup(mon, otmp);
871             }
872         }
873         if ((otmp = which_armor(mon, W_ARMU)) != 0) {
874             if (vis)
875 /*JP
876                 pline("%s shirt rips to shreds!", s_suffix(Monnam(mon)));
877 */
878                 pline("%s\82Ì\83V\83\83\83c\82Í\82¸\82½\82¸\82½\82É\82È\82Á\82½\81I", Monnam(mon));
879             else
880 /*JP
881                 You_hear("a ripping sound.");
882 */
883                 You_hear("\83r\83\8a\83b\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
884             m_useup(mon, otmp);
885         }
886     } else if (sliparm(mdat)) {
887         if ((otmp = which_armor(mon, W_ARM)) != 0) {
888             if (vis)
889 #if 0 /*JP*/
890                 pline("%s armor falls around %s!", s_suffix(Monnam(mon)),
891                       pronoun);
892 #else
893                 pline("%s\82Ì\8aZ\82ª\89ñ\82è\82É\97\8e\82¿\82½\81I", Monnam(mon));
894 #endif
895             else
896 /*JP
897                 You_hear("a thud.");
898 */
899                 You_hear("\83h\83V\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
900             if (polyspot)
901                 bypass_obj(otmp);
902             m_lose_armor(mon, otmp);
903         }
904         if ((otmp = which_armor(mon, W_ARMC)) != 0) {
905             if (vis) {
906                 if (is_whirly(mon->data))
907 #if 0 /*JP*/
908                     pline("%s %s falls, unsupported!", s_suffix(Monnam(mon)),
909                           cloak_simple_name(otmp));
910 #else
911                     pline("%s\82Ì%s\82Í\8ex\82¦\82«\82ê\82¸\82É\97\8e\82¿\82½\81I", Monnam(mon),
912                           cloak_simple_name(otmp));
913 #endif
914                 else
915 #if 0 /*JP*/
916                     pline("%s shrinks out of %s %s!", Monnam(mon), ppronoun,
917                           cloak_simple_name(otmp));
918 #else
919                     pline("%s\82Í%s\82æ\82è\8fk\82ñ\82¾\81I", Monnam(mon),
920                           cloak_simple_name(otmp));
921 #endif
922             }
923             if (polyspot)
924                 bypass_obj(otmp);
925             m_lose_armor(mon, otmp);
926         }
927         if ((otmp = which_armor(mon, W_ARMU)) != 0) {
928             if (vis) {
929                 if (sliparm(mon->data))
930 #if 0 /*JP*/
931                     pline("%s seeps right through %s shirt!", Monnam(mon),
932                           ppronoun);
933 #else
934                     pline("%s\82Í\8e©\95ª\82Ì\83V\83\83\83c\82É\82µ\82Ý\8d\9e\82ñ\82¾\81I", Monnam(mon));
935 #endif
936                 else
937 #if 0 /*JP*/
938                     pline("%s becomes much too small for %s shirt!",
939                           Monnam(mon), ppronoun);
940 #else
941                     pline("%s\82Í\8e©\95ª\82Ì\83V\83\83\83c\82æ\82è\82¸\82Á\82Æ\8f¬\82³\82­\82È\82Á\82½\81I",
942                           Monnam(mon));
943 #endif
944             }
945             if (polyspot)
946                 bypass_obj(otmp);
947             m_lose_armor(mon, otmp);
948         }
949     }
950     if (handless_or_tiny) {
951         /* [caller needs to handle weapon checks] */
952         if ((otmp = which_armor(mon, W_ARMG)) != 0) {
953             if (vis)
954 #if 0 /*JP*/
955                 pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
956                       MON_WEP(mon) ? " and weapon" : "");
957 #else
958                 pline("%s\82Í\8f¬\8eè%s\82ð\97\8e\82µ\82½\81I", Monnam(mon), 
959                       MON_WEP(mon) ? "\82Æ\95\90\8aí" : "");
960 #endif
961             if (polyspot)
962                 bypass_obj(otmp);
963             m_lose_armor(mon, otmp);
964         }
965         if ((otmp = which_armor(mon, W_ARMS)) != 0) {
966             if (vis)
967 #if 0 /*JP*/
968                 pline("%s can no longer hold %s shield!", Monnam(mon),
969                       ppronoun);
970 #else
971                 pline("%s\82Í\82à\82Í\82â\8f\82\82ð\8e\9d\82Â\82±\82Æ\82ª\82Å\82«\82È\82¢\81I", Monnam(mon));
972 #endif
973             else
974 /*JP
975                 You_hear("a clank.");
976 */
977                 You_hear("\83J\83\89\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
978             if (polyspot)
979                 bypass_obj(otmp);
980             m_lose_armor(mon, otmp);
981         }
982     }
983     if (handless_or_tiny || has_horns(mdat)) {
984         if ((otmp = which_armor(mon, W_ARMH)) != 0
985             /* flimsy test for horns matches polyself handling */
986             && (handless_or_tiny || !is_flimsy(otmp))) {
987             if (vis)
988 #if 0 /*JP*/
989                 pline("%s helmet falls to the %s!", s_suffix(Monnam(mon)),
990                       surface(mon->mx, mon->my));
991 #else
992                 pline("%s\82Ì\8a\95\82Í%s\82Ö\97\8e\82¿\82½\81I", 
993                       Monnam(mon), surface(mon->mx, mon->my));
994 #endif
995             else
996 /*JP
997                 You_hear("a clank.");
998 */
999                 You_hear("\83K\83`\83\83\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
1000             if (polyspot)
1001                 bypass_obj(otmp);
1002             m_lose_armor(mon, otmp);
1003         }
1004     }
1005     if (handless_or_tiny || slithy(mdat) || mdat->mlet == S_CENTAUR) {
1006         if ((otmp = which_armor(mon, W_ARMF)) != 0) {
1007             if (vis) {
1008                 if (is_whirly(mon->data))
1009 /*JP
1010                     pline("%s boots fall away!", s_suffix(Monnam(mon)));
1011 */
1012                     pline("%s\82Ì\8cC\82Í\82Ê\82°\97\8e\82¿\82½\81I", Monnam(mon));
1013                 else
1014 #if 0 /*JP*/
1015                     pline("%s boots %s off %s feet!", s_suffix(Monnam(mon)),
1016                           verysmall(mdat) ? "slide" : "are pushed", ppronoun);
1017 #else
1018                     pline("%s\82Ì\8cC\82Í\91«\82©\82ç%s\81I", Monnam(mon),
1019                           verysmall(mdat) ? "\8a\8a\82è\97\8e\82¿\82½" : "\89\9f\82µ\8fo\82³\82ê\82½");
1020 #endif
1021             }
1022             if (polyspot)
1023                 bypass_obj(otmp);
1024             m_lose_armor(mon, otmp);
1025         }
1026     }
1027     if (!can_saddle(mon)) {
1028         if ((otmp = which_armor(mon, W_SADDLE)) != 0) {
1029             if (polyspot)
1030                 bypass_obj(otmp);
1031             m_lose_armor(mon, otmp);
1032             if (vis)
1033 /*JP
1034                 pline("%s saddle falls off.", s_suffix(Monnam(mon)));
1035 */
1036                 pline("%s\82©\82ç\88Æ\82ª\97\8e\82¿\82½\81D", Monnam(mon));
1037         }
1038         if (mon == u.usteed)
1039             goto noride;
1040     } else if (mon == u.usteed && !can_ride(mon)) {
1041     noride:
1042 /*JP
1043         You("can no longer ride %s.", mon_nam(mon));
1044 */
1045         You("\82à\82¤%s\82É\8fæ\82Á\82Ä\82¢\82ç\82ê\82È\82¢\81D", mon_nam(mon));
1046         if (touch_petrifies(u.usteed->data) && !Stone_resistance && rnl(3)) {
1047             char buf[BUFSZ];
1048
1049 /*JP
1050             You("touch %s.", mon_nam(u.usteed));
1051 */
1052             You("%s\82É\90G\82Á\82½\81D", mon_nam(u.usteed));
1053 /*JP
1054             Sprintf(buf, "falling off %s", an(u.usteed->data->mname));
1055 */
1056             Sprintf(buf, "%s\82©\82ç\97\8e\82¿\82Ä", u.usteed->data->mname);
1057             instapetrify(buf);
1058         }
1059         dismount_steed(DISMOUNT_FELL);
1060     }
1061     return;
1062 }
1063
1064 /* bias a monster's preferences towards armor that has special benefits. */
1065 STATIC_OVL int
1066 extra_pref(mon, obj)
1067 struct monst *mon;
1068 struct obj *obj;
1069 {
1070     /* currently only does speed boots, but might be expanded if monsters
1071      * get to use more armor abilities
1072      */
1073     if (obj) {
1074         if (obj->otyp == SPEED_BOOTS && mon->permspeed != MFAST)
1075             return 20;
1076     }
1077     return 0;
1078 }
1079
1080 /*
1081  * Exceptions to things based on race.
1082  * Correctly checks polymorphed player race.
1083  * Returns:
1084  *       0 No exception, normal rules apply.
1085  *       1 If the race/object combination is acceptable.
1086  *      -1 If the race/object combination is unacceptable.
1087  */
1088 int
1089 racial_exception(mon, obj)
1090 struct monst *mon;
1091 struct obj *obj;
1092 {
1093     const struct permonst *ptr = raceptr(mon);
1094
1095     /* Acceptable Exceptions: */
1096     /* Allow hobbits to wear elven armor - LoTR */
1097     if (ptr == &mons[PM_HOBBIT] && is_elven_armor(obj))
1098         return 1;
1099     /* Unacceptable Exceptions: */
1100     /* Checks for object that certain races should never use go here */
1101     /*  return -1; */
1102
1103     return 0;
1104 }
1105 /*worn.c*/