#ifdef PRECOMPILEDHEADERS
	#include "Tactical All.h"
	#include "Enemy Soldier Save.h"
#else
	#include "Types.h"
	#include "MemMan.h"
	#include "message.h"
	#include "Items.h"
	#include "Handle Items.h"
	#include "StrategicMap.h"
	#include "Tactical Save.h"
	#include <stdio.h>
	#include "Campaign Types.h"
	#include "SaveLoadGame.h"
	#include "WorldDef.h"
	#include "rotting corpses.h"
	#include "OverHead.h"
	#include "Keys.h"
	#include "Soldier Create.h"
	#include "Soldier Profile.h"
	#include "Isometric Utils.h"
	#include "Soldier Add.h"
	#include "Npc.h"
	#include "Ai.h"
	#include "Game Clock.h"
	#include "Animation Control.h"
	#include "Map Information.h"
	#include "SaveLoadMap.h"
	#include "debug.h"
	#include "Random.h"
	#include "quests.h"
	#include "Animated ProgressBar.h"
	#include "Text.h"
	#include "meanwhile.h"
	#include "Enemy Soldier Save.h"
	#include "SmokeEffects.h"
	#include "LightEffects.h"
	#include "PATHAI.H"
	#include "GameVersion.h"
	#include "strategic.h"
	#include "Map Screen Interface Map.h"
	#include "Strategic Status.h"
	#include "Soldier macros.h"
	#include "sgp.h"
	#include "MessageBoxScreen.h"
	#include "screenids.h"
	#include "Queen Command.h"
	#include "Map Screen Interface Map Inventory.h"
#endif
#include "Animation Control.h"
#include <vfs/Core/vfs.h>
BOOLEAN gfWasInMeanwhile = FALSE;


//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
extern WorldItems gAllWorldItems;
void SaveWorldItemsToTempFiles();
void LoadWorldItemsFromTempFiles(INT16 sMapX, INT16 sMapY, INT8 bMapZ);
void ClearAllWorldItems(void);
bool LoadWorldItemsFromSavedGame(HWFILE hFile, INT16 x, INT16 y, INT8 z);
bool SaveWorldItemsToSavedGame(HWFILE hFile, INT16 x, INT16 y, INT8 z);
void PruneWorldItems(void);

///////////////////////////////////////////////////////////////
//
// Global Defines
//
///////////////////////////////////////////////////////////////


//dnl ch46 031009
// It's used for save info from the NPCQuoteInfo class that can change.
class TempNPCQuoteInfoSave
{
public:
	UINT16 usFlags;
	INT16 sRequiredItem;
	INT32 sRequiredGridNo;
	INT32 usGoToGridNo;
};

#define		NPC_TEMP_QUOTE_FILE			"Temp\\NpcQuote.tmp"


///////////////////////////////////////////////////////////////
//
// Global Variables
//
///////////////////////////////////////////////////////////////


extern	NPCQuoteInfo *	gpNPCQuoteInfoArray[NUM_PROFILES];

extern UINT32	guiJA2EncryptionSet;
extern UINT8 gubEncryptionArray1[ BASE_NUMBER_OF_ROTATION_ARRAYS * 3 ][ NEW_ROTATION_ARRAY_SIZE ];
extern UINT8 gubEncryptionArray2[ BASE_NUMBER_OF_ROTATION_ARRAYS * 3 ][ NEW_ROTATION_ARRAY_SIZE ];
extern UINT8 gubEncryptionArray3[ BASE_NUMBER_OF_ROTATION_ARRAYS * 3 ][ NEW_ROTATION_ARRAY_SIZE ];
extern UINT8 gubEncryptionArray4[ BASE_NUMBER_OF_ROTATION_ARRAYS * 3 ][ NEW_ROTATION_ARRAY_SIZE ];

INT32 giErrorMessageBox = 0;

///////////////////////////////////////////////////////////////
//
// Function Prototypes
//
///////////////////////////////////////////////////////////////

void TempFileLoadErrorMessageReturnCallback( UINT8 ubRetVal );

BOOLEAN SaveWorldItemsToTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems, WORLDITEM *pData );
BOOLEAN RetrieveTempFileFromSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ );

BOOLEAN AddTempFileToSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ );


BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, std::vector<ROTTING_CORPSE_DEFINITION> aCorpseDefVector );
BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );

void LoadNPCInformationFromProfileStruct();
void SaveNPCInformationToProfileStruct( );

BOOLEAN DoesTempFileExistsForMap( UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ );


INT16 GetSoldierIDFromAnyMercID(UINT8 ubMercID);


BOOLEAN SetUnderGroundSectorFlag( INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ, UINT32 uiFlagToSet );
BOOLEAN GetUnderGroundSectorFlagStatus( INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ, UINT32 uiFlagToCheck );

BOOLEAN LoadAndAddWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ );

BOOLEAN InitTempNpcQuoteInfoForNPCFromTempFile();
BOOLEAN SaveTempNpcQuoteInfoForNPCToTempFile( UINT8 ubNpcId );
BOOLEAN LoadTempNpcQuoteInfoForNPCFromTempFile( UINT8 ubNpcId );
UINT32	GetLastTimePlayerWasInSector();
UINT32 GetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ);	// Flugente: get time for another sector
void		SetLastTimePlayerWasInSector();
void		SetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ);	// Flugente: set last time sector was visited


extern void InitLoadedWorld( );
extern void ReduceAmmoDroppedByNonPlayerSoldiers( SOLDIERTYPE *pSoldier, INT32 iInvSlot );

extern void StripEnemyDetailedPlacementsIfSectorWasPlayerLiberated();

#ifdef JA2BETAVERSION
extern BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode );
#endif


UINT32 UpdateLoadedSectorsItemInventory( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems );

