OSDN Git Service

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