Пример #1
0
/* create a new shopkeeper in the given room */
static int shkinit ( const struct shclass *shp, struct mkroom *sroom) {
    int sh, sx, sy;
    struct monst *shk;

    /* place the shopkeeper in the given room */
    sh = sroom->fdoor;
    sx = doors[sh].x;
    sy = doors[sh].y;

    /* check that the shopkeeper placement is sane */
    if(sroom->irregular) {
        int rmno = (sroom - rooms) + ROOMOFFSET;
        if (isok(sx-1,sy) && !levl[sx-1][sy].edge &&
                (int) levl[sx-1][sy].roomno == rmno) sx--;
        else if (isok(sx+1,sy) && !levl[sx+1][sy].edge &&
                (int) levl[sx+1][sy].roomno == rmno) sx++;
        else if (isok(sx,sy-1) && !levl[sx][sy-1].edge &&
                (int) levl[sx][sy-1].roomno == rmno) sy--;
        else if (isok(sx,sy+1) && !levl[sx][sy+1].edge &&
                (int) levl[sx][sy+1].roomno == rmno) sx++;
        else goto shk_failed;
    }
    else 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 {
shk_failed:
        return(-1);
    }

    if(MON_AT(sx, sy)) (void) rloc(m_at(sx, sy), false); /* insurance */

    /* now initialize the shopkeeper monster structure */
    if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS)))
        return(-1);
    shk->isshk = shk->mpeaceful = 1;
    set_malign(shk);
    shk->msleeping = 0;
    shk->mtrapseen = ~0;    /* we know all the traps already */
    ESHK(shk)->shoproom = (sroom - rooms) + ROOMOFFSET;
    sroom->resident = shk;
    ESHK(shk)->shoptype = sroom->rtype;
    assign_level(&(ESHK(shk)->shoplevel), &u.uz);
    ESHK(shk)->shd = doors[sh];
    ESHK(shk)->shk.x = sx;
    ESHK(shk)->shk.y = sy;
    ESHK(shk)->robbed = 0L;
    ESHK(shk)->credit = 0L;
    ESHK(shk)->debit = 0L;
    ESHK(shk)->loan = 0L;
    ESHK(shk)->visitct = 0;
    ESHK(shk)->following = 0;
    ESHK(shk)->billct = 0;
    shk->mgold = 1000L + 30L*(long)rnd(100);        /* initial capital */
    if (shp->shknms == shkrings)
        (void) mongets(shk, TOUCHSTONE);
    nameshk(shk, shp->shknms);

    return(sh);
}
Пример #2
0
    bool ofchunk::writeBYTES (const char * p, int l) {
	if (!isok())
	    return false;
	if ((remainingchunklen >= 0) && (remainingchunklen < l))
	    return false;
	ofs.write (p, l);
	if (!isok())
	    return false;
	if (remainingchunklen >= 0)
	    remainingchunklen -= l;
	return true;
    }
Пример #3
0
    bool ofchunk::writeBYTE (int l) {
	if (!isok())
	    return false;
	if ((remainingchunklen >= 0) && (remainingchunklen < 1))
	    return false;

	unsigned char buf[4];
	buf [0] = l & 0xff;
	ofs.write ((char *)&buf[0], 1);
	if (!isok())
	    return false;
	if (remainingchunklen >= 0)
	    remainingchunklen -= 1;
	return true;
    }
Пример #4
0
/*
 * Try to choose a stopping point as near as possible to the starting
 * position while still adjacent to the hero.  If all else fails, try
 * enexto().  Use enexto() as a last resort because enexto() chooses
 * its point randomly, which is not what we want.
 */
