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. */
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. */
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 *));
21 } worn[] = { { W_ARM, &uarm },
31 { W_SWAPWEP, &uswapwep },
32 { W_QUIVER, &uquiver },
40 /* This only allows for one blocking item per property */
41 #define w_blocks(o, m) \
42 ((o->otyp == MUMMY_WRAPPING && ((m) & W_ARMC)) \
44 : (o->otyp == CORNUTHAUM && ((m) & W_ARMH) && !Role_if(PM_WIZARD)) \
47 /* note: monsters don't have clairvoyance, so your role
48 has no significant effect on their use of w_blocks() */
50 /* Updated to use the extrinsic and blocked fields. */
53 register struct obj *obj;
56 register const struct worn *wp;
57 register struct obj *oobj;
60 if ((mask & (W_ARM | I_SPECIAL)) == (W_ARM | I_SPECIAL)) {
61 /* restoring saved game; no properties are conferred via skin */
63 /* assert( !uarm ); */
66 u.uroleplay.nudist = FALSE;
67 for (wp = worn; wp->w_mask; wp++)
68 if (wp->w_mask & mask) {
70 if (oobj && !(oobj->owornmask & wp->w_mask))
71 impossible("Setworn: mask = %ld.", wp->w_mask);
73 if (u.twoweap && (oobj->owornmask & (W_WEP | W_SWAPWEP)))
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
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;
85 set_artifact_intrinsic(oobj, 0, mask);
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);
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.
99 if (wp->w_mask & ~(W_SWAPWEP | W_QUIVER)) {
100 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
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;
109 set_artifact_intrinsic(obj, 1, mask);
117 /* called e.g. when obj is destroyed */
118 /* Updated to use the extrinsic and blocked fields. */
121 register struct obj *obj;
123 register const struct worn *wp;
128 if (obj == uwep || obj == uswapwep)
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);
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;
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;
148 /* return item worn in slot indiciated by wornmask; needed by poly_obj() */
150 wearmask_to_obj(wornmask)
153 const struct worn *wp;
155 for (wp = worn; wp->w_mask; wp++)
156 if (wp->w_mask & wornmask)
158 return (struct obj *) 0;
161 /* return a bitmask of the equipment slot(s) a given item might be worn in */
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 */
171 switch (obj->oclass) {
173 res = W_AMUL; /* WORN_AMUL */
176 res = W_RINGL | W_RINGR; /* W_RING, BOTH_SIDES */
179 switch (objects[otyp].oc_armcat) {
182 break; /* WORN_ARMOR */
185 break; /* WORN_SHIELD */
188 break; /* WORN_HELMET */
191 break; /* WORN_GLOVES */
194 break; /* WORN_BOOTS */
197 break; /* WORN_CLOAK */
200 break; /* WORN_SHIRT */
204 res = W_WEP | W_SWAPWEP;
205 if (objects[otyp].oc_merge)
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)
217 if (obj->otyp == MEAT_RING)
218 res = W_RINGL | W_RINGR;
240 if (!mon->invis_blkd) {
242 newsym(mon->mx, mon->my); /* make it disappear */
244 see_wsegs(mon); /* and any tail too */
249 mon_adjust_speed(mon, adjust, obj)
251 int adjust; /* positive => increase speed, negative => decrease */
252 struct obj *obj; /* item to make known if effect can be seen */
255 boolean give_msg = !in_mklev, petrify = FALSE;
256 unsigned int oldspeed = mon->mspeed;
260 mon->permspeed = MFAST;
261 give_msg = FALSE; /* special case monster creation */
264 if (mon->permspeed == MSLOW)
267 mon->permspeed = MFAST;
269 case 0: /* just check for worn speed boots */
272 if (mon->permspeed == MFAST)
275 mon->permspeed = MSLOW;
278 mon->permspeed = MSLOW;
279 give_msg = FALSE; /* (not currently used) */
281 case -3: /* petrification */
282 /* take away intrinsic speed but don't reduce normal speed */
283 if (mon->permspeed == MFAST)
287 case -4: /* green slime */
288 if (mon->permspeed == MFAST)
294 for (otmp = mon->minvent; otmp; otmp = otmp->nobj)
295 if (otmp->owornmask && objects[otmp->otyp].oc_oprop == FAST)
297 if (otmp) /* speed boots */
300 mon->mspeed = mon->permspeed;
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 =
308 (mon->mspeed + oldspeed == MFAST + MSLOW) ? "much " : "";
310 (mon->mspeed + oldspeed == MFAST + MSLOW) ? "
\82·
\82²
\82" : "";
313 /* mimic the player's petrification countdown; "slowing down"
314 even if fast movement rate retained via worn speed boots */
317 pline("%s is slowing down.", Monnam(mon));
319 pline("%s
\82Í
\82Ì
\82ë
\82
\82È
\82Á
\82½
\81D", Monnam(mon));
320 } else if (adjust > 0 || mon->mspeed == MFAST)
322 pline("%s is suddenly moving %sfaster.", Monnam(mon), howmuch);
324 pline("%s
\82Ì
\93®
\82«
\82Í
\93Ë
\91R%s
\82·
\82Î
\82â
\82
\82È
\82Á
\82½
\81D", Monnam(mon), howmuch);
327 pline("%s seems to be moving %sslower.", Monnam(mon), howmuch);
329 pline("%s
\82Ì
\93®
\82«
\82Í%s
\82Ì
\82ë
\82
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D", Monnam(mon), howmuch);
331 /* might discover an object if we see the speed change happen */
337 /* armor put on or taken off; might be magical variety
338 [TODO: rename to 'update_mon_extrinsics()' and change all callers...] */
340 update_mon_intrinsics(mon, obj, on, silently)
343 boolean on, silently;
348 int which = (int) objects[obj->otyp].oc_oprop;
350 unseen = !canseemon(mon);
357 mon->minvis = !mon->invis_blkd;
360 boolean save_in_mklev = in_mklev;
363 mon_adjust_speed(mon, 0, obj);
364 in_mklev = save_in_mklev;
367 /* properties handled elsewhere */
371 /* properties which have no effect for monsters */
376 /* properties which should have an effect but aren't implemented */
380 /* properties which maybe should have an effect but don't */
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;
397 mon->minvis = mon->perminvis;
400 boolean save_in_mklev = in_mklev;
403 mon_adjust_speed(mon, 0, obj);
404 in_mklev = save_in_mklev;
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)
421 && (int) objects[otmp->otyp].oc_oprop == which)
424 mon->mextrinsics &= ~((unsigned short) mask);
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)) {
437 mon->invis_blkd = on ? 1 : 0;
438 mon->minvis = on ? 0 : mon->perminvis;
444 if (!on && mon == u.usteed && obj->otyp == SADDLE)
445 dismount_steed(DISMOUNT_FELL);
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);
454 register struct monst *mon;
456 register struct obj *obj;
457 int base = mon->data->ac;
458 long mwflags = mon->misc_worn_check;
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 */
469 * weapons are handled separately;
470 * rings and eyewear aren't used by monsters
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.
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...
487 m_dowear(mon, creation)
488 register struct monst *mon;
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).
496 if (verysmall(mon->data) || nohands(mon->data) || is_animal(mon->data))
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])))
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);
522 m_dowear_type(mon, W_ARM, creation, RACE_EXCEPTION);
526 m_dowear_type(mon, flag, creation, racialexception)
530 boolean racialexception;
532 struct obj *old, *best, *obj;
534 int unseen = !canseemon(mon);
539 return; /* probably putting previous item on */
541 /* Get a copy of monster's name before altering its visibility */
542 Strcpy(nambuf, See_invisible ? Monnam(mon) : mon_nam(mon));
544 old = which_armor(mon, flag);
545 if (old && old->cursed)
547 if (old && flag == W_AMUL)
548 return; /* no such thing as better amulets */
551 for (obj = mon->minvent; obj; obj = obj->nobj) {
554 if (obj->oclass != AMULET_CLASS
555 || (obj->otyp != AMULET_OF_LIFE_SAVING
556 && obj->otyp != AMULET_OF_REFLECTION))
559 goto outer_break; /* no such thing as better amulets */
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))
577 /* (flimsy exception matches polyself handling) */
578 if (has_horns(mon->data) && !is_flimsy(obj))
596 if (racialexception && (racial_exception(mon, obj) < 1))
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.
608 if (best && (ARM_BONUS(best) + extra_pref(mon, best)
609 >= ARM_BONUS(obj) + extra_pref(mon, obj)))
614 if (!best || best == old)
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))
624 /* when upgrading a piece of armor, account for time spent
625 taking off current one */
627 m_delay += objects[old->otyp].oc_delay;
629 if (old) /* do this first to avoid "(being worn)" */
632 if (canseemon(mon)) {
637 Sprintf(buf, " removes %s and", distant_name(old, doname));
639 Sprintf(buf, "%s
\82ð
\82Í
\82¸
\82µ
\82Ä", distant_name(old, doname));
643 pline("%s%s puts on %s.", Monnam(mon), buf,
644 distant_name(best, doname));
646 pline("%s
\82Í%s%s
\82ð
\90g
\82É
\82Â
\82¯
\82½
\81D", Monnam(mon), buf,
647 distant_name(best,doname));
651 pline("%s %s %s %s for a moment.", s_suffix(Monnam(mon)),
652 simpleonames(best), otense(best, "glow"),
655 pline("%s
\82Ì%s
\82Í
\82µ
\82Î
\82ç
\82%s
\8bP
\82¢
\82½
\81D", Monnam(mon),
657 jconj_adj(hcolor(NH_BLACK)));
660 m_delay += objects[best->otyp].oc_delay;
661 mon->mfrozen = m_delay;
666 update_mon_intrinsics(mon, old, FALSE, creation);
667 mon->misc_worn_check |= flag;
668 best->owornmask |= flag;
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) {
676 pline("Suddenly you cannot see %s.", nambuf);
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!",
684 #undef RACE_EXCEPTION
687 which_armor(mon, flag)
691 if (mon == &youmonst) {
708 impossible("bad flag in which_armor");
712 register struct obj *obj;
714 for (obj = mon->minvent; obj; obj = obj->nobj)
715 if (obj->owornmask & flag)
717 return (struct obj *) 0;
721 /* remove an item of armor and then drop it */
723 m_lose_armor(mon, obj)
727 mon->misc_worn_check &= ~obj->owornmask;
729 update_mon_intrinsics(mon, obj, FALSE, FALSE);
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);
738 /* all objects with their bypass bit set should now be reset to normal */
742 struct obj *otmp, *nobj;
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
752 for (otmp = fobj; otmp; otmp = nobj) {
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.]
764 if (objects[otmp->otyp].oc_merge) {
767 (void) get_obj_location(otmp, &ox, &oy, 0);
774 for (otmp = invent; otmp; otmp = otmp->nobj)
776 for (otmp = migrating_objs; otmp; otmp = otmp->nobj)
778 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
779 if (DEADMONSTER(mtmp))
781 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
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;
791 for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
792 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
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 */
797 /* billobjs and mydogs chains don't matter here */
798 context.bypasses = FALSE;
806 context.bypasses = TRUE;
809 /* set or clear the bypass bit in a list of objects */
811 bypass_objlist(objchain, on)
812 struct obj *objchain;
813 boolean on; /* TRUE => set, FALSE => clear */
816 context.bypasses = TRUE;
818 objchain->bypass = on ? 1 : 0;
819 objchain = objchain->nobj;
823 /* return the first object without its bypass bit set; set that bit
824 before returning so that successive calls will find further objects */
826 nxt_unbypassed_obj(objchain)
827 struct obj *objchain;
830 if (!objchain->bypass) {
831 bypass_obj(objchain);
834 objchain = objchain->nobj;
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)) */
844 nxt_unbypassed_loot(lootarray, listhead)
846 struct obj *listhead;
850 while ((obj = lootarray->obj) != 0) {
851 for (o = listhead; o; o = o->nobj)
854 if (o && !obj->bypass) {
864 mon_break_armor(mon, polyspot)
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);
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 */
885 pline("%s breaks out of %s armor!", Monnam(mon), ppronoun);
887 pline("%s
\82Í
\8aZ
\82ð
\82â
\82Ô
\82è
\8fo
\82½
\81I", Monnam(mon));
890 You_hear("a cracking sound.");
892 You_hear("
\83o
\83\8a\83o
\83\8a\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
895 if ((otmp = which_armor(mon, W_ARMC)) != 0) {
896 if (otmp->oartifact) {
899 pline("%s %s falls off!", s_suffix(Monnam(mon)),
900 cloak_simple_name(otmp));
902 pline("%s
\82Ì%s
\82Í
\97\8e\82¿
\82½
\81I", Monnam(mon),
903 cloak_simple_name(otmp));
907 m_lose_armor(mon, otmp);
911 pline("%s %s tears apart!", s_suffix(Monnam(mon)),
912 cloak_simple_name(otmp));
914 pline("%s
\82Ì%s
\82Í
\82¸
\82½
\82¸
\82½
\82É
\82È
\82Á
\82½
\81I", Monnam(mon),
915 cloak_simple_name(otmp));
919 You_hear("a ripping sound.");
921 You_hear("
\83r
\83\8a\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
925 if ((otmp = which_armor(mon, W_ARMU)) != 0) {
928 pline("%s shirt rips to shreds!", s_suffix(Monnam(mon)));
930 pline("%s
\82Ì
\83V
\83\83\83c
\82Í
\82¸
\82½
\82¸
\82½
\82É
\82È
\82Á
\82½
\81I", Monnam(mon));
933 You_hear("a ripping sound.");
935 You_hear("
\83r
\83\8a\83b
\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
938 } else if (sliparm(mdat)) {
939 if ((otmp = which_armor(mon, W_ARM)) != 0) {
942 pline("%s armor falls around %s!", s_suffix(Monnam(mon)),
945 pline("%s
\82Ì
\8aZ
\82ª
\89ñ
\82è
\82É
\97\8e\82¿
\82½
\81I", Monnam(mon));
951 You_hear("
\83h
\83V
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
954 m_lose_armor(mon, otmp);
956 if ((otmp = which_armor(mon, W_ARMC)) != 0) {
958 if (is_whirly(mon->data))
960 pline("%s %s falls, unsupported!", s_suffix(Monnam(mon)),
961 cloak_simple_name(otmp));
963 pline("%s
\82Ì%s
\82Í
\8ex
\82¦
\82«
\82ê
\82¸
\82É
\97\8e\82¿
\82½
\81I", Monnam(mon),
964 cloak_simple_name(otmp));
968 pline("%s shrinks out of %s %s!", Monnam(mon), ppronoun,
969 cloak_simple_name(otmp));
971 pline("%s
\82Í%s
\82æ
\82è
\8fk
\82ñ
\82¾
\81I", Monnam(mon),
972 cloak_simple_name(otmp));
977 m_lose_armor(mon, otmp);
979 if ((otmp = which_armor(mon, W_ARMU)) != 0) {
981 if (sliparm(mon->data))
983 pline("%s seeps right through %s shirt!", Monnam(mon),
986 pline("%s
\82Í
\8e©
\95ª
\82Ì
\83V
\83\83\83c
\82É
\82µ
\82Ý
\8d\9e\82ñ
\82¾
\81I", Monnam(mon));
990 pline("%s becomes much too small for %s shirt!",
991 Monnam(mon), ppronoun);
993 pline("%s
\82Í
\8e©
\95ª
\82Ì
\83V
\83\83\83c
\82æ
\82è
\82¸
\82Á
\82Æ
\8f¬
\82³
\82
\82È
\82Á
\82½
\81I",
999 m_lose_armor(mon, otmp);
1002 if (handless_or_tiny) {
1003 /* [caller needs to handle weapon checks] */
1004 if ((otmp = which_armor(mon, W_ARMG)) != 0) {
1007 pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
1008 MON_WEP(mon) ? " and weapon" : "");
1010 pline("%s
\82Í
\8f¬
\8eè%s
\82ð
\97\8e\82µ
\82½
\81I", Monnam(mon),
1011 MON_WEP(mon) ? "
\82Æ
\95\90\8aí" : "");
1015 m_lose_armor(mon, otmp);
1017 if ((otmp = which_armor(mon, W_ARMS)) != 0) {
1020 pline("%s can no longer hold %s shield!", Monnam(mon),
1023 pline("%s
\82Í
\82à
\82Í
\82â
\8f\82\82ð
\8e\9d\82Â
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81I", Monnam(mon));
1027 You_hear("a clank.");
1029 You_hear("
\83J
\83\89\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1032 m_lose_armor(mon, otmp);
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))) {
1041 pline("%s helmet falls to the %s!", s_suffix(Monnam(mon)),
1042 surface(mon->mx, mon->my));
1044 pline("%s
\82Ì
\8a\95\82Í%s
\82Ö
\97\8e\82¿
\82½
\81I",
1045 Monnam(mon), surface(mon->mx, mon->my));
1049 You_hear("a clank.");
1051 You_hear("
\83K
\83`
\83\83\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1054 m_lose_armor(mon, otmp);
1057 if (handless_or_tiny || slithy(mdat) || mdat->mlet == S_CENTAUR) {
1058 if ((otmp = which_armor(mon, W_ARMF)) != 0) {
1060 if (is_whirly(mon->data))
1062 pline("%s boots fall away!", s_suffix(Monnam(mon)));
1064 pline("%s
\82Ì
\8cC
\82Í
\82Ê
\82°
\97\8e\82¿
\82½
\81I", Monnam(mon));
1067 pline("%s boots %s off %s feet!", s_suffix(Monnam(mon)),
1068 verysmall(mdat) ? "slide" : "are pushed", ppronoun);
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½");
1076 m_lose_armor(mon, otmp);
1079 if (!can_saddle(mon)) {
1080 if ((otmp = which_armor(mon, W_SADDLE)) != 0) {
1083 m_lose_armor(mon, otmp);
1086 pline("%s saddle falls off.", s_suffix(Monnam(mon)));
1088 pline("%s
\82©
\82ç
\88Æ
\82ª
\97\8e\82¿
\82½
\81D", Monnam(mon));
1090 if (mon == u.usteed)
1092 } else if (mon == u.usteed && !can_ride(mon)) {
1095 You("can no longer ride %s.", mon_nam(mon));
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)) {
1102 You("touch %s.", mon_nam(u.usteed));
1104 You("%s
\82É
\90G
\82Á
\82½
\81D", mon_nam(u.usteed));
1106 Sprintf(buf, "falling off %s", an(u.usteed->data->mname));
1108 Sprintf(buf, "%s
\82©
\82ç
\97\8e\82¿
\82Ä", u.usteed->data->mname);
1111 dismount_steed(DISMOUNT_FELL);
1116 /* bias a monster's preferences towards armor that has special benefits. */
1118 extra_pref(mon, obj)
1122 /* currently only does speed boots, but might be expanded if monsters
1123 * get to use more armor abilities
1126 if (obj->otyp == SPEED_BOOTS && mon->permspeed != MFAST)
1133 * Exceptions to things based on race.
1134 * Correctly checks polymorphed player race.
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.
1141 racial_exception(mon, obj)
1145 const struct permonst *ptr = raceptr(mon);
1147 /* Acceptable Exceptions: */
1148 /* Allow hobbits to wear elven armor - LoTR */
1149 if (ptr == &mons[PM_HOBBIT] && is_elven_armor(obj))
1151 /* Unacceptable Exceptions: */
1152 /* Checks for object that certain races should never use go here */