Esempio n. 1
0
static bool
bhito(struct obj *obj, struct obj *otmp)
	/* object obj was hit by the effect of wand otmp */
	/* returns TRUE if sth was done */
{
	int res = TRUE;

	if(obj == uball || obj == uchain)
		res = FALSE;
	else
	switch(otmp->otyp) {
	case WAN_POLYMORPH:
		/* preserve symbol and quantity, but turn rocks into gems */
		mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
			? GEM_SYM : obj->olet,
			obj->ox, obj->oy) -> quan = obj->quan;
		delobj(obj);
		break;
	case WAN_STRIKING:
		if(obj->otyp == ENORMOUS_ROCK)
			fracture_rock(obj);
		else
			res = FALSE;
		break;
	case WAN_CANCELLATION:
		if(obj->spe && obj->olet != AMULET_SYM) {
			obj->spe = 0;
		}
		break;
	case WAN_TELEPORTATION:
		rloco(obj);
		break;
	case WAN_MAKE_INVISIBLE:
		obj->oinvis = 1;
		break;
	case WAN_UNDEAD_TURNING:
		res = revive(obj);
		break;
	case WAN_SLOW_MONSTER:		/* no effect on objects */
	case WAN_SPEED_MONSTER:
#ifdef WAN_PROBING
	case WAN_PROBING:
#endif /* WAN_PROBING */
		res = FALSE;
		break;
	default:
		impossible("What an interesting wand (%u)", otmp->otyp);
	}
	return(res);
}
Esempio n. 2
0
/* drop (perhaps) a cadaver and remove monster */
void
mondied(struct monst *mdef)
{
	const struct permonst *pd = mdef->data;
	if (letter(pd->mlet) && rn2(3)) {
		(void) mkobj_at(pd->mlet, mdef->mx, mdef->my);
		if (cansee(mdef->mx, mdef->my)) {
			unpmon(mdef);
			atl(mdef->mx, mdef->my, fobj->olet);
		}
		stackobj(fobj);
	}
	mondead(mdef);
}
Esempio n. 3
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;
	}
}
Esempio n. 4
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);
    }
}
Esempio n. 5
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);
    }
}
Esempio n. 6
0
/*
 * called with [x,y] = coordinates;
 *	[0,0] means anyplace
 *	[u.ux,u.uy] means: call mnexto (if !in_mklev)
 *
 *	In case we make an Orc or killer bee, we make an entire horde (swarm);
 *	note that in this case we return only one of them (the one at [x,y]).
 */