STATIC_OVL boolean
md_stop(coord *stopp, coord *startp)
             	/* stopping position (we fill it in) */
              	/* starting positon (read only) */
{
    int x, y, distance, min_distance = -1;

    for (x = u.ux-1; x <= u.ux+1; x++)
        for (y = u.uy-1; y <= u.uy+1; y++) {
            if (!isok(x, y) || (x == u.ux && y == u.uy)) continue;

            if (ACCESSIBLE(levl[x][y].typ) && !MON_AT(x,y)) {
                distance = dist2(x,y,startp->x,startp->y);
                if (min_distance < 0 || distance < min_distance ||
                        (distance == min_distance && rn2(2))) {
                    stopp->x = x;
                    stopp->y = y;
                    min_distance = distance;
                }
            }
        }

    /* If we didn't find a good spot, try enexto(). */
    if (min_distance < 0 &&
            !enexto(stopp, u.ux, u.uy, &mons[PM_MAIL_DAEMON]))
        return FALSE;

    return TRUE;
}
Пример #5
0
    bool ofchunk::writeWORD (int l) {
	if (!isok())
	    return false;
	if ((remainingchunklen >= 0) && (remainingchunklen < 2))
	    return false;

	unsigned char buf[4];
	buf [0] = l & 0xff;
	buf [1] = (l & 0xff00) >> 8;
	ofs.write ((char *)&buf[0], 2);
	if (!isok())
	    return false;
	if (remainingchunklen >= 0)
	    remainingchunklen -= 2;
	return true;
    }
Пример #6
0
int
drawbridge_wall_direction(int x, int y)
{
    struct rm *loc;

    if (!isok(x,y)) {
        impossible("drawbridge_wall_direction(%d,%d) not ok.", x, y);
        return -1;
    }
    loc = &level->locations[x][y];
    if (loc->typ != DOOR && loc->typ != DBWALL)
        return -1;

    if (IS_DRAWBRIDGE(level->locations[x + 1][y].typ) &&
        (level->locations[x + 1][y].drawbridgemask & DB_DIR) == DB_WEST)
        return DB_WEST;
    if (IS_DRAWBRIDGE(level->locations[x - 1][y].typ) &&
        (level->locations[x - 1][y].drawbridgemask & DB_DIR) == DB_EAST)
        return DB_EAST;
    if (IS_DRAWBRIDGE(level->locations[x][y - 1].typ) &&
        (level->locations[x][y - 1].drawbridgemask & DB_DIR) == DB_SOUTH)
        return DB_SOUTH;
    if (IS_DRAWBRIDGE(level->locations[x][y + 1].typ) &&
        (level->locations[x][y + 1].drawbridgemask & DB_DIR) == DB_NORTH)
        return DB_NORTH;

    return -1;
}
Пример #7
0
/*
 * Is (x,y) a good position of mtmp?  If mtmp is NULL, then is (x,y) good
 * for an object?
 *
 * This function will only look at mtmp->mdat, so makemon, mplayer, etc can
 * call it to generate new monster positions with fake monster structures.
 */
