Example #1
0
File: worn.c Project: mbi/NitroHack
static void m_dowear_type(struct monst *mon, long flag, boolean creation,
			  boolean racialexception)
{
	struct obj *old, *best, *obj;
	int m_delay = 0;
	int unseen = !canseemon(mon);
	char nambuf[BUFSZ];

	if (mon->mfrozen) return; /* probably putting previous item on */

	/* Get a copy of monster's name before altering its visibility */
	strcpy(nambuf, See_invisible ? Monnam(mon) : mon_nam(mon));

	old = which_armor(mon, flag);
	if (old && old->cursed) return;
	if (old && flag == W_AMUL) return; /* no such thing as better amulets */
	best = old;

	for (obj = mon->minvent; obj; obj = obj->nobj) {
	    switch(flag) {
		case W_AMUL:
		    if (obj->oclass != AMULET_CLASS ||
			    (obj->otyp != AMULET_OF_LIFE_SAVING &&
				obj->otyp != AMULET_OF_REFLECTION))
			continue;
		    best = obj;
		    goto outer_break; /* no such thing as better amulets */
		case W_ARMU:
		    if (!is_shirt(obj)) continue;
		    break;
		case W_ARMC:
		    if (!is_cloak(obj)) continue;
		    break;
		case W_ARMH:
		    if (!is_helmet(obj)) continue;
		    /* (flimsy exception matches polyself handling) */
		    if (has_horns(mon->data) && !is_flimsy(obj)) continue;
		    break;
		case W_ARMS:
		    if (!is_shield(obj)) continue;
		    break;
		case W_ARMG:
		    if (!is_gloves(obj)) continue;
		    break;
		case W_ARMF:
		    if (!is_boots(obj)) continue;
		    break;
		case W_ARM:
		    if (!is_suit(obj)) continue;
		    if (racialexception && (racial_exception(mon, obj) < 1)) continue;
		    break;
	    }
	    if (obj->owornmask) continue;
	    /* I'd like to define a VISIBLE_ARM_BONUS which doesn't assume the
	     * monster knows obj->spe, but if I did that, a monster would keep
	     * switching forever between two -2 caps since when it took off one
	     * it would forget spe and once again think the object is better
	     * than what it already has.
	     */
	    if (best && (ARM_BONUS(best) + extra_pref(mon,best) >= ARM_BONUS(obj) + extra_pref(mon,obj)))
		continue;
	    best = obj;
	}
outer_break:
	if (!best || best == old) return;

	/* if wearing a cloak, account for the time spent removing
	   and re-wearing it when putting on a suit or shirt */
	if ((flag == W_ARM || flag == W_ARMU) && (mon->misc_worn_check & W_ARMC))
	    m_delay += 2;
	/* when upgrading a piece of armor, account for time spent
	   taking off current one */
	if (old)
	    m_delay += objects[old->otyp].oc_delay;

	if (old) /* do this first to avoid "(being worn)" */
	    old->owornmask = 0L;
	if (!creation) {
	    if (canseemon(mon)) {
		char buf[BUFSZ];

		if (old)
		    sprintf(buf, " removes %s and", distant_name(old, doname));
		else
		    buf[0] = '\0';
		pline("%s%s puts on %s.", Monnam(mon),
		      buf, distant_name(best,doname));
	    } /* can see it */
	    m_delay += objects[best->otyp].oc_delay;
	    mon->mfrozen = m_delay;
	    if (mon->mfrozen) mon->mcanmove = 0;
	}
	if (old)
	    update_mon_intrinsics(mon, old, FALSE, creation);
	mon->misc_worn_check |= flag;
	best->owornmask |= flag;
	update_mon_intrinsics(mon, best, TRUE, creation);
	/* if couldn't see it but now can, or vice versa, */
	if (!creation && (unseen ^ !canseemon(mon))) {
		if (mon->minvis && !See_invisible) {
			pline("Suddenly you cannot see %s.", nambuf);
			makeknown(best->otyp);
		} /* else if (!mon->minvis) pline("%s suddenly appears!", Amonnam(mon)); */
	}
}
Example #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)));
}