Пример #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
void PasteSmartDoor( INT32 iMapIndex )
{
	LEVELNODE *pWall = NULL;
	UINT16 usTileIndex;
	UINT16 usDoorType;
	UINT16 usIndex;
	UINT16 usWallOrientation;

	if( pWall = GetVerticalWall( iMapIndex ) )
	{
		GetWallOrientation( pWall->usIndex, &usWallOrientation );
		usIndex = CalcSmartDoorIndex( usWallOrientation );
		usDoorType = CalcSmartDoorType();
		AddToUndoList( iMapIndex );
		GetTileIndexFromTypeSubIndex( usDoorType, usIndex, &usTileIndex );
		ReplaceStructIndex( iMapIndex, pWall->usIndex, usTileIndex );
	}
	if( pWall = GetHorizontalWall( iMapIndex ) )
	{
		GetWallOrientation( pWall->usIndex, &usWallOrientation );
		usIndex = CalcSmartDoorIndex( usWallOrientation );
		usDoorType = CalcSmartDoorType();
		AddToUndoList( iMapIndex );
		GetTileIndexFromTypeSubIndex( usDoorType, usIndex, &usTileIndex );
		ReplaceStructIndex( iMapIndex, pWall->usIndex, usTileIndex );
	}
}
Пример #3
0
// This function changes the graphic of the statue and adds the exit grid...
void ChangeO3SectorStatue( BOOLEAN fFromExplosion )
{
	EXITGRID								ExitGrid;
	UINT16									usTileIndex;
	INT16 sX, sY;

	// Remove old graphic
	ApplyMapChangesToMapTempFile( TRUE );
	// Remove it!
	// Get index for it...
	GetTileIndexFromTypeSubIndex( EIGHTOSTRUCT, (INT8)( 5 ), &usTileIndex );					
	RemoveStruct( 13830, usTileIndex );
	
	// Add new one...
	if ( fFromExplosion )
	{
		// Use damaged peice
		GetTileIndexFromTypeSubIndex( EIGHTOSTRUCT, (INT8)( 7 ), &usTileIndex );					
	}
	else
	{
		GetTileIndexFromTypeSubIndex( EIGHTOSTRUCT, (INT8)( 8 ), &usTileIndex );					
		// Play sound...

    PlayJA2Sample( OPEN_STATUE, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );			              

	}
	AddStructToHead( 13830, usTileIndex );

	// Add exit grid
	ExitGrid.ubGotoSectorX = 3;
	ExitGrid.ubGotoSectorY = MAP_ROW_O;
	ExitGrid.ubGotoSectorZ = 1;
	ExitGrid.usGridNo = 13037;

	AddExitGridToWorld( 13669, &ExitGrid );
	gpWorldLevelData[ 13669 ].uiFlags |= MAPELEMENT_REVEALED;

	// Turn off permenant changes....
	ApplyMapChangesToMapTempFile( FALSE );

	// Re-render the world!
	gTacticalStatus.uiFlags |= NOHIDE_REDUNDENCY;
	// FOR THE NEXT RENDER LOOP, RE-EVALUATE REDUNDENT TILES
	InvalidateWorldRedundency( );
	SetRenderFlags(RENDER_FLAG_FULL);

	// Redo movement costs....
	ConvertGridNoToXY( 13830, &sX, &sY );

	RecompileLocalMovementCostsFromRadius( 13830, 5 );

}
Пример #4
0
//Road macros vary in size from 3 gridnos to 18 gridnos.  Using the anchor gridno based off of the original
//road system, this function will place the new macro (consisting of multiple road pieces in multiple
//gridnos).
void PlaceRoadMacroAtGridNo( INT32 iMapIndex, INT32 iMacroID )
{
	INT32 i;
	UINT16 usTileIndex;
	i = gsRoadMacroStartIndex[ iMacroID ];
	while( gRoadMacros[ i ].sMacroID == iMacroID )
	{
		AddToUndoList( iMapIndex + gRoadMacros[ i ].sOffset );
		RemoveAllObjectsOfTypeRange( i, ROADPIECES, ROADPIECES );
		GetTileIndexFromTypeSubIndex( ROADPIECES, (UINT16)(i+1) , &usTileIndex );
		AddObjectToHead( iMapIndex + gRoadMacros[ i ].sOffset, usTileIndex );
		i++;
	}
}
Пример #5
0
//Given a gridno, it will erase the current roof, and calculate the new roof piece based on the
//wall orientions giving priority to the top and left walls before anything else.
//NOTE:  passing NULL for usRoofType will force the function to calculate the nearest roof type,
//  and use that for the new roof.  This is needed when erasing parts of multiple buildings simultaneously.
void RebuildRoof( UINT32 iMapIndex, UINT16 usRoofType )
{
	UINT16 usRoofIndex, usTileIndex;
	BOOLEAN fTop, fBottom, fLeft, fRight;
	if( !usRoofType )
	{
		usRoofType = SearchForRoofType( iMapIndex );
	}
	if( usRoofType == 0xffff )
		return;  //no roof type around, so don't draw one.
	//Analyse the mapindex for walls and set the flags.
	//NOTE:  There is no support for more than 2 side on a roof, so if there is, draw TOPLEFT
	AddToUndoList( iMapIndex );
	EraseRoof( iMapIndex );

	fTop = GetHorizontalWall( iMapIndex - WORLD_COLS ) ? TRUE : FALSE;
	fLeft = GetVerticalWall( iMapIndex - 1 ) ? TRUE : FALSE;
	fBottom = GetHorizontalWall( iMapIndex ) ? TRUE : FALSE;
	fRight = GetVerticalWall( iMapIndex ) ? TRUE : FALSE;
	if( fTop && fLeft )						usRoofIndex = TOPLEFT_ROOF_INDEX;
	else if( fTop && fRight)			usRoofIndex = TOPRIGHT_ROOF_INDEX;
	else if( fBottom && fLeft )		usRoofIndex = BOTTOMLEFT_ROOF_INDEX;
	else if( fBottom && fRight )	usRoofIndex = BOTTOMRIGHT_ROOF_INDEX;
	else if( fTop )								usRoofIndex = TOP_ROOF_INDEX;
	else if( fBottom )						usRoofIndex = BOTTOM_ROOF_INDEX;
	else if( fLeft )							usRoofIndex = LEFT_ROOF_INDEX;
	else if( fRight )							usRoofIndex = RIGHT_ROOF_INDEX;
	else													usRoofIndex = CENTER_ROOF_BASE_INDEX + ( rand() % CENTER_ROOF_VARIANTS );
	GetTileIndexFromTypeSubIndex( usRoofType, usRoofIndex, &usTileIndex );
	AddRoofToHead( iMapIndex, usTileIndex );
	//if the editor view roofs is off, then the new roofs need to be hidden.
	if( !fBuildingShowRoofs )
	{
		HideStructOfGivenType( iMapIndex, usRoofType, TRUE );
	}
}	
Пример #6
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 ) ) );
			}
		}
	}
}
Пример #7
0
//When the user removes a section from a building, it will not only erase the 
//entire highlighted area, it'll repair the building itself so there are no
//outside walls missing from the new building. 
void RemoveBuildingSectionFromWorld( SGPRect *pSelectRegion )
{
	UINT32 top, left, right, bottom, x, y;
	UINT32 iMapIndex;
	UINT16 usTileIndex;
	UINT16 usFloorType;
	BOOLEAN fFloor;

	top = pSelectRegion->iTop;
	left = pSelectRegion->iLeft;
	right = pSelectRegion->iRight;
	bottom = pSelectRegion->iBottom;

	//1ST PASS:  Erase all building owned by the floor tile if there is one.
	for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
	{
		iMapIndex = y * WORLD_COLS + x;
		EraseFloorOwnedBuildingPieces( iMapIndex ); //Erase possible top and left walls in bordering tiles.
	}
	//2ND PASS:  Build new walls whereever there are neighboring floor tiles.
	for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
	{
		iMapIndex = y * WORLD_COLS + x;
		//NOTE:  Top and bottom walls MUST be placed first -- it minimizes the number of special cases.
		if( y == top )
		{
			fFloor = FloorAtGridNo( iMapIndex - WORLD_COLS );
			if( gfBasement && !fFloor || !gfBasement && fFloor && !GetHorizontalWall( iMapIndex - WORLD_COLS ) )
				BuildWallPiece( iMapIndex, EXTERIOR_TOP, 0 );
		}
		if( y == bottom )
		{
			fFloor = FloorAtGridNo( iMapIndex + WORLD_COLS );
			if( gfBasement && !fFloor || !gfBasement && fFloor && !GetHorizontalWall( iMapIndex ) )
				BuildWallPiece( iMapIndex, EXTERIOR_BOTTOM, 0 );
		}
		if( x == left )
		{
			fFloor = FloorAtGridNo( iMapIndex - 1 );
			if( gfBasement && !fFloor || !gfBasement && fFloor && !GetVerticalWall( iMapIndex - 1 ) )
				BuildWallPiece( iMapIndex, EXTERIOR_LEFT, 0 );
		}
		if( x == right )
		{
			fFloor = FloorAtGridNo( iMapIndex + 1);
			if( gfBasement && !fFloor || !gfBasement && fFloor && !GetVerticalWall( iMapIndex ) ) 
				BuildWallPiece( iMapIndex, EXTERIOR_RIGHT, 0 );
		}
	}
	//3RD PASS:  Go around the outside of the region, and rebuild the roof.
	if( gfBasement )
	{
		usFloorType = GetRandomIndexByRange( FIRSTFLOOR, LASTFLOOR );
		if( usFloorType == 0xffff ) 
			usFloorType = FIRSTFLOOR;
		for( y = top; y <= bottom; y++ ) for( x = left; x <= right; x++ )
		{
			iMapIndex = y * WORLD_COLS + x;
			GetTileIndexFromTypeSubIndex( usFloorType, 1, &usTileIndex );
			AddLandToHead( iMapIndex, (UINT16)( usTileIndex + Random( FLOOR_VARIANTS ) ) );
		}
	}
	for( y = top - 1; y <= bottom + 1; y++ ) for( x = left - 1; x <= right + 1; x++ )
	{
		iMapIndex = y * WORLD_COLS + x;
		if( y == top - 1 || y == bottom + 1 || x == left - 1 || x == right + 1 )
		{
			if( !gfBasement && FloorAtGridNo( iMapIndex ) || gfBasement && !FloorAtGridNo( iMapIndex ) )
			{
				RebuildRoof( iMapIndex, 0 );
			}
		}
	}
}
Пример #8
0
UINT16 GetCaveTileIndexFromPerimeterValue( UINT8 ubTotal )
{
	UINT16 usType = FIRSTWALL;
	UINT16 usIndex;
	UINT16 usTileIndex;
	
	switch( ubTotal )
	{
		case 0x00: case 0x10: case 0x20: case 0x30: case 0x40: case 0x50: case 0x60: case 0x70: 
		case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xc0: case 0xd0: case 0xe0: case 0xf0:
			//usIndex = 0;	
			//break;
			return 0xffff;
		case 0x01: case 0x11: case 0x21: case 0x31: case 0x41: case 0x51: case 0x61: case 0x71: 
		case 0x81: case 0x91: case 0xa1: case 0xb1: case 0xc1: case 0xd1: case 0xe1: case 0xf1:
			usType = SECONDWALL;
			usIndex = 1 + (UINT16)Random( 4 ); 
			break;
		case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72: 
		case 0x82: case 0x92: case 0xa2: case 0xb2: case 0xc2: case 0xd2: case 0xe2: case 0xf2:
			usType = SECONDWALL;
			usIndex = 5 + (UINT16)Random( 4 );  
			break;
		case 0x03: case 0x13: case 0x43: case 0x53: case 0x83: case 0x93: case 0xc3: case 0xd3: 
			usIndex = 1;	
			break;
		case 0x04: case 0x14: case 0x24: case 0x34: case 0x44: case 0x54: case 0x64: case 0x74: 
		case 0x84: case 0x94: case 0xa4: case 0xb4: case 0xc4: case 0xd4: case 0xe4: case 0xf4:
			usType = SECONDWALL;
			usIndex = 9 + (UINT16)Random( 4 ); 	
			break;
		case 0x05: case 0x15: case 0x25: case 0x35: case 0x45: case 0x55: case 0x65: case 0x75: 
		case 0x85: case 0x95: case 0xa5: case 0xb5: case 0xc5: case 0xd5: case 0xe5: case 0xf5:
			usIndex = 2 + (UINT16)Random( 2 );
			break;
		case 0x06: case 0x16: case 0x26: case 0x36: case 0x86: case 0x96: case 0xa6: case 0xb6: 
			usIndex = 4;
			break;
		case 0x07: case 0x17: case 0x87: case 0x97:
			usIndex = 5;
			break;
		case 0x08: case 0x18: case 0x28: case 0x38: case 0x48: case 0x58: case 0x68: case 0x78: 
		case 0x88: case 0x98: case 0xa8: case 0xb8: case 0xc8: case 0xd8: case 0xe8: case 0xf8:
			usType = SECONDWALL;
			usIndex = 13 + (UINT16)Random( 4 ); 
			break;
		case 0x09: case 0x29: case 0x49: case 0x69: case 0x89: case 0xa9: case 0xc9: case 0xe9: 
			usIndex = 6;
			break;
		case 0x0a: case 0x1a: case 0x2a: case 0x3a: case 0x4a: case 0x5a: case 0x6a: case 0x7a: 
		case 0x8a: case 0x9a: case 0xaa: case 0xba: case 0xca: case 0xda: case 0xea: case 0xfa:
			usIndex = 7 + (UINT16)Random( 2 );
			break;
		case 0x0b: case 0x4b: case 0x8b: case 0xcb: 
			usIndex = 9;
			break;
		case 0x0c: case 0x1c: case 0x2c: case 0x3c: case 0x4c: case 0x5c: case 0x6c: case 0x7c: 
			usIndex = 10;
			break;
		case 0x0d: case 0x2d: case 0x4d: case 0x6d:
			usIndex = 11;
			break;
		case 0x0e: case 0x1e: case 0x2e: case 0x3e: 
			usIndex = 12;
			break;
		case 0x0f: 
			usIndex = 13;
			break;
		case 0x19: case 0x39: case 0x59: case 0x79: case 0x99: case 0xb9: case 0xd9: case 0xf9: 
			usIndex = 14 + (UINT16)Random( 2 );
			break;
		case 0x1b: case 0x5b: case 0x9b: case 0xdb: 
			usIndex = 16;
			break;
		case 0x1d: case 0x3d: case 0x5d: case 0x7d:
			usIndex = 17;
			break;
		case 0x1f:
			usIndex = 18;
			break;
		case 0x23: case 0x33: case 0x63: case 0x73: case 0xa3: case 0xb3: case 0xe3: case 0xf3: 
			usIndex = 19 + (UINT16)Random( 2 );
			break;
		case 0x27: case 0x37: case 0xa7: case 0xb7:
			usIndex = 21;
			break;
		case 0x2b: case 0x6b: case 0xab: case 0xeb: 
			usIndex = 22;
			break;
		case 0x2f:
			usIndex = 23;
			break;
		case 0x3b: case 0x7b: case 0xbb: case 0xfb: 
			usIndex = 24 + (UINT16)Random( 3 );
			break;
		case 0x3f:
			usIndex = 27;
			break;
		case 0x46: case 0x56: case 0x66: case 0x76: case 0xc6: case 0xd6: case 0xe6: case 0xf6: 
			usIndex = 28 + (UINT16)Random( 2 );
			break;
		case 0x47: case 0x57: case 0xc7: case 0xd7:
			usIndex = 30;
			break;
		case 0x4e: case 0x5e: case 0x6e: case 0x7e: 
			usIndex = 31;
			break;
		case 0x4f:
			usIndex = 32;
			break;
		case 0x5f:
			usIndex = 33;
			break;
		case 0x67: case 0x77: case 0xe7: case 0xf7:
			usIndex = 34 + (UINT16)Random( 3 );
			break;
		case 0x6f:
			usIndex = 37;
			break;
		case 0x7f:
			usIndex = 38 + (UINT16)Random( 2 );
			break;
		case 0x8c: case 0x9c: case 0xac: case 0xbc: case 0xcc: case 0xdc: case 0xec: case 0xfc:
			usIndex = 40 + (UINT16)Random( 2 );
			break;
		case 0x8d: case 0xad: case 0xcd: case 0xed:
			usIndex = 42;
			break;
		case 0x8e: case 0x9e: case 0xae: case 0xbe: 
			usIndex = 43;
			break;
		case 0x8f:
			usIndex = 44;
			break;
		case 0x9d: case 0xbd: case 0xdd: case 0xfd:
			usIndex = 45 + (UINT16)Random( 3 );
			break;
		case 0x9f:
			usIndex = 48;
			break;
		case 0xaf:
			usIndex = 49;
			break;
		case 0xbf:
			usIndex = 50 + (UINT16)Random( 2 );
			break;
		case 0xce: case 0xde: case 0xee: case 0xfe: 
			usIndex = 52 + (UINT16)Random( 3 );
			break;
		case 0xcf:
			usIndex = 55;
			break;
		case 0xdf:
			usIndex = 56 + (UINT16)Random( 2 );
			break;
		case 0xef:
			usIndex = 58 + (UINT16)Random( 2 );
			break;
		case 0xff:
			usIndex = 60 + (UINT16)Random( 6 );
			break;
	}
	GetTileIndexFromTypeSubIndex( usType, usIndex, &usTileIndex );
	return usTileIndex;
}
Пример #9
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 );
}
Пример #10
0
void BuildSlantRoof( INT32 iLeft, INT32 iTop, INT32 iRight, INT32 iBottom, UINT16 usWallType, UINT16 usRoofType, BOOLEAN fVertical )
{
	INT32 i;
	UINT16 usTileIndex;
	INT32 iMapIndex;
	if( fVertical )
	{
		iMapIndex = iBottom * WORLD_COLS + iLeft;
		//This happens to be the only mapindex that needs to be backed up.  The rest have already been
		//done because of the building code before this.
		AddToUndoList( iMapIndex + 8 );
		//Add the closest viewable pieces.  There are two aframe walls pieces, and extended aframe roof pieces.
		GetTileIndexFromTypeSubIndex( usWallType, VWALL_LEFT, &usTileIndex );
		AddRoofToHead( iMapIndex + 4, usTileIndex );
		GetTileIndexFromTypeSubIndex( usWallType, VWALL_RIGHT, &usTileIndex );
		AddRoofToHead( iMapIndex + 8, usTileIndex );
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_LEFT, &usTileIndex );
		AddRoofToHead( iMapIndex + 3, usTileIndex );
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_RIGHT, &usTileIndex );
		AddRoofToHead( iMapIndex + 7, usTileIndex );
		for( i = iBottom - 1; i > iTop; i-- )
		{
			iMapIndex -= WORLD_COLS;
			GetTileIndexFromTypeSubIndex( usRoofType, THIN_LEFT, &usTileIndex );
			AddRoofToHead( iMapIndex + 3, usTileIndex );
			GetTileIndexFromTypeSubIndex( usRoofType, THIN_RIGHT, &usTileIndex );
			AddRoofToHead( iMapIndex + 7, usTileIndex );
		}
		iMapIndex -= WORLD_COLS;
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_LEFT, &usTileIndex );
		AddRoofToHead( iMapIndex + 3, usTileIndex );
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_RIGHT, &usTileIndex );
		AddRoofToHead( iMapIndex + 7, usTileIndex );
	}
	else
	{
		iMapIndex = iTop * WORLD_COLS + iRight;
		//This happens to be the only mapindex that needs to be backed up.  The rest have already been
		//done because of the building code before this.
		AddToUndoList( iMapIndex + 8*WORLD_COLS );
		//Add the closest viewable pieces.  There are two aframe walls pieces, and extended aframe roof pieces.
		GetTileIndexFromTypeSubIndex( usWallType, HWALL_LEFT, &usTileIndex );
		AddRoofToHead( iMapIndex + 4*WORLD_COLS, usTileIndex );
		GetTileIndexFromTypeSubIndex( usWallType, HWALL_RIGHT, &usTileIndex );
		AddRoofToHead( iMapIndex + 8*WORLD_COLS, usTileIndex );
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_TOP, &usTileIndex );
		AddRoofToHead( iMapIndex + 3*WORLD_COLS, usTileIndex );
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_BOTTOM, &usTileIndex );
		AddRoofToHead( iMapIndex + 7*WORLD_COLS, usTileIndex );
		for( i = iRight - 1; i > iLeft; i-- )
		{
			iMapIndex--;
			GetTileIndexFromTypeSubIndex( usRoofType, THIN_TOP, &usTileIndex );
			AddRoofToHead( iMapIndex + 3*WORLD_COLS, usTileIndex );
			GetTileIndexFromTypeSubIndex( usRoofType, THIN_BOTTOM, &usTileIndex );
			AddRoofToHead( iMapIndex + 7*WORLD_COLS, usTileIndex );
		}
		iMapIndex--;
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_TOP, &usTileIndex );
		AddRoofToHead( iMapIndex + 3*WORLD_COLS, usTileIndex );
		GetTileIndexFromTypeSubIndex( usRoofType, THICK_BOTTOM, &usTileIndex );
		AddRoofToHead( iMapIndex + 7*WORLD_COLS, usTileIndex );
	}
}