Пример #1
0
void mkzoo(int type)
{
    struct mkroom *sroom;
    struct monst *mon;
    int sh, sx, sy, i;
    int goldlim = 500 * dlevel;
    int moct = 0;

    i = nroom;
    for (sroom = &rooms[rn2(nroom)];; sroom++) {
	if (sroom == &rooms[nroom])
	    sroom = &rooms[0];
	if (!i-- || sroom->hx < 0)
	    return;
	if (sroom->rtype)
	    continue;
	if (type == MORGUE && sroom->rlit)
	    continue;
	if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
	    continue;
	if (sroom->doorct == 1 || !rn2(5))
	    break;
    }
    sroom->rtype = type;
    sh = sroom->fdoor;
    for (sx = sroom->lx; sx <= sroom->hx; sx++)
	for (sy = sroom->ly; sy <= sroom->hy; sy++) {
	    if ((sx == sroom->lx && doors[sh].x == sx - 1) || (sx == sroom->hx && doors[sh].x == sx + 1) || (sy == sroom->ly && doors[sh].y == sy - 1) || (sy == sroom->hy && doors[sh].y == sy + 1))
		continue;
	    mon = makemon((type == MORGUE) ? morguemon() : (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0, sx, sy);
	    if (mon)
		mon->msleep = 1;
	    switch (type) {
		case ZOO:
		    i = sq(dist2(sx, sy, doors[sh].x, doors[sh].y));
		    if (i >= goldlim)
			i = 5 * dlevel;
		    goldlim -= i;
		    mkgold((long) (10 + rn2(i)), sx, sy);
		    break;
		case MORGUE:
		    // Usually there is one dead body in the morgue
		    if (!moct && rn2(3)) {
			mksobj_at(CORPSE, sx, sy);
			moct++;
		    }
		    break;
		case BEEHIVE:
		    if (!rn2(3))
			mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
		    break;
	    }
	}
}
Пример #2
0
/* drop a rock and remove monster */
static void
monstone(struct monst *mdef)
{
	if (strchr(mlarge, mdef->data->mlet))
		mksobj_at(ENORMOUS_ROCK, mdef->mx, mdef->my);
	else
		mksobj_at(ROCK, mdef->mx, mdef->my);
	if (cansee(mdef->mx, mdef->my)) {
		unpmon(mdef);
		atl(mdef->mx, mdef->my, fobj->olet);
	}
	mondead(mdef);
}
Пример #3
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;
	}
}
Пример #4
0
void
rnd_treesticks_at(int x, int y)
{
    int num = rnd(3);
    while(num--)
        mksobj_at(rn2(2) ? QUARTERSTAFF : CLUB, x, y, TRUE, FALSE);
}
Пример #5
0
/* make an object named after someone listed in the scoreboard file */
struct obj *mk_tt_object(struct level *lev,
			 int objtype, /* CORPSE or STATUE */
			 int x, int y)
{
	struct obj *otmp, *otmp2;
	boolean initialize_it;

	/* player statues never contain books */
	initialize_it = (objtype != STATUE);
	if ((otmp = mksobj_at(objtype, lev, x, y, initialize_it, FALSE)) != 0) {
	    /* tt_oname will return null if the scoreboard is empty */
	    if ((otmp2 = tt_oname(otmp)) != 0) otmp = otmp2;
	}
	return otmp;
}
Пример #6
0
struct obj *mkgold(long amount, struct level *lev, int x, int y)
{
    struct obj *gold = gold_at(lev, x, y);

    if (amount <= 0L)
	amount = (long)(1 + rnd(level_difficulty(&lev->z)+2) * rnd(30));
    if (gold) {
	gold->quan += amount;
    } else {
	gold = mksobj_at(GOLD_PIECE, lev, x, y, TRUE, FALSE);
	gold->quan = amount;
    }
    gold->owt = weight(gold);
    return gold;
}
Пример #7
0
struct obj *
mkgold(long int amount, int x, int y)
{
    register struct obj *gold = g_at(x,y);

    if (amount <= 0L)
        amount = (long)(1 + rnd(level_difficulty()+2) * rnd(30));
    if (gold) {
        gold->quan += amount;
    } else {
        gold = mksobj_at(GOLD_PIECE, x, y, TRUE, FALSE);
        gold->quan = amount;
    }
    gold->owt = weight(gold);
    return (gold);
}
Пример #8
0
static void
makeniche(bool with_trap)
{
	struct mkroom *aroom;
	struct rm *rm;
	int vct = 8;
	coord dd;
	int dy,xx,yy;
	struct trap *ttmp;

	if(doorindex < DOORMAX)
	  while(vct--) {
	    aroom = &rooms[rn2(nroom-1)];
	    if(aroom->rtype != 0) continue;	/* not an ordinary room */
	    if(aroom->doorct == 1 && rn2(5)) continue;
	    if(rn2(2)) {
		dy = 1;
		dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1);
	    } else {
		dy = -1;
		dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1);
	    }
	    xx = dd.x;
	    yy = dd.y;
	    if((rm = &levl[xx][yy+dy])->typ) continue;
	    if(with_trap || !rn2(4)) {
		rm->typ = SCORR;
		rm->scrsym = ' ';
		if(with_trap) {
		    ttmp = maketrap(xx, yy+dy, TELEP_TRAP);
		    ttmp->once = 1;
		    make_engr_at(xx, yy-dy, "ad ae?ar um");
		}
		dosdoor(xx, yy, aroom, SDOOR);
	    } else {
		rm->typ = CORR;
		rm->scrsym = CORR_SYM;
		if(rn2(7))
		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
		else {
		    mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
		    if(!rn2(3)) mkobj_at(0, xx, yy+dy);
		}
	    }
	    return;
	}
}
Пример #9
0
/*
 * OEXTRA note: Passing mtmp causes mtraits to be saved
 * even if ptr passed as well, but ptr is always used for
 * the corpse type (corpsenm). That allows the corpse type
 * to be different from the original monster,
 *	i.e.  vampire -> human corpse
 * yet still allow restoration of the original monster upon
 * resurrection.
 */
