buglist entry: hobbits and elven mithril armour

<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
This commit is contained in:
nethack.allison
2002-12-29 23:55:58 +00:00
parent df07fd4b90
commit e8ca725e92
7 changed files with 93 additions and 20 deletions

View 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

View 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 ### */

View 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)

View 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) {

View 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();

View File

@@ -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)

View 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*/