OSDN Git Service

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