Exemple #1
0
//	-----------------------------------------------------------------------------
//	Return true if ok for buddy to talk, else return false.
//	Buddy is allowed to talk if the segment he is in does not contain a blastable wall that has not been blasted
//	AND he has never yet, since being initialized for level, been allowed to talk.
int BuddyMayTalk(void)
{
	int		i;
	segment	*segp;

	if (gameData.objs.objects[gameData.escort.nObjNum].type != OBJ_ROBOT) {
		gameData.escort.bMayTalk = 0;
		return 0;
	}

	if (gameData.escort.bMayTalk)
		return 1;

	if ((gameData.objs.objects[gameData.escort.nObjNum].type == OBJ_ROBOT) && 
		(gameData.escort.nObjNum <= gameData.objs.nLastObject) && 
		!gameData.bots.pInfo[gameData.objs.objects[gameData.escort.nObjNum].id].companion) {
		for (i=0; i<=gameData.objs.nLastObject; i++)
			if (gameData.bots.pInfo[gameData.objs.objects[i].id].companion)
				break;
		if (i > gameData.objs.nLastObject)
			return 0;
		else
			gameData.escort.nObjNum = i;
	}

	segp = gameData.segs.segments + gameData.objs.objects[gameData.escort.nObjNum].segnum;

	for (i=0; i<MAX_SIDES_PER_SEGMENT; i++) {
		short	wall_num = WallNumP (segp, (short) i);

		if (IS_WALL (wall_num)) {
			if ((gameData.walls.walls[wall_num].type == WALL_BLASTABLE) && 
				!(gameData.walls.walls[wall_num].flags & WALL_BLASTED))
				return 0;
		}

		//	Check one level deeper.
		if (IS_CHILD(segp->children[i])) {
			int		j;
			segment	*csegp = &gameData.segs.segments[segp->children[i]];

			for (j=0; j<MAX_SIDES_PER_SEGMENT; j++) {
				short	wall2 = WallNumP (csegp, (short) j);

				if (IS_WALL (wall2)) {
					if ((gameData.walls.walls[wall2].type == WALL_BLASTABLE) && !(gameData.walls.walls[wall2].flags & WALL_BLASTED))
						return 0;
				}
			}
		}
	}

	gameData.escort.bMayTalk = 1;
	return 1;
}
Exemple #2
0
//-----------------------------------------------------------------
// Opens a door
void CSegment::OpenDoor (int nSide)
{
CWall* wallP;
if (!(wallP = Wall (nSide)))
	return;

CActiveDoor* doorP;
if (!(doorP = wallP->OpenDoor ()))
	return;

	short			nConnSide, nConnWall = NO_WALL;
	CSegment		*connSegP;
// So that door can't be shot while opening
if (m_children [nSide] < 0) {
	if (gameOpts->legacy.bWalls)
		Warning (TXT_OPEN_SINGLE, this - SEGMENTS, nSide, WallNum (nSide));
	connSegP = NULL;
	nConnSide = -1;
	nConnWall = NO_WALL;
	}
else {
	connSegP = SEGMENTS + m_children [nSide];
	nConnSide = ConnectedSide (connSegP);
	if (nConnSide >= 0) {
		CWall* wallP = connSegP->Wall (nConnSide);
		if (wallP)
			wallP->state = WALL_DOOR_OPENING;
		}
	}

//KillStuckObjects(WallNumP (connSegP, nConnSide));
doorP->nFrontWall [0] = WallNum (nSide);
doorP->nBackWall [0] = nConnWall;
Assert(SEG_IDX (this) != -1);
if (gameData.demo.nState == ND_STATE_RECORDING)
	NDRecordDoorOpening (SEG_IDX (this), nSide);
if (IS_WALL (wallP->nLinkedWall) && IS_WALL (nConnWall) && (wallP->nLinkedWall == nConnWall)) {
	CWall *linkedWallP = WALLS + wallP->nLinkedWall;
	CSegment *linkedSegP = SEGMENTS + linkedWallP->nSegment;
	linkedWallP->state = WALL_DOOR_OPENING;
	connSegP = SEGMENTS + linkedSegP->m_children [linkedWallP->nSide];
	if (IS_WALL (nConnWall))
		WALLS [nConnWall].state = WALL_DOOR_OPENING;
	doorP->nPartCount = 2;
	doorP->nFrontWall [1] = wallP->nLinkedWall;
	doorP->nBackWall [1] = linkedSegP->ConnectedSide (connSegP);
	}
else
	doorP->nPartCount = 1;
if (gameData.demo.nState != ND_STATE_PLAYBACK) {
	if (gameData.walls.animP [wallP->nClip].openSound > -1)
		CreateSound (gameData.walls.animP [wallP->nClip].openSound, nSide);
	}
}
Exemple #3
0
tRgbaColorf *ColoredSegmentColor (int nSegment, int nSide, char nColor)
{
	short nConnSeg;
	int	owner;
	int	special;

if (nColor > 0)
	nColor--;
else {
	if ((gameData.app.nGameMode & GM_ENTROPY) && (extraGameInfo [1].entropy.nOverrideTextures == 2) &&
		((owner = SEGMENTS [nSegment].m_owner) > 0)) {
		nConnSeg = SEGMENTS [nSegment].m_children [nSide];
		if ((nConnSeg >= 0) && (SEGMENTS [nConnSeg].m_owner == owner))
			return NULL;
		nColor = (owner == 1);
		}
	special = SEGMENTS [nSegment].m_nType;
	if (special == SEGMENT_IS_WATER)
		nColor = 2;
	else if (special == SEGMENT_IS_LAVA)
		nColor = 3;
	else
		return NULL;
	nConnSeg = SEGMENTS [nSegment].m_children [nSide];
	if (nConnSeg >= 0) {
		if (special == SEGMENTS [nConnSeg].m_nType)
			return NULL;
		if (IS_WALL (SEGMENTS [nSegment].WallNum (nSide)))
			return NULL;
		}
	}
return segmentColors + nColor;
}
Exemple #4
0
const char *ceiling(int x, int y)
{
	struct rm *loc = &level->locations[x][y];
	const char *what;

	/* other room types will no longer exist when we're interested --
	 * see check_special_room()
	 */
	if (*in_rooms(level, x, y, VAULT))
	    what = "vault's ceiling";
	else if (*in_rooms(level, x, y, TEMPLE))
	    what = "temple's ceiling";
	else if (*in_rooms(level, x, y, SHOPBASE))
	    what = "shop's ceiling";
	else if (IS_AIR(loc->typ))
	    what = "sky";
	else if (Underwater)
	    what = "water's surface";
	else if ((IS_ROOM(loc->typ) && !Is_earthlevel(&u.uz)) ||
		 IS_WALL(loc->typ) || IS_DOOR(loc->typ) || loc->typ == SDOOR)
	    what = "ceiling";
	else
	    what = "rock above";

	return what;
}
Exemple #5
0
/*
 * Wall cleanup.  This function has two purposes: (1) remove walls that
 * are totally surrounded by stone - they are redundant.  (2) correct
 * the types so that they extend and connect to each other.
 */
