Ejemplo n.º 1
0
static struct permonst *
morguemon (void)
{
        int i = rn2(100), hd = rn2(level_difficulty());

        if(hd > 10 && i < 10)
                return((Inhell || In_endgame(&u.uz)) ? mkclass(S_DEMON,0) :
                                                       &mons[ndemon(A_NONE)]);
        if(hd > 8 && i > 85)
                return(mkclass(S_VAMPIRE,0));

        return((i < 20) ? &mons[PM_GHOST]
                        : (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE,0));
}
Ejemplo n.º 2
0
struct permonst * qt_montype (void) {
    int qpm;

    if (rn2(5)) {
        qpm = urole.enemy1num;
        if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GENOD))
            return (&mons[qpm]);
        return (mkclass(urole.enemy1sym, 0));
    }
    qpm = urole.enemy2num;
    if (qpm != NON_PM && rn2(5) && !(mvitals[qpm].mvflags & G_GENOD))
        return (&mons[qpm]);
    return (mkclass(urole.enemy2sym, 0));
}
Ejemplo n.º 3
0
static const struct permonst *
morguemon(const d_level * dlev)
{
    int i = rn2(100), hd = rn2(level_difficulty(dlev));

    if (hd > 10 && i < 10)
        return (In_hell(dlev) ||
                In_endgame(dlev)) ? mkclass(dlev, S_DEMON,
                                            0) : &mons[ndemon(dlev, A_NONE)];
    if (hd > 8 && i > 85)
        return mkclass(dlev, S_VAMPIRE, 0);

    return (i < 20) ? &mons[PM_GHOST]
        : (i < 40) ? &mons[PM_WRAITH] : mkclass(dlev, S_ZOMBIE, 0);
}
Ejemplo n.º 4
0
/* Note: this now only returns a suggestion; it no longer takes genocide into
   account, so that the caller can handle the RNG implications */
