Beispiel #1
0
/* drop one object taken from a (possibly dead) monster's inventory */
static void mdrop_obj(struct monst *mon, struct obj *obj, boolean verbosely)
{
    int omx = mon->mx, omy = mon->my;

    if (obj->owornmask) {
	/* perform worn item handling if the monster is still alive */
	if (mon->mhp > 0) {
	    mon->misc_worn_check &= ~obj->owornmask;
	    update_mon_intrinsics(level, mon, obj, FALSE, TRUE);
	 /* obj_no_longer_held(obj); -- done by place_object */
	    if (obj->owornmask & W_WEP) setmnotwielded(mon, obj);
	/* don't charge for an owned saddle on dead steed */
	} else if (mon->mtame && (obj->owornmask & W_SADDLE) && 
		!obj->unpaid && costly_spot(omx, omy)) {
	    obj->no_charge = 1;
	}
	obj->owornmask = 0L;
    }
    if (verbosely && cansee(omx, omy))
	pline("%s drops %s.", Monnam(mon), distant_name(obj, doname));
    if (!flooreffects(obj, omx, omy, "fall")) {
	place_object(obj, level, omx, omy);
	stackobj(obj);
    }
}
Beispiel #2
0
/* drop one object taken from a (possibly dead) monster's inventory */
static void mdrop_obj (struct monst *mon, struct obj *obj, bool verbosely) {
    int omx = mon->mx, omy = mon->my;

    if (obj->owornmask) {
        /* perform worn item handling if the monster is still alive */
        if (mon->mhp > 0) {
            mon->misc_worn_check &= ~obj->owornmask;
            update_mon_intrinsics(mon, obj, false, true);
            /* obj_no_longer_held(obj); -- done by place_object */
            if (obj->owornmask & W_WEP) setmnotwielded(mon, obj);
            /* don't charge for an owned saddle on dead steed */
        } else if (mon->mtame && (obj->owornmask & W_SADDLE) &&
                !obj->unpaid && costly_spot(omx, omy)) {
            obj->no_charge = 1;
        }
        obj->owornmask = 0L;
    }
    if (verbosely && cansee(omx, omy)) {
        message_monster_object(MSG_M_DROPS_O, mon, obj);
    }
    if (!flooreffects(obj, omx, omy, "fall")) {
        place_object(obj, omx, omy);
        stackobj(obj);
    }
}
Beispiel #3
0
/* remove an item of armor and then drop it */
static void m_lose_armor(struct monst *mon, struct obj *obj)
{
	mon->misc_worn_check &= ~obj->owornmask;
	if (obj->owornmask)
	    update_mon_intrinsics(mon, obj, FALSE, FALSE);
	obj->owornmask = 0L;

	obj_extract_self(obj);
	place_object(obj, level, mon->mx, mon->my);
	/* call stackobj() if we ever drop anything that can merge */
	newsym(mon->mx, mon->my);
}
Beispiel #4
0
/*
 * This function is only called from newgame, so we know:
 *   - pets aren't genocided so makemon will always work
 *   - the petname has not been used yet
 * This is called very late in the newgame sequence, and so can safely clobber
 * the charstats RNGs.
 */
