Beispiel #1
0
void makerogueghost(struct level *lev)
{
	struct monst *ghost;
	struct obj *ghostobj;
	struct mkroom *croom;
	int x,y;

	if (!lev->nroom)
	    return; /* Should never happen */
	croom = &lev->rooms[rn2(lev->nroom)];
	x = somex(croom);
	y = somey(croom);
	
	if (!(ghost = makemon(&mons[PM_GHOST], lev, x, y, NO_MM_FLAGS)))
		return;
	ghost->msleeping = 1;
	christen_monst(ghost, roguename());

	if (rn2(4)) {
		ghostobj = mksobj_at(FOOD_RATION, lev, x, y, FALSE, FALSE);
		ghostobj->quan = (long) rnd(7);
		ghostobj->owt = weight(ghostobj);
	}
	if (rn2(2)) {
		ghostobj = mksobj_at(MACE, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rnd(3);
		if (rn2(4)) curse(ghostobj);
	} else {
		ghostobj = mksobj_at(TWO_HANDED_SWORD, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rnd(5) - 2;
		if (rn2(4)) curse(ghostobj);
	}
	ghostobj = mksobj_at(BOW, lev, x, y, FALSE, FALSE);
	ghostobj->spe = 1;
	if (rn2(4)) curse(ghostobj);

	ghostobj = mksobj_at(ARROW, lev, x, y, FALSE, FALSE);
	ghostobj->spe = 0;
	ghostobj->quan = (long) rn1(10,25);
	ghostobj->owt = weight(ghostobj);
	if (rn2(4)) curse(ghostobj);

	if (rn2(2)) {
		ghostobj = mksobj_at(RING_MAIL, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rn2(3);
		if (!rn2(3)) ghostobj->oerodeproof = TRUE;
		if (rn2(4)) curse(ghostobj);
	} else {
		ghostobj = mksobj_at(PLATE_MAIL, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rnd(5) - 2;
		if (!rn2(3)) ghostobj->oerodeproof = TRUE;
		if (rn2(4)) curse(ghostobj);
	}
	if (rn2(2)) {
		ghostobj = mksobj_at(FAKE_AMULET_OF_YENDOR, lev, x, y, TRUE, FALSE);
		ghostobj->known = TRUE;
	}
}
Beispiel #2
0
int
do_mname(const struct nh_cmd_arg *arg)
{
    coord cc;
    int cx, cy;
    struct monst *mtmp;
    const char *qbuf, *buf;

    if (Hallucination) {
        pline(msgc_cancelled, "You would never recognize it anyway.");
        return 0;
    }
    cc.x = youmonst.mx;
    cc.y = youmonst.my;
    if (getargpos(arg, &cc, FALSE, "the monster you want to name") ==
        NHCR_CLIENT_CANCEL || (cx = cc.x) < 0)
        return 0;
    cy = cc.y;

    if (cx == youmonst.mx && cy == youmonst.my) {
        if (u.usteed && canspotmon(u.usteed))
            mtmp = u.usteed;
        else {
            pline(msgc_cancelled,
                  "This %s creature is called %s and cannot be renamed.",
                  beautiful(), u.uplname);
            return 0;
        }
    } else
        mtmp = vismon_at(level, cx, cy);

    unsigned msense_status = mtmp ? msensem(&youmonst, mtmp) : 0;

    if (!(msense_status & ~MSENSE_ITEMMIMIC)) {
        pline(msgc_mispaste, "I see no monster there.");
        return 0;
    } else if (!(msense_status & (MSENSE_ANYDETECT | MSENSE_ANYVISION))) {
        pline(msgc_cancelled,
              "You can't see it well enough to recognise it in the future.");
        return 0;
    }

    /* special case similar to the one in lookat() */
    qbuf = distant_monnam(mtmp, NULL, ARTICLE_THE);
    qbuf = msgprintf("What do you want to call %s?", qbuf);
    buf = getarglin(arg, qbuf);
    if (!*buf || *buf == '\033')
        return 0;
    /* strip leading and trailing spaces; unnames monster if all spaces */
    buf = msgmungspaces(buf);

    if (mtmp->data->geno & G_UNIQ) {
        qbuf = msgupcasefirst(distant_monnam(mtmp, NULL, ARTICLE_THE));
        pline(msgc_cancelled, "%s doesn't like being called names!", qbuf);
    } else
        christen_monst(mtmp, buf);
    return 0;
}
Beispiel #3
0
int do_mname(void)
{
	char buf[BUFSZ];
	coord cc;
	int cx,cy;
	struct monst *mtmp;
	char qbuf[QBUFSZ];

	if (Hallucination) {
		pline("You would never recognize it anyway.");
		return 0;
	}
	cc.x = u.ux;
	cc.y = u.uy;
	if (getpos(&cc, FALSE, "the monster you want to name") < 0 ||
			(cx = cc.x) < 0)
		return 0;
	cy = cc.y;

	if (cx == u.ux && cy == u.uy) {
	    if (u.usteed && canspotmon(u.usteed))
		mtmp = u.usteed;
	    else {
		pline("This %s creature is called %s and cannot be renamed.",
		ACURR(A_CHA) > 14 ?
		(flags.female ? "beautiful" : "handsome") :
		"ugly",
		plname);
		return 0;
	    }
	} else
	    mtmp = m_at(level, cx, cy);

	if (!mtmp || (!sensemon(mtmp) &&
			(!(cansee(cx,cy) || see_with_infrared(mtmp)) || mtmp->mundetected
			|| mtmp->m_ap_type == M_AP_FURNITURE
			|| mtmp->m_ap_type == M_AP_OBJECT
			|| (mtmp->minvis && !See_invisible)))) {
		pline("I see no monster there.");
		return 0;
	}
	/* special case similar to the one in lookat() */
	distant_monnam(mtmp, ARTICLE_THE, buf);
	sprintf(qbuf, "What do you want to call %s?", buf);
	getlin(qbuf,buf);
	if (!*buf || *buf == '\033') return 0;
	/* strip leading and trailing spaces; unnames monster if all spaces */
	mungspaces(buf);

	if (mtmp->data->geno & G_UNIQ) {
	    distant_monnam(mtmp, ARTICLE_THE, buf);
	    *buf = highc(*buf);
	    pline("%s doesn't like being called names!", buf);
	} else
	    christen_monst(mtmp, buf);
	return 0;
}
Beispiel #4
0
/* Assign a name to a monster, taken from a list of possible names.
   Note that shopkeepers are special and use nameshk instead, partly
   because it contains additional logic peculiar to them and also
   because their name is stored in ESHK because of reasons. */
static void
namemonsterfromlist(struct monst *mon, const char *const *nlist,
                    struct level *lev, boolean unique)
{
    int names_avail, tryct;
    const char *ourname;
    struct monst *mtmp;
    if (!mon) {
        if (wizard)
            impossible("Cannot name a non-existent monster.");
        return;
    }
    if (!nlist[0]) {
        if (wizard)
            impossible("No names available for the %s.", mon_nam(mon));
        return;
    }
    for (names_avail = 0; nlist[names_avail]; names_avail++)
        ;
    for (tryct = 0; tryct < 500; tryct++) {
        ourname = nlist[rn2(names_avail)];
        if (!unique) {
            christen_monst(mon, ourname);
            return;
        }
        for (mtmp = lev->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp) || (mtmp == mon) ||
                !(mtmp->data->mlet == mon->data->mlet))
                continue;
            if (strcmp(NAME_MUTABLE(mtmp), ourname) != 0)
                continue;
            break;
        }
        if (!mtmp) {
            christen_monst(mon, ourname);
            return;
        } 
    }
    /* We're not going to name this monster. */
    if (wizard)
        pline("Failed to find %s name for the %s.",
              (unique ? "an unused" : "a"), mon_nam(mon));
}
Beispiel #5
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 #6
0
/* extract a shopkeeper name for the given shop type */
static void
nameshk(struct monst *shk, const char *const *nlp, struct level *lev)
{
    int i, trycnt, names_avail;
    const char *shname = 0;
    struct monst *mtmp;
    int name_wanted;
    s_level *sptr;

    if (nlp == shklight && In_mines(&lev->z)
        && (sptr = Is_special(&lev->z)) != 0 && sptr->flags.town) {
        /* special-case minetown lighting shk */
        shname = "Izchak";
        shk->female = FALSE;
    } else {
        /* We want variation from game to game, without needing the save and
           restore support which would be necessary for randomization; thus use
           ubirthday for deterministic random numbers, and use ledger_no rather
           than depth to keep mine town distinct. */
        int nseed = ((unsigned)u.ubirthday / 257U);

        name_wanted = ledger_no(&lev->z) + (nseed % 13) - (nseed % 5);
        if (name_wanted < 0)
            name_wanted += (13 + 5);
        shk->female = name_wanted & 1;

        for (names_avail = 0; nlp[names_avail]; names_avail++)
            continue;

        for (trycnt = 0; trycnt < 50; trycnt++) {
            if (nlp == shktools) {
                shname = shktools[rn2(names_avail)];
                shk->female = (*shname == '_');
                if (shk->female)
                    shname++;
            } else if (name_wanted < names_avail) {
                shname = nlp[name_wanted];
            } else if ((i = rn2(names_avail)) != 0) {
                shname = nlp[i - 1];
            } else if (nlp != shkgeneral) {
                nlp = shkgeneral;       /* try general names */
                for (names_avail = 0; nlp[names_avail]; names_avail++)
                    continue;
                continue;       /* next `trycnt' iteration */
            } else {
                shname = shk->female ? "Lucrezia" : "Dirk";
            }

            /* is name already in use on this level? */
            for (mtmp = lev->monlist; mtmp; mtmp = mtmp->nmon) {
                if (DEADMONSTER(mtmp) || (mtmp == shk) || !mx_eshk(mtmp))
                    continue;
                if (mx_name(mtmp) && strcmp(mx_name(mtmp), shname))
                    continue;
                break;
            }
            if (!mtmp)
                break;  /* new name */
        }
    }
    christen_monst(shk, shname);
}
Beispiel #7
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 #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;
}