struct monst *
makemon(struct permonst *ptr, int x, int y)
{
	struct monst *mtmp;
	int tmp, ct;
	boolean anything = (!ptr);
	extern boolean in_mklev;

	if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
	if(ptr){
		if(strchr(fut_geno, ptr->mlet)) return((struct monst *) 0);
	} else {
		ct = CMNUM - strlen(fut_geno);
		if(strchr(fut_geno, 'm')) ct++;  /* make only 1 minotaur */
		if(strchr(fut_geno, '@')) ct++;
		if(ct <= 0) return(0); 		  /* no more monsters! */
		tmp = rn2(ct*dlevel/24 + 7);
		if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
		if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
		for(ct = 0; ct < CMNUM; ct++){
			ptr = &mons[ct];
			if(strchr(fut_geno, ptr->mlet))
				continue;
			if(!tmp--) goto gotmon;
		}
		panic("makemon?");
	}
gotmon:
	mtmp = newmonst(ptr->pxlth);
	*mtmp = zeromonst;	/* clear all entries in structure */
	for(ct = 0; ct < ptr->pxlth; ct++)
		((char *) &(mtmp->mextra[0]))[ct] = 0;
	mtmp->nmon = fmon;
	fmon = mtmp;
	mtmp->m_id = flags.ident++;
	mtmp->data = ptr;
	mtmp->mxlth = ptr->pxlth;
	if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
	else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
	else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
	mtmp->mx = x;
	mtmp->my = y;
	mtmp->mcansee = 1;
	if(ptr->mlet == 'M'){
		mtmp->mimic = 1;
		mtmp->mappearance = ']';
	}
	if(!in_mklev) {
		if(x == u.ux && y == u.uy && ptr->mlet != ' ')
			mnexto(mtmp);
		if(x == 0 && y == 0)
			rloc(mtmp);
	}
	if(ptr->mlet == 's' || ptr->mlet == 'S') {
		mtmp->mhide = mtmp->mundetected = 1;
		if(in_mklev)
		if(mtmp->mx && mtmp->my)
			(void) mkobj_at(0, mtmp->mx, mtmp->my);
	}
	if(ptr->mlet == ':') {
		mtmp->cham = 1;
		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
	}
	if(ptr->mlet == 'I' || ptr->mlet == ';')
		mtmp->minvis = 1;
	if(ptr->mlet == 'L' || ptr->mlet == 'N'
	    || (in_mklev && strchr("&w;", ptr->mlet) && rn2(5))
	) mtmp->msleep = 1;

#ifndef NOWORM
	if(ptr->mlet == 'w' && getwn(mtmp))
		initworm(mtmp);
#endif /* NOWORM */

	if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
		coord mm;
		int cnt = rnd(10);
		mm.x = x;
		mm.y = y;
		while(cnt--) {
			mm = enexto(mm.x, mm.y);
			(void) makemon(ptr, mm.x, mm.y);
		}
	}

	return(mtmp);
}
Esempio n. 7
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;
        }
}
Esempio n. 8
0
static void
join(int a, int b)
{
	coord cc,tt;
	int tx, ty, xx, yy;
	struct rm *crm;
	struct mkroom *croom, *troom;
	int dx, dy, dix, diy, cct;

	croom = &rooms[a];
	troom = &rooms[b];

	/* find positions cc and tt for doors in croom and troom
	   and direction for a corridor between them */

	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
	if(troom->lx > croom->hx) {
		dx = 1;
		dy = 0;
		xx = croom->hx+1;
		tx = troom->lx-1;
		cc = finddpos(xx,croom->ly,xx,croom->hy);
		tt = finddpos(tx,troom->ly,tx,troom->hy);
	} else if(troom->hy < croom->ly) {
		dy = -1;
		dx = 0;
		yy = croom->ly-1;
		cc = finddpos(croom->lx,yy,croom->hx,yy);
		ty = troom->hy+1;
		tt = finddpos(troom->lx,ty,troom->hx,ty);
	} else if(troom->hx < croom->lx) {
		dx = -1;
		dy = 0;
		xx = croom->lx-1;
		tx = troom->hx+1;
		cc = finddpos(xx,croom->ly,xx,croom->hy);
		tt = finddpos(tx,troom->ly,tx,troom->hy);
	} else {
		dy = 1;
		dx = 0;
		yy = croom->hy+1;
		ty = troom->ly-1;
		cc = finddpos(croom->lx,yy,croom->hx,yy);
		tt = finddpos(troom->lx,ty,troom->hx,ty);
	}
	xx = cc.x;
	yy = cc.y;
	tx = tt.x - dx;
	ty = tt.y - dy;
	if(nxcor && levl[xx+dx][yy+dy].typ)
		return;
	dodoor(xx,yy,croom);

	cct = 0;
	while(xx != tx || yy != ty) {
	    xx += dx;
	    yy += dy;

	    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
	    if(cct++ > 500 || (nxcor && !rn2(35)))
		return;

	    if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
		return;		/* impossible */

	    crm = &levl[xx][yy];
	    if(!(crm->typ)) {
		if(rn2(100)) {
			crm->typ = CORR;
			crm->scrsym = CORR_SYM;
			if(nxcor && !rn2(50))
				mkobj_at(ROCK_SYM, xx, yy);
		} else {
			crm->typ = SCORR;
			crm->scrsym = ' ';
		}
	    } else
	    if(crm->typ != CORR && crm->typ != SCORR) {
		/* strange ... */
		return;
	    }

	    /* find next corridor position */
	    dix = abs(xx-tx);
	    diy = abs(yy-ty);

	    /* do we have to change direction ? */
	    if(dy && dix > diy) {
		int ddx = (xx > tx) ? -1 : 1;

		crm = &levl[xx+ddx][yy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
		    dx = ddx;
		    dy = 0;
		    continue;
		}
	    } else if(dx && diy > dix) {
		int ddy = (yy > ty) ? -1 : 1;

		crm = &levl[xx][yy+ddy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
		    dy = ddy;
		    dx = 0;
		    continue;
		}
	    }

	    /* continue straight on? */
	    crm = &levl[xx+dx][yy+dy];
	    if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
		continue;

	    /* no, what must we do now?? */
	    if(dx) {
		dx = 0;
		dy = (ty < yy) ? -1 : 1;
		crm = &levl[xx+dx][yy+dy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
		    continue;
		dy = -dy;
		continue;
	    } else {
		dy = 0;
		dx = (tx < xx) ? -1 : 1;
		crm = &levl[xx+dx][yy+dy];
		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
		    continue;
		dx = -dx;
		continue;
	    }
	}

	/* we succeeded in digging the corridor */
	dodoor(tt.x, tt.y, troom);

	if(smeq[a] < smeq[b])
		smeq[b] = smeq[a];
	else
		smeq[a] = smeq[b];
}
Esempio n. 9
0
void
makelevel(void)
{
	struct mkroom *croom, *troom;
	unsigned tryct;
	int x,y;

	nroom = 0;
	doorindex = 0;
	rooms[0].hx = -1;	/* in case we are in a maze */

	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
		levl[x][y] = zerorm;

	oinit();	/* assign level dependent obj probabilities */

	if(dlevel >= rn1(3, 26)) {	/* there might be several mazes */
		makemaz();
		return;
	}

	/* construct the rooms */
	nroom = 0;
	secret = FALSE;
	makerooms();

	/* construct stairs (up and down in different rooms if possible) */
	croom = &rooms[rn2(nroom)];
	xdnstair = somex();
	ydnstair = somey();
	levl[xdnstair][ydnstair].scrsym ='>';
	levl[xdnstair][ydnstair].typ = STAIRS;
	if(nroom > 1) {
		troom = croom;
		croom = &rooms[rn2(nroom-1)];
		if(croom >= troom) croom++;
	}
	xupstair = somex();	/* %% < and > might be in the same place */
	yupstair = somey();
	levl[xupstair][yupstair].scrsym ='<';
	levl[xupstair][yupstair].typ = STAIRS;

	/* for each room: put things inside */
	for(croom = rooms; croom->hx > 0; croom++) {

		/* put a sleeping monster inside */
		/* Note: monster may be on the stairs. This cannot be
		   avoided: maybe the player fell through a trapdoor
		   while a monster was on the stairs. Conclusion:
		   we have to check for monsters on the stairs anyway. */
		if(!rn2(3))
			makemon(NULL, somex(), somey());

		/* put traps and mimics inside */
		goldseen = FALSE;
		while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
		if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey());
		if(!rn2(3)) {
			mkobj_at(0, somex(), somey());
			tryct = 0;
			while(!rn2(5)) {
				if(++tryct > 100){
					printf("tryct overflow4\n");
					break;
				}
				mkobj_at(0, somex(), somey());
			}
		}
	}

	qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
	makecorridors();
	make_niches();

	/* make a secret treasure vault, not connected to the rest */
	if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) {
		troom = &rooms[nroom];
		secret = TRUE;
		if(makerooms()) {
			troom->rtype = VAULT;		/* treasure vault */
			for(x = troom->lx; x <= troom->hx; x++)
			for(y = troom->ly; y <= troom->hy; y++)
				mkgold((long)(rnd(dlevel*100) + 50), x, y);
			if(!rn2(3))
				makevtele();
		}
	}

