]> granicus.if.org Git - nethack/commitdiff
buglist entry: hobbits and elven mithril armour
authornethack.allison <nethack.allison>
Sun, 29 Dec 2002 23:55:58 +0000 (23:55 +0000)
committernethack.allison <nethack.allison>
Sun, 29 Dec 2002 23:55:58 +0000 (23:55 +0000)
<Someone> wrote: "Also, hobbits can't wear armour,
at least, you can't wear armour when polymorphed into a hobbit, even
though hobbits do tend to be carrying elven mithril-coats.
It's tempting to suggest adding an explicit exception in
sliparm() for elven mithril just to keep the Tolkienness."

- added a general routine for adding race-based /object
combination exceptions.
- hobbits can wear elven mithril-coats

doc/fixes34.1
include/extern.h
include/obj.h
src/do_wear.c
src/polyself.c
src/read.c
src/worn.c

index 2d032809ea2033e751004afc9df0a395cafe9435..7f4b55ff17bad14d2db9077de6647d4b9b89e08c 100644 (file)
@@ -404,4 +404,4 @@ fire traps are particularly bad for paper and straw golems
 cream pies can be 'a'pplied to cause direct temporary blindness
 eating newt corpse or tin of same can boost magical energy (Malcolm Ryan)
 applying a eucalyptus leaf produces a whistle effect (Malcolm Ryan)
-
+hobbits can wear elven mithril-coats
index 15d321d9b5fee89f5c4658fc7df8fd44ac550905..6394878e91d37a7c51a0e6f4e2752413909379bc 100644 (file)
@@ -2287,6 +2287,7 @@ E struct obj *FDECL(which_armor, (struct monst *,long));
 E void FDECL(mon_break_armor, (struct monst *,BOOLEAN_P));
 E void FDECL(bypass_obj, (struct obj *));
 E void NDECL(clear_bypasses);
+E int FDECL(racial_exception, (struct monst *, struct obj *));
 
 /* ### write.c ### */
 
index 324a1409da505fe834a7a961cdbd91cb1e422b6d..3d5ed3e60f88e055b3fb405151bc81c362e26bd4 100644 (file)
@@ -180,7 +180,24 @@ struct obj {
                         objects[otmp->otyp].oc_armcat == ARM_SHIRT)
 #define is_suit(otmp)  (otmp->oclass == ARMOR_CLASS && \
                         objects[otmp->otyp].oc_armcat == ARM_SUIT)
+#define is_elven_armor(otmp)   ((otmp)->otyp == ELVEN_LEATHER_HELM\
+                               || (otmp)->otyp == ELVEN_MITHRIL_COAT\
+                               || (otmp)->otyp == ELVEN_CLOAK\
+                               || (otmp)->otyp == ELVEN_SHIELD\
+                               || (otmp)->otyp == ELVEN_BOOTS)
+#define is_orcish_armor(otmp)  ((otmp)->otyp == ORCISH_HELM\
+                               || (otmp)->otyp == ORCISH_CHAIN_MAIL\
+                               || (otmp)->otyp == ORCISH_RING_MAIL\
+                               || (otmp)->otyp == ORCISH_CLOAK\
+                               || (otmp)->otyp == URUK_HAI_SHIELD\
+                               || (otmp)->otyp == ORCISH_SHIELD)
+#define is_dwarvish_armor(otmp)        ((otmp)->otyp == DWARVISH_IRON_HELM\
+                               || (otmp)->otyp == DWARVISH_MITHRIL_COAT\
+                               || (otmp)->otyp == DWARVISH_CLOAK\
+                               || (otmp)->otyp == DWARVISH_ROUNDSHIELD)
+#define is_gnomish_armor(otmp) (FALSE)
 
+                               
 /* Eggs and other food */
 #define MAX_EGG_HATCH_TIME 200 /* longest an egg can remain unhatched */
 #define stale_egg(egg) ((monstermoves - (egg)->age) > (2*MAX_EGG_HATCH_TIME))
@@ -212,6 +229,32 @@ struct obj {
                                      - GRAY_DRAGON_SCALE_MAIL]
 #define Dragon_to_scales(pm)   (GRAY_DRAGON_SCALES + (pm - mons))
 
