//Uses a recursive method to elimate adjacent tiles of structure information.
//The code will attempt to delete the current mapindex, then search using this method:
//1) if there isn't structure info here, return.
//2) if there is structure info here, delete it now.
//3) KillBuilding at x-1, y.
//4) KillBuilding at x  , y-1.
//5) KillBuilding at x+1, y.
//6) KillBuilding at x  , y+1.
void KillBuilding( UINT32 iMapIndex )
{
	BOOLEAN fFound = FALSE;

	if( !gfBasement )
		fFound |= RemoveAllRoofsOfTypeRange( iMapIndex, FIRSTTEXTURE, LASTITEM );
	fFound |= RemoveAllLandsOfTypeRange( iMapIndex, FIRSTFLOOR, LASTFLOOR );

	EraseBuilding( iMapIndex );
	gubWorldRoomInfo[ iMapIndex ] = 0;

	if( !fFound )
	{
		if( gfBasement )
			RebuildRoof( iMapIndex, 0 );
		return;
	}

	if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex - WORLD_COLS ) ) )
		KillBuilding( iMapIndex - WORLD_COLS );
	if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex + WORLD_COLS ) ) )
		KillBuilding( iMapIndex + WORLD_COLS );
	if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex + 1 ) ) )
		KillBuilding( iMapIndex + 1 );
	if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex - 1 ) ) )
		KillBuilding( iMapIndex - 1 );

	if( gfBasement )
		RebuildRoof( iMapIndex, 0 );
}
Esempio n. 2
0
//Specialized function that will delete only the TOP_RIGHT oriented wall in the gridno to the left
//and the TOP_LEFT oriented wall in the gridno up one as well as the other building information at this
//gridno.
void EraseFloorOwnedBuildingPieces( UINT32 iMapIndex )
{	
	LEVELNODE	*pStruct = NULL;
	UINT32 uiTileType;
	UINT16 usWallOrientation;

	if( !gfBasement && !FloorAtGridNo( iMapIndex ) )
	{	//We don't have ownership issues if there isn't a floor here.
		return;
	}
	EraseBuilding( iMapIndex );
	//FIRST, SEARCH AND DESTROY FOR A LEFT NEIGHBORING TILE WITH A TOP_RIGHT ORIENTED WALL
	pStruct = gpWorldLevelData[ iMapIndex - 1 ].pStructHead;
	while( pStruct != NULL )
	{
		if ( pStruct->usIndex != NO_TILE )
		{
			GetTileType( pStruct->usIndex, &uiTileType );
			if ( uiTileType >= FIRSTWALL && uiTileType <= LASTWALL ||
					 uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
			{
				GetWallOrientation( pStruct->usIndex, &usWallOrientation );
				if( usWallOrientation == INSIDE_TOP_RIGHT || usWallOrientation == OUTSIDE_TOP_RIGHT )
				{
					AddToUndoList( iMapIndex - 1 );
					RemoveStruct( iMapIndex - 1, pStruct->usIndex );
					RemoveAllShadowsOfTypeRange( iMapIndex - 1, FIRSTWALL, LASTWALL );
					break; //otherwise, it'll crash because pStruct is toast.
				}
			}
		}
		pStruct = pStruct->pNext;
	}
	//FINALLY, SEARCH AND DESTROY FOR A TOP NEIGHBORING TILE WITH A TOP_LEFT ORIENTED WALL
	pStruct = gpWorldLevelData[ iMapIndex - WORLD_COLS ].pStructHead;
	while( pStruct != NULL )
	{
		if ( pStruct->usIndex != NO_TILE )
		{
			GetTileType( pStruct->usIndex, &uiTileType );
			if ( uiTileType >= FIRSTWALL && uiTileType <= LASTWALL ||
					 uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
			{
				GetWallOrientation( pStruct->usIndex, &usWallOrientation );
				if( usWallOrientation == INSIDE_TOP_LEFT || usWallOrientation == OUTSIDE_TOP_LEFT )
				{
					AddToUndoList( iMapIndex - WORLD_COLS );
					RemoveStruct( iMapIndex - WORLD_COLS , pStruct->usIndex );
					RemoveAllShadowsOfTypeRange( iMapIndex - WORLD_COLS, FIRSTWALL, LASTWALL );
					break; //otherwise, it'll crash because pStruct is toast.
				}
			}
		}
		pStruct = pStruct->pNext;
	}
}
Esempio n. 3
0
void AddBuildingSectionToWorld( SGPRect *pSelectRegion )
{
	INT32 top, left, right, bottom, x, y;
	UINT32 iMapIndex;
	UINT16 usFloorType, usWallType, usRoofType;
	UINT16 usTileIndex;
	BOOLEAN fNewBuilding;
	BOOLEAN fSlantRoof = FALSE;
	BOOLEAN fVertical;
	BOOLEAN fFloor;
	top = pSelectRegion->iTop;
	left = pSelectRegion->iLeft;
	right = pSelectRegion->iRight;
	bottom = pSelectRegion->iBottom;

	//Special case scenario:
	//If the user selects a floor without walls, then it is implied that the user wishes to 
	//change the floor for say a kitchen which might have a different floor type.
	usWallType = GetRandomIndexByRange( FIRSTWALL, LASTWALL );
	usFloorType = GetRandomIndexByRange( FIRSTFLOOR, LASTFLOOR );
	if( usWallType == 0xffff && usFloorType != 0xffff )
	{ //allow user to place floors
		for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
		{
			iMapIndex = y * WORLD_COLS + x;
			EraseFloor( iMapIndex );
			GetTileIndexFromTypeSubIndex( usFloorType, 1, &usTileIndex );
			AddLandToHead( iMapIndex, (UINT16)( usTileIndex + Random( FLOOR_VARIANTS ) ) );
		}
		//we are done!
		return;
	}

	//1ST PASS:  Determine if there are any floor tiles in this region.  If there are, then
	//  that signifies that we are concantenating this building to an existing one.  Otherwise,
	//  we are just drawing an individual building.  If we find a floor, extract the type so
	//  we know how to draw it later.
	fNewBuilding = TRUE;
	for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
	{
		iMapIndex = y * WORLD_COLS + x;
		if( FloorAtGridNo( iMapIndex ) )
		{
			LEVELNODE *pFloor;
			UINT32 uiTileType;
			//If a floor is found, then we are adding to an existing structure.
			fNewBuilding = FALSE;
			//Extract the floor type.  We already checked if there was a floor here, so it is assumed.
			pFloor = gpWorldLevelData[ iMapIndex ].pLandHead;
			while( pFloor )
			{
				GetTileType( pFloor->usIndex, &uiTileType );
				if( uiTileType >= FIRSTFLOOR && uiTileType <= LASTFLOOR )
				{	
					usFloorType = (UINT16)uiTileType;
					break;
				}
			}
			usWallType = SearchForWallType( iMapIndex );
			usRoofType = SearchForRoofType( iMapIndex );
			if( usWallType != 0xffff && usRoofType != 0xffff && usFloorType !=0xffff )
			{	//we have extracted all of the information we need, so we can break out.
				y = bottom;
				break;
			}
		}
	}
	
	if( fNewBuilding )
	{
		//if( gfBasement )
		//	return;
		//Get materials via selection window method.
		usWallType = GetRandomIndexByRange( FIRSTWALL, LASTWALL );
		usFloorType = GetRandomIndexByRange( FIRSTFLOOR, LASTFLOOR );
		usRoofType = GetRandomIndexByRange( FIRSTROOF, LASTROOF );
		if( usRoofType == 0xffff )
		{
			usRoofType = GetRandomIndexByRange( FIRSTSLANTROOF, LASTSLANTROOF );
			if( usRoofType != 0xffff )
			{
				if( !gfBasement )
					fSlantRoof = TRUE;
				else
					usRoofType = FIRSTROOF;
			}
		}
		if( usWallType == 0xffff )
			return;
	}

	//2ND PASS:  Remove all walls in the region that border no floor tile, or simply walls
	//  that are considered exterior walls.  That way, it won't wreck the inside of a building
	//  if you select too much interior.  Also, gridnos that delete walls will also delete the 
	//  floor and roof tiles there.  That signifies that the floorless parts will be resmoothed, 
	//  and rebuilt in the third pass.
	for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
	{
		iMapIndex = y * WORLD_COLS + x;
		if( gfBasement )
		{
			EraseBuilding( iMapIndex );			
		}
		else if( FloorAtGridNo( iMapIndex ) && !fNewBuilding) 
		{
			if( y >= top && !FloorAtGridNo( iMapIndex - WORLD_COLS ) )
			{
				EraseHorizontalWall( iMapIndex - WORLD_COLS );
				EraseFloor( iMapIndex );
				EraseRoof( iMapIndex );
			}
			if( y <= bottom && !FloorAtGridNo( iMapIndex + WORLD_COLS ) )
			{
				EraseHorizontalWall( iMapIndex );
				EraseFloor( iMapIndex );
				EraseRoof( iMapIndex );
			}
			if( x >= left && !FloorAtGridNo( iMapIndex - 1 ) )
			{
				EraseVerticalWall( iMapIndex - 1 );
				EraseFloor( iMapIndex );
				EraseRoof( iMapIndex );
			}
			if( x <= right && !FloorAtGridNo( iMapIndex + 1 ) )
			{
				EraseVerticalWall( iMapIndex );
				EraseFloor( iMapIndex );
				EraseRoof( iMapIndex );
			}
		}
		else	//we will be building outside of this structure, so bulldoze the nature -- trees, rocks, etc.
		{
			BulldozeNature( iMapIndex );
		}
	}
	//3RD PASS:  Process the region, and all walls of floorless tiles are rebuilt from interior perspective.
	for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
	{
		iMapIndex = y * WORLD_COLS + x;
		if( !FloorAtGridNo( iMapIndex ) ) 
		{
			if( y == top && !GetHorizontalWall( iMapIndex - WORLD_COLS ) )
			{
				fFloor = FloorAtGridNo( iMapIndex - WORLD_COLS );
				if( gfBasement == fFloor )
					BuildWallPiece( iMapIndex, INTERIOR_TOP, usWallType);
			}
			if( y == bottom && !GetHorizontalWall( iMapIndex ) )
			{
				fFloor = FloorAtGridNo( iMapIndex + WORLD_COLS );
				if( gfBasement == fFloor )
					BuildWallPiece( iMapIndex, INTERIOR_BOTTOM, usWallType );
			}
			if( x == left && !GetVerticalWall( iMapIndex - 1 ) )
			{
				fFloor = FloorAtGridNo( iMapIndex - 1 );
				if( gfBasement == fFloor )
					BuildWallPiece( iMapIndex, INTERIOR_LEFT, usWallType );
			}
			if( x == right && !GetVerticalWall( iMapIndex ) )
			{
				fFloor = FloorAtGridNo( iMapIndex + 1 );
				if( gfBasement == fFloor )
					BuildWallPiece( iMapIndex, INTERIOR_RIGHT, usWallType );
			}
		}
	}

	//If we are dealing with slant roofs then build the whole thing now.
	//Slant roofs always have a width or height of 8 tiles.
	if( fSlantRoof )
	{
		fVertical = (bottom - top == 7) ? FALSE : TRUE;
		BuildSlantRoof( left, top, right, bottom, usWallType, usRoofType, fVertical ); 
	}

	//4TH PASS:  Process the region, and all floorless tiles get new roofs and floors.
	for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
	{
		iMapIndex = y * WORLD_COLS + x;
		if( !FloorAtGridNo( iMapIndex ) ) 
		{
			if( !fSlantRoof )
				RebuildRoof( iMapIndex, usRoofType );
			if( usFloorType != 0xffff && !gfBasement )
			{
				GetTileIndexFromTypeSubIndex( usFloorType, 1, &usTileIndex );
				AddLandToHead( iMapIndex, (UINT16)( usTileIndex + Random( FLOOR_VARIANTS ) ) );
			}
		}
	}
}