boolean goodpos(struct level *lev, int x, int y, struct monst *mtmp, unsigned gpflags)
{
	const struct permonst *mdat = NULL;
	boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0);

	if (!isok(x, y)) return FALSE;

	/* in many cases, we're trying to create a new monster, which
	 * can't go on top of the player or any existing monster.
	 * however, occasionally we are relocating engravings or objects,
	 * which could be co-located and thus get restricted a bit too much.
	 * oh well.
	 */
	if (mtmp != &youmonst && x == u.ux && y == u.uy
			&& (!u.usteed || mtmp != u.usteed))
		return FALSE;

	if (mtmp) {
	    struct monst *mtmp2 = m_at(lev, x,y);

	    /* Be careful with long worms.  A monster may be placed back in
	     * its own location.  Normally, if m_at() returns the same monster
	     * that we're trying to place, the monster is being placed in its
	     * own location.  However, that is not correct for worm segments,
	     * because all the segments of the worm return the same m_at().
	     * Actually we overdo the check a little bit--a worm can't be placed
	     * in its own location, period.  If we just checked for mtmp->mx
	     * != x || mtmp->my != y, we'd miss the case where we're called
	     * to place the worm segment and the worm's head is at x,y.
	     */
	    if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno))
		return FALSE;

	    mdat = mtmp->data;
	    if (is_pool(lev, x,y) && !ignorewater) {
		if (mtmp == &youmonst)
			return !!(HLevitation || Flying || Wwalking ||
					Swimming || Amphibious);
		else	return (is_flyer(mdat) || is_swimmer(mdat) ||
							is_clinger(mdat));
	    } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
		return FALSE;
	    } else if (is_lava(lev, x,y)) {
		if (mtmp == &youmonst)
		    return !!HLevitation;
		else
		    return is_flyer(mdat) || likes_lava(mdat);
	    }
	    if (passes_walls(mdat) && may_passwall(lev, x,y)) return TRUE;
	}
	if (!ACCESSIBLE(lev->locations[x][y].typ)) {
		if (!(is_pool(lev, x,y) && ignorewater)) return FALSE;
	}

	if (closed_door(lev, x, y) && (!mdat || !amorphous(mdat)))
		return FALSE;
	if (sobj_at(BOULDER, lev, x, y) && (!mdat || !throws_rocks(mdat)))
		return FALSE;
	return TRUE;
}
Пример #8
0
void
nh_describe_pos(int x, int y, struct nh_desc_buf *bufs, int *is_in)
{
    bufs->bgdesc[0] = '\0';
    bufs->trapdesc[0] = '\0';
    bufs->objdesc[0] = '\0';
    bufs->mondesc[0] = '\0';
    bufs->invisdesc[0] = '\0';
    bufs->effectdesc[0] = '\0';
    bufs->feature_described = FALSE;
    bufs->objcount = -1;

    if (is_in)
        *is_in = 0;

    if (!program_state.game_running || !isok(x, y))
        return;

    API_ENTRY_CHECKPOINT_RETURN_VOID_ON_ERROR();

    if (is_in) {
        if (IS_ROCK(level->locations[x][y].typ) || closed_door(level, x, y))
            *is_in = 1;
        else
            *is_in = 0;
    }

    int monid = dbuf_get_mon(x, y);
    int mem_bg = level->locations[x][y].mem_bg;

    describe_bg(x, y, mem_bg, bufs->bgdesc);

    int tt = level->locations[x][y].mem_trap;

    if (tt) {
        strcpy(bufs->trapdesc,
               trapexplain[level->locations[x][y].mem_trap - 1]);
        if (tt != BEAR_TRAP && tt != WEB && tt != STATUE_TRAP && mem_bg &&
            is_in)
            *is_in = 1;
    }

    bufs->objcount =
        describe_object(x, y, level->locations[x][y].mem_obj - 1, bufs->objdesc,
                        mem_bg && is_in, &bufs->feature_described);

    describe_mon(x, y, monid - 1, bufs->mondesc);

    if (level->locations[x][y].mem_invis)
        strcpy(bufs->invisdesc, invisexplain);

    if (Engulfed && (x != u.ux || y != u.uy)) {
        /* all locations when swallowed other than the hero are the monster */
        snprintf(bufs->effectdesc, SIZE(bufs->effectdesc), "interior of %s",
                Blind ? "a monster" : a_monnam(u.ustuck));
    }

    API_EXIT();
}
Пример #9
0
boolean
is_any_icewall(int x, int y)
{
    if (!isok(x,y)) return FALSE;
    if (IS_ANY_ICEWALL(levl[x][y].typ))
        return TRUE;
    return FALSE;
}
Пример #10
0
    bool ofchunk::writeLONG (int l) {
	if (!isok())
	    return false;
	if ((remainingchunklen >= 0) && (remainingchunklen < 4))
	    return false;

	unsigned char buf[4];
	buf [0] = l & 0xff;
	buf [1] = (l & 0xff00) >> 8;
	buf [2] = (l & 0xff0000) >> 16;
	buf [3] = (l & 0xff000000) >> 24;
	ofs.write ((char *)&buf[0], 4);
	if (!isok())
	    return false;
	if (remainingchunklen >= 0)
	    remainingchunklen -= 4;
	return true;
    }
Пример #11
0
    bool ifchunk::readWORD (int &l) {
	if (!isok())
	    return false;
	if ((remainingchunklen >= 0) && (remainingchunklen < 2))
	    return false;

	unsigned char buf[2];
	ifs.read ((char *)&buf[0], 2);
	if (!isok())
	    return false;

	if (!isok())
	    return false;
	if (remainingchunklen >= 0)
	    remainingchunklen -= 2;
	l = buf [0] + (buf [1] << 8);
	return true;
    }