void
wallification(int x1, int y1, int x2, int y2)
{
    uchar type;
    register int x,y;
    struct rm *lev;

    /* sanity check on incoming variables */
    if (x1<0 || x2>=COLNO || x1>x2 || y1<0 || y2>=ROWNO || y1>y2)
        panic("wallification: bad bounds (%d,%d) to (%d,%d)",x1,y1,x2,y2);

    /* Step 1: change walls surrounded by rock to rock. */
    for(x = x1; x <= x2; x++)
        for(y = y1; y <= y2; y++) {
            lev = &levl[x][y];
            type = lev->typ;
            if (IS_WALL(type) && type != DBWALL) {
                if (is_solid(x-1,y-1) &&
                        is_solid(x-1,y  ) &&
                        is_solid(x-1,y+1) &&
                        is_solid(x,  y-1) &&
                        is_solid(x,  y+1) &&
                        is_solid(x+1,y-1) &&
                        is_solid(x+1,y  ) &&
                        is_solid(x+1,y+1))
                    lev->typ = STONE;
            }
        }

    wall_extends(x1,y1,x2,y2);
}
Exemple #6
0
const char *surface(int x, int y)
{
	struct rm *loc = &level->locations[x][y];

	if ((x == u.ux) && (y == u.uy) && u.uswallow &&
		is_animal(u.ustuck->data))
	    return "maw";
	else if (IS_AIR(loc->typ) && Is_airlevel(&u.uz))
	    return "air";
	else if (is_pool(level, x, y))
	    return (Underwater && !Is_waterlevel(&u.uz)) ? "bottom" : "water";
	else if (is_ice(level, x, y))
	    return "ice";
	else if (is_lava(level, x, y))
	    return "lava";
	else if (loc->typ == DRAWBRIDGE_DOWN)
	    return "bridge";
	else if (IS_ALTAR(level->locations[x][y].typ))
	    return "altar";
	else if (IS_GRAVE(level->locations[x][y].typ))
	    return "headstone";
	else if (IS_FOUNTAIN(level->locations[x][y].typ))
	    return "fountain";
	else if ((IS_ROOM(loc->typ) && !Is_earthlevel(&u.uz)) ||
		 IS_WALL(loc->typ) || IS_DOOR(loc->typ) || loc->typ == SDOOR)
	    return "floor";
	else
	    return "ground";
}
static void
finish_map(struct level *lev, schar fg_typ, schar bg_typ, boolean lit,
           boolean walled)
{
    int i, j;

    if (walled)
        wallify_map(lev);

    if (lit) {
        for (i = 0; i < COLNO; i++)
            for (j = 0; j < ROWNO; j++)
                if ((!IS_ROCK(fg_typ) && lev->locations[i][j].typ == fg_typ) ||
                    (!IS_ROCK(bg_typ) && lev->locations[i][j].typ == bg_typ) ||
                    (bg_typ == TREE && lev->locations[i][j].typ == bg_typ) ||
                    (walled && IS_WALL(lev->locations[i][j].typ)))
                    lev->locations[i][j].lit = TRUE;
        for (i = 0; i < lev->nroom; i++)
            lev->rooms[i].rlit = 1;
    }
    /* light lava even if everything's otherwise unlit */
    for (i = 0; i < COLNO; i++)
        for (j = 0; j < ROWNO; j++)
            if (lev->locations[i][j].typ == LAVAPOOL)
                lev->locations[i][j].lit = TRUE;
}
Exemple #8
0
int CountLights (void)
{
	int		nLights = 0;
	short		segNum, sideNum; 
	tSegment	*segP;
	tSide		*sideP;

if (!(gameOpts->render.color.bUseLightMaps && gameStates.render.color.bLightMapsOk))
	return 0;
#ifdef _DEBUG
memset (sideFlags, 0, sizeof (sideFlags)); 
#endif
for (segNum = 0, segP = gameData.segs.segments; 
	  segNum <= gameData.segs.nLastSegment; 
	  segNum++, segP++) {
	for (sideNum = 0, sideP = segP->sides; sideNum < 6; sideNum++, sideP++) {
#if TEXTURE_CHECK
		if ((gameData.segs.segments [segNum].children [sideNum] >= 0) && 
			 !IS_WALL (WallNumI (segNum, sideNum)))
			continue; 	//skip open sides
#endif
		if (IsLight (sideP->nBaseTex) || IsLight (sideP->nOvlTex) ||
			 (gameStates.app.bD2XLevel && gameData.render.color.lights [segNum * 6 + sideNum].index)) {
			nLights++;
#ifdef _DEBUG
			sideFlags [segNum * 6 + sideNum] = 1; 
#endif
			}
		}
	}	
return nLights; 
}
Exemple #9
0
static double	chck_verti_inters(t_env *env, double angl)
{
	double		x;
	double		y;
	double		x_plus;
	double		y_plus;

	x = (int)(POS_X / BOX_SZE);
	x = ANGL_LEFT ? x * BOX_SZE - 1 : (x + 1) * BOX_SZE;
	y = POS_Y + (POS_X - x) * tan(angl);
	y_plus = ANGL_HORIZ ? 0 : BOX_SZE * tan(angl);
	y_plus *= ANGL_LEFT ? 1 : -1;
	x_plus = ANGL_VERTI ? 0 : BOX_SZE;
	x_plus *= ANGL_LEFT ? -1 : 1;
	while (WITHIN_MAP && !IS_WALL(x, y))
	{
		x += x_plus;
		y += y_plus;
	}
	if (!WITHIN_MAP)
		return (MAX_WDT);
	angl = sqrt(pow(POS_X - x, 2) + pow(POS_Y - y, 2));
	angl = (angl > MAX_WDT) ? MAX_WDT : angl;
	return (angl);
}
Exemple #10
0
static double	chck_horiz_inters(t_env *env, double angl)
{
	double		x;
	double		y;
	double		x_plus;
	double		y_plus;

	y = (int)(POS_Y / BOX_SZE);
	y = ANGL_UP ? y * BOX_SZE - 1 : (y + 1) * BOX_SZE;
	x = POS_X + (POS_Y - y) / tan(angl);
	x_plus = ANGL_VERTI ? 0 : BOX_SZE / tan(angl);
	x_plus *= ANGL_UP ? 1 : -1;
	y_plus = ANGL_HORIZ ? 0 : BOX_SZE;
	y_plus *= ANGL_UP ? -1 : 1;
	while (WITHIN_MAP && !IS_WALL(x, y))
	{
		x += x_plus;
		y += y_plus;
	}
	if (!WITHIN_MAP)
		return (MAX_HGT);
	angl = sqrt(pow(POS_X - x, 2) + pow(POS_Y - y, 2));
	angl = (angl > MAX_HGT) ? MAX_HGT : angl;
	return (angl);
}
Exemple #11
0
void SokobanState::CalcCost()
{
	// TODO: Test if there exists a bipartite matching of goals and boxes

	// For every goal previously reachable by this box,
	// make sure there still is some box that can reach the goal
	int goals_left = (1<<num_boxes)-1;
	for (int i = 0; i < num_boxes; ++i)
	{
		// Add the boxes reachable from this position to the list of reachable goals
		goals_left &= ~(scribble->GoalsReachable(boxes[i]));
		if (goals_left == 0)
			break;
	}

	// If there is a goal we cant reach with any box, the state is useless
	if (goals_left != 0)
	{
		cost = unsigned(-1);
		return;
	}

    cost = 0;
    for (int i = 0; i < num_boxes; ++i)
    {
        int pos_cost = POSCOST(boxes[i]);
		if (pos_cost < 0)
		{
			cost = unsigned(-1);
			return;
		}
        if (pos_cost > 0)
            cost += pos_cost + 100;
		else
		{
			// Make goals next to walls slightly more attractive
			if (!IS_WALL(boxes[i]))
				cost += 1;
			for (int j=0; j<4; j++)
			{
				if (!IS_WALL(boxes[i]+forward[j]))
					cost += 1;
			}
		}
    }
}
Exemple #12
0
// start the transition from closed -> open CWall
void CSegment::StartCloak (int nSide)
{
if (gameData.demo.nState == ND_STATE_PLAYBACK)
	return;

CWall* wallP = Wall (nSide);
if (!wallP)
	return;

if (wallP->nType == WALL_OPEN || wallP->state == WALL_DOOR_CLOAKING)		//already open or cloaking
	return;

	CCloakingWall*	cloakWallP;
	CSegment*		connSegP;
	short				nConnSide;
	int				i;
	short				nConnWall;


connSegP = SEGMENTS + m_children [nSide];
nConnSide = ConnectedSide (connSegP);

if (!(cloakWallP = wallP->StartCloak ())) {
	wallP->nType = WALL_OPEN;
	if ((wallP = connSegP->Wall (nConnSide)))
		wallP->nType = WALL_OPEN;
	return;
	}

nConnWall = connSegP->WallNum (nConnSide);
if (IS_WALL (nConnWall))
	WALLS [nConnWall].state = WALL_DOOR_CLOAKING;
cloakWallP->nFrontWall = WallNum (nSide);
cloakWallP->nBackWall = nConnWall;
Assert(SEG_IDX (this) != -1);
//Assert(!IS_WALL (wallP->nLinkedWall));
if (gameData.demo.nState != ND_STATE_PLAYBACK) {
	CreateSound (SOUND_WALL_CLOAK_ON, nSide);
	}
for (i = 0; i < 4; i++) {
	cloakWallP->front_ls [i] = m_sides [nSide].m_uvls [i].l;
	if (IS_WALL (nConnWall))
		cloakWallP->back_ls [i] = connSegP->m_sides [nConnSide].m_uvls [i].l;
	}
}
Exemple #13
0
bool RenderWallFace (CSegment *segP, CSegFace *faceP, int bDepthOnly)
{
if (!(faceP->widFlags & WID_RENDER_FLAG))
	return false;
if (!IS_WALL (faceP->nWall))
	return false;
LoadFaceBitmaps (segP, faceP);
g3FaceDrawer (faceP, faceP->bmBot, faceP->bmTop, (faceP->nCamera < 0) || faceP->bTeleport, !bDepthOnly && faceP->bTextured, bDepthOnly);
return true;
}
Exemple #14
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);
}
Exemple #15
0
void
wall_extends(int x1, int y1, int x2, int y2)
{
    uchar type;
    register int x,y;
    struct rm *lev;
    int bits;
    int locale[3][3];	/* rock or wall status surrounding positions */

    /*
     * Value 0 represents a free-standing wall.  It could be anything,
     * so even though this table says VWALL, we actually leave whatever
     * typ was there alone.
     */
    static xchar spine_array[16] = {
        VWALL,	HWALL,		HWALL,		HWALL,
        VWALL,	TRCORNER,	TLCORNER,	TDWALL,
        VWALL,	BRCORNER,	BLCORNER,	TUWALL,
        VWALL,	TLWALL,		TRWALL,		CROSSWALL
    };

    /* sanity check on incoming variables */
    if (x1<0 || x2>=COLNO || x1>x2 || y1<0 || y2>=ROWNO || y1>y2)
        panic("wall_extends: bad bounds (%d,%d) to (%d,%d)",x1,y1,x2,y2);

    for(x = x1; x <= x2; x++)
        for(y = y1; y <= y2; y++) {
            lev = &levl[x][y];
            type = lev->typ;
            if ( !(IS_WALL(type) && type != DBWALL)) continue;

            /* set the locations TRUE if rock or wall or out of bounds */
            locale[0][0] = iswall_or_stone(x-1,y-1);
            locale[1][0] = iswall_or_stone(  x,y-1);
            locale[2][0] = iswall_or_stone(x+1,y-1);

            locale[0][1] = iswall_or_stone(x-1,  y);
            locale[2][1] = iswall_or_stone(x+1,  y);

            locale[0][2] = iswall_or_stone(x-1,y+1);
            locale[1][2] = iswall_or_stone(  x,y+1);
            locale[2][2] = iswall_or_stone(x+1,y+1);

            /* determine if wall should extend to each direction NSEW */
            bits =    (extend_spine(locale, iswall(x,y-1),  0, -1) << 3)
                      | (extend_spine(locale, iswall(x,y+1),  0,  1) << 2)
                      | (extend_spine(locale, iswall(x+1,y),  1,  0) << 1)
                      |  extend_spine(locale, iswall(x-1,y), -1,  0);

            /* don't change typ if wall is free-standing */
            if (bits) lev->typ = spine_array[bits];
        }
}
Exemple #16
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);
}
Exemple #17
0
//-----------------------------------------------------------------
// Closes a door
void CSegment::CloseDoor (int nSide)
{
	CWall*	wallP;

if (!(wallP = Wall (nSide)))
	return;
if ((wallP->state == WALL_DOOR_CLOSING) ||		//already closing
	 (wallP->state == WALL_DOOR_WAITING) ||		//open, waiting to close
	 (wallP->state == WALL_DOOR_CLOSED))			//closed
	return;
if (DoorIsBlocked (nSide))
	return;

	CActiveDoor*	doorP;

if (!(doorP = wallP->CloseDoor ()))
	return;

	CSegment*		connSegP;
	short				nConnSide, nConnWall;

connSegP = SEGMENTS + m_children [nSide];
nConnSide = ConnectedSide (connSegP);
nConnWall = connSegP->WallNum (nConnSide);
if (IS_WALL (nConnWall))
	WALLS [nConnWall].state = WALL_DOOR_CLOSING;
doorP->nFrontWall [0] = WallNum (nSide);
doorP->nBackWall [0] = nConnWall;
Assert(SEG_IDX (this) != -1);
if (gameData.demo.nState == ND_STATE_RECORDING)
	NDRecordDoorOpening (SEG_IDX (this), nSide);
if (IS_WALL (wallP->nLinkedWall))
	Int3();		//don't think we ever used linked walls
else
	doorP->nPartCount = 1;
if (gameData.demo.nState != ND_STATE_PLAYBACK) {
	if (gameData.walls.animP [wallP->nClip].openSound > -1)
		CreateSound (gameData.walls.animP [wallP->nClip].openSound, nSide);
	}
}
Exemple #18
0
// ----------------------------------------------------------------------------
void write_wall_text(FILE *my_file)
{
	int	i, j;
	byte	wallFlags[MAX_WALLS];
	tSegment *segp;
	tSide *sideP;
	tWall	*wallP;

	fprintf(my_file, "-----------------------------------------------------------------------------\n");
	fprintf(my_file, "gameData.walls.walls:\n");
	for (i=0, wallP = gameData.walls.walls; i<gameData.walls.nWalls; i++, wallP++) {
		int	nSegment, nSide;

		fprintf(my_file, 
			"Wall %03i: seg=%3i, tSide=%2i, nLinkedWall=%3i, nType=%s, flags=%4x, hps=%3i, tTrigger=%2i, nClip=%2i, keys=%2i, state=%i\n", i,
			wallP->nSegment, 
			wallP->nSide, 
			wallP->nLinkedWall, 
			pszWallNames[wallP->nType], 
			wallP->flags, wallP->hps >> 16, 
			wallP->nTrigger, 
			wallP->nClip, 
			wallP->keys, 
			wallP->state);

		if (wallP->nTrigger >= gameData.trigs.nTriggers)
			fprintf(my_file, "Wall %03d points to invalid tTrigger %d\n",i,wallP->nTrigger);

		nSegment = wallP->nSegment;
		nSide = wallP->nSide;

		if (WallNumI (nSegment, nSide) != i)
			err_printf(my_file, "Error: Wall %i points at tSegment %i, tSide %i, but that tSegment doesn't point back (it's nWall = %i)\n", 
							i, nSegment, nSide, WallNumI (nSegment, nSide));
	}

	for (i=0; i<MAX_WALLS; i++)
		wallFlags[i] = 0;

	for (i=0, segp = gameData.segs.segments; i<=gameData.segs.nLastSegment; i++, segp++) {
		for (j=0, sideP = segp->sides; j<MAX_SIDES_PER_SEGMENT; j++, sideP++) {
			short nWall = WallNumP (sideP);
			if (IS_WALL (nWall))
				if (wallFlags[nWall])
					err_printf(my_file, "Error: Wall %i appears in two or more segments, including tSegment %i, tSide %i.\n", sideP->nWall, i, j);
				else
					wallFlags[nWall] = 1;
		}
	}

}
Exemple #19
0
static int describe_object(int x, int y, int votyp, char *buf)
{
    int num_objs = 0;
    struct obj *otmp;
    if (votyp == -1)
	return -1;
    
    otmp = vobj_at(x,y);
    
    if (!otmp || otmp->otyp != votyp) {
	if (votyp != STRANGE_OBJECT) {
	    otmp = mksobj(level, votyp, FALSE, FALSE);
	    if (otmp->oclass == COIN_CLASS)
		otmp->quan = 1L; /* to force pluralization off */
	    else if (otmp->otyp == SLIME_MOLD)
		otmp->spe = current_fruit;	/* give the fruit a type */
	    strcpy(buf, distant_name(otmp, xname));
	    dealloc_obj(otmp);
	    otmp = vobj_at(x,y); /* make sure we don't point to the temp obj any more */
	}
    } else
	strcpy(buf, distant_name(otmp, xname));
    
    if (level->locations[x][y].typ == STONE || level->locations[x][y].typ == SCORR)
	strcat(buf, " embedded in stone");
    else if (IS_WALL(level->locations[x][y].typ) || level->locations[x][y].typ == SDOOR)
	strcat(buf, " embedded in a wall");
    else if (closed_door(level, x,y))
	strcat(buf, " embedded in a door");
    else if (is_pool(level, x,y))
	strcat(buf, " in water");
    else if (is_lava(level, x,y))
	strcat(buf, " in molten lava");	/* [can this ever happen?] */
    
    if (!cansee(x, y))
	return -1; /* don't disclose the number of objects for location out of LOS */
    
    if (!otmp)
	/* There is no object here. Since the player sees one it must be a mimic */
	return 1;
    
    if (otmp->otyp != votyp)
	/* Hero sees something other than the actual top object. Probably a mimic */
	num_objs++;
    
    for ( ; otmp; otmp = otmp->nexthere)
	num_objs++;
    
    return num_objs;
}
Exemple #20
0
boolean
create_drawbridge(struct level *lev, int x, int y, int dir, boolean flag)
{
    int x2, y2;
    boolean horiz;
    boolean lava = lev->locations[x][y].typ == LAVAPOOL; /* assume initialized
                                                            map */

    x2 = x;
    y2 = y;
    switch (dir) {
    case DB_NORTH:
        horiz = TRUE;
        y2--;
        break;
    case DB_SOUTH:
        horiz = TRUE;
        y2++;
        break;
    case DB_EAST:
        horiz = FALSE;
        x2++;
        break;
    default:
        impossible("bad direction in create_drawbridge");
        /* fall through */
    case DB_WEST:
        horiz = FALSE;
        x2--;
        break;
    }
    if (!IS_WALL(lev->locations[x2][y2].typ))
        return FALSE;
    if (flag) { /* We want the bridge open */
        lev->locations[x][y].typ = DRAWBRIDGE_DOWN;
        lev->locations[x2][y2].typ = DOOR;
        lev->locations[x2][y2].doormask = D_NODOOR;
    } else {
        lev->locations[x][y].typ = DRAWBRIDGE_UP;
        lev->locations[x2][y2].typ = DBWALL;
        /* Drawbridges are non-diggable. */
        lev->locations[x2][y2].wall_info = W_NONDIGGABLE;
    }
    lev->locations[x][y].horizontal = !horiz;
    lev->locations[x2][y2].horizontal = horiz;
    lev->locations[x][y].drawbridgemask = dir;
    if (lava)
        lev->locations[x][y].drawbridgemask |= DB_LAVA;
    return TRUE;
}
Exemple #21
0
int RenderWall (tFaceProps *propsP, g3sPoint **pointList, int bIsMonitor)
{
	short c, nWallNum = SEGMENTS [propsP->segNum].WallNum (propsP->sideNum);
	static tRgbaColorf cloakColor = {0, 0, 0, -1};

if (IS_WALL (nWallNum)) {
	if (propsP->widFlags & (WID_CLOAKED_FLAG | WID_TRANSPARENT_FLAG)) {
		if (!bIsMonitor) {
			if (!RenderColoredSegFace (propsP->segNum, propsP->sideNum, propsP->nVertices, pointList)) {
				c = WALLS [nWallNum].cloakValue;
				if (propsP->widFlags & WID_CLOAKED_FLAG) {
					if (c < FADE_LEVELS) {
						gameStates.render.grAlpha = GrAlpha (ubyte (c));
						G3DrawPolyAlpha (propsP->nVertices, pointList, &cloakColor, 1, propsP->segNum);		//draw as flat poly
						}
					}
				else {
					if (!gameOpts->render.color.bWalls)
						c = 0;
					if (WALLS [nWallNum].hps)
						gameStates.render.grAlpha = float (WALLS [nWallNum].hps) / float (I2X (100));
					else if (IsMultiGame && gameStates.app.bHaveExtraGameInfo [1])
						gameStates.render.grAlpha = COMPETITION ? 2.0f / 3.0f : GrAlpha (FADE_LEVELS - extraGameInfo [1].grWallTransparency);
					else
						gameStates.render.grAlpha = GrAlpha (ubyte (FADE_LEVELS - extraGameInfo [0].grWallTransparency));
					if (gameStates.render.grAlpha < 1.0f) {
						tRgbaColorf wallColor;
						
						paletteManager.Game ()->ToRgbaf ((ubyte) c, wallColor); 
						G3DrawPolyAlpha (propsP->nVertices, pointList, &wallColor, 1, propsP->segNum);	//draw as flat poly
						}
					}
				}
			gameStates.render.grAlpha = 1.0f;
			return 1;
			}
		}
	else if (gameStates.app.bD2XLevel) {
		c = WALLS [nWallNum].cloakValue;
		if (c && (c < FADE_LEVELS))
			gameStates.render.grAlpha = GrAlpha (FADE_LEVELS - c);
		}
	else if (gameOpts->render.effects.bAutoTransparency && IsTransparentFace (propsP))
		gameStates.render.grAlpha = 0.8f;
	else
		gameStates.render.grAlpha = 1.0f;
	}
return 0;
}
Exemple #22
0
bool 
somexy (struct mkroom *croom, coord *c)
{
        int try_cnt = 0;
        int i;

        if (croom->irregular) {
            i = (croom - rooms) + ROOMOFFSET;

            while(try_cnt++ < 100) {
                c->x = somex(croom);
                c->y = somey(croom);
                if (!levl[c->x][c->y].edge &&
                        (int) levl[c->x][c->y].roomno == i)
                    return true;
            }
            /* try harder; exhaustively search until one is found */
            for(c->x = croom->lx; c->x <= croom->hx; c->x++)
                for(c->y = croom->ly; c->y <= croom->hy; c->y++)
                    if (!levl[c->x][c->y].edge &&
                            (int) levl[c->x][c->y].roomno == i)
                        return true;
            return false;
        }

        if (!croom->nsubrooms) {
                c->x = somex(croom);
                c->y = somey(croom);
                return true;
        }

        /* Check that coords doesn't fall into a subroom or into a wall */

        while(try_cnt++ < 100) {
                c->x = somex(croom);
                c->y = somey(croom);
                if (IS_WALL(levl[c->x][c->y].typ))
                    continue;
                for(i=0 ; i<croom->nsubrooms;i++)
                    if(inside_room(croom->sbrooms[i], c->x, c->y))
                        goto you_lose;
                break;
you_lose:       ;
        }
        if (try_cnt >= 100)
            return false;
        return true;
}
Exemple #23
0
//-----------------------------------------------------------------
// Deteriorate appearance of CWall. (Changes bitmap (paste-ons))
void CSegment::DamageWall (int nSide, fix damage)
{
	int		a, i, n;
	short		nConnSide, nConnWall;
	CWall		*wallP = Wall (nSide);
	CSegment *connSegP;

if (!wallP) {
#if TRACE
	console.printf (CON_DBG, "Damaging illegal CWall\n");
#endif
	return;
	}
if (wallP->nType != WALL_BLASTABLE)
	return;
if ((wallP->flags & WALL_BLASTED) || (wallP->hps < 0))
	return;

if (m_children [nSide] < 0) {
	if (gameOpts->legacy.bWalls)
		Warning (TXT_DMG_SINGLE, this - SEGMENTS, nSide, wallP - WALLS);
	connSegP = NULL;
	nConnSide = -1;
	nConnWall = NO_WALL;
	}
else {
	connSegP = SEGMENTS + m_children [nSide];
	nConnSide = ConnectedSide (connSegP);
	Assert(nConnSide != -1);
	nConnWall = connSegP->WallNum (nConnSide);
	}
wallP->hps -= damage;
if (IS_WALL (nConnWall))
	WALLS [nConnWall].hps -= damage;
a = wallP->nClip;
n = AnimFrameCount (gameData.walls.animP + a);
if (wallP->hps < WALL_HPS * 1 / n) {
	BlastWall (nSide);
	if (IsMultiGame)
		MultiSendDoorOpen (SEG_IDX (this), nSide, wallP->flags);
	}
else {
	for (i = 0; i < n; i++)
		if (wallP->hps < WALL_HPS * (n - i) / n)
			SetTexture (nSide, connSegP, nConnSide, a, i);
	}
}
Exemple #24
0
int		ft_trans_to_print(int pos, t_map *map, int pos_col, int pos_row)
{
    if (pos_col == map->entrance_x && pos_row == map->entrance_y)
        ft_putchar(map->entrance);
    else if (IS_WALL(pos))
        ft_putchar(map->wall);
    else if (IS_EXIT(pos))
        ft_putchar(map->exit);
    else if (IS_SPACE(pos))
        ft_putchar(map->space);
    else if (IS_PATH(pos))
        ft_putchar(map->path);
    else
    {
        map->error = UNRECOGNISED_MAP_CHAR;
        return (0);
    }
    return (1);
}
Exemple #25
0
/* SpawnChildren creates new states from possible moves
 * Tries to push each box in every straight direction several steps
 * making sure the moves are valid.
 */
