diff --git a/Tactical/Air Raid.cpp b/Tactical/Air Raid.cpp index 1ca63ce9..4c2c8df5 100644 --- a/Tactical/Air Raid.cpp +++ b/Tactical/Air Raid.cpp @@ -288,7 +288,9 @@ BOOLEAN BeginAirRaid( ) gfAirRaidHasHadTurn = FALSE; gpRaidSoldier = MercPtrs[ MAX_NUM_SOLDIERS - 1 ]; - memset( gpRaidSoldier, 0, sizeof( SOLDIERTYPE ) ); + // WDS - Clean up inventory handling + //memset( gpRaidSoldier, 0, SIZEOF_SOLDIERTYPE ); + gpRaidSoldier->initialize(); gpRaidSoldier->bLevel = 0; gpRaidSoldier->bTeam = 1; gpRaidSoldier->bSide = 1; diff --git a/Tactical/Enemy Soldier Save.cpp b/Tactical/Enemy Soldier Save.cpp index feb32caa..4e59e380 100644 --- a/Tactical/Enemy Soldier Save.cpp +++ b/Tactical/Enemy Soldier Save.cpp @@ -259,14 +259,17 @@ BOOLEAN LoadEnemySoldiersFromTempFile() for( i = 0; i < slots; i++ ) { - FileRead( hfile, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ), &uiNumBytesRead ); - if( uiNumBytesRead != sizeof( SOLDIERCREATE_STRUCT ) ) + // WDS - Clean up inventory handling + FileRead( hfile, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesRead ); + if( uiNumBytesRead != SIZEOF_SOLDIERCREATE_STRUCT_POD) { #ifdef JA2TESTVERSION sprintf( zReason, "EnemySoldier -- EOF while reading tempDetailedPlacment %d. KM", i ); #endif goto FAIL_LOAD; } + tempDetailedPlacement.CopyOldInventoryToNew(); + curr = gSoldierInitHead; while( curr ) { @@ -279,10 +282,11 @@ BOOLEAN LoadEnemySoldiersFromTempFile() curr->pBasicPlacement->fPriorityExistance = TRUE; if( !curr->pDetailedPlacement ) { //need to upgrade the placement to detailed placement - curr->pDetailedPlacement = (SOLDIERCREATE_STRUCT*)MemAlloc( sizeof( SOLDIERCREATE_STRUCT ) ); + curr->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT; //(SOLDIERCREATE_STRUCT*)MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT ); } //now replace the map pristine placement info with the temp map file version.. - memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ) ); + //memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT ); + *curr->pDetailedPlacement = tempDetailedPlacement; curr->pBasicPlacement->fPriorityExistance = TRUE; curr->pBasicPlacement->bDirection = curr->pDetailedPlacement->bDirection; @@ -470,8 +474,10 @@ BOOLEAN SaveEnemySoldiersToTempFile( INT16 sSectorX, INT16 sSectorY, INT8 bSecto if( !curr->pDetailedPlacement ) { //need to upgrade the placement to detailed placement curr->pBasicPlacement->fDetailedPlacement = TRUE; - curr->pDetailedPlacement = (SOLDIERCREATE_STRUCT*)MemAlloc( sizeof( SOLDIERCREATE_STRUCT ) ); - memset( curr->pDetailedPlacement, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + curr->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT; //(SOLDIERCREATE_STRUCT*)MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT ); + //memset( curr->pDetailedPlacement, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + curr->pDetailedPlacement->initialize(); } //Copy over the data of the soldier. @@ -542,7 +548,9 @@ BOOLEAN SaveEnemySoldiersToTempFile( INT16 sSectorX, INT16 sSectorY, INT8 bSecto sprintf( curr->pDetailedPlacement->MiscPal, pSoldier->MiscPal ); //copy soldier's inventory - memcpy( curr->pDetailedPlacement->Inv, pSoldier->inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); + // WDS - Clean up inventory handling + //memcpy( curr->pDetailedPlacement->Inv, pSoldier->inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); + curr->pDetailedPlacement->Inv = pSoldier->inv; } //DONE, now increment the counter, so we know how many there are. @@ -693,8 +701,10 @@ BOOLEAN SaveEnemySoldiersToTempFile( INT16 sSectorX, INT16 sSectorY, INT8 bSecto } if( curr && curr->pSoldier == pSoldier && pSoldier->ubProfile == NO_PROFILE ) { //found a match. - FileWrite( hfile, curr->pDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ), &uiNumBytesWritten ); - if( uiNumBytesWritten != sizeof( SOLDIERCREATE_STRUCT ) ) + // WDS - Clean up inventory handling + curr->pDetailedPlacement->CopyNewInventoryToOld(); + FileWrite( hfile, curr->pDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesWritten ); + if( uiNumBytesWritten != SIZEOF_SOLDIERCREATE_STRUCT_POD) { goto FAIL_SAVE; } @@ -979,14 +989,16 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile() for( i = 0; i < slots; i++ ) { - FileRead( hfile, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ), &uiNumBytesRead ); - if( uiNumBytesRead != sizeof( SOLDIERCREATE_STRUCT ) ) + // WDS - Clean up inventory handling + FileRead( hfile, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesRead ); + if( uiNumBytesRead != SIZEOF_SOLDIERCREATE_STRUCT_POD) { #ifdef JA2TESTVERSION sprintf( zReason, "EnemySoldier -- EOF while reading tempDetailedPlacment %d. KM", i ); #endif goto FAIL_LOAD; } + tempDetailedPlacement.CopyOldInventoryToNew(); curr = gSoldierInitHead; while( curr ) { @@ -997,10 +1009,11 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile() curr->pBasicPlacement->fPriorityExistance = TRUE; if( !curr->pDetailedPlacement ) { //need to upgrade the placement to detailed placement - curr->pDetailedPlacement = (SOLDIERCREATE_STRUCT*)MemAlloc( sizeof( SOLDIERCREATE_STRUCT ) ); + curr->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT; //(SOLDIERCREATE_STRUCT*)MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT ); } //now replace the map pristine placement info with the temp map file version.. - memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ) ); + //memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT ); + *curr->pDetailedPlacement = tempDetailedPlacement; curr->pBasicPlacement->fPriorityExistance = TRUE; curr->pBasicPlacement->bDirection = curr->pDetailedPlacement->bDirection; @@ -1332,14 +1345,16 @@ BOOLEAN NewWayOfLoadingCiviliansFromTempFile() for( i = 0; i < slots; i++ ) { - FileRead( hfile, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ), &uiNumBytesRead ); - if( uiNumBytesRead != sizeof( SOLDIERCREATE_STRUCT ) ) + // WDS - Clean up inventory handling + FileRead( hfile, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesRead ); + if( uiNumBytesRead != SIZEOF_SOLDIERCREATE_STRUCT_POD) { #ifdef JA2TESTVERSION sprintf( zReason, "Civilian -- EOF while reading tempDetailedPlacment %d. KM", i ); #endif goto FAIL_LOAD; } + tempDetailedPlacement.CopyOldInventoryToNew(); curr = gSoldierInitHead; while( curr ) { @@ -1354,10 +1369,11 @@ BOOLEAN NewWayOfLoadingCiviliansFromTempFile() if( !curr->pDetailedPlacement ) { //need to upgrade the placement to detailed placement - curr->pDetailedPlacement = (SOLDIERCREATE_STRUCT*)MemAlloc( sizeof( SOLDIERCREATE_STRUCT ) ); + curr->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT; } //now replace the map pristine placement info with the temp map file version.. - memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ) ); + //memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT ); + *curr->pDetailedPlacement = tempDetailedPlacement; curr->pBasicPlacement->fPriorityExistance = TRUE; curr->pBasicPlacement->bDirection = curr->pDetailedPlacement->bDirection; @@ -1565,8 +1581,10 @@ BOOLEAN NewWayOfSavingEnemyAndCivliansToTempFile( INT16 sSectorX, INT16 sSectorY if( !curr->pDetailedPlacement ) { //need to upgrade the placement to detailed placement curr->pBasicPlacement->fDetailedPlacement = TRUE; - curr->pDetailedPlacement = (SOLDIERCREATE_STRUCT*)MemAlloc( sizeof( SOLDIERCREATE_STRUCT ) ); - memset( curr->pDetailedPlacement, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + curr->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT; + curr->pDetailedPlacement->initialize(); + //memset( curr->pDetailedPlacement, 0, SIZEOF_SOLDIERCREATE_STRUCT ); } //Copy over the data of the soldier. @@ -1625,7 +1643,9 @@ BOOLEAN NewWayOfSavingEnemyAndCivliansToTempFile( INT16 sSectorX, INT16 sSectorY sprintf( curr->pDetailedPlacement->MiscPal, pSoldier->MiscPal ); //copy soldier's inventory - memcpy( curr->pDetailedPlacement->Inv, pSoldier->inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); + // WDS - Clean up inventory handling + //memcpy( curr->pDetailedPlacement->Inv, pSoldier->inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); + curr->pDetailedPlacement->Inv = pSoldier->inv; } } @@ -1759,8 +1779,10 @@ BOOLEAN NewWayOfSavingEnemyAndCivliansToTempFile( INT16 sSectorX, INT16 sSectorY if( curr && curr->pSoldier == pSoldier && pSoldier->ubProfile == NO_PROFILE ) { //found a match. - FileWrite( hfile, curr->pDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ), &uiNumBytesWritten ); - if( uiNumBytesWritten != sizeof( SOLDIERCREATE_STRUCT ) ) + // WDS - Clean up inventory handling + curr->pDetailedPlacement->CopyNewInventoryToOld(); + FileWrite( hfile, curr->pDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesWritten ); + if( uiNumBytesWritten != SIZEOF_SOLDIERCREATE_STRUCT_POD ) { goto FAIL_SAVE; } @@ -1996,14 +2018,16 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( for( i = 0; i < slots; i++ ) { - FileRead( hfile, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ), &uiNumBytesRead ); - if( uiNumBytesRead != sizeof( SOLDIERCREATE_STRUCT ) ) + // WDS - Clean up inventory handling + FileRead( hfile, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesRead ); + if( uiNumBytesRead != SIZEOF_SOLDIERCREATE_STRUCT_POD) { #ifdef JA2TESTVERSION sprintf( zReason, "Check EnemySoldier -- EOF while reading tempDetailedPlacment %d. KM", i ); #endif goto FAIL_LOAD; } + tempDetailedPlacement.CopyOldInventoryToNew(); //increment the current type of soldier switch( tempDetailedPlacement.ubSoldierClass ) @@ -2038,13 +2062,15 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( { if( curr->pBasicPlacement->bTeam == tempDetailedPlacement.bTeam ) { + // WDS - Clean up inventory handling curr->pBasicPlacement->fPriorityExistance = TRUE; if( !curr->pDetailedPlacement ) { //need to upgrade the placement to detailed placement - curr->pDetailedPlacement = (SOLDIERCREATE_STRUCT*)MemAlloc( sizeof( SOLDIERCREATE_STRUCT ) ); + curr->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT; } //now replace the map pristine placement info with the temp map file version.. - memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ) ); +// memcpy( curr->pDetailedPlacement, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT ); + *curr->pDetailedPlacement = tempDetailedPlacement; curr->pBasicPlacement->fPriorityExistance = TRUE; curr->pBasicPlacement->bDirection = curr->pDetailedPlacement->bDirection; diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index a374fba4..2e5cacc3 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -5243,7 +5243,9 @@ INT16 FindNearestAvailableGridNoForItem( INT16 sSweetGridNo, INT8 ubRadius ) //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + // WDS - Clean up inventory handling + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; @@ -5359,7 +5361,8 @@ UINT8 StealItems(SOLDIERTYPE* pSoldier,SOLDIERTYPE* pOpponent, UINT8* ubIndexRet { fStealItem = FALSE; - pObject=pOpponent->inv+i; + // WDS - Clean up inventory handling + pObject=&pOpponent->inv[i]; if (pObject->usItem!=0) { // Is the enemy collapsed @@ -5473,8 +5476,10 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, cnt++; if ( fPickup ) { + // WDS - Clean up inventory handling // Make copy of item - memcpy( &Object, pOpponent->inv+pTempItemPool->iItemIndex, sizeof( OBJECTTYPE ) ); +// memcpy( &Object, pOpponent->inv+pTempItemPool->iItemIndex, sizeof( OBJECTTYPE ) ); + Object = pOpponent->inv[pTempItemPool->iItemIndex]; if ( ItemIsCool( &Object ) ) { fShouldSayCoolQuote = TRUE; @@ -5483,7 +5488,7 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, { AddItemToPool( pSoldier->sGridNo, &Object, 1, pSoldier->bLevel, 0, -1 ); } - DeleteObj(pOpponent->inv+pTempItemPool->iItemIndex); + DeleteObj(&pOpponent->inv[pTempItemPool->iItemIndex]); } pTempItemPool = pTempItemPool->pNext; } diff --git a/Tactical/Handle Items.h b/Tactical/Handle Items.h index 29a24551..2846b314 100644 --- a/Tactical/Handle Items.h +++ b/Tactical/Handle Items.h @@ -1,9 +1,9 @@ #ifndef __HANDLE_ITEMS_H #define __HANDLE_ITEMS_H -#include "Soldier Control.h" #include "World Items.h" #include "structure.h" +#include "Soldier Control.h" #define ITEM_HANDLE_OK 1 #define ITEM_HANDLE_RELOADING -1 @@ -46,6 +46,10 @@ typedef void ( *ITEM_POOL_LOCATOR_HOOK )( void ); +// WDS - Clean up inventory handling +struct WORLDITEM; +struct LEVELNODE; + typedef struct TAG_ITEM_POOL { struct TAG_ITEM_POOL *pNext; @@ -59,7 +63,7 @@ typedef struct TAG_ITEM_POOL UINT8 ubLevel; UINT16 usFlags; INT8 bRenderZHeightAboveLevel; - struct TAG_level_node *pLevelNode; + LEVELNODE *pLevelNode; } ITEM_POOL; @@ -76,7 +80,8 @@ typedef struct } ITEM_POOL_LOCATOR; - +// WDS - Clean up inventory handling +class SOLDIERTYPE; INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 usHandItem, BOOLEAN fFromUI ); void SoldierPickupItem( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGridNo, INT8 bZLevel ); void HandleSoldierPickupItem( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGridNo, INT8 bZLevel ); diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index 44b7b009..ef760831 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -6502,7 +6502,8 @@ void SetupPickupPage( INT8 bPage ) { gItemPickupMenu.ItemPoolSlots[ cnt - iStart ] = pTempItemPool; - pObject = (gfStealing)? gpOpponent->inv+pTempItemPool->iItemIndex + // WDS - Clean up inventory handling + pObject = (gfStealing)? &gpOpponent->inv[pTempItemPool->iItemIndex] :&(gWorldItems[ pTempItemPool->iItemIndex ].o ); sValue = pObject->bStatus[ 0 ]; @@ -6679,7 +6680,8 @@ void RenderItemPickupMenu( ) if ( gItemPickupMenu.ItemPoolSlots[ cnt ] != NULL ) { // Get item to render - pObject = (gfStealing)? gpOpponent->inv+ gItemPickupMenu.ItemPoolSlots[ cnt ]->iItemIndex + // WDS - Clean up inventory handling + pObject = (gfStealing)? &gpOpponent->inv[gItemPickupMenu.ItemPoolSlots[ cnt ]->iItemIndex] :&(gWorldItems[ gItemPickupMenu.ItemPoolSlots[ cnt ]->iItemIndex ].o ); pItem = &( Item[ pObject->usItem ] ); diff --git a/Tactical/Items.h b/Tactical/Items.h index 799d7cb8..15dcaf20 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -12,6 +12,8 @@ extern UINT8 SlotToPocket[7]; +// WDS - Clean up inventory handling +class SOLDIERTYPE; extern BOOLEAN WeaponInHand( SOLDIERTYPE * pSoldier ); extern INT8 FindObj( SOLDIERTYPE * pSoldier, UINT16 usItem ); diff --git a/Tactical/PATHAI.cpp b/Tactical/PATHAI.cpp index c56c163b..dc0e0a45 100644 --- a/Tactical/PATHAI.cpp +++ b/Tactical/PATHAI.cpp @@ -2050,7 +2050,9 @@ void GlobalReachableTest( INT16 sStartGridNo ) SOLDIERTYPE s; INT32 iCurrentGridNo =0; - memset( &s, 0, sizeof( SOLDIERTYPE ) ); + // WDS - Clean up inventory handling + //memset( &s, 0, SIZEOF_SOLDIERTYPE ); + s.initialize(); s.sGridNo = sStartGridNo; s.bLevel = 0; s.bTeam = 1; @@ -2072,7 +2074,9 @@ void LocalReachableTest( INT16 sStartGridNo, INT8 bRadius ) INT32 iCurrentGridNo = 0; INT32 iX, iY; - memset( &s, 0, sizeof( SOLDIERTYPE ) ); + // WDS - Clean up inventory handling + //memset( &s, 0, SIZEOF_SOLDIERTYPE ); + s.initialize(); s.sGridNo = sStartGridNo; //if we are moving on the gorund level @@ -2113,7 +2117,9 @@ void GlobalItemsReachableTest( INT16 sStartGridNo1, INT16 sStartGridNo2 ) SOLDIERTYPE s; INT32 iCurrentGridNo =0; - memset( &s, 0, sizeof( SOLDIERTYPE ) ); + // WDS - Clean up inventory handling + //memset( &s, 0, SIZEOF_SOLDIERTYPE ); + s.initialize(); s.sGridNo = sStartGridNo1; s.bLevel = 0; s.bTeam = 1; @@ -2139,7 +2145,9 @@ void RoofReachableTest( INT16 sStartGridNo, UINT8 ubBuildingID ) SOLDIERTYPE s; INT16 sGridNo; - memset( &s, 0, sizeof( SOLDIERTYPE ) ); + // WDS - Clean up inventory handling + //memset( &s, 0, SIZEOF_SOLDIERTYPE ); + s.initialize(); s.sGridNo = sStartGridNo; s.bLevel = 1; s.bTeam = 1; diff --git a/Tactical/Real Time Input.cpp b/Tactical/Real Time Input.cpp index 434a0d38..79a47e48 100644 --- a/Tactical/Real Time Input.cpp +++ b/Tactical/Real Time Input.cpp @@ -62,6 +62,8 @@ #include "soldier macros.h" #include "render dirty.h" #include "Militia Control.h" +#include "render dirty.h" +#include "Militia Control.h" #endif diff --git a/Tactical/Rotting Corpses.cpp b/Tactical/Rotting Corpses.cpp index e966a6ad..e5fcfdd2 100644 --- a/Tactical/Rotting Corpses.cpp +++ b/Tactical/Rotting Corpses.cpp @@ -1068,8 +1068,10 @@ void AddCrowToCorpse( ROTTING_CORPSE *pCorpse ) return; } + // WDS - Clean up inventory handling // Put him flying over corpse pisition - memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) ); +// memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) ); + MercCreateStruct.initialize(); MercCreateStruct.ubProfile = NO_PROFILE; MercCreateStruct.sSectorX = gWorldSectorX; MercCreateStruct.sSectorY = gWorldSectorY; @@ -1612,9 +1614,11 @@ INT16 FindNearestAvailableGridNoForCorpse( ROTTING_CORPSE_DEFINITION *pDef, INT8 gubNPCAPBudget = 0; gubNPCDistLimit = ubRadius; + // WDS - Clean up inventory handling //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; diff --git a/Tactical/ShopKeeper Interface.cpp b/Tactical/ShopKeeper Interface.cpp index f6ed5ecc..057e4cf7 100644 --- a/Tactical/ShopKeeper Interface.cpp +++ b/Tactical/ShopKeeper Interface.cpp @@ -2897,12 +2897,12 @@ BOOLEAN DetermineArmsDealersSellingInventory( ) if ( ArmsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer == ARMS_DEALER_REPAIRS ) { // sort this list by object category, and by ascending price within each category - qsort( gpTempDealersInventory, guiNextFreeInvSlot, sizeof( INVENTORY_IN_SLOT ), RepairmanItemQsortCompare ); + qsort( (void*)gpTempDealersInventory, (size_t)guiNextFreeInvSlot, sizeof( INVENTORY_IN_SLOT ), RepairmanItemQsortCompare ); } else { // sort this list by object category, and by ascending price within each category - qsort( gpTempDealersInventory, guiNextFreeInvSlot, sizeof( INVENTORY_IN_SLOT ), ArmsDealerItemQsortCompare ); + qsort( (void*)gpTempDealersInventory, (size_t)guiNextFreeInvSlot, sizeof( INVENTORY_IN_SLOT ), ArmsDealerItemQsortCompare ); } } diff --git a/Tactical/Soldier Add.cpp b/Tactical/Soldier Add.cpp index ab57cdad..91e059a2 100644 --- a/Tactical/Soldier Add.cpp +++ b/Tactical/Soldier Add.cpp @@ -72,9 +72,11 @@ UINT16 FindGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT16 sSweetGridNo, INT8 gubNPCAPBudget = 0; gubNPCDistLimit = ubRadius; + // WDS - Clean up inventory handling //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bLevel = 0; soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; @@ -174,9 +176,11 @@ UINT16 FindGridNoFromSweetSpotThroughPeople( SOLDIERTYPE *pSoldier, INT16 sSweet gubNPCAPBudget = 0; gubNPCDistLimit = ubRadius; + // WDS - Clean up inventory handling //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bLevel = 0; soldier.bTeam = pSoldier->bTeam; soldier.sGridNo = sSweetGridNo; @@ -275,9 +279,11 @@ UINT16 FindGridNoFromSweetSpotWithStructData( SOLDIERTYPE *pSoldier, UINT16 usAn gubNPCAPBudget = 0; gubNPCDistLimit = ubRadius; + // WDS - Clean up inventory handling //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bLevel = 0; soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; @@ -438,9 +444,11 @@ UINT16 FindGridNoFromSweetSpotWithStructDataUsingGivenDirectionFirst( SOLDIERTYP gubNPCAPBudget = 0; gubNPCDistLimit = ubRadius; + // WDS - Clean up inventory handling //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bLevel = 0; soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; @@ -617,9 +625,11 @@ UINT16 FindGridNoFromSweetSpotWithStructDataFromSoldier( SOLDIERTYPE *pSoldier, gubNPCAPBudget = 0; gubNPCDistLimit = ubRadius; + // WDS - Clean up inventory handling //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bLevel = 0; soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; @@ -948,9 +958,11 @@ UINT16 FindRandomGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT16 sSweetGridNo, gubNPCAPBudget = 0; gubNPCDistLimit = ubRadius; + // WDS - Clean up inventory handling //create dummy soldier, and use the pathing to determine which nearby slots are //reachable. - memset( &soldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( &soldier, 0, SIZEOF_SOLDIERTYPE ); + soldier.initialize(); soldier.bLevel = 0; soldier.bTeam = 1; soldier.sGridNo = sSweetGridNo; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index bf52190b..da6fe843 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -226,6 +226,498 @@ BATTLESNDS_STRUCT gBattleSndsData[] = "enem", 0, 1, 1, 1, 0, }; +// WDS - Clean up inventory handling +// ---------------------------------------- +// New inventory handling code. +// ---------------------------------------- + +Inventory::Inventory() { + slotCnt = NUM_INV_SLOTS; + inv.reserve(slotCnt); + for (int idx=0; idx < slotCnt; ++idx) { + OBJECTTYPE *filler = new OBJECTTYPE; // Use MEMALLOC? + inv.push_back(*filler); + } + clear(); + Assert (inv.size() == slotCnt); +}; + +Inventory::Inventory(int slotCount) { + slotCnt = slotCount; + inv.reserve(slotCnt); + for (int idx=0; idx < slotCnt; ++idx) { + OBJECTTYPE *filler = new OBJECTTYPE; // Use MEMALLOC? + inv.push_back(*filler); + } + clear(); + Assert (inv.size() == slotCnt); +}; + +Inventory::Inventory(const Inventory& src) { + inv.reserve(slotCnt); + Assert (src.inv.size() == slotCnt); + inv = src.inv; + Assert (inv.size() == slotCnt); +} + +int Inventory::size() const { + Assert (inv.size() == slotCnt); + return slotCnt; +} + + +// Assignment operator +Inventory& Inventory::operator=(const Inventory& src) +{ + // This IF is just for setting breakpoints when trying to figure out inventory item problems. Remove it later + if ((src.inv.size() != slotCnt) || + (inv.size() != slotCnt)) { + int i = 0; // Set BP here if following asserts throw + } + Assert (src.inv.size() == slotCnt); + Assert (inv.size() == slotCnt); + if (this != &src) { + if (inv.size() == 0) { + inv.reserve(slotCnt); + for (int idx=0; idx < slotCnt; ++idx) { + inv.push_back(src.inv[idx]); + } + } else { + clear(); + for (int idx=0; idx < slotCnt; ++idx) { + inv[idx] = src.inv[idx]; + } + } + } + return *this; +} + +Inventory::~Inventory() { +}; + + +OBJECTTYPE& Inventory::operator [] (int idx) { + // This IF is just from setting breakpoints when trying to figure out inventory item problems. Remove it later + if ((idx < 0) || + (idx >= slotCnt) || + (inv.size() != slotCnt)) { + int i = inv.size(); // Set BP here if following asserts throw + } + Assert(idx >= 0); + Assert(idx < slotCnt); + Assert(inv.size() == slotCnt); + return inv[idx]; +}; + +void Inventory::clear() { + Assert (inv.size() == slotCnt); + for (int idx=0; idx < slotCnt; ++idx) { + memset(&inv[idx], 0, sizeof(OBJECTTYPE)); + } +}; + +// ---------------------------------------- + +SOLDIERTYPE::SOLDIERTYPE() { + bNewItemCount.reserve(inv.size()); + bNewItemCycleCount.reserve(inv.size()); + for (int idx=0; idx < (int)inv.size(); ++idx) { + bNewItemCount.push_back(0); + bNewItemCycleCount.push_back(0); + } + initialize(); + + Assert(bNewItemCount.size() == inv.size()); + Assert(bNewItemCycleCount.size() == inv.size()); + + // The following are based on the "old" SOLDIERTYPE struct + // Remove these later + Assert(SIZEOF_SOLDIERTYPE_POD == 2344); + Assert(offsetof( SOLDIERTYPE, bFiller ) == 2305); +} + +// Copy Constructor +SOLDIERTYPE::SOLDIERTYPE(const SOLDIERTYPE& src) { + memcpy(this, &src, SIZEOF_SOLDIERTYPE_POD); + inv = src.inv; + bNewItemCount = src.bNewItemCount; + bNewItemCycleCount = src.bNewItemCycleCount; + + Assert(bNewItemCount.size() == inv.size()); + Assert(bNewItemCycleCount.size() == inv.size()); +} + +// Assignment operator +SOLDIERTYPE& SOLDIERTYPE::operator=(const SOLDIERTYPE& src) +{ + if (this != &src) { + memcpy(this, &src, SIZEOF_SOLDIERTYPE_POD); + inv = src.inv; + bNewItemCount = src.bNewItemCount; + bNewItemCycleCount = src.bNewItemCycleCount; + } + return *this; +} + +// Destructor +SOLDIERTYPE::~SOLDIERTYPE() { +} + +// Initialize the soldier. +// Use this instead of the old method of calling memset! +// Note that the constructor does this automatically. +void SOLDIERTYPE::initialize() { + memset( this, 0, SIZEOF_SOLDIERTYPE_POD); + inv.clear(); + for (int idx=0; idx < (int)inv.size(); ++idx) { + bNewItemCount[idx] = 0; + bNewItemCycleCount[idx] = 0; + } + + Assert(bNewItemCount.size() == inv.size()); + Assert(bNewItemCycleCount.size() == inv.size()); +} + + +// Ugly temporary solution +// +// These two functions map the "old" style inventory (fixed array of ) to the new (a flexibly sized vector). +// If you change names or eliminate some positions or such you need to change these. +// Eventually the need for these functions will disappear. + +void SOLDIERTYPE::CopyOldInventoryToNew() { + // Do not use a loop in case the new inventory slots are arranged differently than the old + inv[HELMETPOS] = DO_NOT_USE_Inv[OldInventory::HELMETPOS]; + inv[VESTPOS] = DO_NOT_USE_Inv[OldInventory::VESTPOS]; + inv[LEGPOS] = DO_NOT_USE_Inv[OldInventory::LEGPOS]; + inv[HEAD1POS] = DO_NOT_USE_Inv[OldInventory::HEAD1POS]; + inv[HEAD2POS] = DO_NOT_USE_Inv[OldInventory::HEAD2POS]; + inv[HANDPOS] = DO_NOT_USE_Inv[OldInventory::HANDPOS]; + inv[SECONDHANDPOS] = DO_NOT_USE_Inv[OldInventory::SECONDHANDPOS]; + inv[BIGPOCK1POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK1POS]; + inv[BIGPOCK2POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK2POS]; + inv[BIGPOCK3POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK3POS]; + inv[BIGPOCK4POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK4POS]; + inv[SMALLPOCK1POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK1POS]; + inv[SMALLPOCK2POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK2POS]; + inv[SMALLPOCK3POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK3POS]; + inv[SMALLPOCK4POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK4POS]; + inv[SMALLPOCK5POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK5POS]; + inv[SMALLPOCK6POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK6POS]; + inv[SMALLPOCK7POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK7POS]; + inv[SMALLPOCK8POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK8POS]; + + bNewItemCount[OldInventory::HELMETPOS] = DO_NOT_USE_bNewItemCount[HELMETPOS]; + bNewItemCount[OldInventory::VESTPOS] = DO_NOT_USE_bNewItemCount[VESTPOS]; + bNewItemCount[OldInventory::LEGPOS] = DO_NOT_USE_bNewItemCount[LEGPOS]; + bNewItemCount[OldInventory::HEAD1POS] = DO_NOT_USE_bNewItemCount[HEAD1POS]; + bNewItemCount[OldInventory::HEAD2POS] = DO_NOT_USE_bNewItemCount[HEAD2POS]; + bNewItemCount[OldInventory::HANDPOS] = DO_NOT_USE_bNewItemCount[HANDPOS]; + bNewItemCount[OldInventory::SECONDHANDPOS] = DO_NOT_USE_bNewItemCount[SECONDHANDPOS]; + bNewItemCount[OldInventory::BIGPOCK1POS] = DO_NOT_USE_bNewItemCount[BIGPOCK1POS]; + bNewItemCount[OldInventory::BIGPOCK2POS] = DO_NOT_USE_bNewItemCount[BIGPOCK2POS]; + bNewItemCount[OldInventory::BIGPOCK3POS] = DO_NOT_USE_bNewItemCount[BIGPOCK3POS]; + bNewItemCount[OldInventory::BIGPOCK4POS] = DO_NOT_USE_bNewItemCount[BIGPOCK4POS]; + bNewItemCount[OldInventory::SMALLPOCK1POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK1POS]; + bNewItemCount[OldInventory::SMALLPOCK2POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK2POS]; + bNewItemCount[OldInventory::SMALLPOCK3POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK3POS]; + bNewItemCount[OldInventory::SMALLPOCK4POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK4POS]; + bNewItemCount[OldInventory::SMALLPOCK5POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK5POS]; + bNewItemCount[OldInventory::SMALLPOCK6POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK6POS]; + bNewItemCount[OldInventory::SMALLPOCK7POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK7POS]; + bNewItemCount[OldInventory::SMALLPOCK8POS] = DO_NOT_USE_bNewItemCount[SMALLPOCK8POS]; + + bNewItemCycleCount[OldInventory::HELMETPOS] = DO_NOT_USE_bNewItemCycleCount[HELMETPOS]; + bNewItemCycleCount[OldInventory::VESTPOS] = DO_NOT_USE_bNewItemCycleCount[VESTPOS]; + bNewItemCycleCount[OldInventory::LEGPOS] = DO_NOT_USE_bNewItemCycleCount[LEGPOS]; + bNewItemCycleCount[OldInventory::HEAD1POS] = DO_NOT_USE_bNewItemCycleCount[HEAD1POS]; + bNewItemCycleCount[OldInventory::HEAD2POS] = DO_NOT_USE_bNewItemCycleCount[HEAD2POS]; + bNewItemCycleCount[OldInventory::HANDPOS] = DO_NOT_USE_bNewItemCycleCount[HANDPOS]; + bNewItemCycleCount[OldInventory::SECONDHANDPOS] = DO_NOT_USE_bNewItemCycleCount[SECONDHANDPOS]; + bNewItemCycleCount[OldInventory::BIGPOCK1POS] = DO_NOT_USE_bNewItemCycleCount[BIGPOCK1POS]; + bNewItemCycleCount[OldInventory::BIGPOCK2POS] = DO_NOT_USE_bNewItemCycleCount[BIGPOCK2POS]; + bNewItemCycleCount[OldInventory::BIGPOCK3POS] = DO_NOT_USE_bNewItemCycleCount[BIGPOCK3POS]; + bNewItemCycleCount[OldInventory::BIGPOCK4POS] = DO_NOT_USE_bNewItemCycleCount[BIGPOCK4POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK1POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK1POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK2POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK2POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK3POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK3POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK4POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK4POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK5POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK5POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK6POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK6POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK7POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK7POS]; + bNewItemCycleCount[OldInventory::SMALLPOCK8POS] = DO_NOT_USE_bNewItemCycleCount[SMALLPOCK8POS]; +} +void SOLDIERTYPE::CopyNewInventoryToOld() { + // Do not use a loop in case the new inventory slots are arranged differently than the old + DO_NOT_USE_Inv[OldInventory::HELMETPOS] = inv[HELMETPOS]; + DO_NOT_USE_Inv[OldInventory::VESTPOS] = inv[VESTPOS]; + DO_NOT_USE_Inv[OldInventory::LEGPOS] = inv[LEGPOS]; + DO_NOT_USE_Inv[OldInventory::HEAD1POS] = inv[HEAD1POS]; + DO_NOT_USE_Inv[OldInventory::HEAD2POS] = inv[HEAD2POS]; + DO_NOT_USE_Inv[OldInventory::HANDPOS] = inv[HANDPOS]; + DO_NOT_USE_Inv[OldInventory::SECONDHANDPOS] = inv[SECONDHANDPOS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK1POS] = inv[BIGPOCK1POS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK2POS] = inv[BIGPOCK2POS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK3POS] = inv[BIGPOCK3POS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK4POS] = inv[BIGPOCK4POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK1POS] = inv[SMALLPOCK1POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK2POS] = inv[SMALLPOCK2POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK3POS] = inv[SMALLPOCK3POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK4POS] = inv[SMALLPOCK4POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK5POS] = inv[SMALLPOCK5POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK6POS] = inv[SMALLPOCK6POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK7POS] = inv[SMALLPOCK7POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK8POS] = inv[SMALLPOCK8POS]; + + DO_NOT_USE_bNewItemCount[OldInventory::HELMETPOS] = bNewItemCount[HELMETPOS]; + DO_NOT_USE_bNewItemCount[OldInventory::VESTPOS] = bNewItemCount[VESTPOS]; + DO_NOT_USE_bNewItemCount[OldInventory::LEGPOS] = bNewItemCount[LEGPOS]; + DO_NOT_USE_bNewItemCount[OldInventory::HEAD1POS] = bNewItemCount[HEAD1POS]; + DO_NOT_USE_bNewItemCount[OldInventory::HEAD2POS] = bNewItemCount[HEAD2POS]; + DO_NOT_USE_bNewItemCount[OldInventory::HANDPOS] = bNewItemCount[HANDPOS]; + DO_NOT_USE_bNewItemCount[OldInventory::SECONDHANDPOS] = bNewItemCount[SECONDHANDPOS]; + DO_NOT_USE_bNewItemCount[OldInventory::BIGPOCK1POS] = bNewItemCount[BIGPOCK1POS]; + DO_NOT_USE_bNewItemCount[OldInventory::BIGPOCK2POS] = bNewItemCount[BIGPOCK2POS]; + DO_NOT_USE_bNewItemCount[OldInventory::BIGPOCK3POS] = bNewItemCount[BIGPOCK3POS]; + DO_NOT_USE_bNewItemCount[OldInventory::BIGPOCK4POS] = bNewItemCount[BIGPOCK4POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK1POS] = bNewItemCount[SMALLPOCK1POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK2POS] = bNewItemCount[SMALLPOCK2POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK3POS] = bNewItemCount[SMALLPOCK3POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK4POS] = bNewItemCount[SMALLPOCK4POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK5POS] = bNewItemCount[SMALLPOCK5POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK6POS] = bNewItemCount[SMALLPOCK6POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK7POS] = bNewItemCount[SMALLPOCK7POS]; + DO_NOT_USE_bNewItemCount[OldInventory::SMALLPOCK8POS] = bNewItemCount[SMALLPOCK8POS]; + + DO_NOT_USE_bNewItemCycleCount[OldInventory::HELMETPOS] = bNewItemCycleCount[HELMETPOS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::VESTPOS] = bNewItemCycleCount[VESTPOS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::LEGPOS] = bNewItemCycleCount[LEGPOS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::HEAD1POS] = bNewItemCycleCount[HEAD1POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::HEAD2POS] = bNewItemCycleCount[HEAD2POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::HANDPOS] = bNewItemCycleCount[HANDPOS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SECONDHANDPOS] = bNewItemCycleCount[SECONDHANDPOS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::BIGPOCK1POS] = bNewItemCycleCount[BIGPOCK1POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::BIGPOCK2POS] = bNewItemCycleCount[BIGPOCK2POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::BIGPOCK3POS] = bNewItemCycleCount[BIGPOCK3POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::BIGPOCK4POS] = bNewItemCycleCount[BIGPOCK4POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK1POS] = bNewItemCycleCount[SMALLPOCK1POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK2POS] = bNewItemCycleCount[SMALLPOCK2POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK3POS] = bNewItemCycleCount[SMALLPOCK3POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK4POS] = bNewItemCycleCount[SMALLPOCK4POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK5POS] = bNewItemCycleCount[SMALLPOCK5POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK6POS] = bNewItemCycleCount[SMALLPOCK6POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK7POS] = bNewItemCycleCount[SMALLPOCK7POS]; + DO_NOT_USE_bNewItemCycleCount[OldInventory::SMALLPOCK8POS] = bNewItemCycleCount[SMALLPOCK8POS]; +} + +// ---------------------------------------- + +MERCPROFILESTRUCT::MERCPROFILESTRUCT() { + inv.reserve(NUM_INV_SLOTS); + bInvStatus.reserve(NUM_INV_SLOTS); + bInvNumber.reserve(NUM_INV_SLOTS); + for (int idx=0; idx < NUM_INV_SLOTS; ++idx) { + inv.push_back(0); + bInvStatus.push_back(0); + bInvNumber.push_back(0); + } + initialize(); + + Assert(inv.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); + + // The following are based on the "old" MERCPROFILESTRUCT struct + // Remove these later + Assert(SIZEOF_MERCPROFILESTRUCT_POD == 0x2cc); //sizeof(OLD_MERCPROFILESTRUCT)); +} + +// Copy Constructor +MERCPROFILESTRUCT::MERCPROFILESTRUCT(const MERCPROFILESTRUCT& src) { + memcpy(this, &src, SIZEOF_MERCPROFILESTRUCT_POD); + inv = src.inv; + bInvStatus = src.bInvStatus; + bInvNumber = src.bInvNumber; + + Assert(inv.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); +} + +// Assignment operator +MERCPROFILESTRUCT& MERCPROFILESTRUCT::operator=(const MERCPROFILESTRUCT& src) +{ + if (this != &src) { + memcpy(this, &src, SIZEOF_MERCPROFILESTRUCT_POD); + inv = src.inv; + bInvStatus = src.bInvStatus; + bInvNumber = src.bInvNumber; + } + Assert(inv.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); + return *this; +} + +// Destructor +MERCPROFILESTRUCT::~MERCPROFILESTRUCT() { +} + +// Initialize the soldier. +// Use this instead of the old method of calling memset! +// Note that the constructor does this automatically. +void MERCPROFILESTRUCT::initialize() { + memset( this, 0, SIZEOF_MERCPROFILESTRUCT_POD); + clearInventory(); + Assert(inv.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); +} + +// Initialize the soldier. +// Use this instead of the old method of calling memset! +// Note that the constructor does this automatically. +void MERCPROFILESTRUCT::clearInventory() { + for (int idx=0; idx < (int)inv.size(); ++idx) { + inv[idx] = 0; + bInvStatus[idx] = 0; + bInvNumber[idx] = 0; + } + Assert(inv.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); + Assert(bInvStatus.size() == NUM_INV_SLOTS); +} + +// Ugly temporary solution +// +// These two functions map the "old" style inventory (fixed array of ) to the new (a flexibly sized vector). +// If you change names or eliminate some positions or such you need to change these. +// Eventually the need for these functions will disappear. + +void MERCPROFILESTRUCT::CopyOldInventoryToNew() { + // Do not use a loop in case the new inventory slots are arranged differently than the old + inv[HELMETPOS] = DO_NOT_USE_inv[OldInventory::HELMETPOS]; + inv[VESTPOS] = DO_NOT_USE_inv[OldInventory::VESTPOS]; + inv[LEGPOS] = DO_NOT_USE_inv[OldInventory::LEGPOS]; + inv[HEAD1POS] = DO_NOT_USE_inv[OldInventory::HEAD1POS]; + inv[HEAD2POS] = DO_NOT_USE_inv[OldInventory::HEAD2POS]; + inv[HANDPOS] = DO_NOT_USE_inv[OldInventory::HANDPOS]; + inv[SECONDHANDPOS] = DO_NOT_USE_inv[OldInventory::SECONDHANDPOS]; + inv[BIGPOCK1POS] = DO_NOT_USE_inv[OldInventory::BIGPOCK1POS]; + inv[BIGPOCK2POS] = DO_NOT_USE_inv[OldInventory::BIGPOCK2POS]; + inv[BIGPOCK3POS] = DO_NOT_USE_inv[OldInventory::BIGPOCK3POS]; + inv[BIGPOCK4POS] = DO_NOT_USE_inv[OldInventory::BIGPOCK4POS]; + inv[SMALLPOCK1POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK1POS]; + inv[SMALLPOCK2POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK2POS]; + inv[SMALLPOCK3POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK3POS]; + inv[SMALLPOCK4POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK4POS]; + inv[SMALLPOCK5POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK5POS]; + inv[SMALLPOCK6POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK6POS]; + inv[SMALLPOCK7POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK7POS]; + inv[SMALLPOCK8POS] = DO_NOT_USE_inv[OldInventory::SMALLPOCK8POS]; + + bInvStatus[OldInventory::HELMETPOS] = DO_NOT_USE_bInvStatus[HELMETPOS]; + bInvStatus[OldInventory::VESTPOS] = DO_NOT_USE_bInvStatus[VESTPOS]; + bInvStatus[OldInventory::LEGPOS] = DO_NOT_USE_bInvStatus[LEGPOS]; + bInvStatus[OldInventory::HEAD1POS] = DO_NOT_USE_bInvStatus[HEAD1POS]; + bInvStatus[OldInventory::HEAD2POS] = DO_NOT_USE_bInvStatus[HEAD2POS]; + bInvStatus[OldInventory::HANDPOS] = DO_NOT_USE_bInvStatus[HANDPOS]; + bInvStatus[OldInventory::SECONDHANDPOS] = DO_NOT_USE_bInvStatus[SECONDHANDPOS]; + bInvStatus[OldInventory::BIGPOCK1POS] = DO_NOT_USE_bInvStatus[BIGPOCK1POS]; + bInvStatus[OldInventory::BIGPOCK2POS] = DO_NOT_USE_bInvStatus[BIGPOCK2POS]; + bInvStatus[OldInventory::BIGPOCK3POS] = DO_NOT_USE_bInvStatus[BIGPOCK3POS]; + bInvStatus[OldInventory::BIGPOCK4POS] = DO_NOT_USE_bInvStatus[BIGPOCK4POS]; + bInvStatus[OldInventory::SMALLPOCK1POS] = DO_NOT_USE_bInvStatus[SMALLPOCK1POS]; + bInvStatus[OldInventory::SMALLPOCK2POS] = DO_NOT_USE_bInvStatus[SMALLPOCK2POS]; + bInvStatus[OldInventory::SMALLPOCK3POS] = DO_NOT_USE_bInvStatus[SMALLPOCK3POS]; + bInvStatus[OldInventory::SMALLPOCK4POS] = DO_NOT_USE_bInvStatus[SMALLPOCK4POS]; + bInvStatus[OldInventory::SMALLPOCK5POS] = DO_NOT_USE_bInvStatus[SMALLPOCK5POS]; + bInvStatus[OldInventory::SMALLPOCK6POS] = DO_NOT_USE_bInvStatus[SMALLPOCK6POS]; + bInvStatus[OldInventory::SMALLPOCK7POS] = DO_NOT_USE_bInvStatus[SMALLPOCK7POS]; + bInvStatus[OldInventory::SMALLPOCK8POS] = DO_NOT_USE_bInvStatus[SMALLPOCK8POS]; + + bInvNumber[OldInventory::HELMETPOS] = DO_NOT_USE_bInvNumber[HELMETPOS]; + bInvNumber[OldInventory::VESTPOS] = DO_NOT_USE_bInvNumber[VESTPOS]; + bInvNumber[OldInventory::LEGPOS] = DO_NOT_USE_bInvNumber[LEGPOS]; + bInvNumber[OldInventory::HEAD1POS] = DO_NOT_USE_bInvNumber[HEAD1POS]; + bInvNumber[OldInventory::HEAD2POS] = DO_NOT_USE_bInvNumber[HEAD2POS]; + bInvNumber[OldInventory::HANDPOS] = DO_NOT_USE_bInvNumber[HANDPOS]; + bInvNumber[OldInventory::SECONDHANDPOS] = DO_NOT_USE_bInvNumber[SECONDHANDPOS]; + bInvNumber[OldInventory::BIGPOCK1POS] = DO_NOT_USE_bInvNumber[BIGPOCK1POS]; + bInvNumber[OldInventory::BIGPOCK2POS] = DO_NOT_USE_bInvNumber[BIGPOCK2POS]; + bInvNumber[OldInventory::BIGPOCK3POS] = DO_NOT_USE_bInvNumber[BIGPOCK3POS]; + bInvNumber[OldInventory::BIGPOCK4POS] = DO_NOT_USE_bInvNumber[BIGPOCK4POS]; + bInvNumber[OldInventory::SMALLPOCK1POS] = DO_NOT_USE_bInvNumber[SMALLPOCK1POS]; + bInvNumber[OldInventory::SMALLPOCK2POS] = DO_NOT_USE_bInvNumber[SMALLPOCK2POS]; + bInvNumber[OldInventory::SMALLPOCK3POS] = DO_NOT_USE_bInvNumber[SMALLPOCK3POS]; + bInvNumber[OldInventory::SMALLPOCK4POS] = DO_NOT_USE_bInvNumber[SMALLPOCK4POS]; + bInvNumber[OldInventory::SMALLPOCK5POS] = DO_NOT_USE_bInvNumber[SMALLPOCK5POS]; + bInvNumber[OldInventory::SMALLPOCK6POS] = DO_NOT_USE_bInvNumber[SMALLPOCK6POS]; + bInvNumber[OldInventory::SMALLPOCK7POS] = DO_NOT_USE_bInvNumber[SMALLPOCK7POS]; + bInvNumber[OldInventory::SMALLPOCK8POS] = DO_NOT_USE_bInvNumber[SMALLPOCK8POS]; +} +void MERCPROFILESTRUCT::CopyNewInventoryToOld() { + // Do not use a loop in case the new inventory slots are arranged differently than the old + DO_NOT_USE_inv[OldInventory::HELMETPOS] = inv[HELMETPOS]; + DO_NOT_USE_inv[OldInventory::VESTPOS] = inv[VESTPOS]; + DO_NOT_USE_inv[OldInventory::LEGPOS] = inv[LEGPOS]; + DO_NOT_USE_inv[OldInventory::HEAD1POS] = inv[HEAD1POS]; + DO_NOT_USE_inv[OldInventory::HEAD2POS] = inv[HEAD2POS]; + DO_NOT_USE_inv[OldInventory::HANDPOS] = inv[HANDPOS]; + DO_NOT_USE_inv[OldInventory::SECONDHANDPOS] = inv[SECONDHANDPOS]; + DO_NOT_USE_inv[OldInventory::BIGPOCK1POS] = inv[BIGPOCK1POS]; + DO_NOT_USE_inv[OldInventory::BIGPOCK2POS] = inv[BIGPOCK2POS]; + DO_NOT_USE_inv[OldInventory::BIGPOCK3POS] = inv[BIGPOCK3POS]; + DO_NOT_USE_inv[OldInventory::BIGPOCK4POS] = inv[BIGPOCK4POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK1POS] = inv[SMALLPOCK1POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK2POS] = inv[SMALLPOCK2POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK3POS] = inv[SMALLPOCK3POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK4POS] = inv[SMALLPOCK4POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK5POS] = inv[SMALLPOCK5POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK6POS] = inv[SMALLPOCK6POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK7POS] = inv[SMALLPOCK7POS]; + DO_NOT_USE_inv[OldInventory::SMALLPOCK8POS] = inv[SMALLPOCK8POS]; + + DO_NOT_USE_bInvStatus[OldInventory::HELMETPOS] = bInvStatus[HELMETPOS]; + DO_NOT_USE_bInvStatus[OldInventory::VESTPOS] = bInvStatus[VESTPOS]; + DO_NOT_USE_bInvStatus[OldInventory::LEGPOS] = bInvStatus[LEGPOS]; + DO_NOT_USE_bInvStatus[OldInventory::HEAD1POS] = bInvStatus[HEAD1POS]; + DO_NOT_USE_bInvStatus[OldInventory::HEAD2POS] = bInvStatus[HEAD2POS]; + DO_NOT_USE_bInvStatus[OldInventory::HANDPOS] = bInvStatus[HANDPOS]; + DO_NOT_USE_bInvStatus[OldInventory::SECONDHANDPOS] = bInvStatus[SECONDHANDPOS]; + DO_NOT_USE_bInvStatus[OldInventory::BIGPOCK1POS] = bInvStatus[BIGPOCK1POS]; + DO_NOT_USE_bInvStatus[OldInventory::BIGPOCK2POS] = bInvStatus[BIGPOCK2POS]; + DO_NOT_USE_bInvStatus[OldInventory::BIGPOCK3POS] = bInvStatus[BIGPOCK3POS]; + DO_NOT_USE_bInvStatus[OldInventory::BIGPOCK4POS] = bInvStatus[BIGPOCK4POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK1POS] = bInvStatus[SMALLPOCK1POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK2POS] = bInvStatus[SMALLPOCK2POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK3POS] = bInvStatus[SMALLPOCK3POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK4POS] = bInvStatus[SMALLPOCK4POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK5POS] = bInvStatus[SMALLPOCK5POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK6POS] = bInvStatus[SMALLPOCK6POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK7POS] = bInvStatus[SMALLPOCK7POS]; + DO_NOT_USE_bInvStatus[OldInventory::SMALLPOCK8POS] = bInvStatus[SMALLPOCK8POS]; + + DO_NOT_USE_bInvNumber[OldInventory::HELMETPOS] = bInvNumber[HELMETPOS]; + DO_NOT_USE_bInvNumber[OldInventory::VESTPOS] = bInvNumber[VESTPOS]; + DO_NOT_USE_bInvNumber[OldInventory::LEGPOS] = bInvNumber[LEGPOS]; + DO_NOT_USE_bInvNumber[OldInventory::HEAD1POS] = bInvNumber[HEAD1POS]; + DO_NOT_USE_bInvNumber[OldInventory::HEAD2POS] = bInvNumber[HEAD2POS]; + DO_NOT_USE_bInvNumber[OldInventory::HANDPOS] = bInvNumber[HANDPOS]; + DO_NOT_USE_bInvNumber[OldInventory::SECONDHANDPOS] = bInvNumber[SECONDHANDPOS]; + DO_NOT_USE_bInvNumber[OldInventory::BIGPOCK1POS] = bInvNumber[BIGPOCK1POS]; + DO_NOT_USE_bInvNumber[OldInventory::BIGPOCK2POS] = bInvNumber[BIGPOCK2POS]; + DO_NOT_USE_bInvNumber[OldInventory::BIGPOCK3POS] = bInvNumber[BIGPOCK3POS]; + DO_NOT_USE_bInvNumber[OldInventory::BIGPOCK4POS] = bInvNumber[BIGPOCK4POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK1POS] = bInvNumber[SMALLPOCK1POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK2POS] = bInvNumber[SMALLPOCK2POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK3POS] = bInvNumber[SMALLPOCK3POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK4POS] = bInvNumber[SMALLPOCK4POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK5POS] = bInvNumber[SMALLPOCK5POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK6POS] = bInvNumber[SMALLPOCK6POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK7POS] = bInvNumber[SMALLPOCK7POS]; + DO_NOT_USE_bInvNumber[OldInventory::SMALLPOCK8POS] = bInvNumber[SMALLPOCK8POS]; +} BOOLEAN IsValidSecondHandShot( SOLDIERTYPE *pSoldier ); diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 6a07960e..0d8f24e3 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -11,6 +11,13 @@ #include "vobject.h" #include "Overhead Types.h" #include "Item Types.h" +#include "worlddef.h" + +// WDS - Clean up inventory handling +#include +#include + +using namespace std; // TEMP VALUES FOR NAMES @@ -274,6 +281,35 @@ enum { NUM_INV_SLOTS, }; +// WDS - Clean up inventory handling +// NOTE NOTE NOTE! Leave this alone until it is no longer needed. It must match the +// original definition so old files can be read. +namespace OldInventory { +enum { + HELMETPOS = 0, + VESTPOS, + LEGPOS, + HEAD1POS, + HEAD2POS, + HANDPOS, + SECONDHANDPOS, + BIGPOCK1POS, + BIGPOCK2POS, + BIGPOCK3POS, + BIGPOCK4POS, + SMALLPOCK1POS, + SMALLPOCK2POS, + SMALLPOCK3POS, + SMALLPOCK4POS, + SMALLPOCK5POS, + SMALLPOCK6POS, + SMALLPOCK7POS, + SMALLPOCK8POS, // = 18, so 19 pockets needed + + NUM_INV_SLOTS, +}; +}; + //used for color codes, but also shows the enemy type for debugging purposes enum { @@ -335,8 +371,66 @@ enum }; -typedef struct +// WDS - Clean up inventory handling +struct LEVELNODE; + +class Inventory { +public: + // Constructors + // Create an inventory with a fixed maximum number of slots + Inventory(); // Uses NUM_INV_SLOTS for slotCount + Inventory(int slotCount); + + // Copy Constructor + Inventory(const Inventory&); + + // Assignment operator + Inventory& operator=(const Inventory&); + + // Destructor + ~Inventory(); + + // Index operator + OBJECTTYPE& operator [] (int idx); + + // Removes all items from the inventory + void clear(); + + // How any slots are there in this inventory? + int size() const; + +private: + vector inv; + int slotCnt; +}; + +//typedef struct +class SOLDIERTYPE { +public: + // Constructor + SOLDIERTYPE(); + // Copy Constructor + SOLDIERTYPE(const SOLDIERTYPE&); + // Assignment operator + SOLDIERTYPE& operator=(const SOLDIERTYPE&); + // Destructor + ~SOLDIERTYPE(); + + // Initialize the soldier. + // Use this instead of the old method of calling memset. + // Note that the constructor does this automatically. + void initialize(); + + // Ugly temporary solution + void CopyOldInventoryToNew(); + void CopyNewInventoryToOld(); + + // Note: Place all non-POD items at the end (after endOfPOD) + // The format of this structure affects what is written into and read from various + // files (maps, save files, etc.). If you change it then that code will not work + // properly until it is all fixed and the files updated. +public: // ID UINT8 ubID; UINT8 bReserved1; @@ -348,7 +442,9 @@ typedef struct UINT32 uiStatusFlags; - OBJECTTYPE inv[ NUM_INV_SLOTS ]; +private: + OBJECTTYPE DO_NOT_USE_Inv[ OldInventory::NUM_INV_SLOTS ]; +public: OBJECTTYPE *pTempObject; KEY_ON_RING *pKeyRing; @@ -536,9 +632,9 @@ typedef struct THROW_PARAMS *pThrowParams; BOOLEAN fTurningFromPronePosition; INT8 bReverse; - struct TAG_level_node *pLevelNode; - struct TAG_level_node *pExternShadowLevelNode; - struct TAG_level_node *pRoofUILevelNode; + LEVELNODE *pLevelNode; + LEVELNODE *pExternShadowLevelNode; + LEVELNODE *pRoofUILevelNode; // WALKING STUFF INT8 bDesiredDirection; @@ -793,10 +889,12 @@ typedef struct UINT32 uiChangeMechanicalTime; UINT32 uiUniqueSoldierIdValue; // the unique value every instance of a soldier gets - 1 is the first valid value - INT8 bBeingAttackedCount; // Being attacked counter is obsolete and can be renamed and used as something else + INT8 UNUSED1; // This is unused at present and can be used for something else - INT8 bNewItemCount[ NUM_INV_SLOTS ]; - INT8 bNewItemCycleCount[ NUM_INV_SLOTS ]; +private: + INT8 DO_NOT_USE_bNewItemCount[ OldInventory::NUM_INV_SLOTS ]; + INT8 DO_NOT_USE_bNewItemCycleCount[ OldInventory::NUM_INV_SLOTS ]; +public: BOOLEAN fCheckForNewlyAddedItems; INT8 bEndDoorOpenCode; @@ -953,10 +1051,24 @@ typedef struct INT8 snowCamo; INT8 wornSnowCamo; - + UINT8 bFiller[ 36 ]; -} SOLDIERTYPE; + // + // New and OO stuff goes after here. Above this point any changes will goof up reading from files. + // + char ef1,ef2,ef3; // Extra filler to get "offsetof(endOfPOD)" to match SIZEOF(oldstruct) + + char endOfPOD; // marker for end of POD (plain old data) + + Inventory inv; + + vector bNewItemCount; + vector bNewItemCycleCount; +}; // SOLDIERTYPE; + +#define SIZEOF_SOLDIERTYPE_POD offsetof( SOLDIERTYPE, endOfPOD ) +#define SIZEOF_SOLDIERTYPE sizeof( SOLDIERTYPE ) #define HEALTH_INCREASE 0x0001 #define STRENGTH_INCREASE 0x0002 diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 41af7145..ef68f4ee 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -65,6 +65,92 @@ #define MAX_PALACE_DISTANCE 20 +// WDS - Clean up inventory handling +SOLDIERCREATE_STRUCT::SOLDIERCREATE_STRUCT() { + initialize(); +} + +// Copy Constructor +SOLDIERCREATE_STRUCT::SOLDIERCREATE_STRUCT(const SOLDIERCREATE_STRUCT& src) { + memcpy(this, &src, SIZEOF_SOLDIERCREATE_STRUCT_POD); + this->Inv = src.Inv; +} + +// Assignment operator +SOLDIERCREATE_STRUCT& SOLDIERCREATE_STRUCT::operator=(const SOLDIERCREATE_STRUCT& src) +{ + if (this != &src) { + memcpy(this, &src, SIZEOF_SOLDIERCREATE_STRUCT_POD); + this->Inv = src.Inv; + } + return *this; +} + +// Destructor +SOLDIERCREATE_STRUCT::~SOLDIERCREATE_STRUCT() { +} + +// Initialize the soldier. +// Use this instead of the old method of calling memset! +// Note that the constructor does this automatically. +void SOLDIERCREATE_STRUCT::initialize() { + memset( this, 0, SIZEOF_SOLDIERCREATE_STRUCT_POD); + Inv.clear(); +} + + +// Ugly temporary solution +// +// These two functions map the "old" style inventory (fixed array of ) to the new (a flexibly sized vector). +// If you change names or eliminate some positions or such you need to change these. +// Eventually the need for these functions will disappear. + +void SOLDIERCREATE_STRUCT::CopyOldInventoryToNew() { + // Do not use a loop in case the new inventory slots are arranged differently than the old + Inv[HELMETPOS] = DO_NOT_USE_Inv[OldInventory::HELMETPOS]; + Inv[VESTPOS] = DO_NOT_USE_Inv[OldInventory::VESTPOS]; + Inv[LEGPOS] = DO_NOT_USE_Inv[OldInventory::LEGPOS]; + Inv[HEAD1POS] = DO_NOT_USE_Inv[OldInventory::HEAD1POS]; + Inv[HEAD2POS] = DO_NOT_USE_Inv[OldInventory::HEAD2POS]; + Inv[HANDPOS] = DO_NOT_USE_Inv[OldInventory::HANDPOS]; + Inv[SECONDHANDPOS] = DO_NOT_USE_Inv[OldInventory::SECONDHANDPOS]; + Inv[BIGPOCK1POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK1POS]; + Inv[BIGPOCK2POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK2POS]; + Inv[BIGPOCK3POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK3POS]; + Inv[BIGPOCK4POS] = DO_NOT_USE_Inv[OldInventory::BIGPOCK4POS]; + Inv[SMALLPOCK1POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK1POS]; + Inv[SMALLPOCK2POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK2POS]; + Inv[SMALLPOCK3POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK3POS]; + Inv[SMALLPOCK4POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK4POS]; + Inv[SMALLPOCK5POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK5POS]; + Inv[SMALLPOCK6POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK6POS]; + Inv[SMALLPOCK7POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK7POS]; + Inv[SMALLPOCK8POS] = DO_NOT_USE_Inv[OldInventory::SMALLPOCK8POS]; +} +void SOLDIERCREATE_STRUCT::CopyNewInventoryToOld() { + // Do not use a loop in case the new inventory slots are arranged differently than the old + DO_NOT_USE_Inv[OldInventory::HELMETPOS] = Inv[HELMETPOS]; + DO_NOT_USE_Inv[OldInventory::VESTPOS] = Inv[VESTPOS]; + DO_NOT_USE_Inv[OldInventory::LEGPOS] = Inv[LEGPOS]; + DO_NOT_USE_Inv[OldInventory::HEAD1POS] = Inv[HEAD1POS]; + DO_NOT_USE_Inv[OldInventory::HEAD2POS] = Inv[HEAD2POS]; + DO_NOT_USE_Inv[OldInventory::HANDPOS] = Inv[HANDPOS]; + DO_NOT_USE_Inv[OldInventory::SECONDHANDPOS] = Inv[SECONDHANDPOS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK1POS] = Inv[BIGPOCK1POS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK2POS] = Inv[BIGPOCK2POS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK3POS] = Inv[BIGPOCK3POS]; + DO_NOT_USE_Inv[OldInventory::BIGPOCK4POS] = Inv[BIGPOCK4POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK1POS] = Inv[SMALLPOCK1POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK2POS] = Inv[SMALLPOCK2POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK3POS] = Inv[SMALLPOCK3POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK4POS] = Inv[SMALLPOCK4POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK5POS] = Inv[SMALLPOCK5POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK6POS] = Inv[SMALLPOCK6POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK7POS] = Inv[SMALLPOCK7POS]; + DO_NOT_USE_Inv[OldInventory::SMALLPOCK8POS] = Inv[SMALLPOCK8POS]; +} + + //Private functions used within TacticalCreateStruct() void InitSoldierStruct( SOLDIERTYPE *pSoldier ); BOOLEAN TacticalCopySoldierFromProfile( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCreateStruct ); @@ -591,8 +677,10 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 * if( guiCurrentScreen != AUTORESOLVE_SCREEN ) { + // WDS - Clean up inventory handling // Copy into merc struct - memcpy( MercPtrs[ Soldier.ubID ], &Soldier, sizeof( SOLDIERTYPE ) ); + //memcpy( MercPtrs[ Soldier.ubID ], &Soldier, SIZEOF_SOLDIERTYPE ); + *MercPtrs[ Soldier.ubID ] = Soldier; // Alrighty then, we are set to create the merc, stuff after here can fail! CHECKF( CreateSoldierCommon( Soldier.ubBodyType, MercPtrs[ Soldier.ubID ], Soldier.ubID, STANDING ) != FALSE ); } @@ -615,8 +703,10 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 * Soldier.bNeutral = TRUE; } + // WDS - Clean up inventory handling // Copy into merc struct - memcpy( MercPtrs[ Soldier.ubID ], &Soldier, sizeof( SOLDIERTYPE ) ); + //memcpy( MercPtrs[ Soldier.ubID ], &Soldier, SIZEOF_SOLDIERTYPE ); + *MercPtrs[ Soldier.ubID ] = Soldier; // Alrighty then, we are set to create the merc, stuff after here can fail! CHECKF( CreateSoldierCommon( Soldier.ubBodyType, MercPtrs[ Soldier.ubID ], Soldier.ubID, Menptr[ Soldier.ubID ].usAnimState ) != FALSE ); @@ -660,10 +750,12 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 * SOLDIERTYPE *pSoldier; UINT8 ubSectorID; ubSectorID = GetAutoResolveSectorID(); - pSoldier = (SOLDIERTYPE*)MemAlloc( sizeof( SOLDIERTYPE ) ); + // WDS - Clean up inventory handling + pSoldier = new (MemAlloc( SIZEOF_SOLDIERTYPE )) SOLDIERTYPE; //(SOLDIERTYPE*)MemAlloc( SIZEOF_SOLDIERTYPE ); if( !pSoldier ) return NULL; - memcpy( pSoldier, &Soldier, sizeof( SOLDIERTYPE ) ); + //memcpy( pSoldier, &Soldier, SIZEOF_SOLDIERTYPE ); + *pSoldier = Soldier; pSoldier->ubID = 255; pSoldier->sSectorX = (INT16)SECTORX( ubSectorID ); pSoldier->sSectorY = (INT16)SECTORY( ubSectorID ); @@ -1176,8 +1268,10 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT //Generate colors for soldier based on the body type. GeneratePaletteForSoldier( pSoldier, pCreateStruct->ubSoldierClass ); + // WDS - Clean up inventory handling // Copy item info over - memcpy( pSoldier->inv, pCreateStruct->Inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); +// memcpy( pSoldier->inv, pCreateStruct->Inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); + pSoldier->inv = pCreateStruct->Inv; return( TRUE ); } @@ -1185,8 +1279,10 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT void InitSoldierStruct( SOLDIERTYPE *pSoldier ) { + // WDS - Clean up inventory handling // Memset values - memset( pSoldier, 0, sizeof( SOLDIERTYPE ) ); + //memset( pSoldier, 0, SIZEOF_SOLDIERTYPE ); + pSoldier->initialize(); // Set default values pSoldier->bVisible = -1; @@ -1743,7 +1839,9 @@ void CreateStaticDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT INT32 i; if( !spp || !bp ) return; - memset( spp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + //memset( spp, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + spp->initialize(); spp->fStatic = TRUE; spp->ubProfile = NO_PROFILE; spp->sInsertionGridNo = bp->usStartingGridNo; @@ -1817,7 +1915,9 @@ void CreateDetailedPlacementGivenStaticDetailedPlacementAndBasicPlacementInfo( DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenStaticDetailedPlacementAndBasicPlacementInfo")); - memset( pp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + //memset( pp, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + pp->initialize(); pp->fOnRoof = spp->fOnRoof = bp->fOnRoof; pp->fStatic = FALSE; pp->ubSoldierClass = bp->ubSoldierClass; @@ -1968,8 +2068,10 @@ void UpdateSoldierWithStaticDetailedInformation( SOLDIERTYPE *s, SOLDIERCREATE_S s->ubScheduleID = spp->ubScheduleID; + // WDS - Clean up inventory handling //Copy over the current inventory list. - memcpy( s->inv, spp->Inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); +// memcpy( s->inv, spp->Inv, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); + s->inv = spp->Inv; } //In the case of setting a profile ID in order to extract a soldier from the profile array, we @@ -2100,11 +2202,13 @@ SOLDIERTYPE* ReserveTacticalSoldierForAutoresolve( UINT8 ubSoldierClass ) //reserve this soldier MercPtrs[ i ]->sGridNo = NOWHERE; + // WDS - Clean up inventory handling //Allocate and copy the soldier - pSoldier = (SOLDIERTYPE*)MemAlloc( sizeof( SOLDIERTYPE ) ); + pSoldier = new (MemAlloc( SIZEOF_SOLDIERTYPE )) SOLDIERTYPE; //(SOLDIERTYPE*)MemAlloc( SIZEOF_SOLDIERTYPE ); if( !pSoldier ) return NULL; - memcpy( pSoldier, MercPtrs[ i ], sizeof( SOLDIERTYPE ) ); +// memcpy( pSoldier, MercPtrs[ i ], SIZEOF_SOLDIERTYPE ); + *pSoldier = *MercPtrs[i]; //Assign a bogus ID, then return it pSoldier->ubID = 255; @@ -2130,7 +2234,9 @@ SOLDIERTYPE* TacticalCreateAdministrator() } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); - memset( &pp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + //memset( &pp, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + pp.initialize(); RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ADMINISTRATOR ); RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ADMINISTRATOR ); bp.bTeam = ENEMY_TEAM; @@ -2164,7 +2270,9 @@ SOLDIERTYPE* TacticalCreateArmyTroop() } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); - memset( &pp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + //memset( &pp, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + pp.initialize(); RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ARMY ); RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ARMY ); bp.bTeam = ENEMY_TEAM; @@ -2199,7 +2307,9 @@ SOLDIERTYPE* TacticalCreateEliteEnemy() } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); - memset( &pp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + //memset( &pp, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + pp.initialize(); RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ELITE ); RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ELITE ); @@ -2247,11 +2357,13 @@ SOLDIERTYPE* ReserveTacticalMilitiaSoldierForAutoresolve( UINT8 ubSoldierClass ) //reserve this soldier MercPtrs[ i ]->sGridNo = NOWHERE; + // WDS - Clean up inventory handling //Allocate and copy the soldier - pSoldier = (SOLDIERTYPE*)MemAlloc( sizeof( SOLDIERTYPE ) ); + pSoldier = new (MemAlloc( SIZEOF_SOLDIERTYPE )) SOLDIERTYPE; //(SOLDIERTYPE*)MemAlloc( SIZEOF_SOLDIERTYPE ); if( !pSoldier ) return NULL; - memcpy( pSoldier, MercPtrs[ i ], sizeof( SOLDIERTYPE ) ); +// memcpy( pSoldier, MercPtrs[ i ], SIZEOF_SOLDIERTYPE ); + *pSoldier = *MercPtrs[i]; //Assign a bogus ID, then return it pSoldier->ubID = 255; @@ -2277,7 +2389,10 @@ SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass ) } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); - memset( &pp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + //memset( &pp, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + pp.initialize(); + RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), ubMilitiaClass ); RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), ubMilitiaClass ); bp.bTeam = MILITIA_TEAM; @@ -2306,7 +2421,10 @@ SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType ) } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); - memset( &pp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + // WDS - Clean up inventory handling + //memset( &pp, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + pp.initialize(); + RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_CREATURE ); RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_CREATURE ); bp.bTeam = CREATURE_TEAM; @@ -2472,7 +2590,8 @@ void CopyProfileItems( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCreateStruc { // do some special coding to put stuff in the profile in better-looking // spots - memset( pSoldier->inv, 0, NUM_INV_SLOTS * sizeof( OBJECTTYPE ) ); + // WDS - Clean up inventory handling +// memset( pSoldier->inv, 0, NUM_INV_SLOTS * sizeof( OBJECTTYPE ) ); for ( cnt = 0; cnt < NUM_INV_SLOTS; cnt++ ) { if ( pProfile->inv[ cnt ] != NOTHING ) diff --git a/Tactical/Soldier Create.h b/Tactical/Soldier Create.h index 4b8975da..4161c1d9 100644 --- a/Tactical/Soldier Create.h +++ b/Tactical/Soldier Create.h @@ -8,6 +8,12 @@ #include "Item Types.h" #include "soldier control.h" +// WDS - Clean up inventory handling +#include +#include + +using namespace std; + #define SOLDIER_CREATE_AUTO_TEAM -1 //Kris: @@ -51,8 +57,37 @@ typedef struct INT8 PADDINGSLOTS[ 14 ]; } BASIC_SOLDIERCREATE_STRUCT; //50 bytes -typedef struct +// WDS - Clean up inventory handling +//typedef struct +class SOLDIERCREATE_STRUCT { +public: + // Constructor + SOLDIERCREATE_STRUCT(); + // Copy Constructor + SOLDIERCREATE_STRUCT(const SOLDIERCREATE_STRUCT&); + // Assignment operator + SOLDIERCREATE_STRUCT& operator=(const SOLDIERCREATE_STRUCT&); + // Destructor + ~SOLDIERCREATE_STRUCT(); + + // Initialize the soldier. + // Use this instead of the old method of calling memset! + // Note that the constructor does this automatically. + void initialize(); + + // Ugly temporary solution + // + // Note! These two functions should ONLY be used either just before saving to a + // file (NewToOld) or after loading a file (OldToNew). + void CopyOldInventoryToNew(); + void CopyNewInventoryToOld(); + + // Note: Place all non-POD items at the end (after endOfPOD) + // The format of this structure affects what is written into and read from various + // files (maps, save files, etc.). If you change it then that code will not work + // properly until it is all fixed and the files updated. +public: //Bulletproofing so static detailed placements aren't used to tactically create soldiers. //Used by editor for validation purposes. BOOLEAN fStatic; @@ -93,8 +128,10 @@ typedef struct INT8 bMorale; INT8 bAIMorale; +private: //Inventory - OBJECTTYPE Inv[ NUM_INV_SLOTS ]; + OBJECTTYPE DO_NOT_USE_Inv[ OldInventory::NUM_INV_SLOTS ]; +public: //Palette information for soldiers. PaletteRepID HeadPal; @@ -130,8 +167,18 @@ typedef struct INT8 bPadding[115]; + // + // New and OO stuff goes after here. Above this point any changes will goof up reading from files. + // + char ef1,ef2; // Extra filler to get "offsetof(endOfPOD)" to match SIZEOF(oldstruct) -} SOLDIERCREATE_STRUCT; + char endOfPOD; // marker for end of POD (plain old data) + + Inventory Inv; +}; // SOLDIERCREATE_STRUCT; + +#define SIZEOF_SOLDIERCREATE_STRUCT_POD offsetof( SOLDIERCREATE_STRUCT, endOfPOD ) +#define SIZEOF_SOLDIERCREATE_STRUCT sizeof( SOLDIERCREATE_STRUCT ) //Original functions currently used throughout the game. diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index 437162aa..324586ec 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -236,8 +236,9 @@ BOOLEAN SaveSoldiersToMap( HWFILE fp ) { if( !curr->pDetailedPlacement ) return FALSE; - FileWrite( fp, curr->pDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ), &uiBytesWritten ); - + // WDS - Clean up inventory handling + curr->pDetailedPlacement->CopyNewInventoryToOld(); + FileWrite( fp, curr->pDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT_POD /*SIZEOF_SOLDIERCREATE_STRUCT*/, &uiBytesWritten ); } curr = curr->next; } @@ -293,17 +294,21 @@ BOOLEAN LoadSoldiersFromMap( INT8 **hBuffer ) } if( tempBasicPlacement.fDetailedPlacement ) { //Add the static detailed placement information in the same newly created node as the basic placement. + // WDS - Clean up inventory handling + tempDetailedPlacement.initialize(); //read static detailed placement from file - LOADDATA( &tempDetailedPlacement, *hBuffer, sizeof( SOLDIERCREATE_STRUCT ) ); + LOADDATA( &tempDetailedPlacement, *hBuffer, SIZEOF_SOLDIERCREATE_STRUCT_POD ); + tempDetailedPlacement.CopyOldInventoryToNew(); //allocate memory for new static detailed placement - pNode->pDetailedPlacement = (SOLDIERCREATE_STRUCT*)MemAlloc( sizeof( SOLDIERCREATE_STRUCT ) ); + pNode->pDetailedPlacement = new (MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT )) SOLDIERCREATE_STRUCT;//(SOLDIERCREATE_STRUCT*)MemAlloc( SIZEOF_SOLDIERCREATE_STRUCT ); if( !pNode->pDetailedPlacement ) { AssertMsg( 0, "Failed to allocate memory for new detailed placement in LoadSoldiersFromMap." ); return FALSE; } //copy the file information from temp var to node in list. - memcpy( pNode->pDetailedPlacement, &tempDetailedPlacement, sizeof( SOLDIERCREATE_STRUCT ) ); + //memcpy( pNode->pDetailedPlacement, &tempDetailedPlacement, SIZEOF_SOLDIERCREATE_STRUCT ); + *pNode->pDetailedPlacement = tempDetailedPlacement; if( tempDetailedPlacement.ubProfile != NO_PROFILE ) { @@ -527,8 +532,10 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr ) DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld")); // First check if this guy has a profile and if so check his location such that it matches! + // WDS - Clean up inventory handling // Get profile from placement info - memset( &tempDetailedPlacement, 0, sizeof( SOLDIERCREATE_STRUCT ) ); + //memset( &tempDetailedPlacement, 0, SIZEOF_SOLDIERCREATE_STRUCT ); + tempDetailedPlacement.initialize(); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld: decide on placement")); if( curr->pDetailedPlacement ) diff --git a/Tactical/Soldier Profile.cpp b/Tactical/Soldier Profile.cpp index 05660ab3..4d032f5f 100644 --- a/Tactical/Soldier Profile.cpp +++ b/Tactical/Soldier Profile.cpp @@ -275,13 +275,14 @@ BOOLEAN LoadMercProfiles(void) for(uiLoop=0; uiLoop< NUM_PROFILES; uiLoop++) { - if( JA2EncryptedFileRead( fptr, &gMercProfiles[uiLoop], sizeof( MERCPROFILESTRUCT ), &uiNumBytesRead ) != 1) + // WDS - Clean up inventory handling + if( JA2EncryptedFileRead( fptr, &gMercProfiles[uiLoop], SIZEOF_MERCPROFILESTRUCT_POD, &uiNumBytesRead ) != 1) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Read Merc Profiles from File %d %s",uiLoop, pFileName) ); FileClose( fptr ); return(FALSE); } - + gMercProfiles[ uiLoop ].CopyOldInventoryToNew(); //if the Dialogue exists for the merc, allow the merc to be hired if( DialogueDataFileExistsForProfile( (UINT8)uiLoop, 0, FALSE, NULL ) ) @@ -904,8 +905,9 @@ SOLDIERTYPE *ChangeSoldierTeam( SOLDIERTYPE *pSoldier, UINT8 ubTeam ) // Remove him from the game! InternalTacticalRemoveSoldier( ubID, FALSE ); + // WDS - Clean up inventory handling // Create a new one! - memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) ); + MercCreateStruct.initialize(); MercCreateStruct.bTeam = ubTeam; MercCreateStruct.ubProfile = pSoldier->ubProfile; MercCreateStruct.bBodyType = pSoldier->ubBodyType; @@ -1463,9 +1465,10 @@ SOLDIERTYPE * SwapLarrysProfiles( SOLDIERTYPE * pSoldier ) pNewProfile->bExplosivesDelta = gMercProfiles[ ubSrcProfile ].bExplosivesDelta; */ - memcpy( pNewProfile->bInvStatus, gMercProfiles[ ubSrcProfile ].bInvStatus , sizeof( UINT8) * 19 ); - memcpy( pNewProfile->bInvNumber, gMercProfiles[ ubSrcProfile ].bInvNumber , sizeof( UINT8) * 19 ); - memcpy( pNewProfile->inv , gMercProfiles[ ubSrcProfile ].inv , sizeof( UINT16 ) * 19 ); + // WDS - Clean up inventory handling + pNewProfile->bInvStatus = gMercProfiles[ ubSrcProfile ].bInvStatus; + pNewProfile->bInvNumber = gMercProfiles[ ubSrcProfile ].bInvNumber; + pNewProfile->inv = gMercProfiles[ ubSrcProfile ].inv; memcpy( pNewProfile->bMercTownReputation , gMercProfiles[ ubSrcProfile ].bMercTownReputation , sizeof( UINT8 ) * 20 ); // remove face @@ -1551,4 +1554,4 @@ BOOLEAN IsProfileIdAnAimOrMERCMerc( UINT8 ubProfileID ) } return( FALSE ); -} \ No newline at end of file +} diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 1cd2971d..a168ae31 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -4683,7 +4683,8 @@ void CreatePlayerControlledMonster() SOLDIERCREATE_STRUCT MercCreateStruct; INT8 iNewIndex; - memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) ); + // WDS - Clean up inventory handling + MercCreateStruct.initialize(); MercCreateStruct.ubProfile = NO_PROFILE; MercCreateStruct.sSectorX = gWorldSectorX; MercCreateStruct.sSectorY = gWorldSectorY; diff --git a/Tactical/Vehicles.h b/Tactical/Vehicles.h index 0dfaa467..0a156281 100644 --- a/Tactical/Vehicles.h +++ b/Tactical/Vehicles.h @@ -49,6 +49,8 @@ enum{ extern INT16 sVehicleOrigArmorValues[ NUMBER_OF_TYPES_OF_VEHICLES][ NUMBER_OF_INTERNAL_HIT_LOCATIONS_IN_VEHICLE]; +// WDS - Clean up inventory handling +#define MAXPASSENGERS 10 // struct for vehicles typedef struct { @@ -60,7 +62,7 @@ typedef struct INT16 sSectorZ; BOOLEAN fBetweenSectors; // between sectors? INT16 sGridNo; // location in tactical - SOLDIERTYPE *pPassengers[ 10 ]; + SOLDIERTYPE *pPassengers[ MAXPASSENGERS ]; UINT8 ubDriver; INT16 sInternalHitLocations[ NUMBER_OF_EXTERNAL_HIT_LOCATIONS_ON_VEHICLE ]; INT16 sArmourType; diff --git a/Tactical/World Items.h b/Tactical/World Items.h index 5440ff92..244f7ad5 100644 --- a/Tactical/World Items.h +++ b/Tactical/World Items.h @@ -15,7 +15,8 @@ //Kaiden: This constant is to flag items that an enemy drops when they die. #define WORLD_ITEM_DROPPED_FROM_ENEMY 0x0800 -typedef struct +//typedef struct +struct WORLDITEM { BOOLEAN fExists; INT16 sGridNo; @@ -33,7 +34,7 @@ typedef struct //This check is only performed the first time a map is loaded. Later, it is entirely skipped. UINT8 ubNonExistChance; -} WORLDITEM; +}; // WORLDITEM; extern WORLDITEM *gWorldItems; extern UINT32 guiNumWorldItems; diff --git a/Tactical/soldier profile type.h b/Tactical/soldier profile type.h index c28a3fe6..9d85541b 100644 --- a/Tactical/soldier profile type.h +++ b/Tactical/soldier profile type.h @@ -2,6 +2,7 @@ #define __SOLDER_PROFILE_TYPE_H #include "overhead types.h" +#include "Soldier Control.h" #define NUM_PROFILES 170 #define FIRST_RPC 57 @@ -160,8 +161,38 @@ typedef enum{ #define BUDDY_OPINION +25 #define HATED_OPINION -25 -typedef struct -{ +// WDS - Clean up inventory handling +//typedef struct +class MERCPROFILESTRUCT { +public: + // Constructor + MERCPROFILESTRUCT(); + // Copy Constructor + MERCPROFILESTRUCT(const MERCPROFILESTRUCT&); + // Assignment operator + MERCPROFILESTRUCT& operator=(const MERCPROFILESTRUCT&); + // Destructor + ~MERCPROFILESTRUCT(); + + // Initialize the mercenary profile. + // Use this instead of the old method of calling memset. + // Note that the constructor does this automatically. + void initialize(); + + // Clear out the mercenary profile's invetory + // Use this instead of the old method of calling memset. + // Note that the constructor does this automatically. + void clearInventory(); + + // Ugly temporary solution + void CopyOldInventoryToNew(); + void CopyNewInventoryToOld(); + + // Note: Place all non-POD items at the end (after endOfPOD) + // The format of this structure affects what is written into and read from various + // files (maps, save files, etc.). If you change it then that code will not work + // properly until it is all fixed and the files updated. +public: CHAR16 zName[ NAME_LENGTH ]; CHAR16 zNickname[ NICKNAME_LENGTH ]; UINT32 uiAttnSound; @@ -268,8 +299,10 @@ typedef struct UINT8 bResigned; UINT8 bActive; - UINT8 bInvStatus[19]; - UINT8 bInvNumber[19]; +private: + UINT8 DO_NOT_USE_bInvStatus[OldInventory::NUM_INV_SLOTS]; + UINT8 DO_NOT_USE_bInvNumber[OldInventory::NUM_INV_SLOTS]; +public: UINT16 usApproachFactor[4]; INT8 bMainGunAttractiveness; @@ -282,7 +315,9 @@ typedef struct UINT8 ubInvUndroppable; UINT8 ubRoomRangeStart[2]; - UINT16 inv[19]; +private: + UINT16 DO_NOT_USE_inv[OldInventory::NUM_INV_SLOTS]; +public: INT8 bMercTownReputation[ 20 ]; UINT16 usStatChangeChances[ 12 ]; // used strictly for balancing, never shown! @@ -358,7 +393,21 @@ typedef struct UINT32 uiTotalCostToDate; // The total amount of money that has been paid to the merc for their salary UINT8 ubBuffer[4]; -} MERCPROFILESTRUCT; + + // + // New and OO stuff goes after here. Above this point any changes will goof up reading from files. + // + //char ef1; // Extra filler to get "offsetof(endOfPOD)" to match SIZEOF(oldstruct) + + char endOfPOD; // marker for end of POD (plain old data) + + vector inv; + vector bInvStatus; + vector bInvNumber; +}; // MERCPROFILESTRUCT; + +#define SIZEOF_MERCPROFILESTRUCT_POD offsetof( MERCPROFILESTRUCT, endOfPOD ) +#define SIZEOF_MERCPROFILESTRUCT sizeof( MERCPROFILESTRUCT ) #define TIME_BETWEEN_HATED_COMPLAINTS 24