World items patch (by Asdow).

Adds timing logs to savegame function, similar to how we already had in loading a save file. 
Uses a global struct for unloaded sectors' inventory instead of using map item temp files every time unloaded inventory is accessed.
From timing loading and saving functions with a save that has dozens of sectors with hundreds of items each, saving is a little bit slower than before, because map item temp files have to be written to disk just before the save, when that wasn't the case before (from ~0.3 s -> ~0.5s). It is offset by a decrease in loading a game (from ~1.1s -> 0.745s), once an older save is saved at least once. Any unloaded sector inventory access during gameplay is considerably faster and for example the autoresolve lag when militia is using sector equipment is completely gone for me.
Preserves save game compatibility

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9277 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Sevenfm
2022-01-26 01:02:30 +00:00
parent be14552e32
commit 0fdaba84f6
13 changed files with 590 additions and 599 deletions
+12 -12
View File
@@ -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
+16 -32
View File
@@ -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<WORLDITEM> 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<WORLDITEM> 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 ...
{
+12 -15
View File
@@ -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;
}
@@ -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();
+13 -15
View File
@@ -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<WORLDITEM> 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<WORLDITEM> 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 );
}
}
+7 -5
View File
@@ -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 )
{
+1 -2
View File
@@ -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));