Beispiel #1
0
int
tamedog(struct monst *mtmp, struct obj *obj)
{
	struct monst *mtmp2;

	if(flags.moonphase == FULL_MOON && night() && rn2(6))
		return(0);

	/* If we cannot tame him, at least he's no longer afraid. */
	mtmp->mflee = 0;
	mtmp->mfleetim = 0;
	if(mtmp->mtame || mtmp->mfroz ||
#ifndef NOWORM
		mtmp->wormno ||
#endif /* NOWORM */
		mtmp->isshk || mtmp->isgd || strchr(" &@12", mtmp->data->mlet))
		return(0); /* no tame long worms? */
	if(obj) {
		if(dogfood(obj) >= MANFOOD) return(0);
		if(cansee(mtmp->mx,mtmp->my)){
			pline("%s devours the %s.", Monnam(mtmp),
				objects[obj->otyp].oc_name);
		}
		obfree(obj, (struct obj *) 0);
	}
	mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth);
	*mtmp2 = *mtmp;
	mtmp2->mxlth = sizeof(struct edog);
	if(mtmp->mnamelth)
		(void) strlcpy(NAME(mtmp2), NAME(mtmp), mtmp2->mnamelth);
	initedog(mtmp2);
	replmon(mtmp,mtmp2);
	return(1);
}
Beispiel #2
0
void
makedog()
{
	struct monst *mtmp = makemon(&li_dog,u.ux,u.uy);

	if(!mtmp) return; /* dogs were genocided */
	initedog(mtmp);
}
Beispiel #3
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 #4
0
struct monst *
tamedog(struct monst *mtmp, struct obj *obj)
{
    struct monst *mtmp2;

    /* The Wiz, Medusa and the quest nemeses aren't even made peaceful. */
    if (mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]
        || (mtmp->data->mflags3 & M3_WANTSARTI))
        return NULL;

    /* worst case, at least it'll be peaceful; this uses the main RNG because
       realtime effects means that this won't really sync anyway; this also
       calls set_malign (thus there's no need for the caller to call it after
       calling tamedog()) */
    msethostility(mtmp, FALSE, TRUE);
    if (flags.moonphase == FULL_MOON && night() && rn2(6) && obj &&
        mtmp->data->mlet == S_DOG)
        return NULL;

    /* If we cannot tame it, at least it's no longer afraid. */
    mtmp->mflee = 0;
    mtmp->mfleetim = 0;

    /* make grabber let go now, whether it becomes tame or not */
    if (mtmp == u.ustuck) {
        if (Engulfed)
            expels(mtmp, mtmp->data, TRUE);
        else if (!(Upolyd && sticks(youmonst.data)))
            unstuck(mtmp);
    }

    /* feeding it treats makes it tamer */
    if (mtmp->mtame && obj) {
        int tasty;

        if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating &&
            ((tasty = dogfood(mtmp, obj)) == DOGFOOD ||
             (tasty <= ACCFOOD && CONST_EDOG(mtmp)->hungrytime <= moves))) {
            /* pet will "catch" and eat this thrown food */
            if (canseemon(mtmp)) {
                boolean big_corpse = (obj->otyp == CORPSE &&
                                      obj->corpsenm >= LOW_PM &&
                                      mons[obj->corpsenm].msize >
                                      mtmp->data->msize);
                pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)),
                      !big_corpse ? "." : ", or vice versa!");
            } else if (cansee(mtmp->mx, mtmp->my))
                pline("%s.", Tobjnam(obj, "stop"));
            /* dog_eat expects a floor object */
            place_object(obj, level, mtmp->mx, mtmp->my);
            dog_eat(mtmp, obj, mtmp->mx, mtmp->my, FALSE);
            /* eating might have killed it, but that doesn't matter here; a
               non-null result suppresses "miss" message for thrown food and
               also implies that the object has been deleted */
            return mtmp;
        } else
            return NULL;
    }

    if (mtmp->mtame || !mtmp->mcanmove ||
        /* monsters with conflicting structures cannot be tamed */
        mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion ||
        is_covetous(mtmp->data) || is_human(mtmp->data) ||
        (is_demon(mtmp->data) && !is_demon(youmonst.data)) ||
        (obj && dogfood(mtmp, obj) >= MANFOOD))
        return NULL;

    if (mtmp->m_id == u.quest_status.leader_m_id)
        return NULL;

    /* make a new monster which has the pet extension */
    mtmp2 = newmonst(MX_EDOG, mtmp->mnamelth);
    *mtmp2 = *mtmp;
    mtmp2->mxtyp = MX_EDOG;
    mtmp2->mxlth = sizeof (struct edog);
    if (mtmp->mnamelth)
        strcpy(NAME_MUTABLE(mtmp2), NAME(mtmp));
    initedog(mtmp2);
    replmon(mtmp, mtmp2);
    /* `mtmp' is now obsolete */

    if (obj) {  /* thrown food */
        /* defer eating until the edog extension has been set up */
        place_object(obj, level, mtmp2->mx, mtmp2->my); /* put on floor */
        /* devour the food (might grow into larger, genocided monster) */
        if (dog_eat(mtmp2, obj, mtmp2->mx, mtmp2->my, TRUE) == 2)
            return mtmp2;       /* oops, it died... */
        /* `obj' is now obsolete */
    }

    if (mtmp2->dlevel == level)
        newsym(mtmp2->mx, mtmp2->my);
    if (attacktype(mtmp2->data, AT_WEAP)) {
        mtmp2->weapon_check = NEED_HTH_WEAPON;
        mon_wield_item(mtmp2);
    }
    return mtmp2;
}
Beispiel #5
0
struct monst *
make_familiar(struct obj *otmp, xchar x, xchar y, boolean quietly)
{
    const struct permonst *pm;
    struct monst *mtmp = 0;
    int chance, trycnt = 100;

    do {
        if (otmp) {     /* figurine; otherwise spell */
            int mndx = otmp->corpsenm;

            pm = &mons[mndx];
            /* activating a figurine provides one way to exceed the maximum
               number of the target critter created--unless it has a special
               limit (erinys, Nazgul) */
            if ((mvitals[mndx].mvflags & G_EXTINCT) &&
                mbirth_limit(mndx) != MAXMONNO) {
                if (!quietly)
                    /* have just been given "You <do something with> the
                       figurine and it transforms." message */
                    pline("... into a pile of dust.");
                break;  /* mtmp is null */
            }
        } else if (!rn2(3)) {
            pm = &mons[pet_type(NULL)];
        } else {
            pm = rndmonst(&u.uz, rng_t_create_monster);
            if (!pm) {
                if (!quietly)
                    pline
                        ("There seems to be nothing available for a familiar.");
                break;
            }
        }

        mtmp = makemon(pm, level, x, y, MM_EDOG | MM_IGNOREWATER |
                       (otmp ? 0 : (MM_CREATEMONSTER | MM_CMONSTER_T)));
        if (otmp && !mtmp) {    /* monster was genocided or square occupied */
            if (!quietly)
                pline("The figurine writhes and then shatters into pieces!");
            break;
        }
    } while (!mtmp && --trycnt > 0);

    if (!mtmp)
        return NULL;

    if (is_pool(level, mtmp->mx, mtmp->my) && minliquid(mtmp))
        return NULL;

    initedog(mtmp);
    mtmp->msleeping = 0;
    if (otmp) { /* figurine; resulting monster might not become a pet */
        chance = rn2_on_rng(10, rng_figurine_effect);
        /* 0: tame, 1: peaceful, 2: hostile, 3+: matching BCU; this gives
           an 80% chance of the desired effect, 10% of each other effect */
        if (chance > 2)
            chance = otmp->blessed ? 0 : !otmp->cursed ? 1 : 2;
        if (chance > 0) {
            mtmp->mtame = 0;    /* not tame after all */
            if (chance == 2) {  /* hostile (cursed figurine) */
                if (!quietly)
                    pline("You get a bad feeling about this.");
                msethostility(mtmp, TRUE, TRUE);
            }
        }
        /* if figurine has been named, give same name to the monster */
        if (otmp->onamelth)
            mtmp = christen_monst(mtmp, ONAME(otmp));
    }
    set_malign(mtmp);   /* more alignment changes */
    newsym(mtmp->mx, mtmp->my);

    /* must wield weapon immediately since pets will otherwise drop it */
    if (mtmp->mtame && attacktype(mtmp->data, AT_WEAP)) {
        mtmp->weapon_check = NEED_HTH_WEAPON;
        mon_wield_item(mtmp);
    }
    return mtmp;
}
Beispiel #6
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;
}