diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index b737aa3d..e2c8ac5c 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -189,6 +189,7 @@ extern void initMapViewAndBorderCoordinates(void); UINT32 guiNumberOfMapTempFiles; //Test purposes UINT32 guiSizeOfTempFiles; CHAR gzNameOfMapTempFile[128]; +//#define LOADSAVEGAME_LOGTIME 1 #endif extern SOLDIERTYPE *gpSMCurrentMerc; @@ -732,7 +733,6 @@ BOOLEAN LBENODE::Save( HWFILE hFile, bool fSavingMap ) return TRUE; } - BOOLEAN LoadArmsDealerInventoryFromSavedGameFile( HWFILE hFile ) { UINT32 uiNumBytesRead; @@ -3508,6 +3508,15 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) return( FALSE ); alreadySaving = true; +#ifdef LOADSAVEGAME_LOGTIME + // Flugente: log how long this takes + clock_t starttime = clock(); + clock_t t0; + clock_t t1 = starttime; + + FILE* fp_timelog = fopen("LoadSavedGame_TimeLog.txt", "a"); +#endif + //clear out the save game header memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); @@ -3686,6 +3695,16 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) //Create the name of the file CreateSavedGameFileNameFromNumber( ubSaveGameID, zSaveGameName ); +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + fprintf(fp_timelog, "Save savegame: %s\n", zSaveGameName); + + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "Shutdown stuff\t\t\t\t\t\t\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif //if the file already exists, delete it if( FileExists( zSaveGameName ) ) @@ -3820,6 +3839,14 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "Tactical Status" ); #endif +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveTacticalStatusFromSavedGame done\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif @@ -3859,6 +3886,14 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "Laptop Info" ); #endif +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveLaptopInfoFromSavedGame done\t\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif // // Save the merc profiles @@ -3888,6 +3923,14 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "Soldier Structure" ); #endif +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveSoldierStructure done\t\t\t\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif //Save the Finaces Data file @@ -3948,6 +3991,14 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "Strategic Information" ); #endif +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveStrategicInfoFromSavedFile done\t\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif /*// Flugente: Save the strategic supply if( !SaveStrategicSupplyToSavedFile( hFile ) ) @@ -3995,6 +4046,14 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "Strategic Movement Groups" ); #endif +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveStrategicMovementGroupsFromSavedGameFile done\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif @@ -4009,7 +4068,15 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "All the Map Temp files" ); #endif - +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveMapTempFilesFromSavedGameFile done\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif + if( !SaveQuestInfoToSavedGameFile( hFile ) ) { ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing quest info"); @@ -4172,6 +4239,14 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "Militia Movement" ); #endif +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveMilitiaMovementInformationFromSavedGameFile done\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif if( !SaveBulletStructureToSaveGameFile( hFile ) ) { @@ -4409,7 +4484,15 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) #ifdef JA2BETAVERSION SaveGameFilePosition( FileGetPos( hFile ), "Lua global" ); #endif - +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "SaveLuaGlobalFromLoadGameFile done\t\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif + if( !SaveDataSaveToSaveGameFile( hFile ) ) { ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing save data"); @@ -4506,6 +4589,14 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing rebel command data" ); goto FAILED_TO_SAVE; } +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "File read done\t\t\t\t\t\t\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } +#endif //Close the saved game file FileClose( hFile ); @@ -4584,6 +4675,24 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) alreadySaving = false; +#if LOADSAVEGAME_LOGTIME + if (fp_timelog) + { + t0 = t1; + t1 = clock(); + fprintf(fp_timelog, "Update functions\t\t\t\t\t\t\t\t\t\t\t\t: %fs\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } + + if (fp_timelog) + { + t0 = starttime; + t1 = clock(); + fprintf(fp_timelog, "SaveSavedGame total\t\t\t\t\t\t\t\t\t\t\t\t: %fs\n\n", ((float)(t1 - t0) / CLOCKS_PER_SEC)); + } + + if (fp_timelog) + fclose(fp_timelog); +#endif return( TRUE ); //if there is an error saving the game @@ -4636,7 +4745,6 @@ UINT32 guiBrokenSaveGameVersion = 0; extern int gEnemyPreservedTempFileVersion[256]; extern int gCivPreservedTempFileVersion[256]; -#define LOADSAVEGAME_LOGTIME 1 #include "time.h" @@ -7286,11 +7394,11 @@ BOOLEAN LoadPtrInfo( PTR *pData, UINT32 uiSizeOfObject, HWFILE hFile ) BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile ) { - UINT32 uiFileSize; + UINT32 uiFileSize=0; UINT32 uiNumBytesWritten=0; HWFILE hSrcFile=NULL; - UINT8 *pData; - UINT32 uiNumBytesRead; + UINT8 *pData=NULL; + UINT32 uiNumBytesRead=0; if(FileExists(pSrcFileName)) { @@ -7366,14 +7474,13 @@ BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile ) return( TRUE ); } - BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile ) { - UINT32 uiFileSize; + UINT32 uiFileSize=0; UINT32 uiNumBytesWritten=0; - HWFILE hSrcFile; - UINT8 *pData; - UINT32 uiNumBytesRead; + HWFILE hSrcFile=0; + UINT8 *pData=NULL; + UINT32 uiNumBytesRead=0; //If the source file exists, delete it if( FileExists( pSrcFileName ) ) diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 934b6df8..c8209a40 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -89,6 +89,7 @@ class OBJECTTYPE; class SOLDIERTYPE; extern int POP_UP_BOX_X; +extern WorldItems gAllWorldItems; #include "MilitiaSquads.h" // HEADROCK HAM 3.5: Include Facility data @@ -8891,17 +8892,17 @@ void HandleEquipmentMove( INT16 sMapX, INT16 sMapY, INT8 bZ ) else { // not loaded, load - // get total number, visable and invisible - BOOLEAN fReturn = GetNumberOfWorldItemsFromTempItemFile( targetX, targetY, bZ, &( uiTotalNumberOfRealItems_Target ), FALSE ); - Assert( fReturn ); - - if( uiTotalNumberOfRealItems_Target > 0 ) { - // allocate space for the list - pWorldItem_Target.resize(uiTotalNumberOfRealItems_Target);//dnl ch75 271013 - - // now load into mem - LoadWorldItemsFromTempItemFile( targetX, targetY, bZ, pWorldItem_Target ); + const auto i = FindWorldItemSector(targetX, targetY, bZ); + if (i != -1) + { + uiTotalNumberOfRealItems_Target = gAllWorldItems.NumItems[i]; + pWorldItem_Target = gAllWorldItems.Items[i]; + } + else + { + uiTotalNumberOfRealItems_Target = 0; + } } } @@ -9027,8 +9028,7 @@ void HandleEquipmentMove( INT16 sMapX, INT16 sMapY, INT8 bZ ) } else { - //Save the Items to the the file - SaveWorldItemsToTempItemFile( targetX, targetY, bZ, uiTotalNumberOfRealItems_Target, pWorldItem_Target ); + UpdateWorldItems(targetX, targetY, bZ, uiTotalNumberOfRealItems_Target, pWorldItem_Target); } // award a bit of experience to the movers diff --git a/Strategic/Hourly Update.cpp b/Strategic/Hourly Update.cpp index 794dda59..800e5603 100644 --- a/Strategic/Hourly Update.cpp +++ b/Strategic/Hourly Update.cpp @@ -55,6 +55,7 @@ void HourlyFactoryUpdate(); // Flugente: update factories void HourlySnitchUpdate(); // anv: decreasing cooldown after exposition extern SECTOR_EXT_DATA SectorExternalData[256][4]; +extern WorldItems gAllWorldItems; extern INT32 GetCurrentBalance( void ); extern void PayOffSkyriderDebtIfAny( ); @@ -841,37 +842,30 @@ void HourlyStealUpdate() BOOLEAN RemoveItemInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT16 usItem, UINT32 usNumToRemove ) { - // open sector inv UINT32 uiTotalNumberOfRealItems = 0; std::vector pWorldItem;//dnl ch75 271013 - BOOLEAN fReturn = FALSE; + // open sector inventory if ( ( gWorldSectorX == sSectorX ) && ( gWorldSectorY == sSectorY ) && ( gbWorldSectorZ == bSectorZ ) ) { uiTotalNumberOfRealItems = guiNumWorldItems; - pWorldItem = gWorldItems; } else { - // not loaded, load - // get total number, visable and invisible - fReturn = GetNumberOfWorldItemsFromTempItemFile( sSectorX, sSectorY, bSectorZ, &( uiTotalNumberOfRealItems ), FALSE ); - Assert( fReturn ); - - if ( uiTotalNumberOfRealItems > 0 ) + // Check for unloaded sector + const auto i = FindWorldItemSector( sSectorX, sSectorY, bSectorZ); + if (i != -1) { - // allocate space for the list - pWorldItem.resize( uiTotalNumberOfRealItems );//dnl ch75 271013 - - // now load into mem - LoadWorldItemsFromTempItemFile( sSectorX, sSectorY, bSectorZ, pWorldItem ); + uiTotalNumberOfRealItems = gAllWorldItems.NumItems[i]; + pWorldItem = gAllWorldItems.Items[i]; } } if ( !uiTotalNumberOfRealItems ) return FALSE; + BOOLEAN removedsth = FALSE; OBJECTTYPE* pObj = NULL; for ( UINT32 uiCount = 0; uiCount < uiTotalNumberOfRealItems && usNumToRemove > 0; ++uiCount ) // ... for all items in the world ... @@ -906,7 +900,6 @@ BOOLEAN RemoveItemInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT1 if ( removedsth ) { // save the changed inventory - // open sector inv if ( ( gWorldSectorX == sSectorX ) && ( gWorldSectorY == sSectorY ) && ( gbWorldSectorZ == bSectorZ ) ) { guiNumWorldItems = uiTotalNumberOfRealItems; @@ -914,8 +907,7 @@ BOOLEAN RemoveItemInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT1 } else { - //Save the Items to the the file - SaveWorldItemsToTempItemFile( sSectorX, sSectorY, bSectorZ, uiTotalNumberOfRealItems, pWorldItem ); + UpdateWorldItems(sSectorX, sSectorY, bSectorZ, uiTotalNumberOfRealItems, pWorldItem); } return TRUE; @@ -927,35 +919,27 @@ BOOLEAN RemoveItemInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT1 UINT32 CountAccessibleItemsInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT16 usItem ) { UINT32 numfound = 0; - - // open sector inv UINT32 uiTotalNumberOfRealItems = 0; std::vector pWorldItem;//dnl ch75 271013 - BOOLEAN fReturn = FALSE; + // open sector inv if ( ( gWorldSectorX == sSectorX ) && ( gWorldSectorY == sSectorY ) && ( gbWorldSectorZ == bSectorZ ) ) { uiTotalNumberOfRealItems = guiNumWorldItems; - pWorldItem = gWorldItems; } else { - // not loaded, load - // get total number, visable and invisible - fReturn = GetNumberOfWorldItemsFromTempItemFile( sSectorX, sSectorY, bSectorZ, &( uiTotalNumberOfRealItems ), FALSE ); - Assert( fReturn ); - - if ( uiTotalNumberOfRealItems > 0 ) + // Check for unloaded sector + const auto i = FindWorldItemSector(sSectorX, sSectorY, bSectorZ); + if (i != -1) { - // allocate space for the list - pWorldItem.resize( uiTotalNumberOfRealItems );//dnl ch75 271013 - - // now load into mem - LoadWorldItemsFromTempItemFile( sSectorX, sSectorY, bSectorZ, pWorldItem ); + uiTotalNumberOfRealItems = gAllWorldItems.NumItems[i]; + pWorldItem = gAllWorldItems.Items[i]; } } + OBJECTTYPE* pObj = NULL; for ( UINT32 uiCount = 0; uiCount < uiTotalNumberOfRealItems; ++uiCount ) // ... for all items in the world ... { diff --git a/Strategic/LuaInitNPCs.cpp b/Strategic/LuaInitNPCs.cpp index afec6d72..d91243ba 100644 --- a/Strategic/LuaInitNPCs.cpp +++ b/Strategic/LuaInitNPCs.cpp @@ -82,6 +82,7 @@ extern UINT8 gubWaitingForAllMercsToExitCode; extern BOOLEAN gfDoneWithSplashScreen; extern UINT32 iStringToUseLua; extern INT8 Test; +extern INT32 GetAmountOfWorldItems(INT16 x, INT16 y, INT16 z); static int l_HireMerc (lua_State *L); @@ -629,7 +630,7 @@ static int l_AddSameDayStrategicEvent(lua_State *L); static int l_FunctionCheckForKingpinsMoneyMissing(lua_State *L); static int l_MoveItemPools(lua_State *L); -static int l_GetNumberOfWorldItemsFromTempItemFile(lua_State *L); +static int l_GetNumberOfWorldItems(lua_State *L); static int l_gubFact(lua_State *L); @@ -1276,7 +1277,7 @@ void IniFunction(lua_State *L, BOOLEAN bQuests ) lua_register(L, "GetWorldItemsObjectItem", l_gWorldItemsObjectItem); lua_register(L, "GetWorldItemsObjectDataMoney", l_gWorldItemsObjectDataMoney); lua_register(L, "MoveItemPools", l_MoveItemPools); - lua_register(L, "GetNumberOfWorldItemsFromTempItemFile", l_GetNumberOfWorldItemsFromTempItemFile); + lua_register(L, "GetNumberOfWorldItems", l_GetNumberOfWorldItems); lua_register(L, "ItemExistsAtLocation", l_ItemExistsAtLocation); lua_register(L, "AddCreateItemToPool", l_CreateItemToPool); lua_register(L, "AddCreateItemsToUnLoadedSector", l_CreateToUnLoadedSector); @@ -4934,23 +4935,19 @@ return 0; } -static int l_GetNumberOfWorldItemsFromTempItemFile(lua_State *L) +static int l_GetNumberOfWorldItems(lua_State *L) { - if ( lua_gettop(L) >= 5 ) + if ( lua_gettop(L) >= 3 ) { - INT16 sMapX = lua_tointeger(L,1); - INT16 sMapY = lua_tointeger(L,2); - INT8 bMapZ = lua_tointeger(L,3); - UINT32 puiNumberOfItems = lua_tointeger(L,4); - BOOLEAN fIfEmptyCreate = lua_toboolean(L,5); - - - BOOLEAN Bool = GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &puiNumberOfItems, fIfEmptyCreate ); - - lua_pushboolean(L, Bool); + INT16 sMapX = lua_tointeger(L,1); + INT16 sMapY = lua_tointeger(L,2); + INT8 bMapZ = lua_tointeger(L,3); - } + + INT32 NumItems = GetAmountOfWorldItems(sMapX, sMapY, bMapZ); + lua_pushinteger(L, NumItems); + } return 1; } diff --git a/Strategic/Map Screen Interface Map Inventory.cpp b/Strategic/Map Screen Interface Map Inventory.cpp index fbe8313a..32dbf1d3 100644 --- a/Strategic/Map Screen Interface Map Inventory.cpp +++ b/Strategic/Map Screen Interface Map Inventory.cpp @@ -50,6 +50,7 @@ class OBJECTTYPE; class SOLDIERTYPE; extern UILayout_Map UI_MAP; +extern WorldItems gAllWorldItems; // Flugente: external sector data extern SECTOR_EXT_DATA SectorExternalData[256][4]; @@ -1175,8 +1176,7 @@ void SaveSeenAndUnseenItems( void ) } else { - Assert(SaveWorldItemsToTempItemFile(sSelMapX, sSelMapY, iCurrentMapSectorZ, uiNumberOfSeenItems + uiNumberOfUnSeenItems, pInventoryPoolList, FALSE)); - SetNumberOfVisibleWorldItemsInSectorStructureForSector(sSelMapX, sSelMapY, iCurrentMapSectorZ, uiTotalNumberOfVisibleItems); + UpdateWorldItems(sSelMapX, sSelMapY, iCurrentMapSectorZ, uiNumberOfSeenItems + uiNumberOfUnSeenItems, pInventoryPoolList); } #endif } @@ -2345,13 +2345,23 @@ void BuildStashForSelectedSector( INT16 sMapX, INT16 sMapY, INT16 sMapZ ) } else// if map not loaded, use tempfile to build lists { - Assert(GetNumberOfWorldItemsFromTempItemFile(sMapX, sMapY, (INT8)sMapZ, &uiTotalNumberOfItems, FALSE)); + const auto ii = FindWorldItemSector(sMapX, sMapY, (INT8)sMapZ); + if (ii == -1) + { + uiTotalNumberOfItems = 0; + } + else + { + uiTotalNumberOfItems = gAllWorldItems.NumItems[ii]; + pInventoryPoolList = gAllWorldItems.Items[ii]; + } + uiNumOfSlots = (uiTotalNumberOfItems / MAP_INVENTORY_POOL_SLOT_COUNT + 1) * MAP_INVENTORY_POOL_SLOT_COUNT; if(pInventoryPoolList.size() < uiNumOfSlots) pInventoryPoolList.resize(uiNumOfSlots); if(pUnSeenItems.size() < uiNumOfSlots) pUnSeenItems.resize(uiNumOfSlots); - Assert(LoadWorldItemsFromTempItemFile(sMapX, sMapY, (INT8)sMapZ, pInventoryPoolList)); + uiNumberOfSeenItems = uiTotalNumberOfItems; uiNumberOfUnSeenItems = 0; pipl = &pInventoryPoolList.front(); diff --git a/Strategic/Strategic Event Handler.cpp b/Strategic/Strategic Event Handler.cpp index 7fa19180..a1207084 100644 --- a/Strategic/Strategic Event Handler.cpp +++ b/Strategic/Strategic Event Handler.cpp @@ -40,6 +40,7 @@ //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; +extern WorldItems gAllWorldItems; #define MEDUNA_ITEM_DROP_OFF_GRIDNO 10959 @@ -427,9 +428,6 @@ void HandleDelayedItemsArrival( UINT32 uiReason ) // This function moves all the items that Pablos has stolen // (or items that were delayed) to the arrival location for new shipments, INT32 sStartGridNo; - UINT32 uiNumWorldItems, uiLoop; - BOOLEAN fOk; - std::vector pTemp;//dnl ch75 271013 UINT8 ubLoop; if (uiReason == NPC_SYSTEM_EVENT_ACTION_PARAM_BONUS + NPC_ACTION_RETURN_STOLEN_SHIPMENT_ITEMS ) @@ -502,24 +500,24 @@ void HandleDelayedItemsArrival( UINT32 uiReason ) else { // otherwise load the saved items from the item file and change the records of their locations - fOk = GetNumberOfWorldItemsFromTempItemFile( BOBBYR_SHIPPING_DEST_SECTOR_X, BOBBYR_SHIPPING_DEST_SECTOR_Y, BOBBYR_SHIPPING_DEST_SECTOR_Z, &uiNumWorldItems, FALSE ); - if (!fOk) + std::vector pTemp; + UINT32 uiNumWorldItems = 0; + + const auto ii = FindWorldItemSector(BOBBYR_SHIPPING_DEST_SECTOR_X, BOBBYR_SHIPPING_DEST_SECTOR_Y, BOBBYR_SHIPPING_DEST_SECTOR_Z); + if (ii != -1) { - return; + uiNumWorldItems = gAllWorldItems.NumItems[ii]; + pTemp = gAllWorldItems.Items[ii]; } - pTemp.resize(uiNumWorldItems);//dnl ch75 271013 - fOk = LoadWorldItemsFromTempItemFile( BOBBYR_SHIPPING_DEST_SECTOR_X, BOBBYR_SHIPPING_DEST_SECTOR_Y, BOBBYR_SHIPPING_DEST_SECTOR_Z, pTemp ); - if (fOk) + + for (UINT32 uiLoop = 0; uiLoop < uiNumWorldItems; uiLoop++) { - for (uiLoop = 0; uiLoop < uiNumWorldItems; uiLoop++) + if (pTemp[uiLoop].sGridNo == PABLOS_STOLEN_DEST_GRIDNO) { - if (pTemp[uiLoop].sGridNo == PABLOS_STOLEN_DEST_GRIDNO) - { - pTemp[uiLoop].sGridNo = BOBBYR_SHIPPING_DEST_GRIDNO; - } + pTemp[uiLoop].sGridNo = BOBBYR_SHIPPING_DEST_GRIDNO; } - AddWorldItemsToUnLoadedSector( BOBBYR_SHIPPING_DEST_SECTOR_X, BOBBYR_SHIPPING_DEST_SECTOR_Y, BOBBYR_SHIPPING_DEST_SECTOR_Z, 0, uiNumWorldItems, pTemp, TRUE ); } + AddWorldItemsToUnLoadedSector( BOBBYR_SHIPPING_DEST_SECTOR_X, BOBBYR_SHIPPING_DEST_SECTOR_Y, BOBBYR_SHIPPING_DEST_SECTOR_Z, 0, uiNumWorldItems, pTemp, TRUE ); } } diff --git a/Strategic/Strategic Town Loyalty.cpp b/Strategic/Strategic Town Loyalty.cpp index 0572d672..2427201b 100644 --- a/Strategic/Strategic Town Loyalty.cpp +++ b/Strategic/Strategic Town Loyalty.cpp @@ -46,6 +46,7 @@ #include "Interface.h" #include "GameInitOptionsScreen.h" +extern WorldItems gAllWorldItems; // loyalty Omerta drops to and maxes out at if the player betrays the rebels #define HOSTILE_OMERTA_LOYALTY_RATING 10 @@ -1128,19 +1129,20 @@ void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, if( gWorldSectorX != sSectorX || gWorldSectorY != sSectorY || gbWorldSectorZ != sSectorZ ) { // if the player has never been there, there's no temp file, and 0 items will get returned, preventing any stealing - GetNumberOfWorldItemsFromTempItemFile( sSectorX, sSectorY, ( UINT8 )sSectorZ, &uiNumberOfItems, FALSE ); + const auto ii = FindWorldItemSector(sSectorX, sSectorY, (UINT8)sSectorZ); + if (ii != -1) + { + uiNumberOfItems = gAllWorldItems.NumItems[ii]; + pItemList = gAllWorldItems.Items[ii]; + } if( uiNumberOfItems == 0 ) { return; } - pItemList.resize(uiNumberOfItems);//dnl ch75 271013 - // now load items - LoadWorldItemsFromTempItemFile( sSectorX, sSectorY, ( UINT8 )sSectorZ, pItemList ); uiNewTotal = uiNumberOfItems; - // set up item list ptrs for( iCounter = 0; iCounter < uiNumberOfItems ; ++iCounter ) { diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index cded1780..e8071161 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -3167,8 +3167,7 @@ BOOLEAN EnterSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) //Update LastTimePlayerWasInSector SetLastTimePlayerWasInSector( ); - //Save to tempfile - SaveWorldItemsToTempItemFile( sSectorX, sSectorY, (INT8)bSectorZ, guiNumWorldItems, gWorldItems ); + UpdateWorldItems(sSectorX, sSectorY, (INT8)bSectorZ, guiNumWorldItems, gWorldItems); DebugQuestInfo(String("Enter Sector %s%s Level %d", pVertStrings[sSectorY], pHortStrings[sSectorX], bSectorZ)); diff --git a/Tactical/Inventory Choosing.cpp b/Tactical/Inventory Choosing.cpp index 335da71c..475fd139 100644 --- a/Tactical/Inventory Choosing.cpp +++ b/Tactical/Inventory Choosing.cpp @@ -21,6 +21,7 @@ #include "Tactical Save.h" // added by Flugente #include "Soldier macros.h" // added by Flugente #endif +extern WorldItems gAllWorldItems; /* #define ENEMYAMMODROPRATE 100 //Madd 50 // % of time enemies drop ammunition @@ -3766,9 +3767,7 @@ void SpawnFittingAmmo(SOLDIERCREATE_STRUCT *pp, OBJECTTYPE* pObj, UINT8 ammotype void MoveOneMilitiaEquipmentSet(INT16 sSourceX, INT16 sSourceY, INT16 sTargetX, INT16 sTargetY, INT8 bSoldierClass) { - BOOLEAN fReturn = FALSE; UINT32 uiTotalNumberOfRealItems = 0; - UINT32 uiNumOriginalItems = 0; std::vector pWorldItem;//dnl ch75 271013 SOLDIERCREATE_STRUCT tmp; UINT32 uiCount = 0; @@ -3788,25 +3787,22 @@ void MoveOneMilitiaEquipmentSet(INT16 sSourceX, INT16 sSourceY, INT16 sTargetX, else { // not loaded, load - // get total number, visable and invisible - fReturn = GetNumberOfWorldItemsFromTempItemFile( sTargetX, sTargetY, 0, &( uiTotalNumberOfRealItems ), TRUE ); - Assert( fReturn ); - - if( uiTotalNumberOfRealItems > 0 ) + const auto ii = FindWorldItemSector(sTargetX, sTargetY, 0); + if (ii != -1) { - // allocate space for the list - pWorldItem.resize(uiTotalNumberOfRealItems);//dnl ch75 271013 - - // now load into mem - LoadWorldItemsFromTempItemFile( sTargetX, sTargetY, 0, pWorldItem ); + uiTotalNumberOfRealItems = gAllWorldItems.NumItems[ii]; + pWorldItem = gAllWorldItems.Items[ii]; + } + else + { + uiTotalNumberOfRealItems = 10; + pWorldItem.resize(uiTotalNumberOfRealItems); } } - uiNumOriginalItems = uiTotalNumberOfRealItems; // we note the last item existing in the inventory (but not ammo, as we delete those). We use this to assess how much we really need to increase the inventory UINT32 existingitemsfound = 0; - for( uiCount = 0; uiCount < uiTotalNumberOfRealItems; ++uiCount ) // ... for all items in the world ... { if( pWorldItem[ uiCount ].fExists ) // ... if item exists ... @@ -3888,8 +3884,7 @@ void MoveOneMilitiaEquipmentSet(INT16 sSourceX, INT16 sSourceY, INT16 sTargetX, } else { - //Save the Items to the the file - SaveWorldItemsToTempItemFile( sTargetX, sTargetY, 0, uiTotalNumberOfRealItems, pWorldItem ); + UpdateWorldItems(sTargetX, sTargetY, 0, uiTotalNumberOfRealItems, pWorldItem); } } @@ -3999,21 +3994,15 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI } else { - // not loaded, load - // get total number, visable and invisible - fReturn = GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, ( INT8 )( sMapZ ), &( uiTotalNumberOfRealItems ), FALSE ); - Assert( fReturn ); - - if( uiTotalNumberOfRealItems > 0 ) + const auto ii = FindWorldItemSector(sMapX, sMapY, (INT8)(sMapZ)); + if (ii != -1) { - // allocate space for the list - pWorldItem.resize(uiTotalNumberOfRealItems);//dnl ch75 271013 - - if ( !uiTotalNumberOfRealItems ) - return; - - // now load into mem - LoadWorldItemsFromTempItemFile( sMapX, sMapY, ( INT8 ) ( sMapZ ), pWorldItem ); + uiTotalNumberOfRealItems = gAllWorldItems.NumItems[ii]; + pWorldItem = gAllWorldItems.Items[ii]; + } + else + { + uiTotalNumberOfRealItems = 0; } } @@ -4694,7 +4683,7 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI else { //Save the Items to the the file - SaveWorldItemsToTempItemFile( sMapX, sMapY, (INT8)sMapZ, uiTotalNumberOfRealItems, pWorldItem ); + UpdateWorldItems(sMapX, sMapY, (INT8)sMapZ, uiTotalNumberOfRealItems, pWorldItem); } ///////////////////////////////// Exit ///////////////////////////////////////////////////////// diff --git a/Tactical/Tactical Save.cpp b/Tactical/Tactical Save.cpp index 40e32bfd..a4fcf717 100644 --- a/Tactical/Tactical Save.cpp +++ b/Tactical/Tactical Save.cpp @@ -55,6 +55,13 @@ 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); /////////////////////////////////////////////////////////////// // @@ -144,19 +151,14 @@ extern BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode ); #endif -void SynchronizeItemTempFileVisbleItemsToSectorInfoVisbleItems( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fLoadingGame ); 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 ) { @@ -164,9 +166,8 @@ BOOLEAN SaveMapTempFilesToSavedGameFile( HWFILE hFile ) INT16 sMapX; INT16 sMapY; - - //Save the current sectors open temp files to the disk -// SaveCurrentSectorsItemsToTempItemFile(); + // 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 @@ -184,7 +185,6 @@ BOOLEAN SaveMapTempFilesToSavedGameFile( HWFILE hFile ) 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 ) { @@ -364,6 +364,9 @@ BOOLEAN LoadMapTempFilesFromSavedGameFile( HWFILE hFile ) } } + + // Preparation for loading item temp files + ClearAllWorldItems(); // //Loop though all the array elements to see if there is a data file to be loaded // @@ -377,18 +380,8 @@ BOOLEAN LoadMapTempFilesFromSavedGameFile( HWFILE hFile ) { if ( !RetrieveTempFileFromSavedGame( hFile, SF_ITEM_TEMP_FILE_EXISTS, sMapX, sMapY, 0 ) ) return FALSE; - - //sync up the temp file data to the sector structure data - SynchronizeItemTempFileVisbleItemsToSectorInfoVisbleItems( sMapX, sMapY, 0, TRUE ); - - // Flugente: commented out, as the update now happens in SynchronizeItemTempFileVisbleItemsToSectorInfoVisbleItems, which will save us one loading routine per inventory - /*if (guiCurrentSaveGameVersion != SAVE_GAME_VERSION) - { - for (int z = 0; z < 4; ++z) - { - UpdateWorldItemsTempFile(sMapX, sMapY, z); - } - }*/ + // 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 ) @@ -482,7 +475,7 @@ BOOLEAN LoadMapTempFilesFromSavedGameFile( HWFILE hFile ) return FALSE; //sync up the temp file data to the sector structure data - SynchronizeItemTempFileVisbleItemsToSectorInfoVisbleItems( TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ, TRUE ); + LoadWorldItemsFromTempFiles(TempNode->ubSectorX, TempNode->ubSectorY, TempNode->ubSectorZ); } if( TempNode->uiFlags & SF_ROTTING_CORPSE_TEMP_FILE_EXISTS ) @@ -560,31 +553,6 @@ BOOLEAN LoadMapTempFilesFromSavedGameFile( HWFILE hFile ) } -BOOLEAN UpdateWorldItemsTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) -{ - UINT32 uiTotalNumberOfItems=0; - std::vector pTotalSectorList;//dnl ch75 271013 - BOOLEAN fReturn = GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &( uiTotalNumberOfItems ), FALSE ); - if (fReturn == false) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("GetNumberOfWorldItemsFromTempItemFile failed" ) ); - Assert( fReturn ); - } - - if( uiTotalNumberOfItems > 0 ) - { - // allocate space for the list - pTotalSectorList.resize(uiTotalNumberOfItems);//dnl ch75 271013 - - LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pTotalSectorList ); - int backup = guiCurrentSaveGameVersion; - guiCurrentSaveGameVersion = SAVE_GAME_VERSION; - SaveWorldItemsToTempItemFile( sMapX, sMapY, bMapZ, uiTotalNumberOfItems, pTotalSectorList); - guiCurrentSaveGameVersion = backup; - } - - return TRUE; -} /* BOOLEAN UpdateENEMYTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) @@ -610,7 +578,7 @@ BOOLEAN UpdateCIVTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) } */ -BOOLEAN SaveWorldItemsToTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems, std::vector& pData, BOOLEAN fUpdateVisibleItems )//dnl ch75 271013 +BOOLEAN SaveWorldItemsToTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems, std::vector& pData) { HWFILE hFile; UINT32 uiNumBytesWritten=0; @@ -652,9 +620,6 @@ BOOLEAN SaveWorldItemsToTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT SetSectorFlag( sMapX, sMapY, bMapZ, SF_ITEM_TEMP_FILE_EXISTS ); - if( fUpdateVisibleItems )//dnl ch75 311013 - SynchronizeItemTempFileVisbleItemsToSectorInfoVisbleItems( sMapX, sMapY, bMapZ, FALSE ); - return( TRUE ); } @@ -729,7 +694,7 @@ BOOLEAN GetNumberOfWorldItemsFromTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bM { //ADB: I don't know why we are initing 10 WORLDITEMS then saving them, but that's what the code was. WORLDITEM TempWorldItems[ 10 ]; - UINT32 uiNumberOfItems = 10; + uiNumberOfItems = 10; UINT32 uiNumBytesWritten=0; //If the file doesnt exists, create a file that has an initial amount of Items @@ -818,23 +783,20 @@ UINT32 GetNumberOfMovableItems( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) } else { - // not loaded, load - // get total number, visable and invisible - BOOLEAN fReturn = GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &(uiTotalNumberOfRealItems_Target), FALSE ); - Assert( fReturn ); - - if ( uiTotalNumberOfRealItems_Target > 0 ) + const auto ii = FindWorldItemSector(sMapX, sMapY, bMapZ); + if (ii != -1) { - // allocate space for the list - pWorldItem_Target.resize( uiTotalNumberOfRealItems_Target );//dnl ch75 271013 - - // now load into mem - LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pWorldItem_Target ); + uiTotalNumberOfRealItems_Target = gAllWorldItems.NumItems[ii]; + pWorldItem_Target = gAllWorldItems.Items[ii]; + } + else + { + uiTotalNumberOfRealItems_Target = 0; } } - UINT32 validitems = 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 ... @@ -851,131 +813,188 @@ UINT32 GetNumberOfMovableItems( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) } } } - return validitems; } - -BOOLEAN AddItemsToUnLoadedSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT32 sGridNo, UINT32 uiNumberOfItemsToAdd, OBJECTTYPE *pObject, UINT8 ubLevel, UINT16 usFlags, INT8 bRenderZHeightAboveLevel, INT8 bVisible, BOOLEAN fReplaceEntireFile ) +BOOLEAN AddWorldItemsToUnLoadedSector(INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT32 sGridNo, UINT32 uiNumberOfItemsToAdd, std::vector& pWorldItem, BOOLEAN fOverWrite) { - UINT32 uiNumberOfItems=0; + UINT32 uiLoop; + UINT32 uiLastItemPos; + UINT32 uiNumberOfItems; std::vector pWorldItems;//dnl ch75 271013 - UINT32 cnt; - UINT32 uiLoop1=0; - - if ( uiNumberOfItemsToAdd == 0 && fReplaceEntireFile == FALSE ) + if (uiNumberOfItemsToAdd == 0 && fOverWrite == FALSE) { //Moa: nothing to do, so get out of here! - return( TRUE ); + return(TRUE); } - if( !GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &uiNumberOfItems, TRUE ) ) + const auto i = FindWorldItemSector(sMapX, sMapY, bMapZ); + if (i == -1) { - //Errror getting the numbers of the items from the sector - return( FALSE ); + // Can't find world item sector, add it + uiNumberOfItems = uiNumberOfItemsToAdd; + pWorldItems.resize(uiNumberOfItems); } - - //Allocate memeory for the item - pWorldItems.resize(uiNumberOfItems); - - //Load in the sectors Item Info - if( !LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pWorldItems ) ) + else { - //error reading in the items from the Item mod file - return( FALSE ); + uiNumberOfItems = gAllWorldItems.NumItems[i]; + pWorldItems = gAllWorldItems.Items[i]; } - //if we are to replace the entire file - if( fReplaceEntireFile ) + if (fOverWrite) { //first loop through and mark all entries that they dont exists - for( cnt=0; cnt 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++) + 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++) + for (cnt = uiLastFoundSpot; cnt < uiNumberOfItems; cnt++) { - if( pWorldItems[ cnt ].fExists == FALSE ) + 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 ) ) - { -#if 0//dnl ch75 271013 - //Error, there wasnt a free spot. Reallocate memory for the array - WORLDITEM* pTemp = new WORLDITEM[uiNumberOfItems + 1]; - if( pTemp == NULL ) - { - //error realloctin memory - return( FALSE ); } - for (unsigned int x = 0; x < uiNumberOfItems; ++x) { - pTemp[x] = pWorldItems[x]; - } - delete[] pWorldItems; - pWorldItems = pTemp; - - //Increment the total number of item in the array - uiNumberOfItems++; - - //set the spot were the item is to be added - cnt = uiNumberOfItems - 1; -#else - pWorldItems.resize(++uiNumberOfItems); -#endif } - pWorldItems[ cnt ].fExists = TRUE; - pWorldItems[ cnt ].sGridNo = sGridNo; - pWorldItems[ cnt ].ubLevel = ubLevel; - pWorldItems[ cnt ].usFlags = usFlags; - pWorldItems[ cnt ].bVisible = bVisible; - pWorldItems[ cnt ].bRenderZHeightAboveLevel = bRenderZHeightAboveLevel; + 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 ) ) + 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; + 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] ); + 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]; + pWorldItems[cnt].object = pObject[uiLoop1]; - if ( (*pObject)[uiLoop1]->data.sObjectFlag & TAKEN_BY_MILITIA_TABOO_GREEN ) + 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; + pWorldItems[cnt].usFlags |= WORLD_ITEM_TABOO_FOR_MILITIA_EQ_GREEN; } - if ( (*pObject)[uiLoop1]->data.sObjectFlag & TAKEN_BY_MILITIA_TABOO_BLUE ) + 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; + pWorldItems[cnt].usFlags |= WORLD_ITEM_TABOO_FOR_MILITIA_EQ_BLUE; } } - //Save the Items to the the file - SaveWorldItemsToTempItemFile( sMapX, sMapY, bMapZ, uiNumberOfItems, pWorldItems ); - - return( TRUE ); + UpdateWorldItems(sMapX, sMapY, bMapZ, uiNumberOfItems, pWorldItems); + return(TRUE); } + extern BOOLEAN gfInMeanwhile; extern BOOLEAN EnableModifiedFileSetCache(BOOLEAN value); @@ -1012,14 +1031,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) // handle all reachable before save HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - - //Save the Items to the the file - if( !SaveWorldItemsToTempItemFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, guiNumWorldItems, gWorldItems ) ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveWorldItemsToTempItemFile()" ) ); - EnableModifiedFileSetCache(cacheResetValue); - return( FALSE ); - } + UpdateWorldItems(gWorldSectorX, gWorldSectorY, gbWorldSectorZ, guiNumWorldItems, gWorldItems); std::vector corpsedefvector; @@ -1281,13 +1293,12 @@ BOOLEAN LoadCurrentSectorsInformationFromTempItemsFile() // processed! if ( GetMeanwhileID() == INTERROGATION ) { - //If there is a file, load in the Items array - if( DoesTempFileExistsForMap( SF_ITEM_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) + //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 (!LoadAndAddWorldItemsFromTempFile(gWorldSectorX, gWorldSectorY, gbWorldSectorZ)) + return(FALSE); } - gfWasInMeanwhile = FALSE; } return TRUE; @@ -1303,12 +1314,12 @@ BOOLEAN LoadCurrentSectorsInformationFromTempItemsFile() return( FALSE ); } - //If there is a file, load in the Items array - if( DoesTempFileExistsForMap( SF_ITEM_TEMP_FILE_EXISTS, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) + //We no longer use item temp files during gameplay, so check for the sector in gAllWorldItems + if (SectorIsInWorldItems(gWorldSectorX, gWorldSectorY, gbWorldSectorZ)) { - fUsedTempFile = TRUE; - if( !LoadAndAddWorldItemsFromTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) - return( FALSE ); + if (!LoadAndAddWorldItemsFromTempFile(gWorldSectorX, gWorldSectorY, gbWorldSectorZ)) + return(FALSE); + } //If there is a rotting corpse temp file, load the data from the temp file @@ -1543,29 +1554,31 @@ UINT32 GetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ) -BOOLEAN LoadAndAddWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) +BOOLEAN LoadAndAddWorldItemsFromTempFile(INT16 sMapX, INT16 sMapY, INT8 bMapZ) { - UINT32 uiNumberOfItems=0; - std::vector pWorldItems;//dnl ch75 271013 - UINT32 cnt; - INT32 sNewGridNo; + UINT32 uiNumberOfItems = 0; + std::vector pWorldItems; //Get the number of items from the file - if( !GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &uiNumberOfItems, TRUE ) ) + const auto i = FindWorldItemSector(sMapX, sMapY, bMapZ); + if (i == -1) { - //Error getting the numbers of the items from the sector - return( FALSE ); - } - - if( uiNumberOfItems ) - { - pWorldItems.resize(uiNumberOfItems);//dnl ch75 271013 + //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 ) ) + 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!! @@ -1573,23 +1586,15 @@ BOOLEAN LoadAndAddWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) //Destroy the current sectors item table TrashWorldItems(); - - //Add each item to the pool, handle below, outside of the if } //there are no items in the file - return( TRUE ); - } - - //Load the World Items from the file - if( !LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pWorldItems ) ) - { - return( FALSE ); + return(TRUE); } //If we have already been to the sector - if( GetSectorFlagStatus( sMapX, sMapY, bMapZ, SF_ALREADY_LOADED ) ) + 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!! @@ -1606,19 +1611,20 @@ BOOLEAN LoadAndAddWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) // //Loop through all the items loaded from the file - for( cnt=0; cnt< uiNumberOfItems; cnt++) + INT32 sNewGridNo; + for (UINT32 cnt = 0; cnt < uiNumberOfItems; cnt++) { //If the item in the array is valid - if( pWorldItems[cnt].fExists ) + 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 ) + 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 ); - + sNewGridNo = FindNearestAvailableGridNoForItem(pWorldItems[cnt].sGridNo, 5); + + if (TileIsOutOfBounds(sNewGridNo)) + sNewGridNo = FindNearestAvailableGridNoForItem(pWorldItems[cnt].sGridNo, 15); + if (!TileIsOutOfBounds(sNewGridNo)) { pWorldItems[cnt].sGridNo = sNewGridNo; @@ -1626,7 +1632,7 @@ BOOLEAN LoadAndAddWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) } //If the item has an invalid gridno, use the maps entry point - if( pWorldItems[cnt].usFlags & WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT ) + if (pWorldItems[cnt].usFlags & WORLD_ITEM_GRIDNO_NOT_SET_USE_ENTRY_POINT) { pWorldItems[cnt].sGridNo = gMapInformation.sCenterGridNo; @@ -1635,17 +1641,15 @@ BOOLEAN LoadAndAddWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) } //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 ); + AddItemToPool(pWorldItems[cnt].sGridNo, &pWorldItems[cnt].object, pWorldItems[cnt].bVisible, pWorldItems[cnt].ubLevel, pWorldItems[cnt].usFlags, pWorldItems[cnt].bRenderZHeightAboveLevel, pWorldItems[cnt].soldierID); } } - return( TRUE ); + return(TRUE); } - - BOOLEAN AddTempFileToSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ ) { CHAR8 zMapName[ 128 ]; @@ -1773,18 +1777,7 @@ BOOLEAN SaveRottingCorpsesToTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ BOOLEAN DeleteTempItemMapFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) { - UINT8 bSectorId = 0; -// CHAR8 zTempName[ 128 ]; CHAR8 zMapName[ 128 ]; - - // grab the sector id - bSectorId = SECTOR( sMapX, sMapY ); -/* - //Convert the current sector location into a file name - GetMapFileName( sMapX,sMapY, bMapZ, zTempName, FALSE ); - - sprintf( zMapName, "%s\\r_%s", MAPS_DIR, zTempName); -*/ GetMapTempFileName( SF_ITEM_TEMP_FILE_EXISTS, zMapName, sMapX, sMapY, bMapZ ); //Check to see if the file exists @@ -1793,10 +1786,10 @@ BOOLEAN DeleteTempItemMapFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) //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 ); } @@ -1935,126 +1928,6 @@ BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMa } -// Rewritten to load the temp file once, update with the list, and then write it. This was getting insane as items piled up in sectors. -// A few dozen read, update, writes was okay but a few hundred is pushing it. - -BOOLEAN AddWorldItemsToUnLoadedSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT32 sGridNo, UINT32 uiNumberOfItemsToAdd, std::vector& pWorldItem, BOOLEAN fOverWrite )//dnl ch75 271013 -{ - UINT32 uiLoop; - UINT32 uiLastItemPos; - UINT32 uiNumberOfItems; - std::vector pWorldItems;//dnl ch75 271013 - - if( !GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &uiNumberOfItems, TRUE ) ) - { - //Errror getting the numbers of the items from the sector - return( FALSE ); - } - - //Allocate memory for the item - pWorldItems.resize(uiNumberOfItems);//dnl ch75 271013 - - //Load in the sectors Item Info - if( !LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pWorldItems ) ) - { - //error reading in the items from the Item mod file - return( FALSE ); - } - - //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 pWorldItems;//dnl ch75 271013 - UINT32 cnt; - UINT32 uiNumberOfActive=0; - BOOLEAN fFileLoaded = FALSE; - UNDERGROUND_SECTORINFO *TempNode = gpUndergroundSectorInfoHead; - - - // - // Load in the sectors ITems - // - - //If there is a file, load in the Items array - if( bMapZ == 0 ) - { - if( SectorInfo[ SECTOR( sMapX,sMapY) ].uiFlags & SF_ITEM_TEMP_FILE_EXISTS ) - fFileLoaded = TRUE; - } - else - { - while( TempNode ) - { - if( TempNode->ubSectorX == sMapX && TempNode->ubSectorY == sMapY && TempNode->ubSectorZ == bMapZ ) - { - if( TempNode->uiFlags & SF_ITEM_TEMP_FILE_EXISTS ) - fFileLoaded = TRUE; - - break; - } - - TempNode = TempNode->next; - } - } - - if( fFileLoaded ) - { - //Get the number of items from the file - if( !GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &uiNumberOfItems, TRUE ) ) - { - //Error getting the numbers of the items from the sector - return( FALSE ); - } - - //If there items in the data file - if( uiNumberOfItems != 0 ) - { - pWorldItems.resize(uiNumberOfItems);//dnl ch75 271013 - - //Load the World Items from the file - if( !LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pWorldItems ) ) - return( FALSE ); - - uiNumberOfActive = 0; - for( cnt=0; cnt pTotalSectorList;//dnl ch75 271013 - UINT32 uiItemCount = 0; - UINT32 iCounter = 0; - BOOLEAN fReturn; - - /* - // get total number, visable and invisible - fReturn = GetNumberOfActiveWorldItemsFromTempFile( sMapX, sMapY, bMapZ, &( uiTotalNumberOfRealItems ) ); - if (fReturn == TRUE) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("GetNumberOfActiveWorldItemsFromTempFile failed" ) ); - Assert( fReturn ); - }*/ - - fReturn = GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &( uiTotalNumberOfItems ), FALSE ); - if (fReturn == TRUE) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("GetNumberOfWorldItemsFromTempItemFile failed" ) ); - Assert( fReturn ); - } - - if( uiTotalNumberOfItems > 0 ) - { - // allocate space for the list - pTotalSectorList.resize(uiTotalNumberOfItems);//dnl ch75 271013 - - // now load into mem - LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pTotalSectorList ); - - // now run through list and - //for( iCounter = 0; ( UINT32 )( iCounter )< uiTotalNumberOfRealItems; iCounter++ ) - for ( iCounter = 0; iCounter < uiTotalNumberOfItems; ++iCounter ) - { - // if visible to player, then state fact - if ( IsMapScreenWorldItemVisibleInMapInventory( &pTotalSectorList[iCounter] ) ) - { - uiItemCount += pTotalSectorList[iCounter].object.ubNumberOfObjects; - } - } - - // Flugente: if we load a game, we would save the data again in UpdateWorldItemsTempFile. - // But that function simply loads the data again and writes it. If we do the saving here, we can at least save the entire 'load it again' part - if ( fLoadingGame && guiCurrentSaveGameVersion != SAVE_GAME_VERSION ) - { - int backup = guiCurrentSaveGameVersion; - guiCurrentSaveGameVersion = SAVE_GAME_VERSION; - SaveWorldItemsToTempItemFile( sMapX, sMapY, bMapZ, uiTotalNumberOfItems, pTotalSectorList ); - guiCurrentSaveGameVersion = backup; - } - } - -#ifdef JA2BETAVERSION - if( fLoadingGame && guiCurrentSaveGameVersion >= 86 ) - { - UINT32 uiReported = GetNumberOfVisibleWorldItemsFromSectorStructureForSector( sMapX, sMapY, bMapZ ); - - if( uiItemCount != uiReported ) - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"SynchronizeItemTempFile() Error! Reported %d, should be %d", uiReported, uiItemCount ); - } -#endif - - //record the number of items - SetNumberOfVisibleWorldItemsInSectorStructureForSector( sMapX, sMapY, bMapZ, uiItemCount ); -} UINT32 UpdateLoadedSectorsItemInventory( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems ) { @@ -3441,3 +3174,40 @@ UINT32 UpdateLoadedSectorsItemInventory( INT16 sMapX, INT16 sMapY, INT8 bMapZ, U //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 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); + } +} diff --git a/Tactical/Tactical Save.h b/Tactical/Tactical Save.h index d6da8de6..6f60237a 100644 --- a/Tactical/Tactical Save.h +++ b/Tactical/Tactical Save.h @@ -52,10 +52,6 @@ BOOLEAN LoadCurrentSectorsInformationFromTempItemsFile(); // Loads a World Item array from that sectors temp item file BOOLEAN LoadWorldItemsFromTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, std::vector& pData );//dnl ch75 271013 -BOOLEAN SaveWorldItemsToTempItemFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 uiNumberOfItems, std::vector& pData, BOOLEAN fUpdateVisibleItems=TRUE );//dnl ch75 271013 - -//When the savegame version changes, load the temp files, then immediately save them again in the new format -BOOLEAN UpdateWorldItemsTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ); // Adds an array of Item Objects to the specified location on a unloaded map. // If you want to overwrite all the items in the array set fReplaceEntireFile to TRUE. @@ -68,9 +64,6 @@ BOOLEAN AddWorldItemsToUnLoadedSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT BOOLEAN InitTacticalSave( BOOLEAN fCreateTempDir ); -//Gets the number of ACTIVE ( Not the TOTAL number ) of World Items from the sectors temp file -BOOLEAN GetNumberOfActiveWorldItemsFromTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ, UINT32 *pNumberOfData ); - //Call this function to set the new sector a NPC will travel to void ChangeNpcToDifferentSector( UINT8 ubNpcId, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); diff --git a/Tactical/World Items.cpp b/Tactical/World Items.cpp index 404ff38e..8feac68c 100644 --- a/Tactical/World Items.cpp +++ b/Tactical/World Items.cpp @@ -35,6 +35,130 @@ //Global dynamic array of all of the items in a loaded map. std::vector gWorldItems;//dnl ch75 261013 UINT32 guiNumWorldItems = 0; +WorldItems gAllWorldItems; // World items for all unloaded sectors + +INT32 FindWorldItemSector(INT16 x, INT16 y, INT16 z) +{ + for (size_t i = 0; i < gAllWorldItems.sectors.size(); i++) + { + const auto sector = gAllWorldItems.sectors[i]; + if (sector.x == x && sector.y == y && sector.z == z) + { + return i; + } + } + return -1; +} + +bool SectorIsInWorldItems(INT16 x, INT16 y, INT16 z) +{ + for (size_t i = 0; i < gAllWorldItems.sectors.size(); i++) + { + const auto sector = gAllWorldItems.sectors[i]; + if (sector.x == x && sector.y == y && sector.z == z) + { + return true; + } + } + return false; +} + +void AddSectorItemsToWorldItems(INT16 x, INT16 y, INT16 z, UINT32 nItems, std::vector &Items) +{ + gAllWorldItems.sectors.push_back(SectorCoords{ x, y, z }); + gAllWorldItems.NumItems.push_back(nItems); + gAllWorldItems.Items.push_back(Items); +} + +void RemoveSectorFromWorldItems(INT16 x, INT16 y, INT16 z) +{ + for (size_t i = 0; i < gAllWorldItems.sectors.size(); i++) + { + const auto sector = gAllWorldItems.sectors[i]; + if (sector.x == x && sector.y == y && sector.z == z) + { + gAllWorldItems.sectors.erase(gAllWorldItems.sectors.begin() + i); + gAllWorldItems.NumItems.erase(gAllWorldItems.NumItems.begin() + i); + gAllWorldItems.Items.erase(gAllWorldItems.Items.begin() + i); + } + } +} + +void UpdateWorldItems(INT16 x, INT16 y, INT16 z, UINT32 nItems, std::vector &Items) +{ + if (nItems == 0) + { + RemoveSectorFromWorldItems(x, y, z); + ReSetSectorFlag(x, y, z, SF_ITEM_TEMP_FILE_EXISTS); + } + else if (SectorIsInWorldItems(x, y, z)) + { + const auto i = FindWorldItemSector(x, y, z); + gAllWorldItems.NumItems[i] = nItems; + gAllWorldItems.Items[i] = Items; + } + else + { + AddSectorItemsToWorldItems(x, y, z, nItems, Items); + SetSectorFlag(x, y, z, SF_ITEM_TEMP_FILE_EXISTS); + } + + UINT32 visibleItemCount = 0; + for (size_t i = 0; i < nItems; ++i) + { + // if visible to player, then state fact + if (IsMapScreenWorldItemVisibleInMapInventory(&Items[i])) + { + visibleItemCount += Items[i].object.ubNumberOfObjects; + } + } + SetNumberOfVisibleWorldItemsInSectorStructureForSector(x, y, z, visibleItemCount); +} + +void ClearAllWorldItems(void) +{ + gAllWorldItems.sectors.clear(); + gAllWorldItems.NumItems.clear(); + gAllWorldItems.Items.clear(); +} + +INT32 GetAmountOfWorldItems(INT16 x, INT16 y, INT16 z) +{ + const auto i = FindWorldItemSector(x,y, z); + if (i != -1) + { + return gAllWorldItems.NumItems[i]; + } + else + { + return 0; + } +} + +void PruneWorldItems(void) +{ + for (size_t i = 0; i < gAllWorldItems.Items.size(); i++) + { + std::vector& items = gAllWorldItems.Items[i]; + for (INT32 j = items.size()-1; j > 0; j--) + { + if (items[j].fExists == false) + { + items.erase(items.begin()+j); + } + } + if (gAllWorldItems.Items[i].size() > 0) + { + gAllWorldItems.NumItems[i] = gAllWorldItems.Items[i].size(); + } + else + { + gAllWorldItems.sectors.erase(gAllWorldItems.sectors.begin() + i); + gAllWorldItems.NumItems.erase(gAllWorldItems.NumItems.begin() + i); + gAllWorldItems.Items.erase(gAllWorldItems.Items.begin() + i); + } + } +} WORLDBOMB * gWorldBombs = NULL; UINT32 guiNumWorldBombs = 0; diff --git a/Tactical/World Items.h b/Tactical/World Items.h index c4cef6f1..dd841f44 100644 --- a/Tactical/World Items.h +++ b/Tactical/World Items.h @@ -139,4 +139,22 @@ void ResizeWorldItems(void);//dnl ch75 271013 void RefreshWorldItemsIntoItemPools( std::vector& pItemList, INT32 iNumberOfItems );//dnl ch75 271013 void CoolDownWorldItems( ); // Flugente: Cool/decay down all items in this sector +struct SectorCoords +{ + INT16 x; + INT16 y; + INT16 z; +}; + +struct WorldItems +{ + std::vector sectors; + std::vector NumItems; + std::vector> Items; +}; +void UpdateWorldItems(INT16 x, INT16 y, INT16 z, UINT32 nItems, std::vector &Items); +void AddSectorItemsToWorldItems(INT16 x, INT16 y, INT16 z, UINT32 nItems, std::vector &Items); +INT32 FindWorldItemSector(INT16 x, INT16 y, INT16 z); +bool SectorIsInWorldItems(INT16 x, INT16 y, INT16 z); + #endif