Exemplo n.º 1
0
int
rndmonnum(void)	/* select a random, common monster type */
{
    register struct permonst *ptr;
    register int	i;

    /* Plan A: get a level-appropriate common monster */
    ptr = rndmonst();
    if (ptr) return(monsndx(ptr));

    /* Plan B: get any common proper monster */
    int count = 0;
    do {
        i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
        ptr = &mons[i];
        count++;
    } while (((ptr->geno & G_NOGEN) || prohibited_by_generation_flags(ptr)) && count < 10000);

    /* Plan C: get any common monster */
    do {
        i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
        ptr = &mons[i];
        count++;
    } while(ptr->geno & G_NOGEN);

    return(i);
}
Exemplo n.º 2
0
/* select a random, common monster type */
int rndmonnum(const d_level *dlev)
{
	const struct permonst *ptr;
	int i;

	/* Plan A: get a level-appropriate common monster */
	ptr = rndmonst(dlev);
	if (ptr) return monsndx(ptr);

	/* Plan B: get any common monster */
	do {
	    i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
	    ptr = &mons[i];
	} while ((ptr->geno & G_NOGEN) || (!In_hell(dlev) && (ptr->geno & G_HELL)));

	return i;
}
Exemplo n.º 3
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;
}