const struct permonst *
qt_montype(const d_level *dlev, enum rng rng)
{
    int qpm;

    if (rn2_on_rng(5, rng)) {
        qpm = urole.enemy1num;
        if (qpm != NON_PM && rn2_on_rng(5, rng))
            return &mons[qpm];
        return mkclass(dlev, urole.enemy1sym, 0, rng);
    }
    qpm = urole.enemy2num;
    if (qpm != NON_PM && rn2_on_rng(5, rng))
        return &mons[qpm];
    return mkclass(dlev, urole.enemy2sym, 0, rng);
}
Ejemplo n.º 5
0
static void
mkswamp(struct level *lev)
{
    struct mkroom *sroom;
    int sx, sy, i, eelct = 0;

    for (i = 0; i < 5; i++) {   /* turn up to 5 rooms swampy */
        sroom = &lev->rooms[rn2(lev->nroom)];
        if (sroom->hx < 0 || sroom->rtype != OROOM || has_upstairs(lev, sroom)
            || has_dnstairs(lev, sroom))
            continue;

        /* satisfied; make a swamp */
        sroom->rtype = SWAMP;
        for (sx = sroom->lx; sx <= sroom->hx; sx++)
            for (sy = sroom->ly; sy <= sroom->hy; sy++)
                if (!OBJ_AT_LEV(lev, sx, sy) && !MON_AT(lev, sx, sy) &&
                    !t_at(lev, sx, sy) && !nexttodoor(lev, sx, sy)) {
                    if ((sx + sy) % 2) {
                        lev->locations[sx][sy].typ = POOL;
                        if (!eelct || !rn2(4)) {
                            /* mkclass() won't do, as we might get kraken */
                            makemon(rn2(5) ? &mons[PM_GIANT_EEL]
                                    : rn2(2) ? &mons[PM_PIRANHA]
                                    : &mons[PM_ELECTRIC_EEL], lev, sx, sy,
                                    NO_MM_FLAGS);
                            eelct++;
                        }
                    } else if (!rn2(4)) /* swamps tend to be moldy */
                        makemon(mkclass(&lev->z, S_FUNGUS, 0), lev, sx, sy,
                                NO_MM_FLAGS);
                }
        lev->flags.has_swamp = 1;
    }
}
Ejemplo n.º 6
0
static const struct permonst *
morguemon(const d_level *dlev, enum rng rng)
{
    int i = rn2_on_rng(100, rng);
    int hd = rn2_on_rng(level_difficulty(dlev), rng);

    if (hd > 10 && i < 10) {
        if (In_hell(dlev) || In_endgame(dlev))
            return mkclass(dlev, S_DEMON, 0, rng);
        else {
            int mnum = ndemon(dlev, A_NONE);
            if (mnum != NON_PM)
                return &mons[mnum];
            /* otherwise fall through */
        }
    } else if (hd > 8 && i > 85)
        return mkclass(dlev, S_VAMPIRE, 0, rng);

    return (i < 20) ? &mons[PM_GHOST] :
        (i < 40) ? &mons[PM_WRAITH] : mkclass(dlev, S_ZOMBIE, 0, rng);
}
Ejemplo n.º 7
0
int
lminion(void)
{
    int tryct;
    const struct permonst *ptr;

    for (tryct = 0; tryct < 20; tryct++) {
        ptr = mkclass(&u.uz, S_ANGEL, 0);
        if (ptr && !is_lord(ptr))
            return monsndx(ptr);
    }

    return NON_PM;
}
Ejemplo n.º 8
0
int
ndemon(const d_level * dlev, aligntyp atyp)
{
    int tryct;
    const struct permonst *ptr;

    for (tryct = 0; tryct < 20; tryct++) {
        ptr = mkclass(dlev, S_DEMON, 0);
        if (ptr && is_ndemon(ptr) &&
            (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp)))
            return monsndx(ptr);
    }

    return NON_PM;
}
Ejemplo n.º 9
0
struct permonst *
courtmon (void)
{
        int     i = rn2(60) + rn2(3*level_difficulty());
        if (i > 100)            return(mkclass(S_DRAGON,0));
        else if (i > 95)        return(mkclass(S_GIANT,0));
        else if (i > 85)        return(mkclass(S_TROLL,0));
        else if (i > 75)        return(mkclass(S_CENTAUR,0));
        else if (i > 60)        return(mkclass(S_ORC,0));
        else if (i > 45)        return(&mons[PM_BUGBEAR]);
        else if (i > 30)        return(&mons[PM_HOBGOBLIN]);
        else if (i > 15)        return(mkclass(S_GNOME,0));
        else                    return(mkclass(S_KOBOLD,0));
}
Ejemplo n.º 10
0
/* make an object of the appropriate type for a shop square */
static void mkshobj_at ( const struct shclass *shp, int sx, int sy) {
    struct monst *mtmp;
    int atype;
    struct permonst *ptr;

    if (rn2(100) < depth(&u.uz) &&
            !MON_AT(sx, sy) && (ptr = mkclass(S_MIMIC,0)) &&
            (mtmp = makemon(ptr,sx,sy,NO_MM_FLAGS)) != 0) {
        /* note: makemon will set the mimic symbol to a shop item */
        if (rn2(10) >= depth(&u.uz)) {
            mtmp->m_ap_type = M_AP_OBJECT;
            mtmp->mappearance = STRANGE_OBJECT;
        }
    } else {
        atype = get_shop_item(shp - shtypes);
        if (atype < 0)
            (void) mksobj_at(-atype, sx, sy, true, true);
        else
            (void) mkobj_at(atype, sx, sy, true);
    }
}
Ejemplo n.º 11
0
/* Make an object of the appropriate type for a shop square.

   Uses the level generation RNG. */
