From: nethack.allison Date: Sun, 29 Dec 2002 23:55:58 +0000 (+0000) Subject: buglist entry: hobbits and elven mithril armour X-Git-Tag: MOVE2GIT~2277 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e8ca725e9271848834e4029c7fb53cf7049ef4df;p=nethack buglist entry: hobbits and elven mithril armour 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 --- diff --git a/doc/fixes34.1 b/doc/fixes34.1 index 2d032809e..7f4b55ff1 100644 --- a/doc/fixes34.1 +++ b/doc/fixes34.1 @@ -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 diff --git a/include/extern.h b/include/extern.h index 15d321d9b..6394878e9 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 ### */ diff --git a/include/obj.h b/include/obj.h index 324a1409d..3d5ed3e60 100644 --- a/include/obj.h +++ b/include/obj.h @@ -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) diff --git a/src/do_wear.c b/src/do_wear.c index 84a76464d..baeed4dcc 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -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) { diff --git a/src/polyself.c b/src/polyself.c index 20bd7e099..21e43cd16 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -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(); diff --git a/src/read.c b/src/read.c index ba8c4f496..38431ed45 100644 --- a/src/read.c +++ b/src/read.c @@ -17,13 +17,6 @@ #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) diff --git a/src/worn.c b/src/worn.c index 3ec753af9..40693d814 100644 --- a/src/worn.c +++ b/src/worn.c @@ -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*/