+/* Elven gear */
+#define is_elven_obj(otmp)     (is_elven_armor(otmp)\
+                               || (otmp)->otyp == ELVEN_ARROW\
+                               || (otmp)->otyp == ELVEN_SPEAR\
+                               || (otmp)->otyp == ELVEN_DAGGER\
+                               || (otmp)->otyp == ELVEN_SHORT_SWORD\
+                               || (otmp)->otyp == ELVEN_BROADSWORD\
+                               || (otmp)->otyp == ELVEN_BOW)
+
+/* Orcish gear */
+#define is_orcish_obj(otmp)    (is_orcish_armor(otmp)\
+                               || (otmp)->otyp == ORCISH_ARROW\
+                               || (otmp)->otyp == ORCISH_SPEAR\
+                               || (otmp)->otyp == ORCISH_DAGGER\
+                               || (otmp)->otyp == ORCISH_SHORT_SWORD\
+                               || (otmp)->otyp == ORCISH_BOW)
+
+/* Dwarvish gear */
+#define is_dwarvish_obj(otmp)  (is_dwarvish_armor(otmp)\
+                               || (otmp)->otyp == DWARVISH_SPEAR\
+                               || (otmp)->otyp == DWARVISH_SHORT_SWORD\
+                               || (otmp)->otyp == DWARVISH_MATTOCK)
+
+/* Gnomish gear */
+#define is_gnomish_obj(otmp)   (is_gnomish_armor(otmp))
+
 /* Light sources */
 #define Is_candle(otmp) (otmp->otyp == TALLOW_CANDLE || \
                         otmp->otyp == WAX_CANDLE)
index 84a76464d64057f20eb4bff6a7e2c2e927a4a927..baeed4dcc43a83487bbeba4ca7b59a15b429dd47 100644 (file)
@@ -1177,7 +1177,8 @@ boolean noisy;
            is_suit(otmp) ? c_suit : 0;
     if (which && cantweararm(youmonst.data) &&
            /* same exception for cloaks as used in m_dowear() */
-           (which != c_cloak || youmonst.data->msize != MZ_SMALL)) {
+           (which != c_cloak || youmonst.data->msize != MZ_SMALL) &&
+           (racial_exception(&youmonst, otmp) < 1)) {
        if (noisy) pline_The("%s will not fit on your body.", which);
        return 0;
     } else if (otmp->owornmask & W_ARMOR) {
index 20bd7e0996a9b559ae22b5aea4a9c320792de95c..21e43cd16125a9dfa0aac4422ecc0c96708eff75 100644 (file)
@@ -590,7 +590,7 @@ break_armor()
        }
 #endif
     } else if (sliparm(youmonst.data)) {
-       if ((otmp = uarm) != 0) {
+       if (((otmp = uarm) != 0) && (racial_exception(&youmonst, otmp) < 1)) {
                if (donning(otmp)) cancel_don();
                Your("armor falls around you!");
                (void) Armor_gone();
index ba8c4f496035a5f0b24855961eab85ad446b748c..38431ed4511d856ebddd57adc6c8f678d9adea52 100644 (file)
 
 #ifdef OVLB
 
-/* elven armor vibrates warningly when enchanted beyond a limit */
-#define is_elven_armor(optr)   ((optr)->otyp == ELVEN_LEATHER_HELM\
-                               || (optr)->otyp == ELVEN_MITHRIL_COAT\
-                               || (optr)->otyp == ELVEN_CLOAK\
-                               || (optr)->otyp == ELVEN_SHIELD\
-                               || (optr)->otyp == ELVEN_BOOTS)
-
 boolean        known;
 
 static NEARDATA const char readable[] =
@@ -711,6 +704,7 @@ register struct obj *sobj;
                        }
                        break;
                }
+               /* elven armor vibrates warningly when enchanted beyond a limit */
                special_armor = is_elven_armor(otmp) ||
                        (Role_if(PM_WIZARD) && otmp->otyp == CORNUTHAUM);
                if (sobj->cursed)
index 3ec753af95bfbdd0e9f23938da616b811946bc4f..40693d8149154ad5be6452ebe62e330574248ee3 100644 (file)
@@ -5,7 +5,7 @@
 #include "hack.h"
 
 STATIC_DCL void FDECL(m_lose_armor, (struct monst *,struct obj *));