static void
mkshobj_at(const struct shclass *shp, struct level *lev, int sx, int sy)
{
    struct monst *mtmp;
    int atype;
    const struct permonst *ptr;
    enum rng rng = rng_for_level(&lev->z);

    if (rn2_on_rng(100, rng) < depth(&lev->z) && !MON_AT(lev, sx, sy) &&
        (ptr = mkclass(&lev->z, S_MIMIC, 0, rng)) &&
        (mtmp = makemon(ptr, lev, sx, sy, MM_ALLLEVRNG)) != 0) {
        /* note: makemon will set the mimic symbol to a shop item */
        if (rn2_on_rng(10, rng) >= depth(&lev->z)) {
            mtmp->m_ap_type = M_AP_OBJECT;
            mtmp->mappearance = STRANGE_OBJECT;
        }
    } else {
        atype = get_shop_item(shp - shtypes, rng);
        if (atype < 0)
            mksobj_at(-atype, lev, sx, sy, TRUE, TRUE, rng);
        else
            mkobj_at(atype, lev, sx, sy, TRUE, rng);
    }
}
Ejemplo n.º 12
0
const struct permonst *
courtmon(const d_level *dlev, enum rng rng)
{
    int i = rn2_on_rng(60, rng) + rn2_on_rng(3 * level_difficulty(dlev), rng);

    if (i > 100)
        return mkclass(dlev, S_DRAGON, 0, rng);
    else if (i > 95)
        return mkclass(dlev, S_GIANT, 0, rng);
    else if (i > 85)
        return mkclass(dlev, S_TROLL, 0, rng);
    else if (i > 75)
        return mkclass(dlev, S_CENTAUR, 0, rng);
    else if (i > 60)
        return mkclass(dlev, S_ORC, 0, rng);
    else if (i > 45)
        return &mons[PM_BUGBEAR];
    else if (i > 30)
        return &mons[PM_HOBGOBLIN];
    else if (i > 15)
        return mkclass(dlev, S_GNOME, 0, rng);
    else
        return mkclass(dlev, S_KOBOLD, 0, rng);
}
Ejemplo n.º 13
0
/* Record the breaking of a roleplay-conduct. */
void violated(int cdt)
{
	switch (cdt) {
	case CONDUCT_PACIFISM:
	    u.uconduct.killer++;
	    if (u.roleplay.pacifist) {
		pline("你感到狂暴!");
		if (yn("你确定要退出吗?") == 'y') {
		    killer_format = NO_KILLER_PREFIX;
		    killer = "在一阵狂暴之后退出";
		    done(QUIT);
		}
		if (u.uconduct.killer >= 10) u.roleplay.pacifist = FALSE;
	    }
	    break;

	case CONDUCT_NUDISM:
	    u.uconduct.armoruses++;
	    if (u.roleplay.nudist) {
		pline("你意识到你光着身子。");
		makemon(&mons[PM_COBRA], level, u.ux, u.uy, NO_MM_FLAGS);
		mksobj_at(APPLE, level, u.ux, u.uy, FALSE, FALSE);
		u.roleplay.nudist = FALSE;
	    }
	    break;

	case CONDUCT_BLINDFOLDED:
	    u.uconduct.unblinded++;
	    if (u.roleplay.blindfolded) {
		pline("禅之精神,离开你的身体。");
		makemon(mkclass(&level->z, S_ZOMBIE, 0),
			level, u.ux, u.uy, NO_MM_FLAGS);	/* Z */
		makemon(mkclass(&level->z, S_EYE, 0),
			level, u.ux, u.uy, NO_MM_FLAGS);	/* e */
		makemon(mkclass(&level->z, S_NYMPH, 0),
			level, u.ux, u.uy, NO_MM_FLAGS);	/* n */
		u.roleplay.blindfolded = FALSE;
	    }
	    break;

	case CONDUCT_VEGETARIAN:	/* replaces violated_vegetarian() */
	    if (u.roleplay.vegetarian)
		pline("你感到内疚。");
	    if (Role_if(PM_MONK))
		adjalign(-1);
	    u.uconduct.unvegetarian++;
	    u.uconduct.unvegan++;
	    u.uconduct.food++;
	    if (u.uconduct.unvegetarian >= 30) u.roleplay.vegetarian = FALSE;
	    if (u.uconduct.unvegan >= 20) u.roleplay.vegan = FALSE;
	    if (u.uconduct.food >= 10) u.roleplay.ascet = FALSE;
	    break;

	case CONDUCT_VEGAN:
	    if (u.roleplay.vegan)
		pline("你感到有点内疚。");
	    u.uconduct.unvegan++;
	    u.uconduct.food++;
	    if (u.uconduct.unvegan >= 20) u.roleplay.vegan = FALSE;
	    if (u.uconduct.food >= 10) u.roleplay.ascet = FALSE;
	    break;

	case CONDUCT_FOODLESS:
	    if (u.roleplay.ascet)
		pline("你略微感到内疚。");
	    u.uconduct.food++;
	    if (u.uconduct.food >= 10) u.roleplay.ascet = FALSE;
	    break;

	case CONDUCT_ILLITERACY:
	    u.uconduct.literate++;
	    if (u.roleplay.illiterate) {
		/* should be impossible */
		pline("Literatally literature for literate illiterates!");
		exercise(A_WIS, TRUE);
	    }
	    break;

	case CONDUCT_THIEVERY:
	    u.uconduct.robbed++;
	    if (Role_if(PM_ROGUE))
		pline("你感觉自己像一个强盗。");
	    break;

	default:
	    impossible("violated: unknown conduct");
	}
}
Ejemplo n.º 14
0
static void cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
{
    if (dmg == 0 && !is_undirected_spell(AD_CLRC, spellnum)) {
	impossible("cast directed cleric spell (%d) with dmg=0?", spellnum);
	return;
    }

    switch (spellnum) {
    case CLC_GEYSER:
	/* this is physical damage, not magical damage */
	pline("A sudden geyser slams into you from nowhere!");
	dmg = dice(8, 6);
	if (Half_physical_damage) dmg = (dmg + 1) / 2;
	break;
    case CLC_FIRE_PILLAR:
	pline("A pillar of fire strikes all around you!");
	if (Fire_resistance) {
	    shieldeff(u.ux, u.uy);
	    dmg = 0;
	} else
	    dmg = dice(8, 6);
	if (Half_spell_damage) dmg = (dmg + 1) / 2;
	burn_away_slime();
	burnarmor(&youmonst);
	destroy_item(SCROLL_CLASS, AD_FIRE);
	destroy_item(POTION_CLASS, AD_FIRE);
	destroy_item(SPBOOK_CLASS, AD_FIRE);
	burn_floor_paper(u.ux, u.uy, TRUE, FALSE);
	break;
    case CLC_LIGHTNING:
    {
	boolean reflects;

	pline("A bolt of lightning strikes down at you from above!");
	reflects = ureflects("It bounces off your %s%s.", "");
	if (reflects || Shock_resistance) {
	    shieldeff(u.ux, u.uy);
	    dmg = 0;
	    if (reflects)
		break;
	} else
	    dmg = dice(8, 6);
	if (Half_spell_damage) dmg = (dmg + 1) / 2;
	destroy_item(WAND_CLASS, AD_ELEC);
	destroy_item(RING_CLASS, AD_ELEC);
	break;
    }
    case CLC_CURSE_ITEMS:
	pline("You feel as if you need some help.");
	rndcurse();
	dmg = 0;
	break;
    case CLC_INSECTS:
      {
	/* Try for insects, and if there are none
	   left, go for (sticks to) snakes.  -3. */
	const struct permonst *pm = mkclass(&u.uz, S_ANT,0);
	struct monst *mtmp2 = NULL;
	char let = (pm ? S_ANT : S_SNAKE);
	boolean success;
	int i;
	coord bypos;
	int quan;

	quan = (mtmp->m_lev < 2) ? 1 : rnd((int)mtmp->m_lev / 2);
	if (quan < 3) quan = 3;
	success = pm ? TRUE : FALSE;
	for (i = 0; i <= quan; i++) {
	    if (!enexto(&bypos, level, mtmp->mux, mtmp->muy, mtmp->data))
		break;
	    if ((pm = mkclass(&u.uz, let,0)) != 0 &&
		    (mtmp2 = makemon(pm, level, bypos.x, bypos.y, NO_MM_FLAGS)) != 0) {
		success = TRUE;
		mtmp2->msleeping = mtmp2->mpeaceful = mtmp2->mtame = 0;
		set_malign(mtmp2);
	    }
	}
	/* Not quite right:
         * -- message doesn't always make sense for unseen caster (particularly
	 *    the first message)
         * -- message assumes plural monsters summoned (non-plural should be
         *    very rare, unlike in nasty())
         * -- message assumes plural monsters seen
         */
	if (!success)
	    pline("%s casts at a clump of sticks, but nothing happens.",
		Monnam(mtmp));
	else if (let == S_SNAKE)
	    pline("%s transforms a clump of sticks into snakes!",
		Monnam(mtmp));
	else if (Invisible && !perceives(mtmp->data) &&
				(mtmp->mux != u.ux || mtmp->muy != u.uy))
	    pline("%s summons insects around a spot near you!",
		Monnam(mtmp));
	else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy))
	    pline("%s summons insects around your displaced image!",
		Monnam(mtmp));
	else
	    pline("%s summons insects!", Monnam(mtmp));
	dmg = 0;
	break;
      }
    case CLC_BLIND_YOU:
	/* note: resists_blnd() doesn't apply here */
	if (!Blinded) {
	    int num_eyes = eyecount(youmonst.data);
	    pline("Scales cover your %s!",
		  (num_eyes == 1) ?
		  body_part(EYE) : makeplural(body_part(EYE)));
	    make_blinded(Half_spell_damage ? 100L : 200L, FALSE);
	    if (!Blind) pline("Your vision quickly clears.");
	    dmg = 0;
	} else
	    impossible("no reason for monster to cast blindness spell?");
	break;
    case CLC_PARALYZE:
	if (Antimagic || Free_action) {
	    shieldeff(u.ux, u.uy);
	    if (multi >= 0)
		pline("You stiffen briefly.");
	    nomul(-1, "paralyzed by a monster");
	} else {
	    if (multi >= 0)
		pline("You are frozen in place!");
	    dmg = 4 + (int)mtmp->m_lev;
	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
	    nomul(-dmg, "paralyzed by a monster");
	}
	dmg = 0;
	break;
    case CLC_CONFUSE_YOU:
	if (Antimagic) {
	    shieldeff(u.ux, u.uy);
	    pline("You feel momentarily dizzy.");
	} else {
	    boolean oldprop = !!Confusion;

	    dmg = (int)mtmp->m_lev;
	    if (Half_spell_damage) dmg = (dmg + 1) / 2;
	    make_confused(HConfusion + dmg, TRUE);
	    if (Hallucination)
		pline("You feel %s!", oldprop ? "trippier" : "trippy");
	    else
		pline("You feel %sconfused!", oldprop ? "more " : "");
	}
	dmg = 0;
	break;
    case CLC_CURE_SELF:
	if (mtmp->mhp < mtmp->mhpmax) {
	    if (canseemon(mtmp))
		pline("%s looks better.", Monnam(mtmp));
	    /* note: player healing does 6d4; this used to do 1d8 */
	    if ((mtmp->mhp += dice(3,6)) > mtmp->mhpmax)
		mtmp->mhp = mtmp->mhpmax;
	    dmg = 0;
	}
	break;
    case CLC_OPEN_WOUNDS:
	if (Antimagic) {
	    shieldeff(u.ux, u.uy);
	    dmg = (dmg + 1) / 2;
	}
	if (dmg <= 5)
	    pline("Your skin itches badly for a moment.");
	else if (dmg <= 10)
	    pline("Wounds appear on your body!");
	else if (dmg <= 20)
	    pline("Severe wounds appear on your body!");
	else
	    pline("Your body is covered with painful wounds!");
	break;
    default:
	impossible("mcastu: invalid clerical spell (%d)", spellnum);
	dmg = 0;
	break;
    }

    if (dmg) mdamageu(mtmp, dmg);
}