diff --git a/Tactical/Map Information.cpp b/Tactical/Map Information.cpp index f7dc9cc8..b3846b83 100644 --- a/Tactical/Map Information.cpp +++ b/Tactical/Map Information.cpp @@ -20,6 +20,7 @@ FLOAT gdMajorMapVersion = MAJOR_MAP_VERSION; BOOLEAN gfWorldLoaded; MAPCREATE_STRUCT gMapInformation; +MAPCREATE_STRUCT gMapInformationAutoResolve; //CHRISL: MINOR_MAP_VERSION information moved to worlddef.h by ADB. We're using these values elsewhere and need them // in the header file diff --git a/Tactical/Map Information.h b/Tactical/Map Information.h index 76d4e36b..1c8b1912 100644 --- a/Tactical/Map Information.h +++ b/Tactical/Map Information.h @@ -57,6 +57,7 @@ public: }; extern MAPCREATE_STRUCT gMapInformation; +extern MAPCREATE_STRUCT gMapInformationAutoResolve; void LoadMapInformation(INT8** hBuffer, FLOAT dMajorMapVersion); void SaveMapInformation(HWFILE hFile, FLOAT dMajorMapVersion, UINT8 ubMinorMapVersion); diff --git a/TileEngine/worlddef.cpp b/TileEngine/worlddef.cpp index 6c7686da..d51f70d8 100644 --- a/TileEngine/worlddef.cpp +++ b/TileEngine/worlddef.cpp @@ -138,7 +138,8 @@ void SaveMapLights( HWFILE hfile ); void LoadMapLights( INT8 **hBuffer ); // Global Variables -MAP_ELEMENT *gpWorldLevelData; +MAP_ELEMENT* gpWorldLevelData; +MAP_ELEMENT *gpWorldLevelDataAutoResolve; INT32 *gpDirtyData; UINT32 gSurfaceMemUsage; //UINT8 gubWorldMovementCosts[ WORLD_MAX ][MAXDIR][2]; @@ -3312,6 +3313,296 @@ BOOLEAN LoadWorld(const STR8 puiFilename, FLOAT* pMajorMapVersion, UINT8* pMinor return(TRUE); } +// A stub LoadWorld function so we can read a sector's tile height values into gpWorldLevelDataAutoResolve[].sHeight and entrypoint gridnos into gMapInformationAutoResolve +// They are needed when placing corpses and dropped items into a random gridno in an unloaded sector when we're finished with autoresolve battle. +BOOLEAN LoadWorldInfoForAutoResolve(const STR8 puiFilename, INT32& iRowSize, INT32& iColSize) +{ + HWFILE hfile; + FLOAT dMajorMapVersion; + UINT8 ubMinorMapVersion; + UINT32 uiFlags; + UINT32 uiBytesRead; + UINT32 uiFileSize; + INT32 i, cnt, cnt2; + UINT8 ubType; + CHAR8 aFilename[2 * FILENAME_BUFLEN]; + UINT8 ubCombine; + UINT8(*bCounts)[8] = NULL; + INT8* pBuffer; + INT8* pBufferHead; + + + // Append exension to filename! + if ( gfForceLoad ) + sprintf(aFilename, "MAPS\\%s", gzForceLoadFile); + else + sprintf(aFilename, "MAPS\\%s", puiFilename); + + // Open file + hfile = FileOpen(aFilename, FILE_ACCESS_READ); + + if ( !hfile ) + { +#ifndef JA2EDITOR + SET_ERROR("Could not load map file %S", aFilename); +#endif + return(FALSE); + } + + + // Get the file size and alloc one huge buffer for it. We will use this buffer to transfer all of the data from. + uiFileSize = FileGetSize(hfile); + pBuffer = (INT8*)MemAlloc(uiFileSize); + pBufferHead = pBuffer; + FileRead(hfile, pBuffer, uiFileSize, &uiBytesRead); + FileClose(hfile); + + + // Read JA2 Version ID + LOADDATA(&dMajorMapVersion, pBuffer, sizeof(FLOAT)); + LOADDATA(&ubMinorMapVersion, pBuffer, sizeof(UINT8)); + + iRowSize = OLD_WORLD_ROWS; + iColSize = OLD_WORLD_COLS; + if ( dMajorMapVersion >= 7.00 ) + { + LOADDATA(&iRowSize, pBuffer, sizeof(INT32)); + LOADDATA(&iColSize, pBuffer, sizeof(INT32)); + } + + // Actual world size of the map we loaded! + INT32 iWorldSize = iRowSize * iColSize; + gMapTrn.ResizeTrnCfg(WORLD_ROWS, WORLD_COLS, iRowSize, iColSize); + + + // Initialize world data + if ( gpWorldLevelDataAutoResolve != NULL ) + MemFree(gpWorldLevelDataAutoResolve); + gpWorldLevelDataAutoResolve = (MAP_ELEMENT*)MemAlloc(sizeof(MAP_ELEMENT) * WORLD_MAX); + memset(gpWorldLevelDataAutoResolve, 0, sizeof(MAP_ELEMENT) * WORLD_MAX); + + bCounts = (UINT8(*)[8])MemAlloc(WORLD_MAX * 8); + memset(bCounts, 0, sizeof(UINT8) * WORLD_MAX * 8); + + + // Read FLAGS FOR WORLD + LOADDATA(&uiFlags, pBuffer, sizeof(INT32)); + SKIPDATA(pBuffer, pBuffer, sizeof(INT32)); // TilesetID + + // Load soldier size + SKIPDATA(pBuffer, pBuffer, sizeof(INT32)); + + // NOTE! We need this! + // Read height values + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + LOADDATA(&gpWorldLevelDataAutoResolve[cnt].sHeight, pBuffer, sizeof(INT16)); + } + + // Read layer counts + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + // Read combination of land/world flags + LOADDATA(&ubCombine, pBuffer, sizeof(UINT8)); + // Split + bCounts[cnt][0] = (UINT8)(ubCombine & 0x0F); + gpWorldLevelDataAutoResolve[cnt].uiFlags |= (UINT8)((ubCombine & 0xF0) >> 4); + // Read #objects, structs + LOADDATA(&ubCombine, pBuffer, sizeof(UINT8)); + // Split + bCounts[cnt][1] = (UINT8)(ubCombine & 0x0F); + bCounts[cnt][2] = (UINT8)((ubCombine & 0xF0) >> 4); + // Read shadows, roof + LOADDATA(&ubCombine, pBuffer, sizeof(UINT8)); + // Split + bCounts[cnt][3] = (UINT8)(ubCombine & 0x0F); + bCounts[cnt][4] = (UINT8)((ubCombine & 0xF0) >> 4); + // Read OnRoof, nothing + LOADDATA(&ubCombine, pBuffer, sizeof(UINT8)); + // Split + bCounts[cnt][5] = (UINT8)(ubCombine & 0x0F); + } + + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + for ( cnt2 = 0; cnt2 < bCounts[cnt][0]; cnt2++ ) + { + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + } + } + + // New load require UINT16 for the type subindex due to the fact that ROADPIECES contain over 300 type subindices. + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + // Set objects + for ( cnt2 = 0; cnt2 < bCounts[cnt][1]; cnt2++ ) + { + LOADDATA(&ubType, pBuffer, sizeof(UINT8)); + SKIPDATA(pBuffer, pBuffer, sizeof(UINT16)); + + if ( ubType >= FIRSTPOINTERS ) + continue; + } + } + + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + // Set structs + for ( cnt2 = 0; cnt2 < bCounts[cnt][2]; cnt2++ ) + { + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + } + } + + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + for ( cnt2 = 0; cnt2 < bCounts[cnt][3]; cnt2++ ) + { + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + } + } + + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + for ( cnt2 = 0; cnt2 < bCounts[cnt][4]; cnt2++ ) + { + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + } + } + + for ( i = 0; i < iWorldSize; i++ ) + { + gMapTrn.GetTrnCnt(cnt = i); + for ( cnt2 = 0; cnt2 < bCounts[cnt][5]; cnt2++ ) + { + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + } + } + + // For old Russian Maps which have version 6.0 + if ( dMajorMapVersion == 6.00 && ubMinorMapVersion < 27 ) + { + UINT32 uiNums[37]; + LOADDATA(uiNums, pBuffer, sizeof(INT32) * 37); + dMajorMapVersion = 5.00; + } + // For new maps + else if ( dMajorMapVersion == 6.00 && ubMinorMapVersion < 27 && MAJOR_MAP_VERSION == 6.00 ) + { + UINT32 uiNums[37]; + LOADDATA(uiNums, pBuffer, sizeof(UINT32) * 37); + } + //now the data is discarded and when saved, as 6.27, you won't have this problem! + + + for ( i = 0; i < iWorldSize; i++ ) { + // Read room information, 2 byte for new files + if ( ubMinorMapVersion < 29 ) { + SKIPDATA(pBuffer, pBuffer, sizeof(INT8)); + } + else { + SKIPDATA(pBuffer, pBuffer, sizeof(UINT16)); + } + } + + // Load out item information + if ( uiFlags & MAP_WORLDITEMS_SAVED ) + { + WORLDITEM dummyItem; + UINT32 uiNumWorldItems; + + //Read the number of items that were saved in the map. + LOADDATA(&uiNumWorldItems, pBuffer, 4); + + if ( gTacticalStatus.uiFlags & LOADING_SAVED_GAME && !gfEditMode ) + { //The sector has already been visited. The items are saved in a different format that will be + //loaded later on. So, all we need to do is skip the data entirely. + if ( dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26 ) { + for ( unsigned int x = 0; x < uiNumWorldItems; ++x ) + { + //ADB WORLDITEM's size on disk is unknown + dummyItem.Load(&pBuffer, dMajorMapVersion, ubMinorMapVersion); + } + } + else + { + pBuffer += sizeof(OLD_WORLDITEM_101) * uiNumWorldItems; + } + } + else for ( i = 0; i < uiNumWorldItems; i++ ) + { + dummyItem.Load(&pBuffer, dMajorMapVersion, ubMinorMapVersion); + } + } + + if ( uiFlags & MAP_AMBIENTLIGHTLEVEL_SAVED ) + { + //Ambient light levels are only saved in underground levels + SKIPDATA(pBuffer, pBuffer, sizeof(BOOLEAN)); + SKIPDATA(pBuffer, pBuffer, sizeof(BOOLEAN)); + SKIPDATA(pBuffer, pBuffer, sizeof(UINT8)); + + } + + if ( uiFlags & MAP_WORLDLIGHTS_SAVED ) + { + SGPPaletteEntry LColors[3]; + UINT8 ubNumColors; + UINT16 usNumLights; + CHAR8 str[30]; + UINT8 ubStrLen; + LIGHT_SPRITE TmpLight; + + // read in the light colors! + LOADDATA(&ubNumColors, pBuffer, 1); + LOADDATA(LColors, pBuffer, sizeof(SGPPaletteEntry) * ubNumColors); + + LOADDATA(&usNumLights, pBuffer, 2); + + + for ( cnt = 0; cnt < usNumLights; cnt++ ) + { + LOADDATA(&TmpLight, pBuffer, sizeof(LIGHT_SPRITE)); + LOADDATA(&ubStrLen, pBuffer, 1); + + if ( ubStrLen ) + { + LOADDATA(str, pBuffer, ubStrLen); + } + } + } + + gMapInformationAutoResolve.Load(&pBuffer, dMajorMapVersion); + + + // NOTE! We need these! + // Translation routine for map grid numbers + gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sCenterGridNo); + gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sIsolatedGridNo); + gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sNorthGridNo); + gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sEastGridNo); + gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sWestGridNo); + gMapTrn.GetTrnCnt(gMapInformationAutoResolve.sSouthGridNo); + + // Remove this rather large chunk of memory from the system now! + MemFree(pBufferHead); + MemFree(bCounts); + return(TRUE); +} + + //**************************************************************************************** // // Deletes everything then re-creates the world with simple ground tiles diff --git a/TileEngine/worlddef.h b/TileEngine/worlddef.h index 394f6a4a..15f4b144 100644 --- a/TileEngine/worlddef.h +++ b/TileEngine/worlddef.h @@ -281,6 +281,7 @@ typedef struct // World Data extern MAP_ELEMENT *gpWorldLevelData; +extern MAP_ELEMENT* gpWorldLevelDataAutoResolve; extern UINT8 (*gubWorldMovementCosts)[MAXDIR][2];//dnl ch43 260909 //dnl ch44 290909 Translation routine @@ -339,6 +340,7 @@ BOOLEAN NewWorld( INT32 nMapRows, INT32 nMapCols ); BOOLEAN SaveWorld(const STR8 puiFilename, FLOAT dMajorMapVersion=MAJOR_MAP_VERSION, UINT8 ubMinorMapVersion=MINOR_MAP_VERSION);//dnl ch33 150909 BOOLEAN LoadWorld(const STR8 puiFilename, FLOAT* pMajorMapVersion=NULL, UINT8* pMinorMapVersion=NULL);//dnl ch44 290909 +BOOLEAN LoadWorldInfoForAutoResolve(const STR8 puiFilename, INT32& iRowSize, INT32& iColSize); void CompileWorldMovementCosts(void);//dnl ch56 151009 void RecompileLocalMovementCosts( INT32 sCentreGridNo );