#ifndef QUEST
#ifdef WIZARD
	if(wizard && getenv("SHOPTYPE")) mkshop(); else
#endif /* WIZARD */
 	if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop();
	else
	if(dlevel > 6 && !rn2(7)) mkzoo(ZOO);
	else
	if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE);
	else
	if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE);
	else
	if(dlevel > 18 && !rn2(6)) mkswamp();
#endif /* QUEST */
}
Esempio n. 10
0
int
doread()
{
	struct obj *scroll;
	boolean confused = (Confusion != 0);
	boolean known = FALSE;

	scroll = getobj("?", "read");
	if(!scroll) return(0);
	if(!scroll->dknown && Blind) {
	    pline("Being blind, you cannot read the formula on the scroll.");
	    return(0);
	}
	if(Blind)
	  pline("As you pronounce the formula on it, the scroll disappears.");
	else
	  pline("As you read the scroll, it disappears.");
	if(confused)
	  pline("Being confused, you mispronounce the magic words ... ");

	switch(scroll->otyp) {
#ifdef MAIL
	case SCR_MAIL:
		readmail(/* scroll */);
		break;
#endif /* MAIL */
	case SCR_ENCHANT_ARMOR:
	    {	struct obj *otmp = some_armor();
		if(!otmp) {
			strange_feeling(scroll,"Your skin glows then fades.");
			return(1);
		}
		if(confused) {
			pline("Your %s glows silver for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 1;
			break;
		}
		if(otmp->spe > 3 && rn2(otmp->spe)) {
	pline("Your %s glows violently green for a while, then evaporates.",
			objects[otmp->otyp].oc_name);
			useup(otmp);
			break;
		}
		pline("Your %s glows green for a moment.",
			objects[otmp->otyp].oc_name);
		otmp->cursed = 0;
		otmp->spe++;
		break;
	    }
	case SCR_DESTROY_ARMOR:
		if(confused) {
			struct obj *otmp = some_armor();
			if(!otmp) {
				strange_feeling(scroll,"Your bones itch.");
				return(1);
			}
			pline("Your %s glows purple for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 0;
			break;
		}
		if(uarm) {
		    pline("Your armor turns to dust and falls to the floor!");
		    useup(uarm);
		} else if(uarmh) {
		    pline("Your helmet turns to dust and is blown away!");
		    useup(uarmh);
		} else if(uarmg) {
			pline("Your gloves vanish!");
			useup(uarmg);
			selftouch("You");
		} else {
			strange_feeling(scroll,"Your skin itches.");
			return(1);
		}
		break;
	case SCR_CONFUSE_MONSTER:
		if(confused) {
			pline("Your hands begin to glow purple.");
			Confusion += rnd(100);
		} else {
			pline("Your hands begin to glow blue.");
			u.umconf = 1;
		}
		break;
	case SCR_SCARE_MONSTER:
	    {	int ct = 0;
		struct monst *mtmp;

		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
			if(cansee(mtmp->mx,mtmp->my)) {
				if(confused)
					mtmp->mflee = mtmp->mfroz =
					mtmp->msleep = 0;
				else
					mtmp->mflee = 1;
				ct++;
			}
		if(!ct) {
		    if(confused)
			pline("You hear sad wailing in the distance.");
		    else
			pline("You hear maniacal laughter in the distance.");
		}
		break;
	    }
	case SCR_BLANK_PAPER:
		if(confused)
		    pline("You see strange patterns on this scroll.");
		else
		    pline("This scroll seems to be blank.");
		break;
	case SCR_REMOVE_CURSE:
	    {	struct obj *obj;
		if(confused)
		  pline("You feel like you need some help.");
		else
		  pline("You feel like someone is helping you.");
		for(obj = invent; obj ; obj = obj->nobj)
			if(obj->owornmask)
				obj->cursed = confused;
		if(Punished && !confused) {
			Punished = 0;
			freeobj(uchain);
			unpobj(uchain);
			free(uchain);
			uball->spe = 0;
			uball->owornmask &= ~W_BALL;
			uchain = uball = (struct obj *) 0;
		}
		break;
	    }
	case SCR_CREATE_MONSTER:
	    {	int cnt = 1;

		if(!rn2(73)) cnt += rnd(4);
		if(confused) cnt += 12;
		while(cnt--)
		    (void) makemon(confused ? PM_ACID_BLOB :
			(struct permonst *) 0, u.ux, u.uy);
		break;
	    }
	case SCR_ENCHANT_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows silver for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 1;
		} else
			if(!chwepon(scroll, 1))		/* tests for !uwep */
				return(1);
		break;
	case SCR_DAMAGE_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows purple for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 0;
		} else
			if(!chwepon(scroll, -1))	/* tests for !uwep */
				return(1);
		break;
	case SCR_TAMING:
	    {	int i,j;
		int bd = confused ? 5 : 1;
		struct monst *mtmp;

		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
		if ((mtmp = m_at(u.ux+i, u.uy+j)))
			(void) tamedog(mtmp, NULL);
		break;
	    }
	case SCR_GENOCIDE:
	    {	extern char genocided[], fut_geno[];
		char buf[BUFSZ];
		struct monst *mtmp, *mtmp2;

		pline("You have found a scroll of genocide!");
		known = TRUE;
		if(confused)
			*buf = u.usym;
		else do {
	    pline("What monster do you want to genocide (Type the letter)? ");
			getlin(buf);
		} while(strlen(buf) != 1 || !monstersym(*buf));
		if(!strchr(fut_geno, *buf))
			charcat(fut_geno, *buf);
		if(!strchr(genocided, *buf))
			charcat(genocided, *buf);
		else {
			pline("Such monsters do not exist in this world.");
			break;
		}
		for(mtmp = fmon; mtmp; mtmp = mtmp2){
			mtmp2 = mtmp->nmon;
			if(mtmp->data->mlet == *buf)
				mondead(mtmp);
		}
		pline("Wiped out all %c's.", *buf);
		if(*buf == u.usym) {
			killer = "scroll of genocide";
			u.uhp = -1;
		}
		break;
		}
	case SCR_LIGHT:
		if(!Blind) known = TRUE;
		litroom(!confused);
		break;
	case SCR_TELEPORTATION:
		if(confused)
			level_tele();
		else {
#ifdef QUEST
			int oux = u.ux, ouy = u.uy;
			tele();
			if(dist(oux, ouy) > 100) known = TRUE;
#else /* QUEST */
			int uroom = inroom(u.ux, u.uy);
			tele();
			if(uroom != inroom(u.ux, u.uy)) known = TRUE;
#endif /* QUEST */
		}
		break;
	case SCR_GOLD_DETECTION:
	    /* Unfortunately this code has become slightly less elegant,
	       now that gold and traps no longer are of the same type. */
	    if(confused) {
		struct trap *ttmp;

		if(!ftrap) {
			strange_feeling(scroll, "Your toes stop itching.");
			return(1);
		} else {
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				if(ttmp->tx != u.ux || ttmp->ty != u.uy)
					goto outtrapmap;
			/* only under me - no separate display required */
			pline("Your toes itch!");
			break;
		outtrapmap:
			cls();
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				at(ttmp->tx, ttmp->ty, '$');
			prme();
			pline("You feel very greedy!");
		}
	    } else {
		struct gold *gtmp;

		if(!fgold) {
			strange_feeling(scroll, "You feel materially poor.");
			return(1);
		} else {
			known = TRUE;
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				if(gtmp->gx != u.ux || gtmp->gy != u.uy)
					goto outgoldmap;
			/* only under me - no separate display required */
			pline("You notice some gold between your feet.");
			break;
		outgoldmap:
			cls();
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				at(gtmp->gx, gtmp->gy, '$');
			prme();
			pline("You feel very greedy, and sense gold!");
		}
	    }
		/* common sequel */
		more();
		docrt();
		break;
	case SCR_FOOD_DETECTION:
	    {	int ct = 0, ctu = 0;
		struct obj *obj;
		char foodsym = confused ? POTION_SYM : FOOD_SYM;

		for(obj = fobj; obj; obj = obj->nobj)
			if(obj->olet == FOOD_SYM) {
				if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
				else ct++;
			}
		if(!ct && !ctu) {
			strange_feeling(scroll,"Your nose twitches.");
			return(1);
		} else if(!ct) {
			known = TRUE;
			pline("You smell %s close nearby.",
				confused ? "something" : "food");
			
		} else {
			known = TRUE;
			cls();
			for(obj = fobj; obj; obj = obj->nobj)
			    if(obj->olet == foodsym)
				at(obj->ox, obj->oy, FOOD_SYM);
			prme();
			pline("Your nose tingles and you smell %s!",
				confused ? "something" : "food");
			more();
			docrt();
		}
		break;
	    }
	case SCR_IDENTIFY:
		/* known = TRUE; */
		if(confused)
			pline("You identify this as an identify scroll.");
		else
			pline("This is an identify scroll.");
		useup(scroll);
		objects[SCR_IDENTIFY].oc_name_known = 1;
		if(!confused)
		    while(
			!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
			&& invent
		    );
		return(1);
	case SCR_MAGIC_MAPPING:
	    {	struct rm *lev;
		int num, zx, zy;

		known = TRUE;
		pline("On this scroll %s a map!",
			confused ? "was" : "is");
		for(zy = 0; zy < ROWNO; zy++)
			for(zx = 0; zx < COLNO; zx++) {
				if(confused && rn2(7)) continue;
				lev = &(levl[zx][zy]);
				if((num = lev->typ) == 0)
					continue;
				if(num == SCORR) {
					lev->typ = CORR;
					lev->scrsym = CORR_SYM;
				} else
				if(num == SDOOR) {
					lev->typ = DOOR;
					lev->scrsym = '+';
					/* do sth in doors ? */
				} else if(lev->seen) continue;
#ifndef QUEST
				if(num != ROOM)
#endif /* QUEST */
				{
				  lev->seen = lev->new = 1;
				  if(lev->scrsym == ' ' || !lev->scrsym)
				    newsym(zx,zy);
				  else
				    on_scr(zx,zy);
				}
			}
		break;
	    }
	case SCR_AMNESIA:
	    {	int zx, zy;

		known = TRUE;
		for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
		    if(!confused || rn2(7))
			if(!cansee(zx,zy))
			    levl[zx][zy].seen = 0;
		docrt();
		pline("Thinking of Maud you forget everything else.");
		break;
	    }
	case SCR_FIRE:
	    {	int num;
		struct monst *mtmp;

		known = TRUE;
		if(confused) {
		    pline("The scroll catches fire and you burn your hands.");
		    losehp(1, "scroll of fire");
		} else {
		    pline("The scroll erupts in a tower of flame!");
		    if(Fire_resistance)
			pline("You are uninjured.");
		    else {
			num = rnd(6);
			u.uhpmax -= num;
			losehp(num, "scroll of fire");
		    }
		}
		num = (2*num + 1)/3;
		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
		    if(dist(mtmp->mx,mtmp->my) < 3) {
			mtmp->mhp -= num;
			if(strchr("FY", mtmp->data->mlet))
			    mtmp->mhp -= 3*num;	/* this might well kill 'F's */
			if(mtmp->mhp < 1) {
			    killed(mtmp);
			    break;		/* primitive */
			}
		    }
		}
		break;
	    }
	case SCR_PUNISHMENT:
		known = TRUE;
		if(confused) {
			pline("You feel guilty.");
			break;
		}
		pline("You are being punished for your misbehaviour!");
		if(Punished){
			pline("Your iron ball gets heavier.");
			uball->owt += 15;
			break;
		}
		Punished = INTRINSIC;
		setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
		setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
		uball->spe = 1;		/* special ball (see save) */
		break;
	default:
		impossible("What weird language is this written in? (%u)",
			scroll->otyp);
	}