void SokobanState::SpawnChildren(std::vector<SokobanState*> &moves_to_add) const
{
	PrepareScribble();

	#ifdef VERBOSE_DEBUG
	Print();
	#endif

    // Try to push all boxes from every direction
    for (int i = 0; i < num_boxes; ++i)
    {
    	if (IS_WALL(boxes[i]))
    	{
    		PRINT_VERBOSE("disregards moving box %d because it is locked\n", i);
			continue;
    	}

    	SpawnChildrenFrom(i, moves_to_add);
    }
}
Exemple #26
0
// -----------------------------------------------------------------------------
//go through all triggers, killing unused ones
static void CheckAndFixTriggers (void)
{
	int	i, j;
	short	nSegment, nSide, nWall;

for (i = 0; i < gameData.trigs.m_nTriggers; ) {
	//	Find which CWall this CTrigger is connected to.
	for (j = 0; j < gameData.walls.nWalls; j++)
		if (WALLS [j].nTrigger == i)
			break;
		i++;
	}

for (i = 0; i < gameData.walls.nWalls; i++)
	WALLS [i].controllingTrigger = -1;

//	MK, 10/17/95: Make walls point back at the triggers that control them.
//	Go through all triggers, stuffing controllingTrigger field in WALLS.

CTrigger* trigP = TRIGGERS.Buffer ();
for (i = 0; i < gameData.trigs.m_nTriggers; i++, trigP++) {
	for (j = 0; j < trigP->m_info.nLinks; j++) {
		nSegment = trigP->m_info.segments [j];
		nSide = trigP->m_info.sides [j];
		nWall = SEGMENTS [nSegment].WallNum (nSide);
		//check to see that if a CTrigger requires a CWall that it has one,
		//and if it requires a botGen that it has one
		if (trigP->m_info.nType == TT_MATCEN) {
			if (SEGMENTS [nSegment].m_nType != SEGMENT_IS_ROBOTMAKER)
				continue;		//botGen CTrigger doesn'i point to botGen
			}
		else if ((trigP->m_info.nType != TT_LIGHT_OFF) && (trigP->m_info.nType != TT_LIGHT_ON)) { //light triggers don't require walls
			if (IS_WALL (nWall))
				WALLS [nWall].controllingTrigger = i;
			else {
				Int3();	//	This is illegal.  This ttrigger requires a CWall
				}
			}
		}
	}
}
Exemple #27
0
static void
dosdoor(int x, int y, struct mkroom *aroom, int type)
{
	struct mkroom *broom;
	int tmp;

	if(!IS_WALL(levl[x][y].typ))	/* avoid SDOORs with '+' as scrsym */
		type = DOOR;
	levl[x][y].typ = type;
	if(type == DOOR)
		levl[x][y].scrsym = '+';
	aroom->doorct++;
	broom = aroom+1;
	if(broom->hx < 0) tmp = doorindex; else
	for(tmp = doorindex; tmp > broom->fdoor; tmp--)
		doors[tmp] = doors[tmp-1];
	doorindex++;
	doors[tmp].x = x;
	doors[tmp].y = y;
	for( ; broom->hx >= 0; broom++) broom->fdoor++;
}
Exemple #28
0
// -------------------------------------------------------------------------------
//when the CWall has used all its hitpoints, this will destroy it
void CSegment::BlastWall (int nSide)
{
	short			nConnSide;
	CSegment*	connSegP;
	int			a, n;
	short			nConnWall;
	CWall*		wallP = Wall (nSide);

if (!wallP)
	return;
wallP->hps = -1;	//say it's blasted
if (m_children [nSide] < 0) {
	if (gameOpts->legacy.bWalls)
		Warning (TXT_BLAST_SINGLE, this - SEGMENTS, nSide, wallP - WALLS);
	connSegP = NULL;
	nConnSide = -1;
	nConnWall = NO_WALL;
	}
else {
	connSegP = SEGMENTS + m_children [nSide];
	nConnSide = ConnectedSide (connSegP);
	Assert (nConnSide != -1);
	nConnWall = connSegP->WallNum (nConnSide);
	KillStuckObjects (nConnWall);
	}
KillStuckObjects (WallNum (nSide));

//if this is an exploding wall, explode it
if ((gameData.walls.animP [wallP->nClip].flags & WCF_EXPLODES) && !(wallP->flags & WALL_BLASTED))
	ExplodeWall (Index (), nSide);
else {
	//if not exploding, set final frame, and make door passable
	a = wallP->nClip;
	n = AnimFrameCount (gameData.walls.animP + a);
	SetTexture (nSide, connSegP, nConnSide, a, n - 1);
	wallP->flags |= WALL_BLASTED;
	if (IS_WALL (nConnWall))
		WALLS [nConnWall].flags |= WALL_BLASTED;
	}
}
/*
 * use a flooding algorithm to find all locations that should
 * have the same rm number as the current location.
 * if anyroom is TRUE, use IS_ROOM to check room membership instead of
 * exactly matching level->locations[sx][sy].typ and walls are included as well.
 */