struct monst *
makedog(struct newgame_options *ngo)
{
    struct monst *mtmp;
    struct obj *otmp;
    const char *petname;
    int pettype;

    if (ngo->preferred_pet == 'n')
        return NULL;

    pettype = pet_type(ngo);
    if (pettype == PM_LITTLE_DOG)
        petname = ngo->dogname;
    else if (pettype == PM_PONY)
        petname = ngo->horsename;
    else
        petname = ngo->catname;

    /* default pet names */
    if (!*petname && pettype == PM_LITTLE_DOG) {
        /* All of these names were for dogs. */
        if (Role_if(PM_CAVEMAN))
            petname = "Slasher";        /* The Warrior */
        if (Role_if(PM_SAMURAI))
            petname = "Hachi";  /* Shibuya Station */
        if (Role_if(PM_BARBARIAN))
            petname = "Idefix"; /* Obelix */
        if (Role_if(PM_RANGER))
            petname = "Sirius"; /* Orion's dog */
    }

    /* ideally we'd use rng_charstats_role for this, but... */
    mtmp = makemon(&mons[pettype], level, u.ux, u.uy, MM_EDOG);

    /* Horses already wear a saddle */
    if (pettype == PM_PONY &&
        ((otmp = mksobj(level, SADDLE, TRUE, FALSE, rng_charstats_role)))) {
        if (mpickobj(mtmp, otmp))
            panic("merged saddle?");
        mtmp->misc_worn_check |= W_MASK(os_saddle);
        otmp->dknown = otmp->bknown = otmp->rknown = 1;
        otmp->owornmask = W_MASK(os_saddle);
        otmp->leashmon = mtmp->m_id;
        update_mon_intrinsics(mtmp, otmp, TRUE, TRUE);
    }

    if (*petname)
        mtmp = christen_monst(mtmp, petname);

    initedog(mtmp);
    return mtmp;
}
Beispiel #5
0
/* Remove an item from the monster's inventory and destroy it. */
void
m_useup(struct monst *mon, struct obj *obj)
{
    if (obj->quan > 1L) {
        obj->quan--;
        obj->owt = weight(obj);
    } else {
        obj_extract_self(obj);
        possibly_unwield(mon, FALSE);
        if (obj->owornmask) {
            mon->misc_worn_check &= ~obj->owornmask;
            update_mon_intrinsics(mon, obj, FALSE, FALSE);
        }
        obfree(obj, NULL);
    }
}
Beispiel #6
0
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)); */
	}
}
Beispiel #7
0
int
use_saddle(struct obj *otmp, const struct nh_cmd_arg *arg)
{
    struct monst *mtmp;
    const struct permonst *ptr;
    int chance;
    const char *s;
    schar dx, dy, dz;

    /* Can you use it? */
    if (nohands(youmonst.data)) {
        pline("You have no hands!");    /* not `body_part(HAND)' */
        return 0;
    } else if (!freehand()) {
        pline("You have no free %s.", body_part(HAND));
        return 0;
    }

    /* Select an animal */
    if (Engulfed || Underwater || !getargdir(arg, NULL, &dx, &dy, &dz)) {
        pline("Never mind.");
        return 0;
    }
    if (!dx && !dy) {
        pline("Saddle yourself?  Very funny...");
        return 0;
    }
    if (!isok(u.ux + dx, u.uy + dy) ||
            !((mtmp = m_at(level, u.ux + dx, u.uy + dy))) || !canspotmon(mtmp)) {
        if (knownwormtail(u.ux + dx, u.uy + dy))
            pline("It's hard to strap a saddle to a tail.");
        else
            pline("I see nobody there.");
        return 0;
    }

    /* Is this a valid monster? */
    if (mtmp->misc_worn_check & W_MASK(os_saddle) ||
            which_armor(mtmp, os_saddle)) {
        pline("%s doesn't need another one.", Monnam(mtmp));
        return 0;
    }
    ptr = mtmp->data;
    if (!uarmg && touched_monster(ptr - mons)) {
        pline("You touch %s.", mon_nam(mtmp));
        instapetrify(killer_msg(STONING, msgcat("attempting to saddle ",
                                                an(mtmp->data->mname))));
    }
    if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) {
        pline("Shame on you!");
        exercise(A_WIS, FALSE);
        return 1;
    }
    if (mtmp->isminion || mtmp->isshk || mtmp->ispriest || mtmp->isgd ||
            mtmp->iswiz) {
        pline("I think %s would mind.", mon_nam(mtmp));
        return 0;
    }
    if (!can_saddle(mtmp)) {
        pline("You can't saddle such a creature.");
        return 0;
    }

    /* Calculate your chance */
    chance = ACURR(A_DEX) + ACURR(A_CHA) / 2 + 2 * mtmp->mtame;
    chance += u.ulevel * (mtmp->mtame ? 20 : 5);
    if (!mtmp->mtame)
        chance -= 10 * mtmp->m_lev;
    if (Role_if(PM_KNIGHT))
        chance += 20;
    switch (P_SKILL(P_RIDING)) {
    case P_ISRESTRICTED:
    case P_UNSKILLED:
    default:
        chance -= 20;
        break;
    case P_BASIC:
        break;
    case P_SKILLED:
        chance += 15;
        break;
    case P_EXPERT:
        chance += 30;
        break;
    }
    if (Confusion || Fumbling || Glib)
        chance -= 20;
    else if (uarmg && (s = OBJ_DESCR(objects[uarmg->otyp])) != NULL &&
             !strncmp(s, "riding ", 7))
        /* Bonus for wearing "riding" (but not fumbling) gloves */
        chance += 10;
    else if (uarmf && (s = OBJ_DESCR(objects[uarmf->otyp])) != NULL &&
             !strncmp(s, "riding ", 7))
        /* ... or for "riding boots" */
        chance += 10;
    if (otmp->cursed)
        chance -= 50;

    /* steed becomes alert if possible */
    maybewakesteed(mtmp);

    /* Make the attempt */
    if (rn2(100) < chance) {
        pline("You put the saddle on %s.", mon_nam(mtmp));
        if (otmp->owornmask)
            remove_worn_item(otmp, FALSE);
        freeinv(otmp);
        /* mpickobj may free otmp it if merges, but we have already checked for
           a saddle above, so no merger should happen */
        mpickobj(mtmp, otmp);
        mtmp->misc_worn_check |= W_MASK(os_saddle);
        otmp->owornmask = W_MASK(os_saddle);
        otmp->leashmon = mtmp->m_id;
        update_mon_intrinsics(mtmp, otmp, TRUE, FALSE);
    } else
        pline("%s resists!", Monnam(mtmp));
    return 1;
}
Beispiel #8
0
/* this function is only called from newgame, so we know:
 *   - pets aren't genocided so makemon will always work
 *   - the petname has not been used yet */