//ppp
///////////////////////////////////////////////////////////////
//
// Functions
//
///////////////////////////////////////////////////////////////
// SaveMapTempFilesToSavedGameFile() Looks for and opens all Map Modification files.  It add each mod file to the save game file.
BOOLEAN SaveMapTempFilesToSavedGameFile( HWFILE hFile )
{
	UNDERGROUND_SECTORINFO *TempNode = gpUndergroundSectorInfoHead;
	INT16 sMapX;
	INT16 sMapY;

	// Save all the global world items to temp files
	SaveWorldItemsToTempFiles();

	//
	//Loop though all the array elements to see if there is a data file to be saved
	//

	// Lesh: try to fix save/reload havok
	//First look through the above ground sectors
	for( sMapY=1; sMapY<=16; sMapY++ )
	{
		for( sMapX=1; sMapX<=16; sMapX++ )
		{
			//Save the Temp Item Files to the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_ITEM_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_ITEM_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}
			// Save the Rotting Corpse Temp file to the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_ROTTING_CORPSE_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}


			// Save the Map Modifications Temp file to the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			//Save the Door Table temp file to the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_DOOR_TABLE_TEMP_FILES_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_DOOR_TABLE_TEMP_FILES_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			//Save the revealed status temp file to the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_REVEALED_STATUS_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_REVEALED_STATUS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			//Save the door status temp file to the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_DOOR_STATUS_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_DOOR_STATUS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_CIV_PRESERVED_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_CIV_PRESERVED_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS )
			{
				if ( !AddTempFileToSavedGame( hFile, SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}


			//if any other file is to be saved
		}
	}


	//then look throught all the underground sectors
	while( TempNode )
	{
		if( TempNode->uiFlags & SF_ITEM_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_ITEM_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_ROTTING_CORPSE_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		// Save the Map Modifications Temp file to the saved game file
		if( TempNode->uiFlags & SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}


		//Save the door table to the saved game file
		if( TempNode->uiFlags & SF_DOOR_TABLE_TEMP_FILES_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_DOOR_TABLE_TEMP_FILES_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		//Save the revealed status temp file to the saved game file
		if( TempNode->uiFlags & SF_REVEALED_STATUS_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_REVEALED_STATUS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		//Save the door status temp file to the saved game file
		if( TempNode->uiFlags & SF_DOOR_STATUS_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_DOOR_STATUS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_CIV_PRESERVED_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_CIV_PRESERVED_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS )
		{
			if ( !AddTempFileToSavedGame( hFile, SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		//ttt


		TempNode = TempNode->next;
	}


	return( TRUE );
}

extern int gEnemyPreservedTempFileVersion[256];
extern int gCivPreservedTempFileVersion[256];

// LoadMapTempFilesFromSavedGameFile() loads all the temp files from the saved game file and writes them into the temp directory
BOOLEAN	LoadMapTempFilesFromSavedGameFile( HWFILE hFile )
{
	UNDERGROUND_SECTORINFO *TempNode = gpUndergroundSectorInfoHead;
	UINT32	uiPercentage;
	UINT32	iCounter = 0;

	// HACK FOR GABBY
	if ( guiCurrentSaveGameVersion < 81 && (gTacticalStatus.uiFlags & LOADING_SAVED_GAME) )
	{
		if ( gMercProfiles[ GABBY ].bMercStatus != MERC_IS_DEAD )
		{
			// turn off alternate flags for the sectors he could be in
			// randomly place him in one of the two possible sectors
			SectorInfo[ SECTOR( 14, MAP_ROW_L ) ].uiFlags &= ~SF_USE_ALTERNATE_MAP;
			SectorInfo[ SECTOR(  8, MAP_ROW_L ) ].uiFlags &= ~SF_USE_ALTERNATE_MAP;

			if ( Random( 2 ) )
			{
				SectorInfo[ SECTOR( 11, MAP_ROW_H ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
				gMercProfiles[ GABBY ].sSectorX = 11;
				gMercProfiles[ GABBY ].sSectorY = MAP_ROW_H;
			}
			else
			{
				SectorInfo[ SECTOR(  4, MAP_ROW_I ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
				gMercProfiles[ GABBY ].sSectorX = 4;
				gMercProfiles[ GABBY ].sSectorY = MAP_ROW_I;
			}
		}
	}


	// Preparation for loading item temp files
	ClearAllWorldItems();
	//
	//Loop though all the array elements to see if there is a data file to be loaded
	//

	//First look through the above ground sectors
	for ( INT16 sMapY = 1; sMapY < MAP_WORLD_Y - 1; ++sMapY )
	{
		for ( INT16 sMapX = 1; sMapX < MAP_WORLD_X - 1; ++sMapX )
		{
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_ITEM_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_ITEM_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
				// Load world items from map temp files into global struct
				LoadWorldItemsFromTempFiles(sMapX, sMapY, 0);
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_ROTTING_CORPSE_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_DOOR_TABLE_TEMP_FILES_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_DOOR_TABLE_TEMP_FILES_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			//Get the revealed status temp file From the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_REVEALED_STATUS_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_REVEALED_STATUS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			//Get the revealed status temp file From the saved game file
			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_DOOR_STATUS_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_DOOR_STATUS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
				gEnemyPreservedTempFileVersion[SECTOR( sMapX,sMapY)] = guiCurrentSaveGameVersion;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_CIV_PRESERVED_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_CIV_PRESERVED_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;

				if ( guiCurrentSaveGameVersion < 78 && (gTacticalStatus.uiFlags & LOADING_SAVED_GAME) )
				{
					CHAR8 pMapName[ 128 ];

					// KILL IT!!! KILL KIT!!!! IT IS CORRUPTED!!!
					GetMapTempFileName( SF_CIV_PRESERVED_TEMP_FILE_EXISTS, pMapName, sMapX, sMapY, 0 );
					FileDelete( pMapName );

					// turn off the flag
					SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags &= (~SF_CIV_PRESERVED_TEMP_FILE_EXISTS);
				}

				gCivPreservedTempFileVersion[SECTOR( sMapX,sMapY)] = guiCurrentSaveGameVersion;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}

			if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS )
			{
				if ( !RetrieveTempFileFromSavedGame( hFile, SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) )
					return FALSE;
			}
			
			//if any other file is to be saved

			++iCounter;

			//update the progress bar
			uiPercentage = (iCounter * 100) / (255);

			RenderProgressBar( 0, uiPercentage );
		}
	}
	
	//then look throught all the underground sectors
	while( TempNode )
	{
		if( TempNode->uiFlags & SF_ITEM_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_ITEM_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;

			//sync up the temp file data to the sector structure data
			LoadWorldItemsFromTempFiles(TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ);
		}

		if( TempNode->uiFlags & SF_ROTTING_CORPSE_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_DOOR_TABLE_TEMP_FILES_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_DOOR_TABLE_TEMP_FILES_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		//Get the revealed status temp file From the saved game file
		if( TempNode->uiFlags & SF_REVEALED_STATUS_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_REVEALED_STATUS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		//Get the revealed status temp file From the saved game file
		if( TempNode->uiFlags & SF_DOOR_STATUS_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_DOOR_STATUS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_CIV_PRESERVED_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_CIV_PRESERVED_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;

			if ( guiCurrentSaveGameVersion < 78 && (gTacticalStatus.uiFlags & LOADING_SAVED_GAME) )
			{
				CHAR8 pMapName[ 128 ];

				// KILL IT!!! KILL KIT!!!! IT IS CORRUPTED!!!
				GetMapTempFileName( SF_CIV_PRESERVED_TEMP_FILE_EXISTS, pMapName, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ );
				FileDelete( pMapName );

				// turn off the flag
				TempNode->uiFlags &= (~SF_CIV_PRESERVED_TEMP_FILE_EXISTS);
			}
		}

		if( TempNode->uiFlags & SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		if( TempNode->uiFlags & SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS )
		{
			if ( !RetrieveTempFileFromSavedGame( hFile, SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS, TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ ) )
				return FALSE;
		}

		TempNode = TempNode->next;
	}
//ttt
	return( TRUE );
}



/*
BOOLEAN UpdateENEMYTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, TRUE, TRUE );
	NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE, TRUE );
	LoadWorldItemsFromTempItemFile( sMapX,  sMapY, bMapZ, pTotalSectorList );
	int backup = guiCurrentSaveGameVersion;
	guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
	SaveWorldItemsToTempItemFile( sMapX, sMapY, bMapZ, uiTotalNumberOfItems, pTotalSectorList);
	guiCurrentSaveGameVersion = backup;
}


BOOLEAN UpdateCIVTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	LoadWorldItemsFromTempItemFile( sMapX,  sMapY, bMapZ, pTotalSectorList );
	int backup = guiCurrentSaveGameVersion;
	guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
	SaveWorldItemsToTempItemFile( sMapX, sMapY, bMapZ, uiTotalNumberOfItems, pTotalSectorList);
	guiCurrentSaveGameVersion = backup;
	return TRUE;
}
*/

BOOLEAN SaveWorldItemsToTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems, std::vector<WORLDITEM>& pData)
{
	HWFILE	hFile;
	UINT32	uiNumBytesWritten=0;
	CHAR8		zMapName[ 128 ];

	GetMapTempFileName( SF_ITEM_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );

	//Open the file for writing, Create it if it doesnt exist
	hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
	if( hFile == 0 )
	{
		//Error opening map modification file
		return( FALSE );
	}

	//Save the size of the ITem table
	FileWrite( hFile, &uiNumberOfItems, sizeof( UINT32 ), &uiNumBytesWritten );
	if( uiNumBytesWritten != sizeof( UINT32 ) )
	{
		//Error Writing size of array to disk
		FileClose( hFile );
		return( FALSE );
	}


	//if there are items to save..
	for (unsigned int x = 0; x < uiNumberOfItems; ++x)
	{
		//Save the ITem array
		if ( !pData[x].Save(hFile, FALSE) )
		{
			//Error Writing size of array to disk
			FileClose( hFile );
			return( FALSE );
		}
	}

	FileClose( hFile );

	SetSectorFlag( sMapX, sMapY, bMapZ, SF_ITEM_TEMP_FILE_EXISTS );

	return( TRUE );
}



BOOLEAN LoadWorldItemsFromTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, std::vector<WORLDITEM>& pData )//dnl ch75 271013
{
	UINT32	uiNumBytesRead=0;
	HWFILE	hFile;
	CHAR8		zMapName[ 128 ];
	UINT32 uiNumberOfItems=0;

	GetMapTempFileName( SF_ITEM_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );


	//Check to see if the file exists
	if( !FileExists( zMapName ) )
	{
		//If the file doesnt exists, its no problem.
		return( TRUE );
	}

	//Open the file for reading
	hFile = FileOpen( zMapName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
	if( hFile == 0 )
	{
		//Error opening map modification file,
		return( FALSE );
	}


	// Load the size of the World ITem table
	FileRead( hFile, &uiNumberOfItems, sizeof( UINT32 ), &uiNumBytesRead );
	if( uiNumBytesRead != sizeof( UINT32 ) )
	{
		//Error Writing size of array to disk
		FileClose( hFile );
		return( FALSE );
	}

	// Load the World ITem table
	for (unsigned int x = 0; x < uiNumberOfItems; ++x)
	{
		if ( !pData[x].Load(hFile) )
		{
			//Error Writing size of array to disk
			FileClose( hFile );
			return( FALSE );
		}
	}

	FileClose( hFile );

	return( TRUE );
}


BOOLEAN GetNumberOfWorldItemsFromTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 *pSizeOfData, BOOLEAN fIfEmptyCreate )
{
	UINT32	uiNumBytesRead=0;
	HWFILE	hFile;
	CHAR8		zMapName[ 128 ];
	UINT32	uiNumberOfItems=0;

	GetMapTempFileName( SF_ITEM_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );


	//Check if the file DOESNT exists
	if( !FileExistsNoDB( zMapName ) )
	{
		if( fIfEmptyCreate )
		{
			//ADB: I don't know why we are initing 10 WORLDITEMS then saving them, but that's what the code was.
			WORLDITEM	TempWorldItems[ 10 ];
			uiNumberOfItems = 10;
			UINT32		uiNumBytesWritten=0;

			//If the file doesnt exists, create a file that has an initial amount of Items
			hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
			if( hFile == 0 )
			{
				//Error opening item modification file
				return( FALSE );
			}

			//write the the number of item in the maps item file
			FileWrite( hFile, &uiNumberOfItems, sizeof( UINT32 ), &uiNumBytesWritten );
			if( uiNumBytesWritten != sizeof( UINT32 ) )
			{
				//Error Writing size of array to disk
				FileClose( hFile );
				return( FALSE );
			}

			//write the the number of item in the maps item file
			for (unsigned int x = 0; x < uiNumberOfItems; ++x)
			{
				if ( !TempWorldItems[x].Save(hFile, FALSE) )
				{
					//Error Writing size of array to disk
					FileClose( hFile );
					return( FALSE );
				}
			}

			//Close the file
			FileClose( hFile );
		}
		else
		{
			// the file doesnt exist
			*pSizeOfData = 0;

			return( TRUE );
		}
	}


	//Open the file for reading, if it exists
	hFile = FileOpen( zMapName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
	if( hFile == 0 )
	{
		//Error opening map modification file
		return( FALSE );
	}


	// Load the size of the World ITem table
	FileRead( hFile, &uiNumberOfItems, sizeof( UINT32 ), &uiNumBytesRead );
	if( uiNumBytesRead != sizeof( UINT32 ) )
	{
		//Error Writing size of array to disk
		FileClose( hFile );
		return( FALSE );
	}

	*pSizeOfData = uiNumberOfItems;

	FileClose( hFile );

	return( TRUE );
}

UINT32 GetNumberOfMovableItems( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	// not underground!
	if ( bMapZ )
		return 0;

	// open the inventory of the sector we are taking stuff from
	SECTORINFO *pSectorInfo_Target = &(SectorInfo[SECTOR( sMapX, sMapY )]);
	UINT32 uiTotalNumberOfRealItems_Target = 0;

	// use the new map
	std::vector<WORLDITEM> pWorldItem_Target;

	if ( (gWorldSectorX == sMapX) && (gWorldSectorY == sMapY) && (gbWorldSectorZ == bMapZ) )
	{
		uiTotalNumberOfRealItems_Target = guiNumWorldItems;
		pWorldItem_Target = gWorldItems;
	}
	else
	{
		const auto ii = FindWorldItemSector(sMapX, sMapY, bMapZ);
		if (ii != -1)
		{
			uiTotalNumberOfRealItems_Target = gAllWorldItems.NumItems[ii];
			pWorldItem_Target = gAllWorldItems.Items[ii];
		}
		else
		{
			uiTotalNumberOfRealItems_Target = 0;
		}
	}
	

	UINT32 validitems = 0;
	for ( UINT32 uiCount = 0; uiCount < uiTotalNumberOfRealItems_Target; ++uiCount )				// ... for all items in the world ...
	{
		if ( pWorldItem_Target[uiCount].fExists )										// ... if item exists ...
		{
			// test wether item is reachable and allowed to be moved by this assignment
			if ( (pWorldItem_Target[uiCount].usFlags & WORLD_ITEM_REACHABLE) && !(pWorldItem_Target[uiCount].usFlags & WORLD_ITEM_MOVE_ASSIGNMENT_IGNORE) && pWorldItem_Target[uiCount].bVisible > 0 )
			{
				OBJECTTYPE* pObj = &(pWorldItem_Target[uiCount].object);			// ... get pointer for this item ...

				if ( pObj != NULL && pObj->exists( ) )												// ... if pointer is not obviously useless ...
				{
					++validitems;
				}
			}
		}
	}
	return validitems;
}

BOOLEAN AddWorldItemsToUnLoadedSector(INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT32 sGridNo, UINT32 uiNumberOfItemsToAdd, std::vector<WORLDITEM>& pWorldItem, BOOLEAN fOverWrite)
{
	UINT32 uiLoop;
	UINT32 uiLastItemPos;
	UINT32 uiNumberOfItems;
	std::vector<WORLDITEM> pWorldItems;//dnl ch75 271013
	if (uiNumberOfItemsToAdd == 0 && fOverWrite == FALSE)
	{
		//Moa: nothing to do, so get out of here!
		return(TRUE);
	}

	const auto i = FindWorldItemSector(sMapX, sMapY, bMapZ);
	if (i == -1)
	{
		// Can't find world item sector, add it
		uiNumberOfItems = uiNumberOfItemsToAdd;
		pWorldItems.resize(uiNumberOfItems);
	}
	else
	{
		uiNumberOfItems = gAllWorldItems.NumItems[i];
		pWorldItems = gAllWorldItems.Items[i];
	}

	//if we are to replace the entire file
	if (fOverWrite)
	{
		//first loop through and mark all entries that they dont exists
		for (UINT32 cnt = 0; cnt < uiNumberOfItems; ++cnt)
			pWorldItems[cnt].fExists = FALSE;
	}

	uiLastItemPos = 0;

	//loop through all the objects to add
	for (uiLoop = 0; uiLoop < uiNumberOfItemsToAdd; ++uiLoop)
	{
		// Flugente: only add an item if it exists. Otherwise we will happily add items that are supposed to have been deleted
		if (!pWorldItem[uiLoop].fExists)
			continue;

		//Loop through the array to see if there is a free spot to add an item to it
		for (; uiLastItemPos < uiNumberOfItems; ++uiLastItemPos)
		{
			if (pWorldItems[uiLastItemPos].fExists == FALSE)
			{
				//We have found a free spot, break
				break;
			}
		}

		if (uiLastItemPos == (uiNumberOfItems))
		{
			const auto neededAmount = uiNumberOfItemsToAdd - uiLoop;
			uiNumberOfItems += neededAmount;
			pWorldItems.resize(uiNumberOfItems);
		}

		pWorldItems[uiLastItemPos].fExists = TRUE;
		pWorldItems[uiLastItemPos].sGridNo = pWorldItem[uiLoop].sGridNo;
		pWorldItems[uiLastItemPos].ubLevel = pWorldItem[uiLoop].ubLevel;
		pWorldItems[uiLastItemPos].usFlags = pWorldItem[uiLoop].usFlags;
		pWorldItems[uiLastItemPos].bVisible = pWorldItem[uiLoop].bVisible;
		pWorldItems[uiLastItemPos].bRenderZHeightAboveLevel = pWorldItem[uiLoop].bRenderZHeightAboveLevel;

		//Check		
		if (TileIsOutOfBounds(pWorldItem[uiLoop].sGridNo) && !(pWorldItems[uiLastItemPos].usFlags & WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT))
		{
			pWorldItems[uiLastItemPos].usFlags |= WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT;

			// Display warning.....
			ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Error: Trying to add item ( %d: %s ) to invalid gridno in unloaded sector. Please Report.", pWorldItems[uiLoop].object.usItem, ItemNames[pWorldItems[uiLoop].object.usItem]);
		}


		pWorldItems[uiLastItemPos].object = pWorldItem[uiLoop].object;
	}

	UpdateWorldItems(sMapX, sMapY, bMapZ, uiNumberOfItems, pWorldItems);
	return(TRUE);
}


BOOLEAN AddItemsToUnLoadedSector(INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT32 sGridNo, UINT32 uiNumberOfItemsToAdd, OBJECTTYPE* pObject, UINT8 ubLevel, UINT16 usFlags, INT8 bRenderZHeightAboveLevel, INT8 bVisible, BOOLEAN fReplaceEntireFile)
{
	if (uiNumberOfItemsToAdd == 0 && fReplaceEntireFile == FALSE)
	{
		//Moa: nothing to do, so get out of here!
		return(TRUE);
	}

	std::vector<WORLDITEM> pWorldItems;
	UINT32	uiNumberOfItems = 0;
	UINT32	cnt;
	UINT32	uiLoop1 = 0;

	const auto i = FindWorldItemSector(sMapX, sMapY, bMapZ);
	if (i == -1)
	{
		// Can't find world item sector, add it
		uiNumberOfItems = uiNumberOfItemsToAdd;
		pWorldItems.resize(uiNumberOfItems);
	}
	else
	{
		uiNumberOfItems = gAllWorldItems.NumItems[i];
		pWorldItems = gAllWorldItems.Items[i];
	}

	if (fReplaceEntireFile)
	{
		//first loop through and mark all entries that they dont exists
		for (cnt = 0; cnt < uiNumberOfItems; cnt++)
		{
			pWorldItems[cnt].fExists = FALSE;
		}
	}

	UINT16 uiLastFoundSpot = 0;
	//loop through all the objects to add
	for (uiLoop1 = 0; uiLoop1 < uiNumberOfItemsToAdd; uiLoop1++)
	{
		//Loop through the array to see if there is a free spot to add an item to it
		for (cnt = uiLastFoundSpot; cnt < uiNumberOfItems; cnt++)
		{
			if (pWorldItems[cnt].fExists == FALSE)
			{
				// anv: remember first found free spot to not loop through entire inventory again for next added items
				uiLastFoundSpot = cnt;
				//We have found a free spot, break
				break;
			}
		}

		if (cnt == (uiNumberOfItems))
		{
			const auto neededAmount = uiNumberOfItemsToAdd - uiLoop1;
			uiNumberOfItems += neededAmount;
			pWorldItems.resize(uiNumberOfItems);
		}

		pWorldItems[cnt].fExists = TRUE;
		pWorldItems[cnt].sGridNo = sGridNo;
		pWorldItems[cnt].ubLevel = ubLevel;
		pWorldItems[cnt].usFlags = usFlags;
		pWorldItems[cnt].bVisible = bVisible;
		pWorldItems[cnt].bRenderZHeightAboveLevel = bRenderZHeightAboveLevel;


		//Check		
		if (TileIsOutOfBounds(sGridNo) && !(pWorldItems[cnt].usFlags & WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT))
		{
			pWorldItems[cnt].usFlags |= WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT;

			// Display warning.....
			ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Error: Trying to add item ( %d: %s ) to invalid gridno in unloaded sector. Please Report.", pWorldItems[cnt].object.usItem, ItemNames[pWorldItems[cnt].object.usItem]);
		}


		pWorldItems[cnt].object = pObject[uiLoop1];

		if ((*pObject)[uiLoop1]->data.sObjectFlag & TAKEN_BY_MILITIA_TABOO_GREEN)
		{
			(*pObject)[uiLoop1]->data.sObjectFlag &= ~TAKEN_BY_MILITIA_TABOO_GREEN;
			pWorldItems[cnt].usFlags |= WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN;
		}
		if ((*pObject)[uiLoop1]->data.sObjectFlag & TAKEN_BY_MILITIA_TABOO_BLUE)
		{
			(*pObject)[uiLoop1]->data.sObjectFlag &= ~TAKEN_BY_MILITIA_TABOO_BLUE;
			pWorldItems[cnt].usFlags |= WORLD_ITEM_TABOO_FOR_MILITIA_EQ_BLUE;
		}
	}

	UpdateWorldItems(sMapX, sMapY, bMapZ, uiNumberOfItems, pWorldItems);
	return(TRUE);
}


extern BOOLEAN gfInMeanwhile;
extern BOOLEAN EnableModifiedFileSetCache(BOOLEAN value);

BOOLEAN SaveCurrentSectorsInformationToTempItemFile( )
{
	BOOLEAN fShouldBeInMeanwhile = FALSE;
	if( gfWasInMeanwhile )
	{ //Don't save a temp file for the meanwhile scene map.
		gfWasInMeanwhile = FALSE;
		return TRUE;
	}
#ifdef JA2UB
//Ja25v No meanwhiles
#else
	else if( AreInMeanwhile() )
	{
		gfInMeanwhile = FALSE;
		fShouldBeInMeanwhile = TRUE;
	}
#endif
	//If we havent been to tactical yet
	if( ( gWorldSectorX == 0 ) && ( gWorldSectorY == 0 ) )
	{
		return( TRUE );
	}

	BOOLEAN cacheResetValue = EnableModifiedFileSetCache(TRUE);

	//Save the Blood, smell and the revealed status for map elements
	SaveBloodSmellAndRevealedStatesFromMapToTempFile();

	// sevenfm
	SaveMineFlagFromMapToTempFile();

	// handle all reachable before save
	HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
	UpdateWorldItems(gWorldSectorX, gWorldSectorY, gbWorldSectorZ, guiNumWorldItems, gWorldItems);

	std::vector<ROTTING_CORPSE_DEFINITION> corpsedefvector;

	//Determine how many rotting corpses there are
	for ( INT32 iCount = 0; iCount < giNumRottingCorpse; ++iCount )
	{
		if ( gRottingCorpse[iCount].fActivated )
			corpsedefvector.push_back( gRottingCorpse[iCount].def );
	}

	//Save the rotting corpse array to the temp rotting corpse file
	if( !SaveRottingCorpsesToTempCorpseFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, corpsedefvector ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in SaveRottingCorpsesToTempCorpseFile()" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}

	//save the Doortable array to the temp door map file
	if( !SaveDoorTableToDoorTableTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in SaveDoorTableToDoorTableTempFile()" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}

	//save the 'revealed'status of the tiles
	if( !SaveRevealedStatusArrayToRevealedTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in SaveRevealedStatusArrayToRevealedTempFile()" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}

	//save the door open status to the saved game file
	if( !SaveDoorStatusArrayToDoorStatusTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in SaveDoorStatusArrayToDoorStatusTempFile()" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}

	//Save the enemies to the temp file
	if( !NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, TRUE, FALSE ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in NewWayOfSavingEnemyAndCivliansToTempFile( Enemy, Creature Team )" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}

	//Save the civilian info to the temp file
	if( !NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE, FALSE ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in NewWayOfSavingEnemyAndCivliansToTempFile( Civ Team )" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}

	//Save the smoke effects info to the temp file
	if( !SaveSmokeEffectsToMapTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in SaveSmokeEffectsToMapTempFile" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}

	//Save the smoke effects info to the temp file
	if( !SaveLightEffectsToMapTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile:  failed in SaveLightEffectsToMapTempFile" ) );
		EnableModifiedFileSetCache(cacheResetValue);
		return( FALSE );
	}


//ttt

	//Save any other info here


	//Save certain information from the NPC's soldier structure to the Merc structure
	SaveNPCInformationToProfileStruct( );

	//Save the time the player was last in the sector
	SetLastTimePlayerWasInSector();

	EnableModifiedFileSetCache(cacheResetValue);

#ifdef JA2UB
//Ja25 no meanwhile
#else
	if( fShouldBeInMeanwhile )
	{
		gfInMeanwhile = TRUE;
	}
#endif
	return( TRUE );
}


void HandleAllReachAbleItemsInTheSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
	// find out which items in the list are reachable
	UINT32 uiCounter = 0;
	UINT8	ubDir, ubMovementCost;
	BOOLEAN fReachable = FALSE;
	INT32 sGridNo = NOWHERE, sGridNo2 = NOWHERE;
	INT32	sNewLoc;

	SOLDIERTYPE * pSoldier;
	BOOLEAN	fSecondary = FALSE;

	if ( guiNumWorldItems == 0 )
	{
		return;
	}

	if ( gMapInformation.sCenterGridNo != -1 )
	{
		sGridNo = gMapInformation.sCenterGridNo;
	}
	else if ( gMapInformation.sNorthGridNo != -1 )
	{
		// use any!
		sGridNo = gMapInformation.sNorthGridNo;
	}
	else if ( gMapInformation.sEastGridNo != -1 )
	{
		// use any!
		sGridNo = gMapInformation.sEastGridNo;
	}
	else if ( gMapInformation.sSouthGridNo != -1 )
	{
		// use any!
		sGridNo = gMapInformation.sSouthGridNo;
	}
	else if ( gMapInformation.sWestGridNo != -1 )
	{
		// use any!
		sGridNo = gMapInformation.sWestGridNo;
	}
	else
	{
		AssertMsg( 0, String( "Map %c%d_b%d does not have any entry points!", 'A' + gWorldSectorY - 1, gWorldSectorX, gbWorldSectorZ ) );
		return;
	}

	if ( gMapInformation.sIsolatedGridNo != -1 )
	{
		sGridNo2 = gMapInformation.sIsolatedGridNo;

		for( uiCounter = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; uiCounter <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++uiCounter )
		{
			pSoldier = MercPtrs[ uiCounter ];
			if ( pSoldier && pSoldier->bActive && pSoldier->stats.bLife > 0 && pSoldier->sSectorX == sSectorX && pSoldier->sSectorY == sSectorY && pSoldier->bSectorZ == bSectorZ )
			{
				if ( FindBestPath( pSoldier, sGridNo2, pSoldier->pathing.bLevel, WALKING, NO_COPYROUTE, 0 ) )
				{
					fSecondary = TRUE;
					break;
				}
			}
		}

		if ( !fSecondary )
		{
			sGridNo2 = NOWHERE;
		}
	}

	GlobalItemsReachableTest( sGridNo, sGridNo2 );

	for( uiCounter = 0; uiCounter < guiNumWorldItems; ++uiCounter )
	{
		// reset reachablity
		fReachable = FALSE;

		// item doesn't exist, ignore it
		if( gWorldItems[ uiCounter ].fExists == FALSE )
		{
			continue;
		}

		// if the item is trapped then flag it as unreachable, period
		if ( gWorldItems[ uiCounter ].object[0]->data.bTrap > 0 )
		{
			fReachable = FALSE;
		}
		else if ( ItemTypeExistsAtLocation( gWorldItems[ uiCounter ].sGridNo, OWNERSHIP, gWorldItems[ uiCounter ].ubLevel, NULL ) )
		{
			fReachable = FALSE;
		}
		else if ( gWorldItems[ uiCounter ].object.usItem == CHALICE )
		{
			fReachable = FALSE;
		}
		else if ( gpWorldLevelData[ gWorldItems[ uiCounter ].sGridNo ].uiFlags & MAPELEMENT_REACHABLE )
		{
			// the gridno itself is reachable so the item is reachable
			fReachable = TRUE;
		}
		else if ( gWorldItems[ uiCounter ].ubLevel > 0 )
		{
			// items on roofs are always reachable
			fReachable = TRUE;
		}
		else
		{
			// check the 4 grids around the item, if any is reachable...then the item is reachable
			for ( ubDir = 0; ubDir < NUM_WORLD_DIRECTIONS; ubDir += 2 )
			{
				sNewLoc = NewGridNo( gWorldItems[ uiCounter ].sGridNo, DirectionInc( ubDir ) );
				if ( sNewLoc != gWorldItems[ uiCounter ].sGridNo )
				{
					// then it's a valid gridno, so test it
					// requires non-wall movement cost from one location to the other!
					if ( gpWorldLevelData[ sNewLoc ].uiFlags & MAPELEMENT_REACHABLE )
					{
 						ubMovementCost = gubWorldMovementCosts[ gWorldItems[ uiCounter ].sGridNo ][ gOppositeDirection[ ubDir ] ][ 0 ];
						// if we find a door movement cost, if the door is open the gridno should be accessible itself
						if ( ubMovementCost != TRAVELCOST_DOOR && ubMovementCost != TRAVELCOST_WALL )
						{
							fReachable = TRUE;
							break;
						}
					}
				}
			}
		}

		if( fReachable )
		{
			gWorldItems[ uiCounter ].usFlags |= WORLD_ITEM_REACHABLE;
		}
		else
		{
			gWorldItems[ uiCounter ].usFlags &= ~( WORLD_ITEM_REACHABLE );
		}
	}
}


BOOLEAN LoadCurrentSectorsInformationFromTempItemsFile()
{
	BOOLEAN fUsedTempFile = FALSE;

	//
	// Load in the sectors ITems
	//
#ifdef JA2UB
//Ja25v no meanwhiles
#else
	if( AreInMeanwhile() )
	{ //There will never be a temp file for the meanwhile scene, so return TRUE.  However,
		//set a flag to not save it either!
		gfWasInMeanwhile = TRUE;

		// OK  - this is true except for interrotations - we need that item temp file to be
		// processed!
		if ( GetMeanwhileID() == INTERROGATION )
		{
			//We no longer use item temp files during gameplay, so check for the sector in gAllWorldItems
			if (SectorIsInWorldItems(gWorldSectorX, gWorldSectorY, gbWorldSectorZ))
			{
				if (!LoadAndAddWorldItemsFromTempFile(gWorldSectorX, gWorldSectorY, gbWorldSectorZ))
					return(FALSE);
			}
			gfWasInMeanwhile = FALSE;
		}
		return TRUE;
	}
#endif
	//if we are in an above ground sector

	//If there is a map modifications file, load the data from the temp file
	if ( DoesTempFileExistsForMap( SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		fUsedTempFile = TRUE;
		if ( !LoadAllMapChangesFromMapTempFileAndApplyThem() )
			return( FALSE );
	}

	//We no longer use item temp files during gameplay, so check for the sector in gAllWorldItems
	if (SectorIsInWorldItems(gWorldSectorX, gWorldSectorY, gbWorldSectorZ))
	{
		if (!LoadAndAddWorldItemsFromTempFile(gWorldSectorX, gWorldSectorY, gbWorldSectorZ))
			return(FALSE);

	}

	//If there is a rotting corpse temp file, load the data from the temp file
	if( DoesTempFileExistsForMap( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		fUsedTempFile = TRUE;
		if( !LoadRottingCorpsesFromTempCorpseFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
			return( FALSE );
	}

	//if there is a door table temp file, load the data from the temp file
	if( DoesTempFileExistsForMap( SF_DOOR_TABLE_TEMP_FILES_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		fUsedTempFile = TRUE;
		if( !LoadDoorTableFromDoorTableTempFile( ) )
			return( FALSE );
	}

	//if there is a revealed status temp file, load the data from the temp file
	if( DoesTempFileExistsForMap( SF_REVEALED_STATUS_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		fUsedTempFile = TRUE;
		if( !LoadRevealedStatusArrayFromRevealedTempFile( ) )
			return( FALSE );
	}

	//if there is a door status temp file, load the data from the temp file
	if( DoesTempFileExistsForMap( SF_DOOR_STATUS_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		fUsedTempFile = TRUE;
		if( !LoadDoorStatusArrayFromDoorStatusTempFile( ) )
			return( FALSE );
	}


	//if the save is an older version, use the old way of loading it up
	if( guiCurrentSaveGameVersion < 57 )
	{
		if( DoesTempFileExistsForMap( SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
		{
			fUsedTempFile = TRUE;
			if( !LoadEnemySoldiersFromTempFile( ) )
				return( FALSE );
		}
	}

	//else use the new way of loading the enemy and civilian placements
	else
	{
		if( DoesTempFileExistsForMap( SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
		{
			fUsedTempFile = TRUE;
			if( !NewWayOfLoadingEnemySoldiersFromTempFile( ) )
				return( FALSE );
		}

		if( DoesTempFileExistsForMap( SF_CIV_PRESERVED_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
		{
			fUsedTempFile = TRUE;
			if( !NewWayOfLoadingCiviliansFromTempFile( ) )
				return( FALSE );
		}
	}

	if( DoesTempFileExistsForMap( SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		fUsedTempFile = TRUE;
		if( !LoadSmokeEffectsFromMapTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
			return( FALSE );
	}

	if( DoesTempFileExistsForMap( SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
	{
		fUsedTempFile = TRUE;
		if( !LoadLightEffectsFromMapTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
			return( FALSE );
	}

//ttt

	// Check to see if any npc are in this sector, if so load up some saved data for them
	LoadNPCInformationFromProfileStruct();

	//if we are loading a saved game
//	if( gTacticalStatus.uiFlags & LOADING_SAVED_GAME )
	{
		//Init the world since we have modified the map
		InitLoadedWorld();
	}


	// Get the last time the player was in the sector
	guiTimeCurrentSectorWasLastLoaded = GetLastTimePlayerWasInSector();

	if( fUsedTempFile )
	{
//		ValidateSoldierInitLinks( 3 );
	}


	StripEnemyDetailedPlacementsIfSectorWasPlayerLiberated();

	return( TRUE );
}


void SetLastTimePlayerWasInSector()
{
	if( !gbWorldSectorZ )
		SectorInfo[ SECTOR( gWorldSectorX,gWorldSectorY) ].uiTimeCurrentSectorWasLastLoaded = GetWorldTotalMin();
	else if( gbWorldSectorZ > 0 )
	{
		UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead;

		pTempNode = gpUndergroundSectorInfoHead;

		//loop through and look for the right underground sector
		while( pTempNode )
		{
			if( ( pTempNode->ubSectorX == gWorldSectorX ) &&
					( pTempNode->ubSectorY == gWorldSectorY ) &&
					( pTempNode->ubSectorZ == gbWorldSectorZ ) )
			{
				//set the flag indicating that ther is a temp item file exists for the sector
				pTempNode->uiTimeCurrentSectorWasLastLoaded = GetWorldTotalMin();
				return;	//break out
			}
			pTempNode = pTempNode->next;
		}
		#ifdef JA2TESTVERSION
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Failed to Set the 'uiTimeCurrentSectorWasLastLoaded' for an underground sector" );
		#endif
	}
}

// Flugente: set last time sector was visited
void SetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ)
{
	if( !sMapZ )
		SectorInfo[ SECTOR( sMapX,sMapY) ].uiTimeCurrentSectorWasLastLoaded = GetWorldTotalMin();
	else if( sMapZ > 0 )
	{
		UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead;

		pTempNode = gpUndergroundSectorInfoHead;

		//loop through and look for the right underground sector
		while( pTempNode )
		{
			if( ( pTempNode->ubSectorX == sMapX ) &&
					( pTempNode->ubSectorY == sMapY ) &&
					( pTempNode->ubSectorZ == sMapZ ) )
			{
				//set the flag indicating that ther is a temp item file exists for the sector
				pTempNode->uiTimeCurrentSectorWasLastLoaded = GetWorldTotalMin();
				return;	//break out
			}
			pTempNode = pTempNode->next;
		}
		#ifdef JA2TESTVERSION
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Failed to Set the 'uiTimeCurrentSectorWasLastLoaded' for an underground sector" );
		#endif
	}
}


UINT32 GetLastTimePlayerWasInSector()
{
	if( !gbWorldSectorZ )
		return( SectorInfo[ SECTOR( gWorldSectorX,gWorldSectorY) ].uiTimeCurrentSectorWasLastLoaded );
	else if( gbWorldSectorZ > 0 )
	{
		UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead;

		pTempNode = gpUndergroundSectorInfoHead;

		//loop through and look for the right underground sector
		while( pTempNode )
		{
			if( ( pTempNode->ubSectorX == gWorldSectorX ) &&
					( pTempNode->ubSectorY == gWorldSectorY ) &&
					( pTempNode->ubSectorZ == gbWorldSectorZ ) )
			{
				//set the flag indicating that ther is a temp item file exists for the sector
				return( pTempNode->uiTimeCurrentSectorWasLastLoaded );
			}
			pTempNode = pTempNode->next;
		}

		#ifdef JA2TESTVERSION
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Failed to Get the 'uiTimeCurrentSectorWasLastLoaded' from an underground sector" );
		#endif

		return( 0 );
	}
	return( 0 );
}

// Flugente: get time for another sector
UINT32 GetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ)
{
	if( !sMapZ )
		return( SectorInfo[ SECTOR( sMapX,sMapY) ].uiTimeCurrentSectorWasLastLoaded );
	else if( sMapZ > 0 )
	{
		UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead;

		pTempNode = gpUndergroundSectorInfoHead;

		//loop through and look for the right underground sector
		while( pTempNode )
		{
			if( ( pTempNode->ubSectorX == sMapX ) &&
					( pTempNode->ubSectorY == sMapY ) &&
					( pTempNode->ubSectorZ == sMapZ ) )
			{
				//set the flag indicating that ther is a temp item file exists for the sector
				return( pTempNode->uiTimeCurrentSectorWasLastLoaded );
			}
			pTempNode = pTempNode->next;
		}

		#ifdef JA2TESTVERSION
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Failed to Get the 'uiTimeCurrentSectorWasLastLoaded' from an underground sector" );
		#endif

		return( 0 );
	}
	return( 0 );
}




BOOLEAN LoadAndAddWorldItemsFromTempFile(INT16 sMapX, INT16 sMapY, INT8 bMapZ)
{
	UINT32	uiNumberOfItems = 0;
	std::vector<WORLDITEM> pWorldItems;

	//Get the number of items from the file
	const auto i = FindWorldItemSector(sMapX, sMapY, bMapZ);
	if (i == -1)
	{
		//Error getting the numbers of the items from the sector. Create placeholder items.
		//This is what the original code did
		uiNumberOfItems = 10;
		pWorldItems.resize(uiNumberOfItems);
	}
	else
	{
		uiNumberOfItems = gAllWorldItems.NumItems[i];
		pWorldItems= gAllWorldItems.Items[i];
	}

	if (uiNumberOfItems == 0)
	{
		//if there are no items in the temp, the player might have cleared all of them out, check to see
		//If we have already been to the sector
		if (GetSectorFlagStatus(sMapX, sMapY, bMapZ, SF_ALREADY_LOADED))
		{
			//
			//Completly replace the current sectors item table because all the items SHOULD be in the temp file!!
			//

			//Destroy the current sectors item table
			TrashWorldItems();
		}

		//there are no items in the file
		return(TRUE);
	}


	//If we have already been to the sector
	if (GetSectorFlagStatus(sMapX, sMapY, bMapZ, SF_ALREADY_LOADED))
	{
		//
		//Completly replace the current sectors item table because all the items SHOULD be in the temp file!!
		//

		//Destroy the current sectors item table
		TrashWorldItems();

		//Add each item to the pool, handle below, outside of the if
	}

	//
	//Append the items in the file with to the current sectors item table
	//

	//Loop through all the items loaded from the file
	INT32 sNewGridNo;
	for (UINT32 cnt = 0; cnt < uiNumberOfItems; cnt++)
	{
		//If the item in the array is valid
		if (pWorldItems[cnt].fExists)
		{
			//Check the flags to see if we have to find a gridno to place the items at
			if (pWorldItems[cnt].usFlags & WOLRD_ITEM_FIND_SWEETSPOT_FROM_GRIDNO)
			{
				sNewGridNo = FindNearestAvailableGridNoForItem(pWorldItems[cnt].sGridNo, 5);

				if (TileIsOutOfBounds(sNewGridNo))
					sNewGridNo = FindNearestAvailableGridNoForItem(pWorldItems[cnt].sGridNo, 15);

				if (!TileIsOutOfBounds(sNewGridNo))
				{
					pWorldItems[cnt].sGridNo = sNewGridNo;
				}
			}

			//If the item has an invalid gridno, use the maps entry point
			if (pWorldItems[cnt].usFlags & WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT)
			{
				pWorldItems[cnt].sGridNo = gMapInformation.sCenterGridNo;

				// if we move the item, recalculate the height
				pWorldItems[cnt].bRenderZHeightAboveLevel = -1;
			}

			//add the item to the world
			AddItemToPool(pWorldItems[cnt].sGridNo, &pWorldItems[cnt].object, pWorldItems[cnt].bVisible, pWorldItems[cnt].ubLevel, pWorldItems[cnt].usFlags, pWorldItems[cnt].bRenderZHeightAboveLevel, pWorldItems[cnt].soldierID);
		}
	}

	return(TRUE);
}



BOOLEAN AddTempFileToSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	CHAR8		zMapName[ 128 ];

	GetMapTempFileName( uiType, zMapName, sMapX, sMapY, bMapZ );

	//Save the map temp file to the saved game file
	if( !SaveFilesToSavedGame( zMapName, hFile ) )
		return( FALSE );

	return( TRUE );
}



BOOLEAN RetrieveTempFileFromSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	CHAR8		zMapName[ 128 ];

	GetMapTempFileName( uiType, zMapName, sMapX, sMapY, bMapZ );

	//Load the map temp file from the saved game file
 	if( !LoadFilesFromSavedGame( zMapName, hFile ) )
		return( FALSE );

	return( TRUE );
}



//Deletes the Temp map Directory
BOOLEAN InitTacticalSave( BOOLEAN fCreateTempDir )
{
#ifndef USE_VFS
	UINT32	uiRetVal;

	//If the Map Temp directory exists, removes the temp files
	uiRetVal = FileGetAttributes( MAPS_DIR );
	if( uiRetVal != 0xFFFFFFFF )
	{
		if( uiRetVal & FILE_ATTRIBUTES_DIRECTORY )
		{
			//Erase the directory
			if( !EraseDirectory( MAPS_DIR ) )
			{
				//error erasing the temporary maps directory
			}
		}
	}
	else
	{
		if( !MakeFileManDirectory( MAPS_DIR ) )
		{
			//Erro creating the temp map directory
			AssertMsg( 0, "Error creating the Temp Directory.");
		}
	}
#else
	EraseDirectory( MAPS_DIR );
#endif
	if( fCreateTempDir )
	{
		//Create the initial temp file for the Npc Quote Info
		InitTempNpcQuoteInfoForNPCFromTempFile();
	}
 	return( TRUE );
}


BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, std::vector<ROTTING_CORPSE_DEFINITION> aCorpseDefVector )
{
	HWFILE	hFile;
	UINT32	uiNumBytesWritten=0;
	CHAR8	zMapName[ 128 ];
	
	// if we have no corpses at all, we have nothing to write - erase the 'corpse file exists flag', the next time we add a corpse, a new file will be created
	if ( aCorpseDefVector.empty() )
	{
		ReSetSectorFlag( sMapX, sMapY, bMapZ, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS );

		return TRUE;
	}

	GetMapTempFileName( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
	
	//Open the file for writing, Create it if it doesnt exist
	hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
	if( hFile == 0 )
	{
		//Error opening map modification file
		return( FALSE );
	}
	
	UINT32 uiNumberOfCorpses = aCorpseDefVector.size();
	
	//Save the number of the Rotting Corpses array table
	FileWrite( hFile, &uiNumberOfCorpses, sizeof( UINT32 ), &uiNumBytesWritten );
	if( uiNumBytesWritten != sizeof( UINT32 ) )
	{
		//Error Writing size of array to disk
		FileClose( hFile );
		return( FALSE );
	}

	//Loop through all the carcases in the array and save the active ones
	for( std::vector<ROTTING_CORPSE_DEFINITION>::iterator it = aCorpseDefVector.begin(); it != aCorpseDefVector.end(); ++it )
	{
		//Save the RottingCorpse info array
		FileWrite( hFile, &(*it), sizeof( ROTTING_CORPSE_DEFINITION ), &uiNumBytesWritten );
		if ( uiNumBytesWritten != sizeof( ROTTING_CORPSE_DEFINITION ) )
		{
			//Error Writing size of array to disk
			FileClose( hFile );
			return( FALSE );
		}
	}

	FileClose( hFile );

	// Set the flag indicating that there is a rotting corpse Temp File
	SetSectorFlag( sMapX, sMapY, bMapZ, SF_ROTTING_CORPSE_TEMP_FILE_EXISTS );

	return( TRUE );
}

BOOLEAN DeleteTempItemMapFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	CHAR8		zMapName[ 128 ];
	GetMapTempFileName( SF_ITEM_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );

	//Check to see if the file exists
	if( !FileExists( zMapName ) )
	{
		//If the file doesnt exists, its no problem.
		return( TRUE );
	}
	FileDelete(zMapName);
	
	// the sector info flag being reset
	ReSetSectorFlag( sMapX, sMapY, bMapZ, SF_ITEM_TEMP_FILE_EXISTS );
	return( TRUE );
}


BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	HWFILE	hFile;
	UINT32	uiNumBytesRead=0;
	CHAR8		zMapName[ 128 ];
	UINT32	uiNumberOfCorpses=0;
	UINT32		cnt;
	ROTTING_CORPSE_DEFINITION		def;
	INT8                        bTownId;
	
	//Delete the existing rotting corpse array
	RemoveCorpses( );

	GetMapTempFileName( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );
	
	//Check to see if the file exists
	if( !FileExists( zMapName ) )
	{
		//If the file doesnt exists, its no problem.
		return( TRUE );
	}

	//Open the file for reading
	hFile = FileOpen( zMapName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
	if( hFile == 0 )
	{
		//Error opening map modification file,
		return( FALSE );
	}

	// Load the number of Rotting corpses
	FileRead( hFile, &uiNumberOfCorpses, sizeof( UINT32 ), &uiNumBytesRead );
	if( uiNumBytesRead != sizeof( UINT32 ) )
	{
		//Error Writing size of array to disk
		FileClose( hFile );
		return( FALSE );
	}
	
	// WANNE: If we get wrong data (very high value) from the temp file, we assume we have wrong value and therefore set corpses to 0 which will not crash the game!
	if (uiNumberOfCorpses > 10000)
		uiNumberOfCorpses = 0;

	// Get town ID for use later....
	bTownId = GetTownIdForSector( gWorldSectorX, gWorldSectorY );

	for( cnt=0; cnt<uiNumberOfCorpses; ++cnt )
	{
		// Load the Rotting corpses info
		FileRead( hFile, &def, sizeof( ROTTING_CORPSE_DEFINITION ), &uiNumBytesRead );
		if( uiNumBytesRead != sizeof( ROTTING_CORPSE_DEFINITION ) )
		{
			//Error Writing size of array to disk
			FileClose( hFile );
			return( FALSE );
		}
		
		//Check the flags to see if we have to find a gridno to place the rotting corpses at
		if( def.usFlags & ROTTING_CORPSE_FIND_SWEETSPOT_FROM_GRIDNO )
		{
			def.sGridNo = FindNearestAvailableGridNoForCorpse( &def, 5 );
			
			if (TileIsOutOfBounds(def.sGridNo))
			{
				def.sGridNo = FindNearestAvailableGridNoForCorpse(&def, 15);
				if (TileIsOutOfBounds(def.sGridNo))
				{
					//shadooow: if we still have invalid gridno skip adding this corpse, it will crash otherwise
					continue;
				}
			}
		}
		else if( def.usFlags & ROTTING_CORPSE_USE_NORTH_ENTRY_POINT )
		{
			def.sGridNo = gMapInformation.sNorthGridNo;
		}
		else if( def.usFlags & ROTTING_CORPSE_USE_SOUTH_ENTRY_POINT )
		{
			def.sGridNo = gMapInformation.sSouthGridNo;
		}
		else if( def.usFlags & ROTTING_CORPSE_USE_EAST_ENTRY_POINT )
		{
			def.sGridNo = gMapInformation.sEastGridNo;
		}
		else if( def.usFlags & ROTTING_CORPSE_USE_WEST_ENTRY_POINT )
		{
			def.sGridNo = gMapInformation.sWestGridNo;
		}
		//Recalculate the dx,dy info
		def.dXPos = CenterX( def.sGridNo );
		def.dYPos = CenterY( def.sGridNo );
		// If not from loading a save....
		if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
		{
			// ATE: Don't place corpses if
			// a ) in a town and b) indoors
			if ( gbWorldSectorZ == 0 )
			{
				if ( bTownId != BLANK_SECTOR )
				{
					// Are we indoors?
					if( FloorAtGridNo( def.sGridNo ) )
					{
						// OK, finally, check TOC vs game time to see if at least some time has passed
						if ( ( GetWorldTotalMin( ) - def.uiTimeOfDeath ) >= 30 )
						{
							continue;
						}
					}
				}
			}
		}

		//add the rotting corpse info
		if( AddRottingCorpse( &def ) == -1 )
		{
			DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Failed to add a corpse to GridNo # %d", def.sGridNo ) );
			/*
			Assert( 0 );
			FileClose( hFile );
			return( FALSE );
			*/
		}
	}

	FileClose( hFile );

	//Check to see if we have to start decomposing the corpses
	HandleRottingCorpses( );

	return( TRUE );
}


void SaveNPCInformationToProfileStruct( )
{
	UINT32								cnt;
	SOLDIERTYPE *					pSoldier;
	MERCPROFILESTRUCT *		pProfile;

	//Loop through the active NPC's

	// Only do this on save now... on traversal this is handled in the strategic code
	if ( !( gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
	{
		return;
	}

	for ( cnt = 0; cnt < guiNumMercSlots; cnt++)
	{
		pSoldier = MercSlots[ cnt ];

		//if it is an active NPC
		if ( pSoldier && pSoldier->ubProfile != NO_PROFILE && pSoldier->bTeam == CIV_TEAM )
		{
			//Save Temp Npc Quote Info array
			SaveTempNpcQuoteInfoForNPCToTempFile( pSoldier->ubProfile );

			pProfile = &(gMercProfiles[ pSoldier->ubProfile ]);

			pProfile->ubQuoteActionID = pSoldier->ubQuoteActionID;
			pProfile->ubQuoteRecord = pSoldier->ubQuoteRecord;

			// if the merc is NOT added due to flag set, return
			if ( pProfile->ubMiscFlags2 & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR )
			{
				continue;
			}

			if ( pProfile->ubMiscFlags3 & PROFILE_MISC_FLAG3_PERMANENT_INSERTION_CODE )
			{
				continue;
			}

			pProfile->fUseProfileInsertionInfo = TRUE;
			pProfile->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
			//if ( gTacticalStatus.uiFlags & LOADING_SAVED_GAME )
			//{
				// if we are saving the game, save the NPC's current location
				pProfile->usStrategicInsertionData = pSoldier->sGridNo;
			//}
			/*
			else
			{
				// If the NPC is moving, save the final destination, else save the current location
				if ( pSoldier->pathing.sFinalDestination != pSoldier->sGridNo )
				{
					pProfile->usStrategicInsertionData = pSoldier->pathing.sFinalDestination;
				}
				else
				{
					pProfile->usStrategicInsertionData = pSoldier->sGridNo;
				}
			}
			*/

		}
	}
}

extern void EVENT_SetSoldierPositionAndMaybeFinalDestAndMaybeNotDestination( SOLDIERTYPE *pSoldier, FLOAT dNewXPos, FLOAT dNewYPos, BOOLEAN fUpdateDest,  BOOLEAN fUpdateFinalDest );

void LoadNPCInformationFromProfileStruct()
{
	//UINT32				cnt;
	//INT16				sSoldierID;
	//SOLDIERTYPE *		pSoldier;

	// CJC: disabled this Dec 21, 1998 as unnecessary (and messing up quote files for recruited/escorted NPCs
	return;
/* commented out the disabled code (jonathanl)
	for ( cnt = FIRST_RPC; cnt < NUM_PROFILES; cnt++ )
	{
		if ( gMercProfiles[ cnt ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
		{
			// don't load
			continue;
		}

		sSoldierID = GetSoldierIDFromAnyMercID( (UINT8)cnt );

		//if the soldier is not loaded, return
		if( sSoldierID == -1 )
			continue;

		//if we cant get a pointer to the soldier, continue
		if( !GetSoldier( &pSoldier, sSoldierID ) )
			continue;

		// load quote info if it exists
		if ( gMercProfiles[ cnt ].ubMiscFlags & PROFILE_MISC_FLAG_TEMP_NPC_QUOTE_DATA_EXISTS )
		{
			LoadTempNpcQuoteInfoForNPCFromTempFile( (UINT8)cnt );
		}

		// load insertion info
		//if ( gMercProfiles[ cnt ] )
		//{
		//	pSoldier->ubInsertionCode = pProfile->ubStrategicInsertionCode;
		//	pSoldier->usInsertionData = pProfile->usStrategicInsertionData;
		//}

	}
*/

/*
	INT16 sX, sY;
	UINT16	cnt;
	SOLDIERTYPE		*pSoldier;
	INT16			sSoldierID;
	INT16		sXPos, sYPos;

	sXPos = sYPos = 0;

	//Loop through the active NPC's
//	cnt = gTacticalStatus.Team[ OUR_TEAM ].bLastID + 1;
	for(cnt=FIRST_RPC; cnt<NUM_PROFILES; cnt++)
	{
		if ( gMercProfiles[ cnt ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
		{
			// don't load
			continue;
		}

		sSoldierID = GetSoldierIDFromAnyMercID( (UINT8)cnt );

		//if the soldier is not loaded, return
		if( sSoldierID == -1 )
			continue;

		//if we cant get a pointer to the soldier, continue
		if( !GetSoldier( &pSoldier, sSoldierID ) )
			continue;

		pSoldier->ubQuoteActionID = gMercProfiles[ cnt ].ubQuoteActionID;
		pSoldier->ubQuoteRecord = gMercProfiles[ cnt ].ubQuoteRecord;

		if( gMercProfiles[ cnt ].fUseProfileInsertionInfo == PROFILE_USE_GRIDNO )
		{
			sX = CenterX( gMercProfiles[ cnt ].sGridNo );
			sY = CenterY( gMercProfiles[ cnt ].sGridNo );

			//Load the Temp Npc Quote Info array

			//if the NPC has been recruited, continue
			if( gMercProfiles[ cnt ].ubMiscFlags & PROFILE_MISC_FLAG_TEMP_NPC_QUOTE_DATA_EXISTS )
				LoadTempNpcQuoteInfoForNPCFromTempFile( (UINT8)cnt );

			//if the NPC has been recruited, continue
			if( gMercProfiles[ cnt ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
				continue;

			//If the NPC was supposed to do something when they reached their target destination
			if( pSoldier->sGridNo == pSoldier->pathing.sFinalDestination )
			{
				if (pSoldier->ubQuoteRecord && pSoldier->ubQuoteActionID == QUOTE_ACTION_ID_CHECKFORDEST )
				{
					//the mercs gridno has to be the same as the final destination
					pSoldier->EVENT_SetSoldierPosition( (FLOAT) sX, (FLOAT) sY );

					NPCReachedDestination( pSoldier, FALSE );
				}
			}

			//If the NPC's gridno is not nowhere, set him to that position
			//if( !TileIsOutOfBounds(gMercProfiles[ cnt ].sGridNo) )
			if(!TileIsOutOfBounds(gMercProfiles[ cnt ].sGridNo))
			{
				if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
				{
					//Set the NPC's destination
					pSoldier->pathing.sDestination = gMercProfiles[ cnt ].sGridNo;
					pSoldier->pathing.sDestXPos = sXPos;
					pSoldier->pathing.sDestYPos = sYPos;

					// We have moved to a diferent sector and are returning to it, therefore the merc should be in the final dest
					EVENT_SetSoldierPositionAndMaybeFinalDestAndMaybeNotDestination( pSoldier, (FLOAT) sX, (FLOAT) sY, FALSE, TRUE );
				}

				//else we are saving
				else
				{

					//Set the NPC's position
	//				pSoldier->EVENT_SetSoldierPosition( (FLOAT) sX, (FLOAT) sY );
					EVENT_SetSoldierPositionAndMaybeFinalDestAndMaybeNotDestination( pSoldier, (FLOAT) sX, (FLOAT) sY, FALSE, FALSE );
				}
			}
		}

		//else if we are NOT to use the gridno, dont use it but reset the flag
		else if( gMercProfiles[ cnt ].fUseProfileInsertionInfo == PROFILE_DONT_USE_GRIDNO )
		{
			gMercProfiles[ cnt ].fUseProfileInsertionInfo = PROFILE_NOT_SET;
		}
	}
*/
}


BOOLEAN DoesTempFileExistsForMap( UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	UNDERGROUND_SECTORINFO *TempNode = gpUndergroundSectorInfoHead;

	if( bMapZ == 0 )
	{
		return( (SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & uiType) ? 1 : 0 );
	}
	else
	{
		while( TempNode )
		{
			if( TempNode->ubSectorX == sMapX && TempNode->ubSectorY == sMapY && TempNode->ubSectorZ == bMapZ )
			{
				return( (TempNode->uiFlags & uiType ) ? 1 : 0 );
			}
			TempNode = TempNode->next;
		}
	}

	return( FALSE );
}


INT16 GetSoldierIDFromAnyMercID(UINT8 ubMercID)
{
	UINT16 cnt;
	UINT8		ubLastTeamID;
	SOLDIERTYPE		*pTeamSoldier;

	cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;

	ubLastTeamID = TOTAL_SOLDIERS;

  // look for all mercs on the same team,
  for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= ubLastTeamID; cnt++,pTeamSoldier++)
	{
		if( pTeamSoldier->bActive )
		{
			if ( pTeamSoldier->ubProfile == ubMercID )
			{
				return( cnt );
			}
		}
	}

	return( -1 );
}




//Initializes the NPC temp array
BOOLEAN InitTempNpcQuoteInfoForNPCFromTempFile()
{
	UINT32	uiNumBytesWritten;
	UINT8	ubCnt;
	TempNPCQuoteInfoSave TempNpcQuote[ NUM_NPC_QUOTE_RECORDS ];
	UINT32	uiSizeOfTempArray = sizeof( TempNPCQuoteInfoSave ) * NUM_NPC_QUOTE_RECORDS;
	UINT16	usCnt1;
	HWFILE	hFile;


	//Open the temp npc file
	hFile = FileOpen( NPC_TEMP_QUOTE_FILE, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
	if( hFile == 0 )
	{
		//Error opening temp npc quote info
		return( FALSE );
	}


	//loop through all the npc accounts and write the temp array to disk
	//for( usCnt1=0; usCnt1< ( GASTON-FIRST_RPC ); usCnt1++)
	//new profiles by Jazz
	for( usCnt1=0; usCnt1< NUM_PROFILES; usCnt1++)
	{

		memset( TempNpcQuote, 0, uiSizeOfTempArray );

		//Loop through and build the temp array to save
		for( ubCnt=0; ubCnt<NUM_NPC_QUOTE_RECORDS; ubCnt++ )
		{
			if( gpNPCQuoteInfoArray[ usCnt1 ] )
			{
				TempNpcQuote[ ubCnt ].usFlags		= gpNPCQuoteInfoArray[ usCnt1 ][ ubCnt ].fFlags;
				TempNpcQuote[ ubCnt ].sRequiredItem = gpNPCQuoteInfoArray[ usCnt1 ][ ubCnt ].sRequiredItem;
				TempNpcQuote[ ubCnt ].usGoToGridNo	= gpNPCQuoteInfoArray[ usCnt1 ][ ubCnt ].usGoToGridNo;
			}
		}

		//Save the array to a temp file
		FileWrite( hFile, TempNpcQuote, uiSizeOfTempArray, &uiNumBytesWritten );
		if( uiNumBytesWritten != uiSizeOfTempArray )
		{
			FileClose( hFile );
			return( FALSE );
		}
	}

	FileClose( hFile );
	return( TRUE );
}



BOOLEAN SaveTempNpcQuoteInfoForNPCToTempFile( UINT8 ubNpcId )
{
	UINT32	uiNumBytesWritten;
	UINT8	ubCnt;
	TempNPCQuoteInfoSave TempNpcQuote[ NUM_NPC_QUOTE_RECORDS ];
	UINT32	uiSizeOfTempArray = sizeof( TempNPCQuoteInfoSave ) * NUM_NPC_QUOTE_RECORDS;
	UINT32	uiSpotInFile = ubNpcId - FIRST_RPC;
	HWFILE	hFile=0;

	//if there are records to save
	if( gpNPCQuoteInfoArray[ ubNpcId ] )
	{

		hFile = FileOpen( NPC_TEMP_QUOTE_FILE, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
		if( hFile == 0 )
		{
			//Error opening temp npc quote info
			return( FALSE );
		}

		memset( TempNpcQuote, 0, uiSizeOfTempArray );

		//Loop through and build the temp array to save
		for( ubCnt=0; ubCnt<NUM_NPC_QUOTE_RECORDS; ubCnt++ )
		{
			TempNpcQuote[ ubCnt ].usFlags		= gpNPCQuoteInfoArray[ ubNpcId ][ ubCnt ].fFlags;
			TempNpcQuote[ ubCnt ].sRequiredItem = gpNPCQuoteInfoArray[ ubNpcId ][ ubCnt ].sRequiredItem;
			TempNpcQuote[ ubCnt ].usGoToGridNo	= gpNPCQuoteInfoArray[ ubNpcId ][ ubCnt ].usGoToGridNo;
		}

		//Seek to the correct spot in the file
		FileSeek( hFile, uiSpotInFile * uiSizeOfTempArray, FILE_SEEK_FROM_START );

		//Save the array to a temp file
		FileWrite( hFile, TempNpcQuote, uiSizeOfTempArray, &uiNumBytesWritten );
		if( uiNumBytesWritten != uiSizeOfTempArray )
		{
			FileClose( hFile );
			return( FALSE );
		}

		//Set the fact that the merc has the temp npc quote data
		gMercProfiles[ ubNpcId ].ubMiscFlags |= PROFILE_MISC_FLAG_TEMP_NPC_QUOTE_DATA_EXISTS;

		FileClose( hFile );
	}


	return( TRUE );
}




BOOLEAN LoadTempNpcQuoteInfoForNPCFromTempFile( UINT8 ubNpcId )
{
	UINT32	uiNumBytesRead;
	UINT8		ubCnt;
	TempNPCQuoteInfoSave TempNpcQuote[ NUM_NPC_QUOTE_RECORDS ];
	UINT32	uiSizeOfTempArray = sizeof( TempNPCQuoteInfoSave ) * NUM_NPC_QUOTE_RECORDS;
	UINT32	uiSpotInFile = ubNpcId - FIRST_RPC;
	HWFILE	hFile;


	//Init the array
	memset( TempNpcQuote, 0, uiSizeOfTempArray );


	//If there isnt already memory allocated, allocate memory to hold the array
	if( gpNPCQuoteInfoArray[ ubNpcId ] == NULL )
	{
		gpNPCQuoteInfoArray[ ubNpcId ] = (NPCQuoteInfo *) MemAlloc( sizeof( NPCQuoteInfo ) * NUM_NPC_QUOTE_RECORDS );
		if( gpNPCQuoteInfoArray[ ubNpcId ] == NULL )
			return( FALSE );
	}


	hFile = FileOpen( NPC_TEMP_QUOTE_FILE, FILE_ACCESS_READ | FILE_OPEN_ALWAYS, FALSE );
	if( hFile == 0 )
	{
		//Error opening temp npc quote info
		return( FALSE );
	}

	//Seek to the correct spot in the file
	FileSeek( hFile, uiSpotInFile * uiSizeOfTempArray, FILE_SEEK_FROM_START );

	//Save the array to a temp file
	FileRead( hFile, TempNpcQuote, uiSizeOfTempArray, &uiNumBytesRead );
	if( uiNumBytesRead != uiSizeOfTempArray )
	{
		FileClose( hFile );
		return( FALSE );
	}



	//Loop through and build the temp array to save
	for( ubCnt=0; ubCnt<NUM_NPC_QUOTE_RECORDS; ubCnt++ )
	{
		gpNPCQuoteInfoArray[ ubNpcId ][ ubCnt ].fFlags				= TempNpcQuote[ ubCnt ].usFlags;
		gpNPCQuoteInfoArray[ ubNpcId ][ ubCnt ].sRequiredItem		= TempNpcQuote[ ubCnt ].sRequiredItem;
		gpNPCQuoteInfoArray[ ubNpcId ][ ubCnt ].usGoToGridNo		= TempNpcQuote[ ubCnt ].usGoToGridNo;
	}

	FileClose( hFile );

	return( TRUE );
}







void ChangeNpcToDifferentSector( UINT8 ubNpcId, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
	if (gMercProfiles[ ubNpcId ].ubMiscFlags2 & PROFILE_MISC_FLAG2_LEFT_COUNTRY)
	{
		// override location, this person is OUTTA here
		sSectorX = 0;
		sSectorY = 0;
		bSectorZ = 0;
	}
	// Carmen no longer traverses out, he is temporarily removed instead

	gMercProfiles[ ubNpcId ].sSectorX = sSectorX;
	gMercProfiles[ ubNpcId ].sSectorY = sSectorY;
	gMercProfiles[ ubNpcId ].bSectorZ = bSectorZ;

	gMercProfiles[ ubNpcId ].fUseProfileInsertionInfo = FALSE;

	/*
	if (!gMercProfiles[ ubNpcId ].ubMiscFlags2 & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR)
	{
		gMercProfiles[ ubNpcId ].fUseProfileInsertionInfo = PROFILE_DONT_USE_GRIDNO;
	}
	*/
}





BOOLEAN AddRottingCorpseToUnloadedSectorsRottingCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, ROTTING_CORPSE_DEFINITION *pRottingCorpseDef )
{
	HWFILE	hFile;
	UINT32	uiNumberOfCorpses;
	CHAR8	zMapName[ 128 ];
	UINT32	uiNumBytesRead;

	ROTTING_CORPSE_DEFINITION	def;
	std::vector<ROTTING_CORPSE_DEFINITION> corpsedefvector;

	// Flugente 2018-08-15: the old method of reading and writing in the same file at the same time is faulty.
	// We instead open the existing file if it exists, take it's contents, and write them with the new corpse to a new file

	GetMapTempFileName( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ );

	if ( DoesTempFileExistsForMap( SF_ROTTING_CORPSE_TEMP_FILE_EXISTS, sMapX, sMapY, bMapZ ) && FileExists( zMapName ) )
	{
		//Open the file for reading
		hFile = FileOpen( zMapName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
		if ( hFile == 0 )
		{
			//Error opening map modification file,
			return( FALSE );
		}

		// Load the number of Rotting corpses
		FileRead( hFile, &uiNumberOfCorpses, sizeof( UINT32 ), &uiNumBytesRead );
		if ( uiNumBytesRead != sizeof( UINT32 ) )
		{
			//Error Writing size of array to disk
			FileClose( hFile );
			return( FALSE );
		}

		// load existing corpses
		for ( UINT32 cnt = 0; cnt < uiNumberOfCorpses; ++cnt )
		{
			// Load the Rotting corpses info
			FileRead( hFile, &def, sizeof( ROTTING_CORPSE_DEFINITION ), &uiNumBytesRead );
			if ( uiNumBytesRead != sizeof( ROTTING_CORPSE_DEFINITION ) )
			{
				//Error Writing size of array to disk
				continue;
			}

			corpsedefvector.push_back( def );
		}

		FileClose( hFile );
	}

	corpsedefvector.push_back( *pRottingCorpseDef );

	// create the file anew
	SaveRottingCorpsesToTempCorpseFile( sMapX, sMapY, bMapZ, corpsedefvector );

	// Flugente: update number of corpses in this sector
	if ( !bMapZ )
	{
		SECTORINFO *pSectorInfo = &( SectorInfo[SECTOR( sMapX, sMapY )] );

		if ( pSectorInfo )
			pSectorInfo->usNumCorpses = corpsedefvector.size();
	}

	return( TRUE );
}



BOOLEAN SetUnderGroundSectorFlag( INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ, UINT32 uiFlagToSet )
{
	UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead;

	pTempNode = gpUndergroundSectorInfoHead;

	//loop through and look for the right underground sector
	while( pTempNode )
	{
		if( ( pTempNode->ubSectorX == (UINT8)sSectorX ) &&
				( pTempNode->ubSectorY == (UINT8)sSectorY ) &&
				( pTempNode->ubSectorZ == ubSectorZ ) )
		{
			//set the flag indicating that ther is a temp item file exists for the sector
			pTempNode->uiFlags |= uiFlagToSet;

			return( TRUE );
		}
		pTempNode = pTempNode->next;
	}

	return( FALSE );
}

BOOLEAN ReSetUnderGroundSectorFlag( INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ, UINT32 uiFlagToSet )
{
	UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead;

	pTempNode = gpUndergroundSectorInfoHead;

	//loop through and look for the right underground sector
	while( pTempNode )
	{
		if( ( pTempNode->ubSectorX == (UINT8)sSectorX ) &&
				( pTempNode->ubSectorY == (UINT8)sSectorY ) &&
				( pTempNode->ubSectorZ == ubSectorZ ) )
		{
			//set the flag indicating that ther is a temp item file exists for the sector
			pTempNode->uiFlags &= ~( uiFlagToSet );

			return( TRUE );
		}
		pTempNode = pTempNode->next;
	}

	return( FALSE );
}

BOOLEAN GetUnderGroundSectorFlagStatus( INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ, UINT32 uiFlagToCheck )
{
	UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead;

	pTempNode = gpUndergroundSectorInfoHead;

	//loop through and look for the right underground sector
	while( pTempNode )
	{
		if( ( pTempNode->ubSectorX == (UINT8)sSectorX ) &&
				( pTempNode->ubSectorY == (UINT8)sSectorY ) &&
				( pTempNode->ubSectorZ == ubSectorZ ) )
		{
			//set the flag indicating that ther is a temp item file exists for the sector
			if( pTempNode->uiFlags & uiFlagToCheck )
				return( TRUE );
			else
				return( FALSE );
		}
		pTempNode = pTempNode->next;
	}
	return( FALSE );
}


BOOLEAN SetSectorFlag( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, UINT32 uiFlagToSet )
{
	if( uiFlagToSet == SF_ALREADY_VISITED )
	{

		// HEADROCK HAM 3.5: This is no longer required at all.
		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

		// HEADROCK HAM 3.4: Externalized. Hidden facilities listed on the facility array will be
		// added to the sector info now, upon the first visit.

		/*for(UINT32 cnt=0; (gFacilityLocations[cnt].uiSectorID >= 0 && gFacilityLocations[cnt].uiSectorID <= 256); cnt++ )
		{
			// Does the current record match the current sector?
			if (gFacilityLocations[cnt].uiSectorID == SECTOR( sMapX, sMapY ))
			{
				// Is the current record set to be revealed?
				if (gFacilityLocations[cnt].fHidden == 1)
				{
					// Reveal the facility.
					SectorInfo[ SECTOR( sMapX, sMapY) ].uiFacilitiesFlags |= (1 << (gFacilityLocations[cnt].uiFacilityType - 1));
				}
			}
		}*/
		

		// HEADROCK HAM 3.4: Externalized.
		/*
		// do certain things when particular sectors are visited
		if ( ( sMapX == TIXA_SECTOR_X ) && ( sMapY == TIXA_SECTOR_Y ) )
		{
			// Tixa prison (not seen until Tixa visited)
			SectorInfo[ SEC_J9 ].uiFacilitiesFlags |= SFCF_PRISON;
		}

		if ( ( sMapX == GUN_RANGE_X ) && ( sMapY == GUN_RANGE_Y ) && ( bMapZ == GUN_RANGE_Z ) )
		{
			// Alma shooting range (not seen until sector visited)
			SectorInfo[ SEC_H13 ].uiFacilitiesFlags |= SFCF_GUN_RANGE;
			SectorInfo[ SEC_H14 ].uiFacilitiesFlags |= SFCF_GUN_RANGE;
			SectorInfo[ SEC_I13 ].uiFacilitiesFlags |= SFCF_GUN_RANGE;
			SectorInfo[ SEC_I14 ].uiFacilitiesFlags |= SFCF_GUN_RANGE;
		}*/

		if ( !GetSectorFlagStatus( sMapX, sMapY, bMapZ, SF_ALREADY_VISITED ) )
		{
			// increment daily counter of sectors visited
			gStrategicStatus.ubNumNewSectorsVisitedToday++;
			if ( gStrategicStatus.ubNumNewSectorsVisitedToday == NEW_SECTORS_EQUAL_TO_ACTIVITY )
			{
				// visited enough to count as an active day
				UpdateLastDayOfPlayerActivity( (UINT16) GetWorldDay() );
			}

			for ( UINT8 i = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; i <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; i++ )
			{
				if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) && MercPtrs[ i ]->ubProfile != NO_PROFILE &&
					MercPtrs[ i ]->sSectorX == sMapX && MercPtrs[ i ]->sSectorY == sMapY && MercPtrs[ i ]->bSectorZ == bMapZ && !MercPtrs[ i ]->flags.fBetweenSectors &&
					MercPtrs[ i ]->bAssignment != IN_TRANSIT && MercPtrs[ i ]->bAssignment != ASSIGNMENT_DEAD )
				{
					gMercProfiles[ MercPtrs[ i ]->ubProfile ].records.usSectorsDiscovered++;
				}
			}
		}
	}

	if( bMapZ == 0 )
		SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags |= uiFlagToSet;
	else
		SetUnderGroundSectorFlag( sMapX, sMapY, bMapZ, uiFlagToSet );

	return( TRUE );
}

BOOLEAN ReSetSectorFlag( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, UINT32 uiFlagToSet )
{
	if( bMapZ == 0 )
		SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags &= ~( uiFlagToSet );
	else
		ReSetUnderGroundSectorFlag( sMapX, sMapY, bMapZ, uiFlagToSet );

	return( TRUE );
}

BOOLEAN GetSectorFlagStatus( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, UINT32 uiFlagToSet )
{
	if( bMapZ == 0 )
		return( (SectorInfo[ SECTOR( sMapX, sMapY ) ].uiFlags & uiFlagToSet ) ? 1 : 0 );
	else
		return( (GetUnderGroundSectorFlagStatus( sMapX, sMapY, bMapZ, uiFlagToSet ) ) ? 1 : 0  );
}

BOOLEAN AddDeadSoldierToUnLoadedSector( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiFlags )
{
	UINT32			uiNumberOfItems;
	std::vector<WORLDITEM> pWorldItems;//dnl ch75 271013
	UINT8				i;
	UINT8				bCount=0;
	UINT16			uiFlagsForWorldItems=0;
	UINT16			usFlagsForRottingCorpse=0;
	ROTTING_CORPSE_DEFINITION		Corpse;
	INT16				sXPos, sYPos;
	UINT32			uiDeathAnim;
	UINT32			uiPossibleDeathAnims[] = {	GENERIC_HIT_DEATH,
																					FALLBACK_HIT_DEATH,
																					PRONE_HIT_DEATH,
																					FLYBACK_HIT_DEATH };
	//setup the flags for the items and the rotting corpses
	if( uiFlags & ADD_DEAD_SOLDIER_USE_GRIDNO )
	{
		uiFlagsForWorldItems		= 0;
		usFlagsForRottingCorpse	= 0;
	}

	else if( uiFlags & ADD_DEAD_SOLDIER_TO_SWEETSPOT )
	{
		uiFlagsForWorldItems		|= WOLRD_ITEM_FIND_SWEETSPOT_FROM_GRIDNO | WORLD_ITEM_REACHABLE;
		usFlagsForRottingCorpse	|= ROTTING_CORPSE_FIND_SWEETSPOT_FROM_GRIDNO;
	}
	else
		AssertMsg( 0, "ERROR!!	Flag not is Switch statement");
	
	//
	//Create an array of objects from the mercs inventory
	//

	//go through and and find out how many items there are
	uiNumberOfItems = 0;
	UINT8 invsize = pSoldier->inv.size();
	for ( i = 0; i < invsize; ++i )
	{
		if( pSoldier->inv[ i ].exists() == true )
		{
			// Flugente: if we don't want items to drop in autoresolve, this is the place to set that
			if ( pSoldier->bTeam != gbPlayerNum && !gGameExternalOptions.fNPCAutoresolveItemDrop )
			{
				// mark it undroppable...
				pSoldier->inv[i].fFlags |= OBJECT_UNDROPPABLE;
			}

			//if the item can be dropped
			if( !( pSoldier->inv[ i ].fFlags & OBJECT_UNDROPPABLE ) || pSoldier->bTeam == gbPlayerNum )
			{
				++uiNumberOfItems;
			}
		}
	}

  // If a robot, don't drop anything...
  if ( AM_A_ROBOT( pSoldier ) )
  {
    uiNumberOfItems = 0;
  }

	//if there are items to add
	if( uiNumberOfItems )
	{
		//allocate memory for the world item array
		pWorldItems.resize(uiNumberOfItems);//dnl ch75 271013

		//loop through all the soldiers items and add them to the world item array
		bCount = 0;
		for ( i = 0; i < invsize; ++i )
		{
			if( pSoldier->inv[ i ].exists() == true )
			{
				//if the item can be dropped
				if( !(pSoldier->inv[ i ].fFlags & OBJECT_UNDROPPABLE) || pSoldier->bTeam == gbPlayerNum )
				{
					ReduceAmmoDroppedByNonPlayerSoldiers( pSoldier, i );

					pWorldItems[ bCount ].fExists = TRUE;
					pWorldItems[ bCount ].sGridNo = sGridNo;
					pWorldItems[ bCount ].ubLevel = (UINT8)pSoldier->pathing.bLevel;
					pWorldItems[ bCount ].usFlags = uiFlagsForWorldItems;
					pWorldItems[ bCount ].bVisible = TRUE;
					pWorldItems[ bCount ].bRenderZHeightAboveLevel = 0;

					if ( Item[pSoldier->inv[i].usItem].damageable ) // Madd: drop crappier items on higher difficulty levels
					{
						// silversurfer: externalized this
						//pSoldier->inv[i][0]->data.objectStatus -= (gGameOptions.ubDifficultyLevel - 1) * Random(20);
						pSoldier->inv[i][0]->data.objectStatus -= Random( zDiffSetting[gGameOptions.ubDifficultyLevel].usLootStatusModifier );
						pSoldier->inv[i][0]->data.objectStatus = max(pSoldier->inv[i][0]->data.objectStatus,1); // never below 1%
					}
					pWorldItems[ bCount ].object = pSoldier->inv[i];
					++bCount;
				}
			}
		}

		//Add the soldiers items to an unloaded sector
		AddWorldItemsToUnLoadedSector( sMapX, sMapY, bMapZ, sGridNo, uiNumberOfItems, pWorldItems, FALSE );

		//CHRISL: Now that we've copied the dead soldiers items to pWorldItems, we need to actually remove the items from the dead soldier.  Otherwise we have
		//	actually duplicated the items and there's a chance that these duplicated items will again find their way to sector.
		for ( i = 0; i < invsize; ++i )
		{
			if( pSoldier->inv[ i ].exists() == true )
			{
				pSoldier->inv[i].initialize();
			}
		}
	}

  DropKeysInKeyRing( pSoldier, sGridNo, pSoldier->pathing.bLevel, 1, FALSE, 0, TRUE );

	//
	//Convert the soldier into a rottng corpse
	//

	memset( &Corpse, 0, sizeof( ROTTING_CORPSE_DEFINITION ) );

	// Setup some values!
	Corpse.ubBodyType							= pSoldier->ubBodyType;
	Corpse.sGridNo								= sGridNo;

	ConvertGridNoToXY( sGridNo, &sXPos, &sYPos );

	Corpse.dXPos									= (FLOAT)( CenterX( sXPos ) );
	Corpse.dYPos									= (FLOAT)( CenterY( sYPos ) );
	Corpse.sHeightAdjustment			= pSoldier->sHeightAdjustment;
	Corpse.bVisible								=	TRUE;

	SET_PALETTEREP_ID ( Corpse.HeadPal,		pSoldier->HeadPal );
	SET_PALETTEREP_ID ( Corpse.VestPal,		pSoldier->VestPal );
	SET_PALETTEREP_ID ( Corpse.SkinPal,		pSoldier->SkinPal );
	SET_PALETTEREP_ID ( Corpse.PantsPal,   pSoldier->PantsPal );

	Corpse.ubDirection	= pSoldier->ubDirection;

	// Set time of death
	Corpse.uiTimeOfDeath = GetWorldTotalMin( );

	//if the dead body shot be the result of a Jfk headshot, set it
	if( uiFlags & ADD_DEAD_SOLDIER__USE_JFK_HEADSHOT_CORPSE )
		uiDeathAnim = JFK_HITDEATH;

	//else chose a random death sequence
	else
		uiDeathAnim = uiPossibleDeathAnims[ Random( 4 ) ];


	// Set type
	Corpse.ubType	= (UINT8)gubAnimSurfaceCorpseID[ pSoldier->ubBodyType][ uiDeathAnim ];

	Corpse.usFlags |= usFlagsForRottingCorpse;

	//Add the rotting corpse info to the sectors unloaded rotting corpse file
	AddRottingCorpseToUnloadedSectorsRottingCorpseFile( sMapX, sMapY, bMapZ, &Corpse);

	return( TRUE );
}

BOOLEAN SaveTempNpcQuoteArrayToSaveGameFile( HWFILE hFile )
{
	return( SaveFilesToSavedGame( NPC_TEMP_QUOTE_FILE, hFile ) );
}

BOOLEAN LoadTempNpcQuoteArrayToSaveGameFile( HWFILE hFile )
{
	return( LoadFilesFromSavedGame( NPC_TEMP_QUOTE_FILE, hFile ) );
}

void TempFileLoadErrorMessageReturnCallback( UINT8 ubRetVal )
{
	gfProgramIsRunning = FALSE;
}

//if you call this function, make sure you return TRUE (if applicable) to make the game
//think it succeeded the load.  This sets up the dialog for the game exit, after the hacker
//message appears.
void InitExitGameDialogBecauseFileHackDetected()
{
	SGPRect CenteringRect= {0, 0, 639, 479 };

	// do message box and return
	giErrorMessageBox = DoMessageBox( MSG_BOX_BASIC_STYLE, pAntiHackerString[ ANTIHACKERSTR_EXITGAME ],
											GAME_SCREEN, MSG_BOX_FLAG_OK, TempFileLoadErrorMessageReturnCallback, &CenteringRect );
}

// CHRISL: New Checksum for LBENODE
UINT32 LBENODEChecksum( LBENODE * pNode )
{
	UINT32	uiChecksum = 1;
	UINT32	uiLoop;

	uiChecksum += (pNode->lbeClass + 1);
	uiChecksum *= (pNode->lbeIndex +1);
	uiChecksum += (pNode->ubID +1);

	UINT32 invsize = pNode->inv.size();
	for ( uiLoop = 0; uiLoop < invsize; ++uiLoop )
	{
		uiChecksum += pNode->inv[ uiLoop ].usItem;
	}

	return( uiChecksum );
}


//UINT8 gubEncryptionArray4[ BASE_NUMBER_OF_ROTATION_ARRAYS * 3 ][ NEW_ROTATION_ARRAY_SIZE ] =
UINT8 * GetRotationArray( void )
{
	// based on guiJA2EncryptionSet
	if ( guiJA2EncryptionSet < BASE_NUMBER_OF_ROTATION_ARRAYS * 6 )
	{
		if ( guiJA2EncryptionSet < BASE_NUMBER_OF_ROTATION_ARRAYS * 3 )
		{
			return( gubEncryptionArray1[ guiJA2EncryptionSet % (BASE_NUMBER_OF_ROTATION_ARRAYS * 3) ]);
		}
		else
		{
			return( gubEncryptionArray2[ guiJA2EncryptionSet % (BASE_NUMBER_OF_ROTATION_ARRAYS * 3) ]);
		}
	}
	else
	{
		if ( guiJA2EncryptionSet < BASE_NUMBER_OF_ROTATION_ARRAYS * 9 )
		{
			return( gubEncryptionArray3[ guiJA2EncryptionSet % (BASE_NUMBER_OF_ROTATION_ARRAYS * 3) ]);
		}
		else
		{
			return( gubEncryptionArray4[ guiJA2EncryptionSet % (BASE_NUMBER_OF_ROTATION_ARRAYS * 3) ]);
		}
	}
}

BOOLEAN NewJA2EncryptedFileRead( HWFILE hFile, PTR pDest, UINT32 uiBytesToRead, UINT32 *puiBytesRead )
{
	UINT32	uiLoop;
	UINT8		ubArrayIndex = 0;
	UINT8		ubLastByte = 0;
	UINT8		ubLastByteForNextLoop;
	BOOLEAN	fRet;
	UINT8 *	pMemBlock;
	UINT8	* pubRotationArray;

	pubRotationArray = GetRotationArray();

	fRet = FileRead( hFile, pDest, uiBytesToRead, puiBytesRead );
	if ( fRet )
	{
		pMemBlock = (UINT8 *)pDest;
		for ( uiLoop = 0; uiLoop < *puiBytesRead; uiLoop++ )
		{
			ubLastByteForNextLoop = pMemBlock[ uiLoop ];
			pMemBlock[ uiLoop ] -= (ubLastByte + pubRotationArray[ ubArrayIndex ]);
			ubArrayIndex++;
			if ( ubArrayIndex >= NEW_ROTATION_ARRAY_SIZE )
			{
				ubArrayIndex = 0;
			}
			ubLastByte = ubLastByteForNextLoop;
		}
	}

	return( fRet );
}


BOOLEAN NewJA2EncryptedFileWrite( HWFILE hFile, PTR pDest, UINT32 uiBytesToWrite, UINT32 *puiBytesWritten )
{
	UINT32	uiLoop;
	UINT8		ubArrayIndex = 0;
	UINT8		ubLastByte = 0;//, ubTemp;
	UINT8 * pMemBlock;
	BOOLEAN	fRet;
	UINT8	* pubRotationArray;

	pMemBlock = (UINT8 *) MemAlloc( uiBytesToWrite );

	if ( !pMemBlock )
	{
		return( FALSE );
	}
	memset( pMemBlock, 0, uiBytesToWrite );

	pubRotationArray = GetRotationArray();

	memcpy( pMemBlock, pDest, uiBytesToWrite );
	for ( uiLoop = 0; uiLoop < uiBytesToWrite; uiLoop++ )
	{
		pMemBlock[ uiLoop ] += ubLastByte + pubRotationArray[ ubArrayIndex ];
		ubArrayIndex++;
		if ( ubArrayIndex >= NEW_ROTATION_ARRAY_SIZE )
		{
			ubArrayIndex = 0;
		}
		ubLastByte = pMemBlock[ uiLoop ];
	}

	fRet = FileWrite( hFile, pMemBlock, uiBytesToWrite, puiBytesWritten );

	MemFree( pMemBlock );

	return( fRet );

}


#define ROTATION_ARRAY_SIZE 46
UINT8 ubRotationArray[46] = { 132, 235, 125, 99, 15, 220, 140, 89, 205, 132, 254, 144, 217, 78, 156, 58, 215, 76, 163, 187, 55, 49, 65, 48, 156, 140, 201, 68, 184, 13, 45, 69, 102, 185, 122, 225, 23, 250, 160, 220, 114, 240, 64, 175, 057, 233 };

BOOLEAN JA2EncryptedFileRead( HWFILE hFile, PTR pDest, UINT32 uiBytesToRead, UINT32 *puiBytesRead )
{
	UINT32	uiLoop;
	UINT8		ubArrayIndex = 0;
	//UINT8		ubLastNonBlank = 0;
	UINT8		ubLastByte = 0;
	UINT8		ubLastByteForNextLoop;
	BOOLEAN	fRet;
	UINT8 *	pMemBlock;

	fRet = FileRead( hFile, pDest, uiBytesToRead, puiBytesRead );
	if ( fRet )
	{
		pMemBlock = (UINT8 *)pDest;
		for ( uiLoop = 0; uiLoop < *puiBytesRead; uiLoop++ )
		{
			ubLastByteForNextLoop = pMemBlock[ uiLoop ];
			pMemBlock[ uiLoop ] -= (ubLastByte + ubRotationArray[ ubArrayIndex ]);
			ubArrayIndex++;
			if ( ubArrayIndex >= ROTATION_ARRAY_SIZE )
			{
				ubArrayIndex = 0;
			}
			ubLastByte = ubLastByteForNextLoop;
		}
	}

	return( fRet );
}


BOOLEAN JA2EncryptedFileWrite( HWFILE hFile, PTR pDest, UINT32 uiBytesToWrite, UINT32 *puiBytesWritten )
{
	UINT32	uiLoop;
	UINT8		ubArrayIndex = 0;
	//UINT8		ubLastNonBlank = 0;
	UINT8		ubLastByte = 0;//, ubTemp;
	UINT8 * pMemBlock;
	BOOLEAN	fRet;

	pMemBlock = (UINT8 *) MemAlloc( uiBytesToWrite );

	if ( !pMemBlock )
	{
		return( FALSE );
	}
	memset( pMemBlock, 0, uiBytesToWrite );


	memcpy( pMemBlock, pDest, uiBytesToWrite );
	for ( uiLoop = 0; uiLoop < uiBytesToWrite; uiLoop++ )
	{
		//ubTemp = pMemBlock[ uiLoop ];
		pMemBlock[ uiLoop ] += ubLastByte + ubRotationArray[ ubArrayIndex ];
		ubArrayIndex++;
		if ( ubArrayIndex >= ROTATION_ARRAY_SIZE )
		{
			ubArrayIndex = 0;
		}
		ubLastByte = pMemBlock[ uiLoop ];
		/*
		if ( pMemBlock[ uiLoop ] )
		{
			// store last non blank
			ubLastNonBlank = pMemBlock[ uiLoop ];

			pMemBlock[ uiLoop ] += ubRotationArray[ ubArrayIndex ];
			ubArrayIndex++;
			if ( ubArrayIndex >= ROTATION_ARRAY_SIZE )
			{
				ubArrayIndex = 0;
			}
		}
		else // zero byte
		{
			pMemBlock[ uiLoop ] = ubLastNonBlank + ubRotationArray[ ubArrayIndex ];
			ubArrayIndex++;
			if ( ubArrayIndex >= ROTATION_ARRAY_SIZE )
			{
				ubArrayIndex = 0;
			}
		}
		*/
	}

	fRet = FileWrite( hFile, pMemBlock, uiBytesToWrite, puiBytesWritten );

	MemFree( pMemBlock );

	return( fRet );

}

void GetMapTempFileName( UINT32 uiType, STR pMapName, INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	CHAR	zTempName[512];

	//Convert the current sector location into a file name
	GetMapFileName( sMapX,sMapY, bMapZ, zTempName, FALSE, FALSE );

	switch( uiType )
	{
		case SF_ITEM_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\i_%s", MAPS_DIR, zTempName);
			break;

		case SF_ROTTING_CORPSE_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\r_%s", MAPS_DIR, zTempName);
			break;

		case SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\m_%s", MAPS_DIR, zTempName);
			break;

		case SF_DOOR_TABLE_TEMP_FILES_EXISTS:
			sprintf( pMapName, "%s\\d_%s", MAPS_DIR, zTempName);
			break;

		case SF_REVEALED_STATUS_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\v_%s", MAPS_DIR, zTempName);
			break;

		case SF_DOOR_STATUS_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\ds_%s", MAPS_DIR, zTempName);
			break;

		case SF_ENEMY_PRESERVED_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\e_%s", MAPS_DIR, zTempName);
			break;

		case SF_CIV_PRESERVED_TEMP_FILE_EXISTS:
			// NB save game version 0 is "saving game"
			if ( (gTacticalStatus.uiFlags & LOADING_SAVED_GAME) && guiCurrentSaveGameVersion != 0 && guiCurrentSaveGameVersion < 78 )
			{
				sprintf( pMapName, "%s\\c_%s", MAPS_DIR, zTempName);
			}
			else
			{
				sprintf( pMapName, "%s\\cc_%s", MAPS_DIR, zTempName);
			}
			break;

		case SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\sm_%s", MAPS_DIR, zTempName);
			break;

		case SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS:
			sprintf( pMapName, "%s\\l_%s", MAPS_DIR, zTempName);
			break;

		default:
			Assert( 0 );
			break;
	}
}

UINT32	GetNumberOfVisibleWorldItemsFromSectorStructureForSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
	UINT32 uiNumberOfItems=0;
	UNDERGROUND_SECTORINFO *pSector=NULL;

	//if the sector is above ground
	if( bMapZ == 0 )
	{
		uiNumberOfItems = SectorInfo[ SECTOR( sMapX, sMapY ) ].uiNumberOfWorldItemsInTempFileThatCanBeSeenByPlayer;
	}
	else
	{
		//find the underground sector
		pSector = FindUnderGroundSector( sMapX, sMapY, bMapZ );
		if( pSector != NULL )
		{
			//get the number of items
			uiNumberOfItems = pSector->uiNumberOfWorldItemsInTempFileThatCanBeSeenByPlayer;
		}
	}

	//if there is a sector loaded
	if( gfWorldLoaded )
	{
		//and it is the sector we are interested in
		if( sMapX == gWorldSectorX && sMapY == gWorldSectorY && bMapZ == gbWorldSectorZ )
		{
			//since items might have been added, update
			uiNumberOfItems = UpdateLoadedSectorsItemInventory( sMapX, sMapY, bMapZ, uiNumberOfItems );
		}
	}


	return( uiNumberOfItems );
}

void	SetNumberOfVisibleWorldItemsInSectorStructureForSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems )
{
	//if the sector is above ground
	if( bMapZ == 0 )
	{
		SectorInfo[SECTOR( sMapX, sMapY )].uiNumberOfWorldItemsInTempFileThatCanBeSeenByPlayer = uiNumberOfItems;
	}
	else
	{
		//find the underground sector
		UNDERGROUND_SECTORINFO* pSector = FindUnderGroundSector( sMapX, sMapY, bMapZ );
		if( pSector != NULL )
		{
			//get the number of items
			pSector->uiNumberOfWorldItemsInTempFileThatCanBeSeenByPlayer = uiNumberOfItems ;
		}
	}
}


UINT32 UpdateLoadedSectorsItemInventory( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems )
{
	UINT32	uiCounter;
	UINT32	uiItemCounter=0;

	if( !gfWorldLoaded )
		return( 0 );

	//loop through all the world items
	for( uiCounter= 0; uiCounter < guiNumWorldItems; uiCounter++ )
	{
		//if the item CAN be visible in mapscreen sector inventory
		if( IsMapScreenWorldItemVisibleInMapInventory( &gWorldItems[ uiCounter ] ) )
		{
			//increment
			uiItemCounter += gWorldItems[ uiCounter ].object.ubNumberOfObjects;
		}
	}

	//if the item count is DIFFERENT
	if( uiItemCounter != uiNumberOfItems )
	{
		//Update the value in the sector info struct
		SetNumberOfVisibleWorldItemsInSectorStructureForSector( sMapX, sMapY, bMapZ, uiItemCounter );
	}

	//return the number of items
	return( uiItemCounter );
}

// We no longer use map item temp files except during loading and saving a game to preserve savegame compatibility.
// LoadWorldItemsFromTempFiles & SaveWorldItemsToTempFiles are used to read and write world items to and from temp files into the global world items struct gAllWorldItems that is used during gameplay
void LoadWorldItemsFromTempFiles(INT16 sMapX, INT16 sMapY, INT8 bMapZ)
{
	UINT32 nItems = 0;
	std::vector<WORLDITEM> Items;

	const BOOLEAN fReturn = GetNumberOfWorldItemsFromTempItemFile(sMapX, sMapY, bMapZ, &(nItems), FALSE);
	if (fReturn == FALSE)
	{
		DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("GetNumberOfWorldItemsFromTempItemFile failed"));
		Assert(fReturn);
	}

	if (nItems > 0)
	{
		Items.resize(nItems);
		LoadWorldItemsFromTempItemFile(sMapX, sMapY, bMapZ, Items);
		UpdateWorldItems(sMapX, sMapY, bMapZ, nItems, Items);
	}
}

void SaveWorldItemsToTempFiles()
{
	PruneWorldItems();
	for (size_t i = 0; i < gAllWorldItems.sectors.size(); i++)
	{
		const auto x = gAllWorldItems.sectors[i].x;
		const auto y = gAllWorldItems.sectors[i].y;
		const auto z = gAllWorldItems.sectors[i].z;
		const auto nItems = gAllWorldItems.NumItems[i];
		auto Items = gAllWorldItems.Items[i];

		SaveWorldItemsToTempItemFile(x, y, (INT8)z, nItems, Items);
	}
}