void
flood_fill_rm(struct level *lev, int sx, int sy, int rmno, boolean lit,
              boolean anyroom)
{
    int i;
    int nx;
    schar fg_typ = lev->locations[sx][sy].typ;

    /* back up to find leftmost uninitialized location */
    while (sx >= 0 &&
           (anyroom ? IS_ROOM(lev->locations[sx][sy].typ) :
            lev->locations[sx][sy].typ == fg_typ) &&
           (int)lev->locations[sx][sy].roomno != rmno)
        sx--;
    sx++;       /* compensate for extra decrement */

    /* assume sx,sy is valid */
    if (sx < min_rx)
        min_rx = sx;
    if (sy < min_ry)
        min_ry = sy;

    for (i = sx; i <= WIDTH && lev->locations[i][sy].typ == fg_typ; i++) {
        lev->locations[i][sy].roomno = rmno;
        lev->locations[i][sy].lit = lit;
        if (anyroom) {
            /* add walls to room as well */
            int ii, jj;

            for (ii = (i == sx ? i - 1 : i); ii <= i + 1; ii++)
                for (jj = sy - 1; jj <= sy + 1; jj++)
                    if (isok(ii, jj) &&
                        (IS_WALL(lev->locations[ii][jj].typ) ||
                         IS_DOOR(lev->locations[ii][jj].typ))) {
                        lev->locations[ii][jj].edge = 1;
                        if (lit)
                            lev->locations[ii][jj].lit = lit;
                        if ((int)lev->locations[ii][jj].roomno != rmno)
                            lev->locations[ii][jj].roomno = SHARED;
                    }
        }
        n_loc_filled++;
    }
    nx = i;

    if (isok(sx, sy - 1)) {
        for (i = sx; i < nx; i++)
            if (lev->locations[i][sy - 1].typ == fg_typ) {
                if ((int)lev->locations[i][sy - 1].roomno != rmno)
                    flood_fill_rm(lev, i, sy - 1, rmno, lit, anyroom);
            } else {
                if ((i > sx || isok(i - 1, sy - 1)) &&
                    lev->locations[i - 1][sy - 1].typ == fg_typ) {
                    if ((int)lev->locations[i - 1][sy - 1].roomno != rmno)
                        flood_fill_rm(lev, i - 1, sy - 1, rmno, lit, anyroom);
                }
                if ((i < nx - 1 || isok(i + 1, sy - 1)) &&
                    lev->locations[i + 1][sy - 1].typ == fg_typ) {
                    if ((int)lev->locations[i + 1][sy - 1].roomno != rmno)
                        flood_fill_rm(lev, i + 1, sy - 1, rmno, lit, anyroom);
                }
            }
    }
    if (isok(sx, sy + 1)) {
        for (i = sx; i < nx; i++)
            if (lev->locations[i][sy + 1].typ == fg_typ) {
                if ((int)lev->locations[i][sy + 1].roomno != rmno)
                    flood_fill_rm(lev, i, sy + 1, rmno, lit, anyroom);
            } else {
                if ((i > sx || isok(i - 1, sy + 1)) &&
                    lev->locations[i - 1][sy + 1].typ == fg_typ) {
                    if ((int)lev->locations[i - 1][sy + 1].roomno != rmno)
                        flood_fill_rm(lev, i - 1, sy + 1, rmno, lit, anyroom);
                }
                if ((i < nx - 1 || isok(i + 1, sy + 1)) &&
                    lev->locations[i + 1][sy + 1].typ == fg_typ) {
                    if ((int)lev->locations[i + 1][sy + 1].roomno != rmno)
                        flood_fill_rm(lev, i + 1, sy + 1, rmno, lit, anyroom);
                }
            }
    }

    if (nx > max_rx)
        max_rx = nx - 1;        /* nx is just past valid region */
    if (sy > max_ry)
        max_ry = sy;
}
Exemple #30
0
int
gd_move()
{
	int x,y,dx,dy,gx,gy,nx,ny,typ;
	struct fakecorridor *fcp;
	struct rm *crm;

	if(!guard || gdlevel != dlevel){
		impossible("Where is the guard?");
		return(2);	/* died */
	}
	if(u.ugold || goldincorridor())
		return(0);	/* didnt move */
	if(dist(guard->mx,guard->my) > 1 || EGD->gddone) {
		restfakecorr();
		return(0);	/* didnt move */
	}
	x = guard->mx;
	y = guard->my;
	/* look around (hor & vert only) for accessible places */
	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
	    if(nx == x || ny == y) if(nx != x || ny != y)
	    if(isok(nx,ny))
	    if(!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
		int i;
		for(i = EGD->fcbeg; i < EGD->fcend; i++)
			if(EGD->fakecorr[i].fx == nx &&
			   EGD->fakecorr[i].fy == ny)
				goto nextnxy;
		if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
			goto nextnxy;
		/* seems we found a good place to leave him alone */
		EGD->gddone = 1;
		if(ACCESSIBLE(typ)) goto newpos;
		crm->typ = (typ == SCORR) ? CORR : DOOR;
		goto proceed;
	    }
    nextnxy:	;
	}
	nx = x;
	ny = y;
	gx = EGD->gdx;
	gy = EGD->gdy;
	dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
	dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
	if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;

	while((typ = (crm = &levl[nx][ny])->typ) != 0) {
	/* in view of the above we must have IS_WALL(typ) or typ == POOL */
	/* must be a wall here */
		if(isok(nx+nx-x,ny+ny-y) && typ != POOL &&
		    ZAP_POS(levl[nx+nx-x][ny+ny-y].typ)){
			crm->typ = DOOR;
			goto proceed;
		}
		if(dy && nx != x) {
			nx = x; ny = y+dy;
			continue;
		}
		if(dx && ny != y) {
			ny = y; nx = x+dx; dy = 0;
			continue;
		}
		/* I don't like this, but ... */
		crm->typ = DOOR;
		goto proceed;
	}
	crm->typ = CORR;
proceed:
	if(cansee(nx,ny)) {
		mnewsym(nx,ny);
		prl(nx,ny);
	}
	fcp = &(EGD->fakecorr[EGD->fcend]);
	if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
	fcp->fx = nx;
	fcp->fy = ny;
	fcp->ftyp = typ;
newpos:
	if(EGD->gddone) nx = ny = 0;
	guard->mx = nx;
	guard->my = ny;
	pmon(guard);
	restfakecorr();
	return(1);
}