mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Original Source for 1.13 Mod High Resolution version from 12/06/05
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@21 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -0,0 +1,481 @@
|
||||
#ifdef PRECOMPILEDHEADERS
|
||||
#include "TileEngine All.h"
|
||||
#else
|
||||
#include "Types.h"
|
||||
#include "Buildings.h"
|
||||
#include "Isometric Utils.h"
|
||||
#include "Pathai.h"
|
||||
#include "Structure Wrap.h"
|
||||
#include "Random.h"
|
||||
#include "Overhead.h"
|
||||
#include "Render Fun.h"
|
||||
#include "Strategicmap.h"
|
||||
#include "Sys Globals.h"
|
||||
#endif
|
||||
|
||||
#define ROOF_LOCATION_CHANCE 8
|
||||
|
||||
UINT8 gubBuildingInfo[ WORLD_MAX ];
|
||||
BUILDING gBuildings[ MAX_BUILDINGS ];
|
||||
UINT8 gubNumberOfBuildings;
|
||||
|
||||
BUILDING * CreateNewBuilding( UINT8 * pubBuilding )
|
||||
{
|
||||
if (gubNumberOfBuildings + 1 >= MAX_BUILDINGS)
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
// increment # of buildings
|
||||
gubNumberOfBuildings++;
|
||||
// clear entry
|
||||
gBuildings[ gubNumberOfBuildings ].ubNumClimbSpots = 0;
|
||||
*pubBuilding = gubNumberOfBuildings;
|
||||
// return pointer (have to subtract 1 since we just added 1
|
||||
return( &(gBuildings[ gubNumberOfBuildings ]) );
|
||||
}
|
||||
|
||||
BUILDING * GenerateBuilding( INT16 sDesiredSpot )
|
||||
{
|
||||
UINT32 uiLoop;
|
||||
INT16 sTempGridNo, sNextTempGridNo, sVeryTemporaryGridNo;
|
||||
INT16 sStartGridNo, sCurrGridNo, sPrevGridNo = NOWHERE, sRightGridNo;
|
||||
INT8 bDirection, bTempDirection;
|
||||
BOOLEAN fFoundDir, fFoundWall;
|
||||
UINT32 uiChanceIn = ROOF_LOCATION_CHANCE; // chance of a location being considered
|
||||
INT16 sWallGridNo;
|
||||
INT8 bDesiredOrientation;
|
||||
INT8 bSkipSpots = 0;
|
||||
SOLDIERTYPE FakeSoldier;
|
||||
BUILDING * pBuilding;
|
||||
UINT8 ubBuildingID = 0;
|
||||
INT32 iLoopCount = 0;
|
||||
|
||||
pBuilding = CreateNewBuilding( &ubBuildingID );
|
||||
if (!pBuilding)
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
// set up fake soldier for location testing
|
||||
memset( &FakeSoldier, 0, sizeof( SOLDIERTYPE ) );
|
||||
FakeSoldier.sGridNo = sDesiredSpot;
|
||||
FakeSoldier.bLevel = 1;
|
||||
FakeSoldier.bTeam = 1;
|
||||
|
||||
#ifdef ROOF_DEBUG
|
||||
memset( gsCoverValue, 0x7F, sizeof( INT16 ) * WORLD_MAX );
|
||||
#endif
|
||||
|
||||
// Set reachable
|
||||
RoofReachableTest( sDesiredSpot, ubBuildingID );
|
||||
|
||||
// From sGridNo, search until we find a spot that isn't part of the building
|
||||
bDirection = NORTHWEST;
|
||||
sTempGridNo = sDesiredSpot;
|
||||
// using diagonal directions to hopefully prevent picking a
|
||||
// spot that
|
||||
while( (gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE ) )
|
||||
{
|
||||
sNextTempGridNo = NewGridNo( sTempGridNo, DirectionInc( bDirection ) );
|
||||
if ( sTempGridNo == sNextTempGridNo )
|
||||
{
|
||||
// hit edge of map!??!
|
||||
return( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
sTempGridNo = sNextTempGridNo;
|
||||
}
|
||||
}
|
||||
|
||||
// we've got our spot
|
||||
sStartGridNo = sTempGridNo;
|
||||
|
||||
sCurrGridNo = sStartGridNo;
|
||||
sVeryTemporaryGridNo = NewGridNo( sCurrGridNo, DirectionInc( EAST ) );
|
||||
if ( gpWorldLevelData[ sVeryTemporaryGridNo ].uiFlags & MAPELEMENT_REACHABLE )
|
||||
{
|
||||
// go north first
|
||||
bDirection = NORTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// go that way (east)
|
||||
bDirection = EAST;
|
||||
}
|
||||
|
||||
gpWorldLevelData[ sStartGridNo ].ubExtFlags[0] |= MAPELEMENT_EXT_ROOFCODE_VISITED;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
|
||||
// if point to (2 clockwise) is not part of building and is not visited,
|
||||
// or is starting point, turn!
|
||||
sRightGridNo = NewGridNo( sCurrGridNo, DirectionInc( gTwoCDirection[ bDirection ] ) );
|
||||
sTempGridNo = sRightGridNo;
|
||||
if ( ( ( !(gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE) && !(gpWorldLevelData[ sTempGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_ROOFCODE_VISITED) ) || (sTempGridNo == sStartGridNo) ) && (sCurrGridNo != sStartGridNo) )
|
||||
{
|
||||
iLoopCount++;
|
||||
|
||||
if ( iLoopCount >= 10 )
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
bDirection = gTwoCDirection[ bDirection ];
|
||||
// try in that direction
|
||||
continue;
|
||||
}
|
||||
iLoopCount = 0;
|
||||
|
||||
// if spot ahead is part of building, turn
|
||||
sTempGridNo = NewGridNo( sCurrGridNo, DirectionInc( bDirection ) );
|
||||
if ( gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE )
|
||||
{
|
||||
// first search for a spot that is neither part of the building or visited
|
||||
|
||||
// we KNOW that the spot in the original direction is blocked, so only loop 3 times
|
||||
bTempDirection = gTwoCDirection[ bDirection ];
|
||||
fFoundDir = FALSE;
|
||||
for ( uiLoop = 0; uiLoop < 3; uiLoop++ )
|
||||
{
|
||||
sTempGridNo = NewGridNo( sCurrGridNo, DirectionInc( bTempDirection ) );
|
||||
if ( !(gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE) && !(gpWorldLevelData[ sTempGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_ROOFCODE_VISITED) )
|
||||
{
|
||||
// this is the way to go!
|
||||
fFoundDir = TRUE;
|
||||
break;
|
||||
}
|
||||
bTempDirection = gTwoCDirection[ bTempDirection ];
|
||||
}
|
||||
if (!fFoundDir)
|
||||
{
|
||||
// now search for a spot that is just not part of the building
|
||||
bTempDirection = gTwoCDirection[ bDirection ];
|
||||
fFoundDir = FALSE;
|
||||
for ( uiLoop = 0; uiLoop < 3; uiLoop++ )
|
||||
{
|
||||
sTempGridNo = NewGridNo( sCurrGridNo, DirectionInc( bTempDirection ) );
|
||||
if ( !(gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE) )
|
||||
{
|
||||
// this is the way to go!
|
||||
fFoundDir = TRUE;
|
||||
break;
|
||||
}
|
||||
bTempDirection = gTwoCDirection[ bTempDirection ];
|
||||
}
|
||||
if (!fFoundDir)
|
||||
{
|
||||
// WTF is going on?
|
||||
return( NULL );
|
||||
}
|
||||
}
|
||||
bDirection = bTempDirection;
|
||||
// try in that direction
|
||||
continue;
|
||||
}
|
||||
|
||||
// move ahead
|
||||
sPrevGridNo = sCurrGridNo;
|
||||
sCurrGridNo = sTempGridNo;
|
||||
sRightGridNo = NewGridNo( sCurrGridNo, DirectionInc( gTwoCDirection[ bDirection ] ) );
|
||||
|
||||
#ifdef ROOF_DEBUG
|
||||
if (gsCoverValue[sCurrGridNo] == 0x7F7F)
|
||||
{
|
||||
gsCoverValue[sCurrGridNo] = 1;
|
||||
}
|
||||
else if (gsCoverValue[sCurrGridNo] >= 0)
|
||||
{
|
||||
gsCoverValue[sCurrGridNo]++;
|
||||
}
|
||||
|
||||
DebugAI( String( "Roof code visits %d", sCurrGridNo ) );
|
||||
#endif
|
||||
|
||||
if (sCurrGridNo == sStartGridNo)
|
||||
{
|
||||
// done
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !(gpWorldLevelData[ sCurrGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_ROOFCODE_VISITED) )
|
||||
{
|
||||
gpWorldLevelData[ sCurrGridNo ].ubExtFlags[0] |= MAPELEMENT_EXT_ROOFCODE_VISITED;
|
||||
|
||||
//DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("Building info set at %d to %d", sCurrGridNo, ubBuildingID ));
|
||||
|
||||
gubBuildingInfo[ sCurrGridNo ] = ubBuildingID;
|
||||
|
||||
// consider this location as possible climb gridno
|
||||
// there must be a regular wall adjacent to this for us to consider it a
|
||||
// climb gridno
|
||||
|
||||
// if the direction is east or north, the wall would be in our gridno;
|
||||
// if south or west, the wall would be in the gridno two clockwise
|
||||
fFoundWall = FALSE;
|
||||
|
||||
switch( bDirection )
|
||||
{
|
||||
case NORTH:
|
||||
sWallGridNo = sCurrGridNo;
|
||||
bDesiredOrientation = OUTSIDE_TOP_RIGHT;
|
||||
break;
|
||||
case EAST:
|
||||
sWallGridNo = sCurrGridNo;
|
||||
bDesiredOrientation = OUTSIDE_TOP_LEFT;
|
||||
break;
|
||||
case SOUTH:
|
||||
sWallGridNo = (INT16) ( sCurrGridNo + DirectionInc( gTwoCDirection[ bDirection ] ) );
|
||||
bDesiredOrientation = OUTSIDE_TOP_RIGHT;
|
||||
break;
|
||||
case WEST:
|
||||
sWallGridNo = (INT16) ( sCurrGridNo + DirectionInc( gTwoCDirection[ bDirection ] ) );
|
||||
bDesiredOrientation = OUTSIDE_TOP_LEFT;
|
||||
break;
|
||||
default:
|
||||
// what the heck?
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if (bDesiredOrientation == OUTSIDE_TOP_LEFT)
|
||||
{
|
||||
if (WallExistsOfTopLeftOrientation( sWallGridNo ))
|
||||
{
|
||||
fFoundWall = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WallExistsOfTopRightOrientation( sWallGridNo ))
|
||||
{
|
||||
fFoundWall = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (fFoundWall)
|
||||
{
|
||||
if (bSkipSpots > 0)
|
||||
{
|
||||
bSkipSpots--;
|
||||
}
|
||||
else if ( Random( uiChanceIn ) == 0 )
|
||||
{
|
||||
// don't consider people as obstacles
|
||||
if ( NewOKDestination( &FakeSoldier, sCurrGridNo, FALSE, 0 ) )
|
||||
{
|
||||
pBuilding->sUpClimbSpots[ pBuilding->ubNumClimbSpots ] = sCurrGridNo;
|
||||
pBuilding->sDownClimbSpots[ pBuilding->ubNumClimbSpots ] = sRightGridNo;
|
||||
pBuilding->ubNumClimbSpots++;
|
||||
|
||||
if ( pBuilding->ubNumClimbSpots == MAX_CLIMBSPOTS_PER_BUILDING)
|
||||
{
|
||||
// gotta stop!
|
||||
return( pBuilding );
|
||||
}
|
||||
|
||||
// if location is added as a spot, reset uiChanceIn
|
||||
uiChanceIn = ROOF_LOCATION_CHANCE;
|
||||
#ifdef ROOF_DEBUG
|
||||
gsCoverValue[sCurrGridNo] = 99;
|
||||
#endif
|
||||
// skip the next spot
|
||||
bSkipSpots = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if location is not added, 100% chance of handling next location
|
||||
// and the next until we can add one
|
||||
uiChanceIn = 1;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// didn't pick this location, so increase chance that next location
|
||||
// will be considered
|
||||
if (uiChanceIn > 2)
|
||||
{
|
||||
uiChanceIn--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// can't select this spot
|
||||
if ( (sPrevGridNo != NOWHERE) && (pBuilding->ubNumClimbSpots > 0) )
|
||||
{
|
||||
if ( pBuilding->sDownClimbSpots[ pBuilding->ubNumClimbSpots - 1 ] == sCurrGridNo )
|
||||
{
|
||||
// unselect previous spot
|
||||
pBuilding->ubNumClimbSpots--;
|
||||
// overwrote a selected spot so go into automatic selection for later
|
||||
uiChanceIn = 1;
|
||||
#ifdef ROOF_DEBUG
|
||||
// reset marker
|
||||
gsCoverValue[sPrevGridNo] = 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// skip the next gridno
|
||||
bSkipSpots = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// at end could prune # of locations if there are too many
|
||||
|
||||
/*
|
||||
#ifdef ROOF_DEBUG
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
RenderWorld();
|
||||
RenderCoverDebug( );
|
||||
InvalidateScreen( );
|
||||
EndFrameBufferRender();
|
||||
RefreshScreen( NULL );
|
||||
#endif
|
||||
*/
|
||||
|
||||
return( pBuilding );
|
||||
}
|
||||
|
||||
BUILDING * FindBuilding( INT16 sGridNo )
|
||||
{
|
||||
UINT8 ubBuildingID;
|
||||
//UINT8 ubRoomNo;
|
||||
|
||||
if (sGridNo <= 0 || sGridNo > WORLD_MAX)
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
// id 0 indicates no building
|
||||
ubBuildingID = gubBuildingInfo[ sGridNo ];
|
||||
|
||||
if ( ubBuildingID == NO_BUILDING )
|
||||
{
|
||||
return( NULL );
|
||||
/*
|
||||
// need extra checks to see if is valid spot...
|
||||
// must have valid room information and be a flat-roofed
|
||||
// building
|
||||
if ( InARoom( sGridNo, &ubRoomNo ) && (FindStructure( sGridNo, STRUCTURE_NORMAL_ROOF ) != NULL) )
|
||||
{
|
||||
return( GenerateBuilding( sGridNo ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if ( ubBuildingID > gubNumberOfBuildings ) // huh?
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( &(gBuildings[ ubBuildingID ]) );
|
||||
}
|
||||
|
||||
BOOLEAN InBuilding( INT16 sGridNo )
|
||||
{
|
||||
if ( FindBuilding( sGridNo ) == NULL )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
|
||||
void GenerateBuildings( void )
|
||||
{
|
||||
UINT32 uiLoop;
|
||||
|
||||
// init building structures and variables
|
||||
memset( &gubBuildingInfo, 0, WORLD_MAX * sizeof( UINT8 ) );
|
||||
memset( &gBuildings, 0, MAX_BUILDINGS * sizeof( BUILDING ) );
|
||||
gubNumberOfBuildings = 0;
|
||||
|
||||
if ( (gbWorldSectorZ > 0) || gfEditMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// reset ALL reachable flags
|
||||
// do once before we start building generation for
|
||||
// whole map
|
||||
for ( uiLoop = 0; uiLoop < WORLD_MAX; uiLoop++ )
|
||||
{
|
||||
gpWorldLevelData[ uiLoop ].uiFlags &= ~(MAPELEMENT_REACHABLE);
|
||||
gpWorldLevelData[ uiLoop ].ubExtFlags[0] &= ~(MAPELEMENT_EXT_ROOFCODE_VISITED);
|
||||
}
|
||||
|
||||
// search through world
|
||||
// for each location in a room try to find building info
|
||||
|
||||
for ( uiLoop = 0; uiLoop < WORLD_MAX; uiLoop++ )
|
||||
{
|
||||
if ( (gubWorldRoomInfo[ uiLoop ] != NO_ROOM) && (gubBuildingInfo[ uiLoop ] == NO_BUILDING) && (FindStructure( (INT16) uiLoop, STRUCTURE_NORMAL_ROOF ) != NULL) )
|
||||
{
|
||||
GenerateBuilding( (INT16) uiLoop );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INT16 FindClosestClimbPoint( INT16 sStartGridNo, INT16 sDesiredGridNo, BOOLEAN fClimbUp )
|
||||
{
|
||||
BUILDING * pBuilding;
|
||||
UINT8 ubNumClimbSpots;
|
||||
INT16 * psClimbSpots;
|
||||
UINT8 ubLoop;
|
||||
INT16 sDistance, sClosestDistance = 1000, sClosestSpot= NOWHERE;
|
||||
|
||||
pBuilding = FindBuilding( sDesiredGridNo );
|
||||
if (!pBuilding)
|
||||
{
|
||||
return( NOWHERE );
|
||||
}
|
||||
|
||||
ubNumClimbSpots = pBuilding->ubNumClimbSpots;
|
||||
|
||||
if (fClimbUp)
|
||||
{
|
||||
psClimbSpots = pBuilding->sUpClimbSpots;
|
||||
}
|
||||
else
|
||||
{
|
||||
psClimbSpots = pBuilding->sDownClimbSpots;
|
||||
}
|
||||
|
||||
for ( ubLoop = 0; ubLoop < ubNumClimbSpots; ubLoop++ )
|
||||
{
|
||||
if ( (WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 0 ) == NOBODY)
|
||||
&& (WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 1 ) == NOBODY) )
|
||||
{
|
||||
sDistance = PythSpacesAway( sStartGridNo, psClimbSpots[ ubLoop ] );
|
||||
if (sDistance < sClosestDistance )
|
||||
{
|
||||
sClosestDistance = sDistance;
|
||||
sClosestSpot = psClimbSpots[ ubLoop ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( sClosestSpot );
|
||||
}
|
||||
|
||||
BOOLEAN SameBuilding( INT16 sGridNo1, INT16 sGridNo2 )
|
||||
{
|
||||
if ( gubBuildingInfo[ sGridNo1 ] == NO_BUILDING )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
if ( gubBuildingInfo[ sGridNo2 ] == NO_BUILDING )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
return( (BOOLEAN) (gubBuildingInfo[ sGridNo1] == gubBuildingInfo[ sGridNo2 ]) );
|
||||
}
|
||||
Reference in New Issue
Block a user