Пример #12
0
/*
 * Use is_db_wall where you want to verify that a drawbridge "wall" (i.e.,
 * portcullis) is in the UP position in the location x, y.
 *
 * (If you want to find find out the direction or to verify the existence of a
 * portcullis without regard to whether it's UP or DOWN, then in that case use
 * drawbridge_wall_direction instead.)
 */
boolean
is_db_wall(int x, int y)
{
    if (!isok(x,y)) {
        impossible("is_db_wall(%d,%d) not ok.", x, y);
        return FALSE; /* arbitrary choice */
    }
    return (boolean) (level->locations[x][y].typ == DBWALL);
}
Пример #13
0
    bool ifchunk::readLONG (int &l) {
	if (!isok())
	    return false;
	if ((remainingchunklen >= 0) && (remainingchunklen < 4))
	    return false;

	unsigned char buf[4];
	ifs.read ((char *)&buf[0], 4);
	if (!isok())
	    return false;

	if (!isok())
	    return false;
	if (remainingchunklen >= 0)
	    remainingchunklen -= 4;
	l = buf [0] + (buf [1] << 8) + (buf[2] << 16) + (buf[3] << 24);
	return true;
    }
Пример #14
0
boolean
has_upstairs(struct level *lev, struct mkroom *sroom)
{
    if (sroom == lev->upstairs_room)
        return TRUE;
    if (isok(lev->sstairs.sx, lev->sstairs.sy) && lev->sstairs.up)
        return (boolean) (sroom == lev->sstairs_room);
    return FALSE;
}
Пример #15
0
    bool ifchunk::readBYTE (int &l) {
	if (!isok())
	    return false;
	if ((remainingchunklen >= 0) && (remainingchunklen < 1))
	    return false;

	unsigned char buf[1];
	ifs.read ((char *)&buf[0], 1);
	if (!isok())
	    return false;

	if (!isok())
	    return false;
	if (remainingchunklen >= 0)
	    remainingchunklen -= 1;
	l = buf [0];
	return true;
    }