Esempio n. 11
0
mkshop(){
register struct mkroom *sroom;
register int sh,sx,sy,i = -1;
register char let;
int roomno;
register struct monst *shk;
#ifdef WIZARD
	/* first determine shoptype */
	if(wizard){
		extern char *getenv();
		register char *ep = getenv("SHOPTYPE");
		if(ep){
			if(*ep == 'z' || *ep == 'Z'){
				mkzoo(ZOO);
				return;
			}
			if(*ep == 'm' || *ep == 'M'){
				mkzoo(MORGUE);
				return;
			}
			if(*ep == 'b' || *ep == 'B'){
				mkzoo(BEEHIVE);
				return;
			}
			if(*ep == 's' || *ep == 'S'){
				mkswamp();
				return;
			}
			for(i=0; shtypes[i]; i++)
				if(*ep == shtypes[i]) break;
			goto gottype;
		}
	}
gottype:
#endif WIZARD
	for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){
		if(sroom->hx < 0) return;
		if(sroom - rooms >= nroom) {
			pline("rooms not closed by -1?");
			return;
		}
		if(sroom->rtype) continue;
		if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
			continue;
		if(
#ifdef WIZARD
		   (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) ||
#endif WIZARD
			sroom->doorct == 1) break;
	}

	if(i < 0) {			/* shoptype not yet determined */
	    register int j;

	    for(j = rn2(100), i = 0; (j -= shprobs[i])>= 0; i++)
		if(!shtypes[i]) break;			/* superfluous */
	    if(isbig(sroom) && i + SHOPBASE == WANDSHOP)
		i = GENERAL-SHOPBASE;
	}
	sroom->rtype = i + SHOPBASE;
	let = shtypes[i];
	sh = sroom->fdoor;
	sx = doors[sh].x;
	sy = doors[sh].y;
	if(sx == sroom->lx-1) sx++; else
	if(sx == sroom->hx+1) sx--; else
	if(sy == sroom->ly-1) sy++; else
	if(sy == sroom->hy+1) sy--; else {
#ifdef WIZARD
	    /* This is said to happen sometimes, but I've never seen it. */
	    if(wizard) {
		register int j = sroom->doorct;
		extern int doorindex;

		pline("Where is shopdoor?");
		pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly,
			sroom->hx, sroom->hy);
		pline("doormax=%d doorct=%d fdoor=%d",
			doorindex, sroom->doorct, sh);
		while(j--) {
			pline("door [%d,%d]", doors[sh].x, doors[sh].y);
			sh++;
		}
		more();
	    }