-STATIC_DCL void FDECL(m_dowear_type, (struct monst *,long,BOOLEAN_P));
+STATIC_DCL void FDECL(m_dowear_type, (struct monst *,long, BOOLEAN_P, BOOLEAN_P));
 STATIC_DCL int FDECL(extra_pref, (struct monst *, struct obj *));
 
 const struct worn {
@@ -360,6 +360,7 @@ m_dowear(mon, creation)
 register struct monst *mon;
 boolean creation;
 {
+#define RACE_EXCEPTION TRUE
        /* Note the restrictions here are the same as in dowear in do_wear.c
         * except for the additional restriction on intelligence.  (Players
         * are always intelligent, even if polymorphed).
@@ -372,31 +373,34 @@ boolean creation;
            (mon->data->mlet != S_MUMMY && mon->data != &mons[PM_SKELETON])))
                return;
 
-       m_dowear_type(mon, W_AMUL, creation);
+       m_dowear_type(mon, W_AMUL, creation, FALSE);
 #ifdef TOURIST
        /* can't put on shirt if already wearing suit */
        if (!cantweararm(mon->data) || (mon->misc_worn_check & W_ARM))
-           m_dowear_type(mon, W_ARMU, creation);
+           m_dowear_type(mon, W_ARMU, creation, FALSE);
 #endif
        /* treating small as a special case allows
           hobbits, gnomes, and kobolds to wear cloaks */
        if (!cantweararm(mon->data) || mon->data->msize == MZ_SMALL)
-           m_dowear_type(mon, W_ARMC, creation);
-       m_dowear_type(mon, W_ARMH, creation);
+           m_dowear_type(mon, W_ARMC, creation, FALSE);
+       m_dowear_type(mon, W_ARMH, creation, FALSE);
        if (!MON_WEP(mon) || !bimanual(MON_WEP(mon)))
-           m_dowear_type(mon, W_ARMS, creation);
-       m_dowear_type(mon, W_ARMG, creation);
+           m_dowear_type(mon, W_ARMS, creation, FALSE);
+       m_dowear_type(mon, W_ARMG, creation, FALSE);
        if (!slithy(mon->data) && mon->data->mlet != S_CENTAUR)
-           m_dowear_type(mon, W_ARMF, creation);
+           m_dowear_type(mon, W_ARMF, creation, FALSE);
        if (!cantweararm(mon->data))
-           m_dowear_type(mon, W_ARM, creation);
+           m_dowear_type(mon, W_ARM, creation, FALSE);
+       else
+           m_dowear_type(mon, W_ARM, creation, RACE_EXCEPTION);
 }
 
 STATIC_OVL void
-m_dowear_type(mon, flag, creation)
+m_dowear_type(mon, flag, creation, racialexception)
 struct monst *mon;
 long flag;
 boolean creation;
+boolean racialexception;
 {
        struct obj *old, *best, *obj;
        int m_delay = 0;
@@ -439,6 +443,7 @@ boolean creation;
                    break;
                case W_ARM:
                    if (!is_suit(obj)) continue;
+                   if (racialexception && (racial_exception(mon, obj) < 1)) continue;
                    break;
            }
            if (obj->owornmask) continue;
@@ -491,6 +496,7 @@ outer_break:
        best->owornmask |= flag;
        update_mon_intrinsics(mon, best, TRUE, creation);
 }
+#undef RACE_EXCEPTION
 
 struct obj *
 which_armor(mon, flag)
@@ -742,4 +748,32 @@ struct obj *obj;
     }
     return 0;
 }
+
+/*
+ * Exceptions to things based on race. Correctly checks polymorphed player race.
+ * Returns:
+ *      0 No exception, normal rules apply.
+ *      1 If the race/object combination is acceptable.
+ *     -1 If the race/object combination is unacceptable.
+ */
+int
+racial_exception(mon, obj)
+struct monst *mon;
+struct obj *obj;
+{
+    struct permonst *ptr;
+
+    if (mon == &youmonst && !Upolyd) ptr = &mons[urace.malenum];
+    else ptr = mon->data;
+
+    /* Acceptable Exceptions: */
+    /* Allow hobbits to wear elven armor - LoTR */
+    if (ptr == &mons[PM_HOBBIT] && is_elven_armor(obj))
+       return 1;
+    /* Unacceptable Exceptions: */
+    /* Checks for object that certain races should never use go here */
+    /* return -1; */
+
+    return 0;
+}
 /*worn.c*/