Пример #16
0
STATIC_OVL boolean
iswall(int x, int y)
{
    register int type;

    if (!isok(x,y)) return FALSE;
    type = levl[x][y].typ;
    return (IS_WALL(type) || IS_DOOR(type) ||
            type == SDOOR || type == IRONBARS);
}
Пример #17
0
boolean is_pool(struct level *lev, int x, int y)
{
    schar ltyp;

    if (!isok(x,y)) return FALSE;
    ltyp = lev->locations[x][y].typ;
    if (ltyp == POOL || ltyp == MOAT || ltyp == WATER) return TRUE;
    if (ltyp == DRAWBRIDGE_UP &&
	(lev->locations[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE;
    return FALSE;
}
Пример #18
0
boolean is_swamp(struct level *lev, int x, int y)
{
    schar ltyp;

    if (!isok(x,y)) return FALSE;
    ltyp = lev->locations[x][y].typ;
    if (ltyp == BOG
	|| (ltyp == DRAWBRIDGE_UP
	    && (lev->locations[x][y].drawbridgemask & DB_UNDER) == DB_BOG)) return TRUE;
    return FALSE;
}
Пример #19
0
int check(char s[])
{
	for(int i=0; s[i]; i++)
		if(!isok(s[i]))
			return 0;
	len=strlen(s);
	memset(dp,-1,sizeof(dp));
	if(dfs(0,0))
		return 1;
	return 0;
}
Пример #20
0
boolean
is_ice(int x, int y)
{
    schar ltyp;

    if (!isok(x,y)) return FALSE;
    ltyp = levl[x][y].typ;
    if (ltyp == ICE
            || (ltyp == DRAWBRIDGE_UP
                && (levl[x][y].drawbridgemask & DB_UNDER) == DB_ICE)) return TRUE;
    return FALSE;
}
Пример #21
0
boolean
is_lava(int x, int y)
{
    schar ltyp;

    if (!isok(x,y)) return FALSE;
    ltyp = levl[x][y].typ;
    if (ltyp == LAVAPOOL
            || (ltyp == DRAWBRIDGE_UP
                && (levl[x][y].drawbridgemask & DB_UNDER) == DB_LAVA)) return TRUE;
    return FALSE;
}
Пример #22
0
STATIC_OVL boolean
iswall_or_stone(int x, int y)
{
    register int type;

    /* out of bounds = stone */
    if (!isok(x,y)) return TRUE;

    type = levl[x][y].typ;
    return (type == STONE || IS_WALL(type) || IS_DOOR(type) ||
            type == SDOOR || type == IRONBARS);
}
Пример #23
0
STATIC_OVL boolean
rm_waslit()
{
    register xchar x, y;

    if(levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit)
	return(TRUE);
    for(x = u.ux-2; x < u.ux+3; x++)
	for(y = u.uy-1; y < u.uy+2; y++)
	    if(isok(x,y) && levl[x][y].waslit) return(TRUE);
    return(FALSE);
}
Пример #24
0
bool 
nexttodoor (int sx, int sy)
{
        int dx, dy;
        struct rm *lev;
        for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) {
                if(!isok(sx+dx, sy+dy)) continue;
                if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
                    lev->typ == SDOOR)
                        return(true);
        }
        return(false);
}
Пример #25
0
double
Divide::eval(const Metric::IData& mdata) const
{
  double n = m_numerator->eval(mdata);
  double d = m_denominator->eval(mdata);

  double z = c_FP_NAN_d;
  if (isok(d) && d != 0.0) {
    z = n / d;
  }

  AEXPR_CHECK(z);
  return z;
}
Пример #26
0
boolean
is_pool(struct level *lev, int x, int y)
{
    schar ltyp;

    if (!isok(x, y))
        return FALSE;
    ltyp = lev->locations[x][y].typ;
    /* The ltyp == MOAT is not redundant to is_moat due to drawbridges and the
       Juiblex level. There is probably a better way to express this. */
    if (ltyp == POOL || ltyp == WATER || ltyp == MOAT || is_moat(lev, x, y))
        return TRUE;
    return FALSE;
}
Пример #27
0
boolean
is_moat(struct level * lev, int x, int y)
{
    schar ltyp;

    if (!isok(x, y))
        return FALSE;
    ltyp = lev->locations[x][y].typ;
    if (!Is_juiblex_level(&lev->z) &&
        (ltyp == MOAT ||
         (ltyp == DRAWBRIDGE_UP &&
          (lev->locations[x][y].drawbridgemask & DB_UNDER) == DB_MOAT)))
        return TRUE;
    return FALSE;
}
Пример #28
0
boolean
nexttodoor(struct level * lev, int sx, int sy)
{
    int dx, dy;
    struct rm *loc;

    for (dx = -1; dx <= 1; dx++)
        for (dy = -1; dy <= 1; dy++) {
            if (!isok(sx + dx, sy + dy))
                continue;
            if (IS_DOOR((loc = &lev->locations[sx + dx][sy + dy])->typ) ||
                loc->typ == SDOOR)
                return TRUE;
        }
    return FALSE;
}
Пример #29
0
/* "Chained" explosions, used by skilled wand users
   FIXME: make skilled casting of fireball/cone of cold use this */
void
chain_explode(int x, int y, int type,
              int dam, char olet, int expltype,
              const char *descr, int raylevel, int amount)
{
    int ex = x;
    int ey = y;
    while (amount--) {
        ex = x + rnd(3) - 2;
        ey = y + rnd(3) - 2;
        if (!isok(ex, ey) || IS_STWALL(level->locations[ex][ey].typ)) {
            ex = x;
            ey = y;
        }
        explode(ex, ey, type, dam, olet, expltype, descr, raylevel);
    }
}
Пример #30
0
/*
 *	If we have drawn a map without walls, this allows us to
 *	auto-magically wallify it.  Taken from lev_main.c.
 */
STATIC_OVL void
wallify_map(void)
{

    int x, y, xx, yy;

    for(x = 1; x < COLNO; x++)
        for(y = 0; y < ROWNO; y++)
            if(levl[x][y].typ == STONE) {
                for(yy = y - 1; yy <= y+1; yy++)
                    for(xx = x - 1; xx <= x+1; xx++)
                        if(isok(xx,yy) && levl[xx][yy].typ == ROOM) {
                            if(yy != y)	levl[x][y].typ = HWALL;
                            else	levl[x][y].typ = VWALL;
                        }
            }
}