struct obj *
mkcorpstat(int objtype, struct monst *mtmp, struct permonst *ptr, int x, int y, boolean init)
            	/* CORPSE or STATUE */
                   
                     
         
             
{
    register struct obj *otmp;

    if (objtype != CORPSE && objtype != STATUE)
        warning("making corpstat type %d", objtype);
    if (x == 0 && y == 0) {		/* special case - random placement */
        otmp = mksobj(objtype, init, FALSE);
        if (otmp) rloco(otmp);
    } else
        otmp = mksobj_at(objtype, x, y, init, FALSE);
    if (otmp) {
        if (mtmp) {
            struct obj *otmp2;

            if (!ptr) ptr = mtmp->data;
            /* save_mtraits frees original data pointed to by otmp */
            otmp2 = save_mtraits(otmp, mtmp);
            if (otmp2) otmp = otmp2;
        }
        /* use the corpse or statue produced by mksobj() as-is
           unless `ptr' is non-null */
        if (ptr) {
            int old_corpsenm = otmp->corpsenm;

            otmp->corpsenm = monsndx(ptr);
            otmp->owt = weight(otmp);
            if (otmp->otyp == CORPSE &&
                    (special_corpse(old_corpsenm) ||
                     special_corpse(otmp->corpsenm))) {
                obj_stop_timers(otmp);
                start_corpse_timeout(otmp);
            }
        }
    }
    return(otmp);
}
Пример #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);
    }
}
Пример #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);
    }
}
Пример #12
0
void
fill_zoo (struct mkroom *sroom)
{
        struct monst *mon;
        int sx,sy,i;
        int sh, tx, ty, goldlim, type = sroom->rtype;
        int rmno = (sroom - rooms) + ROOMOFFSET;
        coord mm;


        sh = sroom->fdoor;
        switch(type) {
            case COURT:
                if(level.flags.is_maze_lev) {
                    for(tx = sroom->lx; tx <= sroom->hx; tx++)
                        for(ty = sroom->ly; ty <= sroom->hy; ty++)
                            if(IS_THRONE(levl[tx][ty].typ))
                                goto throne_placed;
                }
                i = 100;
                do {    /* don't place throne on top of stairs */
                        (void) somexy(sroom, &mm);
                        tx = mm.x; ty = mm.y;
                } while (occupied((signed char)tx, (signed char)ty) && --i > 0);
            throne_placed:
                /* TODO: try to ensure the enthroned monster is an M2_PRINCE */
                break;
            case BEEHIVE:
                tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
                ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
                if(sroom->irregular) {
                    /* center might not be valid, so put queen elsewhere */
                    if ((int) levl[tx][ty].roomno != rmno ||
                            levl[tx][ty].edge) {
                        (void) somexy(sroom, &mm);
                        tx = mm.x; ty = mm.y;
                    }
                }
                break;
            case ZOO:
            case LEPREHALL:
                goldlim = 500 * level_difficulty();
                break;
        }
        for(sx = sroom->lx; sx <= sroom->hx; sx++)
            for(sy = sroom->ly; sy <= sroom->hy; sy++) {
                if(sroom->irregular) {
                    if ((int) levl[sx][sy].roomno != rmno ||
                          levl[sx][sy].edge ||
                          (sroom->doorct &&
                           distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1))
                        continue;
                } else if(!SPACE_POS(levl[sx][sy].typ) ||
                          (sroom->doorct &&
                           ((sx == sroom->lx && doors[sh].x == sx-1) ||
                            (sx == sroom->hx && doors[sh].x == sx+1) ||
                            (sy == sroom->ly && doors[sh].y == sy-1) ||
                            (sy == sroom->hy && doors[sh].y == sy+1))))
                    continue;
                /* don't place monster on explicitly placed throne */
                if(type == COURT && IS_THRONE(levl[sx][sy].typ))
                    continue;
                mon = makemon(
                    (type == COURT) ? courtmon() :
                    (type == BARRACKS) ? squadmon() :
                    (type == MORGUE) ? morguemon() :
                    (type == BEEHIVE) ?
                        (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] :
                         &mons[PM_KILLER_BEE]) :
                    (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] :
                    (type == COCKNEST) ? &mons[PM_COCKATRICE] :
                    (type == ANTHOLE) ? antholemon() :
                    (struct permonst *) 0,
                   sx, sy, NO_MM_FLAGS);
                if(mon) {
                        mon->msleeping = 1;
                        if (type==COURT && mon->mpeaceful) {
                                mon->mpeaceful = 0;
                                set_malign(mon);
                        }
                }
                switch(type) {
                    case ZOO:
                    case LEPREHALL:
                        if(sroom->doorct)
                        {
                            int distval = dist2(sx,sy,doors[sh].x,doors[sh].y);
                            i = sq(distval);
                        }
                        else
                            i = goldlim;
                        if(i >= goldlim) i = 5*level_difficulty();
                        goldlim -= i;
                        (void) mkgold((long) rn1(i, 10), sx, sy);
                        break;
                    case MORGUE:
                        if(!rn2(5))
                            (void) mk_tt_object(CORPSE, sx, sy);
                        if(!rn2(10))    /* lots of treasure buried with dead */
                            (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
                                             sx, sy, true, false);
                        if (!rn2(5))
                            make_grave(sx, sy, (char *)0);
                        break;
                    case BEEHIVE:
                        if(!rn2(3))
                            (void) mksobj_at(LUMP_OF_ROYAL_JELLY,
                                             sx, sy, true, false);
                        break;
                    case BARRACKS:
                        if(!rn2(20))    /* the payroll and some loot */
                            (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
                                             sx, sy, true, false);
                        break;
                    case COCKNEST:
                        if(!rn2(3)) {
                            struct obj *sobj = mk_tt_object(STATUE, sx, sy);

                            if (sobj) {
                                for (i = rn2(5); i; i--)
                                    (void) add_to_container(sobj,
                                                mkobj(RANDOM_CLASS, false));
                                sobj->owt = weight(sobj);
                            }
                        }
                        break;
                    case ANTHOLE:
                        if(!rn2(3))
                            (void) mkobj_at(FOOD_CLASS, sx, sy, false);
                        break;
                }
            }
        switch (type) {
              case COURT:
                {
                  struct obj *chest;
                  levl[tx][ty].typ = THRONE;
                  (void) somexy(sroom, &mm);
                  (void) mkgold((long) rn1(50 * level_difficulty(),10), mm.x, mm.y);
                  /* the royal coffers */
                  chest = mksobj_at(CHEST, mm.x, mm.y, true, false);
                  chest->spe = 2; /* so it can be found later */
                  level.flags.has_court = 1;
                  break;
                }
              case BARRACKS:
                  level.flags.has_barracks = 1;
                  break;
              case ZOO:
                  level.flags.has_zoo = 1;
                  break;
              case MORGUE:
                  level.flags.has_morgue = 1;
                  break;
              case SWAMP:
                  level.flags.has_swamp = 1;
                  break;
              case BEEHIVE:
                  level.flags.has_beehive = 1;
                  break;
        }
}
Пример #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");
	}
}
Пример #14
0
void
fill_zoo(struct level *lev, struct mkroom *sroom, enum rng rng)
{
    struct monst *mon;
    int sx, sy, i;
    int sh, tx, ty, goldlim, type = sroom->rtype;
    int rmno = (sroom - lev->rooms) + ROOMOFFSET;
    coord mm;

    tx = ty = goldlim = 0;

    sh = sroom->fdoor;
    switch (type) {
    case COURT:
        if (lev->flags.is_maze_lev) {
            for (tx = sroom->lx; tx <= sroom->hx; tx++)
                for (ty = sroom->ly; ty <= sroom->hy; ty++)
                    if (IS_THRONE(lev->locations[tx][ty].typ))
                        goto throne_placed;
        }
        i = 100;
        do {    /* don't place throne on top of stairs */
            somexy(lev, sroom, &mm, rng);
            tx = mm.x;
            ty = mm.y;
        } while (occupied(lev, tx, ty) && --i > 0);
    throne_placed:
        /* TODO: try to ensure the enthroned monster is an M2_PRINCE */
        break;
    case BEEHIVE:
        tx = sroom->lx + (sroom->hx - sroom->lx + 1) / 2;
        ty = sroom->ly + (sroom->hy - sroom->ly + 1) / 2;
        if (sroom->irregular) {
            /* center might not be valid, so put queen elsewhere */
            if ((int)lev->locations[tx][ty].roomno != rmno ||
                lev->locations[tx][ty].edge) {
                somexy(lev, sroom, &mm, rng);
                tx = mm.x;
                ty = mm.y;
            }
        }
        break;
    case ZOO:
    case LEPREHALL:
        goldlim = 500 * level_difficulty(&lev->z);
        break;
    }
    for (sx = sroom->lx; sx <= sroom->hx; sx++)
        for (sy = sroom->ly; sy <= sroom->hy; sy++) {
            if (sroom->irregular) {
                if ((int)lev->locations[sx][sy].roomno != rmno ||
                    lev->locations[sx][sy].edge ||
                    (sroom->doorct &&
                     distmin(sx, sy, lev->doors[sh].x, lev->doors[sh].y) <= 1))
                    continue;
            } else if (!SPACE_POS(lev->locations[sx][sy].typ) ||
                       (sroom->doorct &&
                        ((sx == sroom->lx && lev->doors[sh].x == sx - 1) ||
                         (sx == sroom->hx && lev->doors[sh].x == sx + 1) ||
                         (sy == sroom->ly && lev->doors[sh].y == sy - 1) ||
                         (sy == sroom->hy && lev->doors[sh].y == sy + 1))))
                continue;
            /* don't place monster on explicitly placed throne */
            if (type == COURT && IS_THRONE(lev->locations[sx][sy].typ))
                continue;
            mon = makemon((type == COURT) ? courtmon(&lev->z, rng) :
                          (type == BARRACKS) ? squadmon(&lev->z) :
                          (type == MORGUE) ? morguemon(&lev->z, rng) :
                          (type == BEEHIVE) ? (sx == tx && sy == ty ?
                                               &mons[PM_QUEEN_BEE] :
                                               &mons[PM_KILLER_BEE]) :
                          (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] :
                          (type == COCKNEST) ? &mons[PM_COCKATRICE] :
                          (type == ANTHOLE) ? antholemon(&lev->z) :
                          NULL, lev, sx, sy,
                          rng == rng_main ? NO_MM_FLAGS : MM_ALLLEVRNG);
            if (mon) {
                mon->msleeping = 1;
                if (type == COURT && mon->mpeaceful)
                    msethostility(mon, TRUE, TRUE);
            }
            switch (type) {
            case ZOO:
            case LEPREHALL:
                if (sroom->doorct) {
                    int distval =
                        dist2(sx, sy, lev->doors[sh].x, lev->doors[sh].y);
                    i = sq(distval);
                } else
                    i = goldlim;
                if (i >= goldlim)
                    i = 5 * level_difficulty(&lev->z);
                goldlim -= i;
                mkgold(10 + rn2_on_rng(i, rng), lev, sx, sy, rng);
                break;
            case MORGUE:
                if (!rn2_on_rng(5, rng))
                    mk_tt_object(lev, CORPSE, sx, sy);
                if (!rn2_on_rng(10, rng))   /* lots of treasure */
                    mksobj_at(rn2_on_rng(3, rng) ? LARGE_BOX : CHEST,
                              lev, sx, sy, TRUE, FALSE, rng);
                if (!rn2_on_rng(5, rng))
                    make_grave(lev, sx, sy, NULL);
                break;
            case BEEHIVE:
                if (!rn2_on_rng(3, rng))
                    mksobj_at(LUMP_OF_ROYAL_JELLY, lev, sx, sy,
                              TRUE, FALSE, rng);
                break;
            case BARRACKS:
                if (!rn2_on_rng(20, rng))   /* the payroll and some loot */
                    mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, lev, sx, sy,
                              TRUE, FALSE, rng);
                break;
            case COCKNEST:
                if (!rn2_on_rng(3, rng)) {
                    struct obj *sobj = mk_tt_object(lev, STATUE, sx, sy);

                    if (sobj) {
                        for (i = rn2_on_rng(5, rng); i; i--)
                            add_to_container(sobj, mkobj(lev, RANDOM_CLASS,
                                                         FALSE, rng));
                        sobj->owt = weight(sobj);
                    }
                }
                break;
            case ANTHOLE:
                if (!rn2_on_rng(3, rng))
                    mkobj_at(FOOD_CLASS, lev, sx, sy, FALSE, rng);
                break;
            }
        }

    if (type == COURT) {
        struct obj *chest;

        lev->locations[tx][ty].typ = THRONE;
        somexy(lev, sroom, &mm, rng);
        mkgold(10 + rn2_on_rng(50 * level_difficulty(&lev->z), rng),
               lev, mm.x, mm.y, rng);
        /* the royal coffers */
        chest = mksobj_at(CHEST, lev, mm.x, mm.y, TRUE, FALSE, rng);
        chest->spe = 2;     /* so it can be found later */
    }
}
Пример #15
0
void
makemaz()
{
	int x,y;
	int zx,zy;
	coord mm;
	boolean al = (dlevel >= 30 && !flags.made_amulet);

	for(x = 2; x < COLNO-1; x++)
		for(y = 2; y < ROWNO-1; y++)
			levl[x][y].typ = (x%2 && y%2) ? 0 : HWALL;
	if(al) {
	    struct monst *mtmp;

	    zx = 2*(COLNO/4) - 1;
	    zy = 2*(ROWNO/4) - 1;
	    for(x = zx-2; x < zx+4; x++) for(y = zy-2; y <= zy+2; y++) {
		levl[x][y].typ =
		    (y == zy-2 || y == zy+2 || x == zx-2 || x == zx+3) ? POOL :
		    (y == zy-1 || y == zy+1 || x == zx-1 || x == zx+2) ? HWALL:
		    ROOM;
	    }
	    (void) mkobj_at(AMULET_SYM, zx, zy);
	    flags.made_amulet = 1;
	    walkfrom(zx+4, zy);
	    if ((mtmp = makemon(&hell_hound, zx, zy)))
		mtmp->msleep = 1;
	    if ((mtmp = makemon(PM_WIZARD, zx+1, zy))) {
		mtmp->msleep = 1;
		flags.no_of_wizards = 1;
	    }
	} else {
	    mm = mazexy();
	    zx = mm.x;
	    zy = mm.y;
	    walkfrom(zx,zy);
	    (void) mksobj_at(WAN_WISHING, zx, zy);
	    (void) mkobj_at(ROCK_SYM, zx, zy);	/* put a rock on top of it */
	}

	for(x = 2; x < COLNO-1; x++)
		for(y = 2; y < ROWNO-1; y++) {
			switch(levl[x][y].typ) {
			case HWALL:
				levl[x][y].scrsym = '-';
				break;
			case ROOM:
				levl[x][y].scrsym = '.';
				break;
			}
		}
	for(x = rn1(8,11); x; x--) {
		mm = mazexy();
		(void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y);
	}
	for(x = rn1(10,2); x; x--) {
		mm = mazexy();
		(void) mkobj_at(ROCK_SYM, mm.x, mm.y);
	}
	mm = mazexy();
	(void) makemon(PM_MINOTAUR, mm.x, mm.y);
	for(x = rn1(5,7); x; x--) {
		mm = mazexy();
		(void) makemon((struct permonst *) 0, mm.x, mm.y);
	}
	for(x = rn1(6,7); x; x--) {
		mm = mazexy();
		mkgold(0L,mm.x,mm.y);
	}
	for(x = rn1(6,7); x; x--)
		mktrap(0,1,(struct mkroom *) 0);
	mm = mazexy();
	levl[(int)(xupstair = mm.x)][(int)(yupstair = mm.y)].scrsym = '<';
	levl[(int)xupstair][(int)yupstair].typ = STAIRS;
	xdnstair = ydnstair = 0;
}
Пример #16
0
struct obj *
rnd_treefruit_at(int x, int y)
{
    return mksobj_at(treefruits[rn2(SIZE(treefruits))], x, y, TRUE, FALSE);
}
Пример #17
0
/*
 * Let's destroy the drawbridge located at x,y
 */