#endif WIZARD
	    return;
	}
	if(!(shk = makemon(PM_SHK,sx,sy))) return;
	shk->isshk = shk->mpeaceful = 1;
	shk->msleep = 0;
	shk->mtrapseen = ~0;	/* we know all the traps already */
	ESHK->shoproom = roomno;
	ESHK->shoplevel = dlevel;
	ESHK->shd = doors[sh];
	ESHK->shk.x = sx;
	ESHK->shk.y = sy;
	ESHK->robbed = 0;
	ESHK->visitct = 0;
	ESHK->following = 0;
	shk->mgold = 1000 + 30*rnd(100);	/* initial capital */
	ESHK->billct = 0;
	findname(ESHK->shknam, let);
	for(sx = sroom->lx; sx <= sroom->hx; sx++)
	for(sy = sroom->ly; sy <= sroom->hy; sy++){
		register struct monst *mtmp;
		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;
		if(rn2(100) < dlevel && !m_at(sx,sy) &&
		   (mtmp = makemon(PM_MIMIC, sx, sy))){
			mtmp->mimic = 1;
			mtmp->mappearance =
			    (let && rn2(10) < dlevel) ? let : ']';
			continue;
		}
		(void) mkobj_at(let, sx, sy);
	}
}
Esempio n. 12
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);
                }
            }
        }
    }
}
Esempio n. 13
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;
}
Esempio n. 14
0
//
// called with [x,y] = coordinates;
//      [0,0] means anyplace
//      [_u.ux,_u.uy] means: call mnexto (if !in_mklev)
//
//      In case we make an Orc or killer bee, we make an entire horde (swarm);
//      note that in this case we return only one of them (the one at [x,y]).
struct monst* makemon (const struct permonst* ptr, int x, int y)
{
    if (x != 0 || y != 0)
	if (m_at(x, y))
	    return NULL;
    bool anything = false;
    if (!ptr) {
	anything = true;
	unsigned mi = rn2 (CMNUM*_u.dlevel/24+7);
	if (mi+4 < _u.dlevel)
	    mi = rn2 (CMNUM*_u.dlevel/24+12);
	if (mi >= CMNUM)
	    mi = rn1 (CMNUM-CMNUM/2, CMNUM/2);
	while (mi < CMNUM && is_monster_genocided (c_Monsters[mi].mlet))
	    ++mi;
	if (mi >= CMNUM)
	    return NULL;	// all monsters genocided
	ptr = &c_Monsters[mi];
    } else if (is_monster_genocided (ptr->mlet))
	return NULL;
    struct monst* mtmp = newmonst(ptr->pxlth);
    mtmp->nmon = _level->monsters;
    _level->monsters = mtmp;
    mtmp->m_id = _wflags.ident++;
    mtmp->data = ptr;
    mtmp->mxlth = ptr->pxlth;
    if (ptr->mlet == 'D')
	mtmp->mhpmax = mtmp->mhp = 80;
    else if (!ptr->mlevel)
	mtmp->mhpmax = mtmp->mhp = rnd(4);
    else
	mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
    mtmp->mx = x;
    mtmp->my = y;
    mtmp->mcansee = 1;
    if (!in_mklev) {
	if (x == _u.ux && y == _u.uy && ptr->mlet != ' ')
	    mnexto(mtmp);
	if (x == 0 && y == 0)
	    rloc(mtmp);
    }
    if (ptr->mlet == 's' || ptr->mlet == 'S') {
	mtmp->mhide = mtmp->mundetected = 1;
	if (in_mklev)
	    if (mtmp->mx && mtmp->my)
		mkobj_at(0, mtmp->mx, mtmp->my);
    }
    if (ptr->mlet == 'I' || ptr->mlet == ';')
	mtmp->minvis = 1;
    if (ptr->mlet == 'L' || ptr->mlet == 'N' || (in_mklev && strchr("&w;", ptr->mlet) && rn2(5))
	)
	mtmp->msleep = 1;

