Пример #1
0
void PasteSmartBrokenWall( INT32 iMapIndex )
{
	UINT16 usNewWallIndex;

	LEVELNODE *pWall;
	UINT32 uiTileType;
	UINT16 usWallType;
	UINT16 usIndex;
	UINT16 usWallOrientation;

	pWall = GetVerticalWall( iMapIndex );
	if( pWall )
	{
		GetTileType( pWall->usIndex, &uiTileType );
		usWallType = (UINT16)uiTileType;
		if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
		{
			usWallType = SearchForWallType( iMapIndex );
		}
		GetWallOrientation( pWall->usIndex, &usWallOrientation );
		usIndex = CalcSmartBrokenWallIndex( usWallOrientation );
		if( usIndex == 0xffff )
		{
			AddToUndoList( iMapIndex );
			RemoveStruct( iMapIndex, pWall->usIndex );
		}
		else
		{
			AddToUndoList( iMapIndex );
			GetTileIndexFromTypeSubIndex( usWallType, usIndex, &usNewWallIndex );
			ReplaceStructIndex( iMapIndex, pWall->usIndex, usNewWallIndex );
		}
	}
	pWall = GetHorizontalWall( iMapIndex );
	if( pWall )
	{
		GetTileType( pWall->usIndex, &uiTileType );
		usWallType = (UINT16)uiTileType;
		if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
		{
			//We want to be able to replace doors with a window, however, the doors do not
			//contain the wall type, so we have to search for the nearest wall to extract it.
			usWallType = SearchForWallType( iMapIndex );
		}
		GetWallOrientation( pWall->usIndex, &usWallOrientation );
		usIndex = CalcSmartBrokenWallIndex( usWallOrientation );
		if( usIndex == 0xffff )
		{
			AddToUndoList( iMapIndex );
			RemoveStruct( iMapIndex, pWall->usIndex );
		}
		else
		{
			AddToUndoList( iMapIndex );
			GetTileIndexFromTypeSubIndex( usWallType, usIndex, &usNewWallIndex );
			ReplaceStructIndex( iMapIndex, pWall->usIndex, usNewWallIndex );
		}
		//Calculate the new graphic for the window type selected.
	}
}
Пример #2
0
BOOLEAN CalcBrokenWallInfoUsingSmartMethod( INT32 iMapIndex, UINT16 *pusWallType, UINT16 *pusIndex )
{
	LEVELNODE *pWall = NULL;
	UINT32 uiTileType;
	UINT16 usWallOrientation;

	if( gubBrokenWallUIValue == 2 ) //the hole in the wall
	{
		*pusWallType = 0xffff;
		*pusIndex = 0xffff;	//but it won't draw it.
		return TRUE;
	}

	pWall = GetVerticalWall( iMapIndex );
	if( pWall )
	{
		GetTileType( pWall->usIndex, &uiTileType );
		*pusWallType = (UINT16)uiTileType;
		if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
		{
			//We want to be able to replace doors with a walltype, however, the doors do not
			//contain the wall type, so we have to search for the nearest wall to extract it.
			*pusWallType = SearchForWallType( iMapIndex );
		}
		GetWallOrientation( pWall->usIndex, &usWallOrientation );
		*pusIndex = CalcSmartBrokenWallIndex( usWallOrientation ) - 1;
		return TRUE;
	}
	pWall = GetHorizontalWall( iMapIndex );
	if( pWall )
	{
		GetTileType( pWall->usIndex, &uiTileType );
		*pusWallType = (UINT16)uiTileType;
		if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
		{
			//We want to be able to replace doors with a walltype, however, the doors do not
			//contain the wall type, so we have to search for the nearest wall to extract it.
			*pusWallType = SearchForWallType( iMapIndex );
		}
		GetWallOrientation( pWall->usIndex, &usWallOrientation );
		*pusIndex = CalcSmartBrokenWallIndex( usWallOrientation ) - 1;
		return TRUE;
	}
	return FALSE;
}
Пример #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 ) ) );
			}
		}
	}
}
Пример #4
0
//From a given gridNo and perspective (wallpiece), it will calculate the new piece, and 
//where to place it as well as handle the special cases.
//NOTE:  Placing top and left pieces are placed relative to the gridno, and the gridNo will
// shift accordingly to place the piece.  Pretend you are the floor, and you want to place a piece to
// the left.  You pass your position, and INTERIOR_LEFT, with interior meaning from the inside of a 
// building.  If you were outside the building, you would call EXTERIOR_LEFT.  The left tile will be 
// placed on gridNo - 1!  Up tiles will be placed on gridNo - 160.
//NOTE:  Passing NULL for usWallType will force it to calculate the closest existing wall type, and
//  use that for building this new wall.  It is necessary for restructuring a building, but not for
//  adding on to an existing building, where the type is already known.
void BuildWallPiece( UINT32 iMapIndex, UINT8 ubWallPiece, UINT16 usWallType )
{
	INT16 sIndex;
	UINT16 usTileIndex;
	UINT16 ubWallClass;
	LEVELNODE *pStruct;
	if( !usWallType )
	{
		usWallType = SearchForWallType( iMapIndex );
	}
	switch( ubWallPiece )
	{
		case EXTERIOR_TOP:
			iMapIndex -= WORLD_COLS;
			//exterior bottom left corner generated
			if ( !gfBasement && GetVerticalWall( iMapIndex - 1) && !GetVerticalWall( iMapIndex + WORLD_COLS - 1) )
			{	//Special case where a shadow has to be created as it now is a bottom corner and
				//must contribute to the bottom shadow.
				AddToUndoList( iMapIndex - 1 );
				GetTileIndexFromTypeSubIndex( usWallType, INTERIOR_BOTTOMEND_SHADOW_INDEX, &usTileIndex );
				AddExclusiveShadow( iMapIndex - 1, usTileIndex );
			}
			if ( pStruct = GetVerticalWall( iMapIndex ) ) //right corner
			{	//Special case where placing the new wall will generate a corner to the right, so replace 
				//the vertical piece with a bottomend.
				sIndex = PickAWallPiece( EXTERIOR_BOTTOMEND );
				AddToUndoList( iMapIndex );
				GetTileIndexFromTypeSubIndex( usWallType, sIndex, &usTileIndex );
				ReplaceStructIndex( iMapIndex, pStruct->usIndex, usTileIndex );
			}
			ubWallClass = EXTERIOR_L;
			if( !gfBasement )
			{
				//All exterior_l walls have shadows.
				GetTileIndexFromTypeSubIndex( usWallType, EXTERIOR_L_SHADOW_INDEX, &usTileIndex );
				AddExclusiveShadow( iMapIndex, usTileIndex );
			}
			break;
		case EXTERIOR_BOTTOM:
			ubWallClass = INTERIOR_L;
			if( (pStruct = GetVerticalWall( iMapIndex + WORLD_COLS - 1 )) && !GetVerticalWall( iMapIndex - 1) )
			{
				sIndex = PickAWallPiece( INTERIOR_EXTENDED );
				AddToUndoList( iMapIndex + WORLD_COLS - 1 );
				GetTileIndexFromTypeSubIndex( usWallType, sIndex, &usTileIndex );
				ReplaceStructIndex( iMapIndex + WORLD_COLS - 1, pStruct->usIndex, usTileIndex );
			}
			break;
		case EXTERIOR_LEFT:
			iMapIndex--;
			ubWallClass = EXTERIOR_R;
			if( GetHorizontalWall( iMapIndex ) )
			{	//Special case where placing the new wall will generate a corner.  This piece
				//becomes an exterior bottomend, but nothing else is effected.
				ubWallClass = EXTERIOR_BOTTOMEND;
			}
			if( GetHorizontalWall( iMapIndex - WORLD_COLS + 1 ) )
			{
				if( ubWallClass == EXTERIOR_BOTTOMEND )
					ubWallClass = EXTERIOR_EXTENDED_BOTTOMEND;
				else
					ubWallClass = EXTERIOR_EXTENDED;
			}
			break;
		case EXTERIOR_RIGHT:
			ubWallClass = INTERIOR_R;
			if( GetHorizontalWall( iMapIndex - WORLD_COLS + 1 ) && !GetHorizontalWall( iMapIndex - WORLD_COLS ) )
			{
				ubWallClass = INTERIOR_EXTENDED;
			}
			else if( GetHorizontalWall( iMapIndex ) && !GetVerticalWall( iMapIndex + WORLD_COLS ) )
			{
				ubWallClass = INTERIOR_BOTTOMEND;
			}
			break;
		case INTERIOR_TOP:
			iMapIndex -= WORLD_COLS;
			ubWallClass = INTERIOR_L;
			//check for a lower left corner.
			if( pStruct = GetVerticalWall( iMapIndex + WORLD_COLS - 1 ) )
			{	//Replace the piece with an extended piece.
				sIndex = PickAWallPiece( INTERIOR_EXTENDED );
				AddToUndoList( iMapIndex + WORLD_COLS - 1 );
				GetTileIndexFromTypeSubIndex( usWallType, sIndex, &usTileIndex );
				ReplaceStructIndex( iMapIndex + WORLD_COLS - 1, pStruct->usIndex, usTileIndex );
				//NOTE:  Not yet checking for interior extended bottomend!
			}
			if( pStruct = GetVerticalWall( iMapIndex ) )
			{
				sIndex = PickAWallPiece( INTERIOR_BOTTOMEND );
				AddToUndoList( iMapIndex );
				GetTileIndexFromTypeSubIndex( usWallType, sIndex, &usTileIndex );
				ReplaceStructIndex( iMapIndex, pStruct->usIndex, usTileIndex );
			}
			break;
		case INTERIOR_BOTTOM:
			ubWallClass = EXTERIOR_L;
			if( pStruct = GetVerticalWall( iMapIndex ) ) //right corner
			{	//Special case where placing the new wall will generate a corner to the right, so replace 
				//the vertical piece with a bottomend.
				sIndex = PickAWallPiece( EXTERIOR_BOTTOMEND );
				AddToUndoList( iMapIndex );
				GetTileIndexFromTypeSubIndex( usWallType, sIndex, &usTileIndex );
				ReplaceStructIndex( iMapIndex, pStruct->usIndex, usTileIndex );
			}
			if( (pStruct = GetVerticalWall( iMapIndex + WORLD_COLS - 1 )) && !GetVerticalWall( iMapIndex - 1) )
			{
				sIndex = PickAWallPiece( EXTERIOR_EXTENDED );
				AddToUndoList( iMapIndex + WORLD_COLS - 1 );
				GetTileIndexFromTypeSubIndex( usWallType, sIndex, &usTileIndex );
				ReplaceStructIndex( iMapIndex + WORLD_COLS - 1, pStruct->usIndex, usTileIndex );
			}
			if( !gfBasement )
			{
				//All exterior_l walls have shadows.
				GetTileIndexFromTypeSubIndex( usWallType, EXTERIOR_L_SHADOW_INDEX, &usTileIndex );
				AddExclusiveShadow( iMapIndex, usTileIndex );
			}
			break;
		case INTERIOR_LEFT:
			iMapIndex--;
			ubWallClass = INTERIOR_R;
			if( GetHorizontalWall( iMapIndex ) )
			{
				ubWallClass = INTERIOR_BOTTOMEND;
			}
			if( !gfBasement && GetHorizontalWall( iMapIndex + 1 ) )
			{
				AddToUndoList( iMapIndex );
				GetTileIndexFromTypeSubIndex( usWallType, INTERIOR_BOTTOMEND_SHADOW_INDEX, &usTileIndex );
				AddExclusiveShadow( iMapIndex, usTileIndex );
			}
			if( GetHorizontalWall( iMapIndex - WORLD_COLS + 1 ) )
			{
				if( ubWallClass == INTERIOR_BOTTOMEND )
					ubWallClass = INTERIOR_EXTENDED_BOTTOMEND;
				else
					ubWallClass = INTERIOR_EXTENDED;
			}
			break;
		case INTERIOR_RIGHT:
			ubWallClass = EXTERIOR_R;
			if( GetHorizontalWall( iMapIndex ) )
			{	//Special case where placing the new wall will generate a corner.  This piece
				//becomes an exterior bottomend, but nothing else is effected.
				ubWallClass = EXTERIOR_BOTTOMEND;
			}
			if( GetHorizontalWall( iMapIndex - WORLD_COLS + 1 ) )
			{
				if( ubWallClass == EXTERIOR_BOTTOMEND )
					ubWallClass = EXTERIOR_EXTENDED_BOTTOMEND;
				else
					ubWallClass = EXTERIOR_EXTENDED;
			}
			if( !gfBasement && GetHorizontalWall( iMapIndex + 1 ) && !GetHorizontalWall( iMapIndex ) 
				  && !FloorAtGridNo( iMapIndex + WORLD_COLS ) )
			{
				GetTileIndexFromTypeSubIndex( usWallType, INTERIOR_BOTTOMEND_SHADOW_INDEX, &usTileIndex );
				AddExclusiveShadow( iMapIndex, usTileIndex );
			}
			break;
	}
	sIndex = PickAWallPiece( ubWallClass );
	GetTileIndexFromTypeSubIndex( usWallType, sIndex, &usTileIndex );
	AddToUndoList( iMapIndex );
	AddWallToStructLayer( iMapIndex, usTileIndex, FALSE );
}