void
destroy_drawbridge(int x, int y)
{
    struct rm *loc1, *loc2;
    struct trap *t;
    struct obj *chain;
    int x2, y2, i;
    boolean e_inview;
    struct entity *etmp1 = &(occupants[0]), *etmp2 = &(occupants[1]);

    loc1 = &level->locations[x][y];
    if (!IS_DRAWBRIDGE(loc1->typ))
        return;
    x2 = x;
    y2 = y;
    get_wall_for_db(&x2, &y2);
    loc2 = &level->locations[x2][y2];
    if ((loc1->drawbridgemask & DB_UNDER) == DB_MOAT ||
        (loc1->drawbridgemask & DB_UNDER) == DB_LAVA) {
        struct obj *otmp;
        boolean lava = (loc1->drawbridgemask & DB_UNDER) == DB_LAVA;

        if (loc1->typ == DRAWBRIDGE_UP) {
            if (cansee(x2, y2))
                pline("The portcullis of the drawbridge falls into the %s!",
                      lava ? "lava" : waterbody_name(x2, y2));
            else
                You_hear("a loud *SPLASH*!");
        } else {
            if (cansee(x, y))
                pline("The drawbridge collapses into the %s!",
                      lava ? "lava" : waterbody_name(x, y));
            else
                You_hear("a loud *SPLASH*!");
        }
        loc1->typ = lava ? LAVAPOOL : MOAT;
        loc1->drawbridgemask = 0;
        if ((otmp = sobj_at(BOULDER, level, x, y)) != 0) {
            obj_extract_self(otmp);
            flooreffects(otmp, x, y, "fall");
        }
    } else {
        if (cansee(x, y))
            pline("The drawbridge disintegrates!");
        else
            You_hear("a loud *CRASH*!");
        loc1->typ = ((loc1->drawbridgemask & DB_ICE) ? ICE : ROOM);
        loc1->icedpool = ((loc1->drawbridgemask & DB_ICE) ? ICED_MOAT : 0);
    }
    wake_nearto(x, y, 500);
    loc2->typ = DOOR;
    loc2->doormask = D_NODOOR;
    if ((t = t_at(level, x, y)) != 0)
        deltrap(level, t);
    if ((t = t_at(level, x2, y2)) != 0)
        deltrap(level, t);
    del_engr_at(level, x, y);
    del_engr_at(level, x2, y2);
    for (i = rn2(6); i > 0; --i) {  /* scatter some debris */
        /* doesn't matter if we happen to pick <x,y2> or <x2,y>;
           since drawbridges are never placed diagonally, those
           pairings will always match one of <x,y> or <x2,y2> */
        chain = mksobj_at(IRON_CHAIN, level,
                          rn2(2) ? x : x2, rn2(2) ? y : y2,
                          TRUE, FALSE, rng_main);
        /* a force of 5 here would yield a radius of 2 for
           iron chain; anything less produces a radius of 1 */
        (void) scatter(chain->ox, chain->oy, 1, MAY_HIT, chain);
    }
    newsym(x, y);
    newsym(x2, y2);
    if (!does_block(level, x2, y2))
        unblock_point(x2, y2);  /* vision */
    if (Is_stronghold(&u.uz))
        u.uevent.uopened_dbridge = TRUE;

    set_entity(x2, y2, etmp2);  /* currently only automissers can be here */
    if (etmp2->edata) {
        e_inview = e_canseemon(etmp2);
        if (!automiss(etmp2)) {
            if (e_inview)
                pline("%s blown apart by flying debris.",
                      E_phrase(etmp2, "are"));
            e_died(etmp2, e_inview ? 3 : 2, CRUSHING,
                   killer_msg(CRUSHING, "an exploding drawbridge"));
        }       /* nothing which is vulnerable can survive this */
    }
    set_entity(x, y, etmp1);
    if (etmp1->edata) {
        e_inview = e_canseemon(etmp1);
        if (!e_missed(etmp1, TRUE)) {
            if (e_inview) {
                if (!is_u(etmp1) && Hallucination)
                    pline("%s into some heavy metal!", E_phrase(etmp1, "get"));
                else
                    pline("%s hit by a huge chunk of metal!",
                          E_phrase(etmp1, "are"));
            } else {
                if (!is_u(etmp1) && !is_pool(level, x, y))
                    You_hear("a crushing sound.");
            }
            e_died(etmp1, e_inview ? 3 : 2, CRUSHING,
                   killer_msg(CRUSHING, "a collapsing drawbridge"));
            /* if (loc1->typ == MOAT) do_entity(etmp1); */
        }
        if (is_u(etmp1))
            spoteffects(FALSE);
        else if (!DEADMONSTER(etmp1->emon))
            minliquid(etmp1->emon);
    }
}
Пример #18
0
int
dozap(void)
{
	struct obj *obj;
	xchar zx,zy;

	obj = getobj("/", "zap");
	if(!obj) return(0);
	if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
		pline("Nothing Happens.");
		return(1);
	}
	if(obj->spe == 0)
		pline("You wrest one more spell from the worn-out wand.");
	if(!(objects[obj->otyp].bits & NODIR) && !getdir(1))
		return(1);	/* make him pay for knowing !NODIR */
	obj->spe--;
	if(objects[obj->otyp].bits & IMMEDIATE) {
		if(u.uswallow)
			bhitm(u.ustuck, obj);
		else if(u.dz) {
			if(u.dz > 0) {
				struct obj *otmp = o_at(u.ux, u.uy);
				if(otmp)
					bhito(otmp, obj);
			}
		} else
			bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
	} else {
	    switch(obj->otyp){
		case WAN_LIGHT:
			litroom(TRUE);
			break;
		case WAN_SECRET_DOOR_DETECTION:
			if(!findit()) return(1);
			break;
		case WAN_CREATE_MONSTER:
			{ int cnt = 1;
			if(!rn2(23)) cnt += rn2(7) + 1;
			while(cnt--)
			    makemon(NULL, u.ux, u.uy);
			}
			break;
		case WAN_WISHING:
			{ char buf[BUFSZ];
			  struct obj *otmp;
		      if(u.uluck + rn2(5) < 0) {
			pline("Unfortunately, nothing happens.");
			break;
		      }
		      pline("You may wish for an object. What do you want? ");
		      getlin(buf);
		      if(buf[0] == '\033') buf[0] = 0;
		      otmp = readobjnam(buf);
		      otmp = addinv(otmp);
		      prinv(otmp);
		      break;
			}
		case WAN_DIGGING:
			/* Original effect (approximately):
			 * from CORR: dig until we pierce a wall
			 * from ROOM: piece wall and dig until we reach
			 * an ACCESSIBLE place.
			 * Currently: dig for digdepth positions;
			 * also down on request of Lennart Augustsson.
			 */
			{ struct rm *room;
			  int digdepth;
			if(u.uswallow) {
				struct monst *mtmp = u.ustuck;

				pline("You pierce %s's stomach wall!",
					monnam(mtmp));
				mtmp->mhp = 1;	/* almost dead */
				unstuck(mtmp);
				mnexto(mtmp);
				break;
			}
			if(u.dz) {
			    if(u.dz < 0) {
				pline("You loosen a rock from the ceiling.");
				pline("It falls on your head!");
				losehp(1, "falling rock");
				mksobj_at(ROCK, u.ux, u.uy);
				fobj->quan = 1;
				stackobj(fobj);
				if(Invisible) newsym(u.ux, u.uy);
			    } else {
				dighole();
			    }
			    break;
			}
			zx = u.ux+u.dx;
			zy = u.uy+u.dy;
			digdepth = 8 + rn2(18);
			Tmp_at(-1, '*');	/* open call */
			while(--digdepth >= 0) {
				if(!isok(zx,zy)) break;
				room = &levl[zx][zy];
				Tmp_at(zx,zy);
				if(!xdnstair){
					if(zx < 3 || zx > COLNO-3 ||
					    zy < 3 || zy > ROWNO-3)
						break;
					if(room->typ == HWALL ||
					    room->typ == VWALL){
						room->typ = ROOM;
						break;
					}
				} else
				if(room->typ == HWALL || room->typ == VWALL ||
				   room->typ == SDOOR || room->typ == LDOOR){
					room->typ = DOOR;
					digdepth -= 2;
				} else
				if(room->typ == SCORR || !room->typ) {
					room->typ = CORR;
					digdepth--;
				}
				mnewsym(zx,zy);
				zx += u.dx;
				zy += u.dy;
			}
			mnewsym(zx,zy);	/* not always necessary */
			Tmp_at(-1,-1);	/* closing call */
			break;
			}
		default:
			buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
				u.ux, u.uy, u.dx, u.dy);
			break;
		}
	}
	return(1);
}
Пример #19
0
void
nh_timeout()
{
	register struct prop *upp;
	int sleeptime;
	int m_idx;
	int baseluck = (flags.moonphase == FULL_MOON) ? 1 : 0;

	if (flags.friday13) baseluck -= 1;

	if (u.uluck != baseluck &&
		moves % (u.uhave.amulet || u.ugangr ? 300 : 600) == 0) {
	/* Cursed luckstones stop bad luck from timing out; blessed luckstones
	 * stop good luck from timing out; normal luckstones stop both;
	 * neither is stopped if you don't have a luckstone.
	 * Luck is based at 0 usually, +1 if a full moon and -1 on Friday 13th
	 */
	    register int time_luck = stone_luck(FALSE);
	    boolean nostone = !carrying(LUCKSTONE) && !stone_luck(TRUE);

	    if(u.uluck > baseluck && (nostone || time_luck < 0))
		u.uluck--;
	    else if(u.uluck < baseluck && (nostone || time_luck > 0))
		u.uluck++;
	}
	if(u.uinvulnerable) return; /* things past this point could kill you */
	if(Stoned) stoned_dialogue();
	if(Slimed) slime_dialogue();
	if(Vomiting) vomiting_dialogue();
	if(Strangled) choke_dialogue();
	if(u.mtimedone && !--u.mtimedone) {
		if (Unchanging)
			u.mtimedone = rnd(100*youmonst.data->mlevel + 1);
		else
			rehumanize();
	}
	if(u.ucreamed) u.ucreamed--;

	/* Dissipate spell-based protection. */
	if (u.usptime) {
	    if (--u.usptime == 0 && u.uspellprot) {
		u.usptime = u.uspmtime;
		u.uspellprot--;
		find_ac();
		if (!Blind)
		    Norep("The %s haze around you %s.", hcolor(NH_GOLDEN),
			  u.uspellprot ? "becomes less dense" : "disappears");
	    }
	}

#ifdef STEED
	if (u.ugallop) {
	    if (--u.ugallop == 0L && u.usteed)
	    	pline("%s stops galloping.", Monnam(u.usteed));
	}
#endif

	for(upp = u.uprops; upp < u.uprops+SIZE(u.uprops); upp++)
	    if((upp->intrinsic & TIMEOUT) && !(--upp->intrinsic & TIMEOUT)) {
		switch(upp - u.uprops){
		case STONED:
			if (delayed_killer && !killer) {
				killer = delayed_killer;
				delayed_killer = 0;
			}
			if (!killer) {
				/* leaving killer_format would make it
				   "petrified by petrification" */
				killer_format = NO_KILLER_PREFIX;
				killer = "killed by petrification";
			}
			done(STONING);
			break;
		case SLIMED:
			if (delayed_killer && !killer) {
				killer = delayed_killer;
				delayed_killer = 0;
			}
			if (!killer) {
				killer_format = NO_KILLER_PREFIX;
				killer = "turned into green slime";
			}
			done(TURNED_SLIME);
			break;
		case VOMITING:
			make_vomiting(0L, TRUE);
			break;
		case SICK:
			You("die from your illness.");
			killer_format = KILLED_BY_AN;
			killer = u.usick_cause;
			if ((m_idx = name_to_mon(killer)) >= LOW_PM) {
			    if (type_is_pname(&mons[m_idx])) {
				killer_format = KILLED_BY;
			    } else if (mons[m_idx].geno & G_UNIQ) {
				killer = the(killer);
				Strcpy(u.usick_cause, killer);
				killer_format = KILLED_BY;
			    }
			}
			u.usick_type = 0;
			done(POISONING);
			break;
		case FAST:
			if (!Very_fast)
				You_feel("yourself slowing down%s.",
							Fast ? " a bit" : "");
			break;
		case CONFUSION:
			HConfusion = 1; /* So make_confused works properly */
			make_confused(0L, TRUE);
			stop_occupation();
			break;
		case STUNNED:
			HStun = 1;
			make_stunned(0L, TRUE);
			stop_occupation();
			break;
		case BLINDED:
			Blinded = 1;
			make_blinded(0L, TRUE);
			stop_occupation();
			break;
		case INVIS:
			newsym(u.ux,u.uy);
			if (!Invis && !BInvis && !Blind) {
			    You(!See_invisible ?
				    "are no longer invisible." :
				    "can no longer see through yourself.");
			    stop_occupation();
			}
			break;
		case SEE_INVIS:
			set_mimic_blocking(); /* do special mimic handling */
			see_monsters();		/* make invis mons appear */
			newsym(u.ux,u.uy);	/* make self appear */
			stop_occupation();
			break;
		case WOUNDED_LEGS:
			heal_legs();
			stop_occupation();
			break;
		case HALLUC:
			HHallucination = 1;
			(void) make_hallucinated(0L, TRUE, 0L);
			stop_occupation();
			break;
		case SLEEPING:
			if (unconscious() || Sleep_resistance)
				HSleeping += rnd(100);
			else if (Sleeping) {
				You("fall asleep.");
				sleeptime = rnd(20);
				fall_asleep(-sleeptime, TRUE);
				HSleeping += sleeptime + rnd(100);
			}
			break;
		case LEVITATION:
			(void) float_down(I_SPECIAL|TIMEOUT, 0L);
			break;
		case STRANGLED:
			killer_format = KILLED_BY;
			killer = (u.uburied) ? "suffocation" : "strangulation";
			done(DIED);
			break;
		case FUMBLING:
			/* call this only when a move took place.  */
			/* otherwise handle fumbling msgs locally. */
			if (u.umoved && !Levitation) {
			    slip_or_trip();
			    nomul(-2, "fumbling");
			    nomovemsg = "";
			    /* The more you are carrying the more likely you
			     * are to make noise when you fumble.  Adjustments
			     * to this number must be thoroughly play tested.
			     */
			    if ((inv_weight() > -500)) {
				You("make a lot of noise!");
				wake_nearby();
			    }
			}
			/* from outside means slippery ice; don't reset
			   counter if that's the only fumble reason */
			HFumbling &= ~FROMOUTSIDE;
			if (Fumbling)
			    HFumbling += rnd(20);
			break;
		case DETECT_MONSTERS:
			see_monsters();
			break;
		case PREGNANT: {
			char buf[BUFSZ];
			if (!flags.female) {
			    strcpy(buf, body_part(STOMACH));
			    if (!strcmp(buf, "stomach"))
				strcpy(buf, "belly");
			    pline("Something bursts out of your %s!");
			    killer_format = KILLED_BY;
			    killer = "male childbirth";
			    done(DIED);
			}
			mksobj_at(PLACENTA, u.ux, u.uy, FALSE, FALSE);
			pline("BABIES!"); /* TODO */
			stop_occupation();
			break;
		    }
		}
	}

	run_timers();
}
Пример #20
0
void killed(struct monst *mtmp)
{
#define NEW_SCORING

    int tmp;
    int tmp2;
    int nk;
    int x;
    int y;
    struct permonst *mdat = mtmp->data;

    if(mtmp->cham != 0) {
        mdat = PM_CHAM;
    }

    if(Blind != 0) {
        pline("You destroy it!");
    }
    else {
        if(mtmp->mtame != 0) {
            pline("You destroy %s!", amonnam(mtmp, "poor"));
        }
        else {
            pline("You destroy %s!", monnam(mtmp));
        }
    }

    if(u.umconf != 0) {
        if(Blind == 0) {
            pline("Your hands stop clowing blue.");
            u.umconf = 0;
        }
    }

    /* Count killed monsters */
#define MAXMONNO 100
    /* In case we cannot find it in mons */
    nk = 1;

    /* Index in mons array (if not 'd', '@', ...) */
    tmp = mdat - mons;

    if((tmp >= 0) && (tmp < (CMNUM + 2))) {
        extern char fut_geno[];

        ++u.nr_killed[tmp];
        nk = u.nr_killed[tmp];
        if((nk > MAXMONNO) && (index(fut_geno, mdat->mlet) == 0)) {
            charcat(fut_geno, mdat->mlet);
        }
    }

    /* Punish bad behaviour */
    if(mdat->mlet == '@') {
        Telepat = 0;
        u.uluck -= 2;
    }

    if((mtmp->mpeaceful != 0) || (mtmp->mtame != 0)) {
        --u.uluck;
    }

    if(mdat->mlet == 'u') {
        u.uluck -= 5;
    }

    /* Give experience points */
    tmp = 1 + (mdat->mlevel * mdat->mlevel);

    if(mdat->ac < 3) {
        tmp += (2 * (7 - mdat->ac));
    }

    if(index("AcsSDXaeRTVWU&In:P", mdat->mlet) != 0) {
        tmp += (2 * mdat->mlevel);
    }

    if(index("DeV&P", mdat->mlet) != 0) {
        tmp += (7 * mdat->mlevel);
    }

    if(mdat->mlevel > 6) {
        tmp += 50;
    }

#ifdef NEW_SCORING
    /*
     * ------- Recent addition: make number of points decrease
     * when this is not the first of this kind
     */
    int ul = u.ulevel;
    int ml = mdat->mlevel;
    
    /* Points are given based on present and future level */
    if(ul < 14) {
        for(tmp2 = 0; (tmp2 == 0) || ((ul + tmp2) <= ml); ++tmp2) {
            if(tmp <= 0) {
                if(((u.uexp + 1) + ((tmp + (0)) / nk)) >= (10 * pow(2, (unsigned)(ul - 1)))) {
                    ++ul;
                    if(ul == 14) {
                        break;
                    }
                }
            }
            else {
                if(((u.uexp + 1) + ((tmp + (4 << (tmp2 - 1))) / nk)) >= (10 * pow(2, (unsigned)(ul - 1)))) {
                    ++ul;
                    if(ul == 14) {
                        break;
                    }
                }
            }
        }
    }

    tmp2 = (ml - ul) - 1;
    
    if(tmp2 < 0) {
        tmp = (tmp + (0)) / nk;
    }
    else {
        tmp = (tmp + (4 << tmp2)) / nk;
    }

    if(tmp == 0) {
        tmp = 1;
    }

    /* 
     * Note: ul is not necessarily the future value of u.ulevel
     * ------- End of recent valuation change -------
     */
#endif

    u.uexp += tmp;
    u.urexp += (4 * tmp);
    flags.botl = 1;

    while((u.ulevel < 14) && (u.uexp >= (10 * pow(2, u.ulevel - 1)))) {
        ++u.ulevel;
        pline("Welcome to level %d.", u.ulevel);

        tmp = rnd(30);

        if(tmp < 3) {
            tmp = rnd(10);
        }

        u.uhpmax += tmp;
        u.uhp += tmp;
        flags.botl = 1;
    }

    /* Dispose of monster and make cadaver */
    x = mtmp->mx;
    y = mtmp->my;
    mondead(mtmp);
    tmp = mdat->mlet;

    if(tmp == 'm') {
        /* He killed a minotaur, give him a wand of digging */
        /* Note: The dead minotaur will be on top of it! */
        mksobj_at(WAND_SYM, WAN_DIGGING, x, y);

        /*
         * if(cansee(x, y) != 0) {
         *     atl(x, y, fobj->olet);
         * }
         */

        stackobj(fobj);
    }
#ifndef NOWORM
    else if(tmp == 'w') {
        mksobj_at(WEAPON_SYM, WORM_TOOTH, x, y);
        stackobj(fobj);
    }
#endif
    else {
        if((letter(tmp) == 0) || (rn2(3) == 0)) {
            tmp = 0;
        }

        if(levl[x][y].typ >= DOOR) {
            /* Might be a mimic in wall */
            if((x != u.ux) || (y != u.uy)) {
                /* Might be here after swallowed */
                if((index("NTVm&", mdat->mlet) != NULL) || (rn2(5) != 0)) {
                    mkobj_at(tmp, x, y);
                    
                    if(cansee(x, y) != 0) {
                        atl(x, y, fobj->olet);
                    }

                    stackobj(fobj);
                }
            }
        }
    }
}
Пример #21
0
void do_trap(trap_t *trap) // was dotrap
{
  Short ttype = get_trap_type(trap->trap_info);

  nomul(0);
  if (get_trap_seen(trap->trap_info) && !rund(5) && ttype != PIT) {
    StrPrintF(ScratchBuffer, "You escape a%s.", traps[ttype]);
    message(ScratchBuffer);
  } else {
    trap->trap_info |= SEEN_TRAP;
    switch(ttype) {
    case SLP_GAS_TRAP:
      message("A cloud of gas puts you to sleep!");
      nomul(-rnd(25));
      break;
    case BEAR_TRAP:
      if (Levitation) {
	message("You float over a bear trap.");
	break;
      }
      you.utrap = 4 + rund(4);
      you.utraptype = TT_BEARTRAP;
      message("A bear trap closes on your foot!");
      break;
    case PIERC:
      deltrap(trap);
      if (makemon(PM_PIERCER, you.ux, you.uy)) {
	message("A piercer suddenly drops from the ceiling!");
	if (uarmh)
	  message("Its blow glances off your helmet.");
	else
	  thing_hit_you(3, dice(4,6), "falling piercer");
      }
      break;
    case ARROW_TRAP:
      message("An arrow shoots out at you!");
      if (!thing_hit_you(8, rnd(6), "arrow")){
	mksobj_at(ARROW, you.ux, you.uy);
	fobj->quantity = 1;
      }
      break;
    case TRAPDOOR:
      if (!xdnstair) {
	message("A trap door in the ceiling opens and a rock falls on your head!");
	if (uarmh) message("Fortunately, you are wearing a helmet!");
	losehp((uarmh ? 2 : dice(2,10)), "falling rock");
	mksobj_at(ROCK, you.ux, you.uy);
	fobj->quantity = 1;
	stackobj(fobj);
	if (Invisible) newsym(you.ux, you.uy);
      } else {
	Short newlevel = dlevel + 1;
	while (!rund(4) && newlevel < 29)
	  newlevel++;
	message("A trap door opens up under you!");
	if (Levitation || you.ustuck) {
	  message("For some reason you don't fall in.");
	  break;
	}

	goto_level(newlevel, false);
      }
      break;
    case DART_TRAP:
      message("A little dart shoots out at you!");
      if (thing_hit_you(7, rnd(3), "little dart")) {
	if (!rund(6))
	  poisoned("dart", "poison dart");
      } else {
	mksobj_at(DART, you.ux, you.uy);
	fobj->quantity = 1;
      }
      break;
    case TELEP_TRAP:
      map_mode_teleport = TELE_TRAP;
      if (get_trap_once(trap->trap_info)) {
	deltrap(trap);
	newsym(you.ux,you.uy);
	vtele();
      } else {
	newsym(you.ux,you.uy);
	tele();
      }
      break;
    case PIT:
      if (Levitation) {
	message("A pit opens up under you!");
	message("You don't fall in!");
	break;
      }
      message("You fall into a pit!");
      you.utrap = rund(6) + 2;
      you.utraptype = TT_PIT;
      losehp(rnd(6),"fall into a pit");
      selftouch("Falling, you");
      break;
    default:
      StrPrintF(ScratchBuffer, "BUG: You hit a trap with info=%u",
		trap->trap_info);
      message(ScratchBuffer);
    }
  }
}