    if (anything)
	if (ptr->mlet == 'O' || ptr->mlet == 'k') {
	    struct coord mm;
	    int cnt = rnd(10);
	    mm.x = x;
	    mm.y = y;
	    while (cnt--) {
		mm = enexto(mm.x, mm.y);
		makemon(ptr, mm.x, mm.y);
	    }
	}
    return mtmp;
}
Esempio n. 15
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 */
    }
}
Esempio n. 16
0
void mkshop()
{
    struct mkroom *sroom;
    int sh;
    int sx;
    int sy;
    int i;
    char let;
    int roomno;
    struct monst *shk;

    sroom = &rooms[0];
    roomno = 0;
    while(1) {
        if(sroom->hx < 0) {
            return;
        }

        if((sroom->lx <= xdnstair) 
           && (xdnstair <= sroom->hx)
           && (sroom->ly <= ydnstair)
           && (ydnstair <= sroom->hy)) {
            ++sroom;
            ++roomno;

            continue;
        }

        if((sroom->lx <= xupstair)
           && (xupstair <= sroom->hx)
           && (sroom->ly <= yupstair)
           && (yupstair <= sroom->hy)) {
            ++sroom;
            ++roomno;

            continue;
        }

#ifdef WIZARD
        if(wizard || (sroom->doorct == 1)) {
            break;
        }
#else
        if(sroom->doorct == 1) {
            break;
        }
#endif
    }

#ifdef WIZARD
    int flag = 0;

    if(wizard) {
        char *ep = getenv("SHOPTYPE");

        if(ep != NULL) {
            if((*ep == 'z') || (*ep == 'Z')) {
                mkzoo();
                    
                return;
            }

            for(i = 0; shtypes[i]; ++i) {
                if(*ep == shtypes[i]) {
                    break;
                }
            }
                 
            let = i;

            flag = 1;
        }
    }

    if(flag == 0) {
        let = 0;
        i = rn2(100) - shprobs[(int)let];
        while(i > 0) {
            if(shprobs[(int)let] == 0) {
                break; /* Superfluous */
            }
            
            ++let;
            i -= shprobs[(int)let];
        }
    }
#else
    let = 0;
    i = rn2(100) - shprobs[(int)let];
    while(i > 0) {
        if(shprobs[(int)let] == 0) {
            break; /* Superfluous */
        }
            
        ++let;
        i -= shprobs[(int)let];
    }
#endif

    sroom->rtype = 8 + let;
    let = shtypes[(int)let];
    sh = sroom->fdoor;
    sx = doors[sh].x;
    sy = doors[sh].y;

    if(sx == (sroom->lx - 1)) {
        ++sx;
    }
    else if(sx == (sroom->hx + 1)) {
        --sx;
    }
    else if(sy == (sroom->ly - 1)) {
        --sy;
    }
    else if(sy == (sroom->hy + 1)) {
        --sy;
    }
    else {
        printf("Where is shopdoor?");
            
        return;
    }

    shk = makemon(PM_SHK, sx, sy);

    if(shk == NULL) {
        return;
    }

    shk->mpeaceful = 1;
    shk->isshk = shk->mpeaceful;
    shk->msleep = 0;
    shk->mtrapseen = ~0; /* We know all the traps already */
    ESHK->shoproom = roomno;
    ESHK->shd = doors[sh];
    ESHK->shk.x = sx;
    ESHK->shk.y = sy;
    ESHK->robbed = 0;
    ESHK->visitct = 0;
    shk->mgold = 1000 + (30 * rnd(100)); /* Initial capital */
    ESHK->billct = 0;
        
    findname(ESHK->shknam, let);

    for(sx = sroom->lx; sx <= sroom->hx; ++sx) {
        for(sy = sroom->ly; sy <= sroom->hy; ++sy) {
            struct monst *mtmp;

            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;
            }

            if((rn2(100) < dlevel) && !m_at(sx, sy)) {
                mtmp = makemon(PM_MIMIC, sx, sy);

                if(mtmp != NULL) {
                    if(let && (rn2(10) < dlevel)) {
                        mtmp->mimic = let;
                    }
                    else {
                        mtmp->mimic = ']';
                    }

                    continue;
                }
            }

            mkobj_at(let, sx, sy);
        }
    }

#ifdef WIZARD
    if(wizard) {
        if(let) {
            printf("I made a %c-shop.", let);
        }
        else {
            printf("I made a g-shop.");
        }
    }
#endif
    
    ++sroom;
    ++roomno;
}