Esempio n. 1
0
File: worn.c Progetto: mbi/NitroHack
/* Wear the best object of each type that the monster has.  During creation,
 * the monster can put everything on at once; otherwise, wearing takes time.
 * This doesn't affect monster searching for objects--a monster may very well
 * search for objects it would not want to wear, because we don't want to
 * check which_armor() each round.
 *
 * We'll let monsters put on shirts and/or suits under worn cloaks, but
 * not shirts under worn suits.  This is somewhat arbitrary, but it's
 * too tedious to have them remove and later replace outer garments,
 * and preventing suits under cloaks makes it a little bit too easy for
 * players to influence what gets worn.  Putting on a shirt underneath
 * already worn body armor is too obviously buggy...
 */
void m_dowear(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).
	 */
	if (verysmall(mon->data) || nohands(mon->data) || is_animal(mon->data))
		return;
	/* give mummies a chance to wear their wrappings
	 * and let skeletons wear their initial armor */
	if (mindless(mon->data) && (!creation ||
	    (mon->data->mlet != S_MUMMY && mon->data != &mons[PM_SKELETON])))
		return;

	m_dowear_type(mon, W_AMUL, creation, FALSE);
	/* 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, FALSE);
	/* 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, FALSE);
	m_dowear_type(mon, W_ARMH, creation, FALSE);
	if (!MON_WEP(mon) || !bimanual(MON_WEP(mon)))
	    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, FALSE);
	if (!cantweararm(mon->data))
	    m_dowear_type(mon, W_ARM, creation, FALSE);
	else
	    m_dowear_type(mon, W_ARM, creation, RACE_EXCEPTION);
}
Esempio n. 2
0
/*
 * See if this armor is better than what we're wearing.
 */
static boolean
is_better_armor(struct monst *mtmp, struct obj *otmp)
{
    struct obj *obj;
    struct obj *best = (struct obj *)0;

    if (otmp->oclass != ARMOR_CLASS)
        return FALSE;

    if (mtmp->data == &mons[PM_KI_RIN] || mtmp->data == &mons[PM_COUATL])
        return FALSE;

    if (cantweararm(mtmp->data) &&
        !(is_cloak(otmp) && mtmp->data->msize == MZ_SMALL))
        return FALSE;

    if (is_shirt(otmp) && (mtmp->misc_worn_check & W_ARM))
        return FALSE;

    if (is_shield(otmp) && (mtmp == &youmonst) ? (uwep && bimanual(uwep))
        : (MON_WEP(mtmp) && bimanual(MON_WEP(mtmp))))
        return FALSE;

    if (is_gloves(otmp) && nohands(mtmp->data))
        return FALSE;

    if (is_boots(otmp) && (slithy(mtmp->data) || mtmp->data->mlet == S_CENTAUR))
        return FALSE;

    if (is_helmet(otmp) && !is_flimsy(otmp) && num_horns(mtmp->data) > 0)
        return FALSE;

    obj = (mtmp == &youmonst) ? invent : mtmp->minvent;

    for (; obj; obj = obj->nobj) {
        if (is_cloak(otmp) && !is_cloak(obj))
            continue;
        if (is_suit(otmp) && !is_suit(obj))
            continue;
        if (is_shirt(otmp) && !is_shirt(obj))
            continue;
        if (is_boots(otmp) && !is_boots(obj))
            continue;
        if (is_shield(otmp) && !is_shield(obj))
            continue;
        if (is_helmet(otmp) && !is_helmet(obj))
            continue;
        if (is_gloves(otmp) && !is_gloves(obj))
            continue;

        if (!obj->owornmask)
            continue;

        if (best &&
            (ARM_BONUS(obj) + extra_pref(mtmp, obj) >=
             ARM_BONUS(best) + extra_pref(mtmp, best)))
            best = obj;
    }

    return ((best == (struct obj *)0) ||
            (ARM_BONUS(otmp) + extra_pref(mtmp, otmp) >
             ARM_BONUS(best) + extra_pref(mtmp, best)));
}