struct monst *makedog(void)
{
	struct monst *mtmp;
	struct obj *otmp;
	const char *petname;
	int   pettype;

	if (preferred_pet == 'n') return NULL;

	pettype = pet_type();
	if (pettype == PM_LITTLE_DOG)
		petname = dogname;
	else if (pettype == PM_PONY)
		petname = horsename;
	else if (pettype == PM_MONKEY)
		petname = monkeyname;
	else if (pettype == PM_WOLF || pettype == PM_WINTER_WOLF_CUB)
		petname = wolfname;
	else if (pettype == PM_BABY_CROCODILE)
		petname = crocname;
	else if (pettype == PM_SEWER_RAT)
		petname = ratname;
	else
		petname = catname;

	/* default pet names */
	if (!*petname) {
	    if (pettype == PM_LITTLE_DOG) {
		/* All of these names were for dogs. */
		if (Role_if(PM_CAVEMAN)) petname = "Slasher";   /* The Warrior */
		if (Role_if(PM_SAMURAI)) petname = "Hachi";     /* Shibuya Station */
		if (Role_if(PM_BARBARIAN)) petname = "Idefix";  /* Obelix */
		if (Role_if(PM_RANGER)) petname = "Sirius";     /* Orion's dog */
	    } else if (pettype == PM_SEWER_RAT) {
		if (Role_if(PM_CONVICT)) petname = "Nicodemus"; /* Rats of NIMH */
	    }
	}

	mtmp = makemon(&mons[pettype], level, u.ux, u.uy, MM_EDOG);

	/* Keep the exotic pets from being higher-level than normal starting
	 * pets.  (makedog is only called once, during game setup, so this
	 * is the place to put it.) */
	if (pettype == PM_WOLF ||
	    pettype == PM_WINTER_WOLF_CUB ||
	    pettype == PM_MONKEY ||
	    pettype == PM_BABY_CROCODILE) {
	    mtmp->m_lev  = 1;
	    mtmp->mhpmax = mtmp->mhp = dice(1,8);
	}

	/* Horses already wear a saddle */
	if (pettype == PM_PONY && !!(otmp = mksobj(level, SADDLE, TRUE, FALSE))) {
	    if (mpickobj(mtmp, otmp))
		panic("merged saddle?");
	    mtmp->misc_worn_check |= W_SADDLE;
	    otmp->dknown = otmp->bknown = otmp->rknown = 1;
	    otmp->owornmask = W_SADDLE;
	    otmp->leashmon = mtmp->m_id;
	    update_mon_intrinsics(level, mtmp, otmp, TRUE, TRUE);
	}

	if (!*petname && pettype == PM_KITTEN && !rn2(100)) {
	    if (mtmp->female) petname = "Shiva"; /* PM: RIP 1 Oct 1998 -  6 Sep 2009 */
	    else petname = "Kali";		 /* PM: RIP 1 May 2000 - 22 Oct 2012 */
	}

	if (*petname)
		mtmp = christen_monst(mtmp, petname);

	initedog(mtmp);
	return mtmp;
}