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:
lalien
2006-04-19 11:32:51 +00:00
commit e54aeb96aa
790 changed files with 741287 additions and 0 deletions
+303
View File
@@ -0,0 +1,303 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "stdio.h"
#include "sgp.h"
#include "Ambient types.h"
#include "fileman.h"
#include "environment.h"
#include "Sound Control.h"
#include "Game Events.h"
#endif
AMBIENTDATA_STRUCT gAmbData[ MAX_AMBIENT_SOUNDS ];
INT16 gsNumAmbData = 0;
UINT8 gubCurrentSteadyStateAmbience = SSA_NONE;
UINT8 gubCurrentSteadyStateSound = 0;
UINT32 guiCurrentSteadyStateSoundHandle = NO_SAMPLE;
STEADY_STATE_AMBIENCE gSteadyStateAmbientTable[ NUM_STEADY_STATE_AMBIENCES ] =
{
// NONE
"",
"",
"",
"",
// NIGHT
"",
"",
"",
"",
// COUNTRYSIZE
// DAY
"SOUNDS\\SSA\\insects Day 01.wav",
"",
"",
"",
// NIGHT
"SOUNDS\\SSA\\night_crickets_01D.wav",
"SOUNDS\\SSA\\night_crickets_01B.wav",
"SOUNDS\\SSA\\night_crickets_01C.wav",
"SOUNDS\\SSA\\night_crickets_01A.wav",
// NEAR WATER
// DAY
"SOUNDS\\SSA\\swamp_day_01a.wav",
"SOUNDS\\SSA\\swamp_day_01b.wav",
"SOUNDS\\SSA\\swamp_day_01c.wav",
"SOUNDS\\SSA\\swamp_day_01d.wav",
//NIGHT
"SOUNDS\\SSA\\marsh_at_night_01a.wav",
"SOUNDS\\SSA\\marsh_at_night_01b.wav",
"SOUNDS\\SSA\\marsh_at_night_01c.wav",
"SOUNDS\\SSA\\marsh_at_night_01d.wav",
//INWATER
//DAY
"SOUNDS\\SSA\\middle_of_water_01d.wav",
"SOUNDS\\SSA\\middle_of_water_01c.wav",
"SOUNDS\\SSA\\middle_of_water_01b.wav",
"SOUNDS\\SSA\\middle_of_water_01a.wav",
// night
"SOUNDS\\SSA\\middle_of_water_01d.wav",
"SOUNDS\\SSA\\middle_of_water_01c.wav",
"SOUNDS\\SSA\\middle_of_water_01b.wav",
"SOUNDS\\SSA\\middle_of_water_01a.wav",
// HEAVY FOREST
// day
"SOUNDS\\SSA\\JUNGLE_DAY_01a.wav",
"SOUNDS\\SSA\\JUNGLE_DAY_01b.wav",
"SOUNDS\\SSA\\JUNGLE_DAY_01c.wav",
"SOUNDS\\SSA\\JUNGLE_DAY_01d.wav",
// night
"SOUNDS\\SSA\\night_crickets_03a.wav",
"SOUNDS\\SSA\\night_crickets_03b.wav",
"SOUNDS\\SSA\\night_crickets_03c.wav",
"SOUNDS\\SSA\\night_crickets_03d.wav",
// PINE FOREST
// DAY
"SOUNDS\\SSA\\pine_forest_01a.wav",
"SOUNDS\\SSA\\pine_forest_01b.wav",
"SOUNDS\\SSA\\pine_forest_01c.wav",
"SOUNDS\\SSA\\pine_forest_01d.wav",
// NIGHT
"SOUNDS\\SSA\\night_crickets_02a.wav",
"SOUNDS\\SSA\\night_crickets_02b.wav",
"SOUNDS\\SSA\\night_crickets_02c.wav",
"SOUNDS\\SSA\\night_crickets_02d.wav",
// ABANDANDED
// DAY
"SOUNDS\\SSA\\metal_wind_01a.wav",
"SOUNDS\\SSA\\metal_wind_01b.wav",
"SOUNDS\\SSA\\metal_wind_01c.wav",
"SOUNDS\\SSA\\metal_wind_01d.wav",
// NIGHT
"SOUNDS\\SSA\\night_insects_01a.wav",
"SOUNDS\\SSA\\night_insects_01b.wav",
"SOUNDS\\SSA\\night_insects_01c.wav",
"SOUNDS\\SSA\\night_insects_01d.wav",
// AIRPORT
// DAY
"SOUNDS\\SSA\\rotating radar dish.wav",
"",
"",
"",
// NIGHT
"SOUNDS\\SSA\\rotating radar dish.wav",
"",
"",
"",
// WASTE LAND
// DAY
"SOUNDS\\SSA\\gentle_wind.wav",
"",
"",
"",
// NIGHT
"SOUNDS\\SSA\\insects_at_night_04.wav",
"",
"",
"",
// UNDERGROUND
// DAY
"SOUNDS\\SSA\\low ominous ambience.wav",
"",
"",
"",
// NIGHT
"SOUNDS\\SSA\\low ominous ambience.wav",
"",
"",
"",
// OCEAN
// DAY
"SOUNDS\\SSA\\sea_01a.wav",
"SOUNDS\\SSA\\sea_01b.wav",
"SOUNDS\\SSA\\sea_01c.wav",
"SOUNDS\\SSA\\sea_01d.wav",
// NIGHT
"SOUNDS\\SSA\\ocean_waves_01a.wav",
"SOUNDS\\SSA\\ocean_waves_01b.wav",
"SOUNDS\\SSA\\ocean_waves_01c.wav",
"SOUNDS\\SSA\\ocean_waves_01d.wav",
};
BOOLEAN LoadAmbientControlFile( UINT8 ubAmbientID )
{
SGPFILENAME zFilename;
HWFILE hFile;
INT32 cnt;
// BUILD FILENAME
sprintf( zFilename, "AMBIENT\\%d.bad", ubAmbientID );
// OPEN, LOAD
hFile = FileOpen( zFilename, FILE_ACCESS_READ, FALSE);
if ( !hFile )
{
return( FALSE );
}
// READ #
if( !FileRead( hFile, &gsNumAmbData, sizeof( INT16 ), NULL ) )
{
return( FALSE );
}
// LOOP FOR OTHERS
for ( cnt = 0; cnt < gsNumAmbData; cnt++ )
{
if( !FileRead( hFile, &(gAmbData[ cnt ]), sizeof( AMBIENTDATA_STRUCT ), NULL ) )
{
return( FALSE );
}
sprintf( zFilename, "AMBIENT\\%s", gAmbData[ cnt ].zFilename );
strcpy( gAmbData[ cnt ].zFilename, zFilename );
}
FileClose( hFile );
return( TRUE );
}
void GetAmbientDataPtr( AMBIENTDATA_STRUCT **ppAmbData, UINT16 *pusNumData )
{
*ppAmbData = gAmbData;
*pusNumData = gsNumAmbData;
}
void StopAmbients( )
{
SoundStopAllRandom( );
}
void HandleNewSectorAmbience( UINT8 ubAmbientID )
{
// OK, we could have just loaded a sector, erase all ambient sounds from queue, shutdown all ambient groupings
SoundStopAllRandom( );
DeleteAllStrategicEventsOfType( EVENT_AMBIENT );
if( !gfBasement && !gfCaves )
{
if( LoadAmbientControlFile( ubAmbientID ) )
{
// OK, load them up!
BuildDayAmbientSounds( );
}
else
{
DebugMsg(TOPIC_JA2, DBG_LEVEL_0, String("Cannot load Ambient data for tileset" ) );
}
}
}
void DeleteAllAmbients()
{
// JA2Gold: it seems that ambient sounds don't get unloaded when we exit a sector!?
SoundStopAllRandom();
DeleteAllStrategicEventsOfType( EVENT_AMBIENT );
}
UINT32 SetupNewAmbientSound( UINT32 uiAmbientID )
{
RANDOMPARMS rpParms;
memset(&rpParms, 0xff, sizeof(RANDOMPARMS));
rpParms.uiTimeMin = gAmbData[ uiAmbientID ].uiMinTime;
rpParms.uiTimeMax = gAmbData[ uiAmbientID ].uiMaxTime;
rpParms.uiVolMin = CalculateSoundEffectsVolume( gAmbData[ uiAmbientID ].uiVol );
rpParms.uiVolMax = CalculateSoundEffectsVolume( gAmbData[ uiAmbientID ].uiVol );
rpParms.uiPriority = GROUP_AMBIENT;
return SoundPlayRandom( gAmbData[ uiAmbientID ].zFilename, &rpParms );
}
UINT32 StartSteadyStateAmbient( UINT32 ubVolume, UINT32 ubLoops)
{
SOUNDPARMS spParms;
memset(&spParms, 0xff, sizeof(SOUNDPARMS));
spParms.uiVolume = CalculateSoundEffectsVolume( ubVolume );
spParms.uiLoop = ubLoops;
spParms.uiPriority=GROUP_AMBIENT;
return(SoundPlay( gSteadyStateAmbientTable[ gubCurrentSteadyStateAmbience ].zSoundNames[ gubCurrentSteadyStateSound ], &spParms ) );
}
BOOLEAN SetSteadyStateAmbience( UINT8 ubAmbience )
{
BOOLEAN fInNight = FALSE;
INT32 cnt;
UINT8 ubNumSounds = 0;
UINT8 ubChosenSound;
// Stop all ambients...
if ( guiCurrentSteadyStateSoundHandle != NO_SAMPLE )
{
SoundStop( guiCurrentSteadyStateSoundHandle );
guiCurrentSteadyStateSoundHandle = NO_SAMPLE;
}
// Determine what time of day we are in ( day/night)
if( gubEnvLightValue >= LIGHT_DUSK_CUTOFF)
{
fInNight = TRUE;
}
// loop through listing to get num sounds...
for ( cnt = ( fInNight * 4 ); cnt < ( NUM_SOUNDS_PER_TIMEFRAME / 2 ); cnt++ )
{
if ( gSteadyStateAmbientTable[ ubAmbience ].zSoundNames[ cnt ][ 0 ] == 0 )
{
break;
}
ubNumSounds++;
}
if ( ubNumSounds == 0 )
{
return( FALSE );
}
// Pick one
ubChosenSound = (UINT8) Random( ubNumSounds );
// Set!
gubCurrentSteadyStateAmbience = ubAmbience;
gubCurrentSteadyStateSound = ubChosenSound;
guiCurrentSteadyStateSoundHandle = StartSteadyStateAmbient( LOWVOLUME, 0 );
return( TRUE );
}
+50
View File
@@ -0,0 +1,50 @@
#ifndef __AMBIENT_CONTROL
#define __AMBIENT_CONTROL
#include "sgp.h"
#include "Ambient types.h"
BOOLEAN LoadAmbientControlFile( UINT8 ubAmbientID );
void HandleNewSectorAmbience( UINT8 ubAmbientID );
UINT32 SetupNewAmbientSound( UINT32 uiAmbientID );
void StopAmbients( );
void DeleteAllAmbients();
extern AMBIENTDATA_STRUCT gAmbData[ MAX_AMBIENT_SOUNDS ];
extern INT16 gsNumAmbData;
BOOLEAN SetSteadyStateAmbience( UINT8 ubAmbience );
#define SOUND_NAME_SIZE 256
#define NUM_SOUNDS_PER_TIMEFRAME 8
enum
{
SSA_NONE,
SSA_COUNTRYSIZE,
SSA_NEAR_WATER,
SSA_IN_WATER,
SSA_HEAVY_FOREST,
SSA_PINE_FOREST,
SSA_ABANDONED,
SSA_AIRPORT,
SSA_WASTELAND,
SSA_UNDERGROUND,
SSA_OCEAN,
NUM_STEADY_STATE_AMBIENCES
};
typedef struct
{
CHAR8 zSoundNames[ NUM_SOUNDS_PER_TIMEFRAME ][ SOUND_NAME_SIZE ];
} STEADY_STATE_AMBIENCE;
#endif
+23
View File
@@ -0,0 +1,23 @@
#ifndef _AMBIENT_TYPES_H
#define _AMBIENT_TYPES_H
#define MAX_AMBIENT_SOUNDS 100
#define AMB_TOD_DAWN 0
#define AMB_TOD_DAY 1
#define AMB_TOD_DUSK 2
#define AMB_TOD_NIGHT 3
typedef struct
{
UINT32 uiMinTime;
UINT32 uiMaxTime;
UINT8 ubTimeCatagory;
SGPFILENAME zFilename;
UINT32 uiVol;
} AMBIENTDATA_STRUCT;
#endif
+481
View File
@@ -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 ]) );
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef BUILDING_H
#define BUILDING_H
#include "worlddef.h"
// for what it's worth, 2 bytes, we use roof climb spots as 1-based
// so the 0th entry is always 0 and can be compared with (and not equal)
// NOWHERE or any other location
#define MAX_CLIMBSPOTS_PER_BUILDING 21
// similarly for buildings, only we really want 0 to be invalid index
#define NO_BUILDING 0
#define MAX_BUILDINGS 31
typedef struct BUILDING
{
INT16 sUpClimbSpots[MAX_CLIMBSPOTS_PER_BUILDING];
INT16 sDownClimbSpots[MAX_CLIMBSPOTS_PER_BUILDING];
UINT8 ubNumClimbSpots;
} BUILDING;
extern UINT8 gubBuildingInfo[ WORLD_MAX ];
BOOLEAN InBuilding( INT16 sGridNo );
BUILDING * GenerateBuilding( INT16 sDesiredSpot );
BUILDING * FindBuilding( INT16 sGridNo );
void GenerateBuildings( void );
INT16 FindClosestClimbPoint( INT16 sStartGridNo, INT16 sDesiredGridNo, BOOLEAN fClimbUp );
BOOLEAN SameBuilding( INT16 sGridNo1, INT16 sGridNo2 );
#endif
+409
View File
@@ -0,0 +1,409 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include "FileMan.h"
#include "debug.h"
#include "types.h"
#include "worlddef.h"
#include "worldman.h"
#include "smooth.h"
#include "Exit Grids.h"
#include "Editor Undo.h"
#include "StrategicMap.h"
#include "Strategic Movement.h"
#include "message.h"
#include "Font Control.h"
#include "pathai.h"
#include "overhead.h"
#include "Animation Control.h"
#include "Sys Globals.h"
#include "quests.h"
#include "SaveLoadMap.h"
#endif
BOOLEAN gfLoadingExitGrids = FALSE;
//used by editor.
EXITGRID gExitGrid = {0,1,1,0};
BOOLEAN gfOverrideInsertionWithExitGrid = FALSE;
INT32 ConvertExitGridToINT32( EXITGRID *pExitGrid )
{
INT32 iExitGridInfo;
iExitGridInfo = (pExitGrid->ubGotoSectorX-1)<< 28;
iExitGridInfo += (pExitGrid->ubGotoSectorY-1)<< 24;
iExitGridInfo += pExitGrid->ubGotoSectorZ << 20;
iExitGridInfo += pExitGrid->usGridNo & 0x0000ffff;
return iExitGridInfo;
}
void ConvertINT32ToExitGrid( INT32 iExitGridInfo, EXITGRID *pExitGrid )
{
//convert the int into 4 unsigned bytes.
pExitGrid->ubGotoSectorX = (UINT8)(((iExitGridInfo & 0xf0000000)>>28)+1);
pExitGrid->ubGotoSectorY = (UINT8)(((iExitGridInfo & 0x0f000000)>>24)+1);
pExitGrid->ubGotoSectorZ = (UINT8)((iExitGridInfo & 0x00f00000)>>20);
pExitGrid->usGridNo = (UINT16)(iExitGridInfo & 0x0000ffff);
}
BOOLEAN GetExitGrid( UINT16 usMapIndex, EXITGRID *pExitGrid )
{
LEVELNODE *pShadow;
pShadow = gpWorldLevelData[ usMapIndex ].pShadowHead;
//Search through object layer for an exitgrid
while( pShadow )
{
if ( pShadow->uiFlags & LEVELNODE_EXITGRID )
{
ConvertINT32ToExitGrid( pShadow->iExitGridInfo, pExitGrid );
return TRUE;
}
pShadow = pShadow->pNext;
}
pExitGrid->ubGotoSectorX = 0;
pExitGrid->ubGotoSectorY = 0;
pExitGrid->ubGotoSectorZ = 0;
pExitGrid->usGridNo = 0;
return FALSE;
}
BOOLEAN ExitGridAtGridNo( UINT16 usMapIndex )
{
LEVELNODE *pShadow;
pShadow = gpWorldLevelData[ usMapIndex ].pShadowHead;
//Search through object layer for an exitgrid
while( pShadow )
{
if ( pShadow->uiFlags & LEVELNODE_EXITGRID )
{
return TRUE;
}
pShadow = pShadow->pNext;
}
return FALSE;
}
BOOLEAN GetExitGridLevelNode( UINT16 usMapIndex, LEVELNODE **ppLevelNode )
{
LEVELNODE *pShadow;
pShadow = gpWorldLevelData[ usMapIndex ].pShadowHead;
//Search through object layer for an exitgrid
while( pShadow )
{
if ( pShadow->uiFlags & LEVELNODE_EXITGRID )
{
*ppLevelNode = pShadow;
return TRUE;
}
pShadow = pShadow->pNext;
}
return FALSE;
}
void AddExitGridToWorld( INT32 iMapIndex, EXITGRID *pExitGrid )
{
LEVELNODE *pShadow, *tail;
pShadow = gpWorldLevelData[ iMapIndex ].pShadowHead;
//Search through object layer for an exitgrid
while( pShadow )
{
tail = pShadow;
if( pShadow->uiFlags & LEVELNODE_EXITGRID )
{ //we have found an existing exitgrid in this node, so replace it with the new information.
pShadow->iExitGridInfo = ConvertExitGridToINT32( pExitGrid );
//SmoothExitGridRadius( (UINT16)iMapIndex, 0 );
return;
}
pShadow = pShadow->pNext;
}
// Add levelnode
AddShadowToHead( iMapIndex, MOCKFLOOR1 );
// Get new node
pShadow = gpWorldLevelData[ iMapIndex ].pShadowHead;
//fill in the information for the new exitgrid levelnode.
pShadow->iExitGridInfo = ConvertExitGridToINT32( pExitGrid );
pShadow->uiFlags |= ( LEVELNODE_EXITGRID | LEVELNODE_HIDDEN );
//Add the exit grid to the sector, only if we call ApplyMapChangesToMapTempFile() first.
if( !gfEditMode && !gfLoadingExitGrids )
{
AddExitGridToMapTempFile( (UINT16)iMapIndex, pExitGrid, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
}
}
void RemoveExitGridFromWorld( INT32 iMapIndex )
{
UINT16 usDummy;
if( TypeExistsInShadowLayer( iMapIndex, MOCKFLOOR, &usDummy ) )
{
RemoveAllShadowsOfTypeRange( iMapIndex, MOCKFLOOR, MOCKFLOOR );
}
}
void SaveExitGrids( HWFILE fp, UINT16 usNumExitGrids )
{
EXITGRID exitGrid;
UINT16 usNumSaved = 0;
UINT16 x;
UINT32 uiBytesWritten;
FileWrite( fp, &usNumExitGrids, 2, &uiBytesWritten );
for( x = 0; x < WORLD_MAX; x++ )
{
if( GetExitGrid( x, &exitGrid ) )
{
FileWrite( fp, &x, 2, &uiBytesWritten );
FileWrite( fp, &exitGrid, 5, &uiBytesWritten );
usNumSaved++;
}
}
//If these numbers aren't equal, something is wrong!
Assert( usNumExitGrids == usNumSaved );
}
void LoadExitGrids( INT8 **hBuffer )
{
EXITGRID exitGrid;
UINT16 x;
UINT16 usNumSaved;
UINT16 usMapIndex;
gfLoadingExitGrids = TRUE;
LOADDATA( &usNumSaved, *hBuffer, 2 );
//FileRead( hfile, &usNumSaved, 2, NULL);
for( x = 0; x < usNumSaved; x++ )
{
LOADDATA( &usMapIndex, *hBuffer, 2 );
//FileRead( hfile, &usMapIndex, 2, NULL);
LOADDATA( &exitGrid, *hBuffer, 5 );
//FileRead( hfile, &exitGrid, 5, NULL);
AddExitGridToWorld( usMapIndex, &exitGrid );
}
gfLoadingExitGrids = FALSE;
}
void AttemptToChangeFloorLevel( INT8 bRelativeZLevel )
{
UINT8 ubLookForLevel=0;
UINT16 i;
if( bRelativeZLevel != 1 && bRelativeZLevel != -1 )
return;
//Check if on ground level -- if so, can't go up!
if( bRelativeZLevel == -1 && !gbWorldSectorZ )
{
ScreenMsg( FONT_DKYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CANT_GO_UP ], ubLookForLevel );
return;
}
//Check if on bottom level -- if so, can't go down!
if( bRelativeZLevel == 1 && gbWorldSectorZ == 3 )
{
ScreenMsg( FONT_DKYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CANT_GO_DOWN ], ubLookForLevel );
return;
}
ubLookForLevel = (UINT8)(gbWorldSectorZ + bRelativeZLevel);
for( i = 0; i < WORLD_MAX; i++ )
{
if( GetExitGrid( i, &gExitGrid ) )
{
if( gExitGrid.ubGotoSectorZ == ubLookForLevel )
{ //found an exit grid leading to the goal sector!
gfOverrideInsertionWithExitGrid = TRUE;
//change all current mercs in the loaded sector, and move them
//to the new sector.
MoveAllGroupsInCurrentSectorToSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, ubLookForLevel );
if( ubLookForLevel )
ScreenMsg( FONT_YELLOW, MSG_INTERFACE, pMessageStrings[ MSG_ENTERING_LEVEL ], ubLookForLevel );
else
ScreenMsg( FONT_YELLOW, MSG_INTERFACE, pMessageStrings[ MSG_LEAVING_BASEMENT ] );
SetCurrentWorldSector( gWorldSectorX, gWorldSectorY, ubLookForLevel );
gfOverrideInsertionWithExitGrid = FALSE;
}
}
}
}
UINT16 FindGridNoFromSweetSpotCloseToExitGrid( SOLDIERTYPE *pSoldier, INT16 sSweetGridNo, INT8 ubRadius, UINT8 *pubDirection )
{
INT16 sTop, sBottom;
INT16 sLeft, sRight;
INT16 cnt1, cnt2;
INT16 sGridNo;
INT32 uiRange, uiLowestRange = 999999;
INT16 sLowestGridNo=0;
INT32 leftmost;
BOOLEAN fFound = FALSE;
SOLDIERTYPE soldier;
UINT8 ubSaveNPCAPBudget;
UINT8 ubSaveNPCDistLimit;
EXITGRID ExitGrid;
UINT8 ubGotoSectorX, ubGotoSectorY, ubGotoSectorZ;
// Turn off at end of function...
gfPlotPathToExitGrid = TRUE;
//Save AI pathing vars. changing the distlimit restricts how
//far away the pathing will consider.
ubSaveNPCAPBudget = gubNPCAPBudget;
ubSaveNPCDistLimit = gubNPCDistLimit;
gubNPCAPBudget = 0;
gubNPCDistLimit = ubRadius;
//create dummy soldier, and use the pathing to determine which nearby slots are
//reachable.
memset( &soldier, 0, sizeof( SOLDIERTYPE ) );
soldier.bLevel = 0;
soldier.bTeam = 1;
soldier.sGridNo = pSoldier->sGridNo;
// OK, Get an exit grid ( if possible )
if ( !GetExitGrid( sSweetGridNo, &ExitGrid ) )
{
return( NOWHERE );
}
// Copy our dest values.....
ubGotoSectorX = ExitGrid.ubGotoSectorX;
ubGotoSectorY = ExitGrid.ubGotoSectorY;
ubGotoSectorZ = ExitGrid.ubGotoSectorZ;
sTop = ubRadius;
sBottom = -ubRadius;
sLeft = - ubRadius;
sRight = ubRadius;
//clear the mapelements of potential residue MAPELEMENT_REACHABLE flags
//in the square region.
for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
{
for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
{
sGridNo = pSoldier->sGridNo + (WORLD_COLS * cnt1) + cnt2;
if ( sGridNo >= 0 && sGridNo < WORLD_MAX )
{
gpWorldLevelData[ sGridNo ].uiFlags &= (~MAPELEMENT_REACHABLE);
}
}
}
//Now, find out which of these gridnos are reachable
//(use the fake soldier and the pathing settings)
FindBestPath( &soldier, NOWHERE, 0, WALKING, COPYREACHABLE, PATH_THROUGH_PEOPLE );
uiLowestRange = 999999;
for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
{
leftmost = ( ( pSoldier->sGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;
for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
{
sGridNo = pSoldier->sGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
if ( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) &&
gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REACHABLE )
{
// Go on sweet stop
// ATE: Added this check because for all intensive purposes, cavewalls will be not an OKDEST
// but we want thenm too...
if ( NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->bLevel ) )
{
if ( GetExitGrid( sGridNo, &ExitGrid ) )
{
// Is it the same exitgrid?
if ( ExitGrid.ubGotoSectorX == ubGotoSectorX && ExitGrid.ubGotoSectorY == ubGotoSectorY && ExitGrid.ubGotoSectorZ == ubGotoSectorZ )
{
uiRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
if ( uiRange < uiLowestRange )
{
sLowestGridNo = sGridNo;
uiLowestRange = uiRange;
fFound = TRUE;
}
}
}
}
}
}
}
gubNPCAPBudget = ubSaveNPCAPBudget;
gubNPCDistLimit = ubSaveNPCDistLimit;
gfPlotPathToExitGrid = FALSE;
if ( fFound )
{
// Set direction to center of map!
*pubDirection = (UINT8)GetDirectionToGridNoFromGridNo( sLowestGridNo, ( ( ( WORLD_ROWS / 2 ) * WORLD_COLS ) + ( WORLD_COLS / 2 ) ) );
return( sLowestGridNo );
}
else
{
return( NOWHERE );
}
}
UINT16 FindClosestExitGrid( SOLDIERTYPE *pSoldier, INT16 sSrcGridNo, INT8 ubRadius )
{
INT16 sTop, sBottom;
INT16 sLeft, sRight;
INT16 cnt1, cnt2;
INT16 sGridNo;
INT32 uiRange, uiLowestRange = 999999;
INT16 sLowestGridNo=0;
INT32 leftmost;
BOOLEAN fFound = FALSE;
EXITGRID ExitGrid;
sTop = ubRadius;
sBottom = -ubRadius;
sLeft = - ubRadius;
sRight = ubRadius;
//clear the mapelements of potential residue MAPELEMENT_REACHABLE flags
uiLowestRange = 999999;
for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
{
leftmost = ( ( sSrcGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;
for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
{
sGridNo = sSrcGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
if( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) )
{
if ( GetExitGrid( sGridNo, &ExitGrid ) )
{
uiRange = GetRangeInCellCoordsFromGridNoDiff( sSrcGridNo, sGridNo );
if ( uiRange < uiLowestRange )
{
sLowestGridNo = sGridNo;
uiLowestRange = uiRange;
fFound = TRUE;
}
}
}
}
}
if ( fFound )
{
return( sLowestGridNo );
}
else
{
return( NOWHERE );
}
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef __EXIT_GRIDS_H
#define __EXIT_GRIDS_H
#include "Fileman.h"
#include "Worlddef.h"
typedef struct //for exit grids (object level)
{ //if an item pool is also in same gridno, then this would be a separate levelnode
//in the object level list
UINT16 usGridNo; //sweet spot for placing mercs in new sector.
UINT8 ubGotoSectorX;
UINT8 ubGotoSectorY;
UINT8 ubGotoSectorZ;
}EXITGRID;
BOOLEAN ExitGridAtGridNo( UINT16 usMapIndex );
BOOLEAN GetExitGridLevelNode( UINT16 usMapIndex, LEVELNODE **ppLevelNode );
BOOLEAN GetExitGrid( UINT16 usMapIndex, EXITGRID *pExitGrid );
void AddExitGridToWorld( INT32 iMapIndex, EXITGRID *pExitGrid );
void RemoveExitGridFromWorld( INT32 iMapIndex );
void SaveExitGrids( HWFILE fp, UINT16 usNumExitGrids );
void LoadExitGrids( INT8 **hBuffer );
void AttemptToChangeFloorLevel( INT8 bRelativeZLevel );
extern EXITGRID gExitGrid;
extern BOOLEAN gfOverrideInsertionWithExitGrid;
// Finds closest ExitGrid of same type as is at gridno, within a radius. Checks
// valid paths, destinations, etc.
UINT16 FindGridNoFromSweetSpotCloseToExitGrid( SOLDIERTYPE *pSoldier, INT16 sSweetGridNo, INT8 ubRadius, UINT8 *pubDirection );
UINT16 FindClosestExitGrid( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 ubRadius );
#endif
File diff suppressed because it is too large Load Diff
+117
View File
@@ -0,0 +1,117 @@
#ifndef _EXPLOSION_CONTROL_H
#define _EXPLOSION_CONTROL_H
#include "Weapons.h"
#define MAX_DISTANCE_EXPLOSIVE_CAN_DESTROY_STRUCTURES 2
#define EXPLOSION_FLAG_USEABSPOS 0x00000001
#define EXPLOSION_FLAG_DISPLAYONLY 0x00000002
// Explosion Data
typedef struct
{
UINT32 uiFlags;
UINT8 ubOwner;
UINT8 ubTypeID;
UINT16 usItem;
INT16 sX; // World X ( optional )
INT16 sY; // World Y ( optional )
INT16 sZ; // World Z ( optional )
INT16 sGridNo; // World GridNo
BOOLEAN fLocate;
INT8 bLevel; // World level
UINT8 ubUnsed[1];
} EXPLOSION_PARAMS;
typedef struct
{
EXPLOSION_PARAMS Params;
BOOLEAN fAllocated;
INT16 sCurrentFrame;
INT32 iID;
INT32 iLightID;
UINT8 ubUnsed[2];
} EXPLOSIONTYPE;
enum EXPLOSION_TYPES
{
NO_BLAST,
BLAST_1,
BLAST_2,
BLAST_3,
STUN_BLAST,
WATER_BLAST,
TARGAS_EXP,
SMOKE_EXP,
MUSTARD_EXP,
NUM_EXP_TYPES
} ;
typedef struct
{
UINT32 uiWorldBombIndex;
UINT32 uiTimeStamp;
UINT8 fExists;
} ExplosionQueueElement;
#define ERASE_SPREAD_EFFECT 2
#define BLOOD_SPREAD_EFFECT 3
#define REDO_SPREAD_EFFECT 4
#define NUM_EXPLOSION_SLOTS 100
extern EXPLOSIONTYPE gExplosionData[ NUM_EXPLOSION_SLOTS ];
extern UINT8 gubElementsOnExplosionQueue;
extern BOOLEAN gfExplosionQueueActive;
void IgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT16 sGridNo, UINT16 usItem, INT8 bLevel );
void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT16 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel );
void GenerateExplosion( EXPLOSION_PARAMS *pExpParams );
void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, BOOLEAN fSubsequent, INT8 bLevel, INT32 iSmokeEffectNum );
void AddBombToQueue( UINT32 uiWorldBombIndex, UINT32 uiTimeStamp );
void DecayBombTimers( void );
void SetOffBombsByFrequency( UINT8 ubID, INT8 bFrequency );
BOOLEAN SetOffBombsInGridNo( UINT8 ubID, INT16 sGridNo, BOOLEAN fAllBombs, INT8 bLevel );
void ActivateSwitchInGridNo( UINT8 ubID, INT16 sGridNo );
void SetOffPanicBombs( UINT8 ubID, INT8 bPanicTrigger );
void UpdateExplosionFrame( INT32 iIndex, INT16 sCurrentFrame );
void RemoveExplosionData( INT32 iIndex );
void UpdateAndDamageSAMIfFound( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, INT16 sGridNo, UINT8 ubDamage );
void UpdateSAMDoneRepair( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
BOOLEAN SaveExplosionTableToSaveGameFile( HWFILE hFile );
BOOLEAN LoadExplosionTableFromSavedGameFile( HWFILE hFile );
INT32 FindActiveTimedBomb( void );
BOOLEAN ActiveTimedBombExists( void );
void RemoveAllActiveTimedBombs( void );
#define GASMASK_MIN_STATUS 70
BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, INT16 sSubsequent, BOOLEAN fRecompileMovementCosts, INT16 sWoundAmt, INT16 sBreathAmt, UINT8 ubOwner );
#endif
+35
View File
@@ -0,0 +1,35 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "types.h"
#include "Fog Of War.h"
#include "Isometric Utils.h"
#include "worldman.h"
#include "Simple Render Utils.h"
#include "Renderworld.h"
#include "lighting.h"
#endif
//When line of sight reaches a gridno, and there is a light there, it turns it on.
//This is only done in the cave levels.
void RemoveFogFromGridNo( UINT32 uiGridNo )
{
INT32 i;
INT32 x, y;
UINT32 uiAdjacentGridNo = 0;
x = uiGridNo % WORLD_COLS;
y = uiGridNo / WORLD_COLS;
for( i = 0; i < MAX_LIGHT_SPRITES; i++ )
{
if( LightSprites[ i ].iX == x && LightSprites[ i ].iY == y )
{
if( !(LightSprites[ i ].uiFlags & LIGHT_SPR_ON) )
{
LightSpritePower( i, TRUE );
LightDraw( LightSprites[i].uiLightType, LightSprites[i].iTemplate, LightSprites[i].iX, LightSprites[i].iY, i );
MarkWorldDirty();
return;
}
}
}
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef __FOG_OF_WAR_H
#define __FOG_OF_WAR_H
//Called after a map is loaded. By keying on the MAPELEMENT_REVEALED value, we can easily
//determine what is hidden by the fog.
void InitializeFogInWorld();
//Removes and smooths the adjacent tiles.
void RemoveFogFromGridNo( UINT32 uiGridNo );
#endif
File diff suppressed because it is too large Load Diff
+50
View File
@@ -0,0 +1,50 @@
#ifndef __INTERACTIVE_TILES_H
#define __INTERACTIVE_TILES_H
#include "Soldier Control.h"
#define INTTILE_DOOR_TILE_ONE 1
#define INTTILE_DOOR_OPENSPEED 70
#define INTILE_CHECK_FULL 1
#define INTILE_CHECK_SELECTIVE 2
extern BOOLEAN gfOverIntTile;
void GetLevelNodeScreenRect( LEVELNODE *pNode, SGPRect *pRect, INT16 sXPos, INT16 sYPos, INT16 sGridNo );
BOOLEAN InitInteractiveTileManagement( );
void ShutdownInteractiveTileManagement( );
BOOLEAN AddInteractiveTile( INT16 sGridNo, LEVELNODE *pLevelNode, UINT32 uiFlags, UINT16 usType );
BOOLEAN StartInteractiveObject( INT16 sGridNo, UINT16 usStructureID, SOLDIERTYPE *pSoldier, UINT8 ubDirection );
BOOLEAN StartInteractiveObjectFromMouse( SOLDIERTYPE *pSoldier, UINT8 ubDirection );
void CompileInteractiveTiles( );
UINT32 GetInteractiveTileCursor( UINT32 uiOldCursor, BOOLEAN fConfirm );
BOOLEAN InteractWithInteractiveObject( SOLDIERTYPE *pSoldier, STRUCTURE *pStructure, UINT8 ubDirection );
BOOLEAN SoldierHandleInteractiveObject( SOLDIERTYPE *pSoldier );
BOOLEAN CalcInteractiveObjectAPs( INT16 sGridNo, STRUCTURE * pStructure, INT16 *psAPCost, INT16 *psBPCost );
void HandleStructChangeFromGridNo( SOLDIERTYPE *pSoldier, INT16 sGridNo );
void BeginCurInteractiveTileCheck( UINT8 bCheckFlags );
void EndCurInteractiveTileCheck( );
void LogMouseOverInteractiveTile( INT16 sGridNo );
BOOLEAN ShouldCheckForMouseDetections( );
void CycleIntTileFindStack( UINT16 usMapPos );
void SetActionModeDoorCursorText( );
LEVELNODE *GetCurInteractiveTile( );
LEVELNODE *GetCurInteractiveTileGridNo( INT16 *psGridNo );
LEVELNODE *GetCurInteractiveTileGridNoAndStructure( INT16 *psGridNo, STRUCTURE **ppStructure );
LEVELNODE *ConditionalGetCurInteractiveTileGridNoAndStructure( INT16 *psGridNo, STRUCTURE **ppStructure, BOOLEAN fRejectOnTopItems );
#endif
File diff suppressed because it is too large Load Diff
+116
View File
@@ -0,0 +1,116 @@
#ifndef __ISOMETRIC_UTILSH
#define __ISOMETRIC_UTILSH
#include "worlddef.h"
//DEFINES
#define MAXCOL WORLD_COLS
#define MAXROW WORLD_ROWS
#define GRIDSIZE (MAXCOL * MAXROW)
#define RIGHTMOSTGRID (MAXCOL - 1)
#define LASTROWSTART (GRIDSIZE - MAXCOL)
#define NOWHERE (GRIDSIZE + 1)
#define NO_MAP_POS NOWHERE
#define MAPWIDTH (WORLD_COLS)
#define MAPHEIGHT (WORLD_ROWS)
#define MAPLENGTH (MAPHEIGHT*MAPWIDTH)
#define ADJUST_Y_FOR_HEIGHT( pos, y ) ( y -= gpWorldLevelData[ pos ].sHeight )
extern UINT8 gOppositeDirection[ NUM_WORLD_DIRECTIONS ];
extern UINT8 gTwoCCDirection[ NUM_WORLD_DIRECTIONS ];
extern UINT8 gTwoCDirection[ NUM_WORLD_DIRECTIONS ];
extern UINT8 gOneCDirection[ NUM_WORLD_DIRECTIONS ];
extern UINT8 gOneCCDirection[ NUM_WORLD_DIRECTIONS ];
extern UINT8 gPurpendicularDirection[ NUM_WORLD_DIRECTIONS ][ NUM_WORLD_DIRECTIONS ];
// Macros
// |Check for map bounds------------------------------------------| |Invalid-| |Valid-------------------|
#define MAPROWCOLTOPOS( r, c ) ( ( (r < 0) || (r >= WORLD_ROWS) || (c < 0) || (c >= WORLD_COLS) ) ? ( 0xffff ) : ( (r) * WORLD_COLS + (c) ) )
#define GETWORLDINDEXFROMWORLDCOORDS( r, c ) ( (INT16) ( r / CELL_X_SIZE ) ) * WORLD_COLS + ( (INT16) ( c / CELL_Y_SIZE ) )
void ConvertGridNoToXY( INT16 sGridNo, INT16 *sXPos, INT16 *sYPos );
void ConvertGridNoToCellXY( INT16 sGridNo, INT16 *sXPos, INT16 *sYPos );
void ConvertGridNoToCenterCellXY( INT16 sGridNo, INT16 *sXPos, INT16 *sYPos );
// GRID NO MANIPULATION FUNCTIONS
INT16 NewGridNo(INT16 sGridno, INT16 sDirInc);
INT16 DirectionInc(INT16 sDirection);
INT32 OutOfBounds(INT16 sGridno, INT16 sProposedGridno);
// Functions
BOOLEAN GetMouseCell( INT32 *piMouseMapPos );
BOOLEAN GetMouseXY( INT16 *psMouseX, INT16 *psMouseY );
BOOLEAN GetMouseWorldCoords( INT16 *psMouseX, INT16 *psMouseY );
BOOLEAN GetMouseMapPos( UINT16 *psMapPos ); // (jonathanl) to save me having to cast all the previous code
BOOLEAN GetMouseMapPos( INT16 *psMapPos );
BOOLEAN GetMouseWorldCoordsInCenter( INT16 *psMouseX, INT16 *psMouseY );
BOOLEAN GetMouseXYWithRemainder( INT16 *psMouseX, INT16 *psMouseY, INT16 *psCellX, INT16 *psCellY );
void GetScreenXYWorldCoords( INT16 sScreenX, INT16 sScreenY, INT16 *pWorldX, INT16 *psWorldY );
void GetScreenXYWorldCell( INT16 sScreenX, INT16 sScreenY, INT16 *psWorldCellX, INT16 *psWorldCellY );
void GetScreenXYGridNo( INT16 sScreenX, INT16 sScreenY, INT16 *psMapPos );
void GetWorldXYAbsoluteScreenXY( INT32 sWorldCellX, INT32 sWorldCellY, INT16 *psWorldScreenX, INT16 *psWorldScreenY );
void GetFromAbsoluteScreenXYWorldXY( INT32 *psWorldCellX, INT32* psWorldCellY, INT16 sWorldScreenX, INT16 sWorldScreenY );
void FromCellToScreenCoordinates( INT16 sCellX, INT16 sCellY, INT16 *psScreenX, INT16 *psScreenY );
void FromScreenToCellCoordinates( INT16 sScreenX, INT16 sScreenY, INT16 *psCellX, INT16 *psCellY );
// Higher resolution convertion functions
void FloatFromCellToScreenCoordinates( FLOAT dCellX, FLOAT dCellY, FLOAT *pdScreenX, FLOAT *pdScreenY );
void FloatFromScreenToCellCoordinates( FLOAT dScreenX, FLOAT dScreenY, FLOAT *pdCellX, FLOAT *pdCellY );
BOOLEAN GridNoOnVisibleWorldTile( INT16 sGridNo );
BOOLEAN GridNoOnVisibleWorldTileGivenYLimits( INT16 sGridNo );
BOOLEAN GridNoOnEdgeOfMap( INT16 sGridNo, INT8 * pbDirection );
BOOLEAN ConvertMapPosToWorldTileCenter( UINT16 usMapPos, INT16 *psXPos, INT16 *psYPos );
BOOLEAN CellXYToScreenXY(INT16 sCellX, INT16 sCellY, INT16 *sScreenX, INT16 *sScreenY);
INT32 GetRangeFromGridNoDiff( INT16 sGridNo1, INT16 sGridNo2 );
INT32 GetRangeInCellCoordsFromGridNoDiff( INT16 sGridNo1, INT16 sGridNo2 );
BOOLEAN IsPointInScreenRect( INT16 sXPos, INT16 sYPos, SGPRect *pRect );
BOOLEAN IsPointInScreenRectWithRelative( INT16 sXPos, INT16 sYPos, SGPRect *pRect, INT16 *sXRel, INT16 *sRelY );
INT16 PythSpacesAway(INT16 sOrigin, INT16 sDest);
INT16 SpacesAway(INT16 sOrigin, INT16 sDest);
INT16 CardinalSpacesAway(INT16 sOrigin, INT16 sDest);
INT8 FindNumTurnsBetweenDirs( INT8 sDir1, INT8 sDir2 );
BOOLEAN FindHeigherLevel( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bStartingDir, INT8 *pbDirection );
BOOLEAN FindLowerLevel( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bStartingDir, INT8 *pbDirection );
INT16 QuickestDirection(INT16 origin, INT16 dest);
INT16 ExtQuickestDirection(INT16 origin, INT16 dest);
// Returns the (center ) cell coordinates in X
INT16 CenterX( INT16 sGridno );
// Returns the (center ) cell coordinates in Y
INT16 CenterY( INT16 sGridno );
INT16 MapX( INT16 sGridNo );
INT16 MapY( INT16 sGridNo );
BOOLEAN FindFenceJumpDirection( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bStartingDir, INT8 *pbDirection );
//Simply chooses a random gridno within valid boundaries (for dropping things in unloaded sectors)
INT16 RandomGridNo();
extern UINT32 guiForceRefreshMousePositionCalculation;
#endif
+482
View File
@@ -0,0 +1,482 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include <string.h>
#include "wcheck.h"
#include "stdlib.h"
#include "debug.h"
#include "soldier control.h"
#include "weapons.h"
#include "handle items.h"
#include "worlddef.h"
#include "worldman.h"
#include "animation control.h"
#include "tile animation.h"
#include "handle items.h"
#include "lighteffects.h"
#include "message.h"
#include "isometric utils.h"
#include "renderworld.h"
#include "explosion control.h"
#include "Random.h"
#include "lighting.h"
#endif
#include "SaveLoadGame.h"
#define NUM_LIGHT_EFFECT_SLOTS 25
// GLOBAL FOR LIGHT LISTING
LIGHTEFFECT gLightEffectData[ NUM_LIGHT_EFFECT_SLOTS ];
UINT32 guiNumLightEffects = 0;
INT32 GetFreeLightEffect( void );
void RecountLightEffects( void );
INT32 GetFreeLightEffect( void )
{
UINT32 uiCount;
for(uiCount=0; uiCount < guiNumLightEffects; uiCount++)
{
if(( gLightEffectData[uiCount].fAllocated==FALSE ) )
return( (INT32)uiCount );
}
if( guiNumLightEffects < NUM_LIGHT_EFFECT_SLOTS )
return( (INT32) guiNumLightEffects++ );
return( -1 );
}
void RecountLightEffects( void )
{
INT32 uiCount;
for(uiCount=guiNumLightEffects-1; (uiCount >=0) ; uiCount--)
{
if( ( gLightEffectData[uiCount].fAllocated ) )
{
guiNumLightEffects=(UINT32)(uiCount+1);
break;
}
}
}
void UpdateLightingSprite( LIGHTEFFECT *pLight )
{
CHAR8 LightName[20];
// Build light....
sprintf( LightName, "Light%d", pLight->bRadius );
// Delete old one if one exists...
if( pLight->iLight!=(-1) )
{
LightSpriteDestroy( pLight->iLight );
pLight->iLight = -1;
}
// Effect light.....
if( ( pLight->iLight = LightSpriteCreate( LightName, 0 ) )==(-1))
{
// Could not light!
return;
}
LightSpritePower( pLight->iLight, TRUE );
// LightSpriteFake( pLight->iLight );
LightSpritePosition( pLight->iLight, (INT16)( CenterX( pLight->sGridNo ) / CELL_X_SIZE ), (INT16)( CenterY( pLight->sGridNo ) / CELL_Y_SIZE ) );
}
INT32 NewLightEffect( INT16 sGridNo, INT8 bType )
{
LIGHTEFFECT *pLight;
INT32 iLightIndex;
UINT8 ubDuration=0;
UINT8 ubStartRadius=0;
if( ( iLightIndex = GetFreeLightEffect() )==(-1) )
return(-1);
memset( &gLightEffectData[ iLightIndex ], 0, sizeof( LIGHTEFFECT ) );
pLight = &gLightEffectData[ iLightIndex ];
// Set some values...
pLight->sGridNo = sGridNo;
pLight->bType = bType;
pLight->iLight = -1;
pLight->uiTimeOfLastUpdate = GetWorldTotalSeconds( );
switch( bType )
{
case LIGHT_FLARE_MARK_1:
ubDuration = 6;
ubStartRadius = 6;
break;
}
pLight->ubDuration = ubDuration;
pLight->bRadius = ubStartRadius;
pLight->bAge = 0;
pLight->fAllocated = TRUE;
UpdateLightingSprite( pLight );
// Handle sight here....
AllTeamsLookForAll( FALSE );
//Play the breaklight sound
// PlayJA2Sample( BREAK_LIGHT_IGNITING, RATE_11025, SoundVolume( LOWVOLUME, sGridNo ), 1, SoundDir( sGridNo ) );
// MAdd: for some reason this crashes the game!
return( iLightIndex );
}
void RemoveLightEffectFromTile( INT16 sGridNo )
{
LIGHTEFFECT *pLight;
UINT32 cnt;
// Set to unallocated....
for ( cnt = 0; cnt < guiNumLightEffects; cnt++ )
{
pLight = &gLightEffectData[ cnt ];
if ( pLight->fAllocated )
{
if ( pLight->sGridNo == sGridNo )
{
pLight->fAllocated = FALSE;
// Remove light....
if( pLight->iLight != (-1) )
{
LightSpriteDestroy( pLight->iLight );
}
break;
}
}
}
}
void DecayLightEffects( UINT32 uiTime )
{
LIGHTEFFECT *pLight;
UINT32 cnt, cnt2;
BOOLEAN fDelete = FALSE;
UINT16 usNumUpdates = 1;
// age all active tear gas clouds, deactivate those that are just dispersing
for ( cnt = 0; cnt < guiNumLightEffects; cnt++ )
{
pLight = &gLightEffectData[ cnt ];
fDelete = FALSE;
if ( pLight->fAllocated )
{
// ATE: Do this every so ofte, to acheive the effect we want...
if ( ( uiTime - pLight->uiTimeOfLastUpdate ) > 350 )
{
usNumUpdates = ( UINT16 ) ( ( uiTime - pLight->uiTimeOfLastUpdate ) / 350 );
pLight->uiTimeOfLastUpdate = uiTime;
for ( cnt2 = 0; cnt2 < usNumUpdates; cnt2++ )
{
pLight->bAge++;
// if this cloud remains effective (duration not reached)
if ( pLight->bAge < pLight->ubDuration)
{
// calculate the new cloud radius
// cloud expands by 1 every turn outdoors, and every other turn indoors
if ( ( pLight->bAge % 2 ) )
{
pLight->bRadius--;
}
if ( pLight->bRadius == 0 )
{
// Delete...
fDelete = TRUE;
break;
}
else
{
UpdateLightingSprite( pLight );
}
}
else
{
fDelete = TRUE;
break;
}
}
if ( fDelete )
{
pLight->fAllocated = FALSE;
if( pLight->iLight != (-1) )
{
LightSpriteDestroy( pLight->iLight );
}
}
// Handle sight here....
AllTeamsLookForAll( FALSE );
}
}
}
}
BOOLEAN SaveLightEffectsToSaveGameFile( HWFILE hFile )
{
/*
UINT32 uiNumBytesWritten;
UINT32 uiNumberOfLights=0;
UINT32 uiCnt;
//loop through and count the number of active slots
for( uiCnt=0; uiCnt<guiNumLightEffects; uiCnt++)
{
if( gLightEffectData[ uiCnt ].fAllocated )
{
uiNumberOfLights++;
}
}
//Save the Number of Light Effects
FileWrite( hFile, &uiNumberOfLights, sizeof( UINT32 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( UINT32 ) )
{
return( FALSE );
}
//if there are lights to save
if( uiNumberOfLights != 0 )
{
//loop through and save each active slot
for( uiCnt=0; uiCnt < guiNumLightEffects; uiCnt++)
{
if( gLightEffectData[ uiCnt ].fAllocated )
{
//Save the Light effect Data
FileWrite( hFile, &gLightEffectData[ uiCnt ], sizeof( LIGHTEFFECT ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( LIGHTEFFECT ) )
{
return( FALSE );
}
}
}
}
*/
return( TRUE );
}
BOOLEAN LoadLightEffectsFromLoadGameFile( HWFILE hFile )
{
UINT32 uiNumBytesRead;
UINT32 uiCount;
//no longer need to load Light effects. They are now in temp files
if( guiSaveGameVersion < 76 )
{
memset( gLightEffectData, 0, sizeof( LIGHTEFFECT ) * NUM_LIGHT_EFFECT_SLOTS );
//Load the Number of Light Effects
FileRead( hFile, &guiNumLightEffects, sizeof( UINT32 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( UINT32 ) )
{
return( FALSE );
}
//if there are lights saved.
if( guiNumLightEffects != 0 )
{
//loop through and apply the light effects to the map
for(uiCount=0; uiCount < guiNumLightEffects; uiCount++)
{
//Load the Light effect Data
FileRead( hFile, &gLightEffectData[ uiCount ], sizeof( LIGHTEFFECT ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( LIGHTEFFECT ) )
{
return( FALSE );
}
}
}
//loop through and apply the light effects to the map
for(uiCount=0; uiCount < guiNumLightEffects; uiCount++)
{
if( gLightEffectData[uiCount].fAllocated )
UpdateLightingSprite( &( gLightEffectData[uiCount] ) );
}
}
return( TRUE );
}
BOOLEAN SaveLightEffectsToMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
UINT32 uiNumLightEffects=0;
HWFILE hFile;
UINT32 uiNumBytesWritten=0;
CHAR8 zMapName[ 128 ];
UINT32 uiCnt;
//get the name of the map
GetMapTempFileName( SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
//delete file the file.
FileDelete( zMapName );
//loop through and count the number of Light effects
for( uiCnt=0; uiCnt<guiNumLightEffects; uiCnt++)
{
if( gLightEffectData[ uiCnt ].fAllocated )
uiNumLightEffects++;
}
//if there are no Light effects
if( uiNumLightEffects == 0 )
{
//set the fact that there are no Light effects for this sector
ReSetSectorFlag( sMapX, sMapY, bMapZ, SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS );
return( TRUE );
}
//Open the file for writing
hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
if( hFile == 0 )
{
//Error opening map modification file
return( FALSE );
}
//Save the Number of Light Effects
FileWrite( hFile, &uiNumLightEffects, sizeof( UINT32 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( UINT32 ) )
{
//Close the file
FileClose( hFile );
return( FALSE );
}
//loop through and save the number of Light effects
for( uiCnt=0; uiCnt < guiNumLightEffects; uiCnt++)
{
//if the Light is active
if( gLightEffectData[ uiCnt ].fAllocated )
{
//Save the Light effect Data
FileWrite( hFile, &gLightEffectData[ uiCnt ], sizeof( LIGHTEFFECT ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( LIGHTEFFECT ) )
{
//Close the file
FileClose( hFile );
return( FALSE );
}
}
}
//Close the file
FileClose( hFile );
SetSectorFlag( sMapX, sMapY, bMapZ, SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS );
return( TRUE );
}
BOOLEAN LoadLightEffectsFromMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
UINT32 uiNumBytesRead;
UINT32 uiCount;
UINT32 uiCnt=0;
HWFILE hFile;
UINT32 uiNumBytesWritten=0;
CHAR8 zMapName[ 128 ];
GetMapTempFileName( SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
//Open the file for reading, Create it if it doesnt exist
hFile = FileOpen( zMapName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
if( hFile == 0 )
{
//Error opening file
return( FALSE );
}
//Clear out the old list
ResetLightEffects();
//Load the Number of Light Effects
FileRead( hFile, &guiNumLightEffects, sizeof( UINT32 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( UINT32 ) )
{
FileClose( hFile );
return( FALSE );
}
//loop through and load the list
for( uiCnt=0; uiCnt<guiNumLightEffects;uiCnt++)
{
//Load the Light effect Data
FileRead( hFile, &gLightEffectData[ uiCnt ], sizeof( LIGHTEFFECT ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( LIGHTEFFECT ) )
{
FileClose( hFile );
return( FALSE );
}
}
//loop through and apply the light effects to the map
for(uiCount=0; uiCount < guiNumLightEffects; uiCount++)
{
if( gLightEffectData[uiCount].fAllocated )
UpdateLightingSprite( &( gLightEffectData[uiCount] ) );
}
FileClose( hFile );
return( TRUE );
}
void ResetLightEffects()
{
//Clear out the old list
memset( gLightEffectData, 0, sizeof( LIGHTEFFECT ) * NUM_LIGHT_EFFECT_SLOTS );
guiNumLightEffects = 0;
}
+48
View File
@@ -0,0 +1,48 @@
#ifndef __LIGHT_EFFECTS
#define __LIGHT_EFFECTS
// Light effect types
enum
{
NO_LIGHT_EFFECT,
LIGHT_FLARE_MARK_1,
};
typedef struct
{
INT16 sGridNo; // gridno at which the tear gas cloud is centered
UINT8 ubDuration; // the number of turns will remain effective
UINT8 bRadius; // the current radius
INT8 bAge; // the number of turns light has been around
BOOLEAN fAllocated;
INT8 bType;
INT32 iLight;
UINT32 uiTimeOfLastUpdate;
} LIGHTEFFECT;
// Decays all light effects...
void DecayLightEffects( UINT32 uiTime );
// Add light to gridno
// ( Replacement algorithm uses distance away )
void AddLightEffectToTile( INT8 bType, INT16 sGridNo );
void RemoveLightEffectFromTile( INT16 sGridNo );
INT32 NewLightEffect( INT16 sGridNo, INT8 bType );
BOOLEAN SaveLightEffectsToSaveGameFile( HWFILE hFile );
BOOLEAN LoadLightEffectsFromLoadGameFile( HWFILE hFile );
BOOLEAN SaveLightEffectsToMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
BOOLEAN LoadLightEffectsFromMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
void ResetLightEffects();
#endif
File diff suppressed because it is too large Load Diff
+84
View File
@@ -0,0 +1,84 @@
#ifndef __MAP_EDGEPOINTS_H
#define __MAP_EDGEPOINTS_H
#include "types.h"
#include "Fileman.h"
typedef struct MAPEDGEPOINTINFO
{
UINT8 ubNumPoints;
UINT8 ubStrategicInsertionCode;
UINT16 sGridNo[ 32 ];
}MAPEDGEPOINTINFO;
UINT16 ChooseMapEdgepoint( UINT8 ubStrategicInsertionCode );
void ChooseMapEdgepoints( MAPEDGEPOINTINFO *pMapEdgepointInfo, UINT8 ubStrategicInsertionCode, UINT8 ubNumDesiredPoints );
void GenerateMapEdgepoints();
void SaveMapEdgepoints( HWFILE fp );
BOOLEAN LoadMapEdgepoints( INT8 **hBuffer );
void TrashMapEdgepoints();
//dynamic arrays that contain the valid gridno's for each edge
extern INT16 *gps1stNorthEdgepointArray;
extern INT16 *gps1stEastEdgepointArray;
extern INT16 *gps1stSouthEdgepointArray;
extern INT16 *gps1stWestEdgepointArray;
//contains the size for each array
extern UINT16 gus1stNorthEdgepointArraySize;
extern UINT16 gus1stEastEdgepointArraySize;
extern UINT16 gus1stSouthEdgepointArraySize;
extern UINT16 gus1stWestEdgepointArraySize;
//contains the index value for the first array index of the second row of each edgepoint array.
//Because each edgepoint side has two rows, the outside most row is calculated first, then the inside row.
//For purposes of AI, it may become necessary to avoid this.
extern UINT16 gus1stNorthEdgepointMiddleIndex;
extern UINT16 gus1stEastEdgepointMiddleIndex;
extern UINT16 gus1stSouthEdgepointMiddleIndex;
extern UINT16 gus1stWestEdgepointMiddleIndex;
//dynamic arrays that contain the valid gridno's for each edge
extern INT16 *gps2ndNorthEdgepointArray;
extern INT16 *gps2ndEastEdgepointArray;
extern INT16 *gps2ndSouthEdgepointArray;
extern INT16 *gps2ndWestEdgepointArray;
//contains the size for each array
extern UINT16 gus2ndNorthEdgepointArraySize;
extern UINT16 gus2ndEastEdgepointArraySize;
extern UINT16 gus2ndSouthEdgepointArraySize;
extern UINT16 gus2ndWestEdgepointArraySize;
//contains the index value for the first array index of the second row of each edgepoint array.
//Because each edgepoint side has two rows, the outside most row is calculated first, then the inside row.
//For purposes of AI, it may become necessary to avoid this.
extern UINT16 gus2ndNorthEdgepointMiddleIndex;
extern UINT16 gus2ndEastEdgepointMiddleIndex;
extern UINT16 gus2ndSouthEdgepointMiddleIndex;
extern UINT16 gus2ndWestEdgepointMiddleIndex;
//This is the search code that will determine the closest map edgepoint to a given gridno and
//a strategic insertion code. You must call the begin...() first, the call SearchForClosestMapEdgepoint()
//for each soldier that is looking. After you are completely finished, call the end..(). The return value
//will return NOWHERE if the information is invalid (no edgepoint info for that particular side, or all
//spots are reserved. There are only 20 spots that can be reserved (one for each player soldier). This
//code shouldn't be used for enemies or anybody else.
void BeginMapEdgepointSearch();
void EndMapEdgepointSearch();
INT16 SearchForClosestPrimaryMapEdgepoint( INT16 sGridNo, UINT8 ubInsertionCode );
INT16 SearchForClosestSecondaryMapEdgepoint( INT16 sGridNo, UINT8 ubInsertionCode );
//There are two classes of edgepoints.
//PRIMARY : The default list of edgepoints. This list includes edgepoints that are easily accessible from the
// strategic level.
//SECONDARY : The isolated list of edgepoints. Certain areas of the game are blocked off, but tactically traversing
// to these areas is possible. Examples would be isolated sections of Grumm or Alma, which you can't
// immediately
//
UINT8 CalcMapEdgepointClassInsertionCode( INT16 sGridNo );
#ifdef JA2EDITOR
void ShowMapEdgepoints();
void HideMapEdgepoints();
#endif
#endif
+826
View File
@@ -0,0 +1,826 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "sgp.h"
#include "Radar Screen.h"
#include "line.h"
#include "renderworld.h"
#include "Isometric Utils.h"
#include "Interface.h"
#include "overhead.h"
#include "Soldier Control.h"
#include "lighting.h"
#include "wcheck.h"
#include "sysutil.h"
#include "render dirty.h"
#include "overhead map.h"
#include "Squads.h"
#include "mousesystem.h"
#include "Text.h"
#include "Font Control.h"
#include "vobject.h"
#include "Utilities.h"
#include "Interface Control.h"
#include "Game Clock.h"
#include "Map Screen Interface Map Inventory.h"
#include "environment.h"
#endif
extern INT32 iCurrentMapSectorZ;
void AdjustWorldCenterFromRadarCoords( INT16 sRadarX, INT16 sRadarY );
// render the squad list
void RenderSquadList( void );
// squad list mvt + btn callback
void TacticalSquadListMvtCallback( MOUSE_REGION * pRegion, INT32 iReason );
void TacticalSquadListBtnCallBack(MOUSE_REGION * pRegion, INT32 iReason );
// the squad list font
#define SQUAD_FONT COMPFONT
#define SQUAD_REGION_HEIGHT 2 * RADAR_WINDOW_HEIGHT
#define SQUAD_WINDOW_TM_Y RADAR_WINDOW_TM_Y + GetFontHeight( SQUAD_FONT )
// subtractor for squad list from size of radar view region height
#define SUBTRACTOR_FOR_SQUAD_LIST 0
INT16 gsRadarX;
INT16 gsRadarY;
UINT32 gusRadarImage;
BOOLEAN fImageLoaded = FALSE;
BOOLEAN fRenderRadarScreen = TRUE;
INT16 sSelectedSquadLine = -1;
BOOLEAN gfRadarCurrentGuyFlash = FALSE;
MOUSE_REGION gRadarRegionSquadList[ NUMBER_OF_SQUADS ];
BOOLEAN InitRadarScreen( )
{
// Add region for radar
MSYS_DefineRegion( &gRadarRegion, RADAR_WINDOW_X, RADAR_WINDOW_TM_Y,
RADAR_WINDOW_X + RADAR_WINDOW_WIDTH,
RADAR_WINDOW_TM_Y + RADAR_WINDOW_HEIGHT,
MSYS_PRIORITY_HIGHEST, 0,
RadarRegionMoveCallback,
RadarRegionButtonCallback );
// Add region
MSYS_AddRegion( &gRadarRegion );
//disable the radar map
MSYS_DisableRegion(&gRadarRegion);
gsRadarX = RADAR_WINDOW_X;
gsRadarY = RADAR_WINDOW_TM_Y;
return( TRUE );
}
BOOLEAN LoadRadarScreenBitmap(CHAR8 * aFilename )
{
VOBJECT_DESC VObjectDesc;
CHAR8 zFilename[ 260 ];
INT32 cnt;
HVOBJECT hVObject;
strcpy( zFilename, aFilename );
// If we have loaded, remove old one
if ( fImageLoaded )
{
DeleteVideoObjectFromIndex( gusRadarImage );
fImageLoaded = FALSE;
}
/* ARM - Restriction removed Nov.29/98. Must be able to view different radar maps from map screen while underground!
// If we are in a cave or basement..... dont get a new one...
if( !gfBasement && !gfCaves )
*/
{
// Remove extension
for ( cnt = strlen( zFilename )-1; cnt >=0; cnt-- )
{
if ( zFilename[ cnt ] == '.' )
{
zFilename[ cnt ] = '\0';
}
}
// Grab the Map image
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
sprintf( VObjectDesc.ImageFile, "RADARMAPS\\%s.STI", zFilename );
CHECKF(AddVideoObject(&VObjectDesc, &gusRadarImage));
fImageLoaded = TRUE;
if( GetVideoObject( &hVObject, gusRadarImage ) )
{
// ATE: Add a shade table!
hVObject->pShades[ 0 ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 255, 255, 255, FALSE );
hVObject->pShades[ 1 ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 100, 100, 100, FALSE );
}
}
// Dirty interface
fInterfacePanelDirty = TRUE;
return( TRUE );
}
void ClearOutRadarMapImage( void )
{
// If we have loaded, remove old one
if ( fImageLoaded )
{
DeleteVideoObjectFromIndex( gusRadarImage );
fImageLoaded = FALSE;
}
}
void MoveRadarScreen()
{
// check if we are allowed to do anything?
if( fRenderRadarScreen == FALSE )
{
return;
}
// Remove old region
MSYS_RemoveRegion( &gRadarRegion );
// Add new one
// Move based on inventory panel
if( guiCurrentScreen == MAP_SCREEN )
{
gsRadarY = RADAR_WINDOW_STRAT_Y;
}
else if ( gsCurInterfacePanel == SM_PANEL )
{
gsRadarY = RADAR_WINDOW_TM_Y;
}
else
{
gsRadarY = RADAR_WINDOW_TM_Y;
}
// Add region for radar
MSYS_DefineRegion( &gRadarRegion, RADAR_WINDOW_X, (UINT16)(gsRadarY),
RADAR_WINDOW_X + RADAR_WINDOW_WIDTH,
(UINT16)(gsRadarY + RADAR_WINDOW_HEIGHT),
MSYS_PRIORITY_HIGHEST, 0,
RadarRegionMoveCallback,
RadarRegionButtonCallback );
// Add region
MSYS_AddRegion( &gRadarRegion );
}
void RadarRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason )
{
INT16 sRadarX, sRadarY;
// check if we are allowed to do anything?
if( fRenderRadarScreen == FALSE )
{
return;
}
if (iReason == MSYS_CALLBACK_REASON_MOVE )
{
if ( pRegion->ButtonState & MSYS_LEFT_BUTTON )
{
// Use relative coordinates to set center of viewport
sRadarX = pRegion->RelativeXPos - ( RADAR_WINDOW_WIDTH / 2 );
sRadarY = pRegion->RelativeYPos - ( RADAR_WINDOW_HEIGHT / 2 );
AdjustWorldCenterFromRadarCoords( sRadarX, sRadarY );
SetRenderFlags(RENDER_FLAG_FULL);
}
}
}
void RadarRegionButtonCallback( MOUSE_REGION * pRegion, INT32 iReason )
{
INT16 sRadarX, sRadarY;
// check if we are allowed to do anything?
if( fRenderRadarScreen == FALSE )
{
return;
}
if (iReason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
{
if ( !InOverheadMap( ) )
{
// Use relative coordinates to set center of viewport
sRadarX = pRegion->RelativeXPos - ( RADAR_WINDOW_WIDTH / 2 );
sRadarY = pRegion->RelativeYPos - ( RADAR_WINDOW_HEIGHT / 2 );
AdjustWorldCenterFromRadarCoords( sRadarX, sRadarY );
}
else
{
KillOverheadMap();
}
}
else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_DWN)
{
if ( !InOverheadMap( ) )
{
GoIntoOverheadMap( );
}
else
{
KillOverheadMap();
}
}
}
void RenderRadarScreen( )
{
INT16 sRadarTLX, sRadarTLY;
INT16 sRadarBRX, sRadarBRY;
INT16 sRadarCX, sRadarCY;
INT32 iItemNumber = 0;
INT16 sX_S, sY_S;
INT16 sScreenCenterX, sScreenCenterY;
INT16 sDistToCenterY, sDistToCenterX;
INT16 sTopLeftWorldX, sTopLeftWorldY;
INT16 sTopRightWorldX, sTopRightWorldY;
INT16 sBottomLeftWorldX, sBottomLeftWorldY;
INT16 sBottomRightWorldX, sBottomRightWorldY;
SOLDIERTYPE *pSoldier;
INT16 sXSoldPos, sYSoldPos, sXSoldScreen, sYSoldScreen, sXSoldRadar, sYSoldRadar;
UINT32 uiDestPitchBYTES;
UINT8 *pDestBuf;
UINT16 usLineColor;
UINT32 cnt;
INT16 sHeight, sWidth, sX, sY;
INT32 iCounter = 0;
// create / destroy squad list regions as nessacary
CreateDestroyMouseRegionsForSquadList( );
// check if we are allowed to do anything?
if( fRenderRadarScreen == FALSE )
{
RenderSquadList( );
return;
}
if( AreInMeanwhile( ) == TRUE )
{
// in a meanwhile, don't render any map
fImageLoaded = FALSE;
}
if ( fInterfacePanelDirty == DIRTYLEVEL2 && fImageLoaded )
{
// Set to default
SetObjectHandleShade( gusRadarImage, 0 );
//If night time and on surface, darken the radarmap.
if( NightTime() )
{
if( guiCurrentScreen == MAP_SCREEN && !iCurrentMapSectorZ ||
guiCurrentScreen == GAME_SCREEN && !gbWorldSectorZ )
{
SetObjectHandleShade( gusRadarImage, 1 );
}
}
BltVideoObjectFromIndex( guiSAVEBUFFER, gusRadarImage, 0, RADAR_WINDOW_X, gsRadarY, VO_BLT_SRCTRANSPARENCY, NULL );
}
// FIRST DELETE WHAT'S THERE
RestoreExternBackgroundRect( RADAR_WINDOW_X, gsRadarY, RADAR_WINDOW_WIDTH + 1 , RADAR_WINDOW_HEIGHT + 1 );
// Determine scale factors
// Find the diustance from render center to true world center
sDistToCenterX = gsRenderCenterX - gCenterWorldX;
sDistToCenterY = gsRenderCenterY - gCenterWorldY;
// From render center in world coords, convert to render center in "screen" coords
FromCellToScreenCoordinates( sDistToCenterX , sDistToCenterY, &sScreenCenterX, &sScreenCenterY );
// Subtract screen center
sScreenCenterX += gsCX;
sScreenCenterY += gsCY;
// Get corners in screen coords
// TOP LEFT
sX_S = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 );
sY_S = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 );
sTopLeftWorldX = sScreenCenterX - sX_S;
sTopLeftWorldY = sScreenCenterY - sY_S;
sTopRightWorldX = sScreenCenterX + sX_S;
sTopRightWorldY = sScreenCenterY - sY_S;
sBottomLeftWorldX = sScreenCenterX - sX_S;
sBottomLeftWorldY = sScreenCenterY + sY_S;
sBottomRightWorldX = sScreenCenterX + sX_S;
sBottomRightWorldY = sScreenCenterY + sY_S;
// Determine radar coordinates
sRadarCX = (INT16)( gsCX * gdScaleX );
sRadarCY = (INT16)( gsCY * gdScaleY );
sWidth = ( RADAR_WINDOW_WIDTH );
sHeight = ( RADAR_WINDOW_HEIGHT );
sX = RADAR_WINDOW_X;
sY = gsRadarY;
sRadarTLX = (INT16)( ( sTopLeftWorldX * gdScaleX ) - sRadarCX + sX + ( sWidth /2 ) );
sRadarTLY = (INT16)( ( sTopLeftWorldY * gdScaleY ) - sRadarCY + gsRadarY + ( sHeight /2 ) );
sRadarBRX = (INT16)( ( sBottomRightWorldX * gdScaleX ) - sRadarCX + sX + ( sWidth /2 ) );
sRadarBRY = (INT16)( ( sBottomRightWorldY * gdScaleY ) - sRadarCY + gsRadarY + ( sHeight /2 ) );
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
SetClippingRegionAndImageWidth( uiDestPitchBYTES, RADAR_WINDOW_X, gsRadarY, ( RADAR_WINDOW_X + RADAR_WINDOW_WIDTH - 1 ), ( gsRadarY + RADAR_WINDOW_HEIGHT - 1 ) );
if( !( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
{
if(gbPixelDepth==16)
{
usLineColor = Get16BPPColor( FROMRGB( 0, 255, 0 ) );
RectangleDraw( TRUE, sRadarTLX, sRadarTLY, sRadarBRX, sRadarBRY - 1, usLineColor, pDestBuf );
}
else if(gbPixelDepth==8)
{
// DB Need to change this to a color from the 8-but standard palette
usLineColor = COLOR_GREEN;
RectangleDraw8( TRUE, sRadarTLX + 1, sRadarTLY + 1, sRadarBRX + 1, sRadarBRY + 1, usLineColor, pDestBuf );
}
}
// Cycle fFlash variable
if ( COUNTERDONE( RADAR_MAP_BLINK ) )
{
RESETCOUNTER( RADAR_MAP_BLINK );
gfRadarCurrentGuyFlash = !gfRadarCurrentGuyFlash;
}
if( ( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) && ( fShowMapInventoryPool == TRUE ) )
{
INT32 iNumberOfItems = 0;
iNumberOfItems = GetTotalNumberOfItems( );
for( iCounter = 0; iCounter < MAP_INVENTORY_POOL_SLOT_COUNT; iCounter++ )
{
iItemNumber = iCounter + iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT;
// stolen item
if( ( pInventoryPoolList[ iItemNumber ].o.ubNumberOfObjects == 0 )||( pInventoryPoolList[ iItemNumber ].sGridNo == 0 ) )
{
// yep, continue on
continue;
}
ConvertGridNoToXY( pInventoryPoolList[ iItemNumber ].sGridNo, &sXSoldPos, &sYSoldPos );
GetWorldXYAbsoluteScreenXY( sXSoldPos, sYSoldPos, &sXSoldScreen, &sYSoldScreen );
// get radar x and y postion
sXSoldRadar = (INT16)( sXSoldScreen * gdScaleX );
sYSoldRadar = (INT16)( sYSoldScreen * gdScaleY );
// Add starting relative to interface
sXSoldRadar += RADAR_WINDOW_X;
sYSoldRadar += gsRadarY;
// if we are in 16 bit mode....kind of redundant
if(gbPixelDepth==16)
{
if( ( fFlashHighLightInventoryItemOnradarMap ) )
{
usLineColor = Get16BPPColor( FROMRGB( 0, 255, 0 ) );
}
else
{
// DB Need to add a radar color for 8-bit
usLineColor = Get16BPPColor( FROMRGB( 255, 255, 255 ) );
}
if( iCurrentlyHighLightedItem == iCounter )
{
RectangleDraw( TRUE, sXSoldRadar, sYSoldRadar, sXSoldRadar + 1, sYSoldRadar + 1, usLineColor, pDestBuf );
}
}
}
}
if( !( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
{
// RE-RENDER RADAR
for ( cnt = 0; cnt < guiNumMercSlots; cnt++ )
{
pSoldier = MercSlots[ cnt ];
if ( pSoldier != NULL )
{
// Don't place guys in radar until visible!
if ( pSoldier->bVisible == -1 && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) && !(pSoldier->ubMiscSoldierFlags & SOLDIER_MISC_XRAYED) )
{
continue;
}
// Don't render guys if they are dead!
if ( ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) )
{
continue;
}
// Don't render crows
if ( pSoldier->ubBodyType == CROW )
{
continue;
}
// Get FULL screen coordinate for guy's position
// Getxy from gridno
ConvertGridNoToXY( pSoldier->sGridNo, &sXSoldPos, &sYSoldPos );
GetWorldXYAbsoluteScreenXY( sXSoldPos, sYSoldPos, &sXSoldScreen, &sYSoldScreen );
sXSoldRadar = (INT16)( sXSoldScreen * gdScaleX );
sYSoldRadar = (INT16)( sYSoldScreen * gdScaleY );
if ( !SoldierOnVisibleWorldTile( pSoldier ) )
{
continue;
}
// Add starting relative to interface
sXSoldRadar += RADAR_WINDOW_X;
sYSoldRadar += gsRadarY;
if(gbPixelDepth==16)
{
// DB Need to add a radar color for 8-bit
// Are we a selected guy?
if ( pSoldier->ubID == gusSelectedSoldier )
{
if ( gfRadarCurrentGuyFlash )
{
usLineColor = 0;
}
else
{
// If on roof, make darker....
if ( pSoldier->bLevel > 0 )
{
usLineColor = Get16BPPColor( FROMRGB( 150, 150, 0 ) );
}
else
{
usLineColor = Get16BPPColor( gTacticalStatus.Team[ pSoldier->bTeam ].RadarColor );
}
}
}
else
{
usLineColor = Get16BPPColor( gTacticalStatus.Team[ pSoldier->bTeam ].RadarColor );
// Override civ team with red if hostile...
if ( pSoldier->bTeam == CIV_TEAM && !pSoldier->bNeutral && ( pSoldier->bSide != gbPlayerNum ) )
{
usLineColor = Get16BPPColor( FROMRGB( 255, 0, 0 ) );
}
// Render different color if an enemy and he's unconscious
if ( pSoldier->bTeam != gbPlayerNum && pSoldier->bLife < OKLIFE )
{
usLineColor = Get16BPPColor( FROMRGB( 128, 128, 128 ) );
}
// If on roof, make darker....
if ( pSoldier->bTeam == gbPlayerNum && pSoldier->bLevel > 0 )
{
usLineColor = Get16BPPColor( FROMRGB( 150, 150, 0 ) );
}
}
RectangleDraw( TRUE, sXSoldRadar, sYSoldRadar, sXSoldRadar+1, sYSoldRadar+1, usLineColor, pDestBuf );
}
else if(gbPixelDepth==8)
{
// DB Need to change this to a color from the 8-but standard palette
usLineColor = COLOR_BLUE;
RectangleDraw8( TRUE, sXSoldRadar, sYSoldRadar, sXSoldRadar+1, sYSoldRadar+1, usLineColor, pDestBuf );
}
}
}
}
UnLockVideoSurface( FRAME_BUFFER );
if( ( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) && ( fShowMapInventoryPool == TRUE ) )
{
InvalidateRegion( RADAR_WINDOW_X, gsRadarY,
RADAR_WINDOW_X + RADAR_WINDOW_WIDTH,
gsRadarY + RADAR_WINDOW_HEIGHT );
}
return;
}
void AdjustWorldCenterFromRadarCoords( INT16 sRadarX, INT16 sRadarY )
{
INT16 sScreenX, sScreenY;
INT16 sTempX_W, sTempY_W;
INT16 sNewCenterWorldX, sNewCenterWorldY;
INT16 sNumXSteps, sNumYSteps;
// Use radar scale values to get screen values, then convert ot map values, rounding to nearest middle tile
sScreenX = (INT16) ( sRadarX / gdScaleX );
sScreenY = (INT16) ( sRadarY / gdScaleY );
// Adjust to viewport start!
sScreenX -= ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 );
sScreenY -= ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 );
//Make sure these coordinates are multiples of scroll steps
sNumXSteps = sScreenX / SCROLL_X_STEP;
sNumYSteps = sScreenY / SCROLL_Y_STEP;
sScreenX = ( sNumXSteps * SCROLL_X_STEP );
sScreenY = ( sNumYSteps * SCROLL_Y_STEP );
// Adjust back
sScreenX += ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 );
sScreenY += ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 );
// Subtract world center
//sScreenX += gsCX;
//sScreenY += gsCY;
// Convert these into world coordinates
FromScreenToCellCoordinates( sScreenX, sScreenY, &sTempX_W, &sTempY_W );
// Adjust these to world center
sNewCenterWorldX = (INT16)(gCenterWorldX + sTempX_W);
sNewCenterWorldY = (INT16)(gCenterWorldY + sTempY_W);
SetRenderCenter( sNewCenterWorldX, sNewCenterWorldY );
}
void DisableRadarScreenRender( void )
{
fRenderRadarScreen = FALSE;
return;
}
void EnableRadarScreenRender( void )
{
fRenderRadarScreen = TRUE;
return;
}
void ToggleRadarScreenRender( void )
{
fRenderRadarScreen = ! fRenderRadarScreen;
return;
}
BOOLEAN CreateDestroyMouseRegionsForSquadList( void )
{
// will check the state of renderradarscreen flag and decide if we need to create mouse regions for
static BOOLEAN fCreated = FALSE;
INT16 sCounter = 0;
VOBJECT_DESC VObjectDesc;
HVOBJECT hHandle;
UINT32 uiHandle;
if( ( fRenderRadarScreen == FALSE ) && ( fCreated == FALSE ) )
{
// create regions
// load graphics
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\squadpanel.sti", VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &uiHandle));
GetVideoObject(&hHandle, uiHandle);
BltVideoObject( guiSAVEBUFFER , hHandle, 0,(INTERFACE_WIDTH - 102 - 1), 0 + gsVIEWPORT_END_Y, VO_BLT_SRCTRANSPARENCY,NULL );
RestoreExternBackgroundRect( (INTERFACE_WIDTH - 102), gsVIEWPORT_END_Y, (SCREEN_WIDTH - 538 ),( INT16 ) ( SCREEN_HEIGHT - gsVIEWPORT_END_Y ) );
for( sCounter = 0; sCounter < NUMBER_OF_SQUADS; sCounter++ )
{
// run through list of squads and place appropriatly
if( sCounter < NUMBER_OF_SQUADS / 2 )
{
// left half of list
MSYS_DefineRegion( &gRadarRegionSquadList[ sCounter ], RADAR_WINDOW_X , ( INT16 )( SQUAD_WINDOW_TM_Y + ( sCounter * ( ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / ( NUMBER_OF_SQUADS / 2 ) ) ) ), RADAR_WINDOW_X + RADAR_WINDOW_WIDTH / 2 - 1, ( INT16 )( SQUAD_WINDOW_TM_Y + ( ( sCounter + 1 ) * ( ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / ( NUMBER_OF_SQUADS / 2 ) ) ) ) ,MSYS_PRIORITY_HIGHEST,
0, TacticalSquadListMvtCallback, TacticalSquadListBtnCallBack );
}
else
{
// right half of list
MSYS_DefineRegion( &gRadarRegionSquadList[ sCounter ], RADAR_WINDOW_X + RADAR_WINDOW_WIDTH / 2, ( INT16 )( SQUAD_WINDOW_TM_Y + ( ( sCounter - ( NUMBER_OF_SQUADS / 2) ) * ( 2 * ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / NUMBER_OF_SQUADS ) ) ), RADAR_WINDOW_X + RADAR_WINDOW_WIDTH - 1, ( INT16 )( SQUAD_WINDOW_TM_Y + ( ( ( sCounter + 1 ) - ( NUMBER_OF_SQUADS / 2) )* ( 2 * ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / NUMBER_OF_SQUADS ) ) ), MSYS_PRIORITY_HIGHEST,
0, TacticalSquadListMvtCallback, TacticalSquadListBtnCallBack );
}
// set user data
MSYS_SetRegionUserData( &gRadarRegionSquadList[ sCounter ],0,sCounter);
}
DeleteVideoObjectFromIndex( uiHandle );
// reset the highlighted line
sSelectedSquadLine = -1;
// set fact regions are created
fCreated = TRUE;
}
else if( ( fRenderRadarScreen == TRUE ) && ( fCreated == TRUE ) )
{
// destroy regions
for( sCounter = 0; sCounter < NUMBER_OF_SQUADS; sCounter++ )
{
MSYS_RemoveRegion( &gRadarRegionSquadList[ sCounter ] );
}
// set fact regions are destroyed
fCreated = FALSE;
if ( guiCurrentScreen == GAME_SCREEN )
{
// dirty region
fInterfacePanelDirty = DIRTYLEVEL2;
MarkButtonsDirty( );
// re render region
RenderTacticalInterface( );
RenderButtons( );
// if game is paused, then render paused game text
RenderPausedGameBox( );
}
}
return( TRUE );
}
void RenderSquadList( void )
{
// show list of squads
INT16 sCounter = 0;
INT16 sX, sY;
// clear region
RestoreExternBackgroundRect( RADAR_WINDOW_X, gsRadarY, RADAR_WINDOW_WIDTH , SQUAD_REGION_HEIGHT );
// fill area
ColorFillVideoSurfaceArea( FRAME_BUFFER, RADAR_WINDOW_X, RADAR_WINDOW_TM_Y, RADAR_WINDOW_X + RADAR_WINDOW_WIDTH, RADAR_WINDOW_TM_Y + SQUAD_REGION_HEIGHT , Get16BPPColor( FROMRGB(0,0,0) ) );
// set font
SetFont( SQUAD_FONT );
for( sCounter = 0; sCounter < NUMBER_OF_SQUADS; sCounter++ )
{
// run through list of squads and place appropriatly
if( sCounter < NUMBER_OF_SQUADS / 2 )
{
FindFontCenterCoordinates( RADAR_WINDOW_X , ( INT16 )( SQUAD_WINDOW_TM_Y + ( sCounter * ( 2 * ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / NUMBER_OF_SQUADS ) ) ), RADAR_WINDOW_WIDTH / 2 - 1, ( INT16 )( ( ( 2 * ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / NUMBER_OF_SQUADS ) ) ) ,pSquadMenuStrings[ sCounter ] , SQUAD_FONT, &sX, &sY);
}
else
{
FindFontCenterCoordinates(RADAR_WINDOW_X + RADAR_WINDOW_WIDTH / 2, ( INT16 )( SQUAD_WINDOW_TM_Y + ( ( sCounter - ( NUMBER_OF_SQUADS / 2) ) * ( 2 * ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / NUMBER_OF_SQUADS ) ) ), RADAR_WINDOW_WIDTH / 2 - 1, ( INT16 )( ( ( 2 * ( SQUAD_REGION_HEIGHT - SUBTRACTOR_FOR_SQUAD_LIST ) / NUMBER_OF_SQUADS ) ) ), pSquadMenuStrings[ sCounter ] , SQUAD_FONT, &sX, &sY);
}
// highlight line?
if( sSelectedSquadLine == sCounter)
{
SetFontForeground( FONT_WHITE );
}
else
{
if( IsSquadOnCurrentTacticalMap( ( INT32 ) sCounter ) == TRUE )
{
if( CurrentSquad( ) == ( INT32 ) sCounter )
{
SetFontForeground( FONT_LTGREEN );
}
else
{
SetFontForeground( FONT_DKGREEN);
}
}
else
{
SetFontForeground( FONT_BLACK );
}
}
SetFontBackground( FONT_BLACK );
if( sCounter < NUMBER_OF_SQUADS / 2 )
{
sX = RADAR_WINDOW_X + 2;
}
else
{
sX = RADAR_WINDOW_X + ( RADAR_WINDOW_WIDTH / 2 ) - 2;
}
mprintf( sX, sY , pSquadMenuStrings[ sCounter ]);
}
}
void TacticalSquadListMvtCallback( MOUSE_REGION * pRegion, INT32 iReason )
{
INT32 iValue = -1;
iValue = MSYS_GetRegionUserData( pRegion, 0 );
if (iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE )
{
if( IsSquadOnCurrentTacticalMap( iValue ) == TRUE )
{
sSelectedSquadLine = ( INT16 )iValue;
}
}
if (iReason & MSYS_CALLBACK_REASON_LOST_MOUSE )
{
sSelectedSquadLine = -1;
}
return;
}
void TacticalSquadListBtnCallBack(MOUSE_REGION * pRegion, INT32 iReason )
{
// btn callback handler for team list info region
INT32 iValue = 0;
iValue = MSYS_GetRegionUserData( pRegion, 0 );
if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
{
// find out if this squad is valid and on this map..if so, set as selected
if( IsSquadOnCurrentTacticalMap( iValue ) == TRUE )
{
// ok, squad is here, set as selected
SetCurrentSquad( iValue, FALSE );
// stop showing
fRenderRadarScreen = TRUE;
}
}
return;
}
+42
View File
@@ -0,0 +1,42 @@
#ifndef __RADAR_SCREEN_H
#define __RADAR_SCREEN_H
#include "interface.h"
// RADAR MOUSE REGION STUFF
void RadarRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason );
void RadarRegionButtonCallback( MOUSE_REGION * pRegion, INT32 iReason );
BOOLEAN LoadRadarScreenBitmap( CHAR8 * aFilename );
// RADAR WINDOW DEFINES
#define RADAR_WINDOW_X 543
#define RADAR_WINDOW_TM_Y INTERFACE_START_Y + 13
#define RADAR_WINDOW_SM_Y INV_INTERFACE_START_Y + 13
#define RADAR_WINDOW_WIDTH 88
#define RADAR_WINDOW_HEIGHT 44
#define RADAR_WINDOW_STRAT_Y 373
BOOLEAN InitRadarScreen( );
void RenderRadarScreen( );
void MoveRadarScreen( );
// disable rendering of radar screen
void DisableRadarScreenRender( void );
// enable rendering of radar screen
void EnableRadarScreenRender( void );
// toggle rendering flag of radar screen
void ToggleRadarScreenRender( void );
// create destroy squad list regions as needed
BOOLEAN CreateDestroyMouseRegionsForSquadList( void );
// clear out the video object for the radar map
void ClearOutRadarMapImage( void );
// do we render the radar screen?..or the squad list?
extern BOOLEAN fRenderRadarScreen;
#endif
File diff suppressed because it is too large Load Diff
+152
View File
@@ -0,0 +1,152 @@
#ifndef __RENDER_DIRTY_H
#define __RENDER_DIRTY_H
//DEFINES
#define BGND_FLAG_PERMANENT 0x80000000
#define BGND_FLAG_SINGLE 0x40000000
#define BGND_FLAG_SAVE_Z 0x20000000
#define BGND_FLAG_MERC 0x10000000
#define BGND_FLAG_SAVERECT 0x08000000
#define BGND_FLAG_TOPMOST 0x04000000
#define BGND_FLAG_ANIMATED 0x00000001
#define VOVERLAY_DIRTYBYTEXT 0x00000001
#define VOVERLAY_STARTDISABLED 0x00000002
#define VOVERLAY_DESC_TEXT 0x00001000
#define VOVERLAY_DESC_DISABLED 0x00002000
#define VOVERLAY_DESC_POSITION 0x00004000
// STRUCTURES
// Callback for topmost blitters
typedef void (*OVERLAY_CALLBACK)(struct _VIDEO_OVERLAY * );
// Struct for backgrounds
typedef struct
{
BOOLEAN fAllocated;
BOOLEAN fFilled;
BOOLEAN fFreeMemory;
BOOLEAN fZBuffer;
UINT32 uiFlags;
INT16 *pSaveArea;
INT16 *pZSaveArea;
INT16 sLeft;
INT16 sTop;
INT16 sRight;
INT16 sBottom;
INT16 sWidth;
INT16 sHeight;
BOOLEAN fPendingDelete;
BOOLEAN fDisabled;
} BACKGROUND_SAVE;
// Struct for topmost blitters
typedef struct _VIDEO_OVERLAY
{
UINT32 uiFlags;
BOOLEAN fAllocated;
BOOLEAN fDisabled;
BOOLEAN fActivelySaving;
BOOLEAN fDeletionPending;
INT32 uiBackground;
BACKGROUND_SAVE *pBackground;
INT16 *pSaveArea;
UINT32 uiUserData[ 5 ];
UINT32 uiFontID;
INT16 sX;
INT16 sY;
UINT8 ubFontBack;
UINT8 ubFontFore;
INT16 zText[ 200 ];
UINT32 uiDestBuff;
OVERLAY_CALLBACK BltCallback;
} VIDEO_OVERLAY;
// Struct for init topmost blitter
typedef struct
{
UINT32 uiFlags;
BOOLEAN fDisabled;
INT16 sLeft;
INT16 sTop;
INT16 sRight;
INT16 sBottom;
UINT32 uiFontID;
INT16 sX;
INT16 sY;
UINT8 ubFontBack;
UINT8 ubFontFore;
INT16 pzText[ 200 ];
OVERLAY_CALLBACK BltCallback;
} VIDEO_OVERLAY_DESC;
// GLOBAL VARIABLES
extern SGPRect gDirtyClipRect;
// FUNCTIONS
////////////
// DIRTY QUEUE
BOOLEAN InitializeBaseDirtyRectQueue( );
void ShutdownBaseDirtyRectQueue( );
void AddBaseDirtyRect( INT32 iLeft, INT32 iTop, INT32 iRight, INT32 iBottom );
BOOLEAN ExecuteBaseDirtyRectQueue( );
BOOLEAN EmptyDirtyRectQueue( );
// BACKGROUND RECT BUFFERING STUFF
void DisableBackgroundRect( INT32 iIndex, BOOLEAN fDisabled );
BOOLEAN InitializeBackgroundRects(void);
BOOLEAN ShutdownBackgroundRects(void);
INT32 RegisterBackgroundRect(UINT32 uiFlags, INT16 *pSaveArea, INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom);
BOOLEAN FreeBackgroundRect(INT32 iIndex);
BOOLEAN FreeBackgroundRectPending(INT32 iIndex);
BOOLEAN FreeBackgroundRectType(UINT32 uiFlags);
BOOLEAN RestoreBackgroundRects(void);
BOOLEAN SaveBackgroundRects(void);
BOOLEAN InvalidateBackgroundRects(void);
BOOLEAN UpdateSaveBuffer(void);
BOOLEAN RestoreExternBackgroundRect( INT16 sLeft, INT16 sTop, INT16 sWidth, INT16 sHeight );
void SetBackgroundRectFilled( UINT32 uiBackgroundID );
BOOLEAN EmptyBackgroundRects( void );
// GPRINTF DIRTY STUFF
UINT16 gprintfdirty(INT16 x, INT16 y, UINT16 * pFontString, ...);
UINT16 gprintfinvalidate(INT16 x, INT16 y, UINT16 * pFontString, ...);
UINT16 gprintfRestore(INT16 x, INT16 y, UINT16 * pFontString, ...);
// VIDEO OVERLAY STUFF
INT32 GetFreeVideoOverlay(void);
void RecountVideoOverlays(void);
INT32 RegisterVideoOverlay( UINT32 uiFlags, VIDEO_OVERLAY_DESC *pTopmostDesc );
void ExecuteVideoOverlays( );
BOOLEAN UpdateVideoOverlay( VIDEO_OVERLAY_DESC *pTopmostDesc, UINT32 iBlitterIndex, BOOLEAN fForceAll );
void SaveVideoOverlaysArea( UINT32 uiSrcBuffer );
void DeleteVideoOverlaysArea( );
void AllocateVideoOverlaysArea( );
void ExecuteVideoOverlaysToAlternateBuffer( UINT32 uiNewDestBuffer );
void RemoveVideoOverlay( INT32 iVideoOverlay );
BOOLEAN RestoreShiftedVideoOverlays( INT16 sShiftX, INT16 sShiftY );
BOOLEAN SetOverlayUserData( INT32 iVideoOverlay, UINT8 ubNum, UINT32 uiData );
void EnableVideoOverlay( BOOLEAN fEnable, INT32 iOverlayIndex );
void BlitMFont( VIDEO_OVERLAY *pBlitter );
BOOLEAN BlitBufferToBuffer(UINT32 uiSrcBuffer, UINT32 uiDestBuffer, UINT16 usSrcX, UINT16 usSrcY, UINT16 usWidth, UINT16 usHeight);
#endif
+355
View File
@@ -0,0 +1,355 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "math.h"
#include <stdio.h>
#include <errno.h>
#include "Render Fun.h"
#include "worlddef.h"
#include "input.h"
#include "sysutil.h"
#include "debug.h"
#include "wcheck.h"
#include "worldman.h"
#include "jascreens.h"
#include "Isometric Utils.h"
#include "Timer Control.h"
#include "renderworld.h"
#include "fov.h"
#include "Fog Of War.h"
#include "environment.h"
#include "dialogue control.h"
#include "Random.h"
#endif
// Room Information
UINT8 gubWorldRoomInfo[ WORLD_MAX ];
UINT8 gubWorldRoomHidden[ MAX_ROOMS ];
BOOLEAN InitRoomDatabase( )
{
memset( gubWorldRoomInfo, NO_ROOM, sizeof( gubWorldRoomInfo ) );
memset( gubWorldRoomHidden, TRUE, sizeof( gubWorldRoomHidden ) );
return( TRUE );
}
void ShutdownRoomDatabase( )
{
}
void SetTileRoomNum( INT16 sGridNo, UINT8 ubRoomNum )
{
// Add to global room list
gubWorldRoomInfo[ sGridNo ] = ubRoomNum;
}
void SetTileRangeRoomNum( SGPRect *pSelectRegion, UINT8 ubRoomNum )
{
INT32 cnt1, cnt2;
for ( cnt1 = pSelectRegion->iTop; cnt1 <= pSelectRegion->iBottom; cnt1++ )
{
for ( cnt2 = pSelectRegion->iLeft; cnt2 <= pSelectRegion->iRight; cnt2++ )
{
gubWorldRoomInfo[ (INT16)MAPROWCOLTOPOS( cnt1, cnt2 ) ] = ubRoomNum;
}
}
}
BOOLEAN InARoom( UINT16 sGridNo, UINT8 *pubRoomNo )
{
if ( gubWorldRoomInfo[ sGridNo ] != NO_ROOM )
{
if ( pubRoomNo )
{
*pubRoomNo = gubWorldRoomInfo[ sGridNo ];
}
return( TRUE );
}
return( FALSE );
}
BOOLEAN InAHiddenRoom( UINT16 sGridNo, UINT8 *pubRoomNo )
{
if ( gubWorldRoomInfo[ sGridNo ] != NO_ROOM )
{
if ( (gubWorldRoomHidden[ gubWorldRoomInfo[ sGridNo ] ] ) )
{
*pubRoomNo = gubWorldRoomInfo[ sGridNo ];
return( TRUE );
}
}
return( FALSE );
}
// @@ATECLIP TO WORLD!
void SetRecalculateWireFrameFlagRadius(INT16 sX, INT16 sY, INT16 sRadius)
{
INT16 sCountX, sCountY;
UINT32 uiTile;
for(sCountY=sY-sRadius; sCountY < (sY+sRadius+2); sCountY++)
{
for(sCountX=sX-sRadius; sCountX < (sX+sRadius+2); sCountX++)
{
uiTile=MAPROWCOLTOPOS(sCountY, sCountX);
gpWorldLevelData[uiTile].uiFlags |= MAPELEMENT_RECALCULATE_WIREFRAMES;
}
}
}
void SetGridNoRevealedFlag( UINT16 sGridNo )
{
// UINT32 cnt;
// ITEM_POOL *pItemPool;
// INT16 sX, sY;
LEVELNODE *pNode = NULL;
STRUCTURE *pStructure, *pBase;
// Set hidden flag, for any roofs
SetRoofIndexFlagsFromTypeRange( sGridNo, FIRSTROOF, FOURTHROOF, LEVELNODE_HIDDEN );
// ATE: Do this only if we are in a room...
if ( gubWorldRoomInfo[ sGridNo ] != NO_ROOM )
{
SetStructAframeFlags( sGridNo, LEVELNODE_HIDDEN );
// Find gridno one east as well...
if ( ( sGridNo + WORLD_COLS ) < NOWHERE )
{
SetStructAframeFlags( sGridNo + WORLD_COLS, LEVELNODE_HIDDEN );
}
if ( ( sGridNo + 1 ) < NOWHERE )
{
SetStructAframeFlags( sGridNo + 1, LEVELNODE_HIDDEN );
}
}
// Set gridno as revealed
gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_REVEALED;
if( gfCaves )
{
RemoveFogFromGridNo( sGridNo );
}
// ATE: If there are any structs here, we can render them with the obscured flag!
// Look for anything but walls pn this gridno!
pStructure = gpWorldLevelData[ (INT16)sGridNo ].pStructureHead;
while ( pStructure != NULL )
{
if ( pStructure->sCubeOffset == STRUCTURE_ON_GROUND || ( pStructure->fFlags & STRUCTURE_SLANTED_ROOF ) )
{
if ( ( (pStructure->fFlags & STRUCTURE_OBSTACLE ) && !( pStructure->fFlags & ( STRUCTURE_PERSON | STRUCTURE_CORPSE ) ) ) || ( pStructure->fFlags & STRUCTURE_SLANTED_ROOF ) )
{
pBase = FindBaseStructure( pStructure );
//Ja25: DEF: 10/12/99 Added because ...
if( pBase == NULL )
{
pStructure = pStructure->pNext;
Assert( 0 );
continue;
}
// Get LEVELNODE for struct and remove!
pNode = FindLevelNodeBasedOnStructure( pBase->sGridNo, pBase );
if( pNode )
pNode->uiFlags |= LEVELNODE_SHOW_THROUGH;
if ( pStructure->fFlags & STRUCTURE_SLANTED_ROOF )
{
AddSlantRoofFOVSlot( pBase->sGridNo );
// Set hidden...
pNode->uiFlags |= LEVELNODE_HIDDEN;
}
}
}
pStructure = pStructure->pNext;
}
gubWorldRoomHidden[ gubWorldRoomInfo[ sGridNo ] ] = FALSE;
}
void ExamineGridNoForSlantRoofExtraGraphic( UINT16 sCheckGridNo )
{
LEVELNODE *pNode = NULL;
STRUCTURE *pStructure, *pBase;
UINT8 ubLoop;
DB_STRUCTURE_TILE ** ppTile;
INT16 sGridNo;
UINT16 usIndex;
BOOLEAN fChanged = FALSE;
// CHECK FOR A SLANTED ROOF HERE....
pStructure = FindStructure( sCheckGridNo, STRUCTURE_SLANTED_ROOF );
if ( pStructure != NULL )
{
// We have a slanted roof here ... find base and remove...
pBase = FindBaseStructure( pStructure );
// Get LEVELNODE for struct and remove!
pNode = FindLevelNodeBasedOnStructure( pBase->sGridNo, pBase );
// Loop through each gridno and see if revealed....
for ( ubLoop = 0; ubLoop < pBase->pDBStructureRef->pDBStructure->ubNumberOfTiles; ubLoop++ )
{
ppTile = pBase->pDBStructureRef->ppTile;
sGridNo = pBase->sGridNo + ppTile[ ubLoop ]->sPosRelToBase;
if (sGridNo < 0 || sGridNo > WORLD_MAX)
{
continue;
}
// Given gridno,
// IF NOT REVEALED AND HIDDEN....
if ( !( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) && pNode->uiFlags & LEVELNODE_HIDDEN )
{
// Add graphic if one does not already exist....
if ( !TypeExistsInRoofLayer( sGridNo, SLANTROOFCEILING, &usIndex ) )
{
// Add
AddRoofToHead( sGridNo, SLANTROOFCEILING1 );
fChanged = TRUE;
}
}
// Revealed?
if ( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED )
{
///Remove any slant roof items if they exist
if ( TypeExistsInRoofLayer( sGridNo, SLANTROOFCEILING, &usIndex ) )
{
RemoveRoof( sGridNo, usIndex );
fChanged = TRUE;
}
}
}
}
if ( fChanged )
{
// DIRTY THE WORLD!
InvalidateWorldRedundency();
SetRenderFlags(RENDER_FLAG_FULL );
}
}
void RemoveRoomRoof( UINT16 sGridNo, UINT8 bRoomNum, SOLDIERTYPE *pSoldier )
{
UINT32 cnt;
ITEM_POOL *pItemPool;
INT16 sX, sY;
LEVELNODE *pNode = NULL;
BOOLEAN fSaidItemSeenQuote = FALSE;
// STRUCTURE *pStructure;//, *pBase;
// LOOP THORUGH WORLD AND CHECK ROOM INFO
for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
{
if ( gubWorldRoomInfo[ cnt ] == bRoomNum )
{
SetGridNoRevealedFlag( (UINT16)cnt );
RemoveRoofIndexFlagsFromTypeRange( cnt, FIRSTROOF, SECONDSLANTROOF, LEVELNODE_REVEAL );
// Reveal any items if here!
if ( GetItemPool( (INT16)cnt, &pItemPool, 0 ) )
{
// Set visible! ( only if invisible... )
if ( SetItemPoolVisibilityOn( pItemPool, INVISIBLE, TRUE ) )
{
if ( !fSaidItemSeenQuote )
{
fSaidItemSeenQuote = TRUE;
if ( pSoldier != NULL )
{
TacticalCharacterDialogue( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ) );
}
}
}
}
// OK, re-set writeframes ( in a radius )
// Get XY
ConvertGridNoToXY( (INT16)cnt, &sX, &sY );
SetRecalculateWireFrameFlagRadius( sX, sY, 2 );
}
}
//for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
//{
// if ( gubWorldRoomInfo[ cnt ] == bRoomNum )
// {
// ExamineGridNoForSlantRoofExtraGraphic( (UINT16)cnt );
// }
//}
// DIRTY THE WORLD!
InvalidateWorldRedundency();
SetRenderFlags(RENDER_FLAG_FULL );
CalculateWorldWireFrameTiles( FALSE );
}
BOOLEAN AddSpecialTileRange( SGPRect *pSelectRegion )
{
INT32 cnt1, cnt2;
for ( cnt1 = pSelectRegion->iTop; cnt1 <= pSelectRegion->iBottom; cnt1++ )
{
for ( cnt2 = pSelectRegion->iLeft; cnt2 <= pSelectRegion->iRight; cnt2++ )
{
AddObjectToHead( (INT16)MAPROWCOLTOPOS( cnt1, cnt2 ), SPECIALTILE_MAPEXIT );
}
}
return( TRUE );
}
BOOLEAN RemoveSpecialTileRange( SGPRect *pSelectRegion )
{
INT32 cnt1, cnt2;
for ( cnt1 = pSelectRegion->iTop; cnt1 <= pSelectRegion->iBottom; cnt1++ )
{
for ( cnt2 = pSelectRegion->iLeft; cnt2 <= pSelectRegion->iRight; cnt2++ )
{
RemoveObject( (INT16)MAPROWCOLTOPOS( cnt1, cnt2 ), SPECIALTILE_MAPEXIT );
}
}
return( TRUE );
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef __RENDER_FUN_H
#define __RENDER_FUN_H
#include <stdio.h>
#include "worlddef.h"
#define NO_ROOM 0
#define MAX_ROOMS 250
extern UINT8 gubWorldRoomHidden[ MAX_ROOMS ];
extern UINT8 gubWorldRoomInfo[ WORLD_MAX ];
BOOLEAN InitRoomDatabase( );
void ShutdownRoomDatabase( );
void SetTileRoomNum( INT16 sGridNo, UINT8 ubRoomNum );
void SetTileRangeRoomNum( SGPRect *pSelectRegion, UINT8 ubRoomNum );
void RemoveRoomRoof( UINT16 sGridNo, UINT8 bRoomNum, SOLDIERTYPE *pSoldier );
BOOLEAN InARoom( UINT16 sGridNo, UINT8 *pubRoomNo );
BOOLEAN InAHiddenRoom( UINT16 sGridNo, UINT8 *pubRoomNo );
void SetGridNoRevealedFlag( UINT16 sGridNo );
void ExamineGridNoForSlantRoofExtraGraphic( UINT16 sCheckGridNo );
void SetRecalculateWireFrameFlagRadius(INT16 sX, INT16 sY, INT16 sRadius);
#endif
+247
View File
@@ -0,0 +1,247 @@
#include "worlddef.h"
#include "renderworld.h"
#include "Isometric Utils.h"
INT16 gsRScreenCenterX, gsRScreenCenterY;
INT16 gsRDistToCenterY, gsRDistToCenterX;
#define GetMapXYWorldY( sWorldCellX, sWorldCellY, sWorldY )\
{\
\
gsRDistToCenterX = ( sWorldCellX * CELL_X_SIZE ) - gCenterWorldX;\
gsRDistToCenterY = ( sWorldCellY * CELL_Y_SIZE ) - gCenterWorldY;\
\
gsRScreenCenterY = gsRDistToCenterX + gsRDistToCenterY;\
\
sWorldY = gsRScreenCenterY + gsCY - gsTLY;\
}
#define GetMapXYWorldYFromCellCoords( sWorldCellX, sWorldCellY, sWorldY )\
{\
\
gsRDistToCenterX = sWorldCellX - gCenterWorldX;\
gsRDistToCenterY = sWorldCellY - gCenterWorldY;\
\
gsRScreenCenterY = gsRDistToCenterX + gsRDistToCenterY;\
\
sWorldY = gsRScreenCenterY + gsCY - gsTLY;\
}
#define LandZLevel( sMapX, sMapY )\
{\
sZLevel = LAND_Z_LEVEL;\
}
#define ObjectZLevel( TileElem, pNode, sMapX, sMapY )\
{\
GetMapXYWorldY( sMapX, sMapY, sWorldY );\
\
if ( uiTileElemFlags & CLIFFHANG_TILE )\
{\
sZLevel=LAND_Z_LEVEL;\
}\
else if ( uiTileElemFlags & OBJECTLAYER_USEZHEIGHT )\
{\
sZLevel=( ( sWorldY ) *Z_SUBLAYERS)+LAND_Z_LEVEL;\
}\
else\
{\
sZLevel=OBJECT_Z_LEVEL;\
}\
}
#define StructZLevel( sMapX, sMapY )\
{\
\
GetMapXYWorldY( sMapX, sMapY, sWorldY );\
\
if ( ( uiLevelNodeFlags & LEVELNODE_ROTTINGCORPSE ) )\
{\
if ( pCorpse->def.usFlags & ROTTING_CORPSE_VEHICLE )\
{\
\
if ( pNode->pStructureData != NULL )\
{\
sZOffsetX = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetX;\
sZOffsetY = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetY;\
}\
\
GetMapXYWorldY( (sMapX + sZOffsetX), (sMapY + sZOffsetY), sWorldY );\
\
GetMapXYWorldY( (sMapX + sZOffsetX), (sMapY + sZOffsetY), sWorldY );\
\
sZLevel=( ( sWorldY ) * Z_SUBLAYERS)+STRUCT_Z_LEVEL;\
\
}\
else\
{\
sZOffsetX = -1;\
sZOffsetY = -1;\
GetMapXYWorldY( (sMapX + sZOffsetX), (sMapY + sZOffsetY), sWorldY );\
\
sWorldY += 20;\
\
sZLevel=( ( sWorldY ) * Z_SUBLAYERS)+LAND_Z_LEVEL;\
}\
}\
else if ( uiLevelNodeFlags & LEVELNODE_PHYSICSOBJECT )\
{\
sWorldY += pNode->sRelativeZ;\
\
sZLevel=(sWorldY*Z_SUBLAYERS)+ONROOF_Z_LEVEL;\
\
}\
else if ( uiLevelNodeFlags & LEVELNODE_ITEM )\
{\
if ( pNode->pItemPool->bRenderZHeightAboveLevel > 0 )\
{\
sZLevel=(sWorldY*Z_SUBLAYERS)+STRUCT_Z_LEVEL;\
sZLevel+=( pNode->pItemPool->bRenderZHeightAboveLevel );\
}\
else\
{\
sZLevel=(sWorldY*Z_SUBLAYERS)+OBJECT_Z_LEVEL;\
}\
}\
else if ( uiAniTileFlags & ANITILE_SMOKE_EFFECT )\
{\
sZLevel=(sWorldY*Z_SUBLAYERS)+OBJECT_Z_LEVEL;\
}\
else if ( ( uiLevelNodeFlags & LEVELNODE_USEZ ) )\
{\
\
if ( ( uiLevelNodeFlags & LEVELNODE_NOZBLITTER ) )\
{\
sWorldY += 40;\
}\
else\
{\
sWorldY += pNode->sRelativeZ;\
}\
\
sZLevel=(sWorldY*Z_SUBLAYERS)+ONROOF_Z_LEVEL;\
}\
else\
{\
sZLevel=(sWorldY*Z_SUBLAYERS)+STRUCT_Z_LEVEL;\
}\
\
}
#define RoofZLevel( sMapX, sMapY )\
{\
\
GetMapXYWorldY( sMapX, sMapY, sWorldY );\
\
sWorldY += WALL_HEIGHT;\
\
sZLevel=(sWorldY*Z_SUBLAYERS)+ROOF_Z_LEVEL;\
\
}
#define OnRoofZLevel( sMapX, sMapY )\
{\
\
GetMapXYWorldY( sMapX, sMapY, sWorldY );\
\
if ( uiLevelNodeFlags & LEVELNODE_ROTTINGCORPSE )\
{\
sWorldY += ( WALL_HEIGHT + 40 );\
}\
if ( uiLevelNodeFlags & LEVELNODE_ROTTINGCORPSE )\
{\
sWorldY += ( WALL_HEIGHT + 40 );\
}\
else\
{\
sWorldY += WALL_HEIGHT;\
}\
\
sZLevel=(sWorldY*Z_SUBLAYERS)+ONROOF_Z_LEVEL;\
\
}
#define TopmostZLevel( sMapX, sMapY )\
{\
\
GetMapXYWorldY( sMapX, sMapY, sWorldY );\
\
sZLevel=TOPMOST_Z_LEVEL;\
\
}
#define ShadowZLevel( sMapX, sMapY )\
{\
\
GetMapXYWorldY( sMapX, sMapY, sWorldY );\
\
sZLevel=__max( ( (sWorldY - 80 ) *Z_SUBLAYERS )+SHADOW_Z_LEVEL, 0 );\
\
}
#define SoldierZLevel( pSoldier, sMapX, sMapY )\
{\
\
if ( ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) )\
{\
\
if ( pNode->pStructureData != NULL )\
{\
sZOffsetX = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetX;\
sZOffsetY = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetY;\
}\
\
GetMapXYWorldY( (sMapX + sZOffsetX), (sMapY + sZOffsetY), sWorldY );\
\
}\
else\
{\
GetMapXYWorldY( sMapX, sMapY, sWorldY );\
}\
\
if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE )\
{\
sZLevel=(sWorldY*Z_SUBLAYERS)+STRUCT_Z_LEVEL;\
}\
else\
{\
if ( pSoldier->dHeightAdjustment > 0 )\
{\
sWorldY += ( WALL_HEIGHT + 20 );\
\
sZLevel=(sWorldY*Z_SUBLAYERS)+ONROOF_Z_LEVEL;\
}\
else\
{\
if ( ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) )\
{\
sZLevel=(sWorldY*Z_SUBLAYERS)+MERC_Z_LEVEL;\
}\
else\
{\
sZLevel=(sWorldY*Z_SUBLAYERS)+MERC_Z_LEVEL;\
}\
}\
\
if ( pSoldier->sZLevelOverride != -1 )\
{\
sZLevel = pSoldier->sZLevelOverride;\
}\
\
if ( gsForceSoldierZLevel != 0 )\
{\
sZLevel = gsForceSoldierZLevel;\
}\
}\
\
}
//#if 0
// sZOffsetX = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetX;\
//// sZOffsetY = pNode->pStructureData->pDBStructureRef->pDBStructure->bZTileOffsetY;\
//#endif
File diff suppressed because it is too large Load Diff
+115
View File
@@ -0,0 +1,115 @@
#ifndef _SAVELOADMAP__H_
#define _SAVELOADMAP__H_
#include "WorldDef.h"
#include "Exit Grids.h"
//Used for the ubType in the MODIFY_MAP struct
enum
{
SLM_NONE,
//Adding a map graphic
SLM_LAND,
SLM_OBJECT,
SLM_STRUCT,
SLM_SHADOW,
SLM_MERC, //Should never be used
SLM_ROOF,
SLM_ONROOF,
SLM_TOPMOST, //Should never be used
// For Removing
SLM_REMOVE_LAND,
SLM_REMOVE_OBJECT,
SLM_REMOVE_STRUCT,
SLM_REMOVE_SHADOW,
SLM_REMOVE_MERC, //Should never be used
SLM_REMOVE_ROOF,
SLM_REMOVE_ONROOF,
SLM_REMOVE_TOPMOST, //Should never be used
//Smell, or Blood is used
SLM_BLOOD_SMELL,
// Damage a particular struct
SLM_DAMAGED_STRUCT,
//Exit Grids
SLM_EXIT_GRIDS,
// State of Openable structs
SLM_OPENABLE_STRUCT,
// Modify window graphic & structure
SLM_WINDOW_HIT,
};
typedef struct
{
UINT16 usGridNo; //The gridno the graphic will be applied to
UINT16 usImageType; //graphic index
UINT16 usSubImageIndex; //
// UINT16 usIndex;
UINT8 ubType; // the layer it will be applied to
UINT8 ubExtra; // Misc. variable used to strore arbritary values
} MODIFY_MAP;
// Call this function, to set whether the map changes will be added to the map temp file
void ApplyMapChangesToMapTempFile( BOOLEAN fAddToMap );
BOOLEAN SaveModifiedMapStructToMapTempFile( MODIFY_MAP *pMap, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
//Applies a change TO THE MAP TEMP file
void AddStructToMapTempFile( UINT32 iMapIndex, UINT16 usIndex );
//Applies a change TO THE MAP from the temp file
void AddStructFromMapTempFileToMap( UINT32 iMapIndex, UINT16 usIndex );
void AddObjectToMapTempFile( UINT32 uiMapIndex, UINT16 usIndex );
BOOLEAN LoadAllMapChangesFromMapTempFileAndApplyThem( );
void RemoveStructFromMapTempFile( UINT32 uiMapIndex, UINT16 usIndex );
void AddRemoveObjectToMapTempFile( UINT32 uiMapIndex, UINT16 usIndex );
void SaveBloodSmellAndRevealedStatesFromMapToTempFile();
BOOLEAN SaveRevealedStatusArrayToRevealedTempFile( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
BOOLEAN LoadRevealedStatusArrayFromRevealedTempFile();
void AddRemoveObjectToUnLoadedMapTempFile( UINT32 uiMapIndex, UINT16 usIndex, INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ );
void RemoveStructFromUnLoadedMapTempFile( UINT32 uiMapIndex, UINT16 usIndex, INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ );
void AddObjectToUnLoadedMapTempFile( UINT32 uiMapIndex, UINT16 usIndex, INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ );
void AddStructToUnLoadedMapTempFile( UINT32 uiMapIndex, UINT16 usIndex, INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ );
//Adds the exit grid to
void AddExitGridToMapTempFile( UINT16 usGridNo, EXITGRID *pExitGrid, INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ );
//This function removes a struct with the same MapIndex and graphic index from the given sectors temp file
BOOLEAN RemoveGraphicFromTempFile( UINT32 uiMapIndex, UINT16 usIndex, INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ );
void SetOpenableStructStatusFromMapTempFile( UINT32 uiMapIndex, BOOLEAN fOpened );
void AddOpenableStructStatusToMapTempFile( UINT32 uiMapIndex, BOOLEAN fOpened );
void AddWindowHitToMapTempFile( UINT32 uiMapIndex );
BOOLEAN ChangeStatusOfOpenableStructInUnloadedSector( UINT16 usSectorX, UINT16 usSectorY, INT8 bSectorZ, UINT16 usGridNo, BOOLEAN fChangeToOpen );
#endif
+218
View File
@@ -0,0 +1,218 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include "types.h"
#include "lighting.h"
#include "Shade Table Util.h"
#include "video.h"
#include "WorldDat.h"
#include "Fileman.h"
#endif
#define SHADE_TABLE_DIR "ShadeTables"
extern CHAR8 TileSurfaceFilenames[NUMBEROFTILETYPES][32]; // symbol already declared globally in worlddef.cpp (jonathanl)
BOOLEAN gfForceBuildShadeTables = FALSE;
#ifdef JA2TESTVERSION
extern UINT32 uiNumTablesSaved;
extern UINT32 uiNumTablesLoaded;
#endif
void DetermineRGBDistributionSettings()
{
STRING512 DataDir;
STRING512 ExecDir;
STRING512 ShadeTableDir;
UINT32 uiRBitMask, uiGBitMask, uiBBitMask;
UINT32 uiPrevRBitMask, uiPrevGBitMask, uiPrevBBitMask;
UINT32 uiNumBytesRead;
HWFILE hfile;
BOOLEAN fSaveRGBDist = FALSE;
BOOLEAN fCleanShadeTable = FALSE;
BOOLEAN fLoadedPrevRGBDist = FALSE;
// Snap: save current directory
GetFileManCurrentDirectory( DataDir );
//First, determine if we have a file saved. If not, then this is the first time, and
//all shade tables will have to be built and saved to disk. This can be time consuming, adding up to
//3-4 seconds to the time of a map load.
GetExecutableDirectory( ExecDir );
sprintf( ShadeTableDir, "%s\\%s", DataDir, SHADE_TABLE_DIR );
//Check to make sure we have a ShadeTable directory. If we don't create one!
if( !SetFileManCurrentDirectory( ShadeTableDir ) )
{
if( !MakeFileManDirectory( ShadeTableDir ) )
{
AssertMsg( 0, "ShadeTable directory doesn't exist, and couldn't create one!" );
}
if( !SetFileManCurrentDirectory( ShadeTableDir ) )
{
AssertMsg( 0, "Couldn't access the newly created ShadeTable directory." );
}
fSaveRGBDist = TRUE;
}
if( !fSaveRGBDist )
{ //Load the previous RGBDist and determine if it is the same one
if( !FileExists( "RGBDist.dat" ) || FileExists( "ResetShadeTables.txt" ) )
{ //Can't find the RGBDist.dat file. The directory exists, but the file doesn't, which
//means the user deleted the file manually. Now, set it up to create a new one.
fSaveRGBDist = TRUE;
fCleanShadeTable = TRUE;
}
else
{
hfile = FileOpen( "RGBDist.dat", FILE_ACCESS_READ, FALSE );
if( !hfile )
{
AssertMsg( 0, "Couldn't open RGBDist.dat, even though it exists!" );
}
FileRead( hfile, &uiPrevRBitMask, sizeof( UINT32 ), &uiNumBytesRead );
FileRead( hfile, &uiPrevGBitMask, sizeof( UINT32 ), &uiNumBytesRead );
FileRead( hfile, &uiPrevBBitMask, sizeof( UINT32 ), &uiNumBytesRead );
fLoadedPrevRGBDist = TRUE;
FileClose( hfile );
}
}
if( !GetPrimaryRGBDistributionMasks( &uiRBitMask, &uiGBitMask, &uiBBitMask ) )
{
AssertMsg( 0, "Failed to extract the current RGB distribution masks." );
}
if( fLoadedPrevRGBDist )
{
if( uiRBitMask != uiPrevRBitMask || uiGBitMask != uiPrevGBitMask || uiBBitMask != uiPrevBBitMask )
{ //The user has changed modes since the last time he has played JA2. This essentially can only happen if:
//1) The video card has been changed since the last run of JA2.
//2) Certain video cards have different RGB distributions in different operating systems such as
// the Millenium card using Windows NT or Windows 95
//3) The user has physically modified the RGBDist.dat file.
fSaveRGBDist = TRUE;
fCleanShadeTable = TRUE;
}
}
if( fCleanShadeTable )
{ //This means that we are going to remove all of the current shade tables, if any exist, and
//start fresh.
EraseDirectory( ShadeTableDir );
}
if( fSaveRGBDist )
{ //The RGB distribution is going to be saved in a tiny file for future reference. As long as the
//RGB distribution never changes, the shade table will grow until eventually, all tilesets are loaded,
//shadetables generated and saved in this directory.
hfile = FileOpen( "RGBDist.dat", FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
if( !hfile )
{
AssertMsg( 0, "Couldn't create RGBDist.dat for writing!" );
}
FileWrite( hfile, &uiRBitMask, sizeof( UINT32 ), &uiNumBytesRead );
FileWrite( hfile, &uiGBitMask, sizeof( UINT32 ), &uiNumBytesRead );
FileWrite( hfile, &uiBBitMask, sizeof( UINT32 ), &uiNumBytesRead );
FileClose( hfile );
}
// Snap: Restore the data directory once we are finished.
SetFileManCurrentDirectory( DataDir );
//We're done, so restore the executable directory to JA2\Data.
//sprintf( DataDir, "%s\\Data", ExecDir );
//SetFileManCurrentDirectory( DataDir );
}
BOOLEAN LoadShadeTable( HVOBJECT pObj, UINT32 uiTileTypeIndex )
{
HWFILE hfile;
INT32 i;
UINT32 uiNumBytesRead;
UINT8 ShadeFileName[ 100 ];
UINT8 *ptr;
//ASSUMPTIONS:
//We are assuming that the uiTileTypeIndex is referring to the correct file
//stored in the TileSurfaceFilenames[]. If it isn't, then that is a huge problem
//and should be fixed. Also assumes that the directory is set to Data\ShadeTables.
strcpy( ShadeFileName, TileSurfaceFilenames[ uiTileTypeIndex ] );
ptr = (UINT8 *)strstr( ShadeFileName, "." );
if( !ptr )
{
return FALSE;
}
ptr++;
sprintf( (char *)ptr, "sha" );
hfile = FileOpen( (STR)ShadeFileName, FILE_ACCESS_READ, FALSE );
if( !hfile )
{ //File doesn't exist, so generate it
FileClose( hfile );
return FALSE;
}
//MISSING: Compare time stamps.
for( i = 0; i < 16; i++ )
{
pObj->pShades[ i ] = (UINT16 *) MemAlloc( 512 );
Assert( pObj->pShades[ i ] );
FileRead( hfile, pObj->pShades[ i ], 512, &uiNumBytesRead );
}
//The file exists, now make sure the
FileClose( hfile );
#ifdef JA2TESTVERSION
uiNumTablesLoaded++;
#endif
return TRUE;
}
BOOLEAN SaveShadeTable( HVOBJECT pObj, UINT32 uiTileTypeIndex )
{
HWFILE hfile;
INT32 i;
UINT32 uiNumBytesWritten;
UINT8 ShadeFileName[ 100 ];
UINT8 *ptr;
#ifdef JA2TESTVERSION
uiNumTablesSaved++;
#endif
//ASSUMPTIONS:
//We are assuming that the uiTileTypeIndex is referring to the correct file
//stored in the TileSurfaceFilenames[]. If it isn't, then that is a huge problem
//and should be fixed. Also assumes that the directory is set to Data\ShadeTables.
strcpy( ShadeFileName, TileSurfaceFilenames[ uiTileTypeIndex ] );
ptr = (UINT8 *)strstr( ShadeFileName, "." );
if( !ptr )
{
return FALSE;
}
ptr++;
sprintf( (char *) ptr, "sha" );
hfile = FileOpen( (STR)ShadeFileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
if( !hfile )
{
FileClose( hfile );
AssertMsg( 0, String( "Can't create %s", ShadeFileName ) );
return FALSE;
}
for( i = 0; i < 16; i++ )
{
FileWrite( hfile, pObj->pShades[ i ], 512, &uiNumBytesWritten );
}
FileClose( hfile );
return TRUE;
}
BOOLEAN DeleteShadeTableDir( )
{
return( RemoveFileManDirectory( SHADE_TABLE_DIR, TRUE ) );
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef __SHADE_TABLE_UTIL_H
#define __SHADE_TABLE_UTIL_H
#include "TileDat.h"
void DetermineRGBDistributionSettings();
BOOLEAN LoadShadeTable( HVOBJECT pObj, UINT32 uiTileTypeIndex );
BOOLEAN SaveShadeTable( HVOBJECT pObj, UINT32 uiTileTypeIndex );
extern CHAR8 TileSurfaceFilenames[NUMBEROFTILETYPES][32];
extern BOOLEAN gfForceBuildShadeTables;
BOOLEAN DeleteShadeTableDir( );
#endif
+38
View File
@@ -0,0 +1,38 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "types.h"
#include "Isometric Utils.h"
#include "renderworld.h"
#endif
void MarkMapIndexDirty( INT32 iMapIndex )
{
gpWorldLevelData[ iMapIndex ].uiFlags |= MAPELEMENT_REDRAW;
SetRenderFlags( RENDER_FLAG_MARKED );
}
void CenterScreenAtMapIndex( INT32 iMapIndex )
{
INT16 sWorldX, sWorldY;
INT16 sCellX, sCellY;
//Get X, Y world GRID Coordinates
sWorldY = ( iMapIndex / WORLD_COLS );
sWorldX = iMapIndex - ( sWorldY * WORLD_COLS );
//Convert into cell coords
sCellY = sWorldY * CELL_Y_SIZE;
sCellX = sWorldX * CELL_X_SIZE;
//Set the render values, so that the screen will render here next frame.
gsRenderCenterX = sCellX;
gsRenderCenterY = sCellY;
SetRenderFlags( RENDER_FLAG_FULL );
}
void MarkWorldDirty()
{
SetRenderFlags( RENDER_FLAG_FULL );
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef __SIMPLE_RENDER_UTILS_H
#define __SIMPLE_RENDER_UTILS_H
void MarkMapIndexDirty( INT32 iMapIndex );
void CenterScreenAtMapIndex( INT32 iMapIndex );
void MarkWorldDirty();
#endif
+577
View File
@@ -0,0 +1,577 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "worlddef.h"
#include "Random.h"
#include "Smell.h"
#include "worldman.h"
#include "renderworld.h"
#include "SaveLoadMap.h"
#include "gamesettings.h"
#include "message.h"
#include "Isometric utils.h"
#endif
/*
* Smell & Blood system
*
* Smell and blood trails decay as time passes.
*
* Decay Rate Maximum Strength Decay Time: Min Max (for biggest volume)
*
* Smell 1 per turn 31 31 31
* Blood 1 every 1-3 turns 7 7 21
*
* Smell has a much finer resolution so that creatures which track by smell
* can do so effectively.
*/
/*
* Time for some crazy-ass macros!
* The smell byte is spit as follows:
* O \
* O \
* O \ Smell
* O / Strength (only on ground)
* O /
* O /
* O > Type of blood on roof
* O > Type of smell/blood on ground
*
* The blood byte is split as follows:
* O \
* O > Blood quantity on roof
* O /
* O \
* O > Blood quantity on ground
* O /
* O \ Blood decay
* O / time (roof and ground decay together)
*/
/*
* In these defines,
* s indicates the smell byte, b indicates the blood byte
*/
// LUT for which graphic to use based on strength
// 0 1, 2, 3, 4, 5, 6, 7
UINT8 ubBloodGraphicLUT [ ] = { 3, 3, 2, 2, 1, 1, 0, 0 };
#define SMELL_STRENGTH_MAX 63
#define BLOOD_STRENGTH_MAX 7
#define BLOOD_DELAY_MAX 3
#define SMELL_TYPE_BITS( s ) (s & 0x03)
#define BLOOD_ROOF_TYPE( s ) (s & 0x02)
#define BLOOD_FLOOR_TYPE( s ) (s & 0x01)
#define BLOOD_ROOF_STRENGTH( b ) (b & 0xE0)
#define BLOOD_FLOOR_STRENGTH( b ) ( (b & 0x1C) >> 2 )
#define BLOOD_DELAY_TIME( b ) (b & 0x03)
#define NO_BLOOD_STRENGTH( b ) ((b & 0xFC) == 0)
#define DECAY_SMELL_STRENGTH( s ) \
{ \
UINT8 ubStrength = SMELL_STRENGTH( (s) ); \
ubStrength--; \
ubStrength = ubStrength << SMELL_TYPE_NUM_BITS; \
(s) = SMELL_TYPE_BITS( (s) ) | ubStrength; \
}
// s = smell byte
// ns = new strength
// ntf = new type on floor
// Note that the first part of the macro is designed to
// preserve the type value for the blood on the roof
#define SET_SMELL( s, ns, ntf ) \
{ \
(s) = (BLOOD_ROOF_TYPE( s )) | SMELL_TYPE( ntf ) | (ns << SMELL_TYPE_NUM_BITS); \
}
#define DECAY_BLOOD_DELAY_TIME( b ) \
{ \
(b)--; \
}
#define SET_BLOOD_FLOOR_STRENGTH( b, nb ) \
{ \
(b) = ( (nb) << 2 ) | ( (b) & 0xE3); \
}
#define SET_BLOOD_ROOF_STRENGTH( b, nb ) \
{ \
(b) = BLOOD_FLOOR_STRENGTH( (nb) ) << 5 | ( (b) & 0x1F); \
}
#define DECAY_BLOOD_FLOOR_STRENGTH( b ) \
{ \
UINT8 ubFloorStrength; \
ubFloorStrength = BLOOD_FLOOR_STRENGTH( (b) ); \
ubFloorStrength--; \
SET_BLOOD_FLOOR_STRENGTH( b, ubFloorStrength ); \
}
#define DECAY_BLOOD_ROOF_STRENGTH( b ) \
{ \
UINT8 ubRoofStrength; \
ubRoofStrength = BLOOD_ROOF_STRENGTH( (b) ); \
ubRoofStrength--; \
SET_BLOOD_FLOOR_STRENGTH( b, ubRoofStrength ); \
}
#define SET_BLOOD_DELAY_TIME( b ) \
{ \
(b) = BLOOD_DELAY_TIME( (UINT8) Random( BLOOD_DELAY_MAX ) + 1 ) | (b & 0xFC); \
}
#define SET_BLOOD_FLOOR_TYPE( s, ntg ) \
{ \
(s) = BLOOD_FLOOR_TYPE( ntg ) | (s & 0xFE); \
}
#define SET_BLOOD_ROOF_TYPE( s, ntr ) \
{ \
(s) = BLOOD_ROOF_TYPE( ntr ) | (s & 0xFD); \
}
void RemoveBlood( INT16 sGridNo, INT8 bLevel )
{
gpWorldLevelData[ sGridNo ].ubBloodInfo = 0;
gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_REEVALUATEBLOOD;
UpdateBloodGraphics( sGridNo, bLevel );
}
void DecaySmells( void )
{
UINT32 uiLoop;
MAP_ELEMENT * pMapElement;
//return;
for (uiLoop = 0, pMapElement = gpWorldLevelData; uiLoop < WORLD_MAX; uiLoop++, pMapElement++)
{
if (pMapElement->ubSmellInfo)
{
// decay smell strength!
DECAY_SMELL_STRENGTH( pMapElement->ubSmellInfo );
// if the strength left is 0, wipe the whole byte to clear the type
if (SMELL_STRENGTH( pMapElement->ubSmellInfo ) == 0)
{
pMapElement->ubSmellInfo = 0;
}
}
}
}
void DecayBlood()
{
UINT32 uiLoop;
MAP_ELEMENT * pMapElement;
for (uiLoop = 0, pMapElement = gpWorldLevelData; uiLoop < WORLD_MAX; uiLoop++, pMapElement++)
{
if (pMapElement->ubBloodInfo)
{
// delay blood timer!
DECAY_BLOOD_DELAY_TIME( pMapElement->ubBloodInfo );
if (BLOOD_DELAY_TIME( pMapElement->ubBloodInfo ) == 0)
{
// Set re-evaluate flag
pMapElement->uiFlags |= MAPELEMENT_REEVALUATEBLOOD;
// reduce the floor blood strength if it is above zero
if (BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo ) > 0)
{
DECAY_BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo )
if (BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo ) == 0)
{
// delete the blood graphic on the floor!
// then
if (NO_BLOOD_STRENGTH( pMapElement->ubBloodInfo ))
{
// wipe the whole byte to zero
pMapElement->ubBloodInfo = 0;
}
}
}
// reduce the roof blood strength if it is above zero
if (BLOOD_ROOF_STRENGTH( pMapElement->ubBloodInfo ) > 0)
{
DECAY_BLOOD_ROOF_STRENGTH( pMapElement->ubBloodInfo )
if (BLOOD_ROOF_STRENGTH( pMapElement->ubBloodInfo ) == 0)
{
// delete the blood graphic on the roof!
if (NO_BLOOD_STRENGTH( pMapElement->ubBloodInfo ))
{
// wipe the whole byte to zero
pMapElement->ubBloodInfo = 0;
}
}
}
// if any blood remaining, reset time
if ( pMapElement->ubBloodInfo )
{
SET_BLOOD_DELAY_TIME( pMapElement->ubBloodInfo );
}
}
// end of blood handling
}
// now go on to the next gridno
}
}
void DecayBloodAndSmells( UINT32 uiTime )
{
UINT32 uiCheckTime;
if ( !gfWorldLoaded )
{
return;
}
// period between checks, in game seconds
switch( giTimeCompressMode )
{
// in time compression, let this happen every 5 REAL seconds
case TIME_COMPRESS_5MINS: // rate of 300 seconds per real second
uiCheckTime = 5 * 300;
break;
case TIME_COMPRESS_30MINS: // rate of 1800 seconds per real second
uiCheckTime = 5 * 1800;
break;
case TIME_COMPRESS_60MINS: // rate of 3600 seconds per real second
case TIME_SUPER_COMPRESS: // should not be used but just in frigging case...
uiCheckTime = 5 * 3600;
break;
default: // not compressing
uiCheckTime = 100;
break;
}
// ok so "uiDecayBloodLastUpdate" is a bit of a misnomer now
if ( ( uiTime - gTacticalStatus.uiDecayBloodLastUpdate ) > uiCheckTime )
{
gTacticalStatus.uiDecayBloodLastUpdate = uiTime;
DecayBlood();
DecaySmells();
}
}
void DropSmell( SOLDIERTYPE * pSoldier )
{
MAP_ELEMENT * pMapElement;
UINT8 ubOldSmell;
UINT8 ubOldStrength;
UINT8 ubSmell;
UINT8 ubStrength;
/*
* Here we are creating a new smell on the ground. If there is blood in
* the tile, it overrides dropping smells of any type
*/
if (pSoldier->bLevel == 0)
{
pMapElement = &(gpWorldLevelData[pSoldier->sGridNo]);
if (pMapElement->ubBloodInfo)
{
// blood here, don't drop any smell
return;
}
if (pSoldier->bNormalSmell > pSoldier->bMonsterSmell)
{
ubStrength = pSoldier->bNormalSmell - pSoldier->bMonsterSmell;
ubSmell = HUMAN;
}
else
{
ubStrength = pSoldier->bMonsterSmell - pSoldier->bNormalSmell;
if (ubStrength == 0)
{
// don't drop any smell
return;
}
ubSmell = CREATURE_ON_FLOOR;
}
if (pMapElement->ubSmellInfo)
{
// smell already exists here; check to see if it's the same or not
ubOldSmell = SMELL_TYPE( pMapElement->ubSmellInfo );
ubOldStrength = SMELL_STRENGTH( pMapElement->ubSmellInfo );
if (ubOldSmell == ubSmell)
{
// same smell; increase the strength to the bigger of the two strengths,
// plus 1/5 of the smaller
ubStrength = __max( ubStrength, ubOldStrength ) + __min( ubStrength, ubOldStrength ) / 5;
ubStrength = __max( ubStrength, SMELL_STRENGTH_MAX );
}
else
{
// different smell; we muddy the smell by reducing the smell strength
if (ubOldStrength > ubStrength)
{
ubOldStrength -= ubStrength / 3;
SET_SMELL( pMapElement->ubSmellInfo, ubOldStrength, ubOldSmell );
}
else
{
ubStrength -= ubOldStrength / 3;
if (ubStrength > 0)
{
SET_SMELL( pMapElement->ubSmellInfo, ubStrength, ubSmell );
}
else
{
// smell reduced to 0 - wipe all info on it!
pMapElement->ubSmellInfo = 0;
}
}
}
}
else
{
// the simple case, dropping a smell in a location where there is none
SET_SMELL( pMapElement->ubSmellInfo, ubStrength, ubSmell );
}
}
// otherwise skip dropping smell
}
void InternalDropBlood( INT16 sGridNo, INT8 bLevel, UINT8 ubType, UINT8 ubStrength, INT8 bVisible )
{
MAP_ELEMENT * pMapElement;
UINT8 ubOldStrength=0;
UINT8 ubNewStrength=0;
/*
* Dropping some blood;
* We can check the type of blood by consulting the type in the smell byte
*/
// If we are in water...
if ( GetTerrainType( sGridNo ) == DEEP_WATER || GetTerrainType( sGridNo ) == LOW_WATER || GetTerrainType( sGridNo ) == MED_WATER )
{
return;
}
// ATE: Send warning if dropping blood nowhere....
if ( sGridNo == NOWHERE )
{
#ifdef JA2BETAVERSION
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Attempting to drop blood NOWHERE" );
#endif
return;
}
// ensure max strength is okay
ubStrength = __min( ubStrength, BLOOD_STRENGTH_MAX );
pMapElement = &(gpWorldLevelData[ sGridNo ]);
if ( bLevel == 0 )
{
// dropping blood on ground
ubOldStrength = BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo );
if (ubOldStrength > 0)
{
// blood already there... we'll leave the decay time as it is
if (BLOOD_FLOOR_TYPE( pMapElement->ubBloodInfo ) == ubType)
{
// combine blood strengths!
ubNewStrength = __min( ( ubOldStrength + ubStrength ), BLOOD_STRENGTH_MAX );
SET_BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo, ubNewStrength );
}
else
{
// replace the existing blood if more is being dropped than exists
if (ubStrength > ubOldStrength )
{
// replace!
SET_BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo, ubStrength );
}
// else we don't drop anything at all
}
}
else
{
// no blood on the ground yet, so drop this amount!
// set decay time
SET_BLOOD_DELAY_TIME( pMapElement->ubBloodInfo );
SET_BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo, ubStrength );
// NB blood floor type stored in smell byte!
SET_BLOOD_FLOOR_TYPE( pMapElement->ubSmellInfo, ubType );
}
}
else
{
// dropping blood on roof
ubOldStrength = BLOOD_ROOF_STRENGTH( pMapElement->ubBloodInfo );
if (ubOldStrength > 0)
{
// blood already there... we'll leave the decay time as it is
if (BLOOD_ROOF_TYPE( pMapElement->ubSmellInfo ) == ubType)
{
// combine blood strengths!
ubNewStrength = __max( ubOldStrength, ubStrength ) + 1;
// make sure the strength is legal
ubNewStrength = __max( ubNewStrength, BLOOD_STRENGTH_MAX );
SET_BLOOD_ROOF_STRENGTH( pMapElement->ubBloodInfo, ubNewStrength );
}
else
{
// replace the existing blood if more is being dropped than exists
if (ubStrength > ubOldStrength )
{
// replace!
SET_BLOOD_ROOF_STRENGTH( pMapElement->ubBloodInfo, ubStrength );
}
// else we don't drop anything at all
}
}
else
{
// no blood on the roof yet, so drop this amount!
// set decay time
SET_BLOOD_DELAY_TIME( pMapElement->ubBloodInfo );
SET_BLOOD_ROOF_STRENGTH( pMapElement->ubBloodInfo, ubNewStrength );
SET_BLOOD_ROOF_TYPE( pMapElement->ubSmellInfo, ubType );
}
}
// Turn on flag...
pMapElement->uiFlags |= MAPELEMENT_REEVALUATEBLOOD;
if ( bVisible != -1 )
{
UpdateBloodGraphics( sGridNo, bLevel );
}
}
void DropBlood( SOLDIERTYPE * pSoldier, UINT8 ubStrength, INT8 bVisible )
{
UINT8 ubType;
UINT8 ubOldStrength=0;
UINT8 ubNewStrength=0;
/*
* Dropping some blood;
* We can check the type of blood by consulting the type in the smell byte
*/
// figure out the type of blood that we're dropping
if ( pSoldier->uiStatusFlags & SOLDIER_MONSTER )
{
if ( pSoldier->bLevel == 0 )
{
ubType = CREATURE_ON_FLOOR;
}
else
{
ubType = CREATURE_ON_ROOF;
}
}
else
{
ubType = 0;
}
InternalDropBlood( pSoldier->sGridNo, pSoldier->bLevel, ubType, ubStrength, bVisible );
}
void UpdateBloodGraphics( INT16 sGridNo, INT8 bLevel )
{
MAP_ELEMENT * pMapElement;
INT8 bValue;
UINT16 usIndex, usNewIndex;
// OK, based on level, type, display graphics for blood
pMapElement = &(gpWorldLevelData[ sGridNo ]);
// CHECK FOR BLOOD OPTION
if ( !gGameSettings.fOptions[ TOPTION_BLOOD_N_GORE ] )
{
return;
}
if ( pMapElement->uiFlags & MAPELEMENT_REEVALUATEBLOOD )
{
// Turn off flag!
pMapElement->uiFlags &= ( ~MAPELEMENT_REEVALUATEBLOOD );
// Ground
if ( bLevel == 0 )
{
bValue = BLOOD_FLOOR_STRENGTH( pMapElement->ubBloodInfo );
// OK, remove tile graphic if one exists....
if ( TypeRangeExistsInObjectLayer( sGridNo, HUMANBLOOD, CREATUREBLOOD, &usIndex ) )
{
//This has been removed and it is handled by the ubBloodInfo level when restoring a saved game.
//Set a flag indicating that the following changes are to go the the maps temp file
//ApplyMapChangesToMapTempFile( TRUE );
// Remove
RemoveObject( sGridNo, usIndex );
//ApplyMapChangesToMapTempFile( FALSE );
}
// OK, pick new one. based on strength and randomness
if ( bValue > 0 )
{
usIndex = (UINT16)( ( Random( 4 ) * 4 ) + ubBloodGraphicLUT[ bValue ] );
if ( BLOOD_FLOOR_TYPE( pMapElement->ubSmellInfo ) == 0 )
{
GetTileIndexFromTypeSubIndex( HUMANBLOOD, (UINT16)(usIndex + 1), &usNewIndex );
}
else
{
GetTileIndexFromTypeSubIndex( CREATUREBLOOD, (UINT16)(usIndex + 1), &usNewIndex );
}
//This has been removed and it is handled by the ubBloodInfo level when restoring a saved game.
//Set a flag indicating that the following changes are to go the the maps temp file
//ApplyMapChangesToMapTempFile( TRUE );
// Add!
AddObjectToHead( sGridNo, usNewIndex );
//ApplyMapChangesToMapTempFile( FALSE );
// Update rendering!
pMapElement->uiFlags|=MAPELEMENT_REDRAW;
SetRenderFlags(RENDER_FLAG_MARKED);
}
}
// Roof
else
{
}
}
}
+24
View File
@@ -0,0 +1,24 @@
#include "soldier control.h"
#define HUMAN 0
#define CREATURE_ON_FLOOR 0x01
#define CREATURE_ON_ROOF 0x02
#define NORMAL_HUMAN_SMELL_STRENGTH 10
#define COW_SMELL_STRENGTH 15
#define NORMAL_CREATURE_SMELL_STRENGTH 20
#define SMELL_TYPE_NUM_BITS 2
#define SMELL_TYPE( s ) (s & 0x01)
#define SMELL_STRENGTH( s ) ((s & 0xFC) >> SMELL_TYPE_NUM_BITS)
#define MAXBLOODQUANTITY 7
#define BLOODDIVISOR 10
void DecaySmells( void );
void DecayBloodAndSmells( UINT32 uiTime );
void DropSmell( SOLDIERTYPE * pSoldier );
void DropBlood( SOLDIERTYPE * pSoldier, UINT8 ubStrength, INT8 bVisible );
void UpdateBloodGraphics( INT16 sGridNo, INT8 bLevel );
void RemoveBlood( INT16 sGridNo, INT8 bLevel );
void InternalDropBlood( INT16 sGridNo, INT8 bLevel, UINT8 ubType, UINT8 ubStrength, INT8 bVisible );
+889
View File
@@ -0,0 +1,889 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include <string.h>
#include "wcheck.h"
#include "stdlib.h"
#include "debug.h"
#include "soldier control.h"
#include "weapons.h"
#include "handle items.h"
#include "worlddef.h"
#include "worldman.h"
#include "animation control.h"
#include "tile animation.h"
#include "handle items.h"
#include "smokeeffects.h"
#include "message.h"
#include "isometric utils.h"
#include "renderworld.h"
#include "explosion control.h"
#include "Random.h"
#endif
#include "SaveLoadGame.h"
INT8 FromWorldFlagsToSmokeType( UINT8 ubWorldFlags );
UINT8 FromSmokeTypeToWorldFlags( INT8 bType );
#define NUM_SMOKE_EFFECT_SLOTS 25
// GLOBAL FOR SMOKE LISTING
SMOKEEFFECT gSmokeEffectData[ NUM_SMOKE_EFFECT_SLOTS ];
UINT32 guiNumSmokeEffects = 0;
INT32 GetFreeSmokeEffect( void );
void RecountSmokeEffects( void );
INT32 GetFreeSmokeEffect( void )
{
UINT32 uiCount;
for(uiCount=0; uiCount < guiNumSmokeEffects; uiCount++)
{
if(( gSmokeEffectData[uiCount].fAllocated==FALSE ) )
return( (INT32)uiCount );
}
if( guiNumSmokeEffects < NUM_SMOKE_EFFECT_SLOTS )
return( (INT32) guiNumSmokeEffects++ );
return( -1 );
}
void RecountSmokeEffects( void )
{
INT32 uiCount;
for(uiCount=guiNumSmokeEffects-1; (uiCount >=0) ; uiCount--)
{
if( ( gSmokeEffectData[uiCount].fAllocated ) )
{
guiNumSmokeEffects=(UINT32)(uiCount+1);
break;
}
}
}
// Returns NO_SMOKE_EFFECT if none there...
INT8 GetSmokeEffectOnTile( INT16 sGridNo, INT8 bLevel )
{
UINT8 ubExtFlags;
ubExtFlags = gpWorldLevelData[ sGridNo ].ubExtFlags[ bLevel ];
// Look at worldleveldata to find flags..
if ( ubExtFlags & ANY_SMOKE_EFFECT )
{
// Which smoke am i?
return( FromWorldFlagsToSmokeType( ubExtFlags ) );
}
return( NO_SMOKE_EFFECT );
}
INT8 FromWorldFlagsToSmokeType( UINT8 ubWorldFlags )
{
if ( ubWorldFlags & MAPELEMENT_EXT_SMOKE )
{
return( NORMAL_SMOKE_EFFECT );
}
else if ( ubWorldFlags & MAPELEMENT_EXT_TEARGAS )
{
return( TEARGAS_SMOKE_EFFECT );
}
else if ( ubWorldFlags & MAPELEMENT_EXT_MUSTARDGAS )
{
return( MUSTARDGAS_SMOKE_EFFECT );
}
else if ( ubWorldFlags & MAPELEMENT_EXT_CREATUREGAS )
{
return( CREATURE_SMOKE_EFFECT );
}
else
{
return( NO_SMOKE_EFFECT );
}
}
UINT8 FromSmokeTypeToWorldFlags( INT8 bType )
{
switch( bType )
{
case NORMAL_SMOKE_EFFECT:
return( MAPELEMENT_EXT_SMOKE );
break;
case TEARGAS_SMOKE_EFFECT:
return( MAPELEMENT_EXT_TEARGAS );
break;
case MUSTARDGAS_SMOKE_EFFECT:
return( MAPELEMENT_EXT_MUSTARDGAS );
break;
case CREATURE_SMOKE_EFFECT:
return( MAPELEMENT_EXT_CREATUREGAS );
break;
default:
return( 0 );
}
}
INT32 NewSmokeEffect( INT16 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubOwner )
{
SMOKEEFFECT *pSmoke;
INT32 iSmokeIndex;
INT8 bSmokeEffectType=0;
UINT8 ubDuration=0;
UINT8 ubStartRadius=0;
if( ( iSmokeIndex = GetFreeSmokeEffect() )==(-1) )
return(-1);
memset( &gSmokeEffectData[ iSmokeIndex ], 0, sizeof( SMOKEEFFECT ) );
pSmoke = &gSmokeEffectData[ iSmokeIndex ];
// Set some values...
pSmoke->sGridNo = sGridNo;
pSmoke->usItem = usItem;
pSmoke->uiTimeOfLastUpdate = GetWorldTotalSeconds( );
// Are we indoors?
if ( GetTerrainType( sGridNo ) == FLAT_FLOOR )
{
pSmoke->bFlags |= SMOKE_EFFECT_INDOORS;
}
switch( Explosive[Item[usItem].ubClassIndex].ubType )
{
case EXPLOSV_MUSTGAS:
bSmokeEffectType = MUSTARDGAS_SMOKE_EFFECT;
ubDuration = Explosive[ Item[ usItem ].ubClassIndex ].ubDuration;
ubStartRadius = Explosive[ Item[ usItem ].ubClassIndex ].ubStartRadius;
break;
case EXPLOSV_TEARGAS:
bSmokeEffectType = TEARGAS_SMOKE_EFFECT;
ubDuration = Explosive[ Item[ usItem ].ubClassIndex ].ubDuration;
ubStartRadius = Explosive[ Item[ usItem ].ubClassIndex ].ubStartRadius;
break;
case EXPLOSV_SMOKE:
bSmokeEffectType = NORMAL_SMOKE_EFFECT;
ubDuration = Explosive[ Item[ usItem ].ubClassIndex ].ubDuration;
ubStartRadius = Explosive[ Item[ usItem ].ubClassIndex ].ubStartRadius;
break;
// case SMALL_CREATURE_GAS:
//bSmokeEffectType = CREATURE_SMOKE_EFFECT;
//ubDuration = 3;
//ubStartRadius = 1;
//break;
case EXPLOSV_CREATUREGAS:
bSmokeEffectType = CREATURE_SMOKE_EFFECT;
ubDuration = Explosive[ Item[ usItem ].ubClassIndex ].ubDuration;
ubStartRadius = Explosive[ Item[ usItem ].ubClassIndex ].ubStartRadius;
break;
// case VERY_SMALL_CREATURE_GAS:
//bSmokeEffectType = CREATURE_SMOKE_EFFECT;
//ubDuration = 2;
//ubStartRadius = 0;
break;
}
pSmoke->ubDuration = ubDuration;
pSmoke->ubRadius = ubStartRadius;
pSmoke->bAge = 0;
pSmoke->fAllocated = TRUE;
pSmoke->bType = bSmokeEffectType;
pSmoke->ubOwner = ubOwner;
if ( pSmoke->bFlags & SMOKE_EFFECT_INDOORS )
{
// Duration is increased by 2 turns...indoors
pSmoke->ubDuration += 3;
}
if ( bLevel )
{
pSmoke->bFlags |= SMOKE_EFFECT_ON_ROOF;
}
// ATE: FALSE into subsequent-- it's the first one!
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, FALSE, bLevel, iSmokeIndex );
return( iSmokeIndex );
}
// Add smoke to gridno
// ( Replacement algorithm uses distance away )
void AddSmokeEffectToTile( INT32 iSmokeEffectID, INT8 bType, INT16 sGridNo, INT8 bLevel )
{
ANITILE_PARAMS AniParams;
ANITILE *pAniTile;
SMOKEEFFECT *pSmoke;
BOOLEAN fDissipating = FALSE;
pSmoke = &gSmokeEffectData[ iSmokeEffectID ];
if ( ( pSmoke->ubDuration - pSmoke->bAge ) < 2 )
{
fDissipating = TRUE;
// Remove old one...
RemoveSmokeEffectFromTile( sGridNo, bLevel );
}
// If smoke effect exists already.... stop
if ( gpWorldLevelData[ sGridNo ].ubExtFlags[ bLevel ] & ANY_SMOKE_EFFECT )
{
return;
}
// OK, Create anitile....
memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) );
AniParams.sGridNo = sGridNo;
if ( bLevel == 0 )
{
AniParams.ubLevelID = ANI_STRUCT_LEVEL;
}
else
{
AniParams.ubLevelID = ANI_ONROOF_LEVEL;
}
AniParams.sDelay = (INT16)( 300 + Random( 300 ) );
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
AniParams.sStartFrame = (INT16)0;
}
else
{
AniParams.sStartFrame = (INT16)Random( 5 );
}
// Bare bones flags are...
// AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_OPTIMIZEFORSMOKEEFFECT | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING;
//AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING;
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
AniParams.uiFlags = ANITILE_PAUSED | ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING;
}
else
{
AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING | ANITILE_ALWAYS_TRANSLUCENT;
}
AniParams.sX = CenterX( sGridNo );
AniParams.sY = CenterY( sGridNo );
AniParams.sZ = (INT16)0;
// Use the right graphic based on type..
switch( bType )
{
case NORMAL_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smkechze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalsmke.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\SMOKE.STI" );
}
}
break;
case TEARGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\tearchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smaltear.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\TEARGAS.STI" );
}
}
break;
case MUSTARDGAS_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\mustchze.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\smalmust.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\MUSTARD2.STI" );
}
}
break;
case CREATURE_SMOKE_EFFECT:
if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
if ( fDissipating )
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
else
{
strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" );
}
}
break;
}
// Create tile...
pAniTile = CreateAnimationTile( &AniParams );
// Set world flags
gpWorldLevelData[ sGridNo ].ubExtFlags[ bLevel ] |= FromSmokeTypeToWorldFlags( bType );
// All done...
// Re-draw..... :(
SetRenderFlags(RENDER_FLAG_FULL);
}
void RemoveSmokeEffectFromTile( INT16 sGridNo, INT8 bLevel )
{
ANITILE *pAniTile;
UINT8 ubLevelID;
// Get ANI tile...
if ( bLevel == 0 )
{
ubLevelID = ANI_STRUCT_LEVEL;
}
else
{
ubLevelID = ANI_ONROOF_LEVEL;
}
pAniTile = GetCachedAniTileOfType( sGridNo, ubLevelID, ANITILE_SMOKE_EFFECT );
if ( pAniTile != NULL )
{
DeleteAniTile( pAniTile );
SetRenderFlags( RENDER_FLAG_FULL );
}
// Unset flags in world....
// ( // check to see if we are the last one....
if ( GetCachedAniTileOfType( sGridNo, ubLevelID, ANITILE_SMOKE_EFFECT ) == NULL )
{
gpWorldLevelData[ sGridNo ].ubExtFlags[ bLevel ] &= ( ~ANY_SMOKE_EFFECT );
}
}
void DecaySmokeEffects( UINT32 uiTime )
{
SMOKEEFFECT *pSmoke;
UINT32 cnt, cnt2;
BOOLEAN fUpdate = FALSE;
BOOLEAN fSpreadEffect;
INT8 bLevel;
UINT16 usNumUpdates = 1;
for ( cnt = 0; cnt < guiNumMercSlots; cnt++ )
{
if ( MercSlots[ cnt ] )
{
// reset 'hit by gas' flags
MercSlots[ cnt ]->fHitByGasFlags = 0;
}
}
// ATE: 1 ) make first pass and delete/mark any smoke effect for update
// all the deleting has to be done first///
// age all active tear gas clouds, deactivate those that are just dispersing
for ( cnt = 0; cnt < guiNumSmokeEffects; cnt++ )
{
fSpreadEffect = TRUE;
pSmoke = &gSmokeEffectData[ cnt ];
if ( pSmoke->fAllocated )
{
if ( pSmoke->bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
// Do things differently for combat /vs realtime
// always try to update during combat
if (gTacticalStatus.uiFlags & INCOMBAT )
{
fUpdate = TRUE;
}
else
{
// ATE: Do this every so ofte, to acheive the effect we want...
if ( ( uiTime - pSmoke->uiTimeOfLastUpdate ) > 10 )
{
fUpdate = TRUE;
usNumUpdates = ( UINT16 ) ( ( uiTime - pSmoke->uiTimeOfLastUpdate ) / 10 );
}
}
if ( fUpdate )
{
pSmoke->uiTimeOfLastUpdate = uiTime;
for ( cnt2 = 0; cnt2 < usNumUpdates; cnt2++ )
{
pSmoke->bAge++;
if ( pSmoke->bAge == 1 )
{
// ATE: At least mark for update!
pSmoke->bFlags |= SMOKE_EFFECT_MARK_FOR_UPDATE;
fSpreadEffect = FALSE;
}
else
{
fSpreadEffect = TRUE;
}
if ( fSpreadEffect )
{
// if this cloud remains effective (duration not reached)
if ( pSmoke->bAge <= pSmoke->ubDuration)
{
// ATE: Only mark now and increse radius - actual drawing is done
// in another pass cause it could
// just get erased...
pSmoke->bFlags |= SMOKE_EFFECT_MARK_FOR_UPDATE;
// calculate the new cloud radius
// cloud expands by 1 every turn outdoors, and every other turn indoors
// ATE: If radius is < maximun, increase radius, otherwise keep at max
if ( pSmoke->ubRadius < Explosive[ Item[ pSmoke->usItem ].ubClassIndex ].ubRadius )
{
pSmoke->ubRadius++;
}
}
else
{
// deactivate tear gas cloud (use last known radius)
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, ERASE_SPREAD_EFFECT, bLevel, cnt );
pSmoke->fAllocated = FALSE;
break;
}
}
}
}
else
{
// damage anyone standing in cloud
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, REDO_SPREAD_EFFECT, 0, cnt );
}
}
}
for ( cnt = 0; cnt < guiNumSmokeEffects; cnt++ )
{
pSmoke = &gSmokeEffectData[ cnt ];
if ( pSmoke->fAllocated )
{
if ( pSmoke->bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
// if this cloud remains effective (duration not reached)
if ( pSmoke->bFlags & SMOKE_EFFECT_MARK_FOR_UPDATE )
{
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, TRUE, bLevel, cnt );
pSmoke->bFlags &= (~SMOKE_EFFECT_MARK_FOR_UPDATE);
}
}
}
AllTeamsLookForAll( TRUE );
}
BOOLEAN SaveSmokeEffectsToSaveGameFile( HWFILE hFile )
{
/*
UINT32 uiNumBytesWritten;
UINT32 uiCnt=0;
UINT32 uiNumSmokeEffects=0;
//loop through and count the number of smoke effects
for( uiCnt=0; uiCnt<guiNumSmokeEffects; uiCnt++)
{
if( gSmokeEffectData[ uiCnt ].fAllocated )
uiNumSmokeEffects++;
}
//Save the Number of Smoke Effects
FileWrite( hFile, &uiNumSmokeEffects, sizeof( UINT32 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( UINT32 ) )
{
return( FALSE );
}
if( uiNumSmokeEffects != 0 )
{
//loop through and save the number of smoke effects
for( uiCnt=0; uiCnt < guiNumSmokeEffects; uiCnt++)
{
//if the smoke is active
if( gSmokeEffectData[ uiCnt ].fAllocated )
{
//Save the Smoke effect Data
FileWrite( hFile, &gSmokeEffectData[ uiCnt ], sizeof( SMOKEEFFECT ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( SMOKEEFFECT ) )
{
return( FALSE );
}
}
}
}
*/
return( TRUE );
}
BOOLEAN LoadSmokeEffectsFromLoadGameFile( HWFILE hFile )
{
UINT32 uiNumBytesRead;
UINT32 uiCount;
UINT32 uiCnt=0;
INT8 bLevel;
//no longer need to load smoke effects. They are now in temp files
if( guiSaveGameVersion < 75 )
{
//Clear out the old list
memset( gSmokeEffectData, 0, sizeof( SMOKEEFFECT ) * NUM_SMOKE_EFFECT_SLOTS );
//Load the Number of Smoke Effects
FileRead( hFile, &guiNumSmokeEffects, sizeof( UINT32 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( UINT32 ) )
{
return( FALSE );
}
//This is a TEMP hack to allow us to use the saves
if( guiSaveGameVersion < 37 && guiNumSmokeEffects == 0 )
{
//Load the Smoke effect Data
FileRead( hFile, gSmokeEffectData, sizeof( SMOKEEFFECT ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( SMOKEEFFECT ) )
{
return( FALSE );
}
}
//loop through and load the list
for( uiCnt=0; uiCnt<guiNumSmokeEffects;uiCnt++)
{
//Load the Smoke effect Data
FileRead( hFile, &gSmokeEffectData[ uiCnt ], sizeof( SMOKEEFFECT ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( SMOKEEFFECT ) )
{
return( FALSE );
}
//This is a TEMP hack to allow us to use the saves
if( guiSaveGameVersion < 37 )
break;
}
//loop through and apply the smoke effects to the map
for(uiCount=0; uiCount < guiNumSmokeEffects; uiCount++)
{
//if this slot is allocated
if( gSmokeEffectData[uiCount].fAllocated )
{
if ( gSmokeEffectData[uiCount].bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
SpreadEffect( gSmokeEffectData[uiCount].sGridNo, gSmokeEffectData[uiCount].ubRadius, gSmokeEffectData[uiCount].usItem, gSmokeEffectData[uiCount].ubOwner, TRUE, bLevel, uiCount );
}
}
}
return( TRUE );
}
BOOLEAN SaveSmokeEffectsToMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
UINT32 uiNumSmokeEffects=0;
HWFILE hFile;
UINT32 uiNumBytesWritten=0;
CHAR8 zMapName[ 128 ];
UINT32 uiCnt;
//get the name of the map
GetMapTempFileName( SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
//delete file the file.
FileDelete( zMapName );
//loop through and count the number of smoke effects
for( uiCnt=0; uiCnt<guiNumSmokeEffects; uiCnt++)
{
if( gSmokeEffectData[ uiCnt ].fAllocated )
uiNumSmokeEffects++;
}
//if there are no smoke effects
if( uiNumSmokeEffects == 0 )
{
//set the fact that there are no smoke effects for this sector
ReSetSectorFlag( sMapX, sMapY, bMapZ, SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS );
return( TRUE );
}
//Open the file for writing
hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
if( hFile == 0 )
{
//Error opening file
return( FALSE );
}
//Save the Number of Smoke Effects
FileWrite( hFile, &uiNumSmokeEffects, sizeof( UINT32 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( UINT32 ) )
{
//Close the file
FileClose( hFile );
return( FALSE );
}
//loop through and save the number of smoke effects
for( uiCnt=0; uiCnt < guiNumSmokeEffects; uiCnt++)
{
//if the smoke is active
if( gSmokeEffectData[ uiCnt ].fAllocated )
{
//Save the Smoke effect Data
FileWrite( hFile, &gSmokeEffectData[ uiCnt ], sizeof( SMOKEEFFECT ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( SMOKEEFFECT ) )
{
//Close the file
FileClose( hFile );
return( FALSE );
}
}
}
//Close the file
FileClose( hFile );
SetSectorFlag( sMapX, sMapY, bMapZ, SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS );
return( TRUE );
}
BOOLEAN LoadSmokeEffectsFromMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
UINT32 uiNumBytesRead;
UINT32 uiCount;
UINT32 uiCnt=0;
HWFILE hFile;
UINT32 uiNumBytesWritten=0;
CHAR8 zMapName[ 128 ];
INT8 bLevel;
GetMapTempFileName( SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
//Open the file for reading, Create it if it doesnt exist
hFile = FileOpen( zMapName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
if( hFile == 0 )
{
//Error opening map modification file
return( FALSE );
}
//Clear out the old list
ResetSmokeEffects();
//Load the Number of Smoke Effects
FileRead( hFile, &guiNumSmokeEffects, sizeof( UINT32 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( UINT32 ) )
{
FileClose( hFile );
return( FALSE );
}
//loop through and load the list
for( uiCnt=0; uiCnt<guiNumSmokeEffects;uiCnt++)
{
//Load the Smoke effect Data
FileRead( hFile, &gSmokeEffectData[ uiCnt ], sizeof( SMOKEEFFECT ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( SMOKEEFFECT ) )
{
FileClose( hFile );
return( FALSE );
}
}
//loop through and apply the smoke effects to the map
for(uiCount=0; uiCount < guiNumSmokeEffects; uiCount++)
{
//if this slot is allocated
if( gSmokeEffectData[uiCount].fAllocated )
{
if ( gSmokeEffectData[uiCount].bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
SpreadEffect( gSmokeEffectData[uiCount].sGridNo, gSmokeEffectData[uiCount].ubRadius, gSmokeEffectData[uiCount].usItem, gSmokeEffectData[uiCount].ubOwner, TRUE, bLevel, uiCount );
}
}
FileClose( hFile );
return( TRUE );
}
void ResetSmokeEffects()
{
//Clear out the old list
memset( gSmokeEffectData, 0, sizeof( SMOKEEFFECT ) * NUM_SMOKE_EFFECT_SLOTS );
guiNumSmokeEffects = 0;
}
void UpdateSmokeEffectGraphics( )
{
UINT32 uiCnt;
SMOKEEFFECT *pSmoke;
INT8 bLevel;
//loop through and save the number of smoke effects
for( uiCnt=0; uiCnt < guiNumSmokeEffects; uiCnt++)
{
pSmoke = &gSmokeEffectData[ uiCnt ];
//if the smoke is active
if( gSmokeEffectData[ uiCnt ].fAllocated )
{
if ( gSmokeEffectData[uiCnt].bFlags & SMOKE_EFFECT_ON_ROOF )
{
bLevel = 1;
}
else
{
bLevel = 0;
}
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, ERASE_SPREAD_EFFECT, bLevel, uiCnt );
SpreadEffect( pSmoke->sGridNo, pSmoke->ubRadius, pSmoke->usItem, pSmoke->ubOwner, TRUE, bLevel, uiCnt );
}
}
}
+66
View File
@@ -0,0 +1,66 @@
#ifndef __SMOKE_EFFECTS
#define __SMOKE_EFFECTS
// Smoke effect types
enum
{
NO_SMOKE_EFFECT,
NORMAL_SMOKE_EFFECT,
TEARGAS_SMOKE_EFFECT,
MUSTARDGAS_SMOKE_EFFECT,
CREATURE_SMOKE_EFFECT,
};
#define SMOKE_EFFECT_INDOORS 0x01
#define SMOKE_EFFECT_ON_ROOF 0x02
#define SMOKE_EFFECT_MARK_FOR_UPDATE 0x04
typedef struct TAG_SMOKE_EFFECT
{
INT16 sGridNo; // gridno at which the tear gas cloud is centered
UINT8 ubDuration; // the number of turns gas will remain effective
UINT8 ubRadius; // the current radius of the cloud in map tiles
UINT8 bFlags; // 0 - outdoors (fast spread), 1 - indoors (slow)
INT8 bAge; // the number of turns gas has been around
BOOLEAN fAllocated;
INT8 bType;
UINT16 usItem;
UINT8 ubOwner;
UINT8 ubPadding;
UINT32 uiTimeOfLastUpdate;
} SMOKEEFFECT;
// Returns NO_SMOKE_EFFECT if none there...
INT8 GetSmokeEffectOnTile( INT16 sGridNo, INT8 bLevel );
// Decays all smoke effects...
void DecaySmokeEffects( UINT32 uiTime );
// Add smoke to gridno
// ( Replacement algorithm uses distance away )
void AddSmokeEffectToTile( INT32 iSmokeEffectID, INT8 bType, INT16 sGridNo, INT8 bLevel );
void RemoveSmokeEffectFromTile( INT16 sGridNo, INT8 bLevel );
INT32 NewSmokeEffect( INT16 sGridNo, UINT16 usItem, INT8 bLevel, UINT8 ubOwner );
BOOLEAN SaveSmokeEffectsToSaveGameFile( HWFILE hFile );
BOOLEAN LoadSmokeEffectsFromLoadGameFile( HWFILE hFile );
BOOLEAN SaveSmokeEffectsToMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
BOOLEAN LoadSmokeEffectsFromMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
void ResetSmokeEffects();
void UpdateSmokeEffectGraphics( );
#endif
+245
View File
@@ -0,0 +1,245 @@
#ifndef __STRUCTURE_INTERNAL_H
#define __STRUCTURE_INTERNAL_H
//
// If you wish to use the structure database functions, include
// structure_extern.h, not structure.h!
//
#include "types.h"
#include "himage.h"
// A few words about the overall structure scheme:
//
// Large structures are split into multiple sections,
// one for each tile.
//
// Each section is treated as a separate object,
// except that it does NOT record information about
// hit points, but instead stores a pointer to the
// base object (section).
//
// Each section has a line of sight profile. These
// profiles are split into 5 in each horizontal direction
// and 4 vertically, forming 100 "cubes". In real
// world terms, each section represents a volume
// with a height of 8 feet (and width and length
// of what?)
//
// It is important to note that the vertical
// position of each section is measured in individual
// cubes (rather than, as it were, groups of 4 vertical
// cubes)
#define PROFILE_X_SIZE 5
#define PROFILE_Y_SIZE 5
#define PROFILE_Z_SIZE 4
// these values should be compared for less than rather than less
// than or equal to
#define STRUCTURE_ON_GROUND 0
#define STRUCTURE_ON_ROOF PROFILE_Z_SIZE
#define STRUCTURE_ON_GROUND_MAX PROFILE_Z_SIZE
#define STRUCTURE_ON_ROOF_MAX PROFILE_Z_SIZE * 2
typedef UINT8 PROFILE[PROFILE_X_SIZE][PROFILE_Y_SIZE];
extern UINT8 AtHeight[PROFILE_Z_SIZE];
// MAP_ELEMENT may get later:
// PROFILE * CombinedLOSProfile;
// PROFILE * CombinedProtectionProfile;
//
// LEVELNODE gets a pointer to a STRUCTURE or
// a union between its soldier pointer and a
// STRUCTURE pointer
// if (fFlags & STRUCTURE_BASE_TILE)
// then the structure is the "base" of the object
// and its hitpoint value is the one for the object
//
// vv generic flags for all structures
// vvv type flags
//
// how to handle explodable structures
// NOT used in DB structures!
#define STRUCTURE_BASE_TILE 0x00000001
#define STRUCTURE_OPEN 0x00000002
#define STRUCTURE_OPENABLE 0x00000004
// synonyms for STRUCTURE_OPENABLE
#define STRUCTURE_CLOSEABLE 0x00000004
#define STRUCTURE_SEARCHABLE 0x00000004
#define STRUCTURE_HIDDEN 0x00000008
#define STRUCTURE_MOBILE 0x00000010
// STRUCTURE_PASSABLE is set for each structure instance where
// the tile flag TILE_PASSABLE is set
#define STRUCTURE_PASSABLE 0x00000020
#define STRUCTURE_EXPLOSIVE 0x00000040
#define STRUCTURE_TRANSPARENT 0x00000080
#define STRUCTURE_GENERIC 0x00000100
#define STRUCTURE_TREE 0x00000200
#define STRUCTURE_FENCE 0x00000400
#define STRUCTURE_WIREFENCE 0x00000800
#define STRUCTURE_HASITEMONTOP 0x00001000 // ATE: HASITEM: struct has item on top of it
#define STRUCTURE_SPECIAL 0x00002000
#define STRUCTURE_LIGHTSOURCE 0x00004000
#define STRUCTURE_VEHICLE 0x00008000
#define STRUCTURE_WALL 0x00010000
#define STRUCTURE_WALLNWINDOW 0x00020000
#define STRUCTURE_SLIDINGDOOR 0x00040000
#define STRUCTURE_DOOR 0x00080000
// a "multi" structure (as opposed to multitiled) is composed of multiple graphics & structures
#define STRUCTURE_MULTI 0x00100000
#define STRUCTURE_CAVEWALL 0x00200000
#define STRUCTURE_DDOOR_LEFT 0x00400000
#define STRUCTURE_DDOOR_RIGHT 0x00800000
#define STRUCTURE_NORMAL_ROOF 0x01000000
#define STRUCTURE_SLANTED_ROOF 0x02000000
#define STRUCTURE_TALL_ROOF 0x04000000
#define STRUCTURE_SWITCH 0x08000000
#define STRUCTURE_ON_LEFT_WALL 0x10000000
#define STRUCTURE_ON_RIGHT_WALL 0x20000000
#define STRUCTURE_CORPSE 0x40000000
#define STRUCTURE_PERSON 0x80000000
// COMBINATION FLAGS
#define STRUCTURE_ANYFENCE 0x00000C00
#define STRUCTURE_ANYDOOR 0x00CC0000
#define STRUCTURE_OBSTACLE 0x00008F00
#define STRUCTURE_WALLSTUFF 0x00CF0000
#define STRUCTURE_BLOCKSMOVES 0x00208F00
#define STRUCTURE_TYPE_DEFINED 0x8FEF8F00
#define STRUCTURE_ROOF 0x07000000
#define TILE_ON_ROOF 0x01
#define TILE_PASSABLE 0x02
typedef struct TAG_STRUCTURE_TILE
{
INT16 sPosRelToBase; // "single-axis"
INT8 bXPosRelToBase;
INT8 bYPosRelToBase;
PROFILE Shape; // 25 bytes
UINT8 fFlags;
UINT8 ubVehicleHitLocation;
BYTE bUnused[1];
} DB_STRUCTURE_TILE; // 32 bytes
#define BASE_TILE 0
#define NO_PARTNER_STRUCTURE 0
typedef struct TAG_DB_STRUCTURE
{
UINT8 ubArmour;
UINT8 ubHitPoints;
UINT8 ubDensity;
UINT8 ubNumberOfTiles;
UINT32 fFlags;
UINT16 usStructureNumber;
UINT8 ubWallOrientation;
INT8 bDestructionPartner; // >0 = debris number (bDP - 1), <0 = partner graphic
INT8 bPartnerDelta; // opened/closed version, etc... 0 for unused
INT8 bZTileOffsetX;
INT8 bZTileOffsetY;
BYTE bUnused[1];
} DB_STRUCTURE; // 16 bytes
typedef struct TAG_DB_STRUCTURE_REF
{
DB_STRUCTURE * pDBStructure;
DB_STRUCTURE_TILE ** ppTile; // dynamic array
} DB_STRUCTURE_REF; // 8 bytes
typedef struct TAG_STRUCTURE
{
struct TAG_STRUCTURE * pPrev;
struct TAG_STRUCTURE * pNext;
INT16 sGridNo;
UINT16 usStructureID;
DB_STRUCTURE_REF * pDBStructureRef;
union
{
struct
{
UINT8 ubHitPoints;
UINT8 ubLockStrength;
};
struct
{
INT16 sBaseGridNo;
};
}; // 2 bytes
INT16 sCubeOffset;// height of bottom of object in profile "cubes"
UINT32 fFlags; // need to have something to indicate base tile/not
PROFILE * pShape;
UINT8 ubWallOrientation;
UINT8 ubVehicleHitLocation;
UINT8 ubStructureHeight; // if 0, then unset; otherwise stores height of structure when last calculated
UINT8 ubUnused[1];
} STRUCTURE; // 32 bytes
typedef struct TAG_STRUCTURE_FILE_REF
{
struct TAG_STRUCTURE_FILE_REF * pPrev;
struct TAG_STRUCTURE_FILE_REF * pNext;
AuxObjectData * pAuxData;
RelTileLoc * pTileLocData;
UINT8 * pubStructureData;
DB_STRUCTURE_REF * pDBStructureRef; // dynamic array
UINT16 usNumberOfStructures;
UINT16 usNumberOfStructuresStored;
} STRUCTURE_FILE_REF; // 24 bytes
// IMPORTANT THING TO REMEMBER
//
// Although the number of structures and images about which information
// may be stored in a file, the two are stored very differently.
//
// The structure data stored amounts to a sparse array, with no data
// saved for any structures that are not defined.
//
// For image information, however, an array is stored with every entry
// filled regardless of whether there is non-zero data defined for
// that graphic!
typedef struct TAG_STRUCTURE_FILE_HEADER
{
CHAR8 szId[4];
union
{
struct
{
UINT16 usNumberOfStructures;
};
struct
{
UINT16 usNumberOfImages;
};
};
UINT16 usNumberOfStructuresStored;
UINT16 usStructureDataSize;
UINT8 fFlags;
UINT8 bUnused[3];
UINT16 usNumberOfImageTileLocsStored;
} STRUCTURE_FILE_HEADER; // 16 bytes
// "J2SD" = Jagged 2 Structure Data
#define STRUCTURE_FILE_ID "J2SD"
#define STRUCTURE_FILE_ID_LEN 4
#define STRUCTURE_SCRIPT_FILE_EXTENSION "JSS"
#define STRUCTURE_FILE_EXTENSION "JSD"
#define STRUCTURE_FILE_CONTAINS_AUXIMAGEDATA 0x01
#define STRUCTURE_FILE_CONTAINS_STRUCTUREDATA 0x02
#endif
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
#ifndef __TACTICAL_PLACEMENT_GUI_H
#define __TACTICAL_PLACEMENT_GUI_H
#include "Soldier Control.h"
#include "mousesystem.h"
void InitTacticalPlacementGUI();
void KillTacticalPlacementGUI();
void TacticalPlacementHandle();
void RenderTacticalPlacementGUI();
void HandleTacticalPlacementClicksInOverheadMap( MOUSE_REGION *reg, INT32 reason );
extern BOOLEAN gfTacticalPlacementGUIActive;
extern BOOLEAN gfEnterTacticalPlacementGUI;
extern SOLDIERTYPE *gpTacticalPlacementSelectedSoldier;
extern SOLDIERTYPE *gpTacticalPlacementHilightedSoldier;
//Saved value. Contains the last choice for future battles.
extern UINT8 gubDefaultButton;
#endif
+872
View File
@@ -0,0 +1,872 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "worlddef.h"
#include <stdio.h>
#include <string.h>
#include "wcheck.h"
#include "stdlib.h"
#include "time.h"
#include "video.h"
#include "debug.h"
#include "smooth.h"
#include "worldman.h"
#include "lighting.h"
#include "renderworld.h"
#include "overhead.h"
#include "ai.h"
#include "Sound Control.h"
#include "animation control.h"
#include "isometric utils.h"
#include "Font Control.h"
#include "message.h"
#include "tile animation.h"
#include "tile cache.h"
#include "explosion control.h"
#include "weapons.h"
#include "Keys.h"
#include "bullets.h"
#endif
ANITILE *pAniTileHead = NULL;
ANITILE *CreateAnimationTile( ANITILE_PARAMS *pAniParams )
{
ANITILE *pAniNode;
ANITILE *pNewAniNode;
LEVELNODE *pNode;
INT32 iCachedTile=-1;
INT16 sGridNo;
UINT8 ubLevel;
INT16 usTileType;
INT16 usTileIndex;
INT16 sDelay;
INT16 sStartFrame=-1;
UINT32 uiFlags;
LEVELNODE *pGivenNode;
INT16 sX, sY, sZ;
UINT8 ubTempDir;
// Get some parameters from structure sent in...
sGridNo = pAniParams->sGridNo;
ubLevel = pAniParams->ubLevelID;
usTileType = pAniParams->usTileType;
usTileIndex = pAniParams->usTileIndex;
sDelay = pAniParams->sDelay;
sStartFrame = pAniParams->sStartFrame;
uiFlags = pAniParams->uiFlags;
pGivenNode = pAniParams->pGivenLevelNode;
sX = pAniParams->sX;
sY = pAniParams->sY;
sZ = pAniParams->sZ;
pAniNode = pAniTileHead;
// Allocate head
pNewAniNode = (ANITILE *) MemAlloc( sizeof( ANITILE ) );
if ( (uiFlags & ANITILE_EXISTINGTILE ) )
{
pNewAniNode->pLevelNode = pGivenNode;
pNewAniNode->pLevelNode->pAniTile = pNewAniNode;
}
else
{
if ( ( uiFlags & ANITILE_CACHEDTILE ) )
{
iCachedTile = GetCachedTile( (INT8 *)pAniParams->zCachedFile );
if ( iCachedTile == -1 )
{
return( NULL );
}
usTileIndex = iCachedTile + TILE_CACHE_START_INDEX;
}
// ALLOCATE NEW TILE
switch( ubLevel )
{
case ANI_STRUCT_LEVEL:
pNode = ForceStructToTail( sGridNo, usTileIndex );
break;
case ANI_SHADOW_LEVEL:
AddShadowToHead( sGridNo, usTileIndex );
pNode = gpWorldLevelData[ sGridNo ].pShadowHead;
break;
case ANI_OBJECT_LEVEL:
AddObjectToHead( sGridNo, usTileIndex );
pNode = gpWorldLevelData[ sGridNo ].pObjectHead;
break;
case ANI_ROOF_LEVEL:
AddRoofToHead( sGridNo, usTileIndex );
pNode = gpWorldLevelData[ sGridNo ].pRoofHead;
break;
case ANI_ONROOF_LEVEL:
AddOnRoofToHead( sGridNo, usTileIndex );
pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
break;
case ANI_TOPMOST_LEVEL:
AddTopmostToHead( sGridNo, usTileIndex );
pNode = gpWorldLevelData[ sGridNo ].pTopmostHead;
break;
default:
return( NULL );
}
// SET NEW TILE VALUES
pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
pNewAniNode->pLevelNode = pNode;
if ( ( uiFlags & ANITILE_CACHEDTILE ) )
{
pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_CACHEDANITILE );
pNewAniNode->sCachedTileID = (INT16)iCachedTile;
pNewAniNode->usCachedTileSubIndex = usTileType;
pNewAniNode->pLevelNode->pAniTile = pNewAniNode;
pNewAniNode->sRelativeX = sX;
pNewAniNode->sRelativeY = sY;
pNewAniNode->pLevelNode->sRelativeZ = sZ;
}
// Can't set relative X,Y,Z IF FLAGS ANITILE_CACHEDTILE set!
else if ( (uiFlags & ANITILE_USEABSOLUTEPOS ) )
{
pNewAniNode->pLevelNode->sRelativeX = sX;
pNewAniNode->pLevelNode->sRelativeY = sY;
pNewAniNode->pLevelNode->sRelativeZ = sZ;
pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS );
}
}
switch( ubLevel )
{
case ANI_STRUCT_LEVEL:
ResetSpecificLayerOptimizing( TILES_DYNAMIC_STRUCTURES );
break;
case ANI_SHADOW_LEVEL:
ResetSpecificLayerOptimizing( TILES_DYNAMIC_SHADOWS );
break;
case ANI_OBJECT_LEVEL:
ResetSpecificLayerOptimizing( TILES_DYNAMIC_OBJECTS );
break;
case ANI_ROOF_LEVEL:
ResetSpecificLayerOptimizing( TILES_DYNAMIC_ROOF );
break;
case ANI_ONROOF_LEVEL:
ResetSpecificLayerOptimizing( TILES_DYNAMIC_ONROOF );
break;
case ANI_TOPMOST_LEVEL:
ResetSpecificLayerOptimizing( TILES_DYNAMIC_TOPMOST );
break;
}
// SET FLAGS FOR LEVELNODE
pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_ANIMATION | LEVELNODE_USEZ | LEVELNODE_DYNAMIC );
if ( ( uiFlags & ANITILE_NOZBLITTER ) )
{
pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_NOZBLITTER;
}
if ( ( uiFlags & ANITILE_ALWAYS_TRANSLUCENT ) )
{
pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_REVEAL;
}
if ( ( uiFlags & ANITILE_USEBEST_TRANSLUCENT ) )
{
pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_USEBESTTRANSTYPE;
}
if ( ( uiFlags & ANITILE_ANIMATE_Z ) )
{
pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_DYNAMICZ;
}
if ( ( uiFlags & ANITILE_PAUSED ) )
{
pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_LASTDYNAMIC | LEVELNODE_UPDATESAVEBUFFERONCE );
pNewAniNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
}
if ( ( uiFlags & ANITILE_OPTIMIZEFORSMOKEEFFECT ) )
{
pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_NOWRITEZ;
}
// SET ANITILE VALUES
pNewAniNode->ubLevelID = ubLevel;
pNewAniNode->usTileIndex = usTileIndex;
if ( ( uiFlags & ANITILE_CACHEDTILE ) )
{
pNewAniNode->usNumFrames = gpTileCache[ iCachedTile ].ubNumFrames;
}
else
{
Assert( gTileDatabase[ usTileIndex ].pAnimData != NULL );
pNewAniNode->usNumFrames = gTileDatabase[ usTileIndex ].pAnimData->ubNumFrames;
}
if ( ( uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gOneCDirection[ pAniParams->uiUserData3 ];
sStartFrame = (UINT16)sStartFrame + ( pNewAniNode->usNumFrames * ubTempDir );
}
if ( ( uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gb4DirectionsFrom8[ pAniParams->uiUserData3 ];
sStartFrame = (UINT16)sStartFrame + ( pNewAniNode->usNumFrames * ubTempDir );
}
pNewAniNode->usTileType = usTileType;
pNewAniNode->pNext = pAniNode;
pNewAniNode->uiFlags = uiFlags;
pNewAniNode->sDelay = sDelay;
pNewAniNode->sCurrentFrame = sStartFrame;
pNewAniNode->uiTimeLastUpdate = GetJA2Clock( );
pNewAniNode->sGridNo = sGridNo;
pNewAniNode->sStartFrame = sStartFrame;
pNewAniNode->ubKeyFrame1 = pAniParams->ubKeyFrame1;
pNewAniNode->uiKeyFrame1Code = pAniParams->uiKeyFrame1Code;
pNewAniNode->ubKeyFrame2 = pAniParams->ubKeyFrame2;
pNewAniNode->uiKeyFrame2Code = pAniParams->uiKeyFrame2Code;
pNewAniNode->uiUserData = pAniParams->uiUserData;
pNewAniNode->ubUserData2 = pAniParams->ubUserData2;
pNewAniNode->uiUserData3 = pAniParams->uiUserData3;
//Set head
pAniTileHead = pNewAniNode;
// Set some special stuff
return( pNewAniNode );
}
// Loop throug all ani tiles and remove...
void DeleteAniTiles( )
{
ANITILE *pAniNode = NULL;
ANITILE *pNode = NULL;
// LOOP THROUGH EACH NODE
// And call delete function...
pAniNode = pAniTileHead;
while( pAniNode != NULL )
{
pNode = pAniNode;
pAniNode = pAniNode->pNext;
DeleteAniTile( pNode );
}
}
void DeleteAniTile( ANITILE *pAniTile )
{
ANITILE *pAniNode = NULL;
ANITILE *pOldAniNode = NULL;
TILE_ELEMENT *TileElem;
pAniNode = pAniTileHead;
while( pAniNode!= NULL )
{
if ( pAniNode == pAniTile )
{
// OK, set links
// Check for head or tail
if ( pOldAniNode == NULL )
{
// It's the head
pAniTileHead = pAniTile->pNext;
}
else
{
pOldAniNode->pNext = pAniNode->pNext;
}
if ( !(pAniNode->uiFlags & ANITILE_EXISTINGTILE ) )
{
// Delete memory assosiated with item
switch( pAniNode->ubLevelID )
{
case ANI_STRUCT_LEVEL:
RemoveStructFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
break;
case ANI_SHADOW_LEVEL:
RemoveShadowFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
break;
case ANI_OBJECT_LEVEL:
RemoveObject( pAniNode->sGridNo, pAniNode->usTileIndex );
break;
case ANI_ROOF_LEVEL:
RemoveRoof( pAniNode->sGridNo, pAniNode->usTileIndex );
break;
case ANI_ONROOF_LEVEL:
RemoveOnRoof( pAniNode->sGridNo, pAniNode->usTileIndex );
break;
case ANI_TOPMOST_LEVEL:
RemoveTopmostFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
break;
}
if ( ( pAniNode->uiFlags & ANITILE_CACHEDTILE ) )
{
RemoveCachedTile( pAniNode->sCachedTileID );
}
if ( pAniNode->uiFlags & ANITILE_EXPLOSION )
{
// Talk to the explosion data...
RemoveExplosionData( pAniNode->uiUserData3 );
if ( !gfExplosionQueueActive )
{
// turn on sighting again
// the explosion queue handles all this at the end of the queue
gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT);
}
// Freeup attacker from explosion
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., EXPLOSION effect gone off") );
ReduceAttackBusyCount( (UINT8)pAniNode->ubUserData2, FALSE );
}
if ( pAniNode->uiFlags & ANITILE_RELEASE_ATTACKER_WHEN_DONE )
{
// First delete the bullet!
RemoveBullet( pAniNode->uiUserData3 );
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - miss finished animation") );
FreeUpAttacker( (UINT8) pAniNode->ubAttackerMissed );
}
}
else
{
TileElem = &( gTileDatabase[ pAniNode->usTileIndex ] );
// OK, update existing tile usIndex....
Assert( TileElem->pAnimData != NULL );
pAniNode->pLevelNode->usIndex = TileElem->pAnimData->pusFrames[ pAniNode->pLevelNode->sCurrentFrame ];
// OK, set our frame data back to zero....
pAniNode->pLevelNode->sCurrentFrame = 0;
// Set some flags to write to Z / update save buffer
// pAniNode->pLevelNode->uiFlags |=( LEVELNODE_LASTDYNAMIC | LEVELNODE_UPDATESAVEBUFFERONCE );
pAniNode->pLevelNode->uiFlags &= ~( LEVELNODE_DYNAMIC | LEVELNODE_USEZ | LEVELNODE_ANIMATION );
if (pAniNode->uiFlags & ANITILE_DOOR)
{
// unset door busy!
DOOR_STATUS * pDoorStatus;
pDoorStatus = GetDoorStatus( pAniNode->sGridNo );
if (pDoorStatus)
{
pDoorStatus->ubFlags &= ~(DOOR_BUSY);
}
if ( GridNoOnScreen( pAniNode->sGridNo ) )
{
SetRenderFlags(RENDER_FLAG_FULL);
}
}
}
MemFree( pAniNode );
return;
}
pOldAniNode = pAniNode;
pAniNode = pAniNode->pNext;
}
}
void UpdateAniTiles( )
{
ANITILE *pAniNode = NULL;
ANITILE *pNode = NULL;
UINT32 uiClock = GetJA2Clock( );
UINT16 usMaxFrames, usMinFrames;
UINT8 ubTempDir;
// LOOP THROUGH EACH NODE
pAniNode = pAniTileHead;
while( pAniNode != NULL )
{
pNode = pAniNode;
pAniNode = pAniNode->pNext;
if ( (uiClock - pNode->uiTimeLastUpdate ) > (UINT32)pNode->sDelay && !( pNode->uiFlags & ANITILE_PAUSED ) )
{
pNode->uiTimeLastUpdate = GetJA2Clock( );
if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSLOWMOVING ) )
{
pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC );
pNode->pLevelNode->uiFlags &= (~LEVELNODE_LASTDYNAMIC);
}
else if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSMOKEEFFECT ) )
{
// pNode->pLevelNode->uiFlags |= LEVELNODE_DYNAMICZ;
ResetSpecificLayerOptimizing( TILES_DYNAMIC_STRUCTURES );
pNode->pLevelNode->uiFlags &= (~LEVELNODE_LASTDYNAMIC);
pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC );
}
if ( pNode->uiFlags & ANITILE_FORWARD )
{
usMaxFrames = pNode->usNumFrames;
if ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME )
{
ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
usMaxFrames = (UINT16)usMaxFrames + ( pNode->usNumFrames * ubTempDir );
}
if ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME )
{
ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
usMaxFrames = (UINT16)usMaxFrames + ( pNode->usNumFrames * ubTempDir );
}
if ( ( pNode->sCurrentFrame + 1 ) < usMaxFrames )
{
pNode->sCurrentFrame++;
pNode->pLevelNode->sCurrentFrame = pNode->sCurrentFrame;
if ( pNode->uiFlags & ANITILE_EXPLOSION )
{
// Talk to the explosion data...
UpdateExplosionFrame( pNode->uiUserData3, pNode->sCurrentFrame );
}
// CHECK IF WE SHOULD BE DISPLAYING TRANSLUCENTLY!
if ( pNode->sCurrentFrame == pNode->ubKeyFrame1 )
{
switch( pNode->uiKeyFrame1Code )
{
case ANI_KEYFRAME_BEGIN_TRANSLUCENCY:
pNode->pLevelNode->uiFlags |= LEVELNODE_REVEAL;
break;
case ANI_KEYFRAME_CHAIN_WATER_EXPLOSION:
IgniteExplosion( pNode->ubUserData2, pNode->pLevelNode->sRelativeX, pNode->pLevelNode->sRelativeY, 0, pNode->sGridNo, (UINT16)( pNode->uiUserData ), 0 );
break;
case ANI_KEYFRAME_DO_SOUND:
PlayJA2Sample( pNode->uiUserData, RATE_11025, SoundVolume( MIDVOLUME, (INT16)pNode->uiUserData3 ), 1, SoundDir( (INT16)pNode->uiUserData3 ) );
break;
}
}
// CHECK IF WE SHOULD BE DISPLAYING TRANSLUCENTLY!
if ( pNode->sCurrentFrame == pNode->ubKeyFrame2 )
{
UINT8 ubExpType;
switch( pNode->uiKeyFrame2Code )
{
case ANI_KEYFRAME_BEGIN_DAMAGE:
ubExpType = Explosive[ Item[ (UINT16)pNode->uiUserData ].ubClassIndex ].ubType;
if ( ubExpType == EXPLOSV_TEARGAS || ubExpType == EXPLOSV_MUSTGAS ||
ubExpType == EXPLOSV_SMOKE )
{
// Do sound....
// PlayJA2Sample( AIR_ESCAPING_1, RATE_11025, SoundVolume( HIGHVOLUME, pNode->sGridNo ), 1, SoundDir( pNode->sGridNo ) );
NewSmokeEffect( pNode->sGridNo, (UINT16)pNode->uiUserData, gExplosionData[ pNode->uiUserData3 ].Params.bLevel, (UINT8)pNode->ubUserData2 );
}
else
{
SpreadEffect( pNode->sGridNo, Explosive[ Item[ (UINT16)pNode->uiUserData ].ubClassIndex ].ubRadius, (UINT16)pNode->uiUserData, (UINT8)pNode->ubUserData2, FALSE, gExplosionData[ pNode->uiUserData3 ].Params.bLevel, -1 );
}
// Forfait any other animations this frame....
return;
}
}
}
else
{
// We are done!
if ( pNode->uiFlags & ANITILE_LOOPING )
{
pNode->sCurrentFrame = pNode->sStartFrame;
if ( ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
}
if ( ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
}
}
else if ( pNode->uiFlags & ANITILE_REVERSE_LOOPING )
{
// Turn off backwards flag
pNode->uiFlags &= (~ANITILE_FORWARD );
// Turn onn forwards flag
pNode->uiFlags |= ANITILE_BACKWARD;
}
else
{
// Delete from world!
DeleteAniTile( pNode );
// Turn back on redunency checks!
gTacticalStatus.uiFlags &= (~NOHIDE_REDUNDENCY);
return;
}
}
}
if ( pNode->uiFlags & ANITILE_BACKWARD )
{
if ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER )
{
// ATE: Check if bounding box is on the screen...
if ( pNode->bFrameCountAfterStart == 0 )
{
pNode->bFrameCountAfterStart = 1;
pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC );
// Dangerous here, since we may not even be on the screen...
SetRenderFlags( RENDER_FLAG_FULL );
continue;
}
}
usMinFrames = 0;
if ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME )
{
ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
usMinFrames = ( pNode->usNumFrames * ubTempDir );
}
if ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME )
{
ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
usMinFrames = ( pNode->usNumFrames * ubTempDir );
}
if ( ( pNode->sCurrentFrame - 1 ) >= usMinFrames )
{
pNode->sCurrentFrame--;
pNode->pLevelNode->sCurrentFrame = pNode->sCurrentFrame;
if ( pNode->uiFlags & ANITILE_EXPLOSION )
{
// Talk to the explosion data...
UpdateExplosionFrame( pNode->uiUserData3, pNode->sCurrentFrame );
}
}
else
{
// We are done!
if ( pNode->uiFlags & ANITILE_PAUSE_AFTER_LOOP )
{
// Turn off backwards flag
pNode->uiFlags &= (~ANITILE_BACKWARD );
// Pause
pNode->uiFlags |= ANITILE_PAUSED;
}
else if ( pNode->uiFlags & ANITILE_LOOPING )
{
pNode->sCurrentFrame = pNode->sStartFrame;
if ( ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
}
if ( ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
}
}
else if ( pNode->uiFlags & ANITILE_REVERSE_LOOPING )
{
// Turn off backwards flag
pNode->uiFlags &= (~ANITILE_BACKWARD );
// Turn onn forwards flag
pNode->uiFlags |= ANITILE_FORWARD;
}
else
{
// Delete from world!
DeleteAniTile( pNode );
return;
}
if ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER )
{
// ATE: Check if bounding box is on the screen...
pNode->bFrameCountAfterStart = 0;
//pNode->pLevelNode->uiFlags |= LEVELNODE_UPDATESAVEBUFFERONCE;
// Dangerous here, since we may not even be on the screen...
SetRenderFlags( RENDER_FLAG_FULL );
}
}
}
}
else
{
if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSLOWMOVING ) )
{
// ONLY TURN OFF IF PAUSED...
if ( ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER ) )
{
if ( pNode->uiFlags & ANITILE_PAUSED )
{
if ( pNode->pLevelNode->uiFlags & LEVELNODE_DYNAMIC )
{
pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC);
SetRenderFlags( RENDER_FLAG_FULL );
}
}
}
else
{
pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC);
}
}
else if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSMOKEEFFECT ) )
{
pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC);
pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
}
}
}
}
void SetAniTileFrame( ANITILE *pAniTile, INT16 sFrame )
{
UINT8 ubTempDir;
INT16 sStartFrame = 0;
if ( (pAniTile->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gOneCDirection[ pAniTile->uiUserData3 ];
sStartFrame = (UINT16)sFrame + ( pAniTile->usNumFrames * ubTempDir );
}
if ( (pAniTile->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
{
// Our start frame is actually a direction indicator
ubTempDir = gb4DirectionsFrom8[ pAniTile->uiUserData3 ];
sStartFrame = (UINT16)sFrame + ( pAniTile->usNumFrames * ubTempDir );
}
pAniTile->sCurrentFrame = sStartFrame;
}
ANITILE *GetCachedAniTileOfType( INT16 sGridNo, UINT8 ubLevelID, UINT32 uiFlags )
{
LEVELNODE *pNode = NULL;
switch( ubLevelID )
{
case ANI_STRUCT_LEVEL:
pNode = gpWorldLevelData[ sGridNo ].pStructHead;
break;
case ANI_SHADOW_LEVEL:
pNode = gpWorldLevelData[ sGridNo ].pShadowHead;
break;
case ANI_OBJECT_LEVEL:
pNode = gpWorldLevelData[ sGridNo ].pObjectHead;
break;
case ANI_ROOF_LEVEL:
pNode = gpWorldLevelData[ sGridNo ].pRoofHead;
break;
case ANI_ONROOF_LEVEL:
pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
break;
case ANI_TOPMOST_LEVEL:
pNode = gpWorldLevelData[ sGridNo ].pTopmostHead;
break;
default:
return( NULL );
}
while( pNode != NULL )
{
if ( pNode->uiFlags & LEVELNODE_CACHEDANITILE )
{
if ( pNode->pAniTile->uiFlags & uiFlags )
{
return( pNode->pAniTile );
}
}
pNode = pNode->pNext;
}
return( NULL );
}
void HideAniTile( ANITILE *pAniTile, BOOLEAN fHide )
{
if ( fHide )
{
pAniTile->pLevelNode->uiFlags |= LEVELNODE_HIDDEN;
}
else
{
pAniTile->pLevelNode->uiFlags &= (~LEVELNODE_HIDDEN );
}
}
void PauseAniTile( ANITILE *pAniTile, BOOLEAN fPause )
{
if ( fPause )
{
pAniTile->uiFlags |= ANITILE_PAUSED;
}
else
{
pAniTile->uiFlags &= (~ANITILE_PAUSED );
}
}
void PauseAllAniTilesOfType( UINT32 uiType, BOOLEAN fPause )
{
ANITILE *pAniNode = NULL;
ANITILE *pNode = NULL;
// LOOP THROUGH EACH NODE
pAniNode = pAniTileHead;
while( pAniNode != NULL )
{
pNode = pAniNode;
pAniNode = pAniNode->pNext;
if ( pNode->uiFlags & uiType )
{
PauseAniTile( pNode, fPause );
}
}
}
+140
View File
@@ -0,0 +1,140 @@
#ifndef _TILE_ANIMATION_H
#define _TILE_ANIMATION_H
#define ANITILE_DOOR 0x00000001
#define ANITILE_BACKWARD 0x00000020
#define ANITILE_FORWARD 0x00000040
#define ANITILE_PAUSED 0x00000200
#define ANITILE_EXISTINGTILE 0x00000400
#define ANITILE_USEABSOLUTEPOS 0x00004000
#define ANITILE_CACHEDTILE 0x00008000
#define ANITILE_LOOPING 0x00020000
#define ANITILE_NOZBLITTER 0x00040000
#define ANITILE_REVERSE_LOOPING 0x00080000
#define ANITILE_ALWAYS_TRANSLUCENT 0x00100000
#define ANITILE_USEBEST_TRANSLUCENT 0x00200000
#define ANITILE_OPTIMIZEFORSLOWMOVING 0x00400000
#define ANITILE_ANIMATE_Z 0x00800000
#define ANITILE_USE_DIRECTION_FOR_START_FRAME 0x01000000
#define ANITILE_PAUSE_AFTER_LOOP 0x02000000
#define ANITILE_ERASEITEMFROMSAVEBUFFFER 0x04000000
#define ANITILE_OPTIMIZEFORSMOKEEFFECT 0x08000000
#define ANITILE_SMOKE_EFFECT 0x10000000
#define ANITILE_EXPLOSION 0x20000000
#define ANITILE_RELEASE_ATTACKER_WHEN_DONE 0x40000000
#define ANITILE_USE_4DIRECTION_FOR_START_FRAME 0x02000000
#define ANI_LAND_LEVEL 1
#define ANI_SHADOW_LEVEL 2
#define ANI_OBJECT_LEVEL 3
#define ANI_STRUCT_LEVEL 4
#define ANI_ROOF_LEVEL 5
#define ANI_ONROOF_LEVEL 6
#define ANI_TOPMOST_LEVEL 7
typedef struct TAG_anitile
{
struct TAG_anitile *pNext;
UINT32 uiFlags; // flags struct
UINT32 uiTimeLastUpdate; // Stuff for animated tiles
LEVELNODE *pLevelNode;
UINT8 ubLevelID;
INT16 sCurrentFrame;
INT16 sStartFrame;
INT16 sDelay;
UINT16 usTileType;
UINT16 usNumFrames;
UINT16 usMissAnimationPlayed;
UINT16 ubAttackerMissed;
INT16 sRelativeX;
INT16 sRelativeY;
INT16 sRelativeZ;
INT16 sGridNo;
UINT16 usTileIndex;
UINT16 usCachedTileSubIndex; // sub Index
INT16 sCachedTileID; // Index into cached tile ID
UINT8 ubOwner;
UINT8 ubKeyFrame1;
UINT32 uiKeyFrame1Code;
UINT8 ubKeyFrame2;
UINT32 uiKeyFrame2Code;
UINT32 uiUserData;
UINT8 ubUserData2;
UINT32 uiUserData3;
INT8 bFrameCountAfterStart;
} ANITILE;
typedef struct TAG_anitile_params
{
UINT32 uiFlags; // flags struct
UINT8 ubLevelID; // Level ID for rendering layer
INT16 sStartFrame; // Start frame
INT16 sDelay; // Delay time
UINT16 usTileType; // Tile databse type ( optional )
UINT16 usTileIndex; // Tile database index ( optional )
INT16 sX; // World X ( optional )
INT16 sY; // World Y ( optional )
INT16 sZ; // World Z ( optional )
INT16 sGridNo; // World GridNo
LEVELNODE *pGivenLevelNode; // Levelnode for existing tile ( optional )
CHAR8 zCachedFile[ 100 ]; // Filename for cached tile name ( optional )
UINT8 ubOwner; // UBID for the owner
UINT8 ubKeyFrame1; // Key frame 1
UINT32 uiKeyFrame1Code; // Key frame code
UINT8 ubKeyFrame2; // Key frame 2
UINT32 uiKeyFrame2Code; // Key frame code
UINT32 uiUserData;
UINT8 ubUserData2;
UINT32 uiUserData3;
} ANITILE_PARAMS;
enum KeyFrameEnums
{
ANI_KEYFRAME_NO_CODE,
ANI_KEYFRAME_BEGIN_TRANSLUCENCY,
ANI_KEYFRAME_BEGIN_DAMAGE,
ANI_KEYFRAME_CHAIN_WATER_EXPLOSION,
ANI_KEYFRAME_DO_SOUND,
} ;
// ANimation tile data
extern ANITILE *pAniTileHead;
ANITILE *CreateAnimationTile( ANITILE_PARAMS *pAniParams );
void DeleteAniTile( ANITILE *pAniTile );
void UpdateAniTiles( );
void SetAniTileFrame( ANITILE *pAniTile, INT16 sFrame );
void DeleteAniTiles( );
void HideAniTile( ANITILE *pAniTile, BOOLEAN fHide );
void PauseAniTile( ANITILE *pAniTile, BOOLEAN fPause );
ANITILE *GetCachedAniTileOfType( INT16 sGridNo, UINT8 ubLevelID, UINT32 uiFlags );
void PauseAllAniTilesOfType( UINT32 uiType, BOOLEAN fPause );
#endif
+380
View File
@@ -0,0 +1,380 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include <string.h>
#include "wcheck.h"
#include "stdlib.h"
#include "debug.h"
#include "tiledef.h"
#include "Animation Cache.h"
#include "Animation Data.h"
#include "Animation Control.h"
#include "sys globals.h"
#include "Debug Control.h"
#include "tile surface.h"
#include "tile cache.h"
#include "fileman.h"
#endif
UINT32 guiNumTileCacheStructs = 0;
UINT32 guiMaxTileCacheSize = 50;
UINT32 guiCurTileCacheSize = 0;
INT32 giDefaultStructIndex = -1;
TILE_CACHE_ELEMENT *gpTileCache = NULL;
TILE_CACHE_STRUCT *gpTileCacheStructInfo = NULL;
BOOLEAN InitTileCache( )
{
UINT32 cnt;
GETFILESTRUCT FileInfo;
INT16 sFiles = 0;
gpTileCache = (TILE_CACHE_ELEMENT *)MemAlloc( sizeof( TILE_CACHE_ELEMENT ) * guiMaxTileCacheSize );
// Zero entries
for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
{
gpTileCache[ cnt ].pImagery = NULL;
gpTileCache[ cnt ].sStructRefID = -1;
}
guiCurTileCacheSize = 0;
// OK, look for JSD files in the tile cache directory and
// load any we find....
if( GetFileFirst("TILECACHE\\*.jsd", &FileInfo) )
{
while( GetFileNext(&FileInfo) )
{
sFiles++;
}
GetFileClose(&FileInfo);
}
// Allocate memory...
if ( sFiles > 0 )
{
cnt = 0;
guiNumTileCacheStructs = sFiles;
gpTileCacheStructInfo = (TILE_CACHE_STRUCT *)MemAlloc( sizeof( TILE_CACHE_STRUCT ) * sFiles );
// Loop through and set filenames
if( GetFileFirst("TILECACHE\\*.jsd", &FileInfo) )
{
while( GetFileNext(&FileInfo) )
{
sprintf( gpTileCacheStructInfo[ cnt ].Filename, "TILECACHE\\%s", FileInfo.zFileName );
// Get root name
GetRootName( (INT8 *)gpTileCacheStructInfo[ cnt ].zRootName, (INT8 *)gpTileCacheStructInfo[ cnt ].Filename );
// Load struc data....
gpTileCacheStructInfo[ cnt ].pStructureFileRef = LoadStructureFile( gpTileCacheStructInfo[ cnt ].Filename );
#ifdef JA2TESTVERSION
if ( gpTileCacheStructInfo[ cnt ].pStructureFileRef == NULL )
{
SET_ERROR( "Cannot load tilecache JSD: %s", gpTileCacheStructInfo[ cnt ].Filename );
}
#endif
if ( stricmp( gpTileCacheStructInfo[ cnt ].zRootName, "l_dead1" ) == 0 )
{
giDefaultStructIndex = cnt;
}
cnt++;
}
GetFileClose(&FileInfo);
}
}
return( TRUE );
}
void DeleteTileCache( )
{
UINT32 cnt;
// Allocate entries
if ( gpTileCache != NULL )
{
// Loop through and delete any entries
for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
{
if ( gpTileCache[ cnt ].pImagery != NULL )
{
DeleteTileSurface( gpTileCache[ cnt ].pImagery );
}
}
MemFree( gpTileCache );
}
if ( gpTileCacheStructInfo != NULL )
{
MemFree( gpTileCacheStructInfo );
}
guiCurTileCacheSize = 0;
}
INT16 FindCacheStructDataIndex( INT8 * cFilename )
{
UINT32 cnt;
for ( cnt = 0; cnt < guiNumTileCacheStructs; cnt++ )
{
if ( _stricmp( gpTileCacheStructInfo[ cnt ].zRootName, cFilename ) == 0 )
{
return( (INT16)cnt );
}
}
return( -1 );
}
INT32 GetCachedTile( INT8 * cFilename )
{
UINT32 cnt;
UINT32 ubLowestIndex = 0;
INT16 sMostHits = (INT16)15000;
// Check to see if surface exists already
for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
{
if ( gpTileCache[ cnt ].pImagery != NULL )
{
if ( _stricmp( gpTileCache[ cnt ].zName, cFilename ) == 0 )
{
// Found surface, return
gpTileCache[ cnt ].sHits++;
return( (INT32)cnt );
}
}
}
// Check if max size has been reached
if ( guiCurTileCacheSize == guiMaxTileCacheSize )
{
// cache out least used file
for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
{
if ( gpTileCache[ cnt ].sHits < sMostHits )
{
sMostHits = gpTileCache[ cnt ].sHits;
ubLowestIndex = cnt;
}
}
// Bump off lowest index
DeleteTileSurface( gpTileCache[ ubLowestIndex ].pImagery );
// Decrement
gpTileCache[ ubLowestIndex ].sHits = 0;
gpTileCache[ ubLowestIndex ].pImagery = NULL;
gpTileCache[ ubLowestIndex ].sStructRefID = -1;
}
// If here, Insert at an empty slot
// Find an empty slot
for ( cnt = 0; cnt < guiMaxTileCacheSize; cnt++ )
{
if ( gpTileCache[ cnt ].pImagery == NULL )
{
// Insert here
gpTileCache[ cnt ].pImagery = LoadTileSurface( (char *)cFilename );
if ( gpTileCache[ cnt ].pImagery == NULL )
{
return( -1 );
}
strcpy( gpTileCache[ cnt ].zName, cFilename );
gpTileCache[ cnt ].sHits = 1;
// Get root name
GetRootName( (INT8 *)gpTileCache[ cnt ].zRootName, cFilename );
gpTileCache[ cnt ].sStructRefID = FindCacheStructDataIndex( (INT8 *)gpTileCache[ cnt ].zRootName );
// ATE: Add z-strip info
if ( gpTileCache[ cnt ].sStructRefID != -1 )
{
AddZStripInfoToVObject( gpTileCache[ cnt ].pImagery->vo, gpTileCacheStructInfo[ gpTileCache[ cnt ].sStructRefID ].pStructureFileRef, TRUE, 0 );
}
if ( gpTileCache[ cnt ].pImagery->pAuxData != NULL )
{
gpTileCache[ cnt ].ubNumFrames = gpTileCache[ cnt ].pImagery-> pAuxData->ubNumberOfFrames;
}
else
{
gpTileCache[ cnt ].ubNumFrames = 1;
}
// Has our cache size increased?
if ( cnt >= guiCurTileCacheSize )
{
guiCurTileCacheSize = cnt + 1;;
}
return( cnt );
}
}
// Can't find one!
return( -1 );
}
BOOLEAN RemoveCachedTile( INT32 iCachedTile )
{
UINT32 cnt;
// Find tile
for ( cnt = 0; cnt < guiCurTileCacheSize; cnt++ )
{
if ( gpTileCache[ cnt ].pImagery != NULL )
{
if ( cnt == (UINT32)iCachedTile )
{
// Found surface, decrement hits
gpTileCache[ cnt ].sHits--;
// Are we at zero?
if ( gpTileCache[ cnt ].sHits == 0 )
{
DeleteTileSurface( gpTileCache[ cnt ].pImagery );
gpTileCache[ cnt ].pImagery = NULL;
gpTileCache[ cnt ].sStructRefID = -1;
return( TRUE );;
}
}
}
}
return( FALSE );
}
HVOBJECT GetCachedTileVideoObject( INT32 iIndex )
{
if ( iIndex == -1 )
{
return( NULL );
}
if ( gpTileCache[ iIndex ].pImagery == NULL )
{
return( NULL );
}
return( gpTileCache[ iIndex ].pImagery->vo );
}
STRUCTURE_FILE_REF *GetCachedTileStructureRef( INT32 iIndex )
{
if ( iIndex == -1 )
{
return( NULL );
}
if ( gpTileCache[ iIndex ].sStructRefID == -1 )
{
return( NULL );
}
return( gpTileCacheStructInfo[ gpTileCache[ iIndex ].sStructRefID ].pStructureFileRef );
}
STRUCTURE_FILE_REF *GetCachedTileStructureRefFromFilename( INT8 *cFilename )
{
INT16 sStructDataIndex;
// Given filename, look for index
sStructDataIndex = FindCacheStructDataIndex( cFilename );
if ( sStructDataIndex == -1 )
{
return( NULL );
}
return( gpTileCacheStructInfo[ sStructDataIndex ].pStructureFileRef );
}
void CheckForAndAddTileCacheStructInfo( LEVELNODE *pNode, INT16 sGridNo, UINT16 usIndex, UINT16 usSubIndex )
{
STRUCTURE_FILE_REF *pStructureFileRef;
pStructureFileRef = GetCachedTileStructureRef( usIndex );
if ( pStructureFileRef != NULL)
{
if ( !AddStructureToWorld( sGridNo, 0, &( pStructureFileRef->pDBStructureRef[ usSubIndex ] ), pNode ) )
{
if ( giDefaultStructIndex != -1 )
{
pStructureFileRef = gpTileCacheStructInfo[ giDefaultStructIndex ].pStructureFileRef;
if ( pStructureFileRef != NULL)
{
AddStructureToWorld( sGridNo, 0, &( pStructureFileRef->pDBStructureRef[ usSubIndex ] ), pNode );
}
}
}
}
}
void CheckForAndDeleteTileCacheStructInfo( LEVELNODE *pNode, UINT16 usIndex )
{
STRUCTURE_FILE_REF *pStructureFileRef;
if ( usIndex >= TILE_CACHE_START_INDEX )
{
pStructureFileRef = GetCachedTileStructureRef( ( usIndex - TILE_CACHE_START_INDEX ) );
if ( pStructureFileRef != NULL)
{
DeleteStructureFromWorld( pNode->pStructureData );
}
}
}
void GetRootName( INT8 * pDestStr, INT8 * pSrcStr )
{
// Remove path and extension
INT8 cTempFilename[ 120 ];
STR cEndOfName;
// Remove path
strcpy( cTempFilename, pSrcStr );
cEndOfName = strrchr( cTempFilename, '\\' );
if (cEndOfName != NULL)
{
cEndOfName++;
strcpy( pDestStr, cEndOfName );
}
else
{
strcpy( pDestStr, cTempFilename );
}
// Now remove extension...
cEndOfName = strchr( (const char *)pDestStr, '.' );
if (cEndOfName != NULL)
{
*cEndOfName = '\0';
}
}
+57
View File
@@ -0,0 +1,57 @@
#ifndef __TILE_CACHE_H
#define __TILE_CACHE_H
#include "tiledef.h"
#include "structure.h"
#define TILE_CACHE_START_INDEX 36000
typedef struct
{
CHAR8 zName[ 128 ]; // Name of tile ( filename and directory here )
CHAR8 zRootName[ 30 ]; // Root name
TILE_IMAGERY *pImagery; // Tile imagery
INT16 sHits;
UINT8 ubNumFrames;
INT16 sStructRefID;
} TILE_CACHE_ELEMENT;
typedef struct
{
CHAR8 Filename[ 150 ];
CHAR8 zRootName[ 30 ]; // Root name
STRUCTURE_FILE_REF * pStructureFileRef;
} TILE_CACHE_STRUCT;
extern TILE_CACHE_ELEMENT *gpTileCache;
BOOLEAN InitTileCache( );
void DeleteTileCache( );
INT32 GetCachedTile( INT8 *cFilename );
BOOLEAN RemoveCachedTile( INT32 iCachedTile );
STRUCTURE_FILE_REF *GetCachedTileStructureRefFromFilename( INT8 *cFilename );
HVOBJECT GetCachedTileVideoObject( INT32 iIndex );
STRUCTURE_FILE_REF *GetCachedTileStructureRef( INT32 iIndex );
void CheckForAndAddTileCacheStructInfo( LEVELNODE *pNode, INT16 sGridNo, UINT16 usIndex, UINT16 usSubIndex );
void CheckForAndDeleteTileCacheStructInfo( LEVELNODE *pNode, UINT16 usIndex );
void GetRootName( INT8 *pDestStr, INT8 *pSrcStr );
// OF COURSE, FOR SPEED, WE EXPORT OUR ARRAY
// ACCESS FUNCTIONS IN RENDERER IS NOT TOO NICE
// ATE
#endif
+199
View File
@@ -0,0 +1,199 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "worlddef.h"
#include "worlddat.h"
#include <stdio.h>
#include <string.h>
#include "wcheck.h"
#include "stdlib.h"
#include "time.h"
#include "video.h"
#include "debug.h"
#include "smooth.h"
#include "worldman.h"
#include "mousesystem.h"
#include "sys globals.h"
#include "tiledat.h"
#include "Fileman.h"
#endif
TILE_IMAGERY *gTileSurfaceArray[ NUMBEROFTILETYPES ];
UINT8 gbDefaultSurfaceUsed[ NUMBEROFTILETYPES ];
UINT8 gbSameAsDefaultSurfaceUsed[ NUMBEROFTILETYPES ];
TILE_IMAGERY *LoadTileSurface( char * cFilename )
{
// Add tile surface
PTILE_IMAGERY pTileSurf = NULL;
VOBJECT_DESC VObjectDesc;
HVOBJECT hVObject;
HIMAGE hImage;
SGPFILENAME cStructureFilename;
STR cEndOfName;
STRUCTURE_FILE_REF * pStructureFileRef;
BOOLEAN fOk;
hImage = CreateImage( cFilename, IMAGE_ALLDATA );
if (hImage == NULL)
{
// Report error
SET_ERROR( "Could not load tile file: %s", cFilename );
return( NULL );
}
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMHIMAGE;
VObjectDesc.hImage = hImage;
hVObject = CreateVideoObject( &VObjectDesc );
if ( hVObject == NULL )
{
// Report error
SET_ERROR( "Could not load tile file: %s", cFilename );
// Video Object will set error conition.]
DestroyImage( hImage );
return( NULL );
}
// Load structure data, if any.
// Start by hacking the image filename into that for the structure data
strcpy( cStructureFilename, cFilename );
cEndOfName = strchr( cStructureFilename, '.' );
if (cEndOfName != NULL)
{
cEndOfName++;
*cEndOfName = '\0';
}
else
{
strcat( cStructureFilename, "." );
}
strcat( cStructureFilename, STRUCTURE_FILE_EXTENSION );
if (FileExists( cStructureFilename ))
{
pStructureFileRef = LoadStructureFile( cStructureFilename );
if (pStructureFileRef == NULL || hVObject->usNumberOfObjects != pStructureFileRef->usNumberOfStructures)
{
DestroyImage( hImage );
DeleteVideoObject( hVObject );
SET_ERROR( "Structure file error: %s", cStructureFilename );
return( NULL );
}
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, cStructureFilename );
fOk = AddZStripInfoToVObject( hVObject, pStructureFileRef, FALSE, 0 );
if (fOk == FALSE)
{
DestroyImage( hImage );
DeleteVideoObject( hVObject );
SET_ERROR( "ZStrip creation error: %s", cStructureFilename );
return( NULL );
}
}
else
{
pStructureFileRef = NULL;
}
pTileSurf = (PTILE_IMAGERY) MemAlloc( sizeof( TILE_IMAGERY ) );
// Set all values to zero
memset( pTileSurf, 0, sizeof( TILE_IMAGERY ) );
pTileSurf->vo = hVObject;
pTileSurf->pStructureFileRef = pStructureFileRef;
if (pStructureFileRef && pStructureFileRef->pAuxData != NULL)
{
pTileSurf->pAuxData = pStructureFileRef->pAuxData;
pTileSurf->pTileLocData = pStructureFileRef->pTileLocData;
}
else if (hImage->uiAppDataSize == hVObject->usNumberOfObjects * sizeof( AuxObjectData ))
{
// Valid auxiliary data, so make a copy of it for TileSurf
pTileSurf->pAuxData = (AuxObjectData *) MemAlloc( hImage->uiAppDataSize );
if ( pTileSurf->pAuxData == NULL)
{
DestroyImage( hImage );
DeleteVideoObject( hVObject );
return( NULL );
}
memcpy( pTileSurf->pAuxData, hImage->pAppData, hImage->uiAppDataSize );
}
else
{
pTileSurf->pAuxData = NULL;
}
// the hImage is no longer needed
DestroyImage( hImage );
return( pTileSurf );
}
void DeleteTileSurface( PTILE_IMAGERY pTileSurf )
{
if ( pTileSurf->pStructureFileRef != NULL )
{
FreeStructureFile( pTileSurf->pStructureFileRef );
}
else
{
// If a structure file exists, it will free the auxdata.
// Since there is no structure file in this instance, we
// free it ourselves.
if (pTileSurf->pAuxData != NULL)
{
MemFree( pTileSurf->pAuxData );
}
}
DeleteVideoObject( pTileSurf->vo );
MemFree( pTileSurf );
}
extern void GetRootName( INT8 *pDestStr, INT8 *pSrcStr );
void SetRaisedObjectFlag( char *cFilename, TILE_IMAGERY *pTileSurf )
{
INT32 cnt = 0;
CHAR8 cRootFile[ 128 ];
UINT8 ubRaisedObjectFiles[][80] =
{
"bones",
"bones2",
"grass2",
"grass3",
"l_weed3",
"litter",
"miniweed",
"sblast",
"sweeds",
"twigs",
"wing",
"1"
};
// Loop through array of RAISED objecttype imagery and
// set global value...
if ( ( pTileSurf->fType >= DEBRISWOOD && pTileSurf->fType <= DEBRISWEEDS ) || pTileSurf->fType == DEBRIS2MISC || pTileSurf->fType == ANOTHERDEBRIS )
{
GetRootName( (INT8 *)cRootFile, (INT8 *)cFilename );
while( ubRaisedObjectFiles[ cnt ][ 0 ] != '1' )
{
if ( stricmp( ubRaisedObjectFiles[ cnt ], cRootFile ) == 0 )
{
pTileSurf->bRaisedObjectType = TRUE;
}
cnt++;
}
}
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef _TILE_SURFACE_H
#define _TILE_SURFACE_H
#include "worlddef.h"
extern TILE_IMAGERY *gTileSurfaceArray[ NUMBEROFTILETYPES ];
extern UINT8 gbDefaultSurfaceUsed[ NUMBEROFTILETYPES ];
extern UINT8 gbSameAsDefaultSurfaceUsed[ NUMBEROFTILETYPES ];
TILE_IMAGERY *LoadTileSurface( char * cFilename );
void DeleteTileSurface( PTILE_IMAGERY pTileSurf );
void SetRaisedObjectFlag( char *cFilename, TILE_IMAGERY *pTileSurf );
#endif
+938
View File
@@ -0,0 +1,938 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "tiledef.h"
#include "worlddef.h"
#endif
INT16 gOpenDoorList[20] =
{
FIRSTDOOR1,
SECONDDOOR1,
THIRDDOOR1,
FOURTHDOOR1,
FIRSTDOOR6,
SECONDDOOR6,
THIRDDOOR6,
FOURTHDOOR6,
FIRSTDOOR11,
SECONDDOOR11,
THIRDDOOR11,
FOURTHDOOR11,
FIRSTDOOR16,
SECONDDOOR16,
THIRDDOOR16,
FOURTHDOOR16,
-1
};
INT16 gOpenDoorShadowList[20] =
{
FIRSTDOORSH1,
SECONDDOORSH1,
THIRDDOORSH1,
FOURTHDOORSH1,
FIRSTDOORSH6,
SECONDDOORSH6,
THIRDDOORSH6,
FOURTHDOORSH6,
FIRSTDOORSH11,
SECONDDOORSH11,
THIRDDOORSH11,
FOURTHDOORSH11,
FIRSTDOORSH16,
SECONDDOORSH16,
THIRDDOORSH16,
FOURTHDOORSH16,
-1
};
INT16 gClosedDoorList[20] =
{
FIRSTDOOR5,
SECONDDOOR5,
THIRDDOOR5,
FOURTHDOOR5,
FIRSTDOOR10,
SECONDDOOR10,
THIRDDOOR10,
FOURTHDOOR10,
FIRSTDOOR15,
SECONDDOOR15,
THIRDDOOR15,
FOURTHDOOR15,
FIRSTDOOR20,
SECONDDOOR20,
THIRDDOOR20,
FOURTHDOOR20,
-1
};
INT16 gClosedDoorShadowList[20] =
{
FIRSTDOORSH5,
SECONDDOORSH5,
THIRDDOORSH5,
FOURTHDOORSH5,
FIRSTDOORSH10,
SECONDDOORSH10,
THIRDDOORSH10,
FOURTHDOORSH10,
FIRSTDOORSH15,
SECONDDOORSH15,
THIRDDOORSH15,
FOURTHDOORSH15,
FIRSTDOORSH20,
SECONDDOORSH20,
THIRDDOORSH20,
FOURTHDOORSH20,
-1
};
// REVERSE BUDDIES FROM SHADOW BACK TO STRUCT
INT16 gReverseShadowBuddys[] =
{
FIRSTCLIFFSHADOW, FIRSTCLIFFSHADOW1, FIRSTCLIFF1,
FIRSTSHADOW, FIRSTSHADOW1, FIRSTOSTRUCT1,
SECONDSHADOW, SECONDSHADOW1, SECONDOSTRUCT1,
THIRDSHADOW, THIRDSHADOW1, THIRDOSTRUCT1,
FOURTHSHADOW, FOURTHSHADOW1, FOURTHOSTRUCT1,
FIFTHSHADOW, FIFTHSHADOW1, FIFTHOSTRUCT1,
SIXTHSHADOW, SIXTHSHADOW1, SIXTHOSTRUCT1,
SEVENTHSHADOW, SEVENTHSHADOW1, SEVENTHOSTRUCT1,
EIGHTSHADOW, EIGHTSHADOW1, EIGHTOSTRUCT1,
FIRSTFULLSHADOW, FIRSTFULLSHADOW1, FIRSTFULLSTRUCT1,
SECONDFULLSHADOW, SECONDFULLSHADOW1, SECONDFULLSTRUCT1,
THIRDFULLSHADOW, THIRDFULLSHADOW1, THIRDFULLSTRUCT1,
FOURTHFULLSHADOW, FOURTHFULLSHADOW1, FOURTHFULLSTRUCT1,
FIRSTDOORSHADOW, FIRSTDOORSH1, FIRSTDOOR1,
SECONDDOORSHADOW, SECONDDOORSH1, SECONDDOOR1,
THIRDDOORSHADOW, THIRDDOORSH1, THIRDDOOR1,
FOURTHDOORSHADOW, FOURTHDOORSH1, FOURTHDOOR1,
//FENCE
FENCESHADOW, FENCESHADOW1, FENCESTRUCT1,
// VEHICLES
FIRSTVEHICLESHADOW, FIRSTVEHICLESHADOW1, FIRSTVEHICLE1,
SECONDVEHICLESHADOW, SECONDVEHICLESHADOW1, SECONDVEHICLE1,
//DebrisSTRUCT
FIRSTDEBRISSTRUCTSHADOW, FIRSTDEBRISSTRUCTSHADOW1, FIRSTDEBRISSTRUCT1,
SECONDDEBRISSTRUCTSHADOW, SECONDDEBRISSTRUCTSHADOW1, SECONDDEBRISSTRUCT1,
NINTHOSTRUCTSHADOW, NINTHOSTRUCTSHADOW1, NINTHOSTRUCT1,
TENTHOSTRUCTSHADOW, TENTHOSTRUCTSHADOW1, TENTHOSTRUCT1,
FIRSTLARGEEXPDEBRISSHADOW, FIRSTLARGEEXPDEBRISSHADOW1, FIRSTLARGEEXPDEBRIS1,
SECONDLARGEEXPDEBRISSHADOW, SECONDLARGEEXPDEBRISSHADOW1, SECONDLARGEEXPDEBRIS1,
-1
};
// SHADOW BUDDIES FROM STRUCT FORWARD TO SHADOW
INT16 gForwardShadowBuddys[] =
{
FIRSTCLIFF, FIRSTCLIFF1, FIRSTCLIFFSHADOW1,
FIRSTOSTRUCT, FIRSTOSTRUCT1, FIRSTSHADOW1,
SECONDOSTRUCT, SECONDOSTRUCT1, SECONDSHADOW1,
THIRDOSTRUCT, THIRDOSTRUCT1, THIRDSHADOW1,
FOURTHOSTRUCT, FOURTHOSTRUCT1, FOURTHSHADOW1,
FIFTHOSTRUCT, FIFTHOSTRUCT1, FIFTHSHADOW1,
SIXTHOSTRUCT, SIXTHOSTRUCT1, SIXTHSHADOW1,
SEVENTHOSTRUCT, SEVENTHOSTRUCT1, SEVENTHSHADOW1,
EIGHTOSTRUCT, EIGHTOSTRUCT1, EIGHTSHADOW1,
FIRSTFULLSTRUCT, FIRSTFULLSTRUCT1, FIRSTFULLSHADOW1,
SECONDFULLSTRUCT, SECONDFULLSTRUCT1, SECONDFULLSHADOW1,
THIRDFULLSTRUCT, THIRDFULLSTRUCT1, THIRDFULLSHADOW1,
FOURTHFULLSTRUCT, FOURTHFULLSTRUCT1, FOURTHFULLSHADOW1,
FIRSTDOOR, FIRSTDOOR1, FIRSTDOORSH1,
SECONDDOOR, SECONDDOOR1, SECONDDOORSH1,
THIRDDOOR, THIRDDOOR1, THIRDDOORSH1,
FOURTHDOOR, FOURTHDOOR1, FOURTHDOORSH1,
//FENCE
FENCESTRUCT, FENCESTRUCT1, FENCESHADOW1,
// VEHICLE
FIRSTVEHICLE, FIRSTVEHICLE1, FIRSTVEHICLESHADOW1,
SECONDVEHICLE, SECONDVEHICLE1, SECONDVEHICLESHADOW1,
FIRSTDEBRISSTRUCT, FIRSTDEBRISSTRUCT1, FIRSTDEBRISSTRUCTSHADOW1,
SECONDDEBRISSTRUCT, SECONDDEBRISSTRUCT1, SECONDDEBRISSTRUCTSHADOW1,
NINTHOSTRUCT, NINTHOSTRUCT1, NINTHOSTRUCTSHADOW1,
TENTHOSTRUCT, TENTHOSTRUCT1, TENTHOSTRUCTSHADOW1,
FIRSTLARGEEXPDEBRIS, FIRSTLARGEEXPDEBRIS1, FIRSTLARGEEXPDEBRISSHADOW1,
SECONDLARGEEXPDEBRIS, SECONDLARGEEXPDEBRIS1, SECONDLARGEEXPDEBRISSHADOW1,
-1
};
// Global variable used to initialize tile database with full tile spec
UINT8 gFullBaseTileValues[] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // First Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Second Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Third Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Forth Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Fifth Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Sixth Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Seventh Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Water1 Texture
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // Water2 Texture
};
STR gTileSurfaceName[NUMBEROFTILETYPES] =
{
"TEXTURE1",
"TEXTURE2",
"TEXTURE3",
"TEXTURE4",
"TEXTURE5",
"TEXTURE6",
"TEXTURE7",
"WATER1",
"DEEP WATER",
"FIRSTCLIFFHANG",
"FIRSTCLIFF",
"FIRSTCLIFFSHADOW",
"OSTRUCT1",
"OSTRUCT2",
"OSTRUCT3",
"OSTRUCT4",
"OSTRUCT5",
"OSTRUCT6",
"OSTRUCT7",
"OSTRUCT8",
"OFSTRUCT1",
"OFSTRUCT2",
"PLACEHOLDER1",
"PLACEHOLDER2",
"SHADOW1",
"SHADOW2",
"SHADOW3",
"SHADOW4",
"SHADOW5",
"SHADOW6",
"SHADOW7",
"SHADOW8",
"FSHADOW1",
"FSHADOW2",
"PLACEHOLDER3",
"PLACEHOLDER4",
"WALL1",
"WALL2",
"WALL3",
"WALL4",
"DOOR1",
"DOOR2",
"DOOR3",
"DOOR4",
"DOORSH1",
"DOORSH2",
"DOORSH3",
"DOORSH4",
"SLANTFLATPEICE",
"ANOTHERDEBRIS",
"ROADPIECES",
"WINDOW4",
"DECORATIONS1",
"DECORATIONS2",
"DECORATIONS3",
"DECORATIONS4",
"WALLDECAL1",
"WALLDECAL2",
"WALLDECAL3",
"WALLDECAL4",
"FLOOR1",
"FLOOR2",
"FLOOR3",
"FLOOR4",
"ROOF1",
"ROOF2",
"ROOF3",
"ROOF4",
"SROOF1",
"SROOF2",
"ONROOF1",
"ONROOF2",
"MOCKF1",
"ISTRUCT1",
"ISTRUCT2",
"ISTRUCT3",
"ISTRUCT4",
"FIRSTCISTRCUT",
"FIRSTROAD",
"ROCKS",
"WOOD",
"WEEDS",
"GRASS",
"SAND",
"MISC",
"ANIOSTRUCT",
"FENCESTRUCT",
"FENCESHADOW",
"FIRSTVEHICLE",
"SECONDVEHICLE",
"FIRSTVEHICLESHADOW",
"SECONDVEHICLESHADOW",
"MISC2",
"FIRSTDEBRISSTRUCT",
"SECONDDEBRISSTRUCT",
"FIRSTDEBRISSTRUCTSHADOW",
"SECONDDEBRISSTRUCTSHADOW",
"NINTHOSTRUCT",
"TENTHOSTRUCT",
"NINTHOSTRUCTSHADOW",
"TENTHOSTRUCTSHADOW",
"FIRSTEXPLODEDEBRIS",
"SECONDEXPLODEDEBRIS",
"FIRSTLARGEEXPLODEDEBRIS",
"SECONDLARGEEXPLODEDEBRIS",
"FIRSTLARGEEXPLODEDEBRISSHADOW",
"SECONDLARGEEXPLODEDEBRISSHADOW",
"FIFTHISTRUCT",
"SIXTHISTRUCT",
"SEVENTHISTRUCT",
"EIGHTISTRUCT",
"FIRSTHIGHROOF",
"SECONDHIGHROOF",
"WALLDECAL5",
"WALLDECAL6",
"WALLDECAL7",
"WALLDECAL8",
"HUMANBLOOD",
"CREATUREBLOOD",
"FIRSTSWITCHES",
// ABSOLUTELY NO STUFF PAST HERE!
// CAN BE SAVED IN THE MAP DIRECTLY!
"REVEALEDSLANTROOF",
"1stREVEALEDHIGHROOF",
"2ndREVEALEDHIGHROOF",
"GUNS",
"ITEMS",
"ITEMS2",
"GLASSSHATTER",
"ITEMS3",
"BODYBLOW",
"EXITTEXTURE",
"FOOTPRINTS",
"POINTERS",
"POINTERS2",
"POINTERS3",
"GOODRUN",
"GOODWALK",
"GOODSWAT",
"GOODSCOOT",
"CONFIRMMOVE",
"VEHICLEMOVE",
"ACTIONTWO",
"BADMARKER",
"GRING",
"ROTATINGKEY",
"SELRING",
"SPECIAL",
"BULLET",
"MISS1",
"MISS2",
"MISS3",
"WIREFRAME"
};
UINT16 gNumTilesPerType[ NUMBEROFTILETYPES ] =
{
FIRSTTEXTURE35 - FIRSTTEXTURE1 + 1,
SECONDTEXTURE35 - SECONDTEXTURE1 + 1,
THIRDTEXTURE35 - THIRDTEXTURE1 + 1,
FOURTHTEXTURE35 - FOURTHTEXTURE1 + 1,
FIFTHTEXTURE35 - FIFTHTEXTURE1 + 1,
SIXTHTEXTURE37 - SIXTHTEXTURE1 + 1,
SEVENTHTEXTURE49 - SEVENTHTEXTURE1 + 1,
REGWATERTEXTURE50 - REGWATERTEXTURE1 + 1,
DEEPWATERTEXTURE37 - DEEPWATERTEXTURE1 + 1,
FIRSTCLIFFHANG17 - FIRSTCLIFFHANG1 + 1,
FIRSTCLIFF17 - FIRSTCLIFF1 + 1,
FIRSTCLIFFSHADOW17 - FIRSTCLIFFSHADOW1 + 1, // Med hill
FIRSTOSTRUCT12 - FIRSTOSTRUCT1 + 1,
SECONDOSTRUCT12 - SECONDOSTRUCT1 + 1,
THIRDOSTRUCT12 - THIRDOSTRUCT1 + 1,
FOURTHOSTRUCT12 - FOURTHOSTRUCT1 + 1, // Fourth OSTRUCT
FIFTHOSTRUCT12 - FIFTHOSTRUCT1 + 1, // Fifth OSTRUCT
SIXTHOSTRUCT12 - SIXTHOSTRUCT1 + 1, // Sixth OSTRUCT
SEVENTHOSTRUCT12 - SEVENTHOSTRUCT1 + 1, // Seventh OSTRUCT
EIGHTOSTRUCT12 - EIGHTOSTRUCT1 + 1, // Eigth OSTRUCT
FIRSTFULLSTRUCT12 - FIRSTFULLSTRUCT1 + 1,
SECONDFULLSTRUCT12 - SECONDFULLSTRUCT1 + 1,
THIRDFULLSTRUCT2 - THIRDFULLSTRUCT1 + 1,
FOURTHFULLSTRUCT2 - FOURTHFULLSTRUCT1 + 1,
FIRSTSHADOW12 - FIRSTSHADOW1 + 1,
SECONDSHADOW12 - SECONDSHADOW1 + 1,
THIRDSHADOW12 - THIRDSHADOW1 + 1,
FOURTHSHADOW12 - FOURTHSHADOW1 + 1,
FIFTHSHADOW12 - FIFTHSHADOW1 + 1,
SIXTHSHADOW12 - SIXTHSHADOW1 + 1,
SEVENTHSHADOW12 - SEVENTHSHADOW1 + 1,
EIGHTSHADOW12 - EIGHTSHADOW1 + 1,
FIRSTFULLSHADOW12 - FIRSTFULLSHADOW1 + 1,
SECONDFULLSHADOW12 - SECONDFULLSHADOW1 + 1,
THIRDFULLSHADOW2 - THIRDFULLSHADOW1 + 1,
FOURTHFULLSHADOW2 - FOURTHFULLSHADOW1 + 1,
FIRSTWALL65 - FIRSTWALL1 + 1,
SECONDWALL65 - SECONDWALL1 + 1,
THIRDWALL65 - THIRDWALL1 + 1,
FOURTHWALL65 - FOURTHWALL1 + 1,
FIRSTDOOR20 - FIRSTDOOR1 + 1,
SECONDDOOR20 - SECONDDOOR1 + 1,
THIRDDOOR20 - THIRDDOOR1 + 1,
FOURTHDOOR20 - FOURTHDOOR1 + 1,
FIRSTDOORSH20 - FIRSTDOORSH1 + 1,
SECONDDOORSH20 - SECONDDOORSH1 + 1,
THIRDDOORSH20 - THIRDDOORSH1 + 1,
FOURTHDOORSH20 - FOURTHDOORSH1 + 1,
SLANTROOFCEILING2 - SLANTROOFCEILING1 + 1,
ANOTHERDEBRIS10 - ANOTHERDEBRIS1 + 1,
ROADPIECES400 - ROADPIECES001 + 1,
FOURTHWINDOW2 - FOURTHWINDOW1 + 1,
FIRSTDECORATIONS10 - FIRSTDECORATIONS1 + 1,
SECONDDECORATIONS10 - SECONDDECORATIONS1 + 1,
THIRDDECORATIONS10 - THIRDDECORATIONS1 + 1,
FOURTHDECORATIONS10 - FOURTHDECORATIONS1 + 1,
FIRSTWALLDECAL10 - FIRSTWALLDECAL1 + 1,
SECONDWALLDECAL10 - SECONDWALLDECAL1 + 1,
THIRDWALLDECAL10 - THIRDWALLDECAL1 + 1,
FOURTHWALLDECAL10 - FOURTHWALLDECAL1 + 1,
FIRSTFLOOR8 - FIRSTFLOOR1 + 1,
SECONDFLOOR8 - SECONDFLOOR1 + 1,
THIRDFLOOR8 - THIRDFLOOR1 + 1,
FOURTHFLOOR8 - FOURTHFLOOR1 + 1,
FIRSTROOF14 - FIRSTROOF1 + 1,
SECONDROOF14 - SECONDROOF1 + 1,
THIRDROOF14 - THIRDROOF1 + 1,
FOURTHROOF14 - FOURTHROOF1 + 1,
FIRSTSLANTROOF20 - FIRSTSLANTROOF1 + 1,
SECONDSLANTROOF20 - SECONDSLANTROOF1 + 1,
FIRSTONROOF12 - FIRSTONROOF1 + 1,
SECONDONROOF12 - SECONDONROOF1 + 1,
1,
FIRSTISTRUCT24 - FIRSTISTRUCT1 + 1,
SECONDISTRUCT24 - SECONDISTRUCT1 + 1,
THIRDISTRUCT24 - THIRDISTRUCT1 + 1,
FOURTHISTRUCT24 - FOURTHISTRUCT1 + 1,
FIRSTCISTRUCT24 - FIRSTCISTRUCT1 + 1,
FIRSTROAD35 - FIRSTROAD1 + 1,
DEBRISROCKS10 - DEBRISROCKS1 + 1,
DEBRISWOOD10 - DEBRISWOOD1 + 1,
DEBRISWEEDS10 - DEBRISWEEDS1 + 1,
DEBRISGRASS10 - DEBRISGRASS1 + 1,
DEBRISSAND10 - DEBRISSAND1 + 1,
DEBRISMISC10 - DEBRISMISC1 + 1,
ANIOSTRUCT20 - ANIOSTRUCT1 + 1,
FENCESTRUCT23 - FENCESTRUCT1 + 1,
FENCESHADOW23 - FENCESHADOW1 + 1,
FIRSTVEHICLE12 - FIRSTVEHICLE1 + 1,
SECONDVEHICLE12 - SECONDVEHICLE1 + 1,
FIRSTVEHICLESHADOW12 - FIRSTVEHICLESHADOW1 + 1,
SECONDVEHICLESHADOW12 - SECONDVEHICLESHADOW1 + 1,
DEBRIS2MISC10 - DEBRIS2MISC1 + 1,
FIRSTDEBRISSTRUCT10 - FIRSTDEBRISSTRUCT1 + 1,
SECONDDEBRISSTRUCT10 - SECONDDEBRISSTRUCT1 + 1,
FIRSTDEBRISSTRUCTSHADOW10 - FIRSTDEBRISSTRUCTSHADOW1 + 1,
SECONDDEBRISSTRUCTSHADOW10 - SECONDDEBRISSTRUCTSHADOW1 + 1,
NINTHOSTRUCT12 - NINTHOSTRUCT1 + 1,
TENTHOSTRUCT12 - TENTHOSTRUCT1 + 1,
NINTHOSTRUCTSHADOW12 - NINTHOSTRUCTSHADOW1 + 1,
TENTHOSTRUCTSHADOW12 - TENTHOSTRUCTSHADOW1 + 1,
FIRSTEXPLDEBRIS40 - FIRSTEXPLDEBRIS1 + 1,
SECONDEXPLDEBRIS40 - SECONDEXPLDEBRIS1 + 1,
FIRSTLARGEEXPDEBRIS10 - FIRSTLARGEEXPDEBRIS1 + 1,
SECONDLARGEEXPDEBRIS10 - SECONDLARGEEXPDEBRIS1 + 1,
FIRSTLARGEEXPDEBRISSHADOW10 - FIRSTLARGEEXPDEBRISSHADOW1 + 1,
SECONDLARGEEXPDEBRISSHADOW10 - SECONDLARGEEXPDEBRISSHADOW1 + 1,
FIFTHISTRUCT24 - FIFTHISTRUCT1 + 1,
SIXTHISTRUCT24 - SIXTHISTRUCT1 + 1,
SEVENTHISTRUCT24 - SEVENTHISTRUCT1 + 1,
EIGHTISTRUCT24 - EIGHTISTRUCT1 + 1,
FIRSTHIGHROOF15 - FIRSTHIGHROOF1 + 1,
SECONDHIGHROOF15 - SECONDHIGHROOF1 + 1,
FIFTHWALLDECAL10 - FIFTHWALLDECAL1 + 1,
SIXTHWALLDECAL10 - SIXTHWALLDECAL1 + 1,
SEVENTHWALLDECAL10 - SEVENTHWALLDECAL1 + 1,
EIGTHWALLDECAL10 - EIGTHWALLDECAL1 + 1,
HUMANBLOOD16 - HUMANBLOOD1 + 1,
CREATUREBLOOD16 - CREATUREBLOOD1 + 1,
FIRSTSWITCHES21 - FIRSTSWITCHES1 + 1,
// NO SAVED STUFF AFTER HERE!
REVEALEDSLANTROOFS8 - REVEALEDSLANTROOFS1 + 1,
FIRSTREVEALEDHIGHROOFS11 - FIRSTREVEALEDHIGHROOFS1 + 1,
SECONDREVEALEDHIGHROOFS11 - SECONDREVEALEDHIGHROOFS1 + 1,
GUN5000 - GUN1 + 1,
P1ITEM5000 - P1ITEM1 + 1,
P2ITEM45 - P2ITEM1 + 1,
WINDOWSHATTER20 - WINDOWSHATTER1 + 1,
P3ITEM16 - P3ITEM1 + 1,
BODYEXPLOSION15 - BODYEXPLOSION1 + 1,
EXITTEXTURE35 - EXITTEXTURE1 + 1,
FOOTPRINTS80 - FOOTPRINTS1 + 1,
FIRSTPOINTERS24 - FIRSTPOINTERS1 + 1,
SECONDPOINTERS8 - SECONDPOINTERS1 + 1,
THIRDPOINTERS3 - THIRDPOINTERS1 + 1,
GOODRUN11 - GOODRUN1 + 1,
GOODWALK11 - GOODWALK1 + 1,
GOODSWAT11 - GOODSWAT1 + 1,
GOODPRONE11 - GOODPRONE1 + 1,
CONFIRMMOVE11 - CONFIRMMOVE1 + 1,
VEHICLEMOVE10 - VEHICLEMOVE1 + 1,
ACTIONTWO11 - ACTIONTWO1 + 1,
BADMARKER11 - BADMARKER1 + 1,
GOODRING10 - GOODRING1 + 1,
ROTATINGKEY8 - ROTATINGKEY1 + 1,
SELRING10 - SELRING1 + 1,
SPECIALTILE_COVER_5 - SPECIALTILE_MAPEXIT + 1,
BULLETTILE2 - BULLETTILE1 + 1,
FIRSTMISS5 - FIRSTMISS1 + 1,
SECONDMISS5 - SECONDMISS1 + 1,
THIRDMISS14 - THIRDMISS1 + 1,
WIREFRAMES15 - WIREFRAMES1 + 1
};
UINT8 gTileTypeLogicalHeight[ NUMBEROFTILETYPES ] =
{
2, // First texture
2, // Second texture
2, // Third texture
2, // Forth texture
2, // Fifth texture
2, // Sixth texture
2, // Seventh texture
10, // First water
10 // Second water
};
void SetSpecificDatabaseValues( UINT16 usType, UINT16 uiDatabaseElem, TILE_ELEMENT *TileElement, BOOLEAN fUseRaisedObjectType )
{
UINT8 ubLoop;
INT16 sIndexDiff;
UINT32 cnt;
// SETUP BUDDYS FOR SHADOWS
cnt = 0;
while( gReverseShadowBuddys[ cnt ] != -1 )
{
// IF WE ARE A SHADOW TYPE
if ( usType == gReverseShadowBuddys[ cnt ] )
{
TileElement->sBuddyNum = gReverseShadowBuddys[ cnt + 2 ] + ( uiDatabaseElem - gReverseShadowBuddys[ cnt + 1 ] );
// Check flags and made the same, take from buddy's
TileElement->uiFlags |= gTileDatabase[ TileElement->sBuddyNum ].uiFlags;
}
cnt+=3;
};
// SETUP BUDDYS THAT GO FROM STRUCT TO SHADOW
cnt = 0;
while( gForwardShadowBuddys[ cnt ] != -1 )
{
// IF WE ARE A SHADOW TYPE
if ( usType == gForwardShadowBuddys[ cnt ] )
{
TileElement->sBuddyNum = gForwardShadowBuddys[ cnt + 2 ] + ( uiDatabaseElem - gForwardShadowBuddys[ cnt + 1 ] );
// Set flag indicating such
TileElement->uiFlags |= HAS_SHADOW_BUDDY;
}
cnt+=3;
};
if ( uiDatabaseElem >= FIRSTDOOR1 &&
uiDatabaseElem <= FOURTHDOORSH20 )
{
// Door anims
// Open
cnt = 0;
while( gOpenDoorList[ cnt ] != -1 )
{
// IF WE ARE A SHADOW TYPE
if ( uiDatabaseElem == gOpenDoorList[ cnt ] )
{
// Allocate Animated tile data
AllocateAnimTileData( TileElement, 5 );
TileElement->pAnimData->bCurrentFrame = 0;
for (ubLoop = 0; ubLoop < TileElement->pAnimData->ubNumFrames; ubLoop++)
{
TileElement->pAnimData->pusFrames[ubLoop] = uiDatabaseElem + ubLoop;
}
}
cnt++;
};
// Open Shadow
cnt = 0;
while( gOpenDoorShadowList[ cnt ] != -1 )
{
// IF WE ARE A SHADOW TYPE
if ( uiDatabaseElem == gOpenDoorShadowList[ cnt ] )
{
// Allocate Animated tile data
AllocateAnimTileData( TileElement, 5 );
TileElement->pAnimData->bCurrentFrame = 0;
for (ubLoop = 0; ubLoop < TileElement->pAnimData->ubNumFrames; ubLoop++)
{
TileElement->pAnimData->pusFrames[ubLoop] = uiDatabaseElem + ubLoop;
}
}
cnt++;
};
// Closed
cnt = 0;
while( gClosedDoorList[ cnt ] != -1 )
{
// IF WE ARE A SHADOW TYPE
if ( uiDatabaseElem == gClosedDoorList[ cnt ] )
{
// Allocate Animated tile data
AllocateAnimTileData( TileElement, 5 );
TileElement->pAnimData->bCurrentFrame = 0;
for (ubLoop = 0; ubLoop < TileElement->pAnimData->ubNumFrames; ubLoop++)
{
TileElement->pAnimData->pusFrames[ubLoop] = uiDatabaseElem - ubLoop;
}
}
cnt++;
};
// Open Shadow
cnt = 0;
while( gClosedDoorShadowList[ cnt ] != -1 )
{
// IF WE ARE A SHADOW TYPE
if ( uiDatabaseElem == gClosedDoorShadowList[ cnt ] )
{
// Allocate Animated tile data
AllocateAnimTileData( TileElement, 5 );
TileElement->pAnimData->bCurrentFrame = 0;
for (ubLoop = 0; ubLoop < TileElement->pAnimData->ubNumFrames; ubLoop++)
{
TileElement->pAnimData->pusFrames[ubLoop] = uiDatabaseElem - ubLoop;
}
}
cnt++;
};
}
if ( uiDatabaseElem == FIRSTMISS1 )
{
// Allocate Animated tile data
AllocateAnimTileData( TileElement, 5 );
TileElement->pAnimData->bCurrentFrame = 0;
for (ubLoop = 0; ubLoop < TileElement->pAnimData->ubNumFrames; ubLoop++)
{
TileElement->pAnimData->pusFrames[ubLoop] = uiDatabaseElem + ubLoop;
}
}
if ( uiDatabaseElem >= FIRSTMISS1 &&
uiDatabaseElem <= FIRSTMISS5 )
{
TileElement->uiFlags |= DYNAMIC_TILE;
}
if ( uiDatabaseElem == WINDOWSHATTER1 || uiDatabaseElem == WINDOWSHATTER6 || uiDatabaseElem == WINDOWSHATTER11 || uiDatabaseElem == WINDOWSHATTER16 )
{
// Allocate Animated tile data
AllocateAnimTileData( TileElement, 5 );
TileElement->pAnimData->bCurrentFrame = 0;
for (ubLoop = 0; ubLoop < TileElement->pAnimData->ubNumFrames; ubLoop++)
{
TileElement->pAnimData->pusFrames[ubLoop] = uiDatabaseElem + ubLoop;
}
}
if ( uiDatabaseElem >= WINDOWSHATTER1 &&
uiDatabaseElem <= WINDOWSHATTER20 )
{
TileElement->uiFlags |= DYNAMIC_TILE;
}
// if ( usType == FIRSTEXPLOSION )
// {
// TileElement->uiFlags |= DYNAMIC_TILE;
// }
if ( usType == BODYEXPLOSION )
{
TileElement->uiFlags |= DYNAMIC_TILE;
}
if ( usType == FIRSTROAD )
{
TileElement->uiFlags |= ROAD_TILE;
}
// SET FLAGS FOR OBJECTS PEICES WHICH USE PROPER Z
if ( fUseRaisedObjectType )
{
TileElement->uiFlags |= OBJECTLAYER_USEZHEIGHT;
}
// OFFSET SLANTED ROOFS TO HEIGHT OF WALLS
if ( uiDatabaseElem >= FIRSTROOF1 &&
uiDatabaseElem <= SECONDSLANTROOF20 )
{
//TileElement->sOffsetHeight = WALL_HEIGHT;
}
// Set flag for full 3d tiles, as well as the dynamic flag for the folliage
if ( uiDatabaseElem >= FIRSTFULLSTRUCT1 &&
uiDatabaseElem <= SECONDFULLSTRUCT12 )
{
//TileElement->uiFlags |= FULL3D_TILE;
sIndexDiff = uiDatabaseElem - gTileTypeStartIndex[ usType ];
// Every second set as dynamic
if ( ( ( sIndexDiff ) % 3 ) == 1 )
{
TileElement->uiFlags |= DYNAMIC_TILE;
}
// Set every first as full tile
if ( ( ( sIndexDiff ) % 3 ) == 0 )
{
TileElement->uiFlags |= FULL3D_TILE;
}
}
//Ignore height for cliffs ie: if we rasie the land, do not offset the cliff
if ( uiDatabaseElem >= FIRSTCLIFFHANG1 &&
uiDatabaseElem <= FIRSTCLIFFSHADOW17 )
{
if ( usType == FIRSTCLIFFHANG )
{
TileElement->uiFlags |= CLIFFHANG_TILE;
}
TileElement->uiFlags |= IGNORE_WORLD_HEIGHT;
}
if ( uiDatabaseElem >= FIRSTWALL1 &&
uiDatabaseElem <= FOURTHWALL65 )
{
TileElement->uiFlags |= WALL_TILE;
}
// Set a-frames heigher!
if ( uiDatabaseElem >= FIRSTWALL1 &&
uiDatabaseElem <= FOURTHWALL47 )
{
// Set these ones higher ( for roof pieces )
if ( uiDatabaseElem >= ( gTileTypeStartIndex[ usType ] + WALL_AFRAME_START ) &&
uiDatabaseElem <= ( gTileTypeStartIndex[ usType ] + WALL_AFRAME_END ) )
{
//TileElement->sOffsetHeight = WALL_HEIGHT;
TileElement->uiFlags |= AFRAME_TILE;
}
}
// Set UI Elements to be dynamic
if ( uiDatabaseElem >= FOOTPRINTS1 &&
uiDatabaseElem <= THIRDPOINTERS2 )
{
TileElement->uiFlags |= DYNAMIC_TILE;
TileElement->uiFlags |= OBJECTLAYER_USEZHEIGHT;
}
// Set UI Elements to use object z level
if ( usType >= FOOTPRINTS &&
usType <= LASTUIELEM )
{
TileElement->uiFlags |= OBJECTLAYER_USEZHEIGHT;
}
// Set UI Elements to use object z level
if ( usType >= HUMANBLOOD &&
usType <= CREATUREBLOOD )
{
TileElement->uiFlags |= OBJECTLAYER_USEZHEIGHT;
}
// Set UI Elements to use object z level
if ( usType >= GUNS &&
usType <= P2ITEMS )
{
TileElement->uiFlags |= OBJECTLAYER_USEZHEIGHT;
}
if ( usType == P3ITEMS )
{
TileElement->uiFlags |= OBJECTLAYER_USEZHEIGHT;
}
if ( usType >= FIRSTEXPLDEBRIS && usType <= SECONDEXPLDEBRIS )
{
TileElement->uiFlags |= OBJECTLAYER_USEZHEIGHT;
}
if ( uiDatabaseElem >= FIRSTDOOR1 &&
uiDatabaseElem <= FOURTHDOORSH20 )
{
//TileElement->uiFlags |= DYNAMIC_TILE;
}
// Set UI Elements to be dynamic
if ( uiDatabaseElem == MOCKFLOOR1 )
{
TileElement->uiFlags |= DYNAMIC_TILE;
}
if ( usType == BULLETTILE )
{
TileElement->uiFlags |= DYNAMIC_TILE;
}
if ( usType == WIREFRAMES )
{
//TileElement->uiFlags |= DYNAMIC_TILE;
}
// Set full tile flag for floors
if ( uiDatabaseElem >= FIRSTFLOOR1 &&
uiDatabaseElem <= FOURTHFLOOR8 )
{
TileElement->ubFullTile = 1;
}
if ( uiDatabaseElem >= FIRSTTEXTURE1 &&
uiDatabaseElem <= DEEPWATERTEXTURE10 )
{
// Set tile 'fullness' attribute
TileElement->ubFullTile = gFullBaseTileValues[ uiDatabaseElem ];
}
if ( usType >= FIRSTONROOF && usType <= SECONDONROOF )
{
// Set height!
//TileElement->sOffsetHeight = WALL_HEIGHT;
}
if ( uiDatabaseElem >= REGWATERTEXTURE18 && uiDatabaseElem <= REGWATERTEXTURE50 || uiDatabaseElem == REGWATERTEXTURE ||
uiDatabaseElem == REGWATERTEXTURE12 || uiDatabaseElem == REGWATERTEXTURE14 || uiDatabaseElem == REGWATERTEXTURE16 )
{
TileElement->ubTerrainID = FLAT_GROUND;
}
if ( ( usType >= FIRSTROOF && usType <= SECONDSLANTROOF ) || usType == FIRSTHIGHROOF || usType == SECONDHIGHROOF )
{
TileElement->uiFlags |= ROOF_TILE;
}
}
+3257
View File
File diff suppressed because it is too large Load Diff
+158
View File
@@ -0,0 +1,158 @@
#ifndef __TILEENGINE_ALL_H
#define __TILEENGINE_ALL_H
#pragma message("GENERATED PCH FOR TILEENGINE PROJECT.")
#include <stdio.h>
#include "sgp.h"
#include "Ambient types.h"
#include "fileman.h"
#include "environment.h"
#include "Sound Control.h"
#include "Game Events.h"
#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"
#include "lighting.h"
#include "renderworld.h"
#include "Game Clock.h"
#include "quests.h"
#include "Ambient Control.h"
#include "AimMembers.h"
#include "Strategic Event Handler.h"
#include "BobbyR.h"
#include "mercs.h"
#include "email.h"
#include "Merc Hiring.h"
#include "insurance Contract.h"
#include "Strategic Merc Handler.h"
#include "message.h"
#include "opplist.h"
#include "debug.h"
#include "worlddef.h"
#include "worldman.h"
#include "smooth.h"
#include "Exit Grids.h"
#include "Editor Undo.h"
#include "Strategic Movement.h"
#include "Font Control.h"
#include "SaveLoadMap.h"
#include <string.h>
#include "wcheck.h"
#include "soldier control.h"
#include "weapons.h"
#include "handle items.h"
#include "rotting corpses.h"
#include "tile cache.h"
#include "animation control.h"
#include "utilities.h"
#include "soldier create.h"
#include "soldier add.h"
#include "explosion control.h"
#include "tile animation.h"
#include "world items.h"
#include "tiledef.h"
#include "tiledat.h"
#include "interactive tiles.h"
#include "Handle Doors.h"
#include "smokeeffects.h"
#include "handle ui.h"
#include "pits.h"
#include "campaign Types.h"
#include "strategic.h"
#include "Action Items.h"
#include "Soldier Profile.h"
#include "Interface Dialogue.h"
#include "LightEffects.h"
#include "AI.h"
#include "Soldier tile.h"
#include "smell.h"
#include "GameSettings.h"
#include "Fog Of War.h"
#include "Simple Render Utils.h"
#include <stdarg.h>
#include <time.h>
#include "himage.h"
#include "vsurface.h"
#include "vsurface_private.h"
#include "sysutil.h"
#include "interface.h"
#include "interface cursors.h"
#include "structure.h"
#include "points.h"
#include "Dialogue Control.h"
#include "english.h"
#include "mousesystem.h"
#include "jascreens.h"
#include "math.h"
#include <stdlib.h>
#include <errno.h>
#include "input.h"
#include "video.h"
#include "vobject_blitters.h"
#include "edit_sys.h"
#include "line.h"
#include "Animation Data.h"
#include "Timer Control.h"
#include "Radar Screen.h"
#include "Render Dirty.h"
#include "Structure Internals.h"
#include "Shade Table Util.h"
#include <memory.h>
#include "Map Edgepoints.h"
#include "Map Information.h"
#include "vobject.h"
#include "worlddat.h"
#include "overhead map.h"
#include "interface control.h"
#include "cursors.h"
#include "soldier find.h"
#include "interface panels.h"
#include "Tactical Placement GUI.h"
#include "phys math.h"
#include "physics.h"
#include "los.h"
#include "event pump.h"
#include "interface items.h"
#include "Debug Control.h"
#include "text.h"
#include "Squads.h"
#include "Map Screen Interface Map Inventory.h"
//#include "container.h"
#include "fov.h"
#include "Overhead types.h"
#include "Tactical Save.h"
#include "MemMan.h"
#include "font.h"
#include "Button System.h"
#include "gameloop.h"
#include "Cursor Control.h"
#include "MessageBoxScreen.h"
#include "assignments.h"
#include "WordWrap.h"
#include "time.h"
#include "Keys.h"
#include "bullets.h"
#include "Animation Cache.h"
#include "tile surface.h"
#include <wchar.h>
#include "screenids.h"
#include "shading.h"
#include "Soldier Init List.h"
#include "Summary Info.h"
#include "Animated ProgressBar.h"
#include "EditorBuildings.h"
#include "music control.h"
#include "Scheduling.h"
#include "EditorMapInfo.h"
#include "Smoothing Utils.h"
#include "Meanwhile.h"
#endif
File diff suppressed because it is too large Load Diff
+506
View File
@@ -0,0 +1,506 @@
# Microsoft Developer Studio Project File - Name="TileEngine" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=TileEngine - Win32 Demo Bounds Checker
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "TileEngine.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "TileEngine.mak" CFG="TileEngine - Win32 Demo Bounds Checker"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "TileEngine - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "TileEngine - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "TileEngine - Win32 Release with Debug Info" (based on "Win32 (x86) Static Library")
!MESSAGE "TileEngine - Win32 Bounds Checker" (based on "Win32 (x86) Static Library")
!MESSAGE "TileEngine - Win32 Debug Demo" (based on "Win32 (x86) Static Library")
!MESSAGE "TileEngine - Win32 Release Demo" (based on "Win32 (x86) Static Library")
!MESSAGE "TileEngine - Win32 Demo Release with Debug Info" (based on "Win32 (x86) Static Library")
!MESSAGE "TileEngine - Win32 Demo Bounds Checker" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Jagged Alliance 2/Development/Programming/Jagged Alliance 2/Build", AVAAAAAA"
# PROP Scc_LocalPath "..\..\..\ja2\build"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "TileEngine - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir "."
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir "."
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\Standard Gaming Platform" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\Editor" /I "..\strategic" /I "..\Laptop" /I ".\\" /D "CALLBACKTIMER" /D "PRECOMPILEDHEADERS" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"TileEngine All.h" /FD /O2b2 /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TileEngine - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir "."
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir "."
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\Standard Gaming Platform" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\Editor" /I "..\strategic" /I "..\Laptop" /I ".\\" /D "CALLBACKTIMER" /D "PRECOMPILEDHEADERS" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "_VTUNE_PROFILING" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"TileEngine All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TileEngine - Win32 Release with Debug Info"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release with Debug Info"
# PROP BASE Intermediate_Dir "Release with Debug Info"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release with Debug"
# PROP Intermediate_Dir "Release with Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\tacticalai" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "NDEBUG" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /FR /YX /FD /O2b2 /c
# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "..\Standard Gaming Platform" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\Editor" /I "..\strategic" /I "..\Laptop" /I ".\\" /D "NDEBUG" /D "RELEASE_WITH_DEBUG_INFO" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "_VTUNE_PROFILING" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"TileEngine All.h" /FD /O2b2 /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TileEngine - Win32 Bounds Checker"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "TileEng0"
# PROP BASE Intermediate_Dir "TileEng0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Bounds Checker"
# PROP Intermediate_Dir "Bounds Checker"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "_DEBUG" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "_DEBUG" /D "BOUNDS_CHECKER" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "_VTUNE_PROFILING" /FR /YX"TileEngine All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TileEngine - Win32 Debug Demo"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "TileEngi"
# PROP BASE Intermediate_Dir "TileEngi"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug Demo"
# PROP Intermediate_Dir "Debug Demo"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "_DEBUG" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "_DEBUG" /D "JA2DEMO" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"TileEngine All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TileEngine - Win32 Release Demo"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "TileEng1"
# PROP BASE Intermediate_Dir "TileEng1"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release Demo"
# PROP Intermediate_Dir "Release Demo"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W4 /GX /Zi /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\tacticalai" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "NDEBUG" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "RELEASE_WITH_DEBUG_INFO" /FR /YX /FD /O2b2 /c
# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\tacticalai" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "RELEASE_WITH_DEBUG_INFO" /D "NDEBUG" /D "JA2DEMO" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"TileEngine All.h" /FD /O2b2 /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TileEngine - Win32 Demo Release with Debug Info"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "TileEng2"
# PROP BASE Intermediate_Dir "TileEng2"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Demo Release with Debug"
# PROP Intermediate_Dir "Demo Release with Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W4 /GX /Zi /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\tacticalai" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "NDEBUG" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "RELEASE_WITH_DEBUG_INFO" /FR /YX /FD /O2b2 /c
# ADD CPP /nologo /MT /W4 /GX /Zi /O2 /I "..\Standard Gaming Platform" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\Editor" /I "..\strategic" /I "..\Laptop" /I ".\\" /D "RELEASE_WITH_DEBUG_INFO" /D "NDEBUG" /D "JA2DEMO" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"TileEngine All.h" /FD /O2b2 /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TileEngine - Win32 Demo Bounds Checker"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "TileEng3"
# PROP BASE Intermediate_Dir "TileEng3"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Demo Bounds Checker"
# PROP Intermediate_Dir "Demo Bounds Checker"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "CALLBACKTIMER" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "BOUNDS_CHECKER" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\Tactical" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Editor" /I "\ja2\build\strategic" /I "\ja2\build\Laptop" /D "_DEBUG" /D "BOUNDS_CHECKER" /D "JA2DEMO" /D "CALLBACKTIMER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"TileEngine All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "TileEngine - Win32 Release"
# Name "TileEngine - Win32 Debug"
# Name "TileEngine - Win32 Release with Debug Info"
# Name "TileEngine - Win32 Bounds Checker"
# Name "TileEngine - Win32 Debug Demo"
# Name "TileEngine - Win32 Release Demo"
# Name "TileEngine - Win32 Demo Release with Debug Info"
# Name "TileEngine - Win32 Demo Bounds Checker"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=".\Ambient Control.cpp"
# End Source File
# Begin Source File
SOURCE=.\Buildings.cpp
# End Source File
# Begin Source File
SOURCE=.\environment.cpp
# End Source File
# Begin Source File
SOURCE=".\Exit Grids.cpp"
# End Source File
# Begin Source File
SOURCE=".\Explosion Control.cpp"
# End Source File
# Begin Source File
SOURCE=".\Fog Of War.cpp"
# End Source File
# Begin Source File
SOURCE=".\Interactive Tiles.cpp"
# End Source File
# Begin Source File
SOURCE=".\Isometric Utils.cpp"
# End Source File
# Begin Source File
SOURCE=.\LightEffects.cpp
# End Source File
# Begin Source File
SOURCE=.\lighting.cpp
# End Source File
# Begin Source File
SOURCE=".\Map Edgepoints.cpp"
# End Source File
# Begin Source File
SOURCE=".\overhead map.cpp"
# End Source File
# Begin Source File
SOURCE=".\phys math.cpp"
# End Source File
# Begin Source File
SOURCE=.\physics.cpp
# End Source File
# Begin Source File
SOURCE=.\pits.cpp
# End Source File
# Begin Source File
SOURCE=".\Radar Screen.cpp"
# End Source File
# Begin Source File
SOURCE=".\Render Dirty.cpp"
# End Source File
# Begin Source File
SOURCE=".\Render Fun.cpp"
# End Source File
# Begin Source File
SOURCE=.\renderworld.cpp
# End Source File
# Begin Source File
SOURCE=.\SaveLoadMap.cpp
# End Source File
# Begin Source File
SOURCE=".\Shade Table Util.cpp"
# End Source File
# Begin Source File
SOURCE=".\Simple Render Utils.cpp"
# End Source File
# Begin Source File
SOURCE=.\Smell.cpp
# End Source File
# Begin Source File
SOURCE=.\SmokeEffects.cpp
# End Source File
# Begin Source File
SOURCE=.\structure.cpp
# End Source File
# Begin Source File
SOURCE=.\sysutil.cpp
# End Source File
# Begin Source File
SOURCE=".\Tactical Placement GUI.cpp"
# End Source File
# Begin Source File
SOURCE=".\Tile Animation.cpp"
# End Source File
# Begin Source File
SOURCE=".\Tile Cache.cpp"
# End Source File
# Begin Source File
SOURCE=".\Tile Surface.cpp"
# End Source File
# Begin Source File
SOURCE=.\TileDat.cpp
# End Source File
# Begin Source File
SOURCE=.\tiledef.cpp
# End Source File
# Begin Source File
SOURCE=.\WorldDat.cpp
# End Source File
# Begin Source File
SOURCE=.\worlddef.cpp
# End Source File
# Begin Source File
SOURCE=.\worldman.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=".\Ambient Control.h"
# End Source File
# Begin Source File
SOURCE=".\Ambient Types.h"
# End Source File
# Begin Source File
SOURCE=.\Buildings.h
# End Source File
# Begin Source File
SOURCE=.\edit_sys.h
# End Source File
# Begin Source File
SOURCE=.\environment.h
# End Source File
# Begin Source File
SOURCE=".\Exit Grids.h"
# End Source File
# Begin Source File
SOURCE=".\Fog Of War.h"
# End Source File
# Begin Source File
SOURCE=".\Interactive Tiles.h"
# End Source File
# Begin Source File
SOURCE=".\Isometric Utils.h"
# End Source File
# Begin Source File
SOURCE=.\lighting.h
# End Source File
# Begin Source File
SOURCE=".\Map Edgepoints.h"
# End Source File
# Begin Source File
SOURCE=.\pits.h
# End Source File
# Begin Source File
SOURCE=".\Radar Screen.h"
# End Source File
# Begin Source File
SOURCE=".\render dirty.h"
# End Source File
# Begin Source File
SOURCE=".\Render Fun.h"
# End Source File
# Begin Source File
SOURCE=.\renderworld.h
# End Source File
# Begin Source File
SOURCE=.\SaveLoadMap.h
# End Source File
# Begin Source File
SOURCE=".\Shade Table Util.h"
# End Source File
# Begin Source File
SOURCE=".\Simple Render Utils.h"
# End Source File
# Begin Source File
SOURCE=.\Smell.h
# End Source File
# Begin Source File
SOURCE=".\Structure Internals.h"
# End Source File
# Begin Source File
SOURCE=.\structure.h
# End Source File
# Begin Source File
SOURCE=.\sysutil.h
# End Source File
# Begin Source File
SOURCE=".\Tile Animation.h"
# End Source File
# Begin Source File
SOURCE=.\TileDat.h
# End Source File
# Begin Source File
SOURCE=.\tiledef.h
# End Source File
# Begin Source File
SOURCE=".\TileEngine All.h"
# End Source File
# Begin Source File
SOURCE=.\WorldDat.h
# End Source File
# Begin Source File
SOURCE=.\worlddef.h
# End Source File
# Begin Source File
SOURCE=.\worldman.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+89
View File
@@ -0,0 +1,89 @@
#ifndef WORLD_TILESET_NUMS_H
#define WORLD_TILESET_NUMS_H
// Snap: NUM_TILESETS no longer limits the number of tilesets.
// See gubNumSets in WorldDat.cpp
enum
{
TLS_GENERIC_1, // 0, JA2 default
TLS_CAVES_1,
TLS_DESERT_1,
TLS_LUSH_1,
TLS_TROPICAL_1,
TLS_MOUNTAINS_1,
TLS_COASTAL_1,
TLS_SWAMP_1,
TLS_FARM_1,
TLS_OMERTA,
TLS_GENERIC_2, // 10
TLS_FARM_2,
TLS_PRISON,
TLS_HOSPITAL,
TLS_DEMO_BASEMENT,
TLS_BURNT_TREES,
TLS_LAWLESS_1,
TLS_AIRSTRIP,
TLS_LAWLESS_2,
TLS_DEAD_AIRSTRIP,
TLS_BASEMENT, // 20
TLS_LAWLESS_3,
TLS_PRISON_DUNGEON,
TLS_ACTIVE_DRASSEN,
TLS_SAM_SITES,
TLS_LUSH_2,
TLS_MILITARY_BASE,
TLS_MILITARY_JAIL,
TLS_MILITARY_WAREHOUSE,
TLS_MILITARY_TOWN,
TLS_OLD_SCHOOL, // 30
TLS_CAMBRIA_STRIP,
TLS_CAMBRIA_HOMES,
TLS_PALACE,
TLS_TROPICAL_SAM,
TLS_GRUMM_1,
TLS_GRUMM_2,
TLS_BALIME,
TLS_BALIME_MUSEUM,
TLS_DESERT_SAM,
TLS_ORTA, // 40
TLS_ORTA_WEAPONS,
TLS_SWAMP_BARETREES,
TLS_ESTONI,
TLS_QUEENS_PRISON,
TLS_QUEENS_TROPICAL,
TLS_MEDUNA_INNER_TOWN,
TLS_QUEENS_SAM,
TLS_QUEENS_AIRPORT,
TLS_DEMO_TILESET,
TLS_HEAVY_SNOW, // 50, JA2.5 default
TLS_MIXED_SNOW,
TLS_GRASS_SNOW,
TLS_FALL_TOWN,
TLS_MINING_TOWN,
TLS_POWER_PLANT,
TLS_SEWERS,
TLS_UNDERGROUND_COMPLEX,
TLS_UPPER_COMPLEX,
TLS_LOWEST_LEVEL_COMPLEX,
TILESET_60, // 60
TILESET_61,
TILESET_62,
TILESET_63,
TILESET_64,
TILESET_65,
TILESET_66,
TILESET_67,
TILESET_68,
TILESET_69,
NUM_TILESETS // 70
};
#endif
+234
View File
@@ -0,0 +1,234 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include "worlddat.h"
#include "worlddef.h"
#include "tiledef.h"
#include "sys globals.h"
#include "tile surface.h"
#include "fileMan.h"
#endif
// THIS FILE CONTAINS DEFINITIONS FOR TILESET FILES
void SetTilesetThreeTerrainValues();
void SetTilesetFourTerrainValues();
// Snap: This global gives the number of tilesets in JA2SET.DAT
// It is properly initialized in InitEngineTilesets,
// where it is read from JA2SET.DAT header.
UINT8 gubNumSets = MAX_TILESETS;
TILESET gTilesets[ MAX_TILESETS ];
void InitEngineTilesets( )
{
UINT32 cnt, cnt2, uiNumFiles;
// FILE *hfile;
HWFILE hfile;
CHAR8 zName[32];
UINT32 uiNumBytesRead;
//OPEN FILE
// hfile = fopen( "BINARYDATA\\JA2SET.DAT", "rb" );
hfile = FileOpen( "BINARYDATA\\JA2SET.DAT", FILE_ACCESS_READ, FALSE );
if ( !hfile )
{
SET_ERROR( "Cannot open tileset data file" );
return;
}
// READ # TILESETS and compare
// fread( &gubNumSets, sizeof( gubNumSets ), 1, hfile );
FileRead( hfile, &gubNumSets, sizeof( gubNumSets ), &uiNumBytesRead );
// CHECK
if ( gubNumSets > MAX_TILESETS )
{
// Report error
SET_ERROR( "Too many tilesets in the data file" );
return;
}
// READ #files
// fread( &uiNumFiles, sizeof( uiNumFiles ), 1, hfile );
FileRead( hfile, &uiNumFiles, sizeof( uiNumFiles ), &uiNumBytesRead );
// COMPARE
if ( uiNumFiles != NUMBEROFTILETYPES )
{
// Report error
SET_ERROR( "Number of tilesets slots in code does not match data file" );
return;
}
// Loop through each tileset, load name then files
for ( cnt = 0; cnt < gubNumSets; cnt++ )
{
//Read name
// fread( &zName, sizeof( zName ), 1, hfile );
FileRead( hfile, &zName, sizeof( zName ), &uiNumBytesRead );
// Read ambience value
// fread( &(gTilesets[ cnt ].ubAmbientID), sizeof( UINT8), 1, hfile );
FileRead( hfile, &(gTilesets[ cnt ].ubAmbientID), sizeof( UINT8 ), &uiNumBytesRead );
// Set into tileset
swprintf( (wchar_t *)gTilesets[ cnt ].zName, L"%S", zName );
// Loop for files
for ( cnt2 = 0; cnt2 < uiNumFiles; cnt2++ )
{
// Read file name
// fread( &zName, sizeof( zName ), 1, hfile );
FileRead( hfile, &zName, sizeof( zName ), &uiNumBytesRead );
// Set into database
strcpy( gTilesets[ cnt ].TileSurfaceFilenames[ cnt2 ], zName );
}
}
// fclose( hfile );
FileClose( hfile );
// SET CALLBACK FUNTIONS!!!!!!!!!!!!!
gTilesets[ TLS_CAVES_1 ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetTwoTerrainValues;
gTilesets[ TLS_AIRSTRIP ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_DEAD_AIRSTRIP ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_PALACE ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_BALIME ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_BALIME_MUSEUM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_QUEENS_TROPICAL ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_MEDUNA_INNER_TOWN ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_QUEENS_SAM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_QUEENS_AIRPORT ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
gTilesets[ TLS_TROPICAL_1 ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetFourTerrainValues;
gTilesets[ TLS_DESERT_SAM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetFourTerrainValues;
}
void SetTilesetOneTerrainValues( )
{
// FIRST TEXUTRES
gTileSurfaceArray[ FIRSTTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ SECONDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ THIRDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FOURTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FIFTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SIXTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SEVENTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ REGWATERTEXTURE ]->ubTerrainID = LOW_WATER;
gTileSurfaceArray[ DEEPWATERTEXTURE ]->ubTerrainID = DEEP_WATER;
// NOW ROADS
gTileSurfaceArray[ FIRSTROAD ]->ubTerrainID = DIRT_ROAD;
gTileSurfaceArray[ ROADPIECES ]->ubTerrainID = DIRT_ROAD;
// NOW FLOORS
gTileSurfaceArray[ FIRSTFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ SECONDFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ THIRDFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ FOURTHFLOOR ]->ubTerrainID = FLAT_FLOOR;
// NOW ANY TERRAIN MODIFYING DEBRIS
}
void SetTilesetTwoTerrainValues( )
{
// FIRST TEXUTRES
gTileSurfaceArray[ FIRSTTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ SECONDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ THIRDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FOURTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FIFTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SIXTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SEVENTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ REGWATERTEXTURE ]->ubTerrainID = LOW_WATER;
gTileSurfaceArray[ DEEPWATERTEXTURE ]->ubTerrainID = DEEP_WATER;
// NOW ROADS
gTileSurfaceArray[ FIRSTROAD ]->ubTerrainID = DIRT_ROAD;
gTileSurfaceArray[ ROADPIECES ]->ubTerrainID = DIRT_ROAD;
// NOW FLOORS
gTileSurfaceArray[ FIRSTFLOOR ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ SECONDFLOOR ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ THIRDFLOOR ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FOURTHFLOOR ]->ubTerrainID = FLAT_GROUND;
}
void SetTilesetThreeTerrainValues( )
{
// DIFFERENCE FROM #1 IS THAT ROADS ARE PAVED
// FIRST TEXUTRES
gTileSurfaceArray[ FIRSTTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ SECONDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ THIRDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FOURTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FIFTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SIXTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SEVENTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ REGWATERTEXTURE ]->ubTerrainID = LOW_WATER;
gTileSurfaceArray[ DEEPWATERTEXTURE ]->ubTerrainID = DEEP_WATER;
// NOW ROADS
gTileSurfaceArray[ FIRSTROAD ]->ubTerrainID = PAVED_ROAD;
gTileSurfaceArray[ ROADPIECES ]->ubTerrainID = PAVED_ROAD;
// NOW FLOORS
gTileSurfaceArray[ FIRSTFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ SECONDFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ THIRDFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ FOURTHFLOOR ]->ubTerrainID = FLAT_FLOOR;
// NOW ANY TERRAIN MODIFYING DEBRIS
}
void SetTilesetFourTerrainValues( )
{
// DIFFERENCE FROM #1 IS THAT FLOOR2 IS NOT FLAT_FLOOR BUT FLAT_GROUND
// FIRST TEXUTRES
gTileSurfaceArray[ FIRSTTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ SECONDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ THIRDTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FOURTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ FIFTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SIXTHTEXTURE ]->ubTerrainID = LOW_GRASS;
gTileSurfaceArray[ SEVENTHTEXTURE ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ REGWATERTEXTURE ]->ubTerrainID = LOW_WATER;
gTileSurfaceArray[ DEEPWATERTEXTURE ]->ubTerrainID = DEEP_WATER;
// NOW ROADS
gTileSurfaceArray[ FIRSTROAD ]->ubTerrainID = DIRT_ROAD;
gTileSurfaceArray[ ROADPIECES ]->ubTerrainID = DIRT_ROAD;
// NOW FLOORS
gTileSurfaceArray[ FIRSTFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ SECONDFLOOR ]->ubTerrainID = FLAT_GROUND;
gTileSurfaceArray[ THIRDFLOOR ]->ubTerrainID = FLAT_FLOOR;
gTileSurfaceArray[ FOURTHFLOOR ]->ubTerrainID = FLAT_FLOOR;
// NOW ANY TERRAIN MODIFYING DEBRIS
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef WORLD_DAT_H
#define WORLD_DAT_H
#include "types.h"
#include "tiledat.h"
#include "World Tileset Enums.h"
typedef void (*TILESET_CALLBACK)( void );
typedef struct
{
INT16 zName[ 32 ];
CHAR8 TileSurfaceFilenames[ NUMBEROFTILETYPES ][32];
UINT8 ubAmbientID;
TILESET_CALLBACK MovementCostFnc;
} TILESET;
// Snap: The maximum number of tilesets allowed is max of UINT8
#define MAX_TILESETS 255
extern UINT8 gubNumSets; // from WorldDat.cpp
extern TILESET gTilesets[ MAX_TILESETS ];
void InitEngineTilesets( );
// THESE FUNCTIONS WILL SET TERRAIN VALUES - CALL ONE FOR EACH TILESET
void SetTilesetOneTerrainValues( );
void SetTilesetTwoTerrainValues( );
#endif
+634
View File
@@ -0,0 +1,634 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "sgp.h"
#include "lighting.h"
#include "environment.h"
#include "renderworld.h"
#include "sound control.h"
#include "overhead.h"
#include "Game Clock.h"
#include "quests.h"
#include "Ambient Control.h"
#include "AimMembers.h"
#include "Strategic Event Handler.h"
#include "BobbyR.h"
#include "mercs.h"
#include "email.h"
#include "Merc Hiring.h"
#include "insurance Contract.h"
#include "Strategic Merc Handler.h"
#include "Game Events.h"
#include "message.h"
#include "opplist.h"
#include "Random.h"
#include "strategicmap.h"
#endif
//effects whether or not time of day effects the lighting. Underground
//maps have an ambient light level that is saved in the map, and doesn't change.
BOOLEAN gfBasement = FALSE;
BOOLEAN gfCaves = FALSE;
#define ENV_TOD_FLAGS_DAY 0x00000001
#define ENV_TOD_FLAGS_DAWN 0x00000002
#define ENV_TOD_FLAGS_DUSK 0x00000004
#define ENV_TOD_FLAGS_NIGHT 0x00000008
/*
#define DAWNLIGHT_START ( 5 * 60 )
#define DAWN_START ( 6 * 60 )
#define DAY_START ( 8 * 60 )
#define TWILLIGHT_START ( 19 * 60 )
#define DUSK_START ( 20 * 60 )
#define NIGHT_START ( 22 * 60 )
*/
#define DAWN_START ( 6 * 60 + 47 ) //6:47AM
#define DAY_START ( 7 * 60 + 5 ) //7:05AM
#define DUSK_START ( 20 * 60 + 57 ) //8:57PM
#define NIGHT_START ( 21 * 60 + 15 ) //9:15PM
#define DAWN_TO_DAY (DAY_START-DAWN_START)
#define DAY_TO_DUSK (DUSK_START-DAY_START)
#define DUSK_TO_NIGHT (NIGHT_START-DUSK_START)
#define NIGHT_TO_DAWN (24*60-NIGHT_START+DAWN_START)
UINT32 guiEnvWeather = 0;
UINT32 guiRainLoop = NO_SAMPLE;
// frame cues for lightning
UINT8 ubLightningTable[3][10][2]=
{ { {0, 15},
{1, 0},
{2, 0},
{3, 6},
{4, 0},
{5, 0},
{6, 0},
{7, 0},
{8, 0},
{9, 0} },
{ {0, 15},
{1, 0},
{2, 0},
{3, 6},
{4, 0},
{5, 15},
{6, 0},
{7, 6},
{8, 0},
{9, 0} },
{ {0, 15},
{1, 0},
{2, 15},
{3, 0},
{4, 0},
{5, 0},
{6, 0},
{7, 0},
{8, 0},
{9, 0} } };
// CJC: I don't think these are used anywhere!
UINT8 guiTODFlags[ENV_NUM_TIMES] = {
ENV_TOD_FLAGS_NIGHT, // 00
ENV_TOD_FLAGS_NIGHT, // 01
ENV_TOD_FLAGS_NIGHT, // 02
ENV_TOD_FLAGS_NIGHT, // 03
ENV_TOD_FLAGS_NIGHT, // 04
ENV_TOD_FLAGS_DAWN, // 05
ENV_TOD_FLAGS_DAWN, // 06
ENV_TOD_FLAGS_DAWN, // 07
ENV_TOD_FLAGS_DAY, // 08
ENV_TOD_FLAGS_DAY, // 09
ENV_TOD_FLAGS_DAY, // 10
ENV_TOD_FLAGS_DAY, // 11
ENV_TOD_FLAGS_DAY, // 12
ENV_TOD_FLAGS_DAY, // 13
ENV_TOD_FLAGS_DAY, // 14
ENV_TOD_FLAGS_DAY, // 15
ENV_TOD_FLAGS_DAY, // 16
ENV_TOD_FLAGS_DAY, // 17
ENV_TOD_FLAGS_DAY, // 18
ENV_TOD_FLAGS_DUSK, // 19
ENV_TOD_FLAGS_DUSK, // 20
ENV_TOD_FLAGS_DUSK, // 21
ENV_TOD_FLAGS_NIGHT, // 22
ENV_TOD_FLAGS_NIGHT}; // 23
typedef enum
{
COOL,
WARM,
HOT
} Temperatures;
typedef enum
{
TEMPERATURE_DESERT_COOL,
TEMPERATURE_DESERT_WARM,
TEMPERATURE_DESERT_HOT,
TEMPERATURE_GLOBAL_COOL,
TEMPERATURE_GLOBAL_WARM,
TEMPERATURE_GLOBAL_HOT,
} TemperatureEvents;
#define DESERT_WARM_START ( 8 * 60 )
#define DESERT_HOT_START ( 9 * 60 )
#define DESERT_HOT_END (17 * 60 )
#define DESERT_WARM_END (19 * 60 )
#define GLOBAL_WARM_START ( 9 * 60 )
#define GLOBAL_HOT_START (12 * 60 )
#define GLOBAL_HOT_END (14 * 60 )
#define GLOBAL_WARM_END (17 * 60 )
#define HOT_DAY_LIGHTLEVEL 2
BOOLEAN fTimeOfDayControls=TRUE;
UINT32 guiEnvTime=0;
UINT32 guiEnvDay=0;
UINT8 gubEnvLightValue = 0;
BOOLEAN gfDoLighting = FALSE;
UINT8 gubDesertTemperature = 0;
UINT8 gubGlobalTemperature = 0;
// local prototypes
void EnvDoLightning(void);
// polled by the game to handle time/atmosphere changes from gamescreen
void EnvironmentController( BOOLEAN fCheckForLights )
{
UINT32 uiOldWorldHour;
UINT8 ubLightAdjustFromWeather = 0;
// do none of this stuff in the basement or caves
if( gfBasement || gfCaves )
{
guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS );
guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS );
if ( guiRainLoop != NO_SAMPLE )
{
SoundStop( guiRainLoop );
guiRainLoop = NO_SAMPLE;
}
return;
}
if(fTimeOfDayControls )
{
uiOldWorldHour = GetWorldHour();
// If hour is different
if ( uiOldWorldHour != guiEnvTime )
{
// Hour change....
guiEnvTime=uiOldWorldHour;
}
//ExecuteStrategicEventsUntilTimeStamp( (UINT16)GetWorldTotalMin( ) );
// Polled weather stuff...
// ONly do indooors
if( !gfBasement && !gfCaves )
{
#if 0
if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) )
{
if ( guiRainLoop == NO_SAMPLE )
{
guiRainLoop = PlayJA2Ambient( RAIN_1, MIDVOLUME, 0 );
}
// Do lightning if we want...
if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS ) )
{
EnvDoLightning( );
}
}
else
{
if ( guiRainLoop != NO_SAMPLE )
{
SoundStop( guiRainLoop );
guiRainLoop = NO_SAMPLE;
}
}
#endif
}
if ( gfDoLighting && fCheckForLights )
{
// Adjust light level based on weather...
ubLightAdjustFromWeather = GetTimeOfDayAmbientLightLevel();
// ONly do indooors
if( !gfBasement && !gfCaves )
{
// Rain storms....
#if 0
if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) )
{
// Thunder showers.. make darker
if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS ) )
{
ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+2, NORMAL_LIGHTLEVEL_NIGHT ));
}
else
{
ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+1, NORMAL_LIGHTLEVEL_NIGHT ));
}
}
#endif
}
LightSetBaseLevel( ubLightAdjustFromWeather );
//Update Merc Lights since the above function modifies it.
HandlePlayerTogglingLightEffects( FALSE );
// Make teams look for all
// AllTeamsLookForAll( FALSE );
// Set global light value
SetRenderFlags(RENDER_FLAG_FULL);
gfDoLighting = FALSE;
}
}
}
void BuildDayLightLevels()
{
UINT32 uiLoop, uiHour;
/*
// Dawn; light 12
AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DAWNLIGHT_START, NORMAL_LIGHTLEVEL_NIGHT - 1 );
// loop from light 12 down to light 4
for (uiLoop = 1; uiLoop < 8; uiLoop++)
{
AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DAWN_START + 15 * uiLoop, NORMAL_LIGHTLEVEL_NIGHT - 1 - uiLoop );
}
*/
//Transition from night to day
for( uiLoop = 0; uiLoop < 9; uiLoop++ )
{
AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DAWN_START + 2 * uiLoop, NORMAL_LIGHTLEVEL_NIGHT - 1 - uiLoop );
}
// Add events for hot times
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_WARM_START, TEMPERATURE_DESERT_WARM );
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_HOT_START, TEMPERATURE_DESERT_HOT );
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_HOT_END, TEMPERATURE_DESERT_WARM );
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_WARM_END, TEMPERATURE_DESERT_COOL );
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_WARM_START, TEMPERATURE_GLOBAL_WARM );
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_HOT_START, TEMPERATURE_GLOBAL_HOT );
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_HOT_END, TEMPERATURE_GLOBAL_WARM );
AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_WARM_END, TEMPERATURE_GLOBAL_COOL );
/*
// Twilight; light 5
AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, TWILLIGHT_START, NORMAL_LIGHTLEVEL_DAY + 1 );
// Dusk; loop from light 5 up to 12
for (uiLoop = 1; uiLoop < 8; uiLoop++)
{
AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DUSK_START + 15 * uiLoop, NORMAL_LIGHTLEVEL_DAY + 1 + uiLoop );
}
*/
//Transition from day to night
for( uiLoop = 0; uiLoop < 9; uiLoop++ )
{
AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DUSK_START + 2 * uiLoop, NORMAL_LIGHTLEVEL_DAY + 1 + uiLoop );
}
//Set up the scheduling for turning lights on and off based on the various types.
uiHour = NIGHT_TIME_LIGHT_START_HOUR == 24 ? 0 : NIGHT_TIME_LIGHT_START_HOUR;
AddEveryDayStrategicEvent( EVENT_TURN_ON_NIGHT_LIGHTS, uiHour * 60, 0 );
uiHour = NIGHT_TIME_LIGHT_END_HOUR == 24 ? 0 : NIGHT_TIME_LIGHT_END_HOUR;
AddEveryDayStrategicEvent( EVENT_TURN_OFF_NIGHT_LIGHTS, uiHour * 60, 0 );
uiHour = PRIME_TIME_LIGHT_START_HOUR == 24 ? 0 : PRIME_TIME_LIGHT_START_HOUR;
AddEveryDayStrategicEvent( EVENT_TURN_ON_PRIME_LIGHTS, uiHour * 60, 0 );
uiHour = PRIME_TIME_LIGHT_END_HOUR == 24 ? 0 : PRIME_TIME_LIGHT_END_HOUR;
AddEveryDayStrategicEvent( EVENT_TURN_OFF_PRIME_LIGHTS, uiHour * 60, 0 );
}
void BuildDayAmbientSounds( )
{
INT32 cnt;
// Add events!
for ( cnt = 0; cnt < gsNumAmbData; cnt++ )
{
switch( gAmbData[ cnt ].ubTimeCatagory )
{
case AMB_TOD_DAWN:
AddSameDayRangedStrategicEvent( EVENT_AMBIENT, DAWN_START, DAWN_TO_DAY, cnt );
break;
case AMB_TOD_DAY:
AddSameDayRangedStrategicEvent( EVENT_AMBIENT, DAY_START, DAY_TO_DUSK, cnt );
break;
case AMB_TOD_DUSK:
AddSameDayRangedStrategicEvent( EVENT_AMBIENT, DUSK_START, DUSK_TO_NIGHT, cnt );
break;
case AMB_TOD_NIGHT:
AddSameDayRangedStrategicEvent( EVENT_AMBIENT, NIGHT_START, NIGHT_TO_DAWN, cnt );
break;
}
}
guiRainLoop = NO_SAMPLE;
}
void ForecastDayEvents( )
{
UINT32 uiOldDay;
UINT32 uiStartTime, uiEndTime;
UINT8 ubStormIntensity;
// UINT32 cnt;
// Get current day and see if different
if ( ( uiOldDay = GetWorldDay() ) != guiEnvDay )
{
// It's a new day, forecast weather
guiEnvDay = uiOldDay;
// Set light level changes
//BuildDayLightLevels();
// Build ambient sound queues
BuildDayAmbientSounds( );
// Build weather....
// ATE: Don't forecast if start of game...
if ( guiEnvDay > 1 )
{
// Should it rain...?
if ( Random( 100 ) < 20 )
{
// Add rain!
// Between 6:00 and 10:00
uiStartTime = (UINT32)( 360 + Random( 1080 ) );
// Between 5 - 15 miniutes
uiEndTime = uiStartTime + ( 5 + Random( 10 ) );
ubStormIntensity = 0;
// Randomze for a storm!
if ( Random( 10 ) < 5 )
{
ubStormIntensity = 1;
}
// ATE: Disable RAIN!
// AddSameDayRangedStrategicEvent( EVENT_RAINSTORM, uiStartTime, uiEndTime - uiStartTime, ubStormIntensity );
//AddSameDayStrategicEvent( EVENT_BEGINRAINSTORM, uiStartTime, ubStormIntensity );
//AddSameDayStrategicEvent( EVENT_ENDRAINSTORM, uiEndTime, 0 );
}
}
}
}
void EnvEnableTOD(void)
{
fTimeOfDayControls=TRUE;
}
void EnvDisableTOD(void)
{
fTimeOfDayControls=FALSE;
}
void EnvDoLightning(void)
{
static UINT32 uiCount=0, uiIndex=0, uiStrike=0, uiFrameNext=1000;
static UINT8 ubLevel=0, ubLastLevel=0;
if ( gfPauseDueToPlayerGamePause )
{
return;
}
uiCount++;
if(uiCount >= (uiFrameNext+10))
{
uiCount=0;
uiIndex=0;
ubLevel=0;
ubLastLevel=0;
uiStrike=Random(3);
uiFrameNext=1000+Random(1000);
}
else if(uiCount >= uiFrameNext)
{
if(uiCount == uiFrameNext)
{
//EnvStopCrickets();
PlayJA2Ambient(LIGHTNING_1+Random(2), HIGHVOLUME, 1);
}
while(uiCount > ((UINT32)ubLightningTable[uiStrike][uiIndex][0] + uiFrameNext))
uiIndex++;
ubLastLevel=ubLevel;
ubLevel=ubLightningTable[uiStrike][uiIndex][1];
// ATE: Don't modify if scrolling!
if ( gfScrollPending || gfScrollInertia )
{
}
else
{
if(ubLastLevel!=ubLevel)
{
if(ubLevel > ubLastLevel)
{
LightAddBaseLevel(0, (UINT8)(ubLevel-ubLastLevel));
if(ubLevel > 0)
RenderSetShadows(TRUE);
}
else
{
LightSubtractBaseLevel(0, (UINT8)(ubLastLevel-ubLevel));
if(ubLevel > 0)
RenderSetShadows(TRUE);
}
SetRenderFlags(RENDER_FLAG_FULL);
}
}
}
}
UINT8 GetTimeOfDayAmbientLightLevel()
{
if ( SectorTemperature( GetWorldMinutesInDay(), gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == HOT )
{
return( HOT_DAY_LIGHTLEVEL );
}
else
{
return( gubEnvLightValue );
}
}
void EnvBeginRainStorm( UINT8 ubIntensity )
{
if( !gfBasement && !gfCaves )
{
gfDoLighting = TRUE;
#ifdef JA2TESTVERSION
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Starting Rain...." );
#endif
if ( ubIntensity == 1 )
{
// Turn on rain storms
guiEnvWeather |= WEATHER_FORECAST_THUNDERSHOWERS;
}
else
{
guiEnvWeather |= WEATHER_FORECAST_SHOWERS;
}
}
}
void EnvEndRainStorm( )
{
gfDoLighting = TRUE;
#ifdef JA2TESTVERSION
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Ending Rain...." );
#endif
guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS );
guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS );
}
void TurnOnNightLights()
{
INT32 i;
for( i = 0; i < MAX_LIGHT_SPRITES; i++ )
{
if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE &&
LightSprites[ i ].uiFlags & LIGHT_NIGHTTIME &&
!(LightSprites[ i ].uiFlags & (LIGHT_SPR_ON|MERC_LIGHT) ) )
{
LightSpritePower( i, TRUE );
}
}
}
void TurnOffNightLights()
{
INT32 i;
for( i = 0; i < MAX_LIGHT_SPRITES; i++ )
{
if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE &&
LightSprites[ i ].uiFlags & LIGHT_NIGHTTIME &&
LightSprites[ i ].uiFlags & LIGHT_SPR_ON &&
!(LightSprites[ i ].uiFlags & MERC_LIGHT) )
{
LightSpritePower( i, FALSE );
}
}
}
void TurnOnPrimeLights()
{
INT32 i;
for( i = 0; i < MAX_LIGHT_SPRITES; i++ )
{
if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE &&
LightSprites[ i ].uiFlags & LIGHT_PRIMETIME &&
!(LightSprites[ i ].uiFlags & (LIGHT_SPR_ON|MERC_LIGHT) ) )
{
LightSpritePower( i, TRUE );
}
}
}
void TurnOffPrimeLights()
{
INT32 i;
for( i = 0; i < MAX_LIGHT_SPRITES; i++ )
{
if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE &&
LightSprites[ i ].uiFlags & LIGHT_PRIMETIME &&
LightSprites[ i ].uiFlags & LIGHT_SPR_ON &&
!(LightSprites[ i ].uiFlags & MERC_LIGHT) )
{
LightSpritePower( i, FALSE );
}
}
}
void UpdateTemperature( UINT8 ubTemperatureCode )
{
switch( ubTemperatureCode )
{
case TEMPERATURE_DESERT_COOL:
gubDesertTemperature = 0;
break;
case TEMPERATURE_DESERT_WARM:
gubDesertTemperature = 1;
break;
case TEMPERATURE_DESERT_HOT:
gubDesertTemperature = 2;
break;
case TEMPERATURE_GLOBAL_COOL:
gubGlobalTemperature = 0;
break;
case TEMPERATURE_GLOBAL_WARM:
gubGlobalTemperature = 1;
break;
case TEMPERATURE_GLOBAL_HOT:
gubGlobalTemperature = 2;
break;
}
gfDoLighting = TRUE;
}
INT8 SectorTemperature( UINT32 uiTime, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
if (bSectorZ > 0)
{
// cool underground
return( 0 );
}
else if ( IsSectorDesert( sSectorX, sSectorY ) ) // is desert
{
return( gubDesertTemperature );
}
else
{
return( gubGlobalTemperature );
}
}
+84
View File
@@ -0,0 +1,84 @@
#ifndef _ENVIRONMENT_H_
#define _ENVIRONMENT_H_
#define ENV_TIME_00 0
#define ENV_TIME_01 1
#define ENV_TIME_02 2
#define ENV_TIME_03 3
#define ENV_TIME_04 4
#define ENV_TIME_05 5
#define ENV_TIME_06 6
#define ENV_TIME_07 7
#define ENV_TIME_08 8
#define ENV_TIME_09 9
#define ENV_TIME_10 10
#define ENV_TIME_11 11
#define ENV_TIME_12 12
#define ENV_TIME_13 13
#define ENV_TIME_14 14
#define ENV_TIME_15 15
#define ENV_TIME_16 16
#define ENV_TIME_17 17
#define ENV_TIME_18 18
#define ENV_TIME_19 19
#define ENV_TIME_20 20
#define ENV_TIME_21 21
#define ENV_TIME_22 22
#define ENV_TIME_23 23
#define ENV_NUM_TIMES 24
//Make sure you use 24 for end time hours and 0 for start time hours if
//midnight is the hour you wish to use.
#define NIGHT_TIME_LIGHT_START_HOUR 21
#define NIGHT_TIME_LIGHT_END_HOUR 7
#define PRIME_TIME_LIGHT_START_HOUR 21
#define PRIME_TIME_LIGHT_END_HOUR 24
#define WEATHER_FORECAST_SUNNY 0x00000001
#define WEATHER_FORECAST_OVERCAST 0x00000002
#define WEATHER_FORECAST_PARTLYSUNNY 0x00000004
#define WEATHER_FORECAST_DRIZZLE 0x00000008
#define WEATHER_FORECAST_SHOWERS 0x00000010
#define WEATHER_FORECAST_THUNDERSHOWERS 0x00000020
// higher is darker, remember
#define NORMAL_LIGHTLEVEL_NIGHT 12
#define NORMAL_LIGHTLEVEL_DAY 3
void ForecastDayEvents( );
void EnvironmentController( BOOLEAN fCheckForLights );
void EnvEnableTOD(void);
void EnvDisableTOD(void);
void BuildDayAmbientSounds( );
void BuildDayLightLevels();
UINT8 GetTimeOfDayAmbientLightLevel();
void EnvBeginRainStorm( UINT8 ubIntensity );
void EnvEndRainStorm( );
extern UINT8 gubEnvLightValue;
extern BOOLEAN gfDoLighting;
extern UINT32 guiEnvWeather;
void TurnOnNightLights();
void TurnOffNightLights();
void TurnOnPrimeLights();
void TurnOffPrimeLights();
//effects whether or not time of day effects the lighting. Underground
//maps have an ambient light level that is saved in the map, and doesn't change.
extern BOOLEAN gfCaves;
extern BOOLEAN gfBasement;
extern INT8 SectorTemperature( UINT32 uiTime, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
extern void UpdateTemperature( UINT8 ubTemperatureCode );
#endif
File diff suppressed because it is too large Load Diff
+206
View File
@@ -0,0 +1,206 @@
#ifndef _LIGHTING_H_
#define _LIGHTING_H_
#include "Soldier Control.h"
/****************************************************************************************
* JA2 Lighting Module
*
* Tile-based, ray-casted lighting system.
*
* Lights are precalculated into linked lists containing offsets from 0,0, and a light
* level to add at that tile. Lists are constructed by casting a ray from the origin of
* the light, and each tile stopped at is stored as a node in the list. To draw the light
* during runtime, you traverse the list, checking at each tile that it isn't of the type
* that can obscure light. If it is, you keep traversing the list until you hit a node
* with a marker LIGHT_NEW_RAY, which means you're back at the origin, and have skipped
* the remainder of the last ray.
*
* Written by Derek Beland, April 14, 1997
*
***************************************************************************************/
#define DISTANCE_SCALE 4
#define LIGHT_DUSK_CUTOFF 8
#define LIGHT_DECAY 0.9 // shade level decay per tile distance
// lightlist node flags
#define LIGHT_NODE_DRAWN 0x00000001 // light node duplicate marker
#define LIGHT_ROOF_ONLY 0x00001000 // light only rooftops
#define LIGHT_IGNORE_WALLS 0x00002000 // doesn't take walls into account
#define LIGHT_BACKLIGHT 0x00004000 // light does not light objs, trees
#define LIGHT_NEW_RAY 0x00008000 // start of new ray in linked list
#define LIGHT_EVERYTHING 0x00010000 // light up everything
#define LIGHT_FAKE 0x10000000 // "fake" light for display only
// standard light file symbols
#define LIGHT_OMNI_R1 "LTO1.LHT"
#define LIGHT_OMNI_R2 "LTO2.LHT"
#define LIGHT_OMNI_R3 "LTO3.LHT"
#define LIGHT_OMNI_R4 "LTO4.LHT"
#define LIGHT_OMNI_R5 "LTO5.LHT"
#define LIGHT_OMNI_R6 "LTO6.LHT"
#define LIGHT_OMNI_R7 "LTO7.LHT"
#define LIGHT_OMNI_R8 "LTO8.LHT"
#define MAX_LIGHT_TEMPLATES 32 // maximum number of light types
#define MAX_LIGHT_SPRITES 256 // maximum number of light types
#define SHADE_MIN 15 // DARKEST shade value
#define SHADE_MAX 1 // LIGHTEST shade value
// light sprite flags
#define LIGHT_SPR_ACTIVE 0x0001
#define LIGHT_SPR_ON 0x0002
#define LIGHT_SPR_ANIMATE 0x0004
#define LIGHT_SPR_ERASE 0x0008
#define LIGHT_SPR_REDRAW 0x0010
#define LIGHT_SPR_ONROOF 0x0020
#define MERC_LIGHT 0x0040
#define LIGHT_PRIMETIME 0x0080 // light turns goes on in evening, turns off at bedtime.
#define LIGHT_NIGHTTIME 0x0100 // light stays on when dark outside
#define COLOR_RED 162
#define COLOR_BLUE 203
#define COLOR_YELLOW 144
#define COLOR_GREEN 184
#define COLOR_LTGREY 134
#define COLOR_DKGREY 136
#define COLOR_BROWN 80
#define COLOR_PURPLE 160
#define COLOR_ORANGE 76
#define COLOR_WHITE 208
#define COLOR_BLACK 72
// stucture of node in linked list for lights
typedef struct light_p {
INT16 iDX, iDY;
UINT8 uiFlags;
UINT8 ubLight;
} LIGHT_NODE;
// structure of light instance, or sprite (a copy of the template)
typedef struct {
INT16 iX, iY;
INT16 iOldX, iOldY;
INT16 iAnimSpeed;
INT32 iTemplate;
UINT32 uiFlags;
UINT32 uiLightType;
} LIGHT_SPRITE;
// Initializes the lighting system
BOOLEAN InitLightingSystem(void);
// Shuts down, and frees up all lights/memory
BOOLEAN ShutdownLightingSystem(void);
// Resets all light sprites and deallocates templates
BOOLEAN LightReset(void);
// THIS MUST BE CALLED ONCE ALL SURFACE VIDEO OBJECTS HAVE BEEN LOADED!
BOOLEAN SetDefaultWorldLightingColors(void);
// Low-Level Template Interface
// Sets the normal light level for all tiles in the world
BOOLEAN LightSetBaseLevel(UINT8 iIntensity);
// Adds a light value to all tiles
BOOLEAN LightAddBaseLevel(UINT32 uiLightType, UINT8 iIntensity);
// Subtracts a light value from all tiles
BOOLEAN LightSubtractBaseLevel(UINT32 uiLightType, UINT8 iIntensity);
// Creates an omni (circular) light
INT32 LightCreateOmni( UINT8 ubIntensity, INT16 iRadius);
// Creates an oval-shaped light (two separate radii)
INT32 LightCreateElliptical(UINT8 ubIntensity, INT16 iRadius1, INT16 iRadius2);
// Creates a square light
INT32 LightCreateSquare(UINT8 ubIntensity, INT16 iRadius1, INT16 iRadius2);
// Draws a light into the scene at X,Y
BOOLEAN LightDraw(UINT32 uiLightType, INT32 iLight, INT16 iX, INT16 iY, UINT32 uiSprite);
// Reverts the tiles a light has affected back to normal
BOOLEAN LightErase(UINT32 uiLightType, INT32 iLight, INT16 iX, INT16 iY, UINT32 uiSprite);
// Save a light list into a file
BOOLEAN LightSave(INT32 uiLight, STR pFilename);
// Load a light list from a file
INT32 LightLoad(STR pFilename);
// Sets the RGB values and number of light colors (1/2)
BOOLEAN LightSetColors(SGPPaletteEntry *pPal, UINT8 ubNumColors);
// Returns the number of colors active (1/2) and the palette colors
UINT8 LightGetColors(SGPPaletteEntry *pPal);
// High-Level Sprite Interface
// Creates a new light sprite from a given filename/predefined symbol
INT32 LightSpriteCreate(STR pName, UINT32 uiLightType);
// Destroys the instance of that light
BOOLEAN LightSpriteDestroy(INT32 iSprite);
// Sets the tile position of the light instance
BOOLEAN LightSpritePosition(INT32 iSprite, INT16 iX, INT16 iY);
// Makes a light "fake"
BOOLEAN LightSpriteFake(INT32 iSprite);
// Updates any change in position in lights
BOOLEAN LightSpriteRender();
// Renders all lights
BOOLEAN LightSpriteRenderAll(void);
// Turns on/off power to a light
BOOLEAN LightSpritePower(INT32 iSprite, BOOLEAN fOn);
// Moves light to/from roof position
BOOLEAN LightSpriteRoofStatus(INT32 iSprite, BOOLEAN fOnRoof);
// Reveals translucent walls
BOOLEAN CalcTranslucentWalls(INT16 iX, INT16 iY);
BOOLEAN ApplyTranslucencyToWalls(INT16 iX, INT16 iY);
// Makes trees translucent
BOOLEAN LightTranslucentTrees(INT16 iX, INT16 iY);
BOOLEAN LightHideTrees(INT16 iX, INT16 iY);
BOOLEAN LightShowRays(INT16 iX, INT16 iY, BOOLEAN fReset);
BOOLEAN LightHideRays(INT16 iX, INT16 iY);
// makes the 16-bit palettes
UINT16 CreateTilePaletteTables(HVOBJECT pObj, UINT32 uiType, BOOLEAN fForce );
BOOLEAN CreateSoldierShadedPalette( SOLDIERTYPE *pSoldier, UINT32 uiBase, SGPPaletteEntry *pShadePal);
UINT16 CreateSoldierPaletteTables(SOLDIERTYPE *pSoldier, UINT32 uiType);
// returns the true light value at a tile (ignoring fake/merc lights)
UINT8 LightTrueLevel( INT16 sGridNo, INT8 bLevel );
// system variables
extern LIGHT_NODE *pLightList[MAX_LIGHT_TEMPLATES];
extern UINT16 usTemplateSize[MAX_LIGHT_TEMPLATES];
extern UINT16 *pLightRayList[MAX_LIGHT_TEMPLATES];
extern UINT16 usRaySize[MAX_LIGHT_TEMPLATES];
extern INT16 LightHeight[MAX_LIGHT_TEMPLATES];
extern INT16 LightWidth[MAX_LIGHT_TEMPLATES];
extern INT16 LightXOffset[MAX_LIGHT_TEMPLATES];
extern INT16 LightYOffset[MAX_LIGHT_TEMPLATES];
extern INT16 LightMapLeft[MAX_LIGHT_TEMPLATES];
extern INT16 LightMapTop[MAX_LIGHT_TEMPLATES];
extern INT16 LightMapRight[MAX_LIGHT_TEMPLATES];
extern INT16 LightMapBottom[MAX_LIGHT_TEMPLATES];
extern STR pLightNames[MAX_LIGHT_TEMPLATES];
// Sprite data
extern LIGHT_SPRITE LightSprites[MAX_LIGHT_SPRITES];
// Lighting system general data
extern UINT8 ubAmbientLightLevel;
extern UINT8 gubNumLightColors;
// Lighting colors
extern UINT8 gubNumLightColors;
extern SGPPaletteEntry gpLightColors[3];
// macros
#define LightSpriteGetType(x) (LightSprites[x].uiLightType)
#define LightSpriteGetTypeName(x) (pLightNames[LightSprites[x].iTemplate])
#define LightGetAmbient() (ubAmbientLightLevel)
#endif
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
#ifndef __OVERHEADMAP_H
#define __OVERHEADMAP_H
void InitNewOverheadDB( UINT8 ubTilesetID );
void RenderOverheadMap( INT16 sStartPointX_M, INT16 sStartPointY_M, INT16 sStartPointX_S, INT16 sStartPointY_S, INT16 sEndXS, INT16 sEndYS, BOOLEAN fFromMapUtility );
void HandleOverheadMap( );
BOOLEAN InOverheadMap( );
void GoIntoOverheadMap( );
void HandleOverheadUI( );
void KillOverheadMap();
void ClickOverheadRegionCallback( MOUSE_REGION *reg, INT32 reason );
void MoveInOverheadRegionCallback( MOUSE_REGION *reg, INT32 reason );
void CalculateRestrictedMapCoords( INT8 bDirection, INT16 *psX1, INT16 *psY1, INT16 *psX2, INT16 *psY2, INT16 sEndXS, INT16 sEndYS );
void CalculateRestrictedScaleFactors( INT16 *pScaleX, INT16 *pScaleY );
void TrashOverheadMap( );
#endif
+145
View File
@@ -0,0 +1,145 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "phys math.h"
#include <memory.h>
#endif
vector_3 VSetEqual( vector_3 *a )
{
vector_3 c;
// c.x = a->x;
// c.y = a->y;
// c.z = a->z;
memcpy( &c, a, sizeof( vector_3 ) );
return( c );
}
vector_3 VSubtract( vector_3 *a, vector_3 *b )
{
vector_3 c;
c.x = a->x - b->x;
c.y = a->y - b->y;
c.z = a->z - b->z;
return( c );
}
vector_3 VAdd( vector_3 *a, vector_3 *b )
{
vector_3 c;
c.x = a->x + b->x;
c.y = a->y + b->y;
c.z = a->z + b->z;
return( c );
}
vector_3 VMultScalar( vector_3 *a, real b )
{
vector_3 c;
c.x = a->x * b;
c.y = a->y * b;
c.z = a->z * b;
return( c );
}
vector_3 VDivScalar( vector_3 *a, real b )
{
vector_3 c;
c.x = a->x / b;
c.y = a->y / b;
c.z = a->z / b;
return( c );
}
real VDotProduct( vector_3 *a, vector_3 *b )
{
return ( ( a->x * b->x ) + ( a->y * b->y ) + ( a->z * b->z ) );
}
real VPerpDotProduct( vector_3 *a, vector_3 *b )
{
return ( ( a->x * b->x ) - ( a->y * b->y ) - ( a->z * b->z ) );
}
vector_3 VCrossProduct( vector_3 *a, vector_3 *b )
{
vector_3 c;
c.x = ( a->y * b->z ) - ( a->z * b->y );
c.y = ( a->x * b->z ) - ( a->z * b->x );
c.z = ( a->x * b->y ) - ( a->y * b->x );
return( c );
}
vector_3 VGetPerpendicular( vector_3 *a )
{
vector_3 c;
c.x = -a->y;
c.y = a->x;
c.z = a->z;
return( c );
}
real VGetLength( vector_3 *a )
{
return( (real) sqrt( ( a->x * a->x ) + ( a->y * a->y ) + ( a->z * a->z ) ) );
}
vector_3 VGetNormal( vector_3 *a )
{
vector_3 c;
real OneOverLength, Length;
Length = VGetLength( a );
if ( Length == 0 )
{
c.x = 0;
c.y = 0;
c.z = 0;
}
else
{
OneOverLength = 1/Length;
c.x = OneOverLength * a->x;
c.y = OneOverLength * a->y;
c.z = OneOverLength * a->z;
}
return ( c );
}
+63
View File
@@ -0,0 +1,63 @@
#ifndef __PHYS_MATH_H
#define __PHYS_MATH_H
// explicit dependencies
#include <math.h> // for sqrt
#include <float.h>
typedef float real;
#define REAL_MAX FLT_MAX
#define REAL_MIN FLT_MIN
#define PI2 3.14159265358979323846
#define Epsilon2 0.00001
typedef struct
{
real x, y, z;
} vector_3;
typedef struct
{
real aElements[3][3];
} matrix_3x3;
// DEFINES
#define RADIANS_FROM( d ) ( ( d * PI2 ) / 180 )
#define DEGREES_FROM( r ) ( ( r * 180 ) / PI2 )
#ifdef __cplusplus
extern "C" {
#endif
vector_3 VSetEqual( vector_3 *a );
vector_3 VSubtract( vector_3 *a, vector_3 *b );
vector_3 VAdd( vector_3 *a, vector_3 *b );
vector_3 VMultScalar( vector_3 *a, real b );
vector_3 VDivScalar( vector_3 *a, real b );
real VDotProduct( vector_3 *a, vector_3 *b );
real VPerpDotProduct( vector_3 *a, vector_3 *b );
vector_3 VGetPerpendicular( vector_3 *a );
real VGetLength( vector_3 *a );
vector_3 VGetNormal( vector_3 *a );
vector_3 VCrossProduct( vector_3 *a, vector_3 *b );
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
+106
View File
@@ -0,0 +1,106 @@
#ifndef __PHYSICS_H
#define __PHYSICS_H
#include "phys math.h"
#include "sgp.h"
#include "worlddef.h"
#include "items.h"
#include "Soldier Control.h"
extern UINT32 guiNumObjectSlots;
typedef struct
{
BOOLEAN fAllocated;
BOOLEAN fAlive;
BOOLEAN fApplyFriction;
BOOLEAN fColliding;
BOOLEAN fZOnRest;
BOOLEAN fVisible;
BOOLEAN fInWater;
BOOLEAN fTestObject;
BOOLEAN fTestEndedWithCollision;
BOOLEAN fTestPositionNotSet;
real TestZTarget;
real OneOverMass;
real AppliedMu;
vector_3 Position;
vector_3 TestTargetPosition;
vector_3 OldPosition;
vector_3 Velocity;
vector_3 OldVelocity;
vector_3 InitialForce;
vector_3 Force;
vector_3 CollisionNormal;
vector_3 CollisionVelocity;
real CollisionElasticity;
INT16 sGridNo;
INT32 iID;
LEVELNODE *pNode;
LEVELNODE *pShadow;
INT16 sConsecutiveCollisions;
INT16 sConsecutiveZeroVelocityCollisions;
INT32 iOldCollisionCode;
FLOAT dLifeLength;
FLOAT dLifeSpan;
OBJECTTYPE Obj;
BOOLEAN fFirstTimeMoved;
INT16 sFirstGridNo;
UINT8 ubOwner;
UINT8 ubActionCode;
UINT32 uiActionData;
BOOLEAN fDropItem;
UINT32 uiNumTilesMoved;
BOOLEAN fCatchGood;
BOOLEAN fAttemptedCatch;
BOOLEAN fCatchAnimOn;
BOOLEAN fCatchCheckDone;
BOOLEAN fEndedWithCollisionPositionSet;
vector_3 EndedWithCollisionPosition;
BOOLEAN fHaveHitGround;
BOOLEAN fPotentialForDebug;
INT16 sLevelNodeGridNo;
INT32 iSoundID;
UINT8 ubLastTargetTakenDamage;
UINT8 ubPadding[1];
} REAL_OBJECT;
#define NUM_OBJECT_SLOTS 50
extern REAL_OBJECT ObjectSlots[ NUM_OBJECT_SLOTS ];
// OBJECT LIST STUFF
INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, real yPos, real zPos, real xForce, real yForce, real zForce, UINT8 ubOwner, UINT8 ubActionCode, UINT32 uiActionData );
BOOLEAN RemoveObjectSlot( INT32 iObject );
void RemoveAllPhysicsObjects( );
FLOAT CalculateLaunchItemAngle( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubHeight, real dForce, OBJECTTYPE *pItem, INT16 *psGridNo );
BOOLEAN CalculateLaunchItemChanceToGetThrough( SOLDIERTYPE *pSoldier, OBJECTTYPE *pItem, INT16 sGridNo, UINT8 ubLevel, INT16 sEndZ, INT16 *psFinalGridNo, BOOLEAN fArmed, INT8 *pbLevel, BOOLEAN fFromUI );
void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubLevel, INT16 sZPos, OBJECTTYPE *pItem, INT8 bMissBy, UINT8 ubActionCode, UINT32 uiActionData );
// SIMULATE WORLD
void SimulateWorld( );
BOOLEAN SavePhysicsTableToSaveGameFile( HWFILE hFile );
BOOLEAN LoadPhysicsTableFromSavedGameFile( HWFILE hFile );
#endif
+265
View File
@@ -0,0 +1,265 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "types.h"
#include "pits.h"
#include "worlddef.h"
#include "worldman.h"
#include "Simple Render Utils.h"
#include "World Items.h"
#include "SaveLoadMap.h"
#include "Exit Grids.h"
#include "Sys Globals.h"
#include "strategicmap.h"
#include "Isometric Utils.h"
#include "overhead.h"
#include "Sound Control.h"
#include "animation control.h"
#include "strategic.h"
#include "Action Items.h"
#endif
//used by editor
BOOLEAN gfShowPits = FALSE;
BOOLEAN gfLoadPitsWithoutArming = FALSE;
void Add3X3Pit( INT32 iMapIndex )
{
EXITGRID ExitGrid;
if( !gfEditMode )
ApplyMapChangesToMapTempFile( TRUE );
AddObjectToTail( iMapIndex + 159, REGWATERTEXTURE1 );
AddObjectToTail( iMapIndex - 1, REGWATERTEXTURE2 );
AddObjectToTail( iMapIndex - 161, REGWATERTEXTURE3 );
AddObjectToTail( iMapIndex + 160, REGWATERTEXTURE4 );
AddObjectToTail( iMapIndex, REGWATERTEXTURE5 );
AddObjectToTail( iMapIndex - 160, REGWATERTEXTURE6 );
AddObjectToTail( iMapIndex + 161, REGWATERTEXTURE7 );
AddObjectToTail( iMapIndex + 1, REGWATERTEXTURE8 );
AddObjectToTail( iMapIndex - 159, REGWATERTEXTURE9 );
if( !gfEditMode )
{ //Add the exitgrids associated with the pit.
ExitGrid.ubGotoSectorX = (UINT8)gWorldSectorX;
ExitGrid.ubGotoSectorY = (UINT8)gWorldSectorY;
ExitGrid.ubGotoSectorZ = (UINT8)(gbWorldSectorZ+1);
ExitGrid.usGridNo = (UINT16)iMapIndex;
AddExitGridToWorld( iMapIndex + 159, &ExitGrid );
AddExitGridToWorld( iMapIndex - 1, &ExitGrid );
AddExitGridToWorld( iMapIndex - 161, &ExitGrid );
AddExitGridToWorld( iMapIndex + 160, &ExitGrid );
AddExitGridToWorld( iMapIndex, &ExitGrid );
AddExitGridToWorld( iMapIndex - 160, &ExitGrid );
AddExitGridToWorld( iMapIndex + 161, &ExitGrid );
AddExitGridToWorld( iMapIndex + 1, &ExitGrid );
AddExitGridToWorld( iMapIndex - 159, &ExitGrid );
RecompileLocalMovementCostsFromRadius( (INT16)iMapIndex, 2 );
}
MarkWorldDirty();
if( !gfEditMode )
ApplyMapChangesToMapTempFile( FALSE );
}
void Add5X5Pit( INT32 iMapIndex )
{
EXITGRID ExitGrid;
if( !gfEditMode )
ApplyMapChangesToMapTempFile( TRUE );
AddObjectToTail( iMapIndex + 318, REGWATERTEXTURE10 );
AddObjectToTail( iMapIndex + 158, REGWATERTEXTURE11 );
AddObjectToTail( iMapIndex - 2, REGWATERTEXTURE12 );
AddObjectToTail( iMapIndex - 162, REGWATERTEXTURE13 );
AddObjectToTail( iMapIndex - 322, REGWATERTEXTURE14 );
AddObjectToTail( iMapIndex + 319, REGWATERTEXTURE15 );
AddObjectToTail( iMapIndex + 159, REGWATERTEXTURE16 );
AddObjectToTail( iMapIndex - 1, REGWATERTEXTURE17 );
AddObjectToTail( iMapIndex - 161, REGWATERTEXTURE18 );
AddObjectToTail( iMapIndex - 321, REGWATERTEXTURE19 );
AddObjectToTail( iMapIndex + 320, REGWATERTEXTURE20 );
AddObjectToTail( iMapIndex + 160, REGWATERTEXTURE21 );
AddObjectToTail( iMapIndex, REGWATERTEXTURE22 );
AddObjectToTail( iMapIndex - 160, REGWATERTEXTURE23 );
AddObjectToTail( iMapIndex - 320, REGWATERTEXTURE24 );
AddObjectToTail( iMapIndex + 321, REGWATERTEXTURE25 );
AddObjectToTail( iMapIndex + 161, REGWATERTEXTURE26 );
AddObjectToTail( iMapIndex + 1, REGWATERTEXTURE27 );
AddObjectToTail( iMapIndex - 159, REGWATERTEXTURE28 );
AddObjectToTail( iMapIndex - 319, REGWATERTEXTURE29 );
AddObjectToTail( iMapIndex + 322, REGWATERTEXTURE30 );
AddObjectToTail( iMapIndex + 162, REGWATERTEXTURE31 );
AddObjectToTail( iMapIndex + 2, REGWATERTEXTURE32 );
AddObjectToTail( iMapIndex - 158, REGWATERTEXTURE33 );
AddObjectToTail( iMapIndex - 318, REGWATERTEXTURE34 );
if( !gfEditMode )
{ //Add the exitgrids associated with the pit.
ExitGrid.ubGotoSectorX = (UINT8)gWorldSectorX;
ExitGrid.ubGotoSectorY = (UINT8)gWorldSectorY;
ExitGrid.ubGotoSectorZ = (UINT8)(gbWorldSectorZ+1);
ExitGrid.usGridNo = (UINT16)iMapIndex;
AddExitGridToWorld( iMapIndex + 318, &ExitGrid );
AddExitGridToWorld( iMapIndex + 158, &ExitGrid );
AddExitGridToWorld( iMapIndex - 2, &ExitGrid );
AddExitGridToWorld( iMapIndex - 162, &ExitGrid );
AddExitGridToWorld( iMapIndex - 322, &ExitGrid );
AddExitGridToWorld( iMapIndex + 319, &ExitGrid );
AddExitGridToWorld( iMapIndex + 159, &ExitGrid );
AddExitGridToWorld( iMapIndex - 1, &ExitGrid );
AddExitGridToWorld( iMapIndex - 161, &ExitGrid );
AddExitGridToWorld( iMapIndex - 321, &ExitGrid );
AddExitGridToWorld( iMapIndex + 320, &ExitGrid );
AddExitGridToWorld( iMapIndex + 160, &ExitGrid );
AddExitGridToWorld( iMapIndex, &ExitGrid );
AddExitGridToWorld( iMapIndex - 160, &ExitGrid );
AddExitGridToWorld( iMapIndex - 320, &ExitGrid );
AddExitGridToWorld( iMapIndex + 321, &ExitGrid );
AddExitGridToWorld( iMapIndex + 161, &ExitGrid );
AddExitGridToWorld( iMapIndex + 1, &ExitGrid );
AddExitGridToWorld( iMapIndex - 159, &ExitGrid );
AddExitGridToWorld( iMapIndex - 319, &ExitGrid );
AddExitGridToWorld( iMapIndex + 322, &ExitGrid );
AddExitGridToWorld( iMapIndex + 162, &ExitGrid );
AddExitGridToWorld( iMapIndex + 2, &ExitGrid );
AddExitGridToWorld( iMapIndex - 158, &ExitGrid );
AddExitGridToWorld( iMapIndex - 318, &ExitGrid );
RecompileLocalMovementCostsFromRadius( (INT16)iMapIndex, 3 );
}
MarkWorldDirty();
if( !gfEditMode )
ApplyMapChangesToMapTempFile( FALSE );
}
void Remove3X3Pit( INT32 iMapIndex )
{
RemoveAllObjectsOfTypeRange( iMapIndex + 159, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 1, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 161, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 160, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 160, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 161, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 1, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 159, REGWATERTEXTURE, REGWATERTEXTURE );
MarkWorldDirty();
}
void Remove5X5Pit( INT32 iMapIndex )
{
RemoveAllObjectsOfTypeRange( iMapIndex + 318, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 158, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 2, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 162, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 322, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 319, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 159, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 1, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 161, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 321, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 320, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 160, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 160, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 320, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 321, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 161, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 1, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 159, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 319, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 322, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 162, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex + 2, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 158, REGWATERTEXTURE, REGWATERTEXTURE );
RemoveAllObjectsOfTypeRange( iMapIndex - 318, REGWATERTEXTURE, REGWATERTEXTURE );
MarkWorldDirty();
}
void AddAllPits()
{
UINT32 i;
for( i = 0; i < guiNumWorldItems; i++ )
{
if( gWorldItems[ i ].o.usItem == ACTION_ITEM )
{
if( gWorldItems[ i ].o.bActionValue == ACTION_ITEM_SMALL_PIT )
Add3X3Pit( gWorldItems[ i ].sGridNo );
else if( gWorldItems[ i ].o.bActionValue == ACTION_ITEM_LARGE_PIT )
Add5X5Pit( gWorldItems[ i ].sGridNo );
}
}
}
void RemoveAllPits()
{
UINT32 i;
for( i = 0; i < guiNumWorldItems; i++ )
{
if( gWorldItems[ i ].o.usItem == ACTION_ITEM )
{
if( gWorldItems[ i ].o.bActionValue == ACTION_ITEM_SMALL_PIT )
Remove3X3Pit( gWorldItems[ i ].sGridNo );
else if( gWorldItems[ i ].o.bActionValue == ACTION_ITEM_LARGE_PIT )
Remove5X5Pit( gWorldItems[ i ].sGridNo );
}
}
}
void SearchForOtherMembersWithinPitRadiusAndMakeThemFall( INT16 sGridNo, INT16 sRadius )
{
INT16 x, y, sNewGridNo;
UINT8 ubID;
SOLDIERTYPE *pSoldier;
PlayJA2Sample( CAVE_COLLAPSE, RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) );
for( y = -sRadius; y <= sRadius; y++ ) for( x = -sRadius; x <= sRadius; x++ )
{
sNewGridNo = sGridNo + y * WORLD_COLS + x;
//Validate gridno location, and check if there are any mercs here. If there are
//any mercs, we want them to fall below. The exitgrid already exists at this location
if( GridNoOnVisibleWorldTile( sNewGridNo ) )
{
// Check if buddy exists here.....
ubID = WhoIsThere2( sNewGridNo, 0 );
if ( ubID != NOBODY )
{
// OK, make guy fall...
// Set data to look for exit grid....
pSoldier = MercPtrs[ ubID ];
pSoldier->uiPendingActionData4 = sNewGridNo;
EVENT_InitNewSoldierAnim( pSoldier, FALL_INTO_PIT, 0 , FALSE );
}
}
}
}
void HandleFallIntoPitFromAnimation( UINT8 ubID )
{
SOLDIERTYPE *pSoldier = MercPtrs[ ubID ];
EXITGRID ExitGrid;
INT16 sPitGridNo;
// OK, get exit grid...
sPitGridNo = (INT16)pSoldier->uiPendingActionData4;
GetExitGrid( sPitGridNo, &ExitGrid );
// Given exit grid, make buddy move to next sector....
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = ExitGrid.usGridNo;
pSoldier->sSectorX = ExitGrid.ubGotoSectorX;
pSoldier->sSectorY = ExitGrid.ubGotoSectorY;
pSoldier->bSectorZ = ExitGrid.ubGotoSectorZ;
// Remove from world......
RemoveSoldierFromTacticalSector( pSoldier, TRUE );
HandleSoldierLeavingSectorByThemSelf( pSoldier );
SetSoldierHeight( pSoldier, 0 );
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef __PITS_H
#define __PITS_H
void Add3X3Pit( INT32 iMapIndex );
void Add5X5Pit( INT32 iMapIndex );
void Remove3X3Pit( INT32 iMapIndex );
void Remove5X5Pit( INT32 iMapIndex );
void SearchForOtherMembersWithinPitRadiusAndMakeThemFall( INT16 sGridNo, INT16 sRadius );
void AddAllPits();
void RemoveAllPits();
extern BOOLEAN gfShowPits;
extern BOOLEAN gfLoadPitsWithoutArming;
void HandleFallIntoPitFromAnimation( UINT8 ubID );
#endif
File diff suppressed because it is too large Load Diff
+220
View File
@@ -0,0 +1,220 @@
#ifndef __RENDERWORLD_H
#define __RENDERWORLD_H
#include "worlddef.h"
// TEMP SELECT STUFF
#define NO_SELECT 0
#define FULL_SELECT 1
#define SELECT_WIDTH 2
#define SELECT_HEIGHT 3
extern BOOLEAN gfDoVideoScroll;
extern BOOLEAN gfDoSubtileScroll;
extern UINT8 gubCurScrollSpeedID;
// RENDERING FLAGS
#define RENDER_FLAG_FULL 0x00000001
#define RENDER_FLAG_SHADOWS 0x00000002
#define RENDER_FLAG_MARKED 0x00000004
#define RENDER_FLAG_SAVEOFF 0x00000008
#define RENDER_FLAG_NOZ 0x00000010
#define RENDER_FLAG_ROOMIDS 0x00000020
#define RENDER_FLAG_CHECKZ 0x00000040
#define RENDER_FLAG_ONLYLAND 0x00000080
#define RENDER_FLAG_ONLYSTRUCT 0x00000100
#define RENDER_FLAG_FOVDEBUG 0x00000200
#define SCROLL_UP 0x00000001
#define SCROLL_DOWN 0x00000002
#define SCROLL_RIGHT 0x00000004
#define SCROLL_LEFT 0x00000008
#define SCROLL_UPLEFT 0x00000020
#define SCROLL_UPRIGHT 0x00000040
#define SCROLL_DOWNLEFT 0x00000080
#define SCROLL_DOWNRIGHT 0x00000200
#define Z_SUBLAYERS 8
#define LAND_Z_LEVEL 0
#define OBJECT_Z_LEVEL 1
#define SHADOW_Z_LEVEL 2
#define MERC_Z_LEVEL 3
#define STRUCT_Z_LEVEL 4
#define ROOF_Z_LEVEL 5
#define ONROOF_Z_LEVEL 6
#define FOG_Z_LEVEL 7
#define TOPMOST_Z_LEVEL 32767
// highest bit value is rendered first!
#define TILES_STATIC_LAND 0x00040000
#define TILES_STATIC_OBJECTS 0x00020000
#define TILES_STATIC_SHADOWS 0x00008000
#define TILES_STATIC_STRUCTURES 0x00004000
#define TILES_STATIC_ROOF 0x00002000
#define TILES_STATIC_ONROOF 0x00001000
#define TILES_STATIC_TOPMOST 0x00000800
// highest bit value is rendered first!
#define TILES_ALL_DYNAMICS 0x00000fff
#define TILES_DYNAMIC_CHECKFOR_INT_TILE 0x00000400
#define TILES_DYNAMIC_LAND 0x00000200
#define TILES_DYNAMIC_OBJECTS 0x00000100
#define TILES_DYNAMIC_SHADOWS 0x00000080
#define TILES_DYNAMIC_STRUCT_MERCS 0x00000040
#define TILES_DYNAMIC_MERCS 0x00000020
#define TILES_DYNAMIC_STRUCTURES 0x00000010
#define TILES_DYNAMIC_ROOF 0x00000008
#define TILES_DYNAMIC_HIGHMERCS 0x00000004
#define TILES_DYNAMIC_ONROOF 0x00000002
#define TILES_DYNAMIC_TOPMOST 0x00000001
extern BOOLEAN gfRenderScroll;
extern INT16 gsScrollXIncrement;
extern INT16 gsScrollYIncrement;
extern INT32 guiScrollDirection;
extern BOOLEAN gfScrollStart;
extern INT16 gsRenderHeight;
// Distance around mercs to pixelate walls
#define REVEAL_WALLS_RADIUS 3
// GLOBAL VARIABLES
extern INT16 SCROLL_X_STEP;
extern INT16 SCROLL_Y_STEP;
extern INT16 gsVIEWPORT_START_X;
extern INT16 gsVIEWPORT_START_Y;
extern INT16 gsVIEWPORT_WINDOW_START_Y;
extern INT16 gsVIEWPORT_END_Y;
extern INT16 gsVIEWPORT_WINDOW_END_Y;
extern INT16 gsVIEWPORT_END_X;
extern INT16 gsRenderCenterX;
extern INT16 gsRenderCenterY;
extern INT16 gsRenderWorldOffsetX;
extern INT16 gsRenderWorldOffsetY;
// CURRENT VIEWPORT IN WORLD COORDS
extern INT16 gsTopLeftWorldX;
extern INT16 gsTopLeftWorldY;
extern INT16 gsTopRightWorldX;
extern INT16 gsTopRightWorldY;
extern INT16 gsBottomLeftWorldX;
extern INT16 gsBottomLeftWorldY;
extern INT16 gsBottomRightWorldX;
extern INT16 gsBottomRightWorldY;
extern SGPRect gSelectRegion;
extern SGPPoint gSelectAnchor;
extern UINT32 fSelectMode;
// GLOBAL COORDINATES
extern INT16 gTopLeftWorldLimitX;
extern INT16 gTopLeftWorldLimitY;
extern INT16 gTopRightWorldLimitX;
extern INT16 gTopRightWorldLimitY;
extern INT16 gBottomLeftWorldLimitX;
extern INT16 gBottomLeftWorldLimitY;
extern INT16 gBottomRightWorldLimitX;
extern INT16 gBottomRightWorldLimitY;
extern INT16 gCenterWorldX;
extern INT16 gCenterWorldY;
extern INT16 gsTLX;
extern INT16 gsTLY;
extern INT16 gsTRX;
extern INT16 gsTRY;
extern INT16 gsBLX;
extern INT16 gsBLY;
extern INT16 gsBRX;
extern INT16 gsBRY;
extern INT16 gsCX;
extern INT16 gsCY;
extern DOUBLE gdScaleX;
extern DOUBLE gdScaleY;
extern BOOLEAN fLandLayerDirty;
extern BOOLEAN gfIgnoreScrollDueToCenterAdjust;
// FUNCTIONS
void ScrollWorld( );
void InitRenderParams( UINT8 ubRestrictionID );
void RenderWorld( );
/* This procedure will initialize gsVIEWPORT_xxx variables
* they ware declared with static initializer
* any question? joker
*/
void InitializeViewPort();
void ResetLayerOptimizing(void);
void ResetSpecificLayerOptimizing( UINT32 uiRowFlag );
// Routines of RenderWorld
extern void RenderStaticWorld( );
extern void RenderDynamicWorld( );
void CopyRenderBuffer( );
void SetRenderFlags(UINT32 uiFlags);
UINT32 GetRenderFlags(void);
void ClearRenderFlags(UINT32 uiFlags);
void RenderSetShadows(BOOLEAN fShadows);
extern UINT16 *gpZBuffer;
extern UINT32 gRenderFlags;
extern BOOLEAN gfIgnoreScrolling;
extern BOOLEAN gfScrollInertia;
extern BOOLEAN gfScrollPending;
// Definitions for dirty rectangle uploads
void ReRenderWorld(INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom);
BOOLEAN ConcealWalls(INT16 sX, INT16 sY, INT16 sRadius);
BOOLEAN RevealWalls(INT16 sX, INT16 sY, INT16 sRadius);
void ConcealAllWalls(void);
BOOLEAN ApplyScrolling( INT16 sTempRenderCenterX, INT16 sTempRenderCenterY, BOOLEAN fForceAdjust, BOOLEAN fCheckOnly );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
void RenderStaticWorldRect(INT16, INT16, INT16, INT16, BOOLEAN );
void RenderMarkedWorld(void);
void RenderDynamicMercWorld( void );
void ExamineZBufferRect( INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom);
void InvalidateWorldRedundency(void);
void InvalidateWorldRedundencyRadius(INT16 sX, INT16 sY, INT16 sRadius);
void DirtyWorldRender( );
// These two functions will setup the glow frame script to use then glowing enemy mercs....
void SetMercGlowFast( );
void SetMercGlowNormal( );
void SetRenderCenter( INT16 sNewX, INT16 sNewY );
#ifdef _DEBUG
void RenderFOVDebug( );
#endif
BOOLEAN Zero8BPPDataTo16BPPBufferTransparent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncClipZSameZBurnsThrough( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZStripIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferTransInvZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncObscureClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncObscureClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette );
#endif
File diff suppressed because it is too large Load Diff
+127
View File
@@ -0,0 +1,127 @@
#ifndef STRUCTURE_H
#define STRUCTURE_H
#include "Structure Internals.h"
#include "tiledef.h"
#include "overhead types.h"
#define NOTHING_BLOCKING 0
#define BLOCKING_REDUCE_RANGE 1
#define BLOCKING_NEXT_TILE 10
#define BLOCKING_TOPLEFT_WINDOW 30
#define BLOCKING_TOPRIGHT_WINDOW 40
#define BLOCKING_TOPLEFT_DOOR 50
#define BLOCKING_TOPRIGHT_DOOR 60
#define FULL_BLOCKING 70
#define BLOCKING_TOPLEFT_OPEN_WINDOW 90
#define BLOCKING_TOPRIGHT_OPEN_WINDOW 100
// ATE: Increased to allow corpses to not collide with soldiers
// 100 == MAX_CORPSES
#define INVALID_STRUCTURE_ID ( TOTAL_SOLDIERS + 100 )
#define IGNORE_PEOPLE_STRUCTURE_ID (TOTAL_SOLDIERS+101)
#define STRUCTURE_DAMAGE_EXPLOSION 1
#define STRUCTURE_DAMAGE_GUNFIRE 2
// functions at the structure database level
//
STRUCTURE_FILE_REF * LoadStructureFile( STR szFileName );
void FreeAllStructureFiles( void );
BOOLEAN FreeStructureFile( STRUCTURE_FILE_REF * pStructureFile );
//
// functions at the structure instance level
//
BOOLEAN OkayToAddStructureToWorld( INT16 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, INT16 sExclusionID );
// for the PTR argument of AddStructureToWorld, pass in a LEVELNODE * please!
BOOLEAN AddStructureToWorld( INT16 sBaseGridNo, INT8 bLevel, DB_STRUCTURE_REF * pDBStructureRef, PTR pLevelN );
BOOLEAN DeleteStructureFromWorld( STRUCTURE * pStructure );
//
// functions to find a structure in a location
//
STRUCTURE * FindStructure( INT16 sGridNo, UINT32 fFlags );
STRUCTURE * FindNextStructure( STRUCTURE * pStructure, UINT32 fFlags );
STRUCTURE * FindStructureByID( INT16 sGridNo, UINT16 usStructureID );
STRUCTURE * FindBaseStructure( STRUCTURE * pStructure );
STRUCTURE * FindNonBaseStructure( INT16 sGridNo, STRUCTURE * pStructure );
//
// functions related to interactive tiles
//
STRUCTURE * SwapStructureForPartner( INT16 sGridNo, STRUCTURE * pStructure );
STRUCTURE * SwapStructureForPartnerWithoutTriggeringSwitches( INT16 sGridNo, STRUCTURE * pStructure );
STRUCTURE * SwapStructureForPartnerAndStoreChangeInMap( INT16 sGridNo, STRUCTURE * pStructure );
//
// functions useful for AI that return info about heights
//
INT8 StructureHeight( STRUCTURE * pStructure );
INT8 StructureBottomLevel( STRUCTURE * pStructure );
INT8 GetTallestStructureHeight( INT16 sGridNo, BOOLEAN fOnRoof );
INT8 GetStructureTargetHeight( INT16 sGridNo, BOOLEAN fOnRoof );
BOOLEAN StructureDensity( STRUCTURE * pStructure, UINT8 * pubLevel0, UINT8 * pubLevel1, UINT8 * pubLevel2, UINT8 * pubLevel3 );
BOOLEAN FindAndSwapStructure( INT16 sGridNo );
INT16 GetBaseTile( STRUCTURE * pStructure );
//
// functions to work with the editor undo code
//
void DebugStructurePage1( void );
BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructureFileRef, BOOLEAN fFromAnimation, INT16 sSTIStartIndex );
// FUNCTIONS FOR DETERMINING STUFF THAT BLOCKS VIEW FOR TILE_bASED LOS
INT8 GetBlockingStructureInfo( INT16 sGridNo, INT8 bDir, INT8 bNextDir, INT8 bLevel, INT8 *pStructHeight, STRUCTURE ** ppTallestStructure, BOOLEAN fWallsBlock );
BOOLEAN DamageStructure( STRUCTURE * pStructure, UINT8 ubDamage, UINT8 ubReason, INT16 sGridNo, INT16 sX, INT16 sY, UINT8 ubOwner );
// Material armour type enumeration
enum
{
MATERIAL_NOTHING,
MATERIAL_WOOD_WALL,
MATERIAL_PLYWOOD_WALL,
MATERIAL_LIVE_WOOD,
MATERIAL_LIGHT_VEGETATION,
MATERIAL_FURNITURE,
MATERIAL_PORCELAIN,
MATERIAL_CACTUS,
MATERIAL_NOTUSED1,
MATERIAL_NOTUSED2,
MATERIAL_NOTUSED3,
MATERIAL_STONE,
MATERIAL_CONCRETE1,
MATERIAL_CONCRETE2,
MATERIAL_ROCK,
MATERIAL_RUBBER,
MATERIAL_SAND,
MATERIAL_CLOTH,
MATERIAL_SANDBAG,
MATERIAL_NOTUSED5,
MATERIAL_NOTUSED6,
MATERIAL_LIGHT_METAL,
MATERIAL_THICKER_METAL,
MATERIAL_HEAVY_METAL,
MATERIAL_INDESTRUCTABLE_STONE,
MATERIAL_INDESTRUCTABLE_METAL,
MATERIAL_THICKER_METAL_WITH_SCREEN_WINDOWS,
NUM_MATERIAL_TYPES
};
extern INT32 guiMaterialHitSound[ NUM_MATERIAL_TYPES ];
STRUCTURE *FindStructureBySavedInfo( INT16 sGridNo, UINT8 ubType, UINT8 ubWallOrientation, INT8 bLevel );
UINT32 StructureTypeToFlag( UINT8 ubType );
UINT8 StructureFlagToType( UINT32 uiFlag );
UINT32 GetStructureOpenSound( STRUCTURE *pStructure, BOOLEAN fClose );
#endif
+53
View File
@@ -0,0 +1,53 @@
#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "sgp.h"
#include "himage.h"
#include "vsurface.h"
#include "vsurface_private.h"
#include "wcheck.h"
#include "sysutil.h"
#include "renderworld.h"
#endif
UINT32 guiBOTTOMPANEL = 0;
UINT32 guiRIGHTPANEL = 0;
UINT32 guiRENDERBUFFER = 0;
UINT32 guiSAVEBUFFER = 0;
UINT32 guiEXTRABUFFER = 0;
BOOLEAN gfExtraBuffer = FALSE;
BOOLEAN InitializeSystemVideoObjects( )
{
return( TRUE );
}
BOOLEAN InitializeGameVideoObjects( )
{
VSURFACE_DESC vs_desc;
UINT16 usWidth;
UINT16 usHeight;
UINT8 ubBitDepth;
// Create render buffer
GetCurrentVideoSettings( &usWidth, &usHeight, &ubBitDepth );
vs_desc.fCreateFlags = VSURFACE_CREATE_DEFAULT | VSURFACE_SYSTEM_MEM_USAGE;
vs_desc.usWidth = usWidth;
vs_desc.usHeight = usHeight;
vs_desc.ubBitDepth = ubBitDepth;
CHECKF( AddVideoSurface( &vs_desc, &guiSAVEBUFFER ) );
CHECKF( AddVideoSurface( &vs_desc, &guiEXTRABUFFER ) );
gfExtraBuffer = TRUE;
guiRENDERBUFFER=FRAME_BUFFER;
return( TRUE );
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef __SYSTEM_UTILS
#define __SYSTEM_UTILS
#include "font.h"
#include "Isometric Utils.h"
#include "interface.h"
// Global variables for video objects
extern UINT32 guiBOTTOMPANEL;
extern UINT32 guiRIGHTPANEL;
extern UINT32 guiRENDERBUFFER;
extern UINT32 guiSAVEBUFFER;
extern UINT32 guiEXTRABUFFER;
extern BOOLEAN gfExtraBuffer;
BOOLEAN InitializeSystemVideoObjects( );
BOOLEAN InitializeGameVideoObjects( );
#endif
File diff suppressed because it is too large Load Diff
+197
View File
@@ -0,0 +1,197 @@
#ifndef __TILEDEF_H
#define __TILEDEF_H
#include "vobject.h"
#include "timer.h"
#include "TileDat.h"
#include "structure.h"
// CATEGORY TYPES
#define NO_TILE 64000
#define ERASE_TILE 65000
#define REQUIRES_SMOOTHING_TILE 19
#define NUM_WALL_ORIENTATIONS 40
#define WALL_TILE 0x00000001
#define ANIMATED_TILE 0x00000002
#define DYNAMIC_TILE 0x00000004
#define IGNORE_WORLD_HEIGHT 0x00000008
#define ROAD_TILE 0x00000010
#define FULL3D_TILE 0x00000020
#define MULTI_Z_TILE 0x00000080
#define OBJECTLAYER_USEZHEIGHT 0x00000100
#define ROOFSHADOW_TILE 0x00000200
#define ROOF_TILE 0x00000400
#define TRANSLUCENT_TILE 0x00000800
#define HAS_SHADOW_BUDDY 0x00001000
#define AFRAME_TILE 0x00002000
#define HIDDEN_TILE 0x00004000
#define CLIFFHANG_TILE 0x00008000
#define UNDERFLOW_FILLER 0x00010000
#define Z_AWARE_DYNAMIC_TILE 0x00020000
#define MAX_ANIMATED_TILES 200
#define WALL_HEIGHT 50
//Kris: Added the last two bottom corner orientation values. This won't effect
//current code, but there is new code that makes use of this. A function called
//UINT8 CalculateWallOrientationsAtGridNo( INT32 iMapIndex ) that will look at all
//of the walls and return the last two wall orientations for tiles with two proper
//wall pieces.
enum WallOrientationDefines
{
NO_ORIENTATION, INSIDE_TOP_LEFT, INSIDE_TOP_RIGHT, OUTSIDE_TOP_LEFT,
OUTSIDE_TOP_RIGHT, INSIDE_BOTTOM_CORNER, OUTSIDE_BOTTOM_CORNER
};
// TERRAIN ID VALUES.
enum TerrainTypeDefines
{
NO_TERRAIN,
FLAT_GROUND,
FLAT_FLOOR,
PAVED_ROAD,
DIRT_ROAD,
LOW_GRASS,
HIGH_GRASS,
TRAIN_TRACKS,
LOW_WATER,
MED_WATER,
DEEP_WATER,
NUM_TERRAIN_TYPES
} ;
// These structures are placed in a list and used for all tile imagery
typedef struct
{
HVOBJECT vo;
UINT32 fType;
AuxObjectData * pAuxData;
RelTileLoc * pTileLocData;
STRUCTURE_FILE_REF * pStructureFileRef;
UINT8 ubTerrainID;
BYTE bRaisedObjectType;
// Reserved for added room and 32-byte boundaries
BYTE bReserved[ 2 ];
} TILE_IMAGERY, *PTILE_IMAGERY;
typedef struct
{
UINT16 *pusFrames;
INT8 bCurrentFrame;
UINT8 ubNumFrames;
} TILE_ANIMATION_DATA;
// Tile data element
typedef struct
{
UINT16 fType;
HVOBJECT hTileSurface;
DB_STRUCTURE_REF * pDBStructureRef;
UINT32 uiFlags;
RelTileLoc * pTileLocData;
UINT16 usRegionIndex;
INT16 sBuddyNum;
UINT8 ubTerrainID;
UINT8 ubNumberOfTiles;
UINT8 bZOffsetX;
UINT8 bZOffsetY;
// This union contains different data based on tile type
union
{
// Land and overlay type
struct
{
INT16 sOffsetHeight;
UINT16 usWallOrientation;
UINT8 ubFullTile;
// For animated tiles
TILE_ANIMATION_DATA *pAnimData;
};
};
// Reserved for added room and 32-byte boundaries
BYTE bReserved[ 3 ];
} TILE_ELEMENT, *PTILE_ELEMENT;
typedef struct
{
INT32 iMapIndex;
UINT8 ubNumLayers;
UINT16 *pIndexValues;
} land_undo_struct;
// Globals used
extern TILE_ELEMENT gTileDatabase[ NUMBEROFTILES ];
extern UINT16 gTileDatabaseSize;
UINT8 gFullBaseTileValues[];
extern UINT16 gNumTilesPerType[ NUMBEROFTILETYPES ];
extern UINT16 gTileTypeStartIndex[ NUMBEROFTILETYPES ];
extern STR gTileSurfaceName[NUMBEROFTILETYPES];
extern UINT8 gTileTypeLogicalHeight[ NUMBEROFTILETYPES ];
extern UINT16 gusNumAnimatedTiles;
extern UINT16 gusAnimatedTiles[ MAX_ANIMATED_TILES ];
extern UINT8 gTileTypeMovementCost[ NUM_TERRAIN_TYPES ];
void CreateTileDatabase( );
// Land level manipulation functions
BOOLEAN GetLandHeadType( INT32 iMapIndex, UINT32 *puiType );
BOOLEAN SetLandIndex( INT32 iMapIndex, UINT16 usIndex, UINT32 uiNewType, BOOLEAN fDelete );
BOOLEAN GetTypeLandLevel( UINT32 iMapIndex, UINT32 uiNewType, UINT8 *pubLevel );
UINT8 GetLandLevelDepth( UINT32 iMapIndex );
BOOLEAN SetLandIndexWithRadius( INT32 iMapIndex, UINT16 usIndex, UINT32 uiNewType, UINT8 ubRadius, BOOLEAN fReplace );
BOOLEAN LandTypeHeigher( UINT32 uiDestType, UINT32 uiSrcType );
BOOLEAN MoveLandIndexToTop( UINT32 iMapIndex, UINT16 usIndex );
// Database access functions
BOOLEAN GetSubIndexFromTileIndex( UINT16 usIndex, UINT16 *pusSubIndex );
BOOLEAN GetTypeSubIndexFromTileIndex( UINT32 uiCheckType, UINT16 usIndex, UINT16 *pusSubIndex );
BOOLEAN GetTypeSubIndexFromTileIndexChar( UINT32 uiCheckType, UINT16 usIndex, UINT8 *pusSubIndex );
BOOLEAN GetTileIndexFromTypeSubIndex( UINT32 uiCheckType, UINT16 usSubIndex, UINT16 *pusTileIndex );
BOOLEAN GetTileType( UINT16 usIndex, UINT32 *puiType );
BOOLEAN GetTileFlags( UINT16 usIndex, UINT32 *puiFlags );
BOOLEAN GetTileTypeLogicalHeight( UINT32 fType, UINT8 *pubLogHeight );
BOOLEAN AnyHeigherLand( UINT32 iMapIndex, UINT32 uiSrcType, UINT8 *pubLastLevel );
BOOLEAN AnyLowerLand( UINT32 iMapIndex, UINT32 uiSrcType, UINT8 *pubLastLevel );
BOOLEAN GetWallOrientation( UINT16 usIndex, UINT16 *pusWallOrientation );
BOOLEAN ContainsWallOrientation( INT32 iMapIndex, UINT32 uiType, UINT16 usWallOrientation, UINT8 *pubLevel );
UINT8 CalculateWallOrientationsAtGridNo( INT32 iMapIndex );
void SetSpecificDatabaseValues( UINT16 usType, UINT16 uiDatabaseElem, TILE_ELEMENT *TileElement, BOOLEAN fUseRaisedObjectType );
BOOLEAN AllocateAnimTileData( TILE_ELEMENT *pTileElem, UINT8 ubNumFrames );
void FreeAnimTileData( TILE_ELEMENT *pTileElem );
void DeallocateTileDatabase( );
#endif
File diff suppressed because it is too large Load Diff
+296
View File
@@ -0,0 +1,296 @@
#ifndef __WORLDDEF_H
#define __WORLDDEF_H
#include "vobject.h"
#include "tiledef.h"
#include "Soldier Control.h"
#include "structure.h"
#include "Handle Items.h"
#define WORLD_TILE_X 40
#define WORLD_TILE_Y 20
#define WORLD_COLS 160
#define WORLD_ROWS 160
#define WORLD_COORD_COLS 1600
#define WORLD_COORD_ROWS 1600
#define WORLD_MAX 25600
#define CELL_X_SIZE 10
#define CELL_Y_SIZE 10
#define WORLD_BASE_HEIGHT 0
#define WORLD_CLIFF_HEIGHT 80
//A macro that actually memcpy's over data and increments the pointer automatically
//based on the size. Works like a FileRead except with a buffer instead of a file pointer.
//Used by LoadWorld() and child functions.
#include <memory.h>
#define LOADDATA( dst, src, size ) memcpy( dst, src, size ); src += size
#define LANDHEAD 0
#define MAXDIR 8
// Defines for shade levels
#define DEFAULT_SHADE_LEVEL 4
#define MIN_SHADE_LEVEL 4
#define MAX_SHADE_LEVEL 15
// DEFINES FOR LEVELNODE FLAGS
#define LEVELNODE_SOLDIER 0x00000001
#define LEVELNODE_UNUSED2 0x00000002
#define LEVELNODE_MERCPLACEHOLDER 0x00000004
#define LEVELNODE_SHOW_THROUGH 0x00000008
#define LEVELNODE_NOZBLITTER 0x00000010
#define LEVELNODE_CACHEDANITILE 0x00000020
#define LEVELNODE_ROTTINGCORPSE 0x00000040
#define LEVELNODE_BUDDYSHADOW 0x00000080
#define LEVELNODE_HIDDEN 0x00000100
#define LEVELNODE_USERELPOS 0x00000200
#define LEVELNODE_DISPLAY_AP 0x00000400
#define LEVELNODE_ANIMATION 0x00000800
#define LEVELNODE_USEABSOLUTEPOS 0x00001000
#define LEVELNODE_REVEAL 0x00002000
#define LEVELNODE_REVEALTREES 0x00004000
#define LEVELNODE_USEBESTTRANSTYPE 0x00008000
#define LEVELNODE_USEZ 0x00010000
#define LEVELNODE_DYNAMICZ 0x00020000
#define LEVELNODE_UPDATESAVEBUFFERONCE 0x00040000
#define LEVELNODE_ERASEZ 0x00080000
#define LEVELNODE_WIREFRAME 0x00100000
#define LEVELNODE_ITEM 0x00200000
#define LEVELNODE_IGNOREHEIGHT 0x00400000
#define LEVELNODE_DYNAMIC 0x02000000
#define LEVELNODE_LASTDYNAMIC 0x04000000
#define LEVELNODE_PHYSICSOBJECT 0x08000000
#define LEVELNODE_NOWRITEZ 0x10000000
#define LEVELNODE_MULTITILESOLDIER 0x20000000
#define LEVELNODE_EXITGRID 0x40000000
#define LEVELNODE_CAVE 0x80000000
// THE FIRST FEW ( 4 ) bits are flags which are saved in the world
#define MAPELEMENT_REDUNDENT 0x0001
#define MAPELEMENT_REEVALUATE_REDUNDENCY 0x0002
#define MAPELEMENT_ENEMY_MINE_PRESENT 0x0004
#define MAPELEMENT_PLAYER_MINE_PRESENT 0x0008
#define MAPELEMENT_STRUCTURE_DAMAGED 0x0010
#define MAPELEMENT_REEVALUATEBLOOD 0x0020
#define MAPELEMENT_INTERACTIVETILE 0x0040
#define MAPELEMENT_RAISE_LAND_START 0x0080
#define MAPELEMENT_REVEALED 0x0100
#define MAPELEMENT_RAISE_LAND_END 0x0200
#define MAPELEMENT_REDRAW 0x0400
#define MAPELEMENT_REVEALED_ROOF 0x0800
#define MAPELEMENT_MOVEMENT_RESERVED 0x1000
#define MAPELEMENT_RECALCULATE_WIREFRAMES 0x2000
#define MAPELEMENT_ITEMPOOL_PRESENT 0x4000
#define MAPELEMENT_REACHABLE 0x8000
#define MAPELEMENT_EXT_SMOKE 0x01
#define MAPELEMENT_EXT_TEARGAS 0x02
#define MAPELEMENT_EXT_MUSTARDGAS 0x04
#define MAPELEMENT_EXT_DOOR_STATUS_PRESENT 0x08
#define MAPELEMENT_EXT_RECALCULATE_MOVEMENT 0x10
#define MAPELEMENT_EXT_NOBURN_STRUCT 0x20
#define MAPELEMENT_EXT_ROOFCODE_VISITED 0x40
#define MAPELEMENT_EXT_CREATUREGAS 0x80
#define FIRST_LEVEL 0
#define SECOND_LEVEL 1
#define ANY_SMOKE_EFFECT ( MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS )
typedef struct TAG_level_node
{
struct TAG_level_node *pNext;
UINT32 uiFlags; // flags struct
UINT8 ubSumLights; // LIGHTING INFO
UINT8 ubMaxLights; // MAX LIGHTING INFO
union
{
struct TAG_level_node *pPrevNode; // FOR LAND, GOING BACKWARDS POINTER
STRUCTURE *pStructureData; // STRUCTURE DATA
INT32 iPhysicsObjectID; // ID FOR PHYSICS ITEM
INT32 uiAPCost; // FOR AP DISPLAY
INT32 iExitGridInfo;
}; // ( 4 byte union )
union
{
struct
{
UINT16 usIndex; // TILE DATABASE INDEX
INT16 sCurrentFrame; // Stuff for animated tiles for a given tile location ( doors, etc )
};
SOLDIERTYPE *pSoldier; // POINTER TO SOLDIER
}; // ( 4 byte union )
union
{
// Some levelnodes can specify relative X and Y values!
struct
{
INT16 sRelativeX; // Relative position values
INT16 sRelativeY; // Relative position values
};
// Some can contains index values into dead corpses
struct
{
INT32 iCorpseID; // Index into corpse ID
};
struct
{
UINT32 uiAnimHitLocationFlags; // Animation profile flags for soldier placeholders ( prone merc hit location values )
};
// Some can contains index values into animated tile data
struct
{
struct TAG_anitile *pAniTile;
};
// Can be an item pool as well...
struct
{
ITEM_POOL *pItemPool; // ITEM POOLS
};
};
INT16 sRelativeZ; // Relative position values
UINT8 ubShadeLevel; // LIGHTING INFO
UINT8 ubNaturalShadeLevel; // LIGHTING INFO
UINT8 ubFakeShadeLevel; // LIGHTING INFO
} LEVELNODE;
#define LAND_START_INDEX 1
#define OBJECT_START_INDEX 2
#define STRUCT_START_INDEX 3
#define SHADOW_START_INDEX 4
#define MERC_START_INDEX 5
#define ROOF_START_INDEX 6
#define ONROOF_START_INDEX 7
#define TOPMOST_START_INDEX 8
typedef struct
{
union
{
struct
{
LEVELNODE *pLandHead; //0
LEVELNODE *pLandStart; //1
LEVELNODE *pObjectHead; //2
LEVELNODE *pStructHead; //3
LEVELNODE *pShadowHead; //4
LEVELNODE *pMercHead; //5
LEVELNODE *pRoofHead; //6
LEVELNODE *pOnRoofHead; //7
LEVELNODE *pTopmostHead; //8
};
LEVELNODE *pLevelNodes[ 9 ];
};
STRUCTURE *pStructureHead;
STRUCTURE *pStructureTail;
UINT16 uiFlags;
UINT8 ubExtFlags[2];
UINT16 sSumRealLights[1];
UINT8 sHeight;
UINT8 ubAdjacentSoldierCnt;
UINT8 ubTerrainID;
UINT8 ubReservedSoldierID;
UINT8 ubBloodInfo;
UINT8 ubSmellInfo;
} MAP_ELEMENT;
// World Data
extern MAP_ELEMENT *gpWorldLevelData;
// World Movement Costs
extern UINT8 gubWorldMovementCosts[ WORLD_MAX ][MAXDIR][2];
extern UINT8 gubCurrentLevel;
extern INT32 giCurrentTilesetID;
extern HVOBJECT hRenderVObject;
extern UINT32 gSurfaceMemUsage;
extern CHAR8 gzLastLoadedFile[ 260 ];
extern INT16 gsRecompileAreaTop;
extern INT16 gsRecompileAreaLeft;
extern INT16 gsRecompileAreaRight;
extern INT16 gsRecompileAreaBottom;
// Functions
BOOLEAN InitializeWorld( );
void DeinitializeWorld( );
void BuildTileShadeTables( );
void DestroyTileShadeTables( );
void TrashWorld(void);
void TrashMapTile(INT16 MapTile);
BOOLEAN NewWorld( void );
BOOLEAN SaveWorld( UINT8 * puiFilename );
BOOLEAN LoadWorld( UINT8 *puiFilename );
void CompileWorldMovementCosts( );
void RecompileLocalMovementCosts( INT16 sCentreGridNo );
void RecompileLocalMovementCostsFromRadius( INT16 sCentreGridNo, INT8 bRadius );
BOOLEAN LoadMapTileset( INT32 iTilesetID );
BOOLEAN SaveMapTileset( INT32 iTilesetID );
void SetLoadOverrideParams( BOOLEAN fForceLoad, BOOLEAN fForceFile, CHAR8 *zLoadName );
void CalculateWorldWireFrameTiles( BOOLEAN fForce );
void RemoveWorldWireFrameTiles( );
void RemoveWireFrameTiles( INT16 sGridNo );
LEVELNODE *GetAnimProfileFlags( UINT16 sGridNo, UINT16 *usFlags, SOLDIERTYPE **ppTargSoldier, LEVELNODE *pGivenNode );
void ReloadTileset( UINT8 ubID );
BOOLEAN FloorAtGridNo( UINT32 iMapIndex );
BOOLEAN DoorAtGridNo( UINT32 iMapIndex );
BOOLEAN GridNoIndoors( UINT32 iMapIndex );
BOOLEAN OpenableAtGridNo( UINT32 iMapIndex );
void RecompileLocalMovementCostsInAreaWithFlags( void );
void AddTileToRecompileArea( INT16 sGridNo );
#endif
File diff suppressed because it is too large Load Diff
+156
View File
@@ -0,0 +1,156 @@
#ifndef __WORLDMAN_H_
#define __WORLDMAN_H_
// memory-accounting function
void CountLevelNodes( void );
// Object manipulation functions
BOOLEAN RemoveObject( UINT32 iMapIndex, UINT16 usIndex );
LEVELNODE *AddObjectToTail( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddObjectToHead( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN TypeExistsInObjectLayer( UINT32 iMapIndex, UINT32 fType, UINT16 *pusObjectIndex );
BOOLEAN RemoveAllObjectsOfTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
void SetAllObjectShadeLevels( UINT32 iMapIndex, UINT8 ubShadeLevel );
void AdjustAllObjectShadeLevels( UINT32 iMapIndex, INT8 bShadeDiff );
BOOLEAN TypeRangeExistsInObjectLayer( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT16 *pusObjectIndex );
// Roof manipulation functions
BOOLEAN RemoveRoof( UINT32 iMapIndex, UINT16 usIndex );
LEVELNODE *AddRoofToTail( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddRoofToHead( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN TypeExistsInRoofLayer( UINT32 iMapIndex, UINT32 fType, UINT16 *pusRoofIndex );
BOOLEAN RemoveAllRoofsOfTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
void SetAllRoofShadeLevels( UINT32 iMapIndex, UINT8 ubShadeLevel );
void AdjustAllRoofShadeLevels( UINT32 iMapIndex, INT8 bShadeDiff );
void RemoveRoofIndexFlagsFromTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT32 uiFlags );
void SetRoofIndexFlagsFromTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT32 uiFlags );
BOOLEAN TypeRangeExistsInRoofLayer( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT16 *pusRoofIndex );
void SetWallLevelnodeFlags( UINT16 sGridNo, UINT32 uiFlags );
void RemoveWallLevelnodeFlags( UINT16 sGridNo, UINT32 uiFlags );
BOOLEAN IndexExistsInRoofLayer( INT16 sGridNo, UINT16 usIndex );
// OnRoof manipulation functions
BOOLEAN RemoveOnRoof( UINT32 iMapIndex, UINT16 usIndex );
LEVELNODE *AddOnRoofToTail( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddOnRoofToHead( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN TypeExistsInOnRoofLayer( UINT32 iMapIndex, UINT32 fType, UINT16 *pusOnRoofIndex );
BOOLEAN RemoveAllOnRoofsOfTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
void SetAllOnRoofShadeLevels( UINT32 iMapIndex, UINT8 ubShadeLevel );
void AdjustAllOnRoofShadeLevels( UINT32 iMapIndex, INT8 bShadeDiff );
BOOLEAN RemoveOnRoofFromLevelNode( UINT32 iMapIndex, LEVELNODE *pNode );
// Land manipulation functions
BOOLEAN RemoveLand( UINT32 iMapIndex, UINT16 usIndex );
LEVELNODE *AddLandToTail( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddLandToHead( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN TypeExistsInLandLayer( UINT32 iMapIndex, UINT32 fType, UINT16 *pusLandIndex );
BOOLEAN RemoveAllLandsOfTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
BOOLEAN TypeRangeExistsInLandLayer( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT16 *pusLandIndex );
BOOLEAN TypeRangeExistsInLandHead( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT16 *pusLandIndex );
BOOLEAN ReplaceLandIndex( UINT32 iMapIndex, UINT16 usOldIndex, UINT16 usNewIndex );
BOOLEAN DeleteAllLandLayers( UINT32 iMapIndex );
BOOLEAN InsertLandIndexAtLevel( UINT32 iMapIndex, UINT16 usIndex, UINT8 ubLevel );
BOOLEAN RemoveHigherLandLevels( UINT32 iMapIndex, UINT32 fSrcType, UINT32 **puiHigherTypes, UINT8 *pubNumHigherTypes );
BOOLEAN SetLowerLandLevels( UINT32 iMapIndex, UINT32 fSrcType, UINT16 usIndex );
BOOLEAN AdjustForFullTile( UINT32 iMapIndex );
void SetAllLandShadeLevels( UINT32 iMapIndex, UINT8 ubShadeLevel );
void AdjustAllLandShadeLevels( UINT32 iMapIndex, INT8 bShadeDiff );
void AdjustAllLandDirtyCount( UINT32 iMapIndex, INT8 bDirtyDiff );
UINT8 GetTerrainType( INT16 sGridNo );
BOOLEAN Water( INT16 sGridNo );
BOOLEAN DeepWater( INT16 sGridNo );
BOOLEAN WaterTooDeepForAttacks( INT16 sGridNo );
// Structure manipulation routines
BOOLEAN RemoveStruct( UINT32 iMapIndex, UINT16 usIndex );
LEVELNODE *AddStructToTail( UINT32 iMapIndex, UINT16 usIndex );
LEVELNODE *AddStructToTailCommon( UINT32 iMapIndex, UINT16 usIndex, BOOLEAN fAddStructDBInfo );
LEVELNODE *ForceStructToTail( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddStructToHead( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN TypeExistsInStructLayer( UINT32 iMapIndex, UINT32 fType, UINT16 *pusStructIndex );
BOOLEAN RemoveAllStructsOfTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
BOOLEAN AddWallToStructLayer( INT32 iMapIndex, UINT16 usIndex, BOOLEAN fReplace );
BOOLEAN ReplaceStructIndex( UINT32 iMapIndex, UINT16 usOldIndex, UINT16 usNewIndex );
BOOLEAN HideStructOfGivenType( UINT32 iMapIndex, UINT32 fType, BOOLEAN fHide );
BOOLEAN InsertStructIndex( UINT32 iMapIndex, UINT16 usIndex, UINT8 ubLevel );
void SetAllStructShadeLevels( UINT32 iMapIndex, UINT8 ubShadeLevel );
void AdjustAllStructShadeLevels( UINT32 iMapIndex, INT8 bShadeDiff );
void SetStructIndexFlagsFromTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT32 uiFlags );
void RemoveStructIndexFlagsFromTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT32 uiFlags );
void SetStructAframeFlags( UINT32 iMapIndex, UINT32 uiFlags );
void RemoveStructAframeFlags( UINT32 iMapIndex, UINT32 uiFlags );
BOOLEAN RemoveStructFromLevelNode( UINT32 iMapIndex, LEVELNODE *pNode );
BOOLEAN RemoveStructFromTail( UINT32 iMapIndex );
BOOLEAN RemoveStructFromTailCommon( UINT32 iMapIndex, BOOLEAN fRemoveStructDBInfo );
BOOLEAN ForceRemoveStructFromTail( UINT32 iMapIndex );
BOOLEAN TypeRangeExistsInStructLayer( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT16 *pusStructIndex );
// Shadow manipulation routines
BOOLEAN RemoveShadow( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddShadowToTail( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddShadowToHead( UINT32 iMapIndex, UINT16 usIndex );
void AddExclusiveShadow( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN TypeExistsInShadowLayer( UINT32 iMapIndex, UINT32 fType, UINT16 *pusShadowIndex );
BOOLEAN RemoveAllShadowsOfTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
BOOLEAN RemoveAllShadows( UINT32 iMapIndex );
BOOLEAN RemoveShadowFromLevelNode( UINT32 iMapIndex, LEVELNODE *pNode );
// Merc manipulation routines
// #################################################################
BOOLEAN AddMercToHead( UINT32 iMapIndex, SOLDIERTYPE *pSoldier, BOOLEAN fAddStructInfo );
BOOLEAN RemoveMerc( UINT32 iMapIndex, SOLDIERTYPE *pSoldier, BOOLEAN fPlaceHolder );
UINT8 WhoIsThere2( INT16 sGridNo, INT8 bLevel );
BOOLEAN AddMercStructureInfo( INT16 sGridNo, SOLDIERTYPE *pSoldier );
BOOLEAN AddMercStructureInfoFromAnimSurface( INT16 sGridNo, SOLDIERTYPE *pSoldier, UINT16 usAnimSurface, UINT16 usAnimState );
BOOLEAN UpdateMercStructureInfo( SOLDIERTYPE *pSoldier );
BOOLEAN OKToAddMercToWorld( SOLDIERTYPE *pSoldier, INT8 bDirection );
// TOPMOST manipulation functions
LEVELNODE *AddTopmostToTail( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN AddTopmostToHead( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN RemoveTopmost( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN TypeExistsInTopmostLayer( UINT32 iMapIndex, UINT32 fType, UINT16 *pusTopmostIndex );
BOOLEAN RemoveAllTopmostsOfTypeRange( UINT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
BOOLEAN SetMapElementShadeLevel( UINT32 uiMapIndex, UINT8 ubShadeLevel );
void SetTopmostFlags( UINT32 iMapIndex, UINT32 uiFlags, UINT16 usIndex );
void RemoveTopmostFlags( UINT32 iMapIndex, UINT32 uiFlags, UINT16 usIndex );
BOOLEAN AddUIElem( UINT32 iMapIndex, UINT16 usIndex, INT8 sRelativeX, INT8 sRelativeY, LEVELNODE **ppNewNode );
void RemoveUIElem( UINT32 iMapIndex, UINT16 usIndex );
BOOLEAN RemoveTopmostFromLevelNode( UINT32 iMapIndex, LEVELNODE *pNode );
BOOLEAN IsLowerLevel( INT16 sGridNo );
BOOLEAN IsHeigherLevel( INT16 sGridNo );
BOOLEAN IsRoofVisible( INT16 sMapPos );
BOOLEAN IsRoofVisible2( INT16 sMapPos );
LEVELNODE * FindLevelNodeBasedOnStructure( INT16 sGridNo, STRUCTURE * pStructure );
LEVELNODE * FindShadow( INT16 sGridNo, UINT16 usStructIndex );
void WorldHideTrees( );
void WorldShowTrees( );
BOOLEAN IsTileRedundent( UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
//this is found in editscreen.c
//Andrew, you had worldman.c checked out at the time, so I stuck it here.
//The best thing to do is toast it here, and include editscreen.h in worldman.c.
extern UINT32 gCurrentBackground;
void SetTreeTopStateForMap();
#endif