Fix: crash if player offer area exceeds 255 fields (possible on high resolutions)

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8823 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2020-06-17 22:24:52 +00:00
parent 01d8bbf408
commit f1bd0f8e8e
3 changed files with 48 additions and 74 deletions
+4 -4
View File
@@ -1515,23 +1515,23 @@ bool ItemIsSpecial(DEALER_SPECIAL_ITEM& item)
return false; return false;
} }
UINT16 CountTotalItemsRepairDealerHasInForRepairs( UINT8 ubArmsDealer ) int CountTotalItemsRepairDealerHasInForRepairs( UINT8 ubArmsDealer )
{ {
//if the dealer is not a repair dealer, no need to count, return 0 //if the dealer is not a repair dealer, no need to count, return 0
if ( !DoesDealerDoRepairs( ubArmsDealer ) ) if ( !DoesDealerDoRepairs( ubArmsDealer ) )
return 0; return 0;
UINT16 usHowManyInForRepairs = 0; int count = 0;
for ( DealerItemList::iterator iter = gArmsDealersInventory[ubArmsDealer].begin(); iter != gArmsDealersInventory[ubArmsDealer].end(); ++iter ) for ( DealerItemList::iterator iter = gArmsDealersInventory[ubArmsDealer].begin(); iter != gArmsDealersInventory[ubArmsDealer].end(); ++iter )
{ {
if ( iter->object.exists() && iter->IsUnderRepair() ) if ( iter->object.exists() && iter->IsUnderRepair() )
{ {
++usHowManyInForRepairs; ++count;
} }
} }
return( usHowManyInForRepairs ); return( count );
} }
void AddObjectToArmsDealerInventory( UINT8 ubArmsDealer, OBJECTTYPE *pObject ) void AddObjectToArmsDealerInventory( UINT8 ubArmsDealer, OBJECTTYPE *pObject )
+1 -1
View File
@@ -340,7 +340,7 @@ UINT32 GetArmsDealerItemTypeFromItemNumber( UINT16 usItem );
//Count every single item the dealer has in stock //Count every single item the dealer has in stock
//UINT32 CountTotalItemsInArmsDealersInventory( UINT8 ubArmsDealer ); //UINT32 CountTotalItemsInArmsDealersInventory( UINT8 ubArmsDealer );
//Count only the # of "distinct" item types (for shopkeeper purposes) //Count only the # of "distinct" item types (for shopkeeper purposes)
UINT16 CountTotalItemsRepairDealerHasInForRepairs( UINT8 ubArmsDealer ); int CountTotalItemsRepairDealerHasInForRepairs( UINT8 ubArmsDealer );
void AddObjectToArmsDealerInventory( UINT8 ubArmsDealer, OBJECTTYPE *pObject ); void AddObjectToArmsDealerInventory( UINT8 ubArmsDealer, OBJECTTYPE *pObject );
+43 -69
View File
@@ -539,10 +539,9 @@ void RemoveShopKeeperSubTitledText();
BOOLEAN AreThereItemsInTheArmsDealersOfferArea( ); BOOLEAN AreThereItemsInTheArmsDealersOfferArea( );
BOOLEAN AreThereItemsInThePlayersOfferArea( ); BOOLEAN AreThereItemsInThePlayersOfferArea( );
void ShutUpShopKeeper(); void ShutUpShopKeeper();
UINT8 CountNumberOfValuelessItemsInThePlayersOfferArea( ); int CountNumberOfValuelessItemsInThePlayersOfferArea( );
UINT8 CountNumberOfItemsOfValueInThePlayersOfferArea( ); int CountNumberOfItemsInThePlayersOfferArea( );
UINT8 CountNumberOfItemsInThePlayersOfferArea( ); int CountNumberOfItemsInTheArmsDealersOfferArea( );
UINT8 CountNumberOfItemsInTheArmsDealersOfferArea( );
INT8 GetSlotNumberForMerc( UINT8 ubProfile ); INT8 GetSlotNumberForMerc( UINT8 ubProfile );
void HandleCurrentModeText( UINT8 ubMode ); void HandleCurrentModeText( UINT8 ubMode );
void EnableDisableDealersInventoryPageButtons(); void EnableDisableDealersInventoryPageButtons();
@@ -766,8 +765,8 @@ UINT32 ShopKeeperScreenShutdown()
BOOLEAN EnterShopKeeperInterface() BOOLEAN EnterShopKeeperInterface()
{ {
VOBJECT_DESC VObjectDesc; VOBJECT_DESC VObjectDesc;
UINT8 ubCnt; UINT16 ubCnt;
CHAR8 zTemp[32]; CHAR8 zTemp[32];
VSURFACE_DESC vs_desc; VSURFACE_DESC vs_desc;
//ADB if we are here, we must be able to talk with an extended ear (CheckIfRadioIsEquipped()) //ADB if we are here, we must be able to talk with an extended ear (CheckIfRadioIsEquipped())
@@ -893,7 +892,7 @@ BOOLEAN EnterShopKeeperInterface()
//Create an array of all mercs (anywhere!) currently in the player's employ, and load their small faces //Create an array of all mercs (anywhere!) currently in the player's employ, and load their small faces
// This is to support showing of repair item owner's faces even when they're not in the sector, as long as they still work for player // This is to support showing of repair item owner's faces even when they're not in the sector, as long as they still work for player
gubNumberMercsInArray = 0; gubNumberMercsInArray = 0;
for( ubCnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; ubCnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ubCnt++ ) for( ubCnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; ubCnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++ubCnt )
{ {
pSoldier = MercPtrs[ ubCnt ]; pSoldier = MercPtrs[ ubCnt ];
@@ -3591,8 +3590,6 @@ void SkiHelpTextDoneCallBack( void )
INT8 AddItemToPlayersOfferArea( UINT8 ubProfileID, INVENTORY_IN_SLOT* pInvSlot, INT16 bSlotIdInOtherLocation ) INT8 AddItemToPlayersOfferArea( UINT8 ubProfileID, INVENTORY_IN_SLOT* pInvSlot, INT16 bSlotIdInOtherLocation )
{ {
INT8 bCnt;
//if we are to check for a previous slot //if we are to check for a previous slot
if( bSlotIdInOtherLocation != -1 ) if( bSlotIdInOtherLocation != -1 )
{ {
@@ -3602,7 +3599,7 @@ INT8 AddItemToPlayersOfferArea( UINT8 ubProfileID, INVENTORY_IN_SLOT* pInvSlot,
} }
//look for the first free slot //look for the first free slot
for ( bCnt = 0; bCnt<gPlayersOfferActiveRegions; ++bCnt ) for ( int bCnt = 0; bCnt<gPlayersOfferActiveRegions; ++bCnt )
{ {
//if there are no items here, copy the data in //if there are no items here, copy the data in
if( PlayersOfferArea[bCnt].fActive == FALSE ) if( PlayersOfferArea[bCnt].fActive == FALSE )
@@ -3846,8 +3843,8 @@ void PerformTransaction( UINT32 uiMoneyFromPlayersAccount )
UINT32 uiPlayersTotalMoneyValue = CalculateTotalPlayersValue() + uiMoneyFromPlayersAccount; UINT32 uiPlayersTotalMoneyValue = CalculateTotalPlayersValue() + uiMoneyFromPlayersAccount;
UINT32 uiArmsDealersItemsCost = CalculateTotalArmsDealerCost(); UINT32 uiArmsDealersItemsCost = CalculateTotalArmsDealerCost();
UINT32 uiMoneyInPlayersOfferArea = CalculateHowMuchMoneyIsInPlayersOfferArea( ); UINT32 uiMoneyInPlayersOfferArea = CalculateHowMuchMoneyIsInPlayersOfferArea( );
INT32 iChangeToGiveToPlayer = 0; INT32 iChangeToGiveToPlayer = 0;
UINT32 uiAvailablePlayerOfferSlots; int iAvailablePlayerOfferSlots;
//if the player has already requested to leave, get out //if the player has already requested to leave, get out
if( gfUserHasRequestedToLeave ) if( gfUserHasRequestedToLeave )
@@ -3873,17 +3870,17 @@ void PerformTransaction( UINT32 uiMoneyFromPlayersAccount )
//if the dealer is not a repairman //if the dealer is not a repairman
if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer != ARMS_DEALER_REPAIRS ) if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer != ARMS_DEALER_REPAIRS )
{ {
uiAvailablePlayerOfferSlots = (gPlayersOfferActiveRegions - CountNumberOfValuelessItemsInThePlayersOfferArea( )); iAvailablePlayerOfferSlots = (gPlayersOfferActiveRegions - CountNumberOfValuelessItemsInThePlayersOfferArea( ));
// always reserve an empty slot for change. We can't tell for sure whether player is getting change because that // always reserve an empty slot for change. We can't tell for sure whether player is getting change because that
// could depend on how many items he's trying to buy won't fit - he could only be getting change because of that! // could depend on how many items he's trying to buy won't fit - he could only be getting change because of that!
if ( uiAvailablePlayerOfferSlots > 0 ) if ( iAvailablePlayerOfferSlots > 0 )
{ {
--uiAvailablePlayerOfferSlots; --iAvailablePlayerOfferSlots;
} }
//if there is NOT enough room in the players offer area //if there is NOT enough room in the players offer area
if( CountNumberOfItemsInTheArmsDealersOfferArea( ) > uiAvailablePlayerOfferSlots ) if( CountNumberOfItemsInTheArmsDealersOfferArea( ) > iAvailablePlayerOfferSlots )
{ {
// tell player there's not enough room in the player's offer area // tell player there's not enough room in the player's offer area
DoSkiMessageBox( MSG_BOX_BASIC_STYLE, SKI_Text[ SKI_TEXT_NO_MORE_ROOM_IN_PLAYER_OFFER_AREA ], SHOPKEEPER_SCREEN, MSG_BOX_FLAG_OK, NULL ); DoSkiMessageBox( MSG_BOX_BASIC_STYLE, SKI_Text[ SKI_TEXT_NO_MORE_ROOM_IN_PLAYER_OFFER_AREA ], SHOPKEEPER_SCREEN, MSG_BOX_FLAG_OK, NULL );
@@ -4539,7 +4536,7 @@ void RestrictSkiMouseCursor()
void SetSkiCursor( UINT16 usCursor ) void SetSkiCursor( UINT16 usCursor )
{ {
UINT8 ubCnt; int ubCnt;
//if we are setting up an item as a cursor //if we are setting up an item as a cursor
if( usCursor == EXTERN_CURSOR ) if( usCursor == EXTERN_CURSOR )
@@ -4639,7 +4636,7 @@ void SetSkiCursor( UINT16 usCursor )
if( gInvDesc.uiFlags & MSYS_REGION_EXISTS ) if( gInvDesc.uiFlags & MSYS_REGION_EXISTS )
MSYS_ChangeRegionCursor( &gInvDesc, usCursor ); MSYS_ChangeRegionCursor( &gInvDesc, usCursor );
for( ubCnt = 0; ubCnt < gMoveingItem.ItemObject[0]->attachments.size(); ubCnt++) for( ubCnt = 0; ubCnt < gMoveingItem.ItemObject[0]->attachments.size(); ++ubCnt)
{ {
if( gItemDescAttachmentRegions[ubCnt].uiFlags & MSYS_REGION_EXISTS ) if( gItemDescAttachmentRegions[ubCnt].uiFlags & MSYS_REGION_EXISTS )
MSYS_ChangeRegionCursor( &gItemDescAttachmentRegions[ubCnt], usCursor ); MSYS_ChangeRegionCursor( &gItemDescAttachmentRegions[ubCnt], usCursor );
@@ -5151,9 +5148,9 @@ void ShutUpShopKeeper()
gubSkiDirtyLevel = SKI_DIRTY_LEVEL2; gubSkiDirtyLevel = SKI_DIRTY_LEVEL2;
} }
UINT8 CountNumberOfValuelessItemsInThePlayersOfferArea( ) int CountNumberOfValuelessItemsInThePlayersOfferArea( )
{ {
UINT8 ubCount=0; int count = 0;
//loop through the players offer area and see if there are any items there //loop through the players offer area and see if there are any items there
for ( int ubCnt = 0; ubCnt<gPlayersOfferActiveRegions; ++ubCnt ) for ( int ubCnt = 0; ubCnt<gPlayersOfferActiveRegions; ++ubCnt )
@@ -5164,38 +5161,17 @@ UINT8 CountNumberOfValuelessItemsInThePlayersOfferArea( )
//and if it has no value //and if it has no value
if( !( PlayersOfferArea[ubCnt].uiFlags & ARMS_INV_PLAYERS_ITEM_HAS_VALUE ) ) if( !( PlayersOfferArea[ubCnt].uiFlags & ARMS_INV_PLAYERS_ITEM_HAS_VALUE ) )
{ {
++ubCount; ++count;
} }
} }
} }
return( ubCount ); return( count );
} }
UINT8 CountNumberOfItemsOfValueInThePlayersOfferArea( ) int CountNumberOfItemsInThePlayersOfferArea( )
{ {
UINT8 ubCount=0; int count = 0;
//loop through the players offer area and see if there are any items there
for ( int ubCnt = 0; ubCnt < gPlayersOfferActiveRegions; ++ubCnt )
{
//if is an item here
if( PlayersOfferArea[ubCnt].fActive )
{
//and if it has not been evaluated
if( PlayersOfferArea[ubCnt].uiFlags & ARMS_INV_PLAYERS_ITEM_HAS_VALUE )
{
ubCount++;
}
}
}
return( ubCount );
}
UINT8 CountNumberOfItemsInThePlayersOfferArea( )
{
UINT8 ubItemCount=0;
//loop through the player's offer area and see if there are any items there //loop through the player's offer area and see if there are any items there
for ( int ubCnt = 0; ubCnt < gPlayersOfferActiveRegions; ++ubCnt ) for ( int ubCnt = 0; ubCnt < gPlayersOfferActiveRegions; ++ubCnt )
@@ -5203,15 +5179,16 @@ UINT8 CountNumberOfItemsInThePlayersOfferArea( )
//if is an item here //if is an item here
if( PlayersOfferArea[ubCnt].fActive ) if( PlayersOfferArea[ubCnt].fActive )
{ {
++ubItemCount; ++count;
} }
} }
return( ubItemCount );
return( count );
} }
UINT8 CountNumberOfItemsInTheArmsDealersOfferArea( ) int CountNumberOfItemsInTheArmsDealersOfferArea( )
{ {
UINT8 ubItemCount=0; int count = 0;
//loop through the dealer's offer area and see if there are any items there //loop through the dealer's offer area and see if there are any items there
for ( int ubCnt = 0; ubCnt < gDealersOfferActiveRegions; ++ubCnt ) for ( int ubCnt = 0; ubCnt < gDealersOfferActiveRegions; ++ubCnt )
@@ -5219,11 +5196,11 @@ UINT8 CountNumberOfItemsInTheArmsDealersOfferArea( )
//if is an item here //if is an item here
if( ArmsDealerOfferArea[ubCnt].fActive ) if( ArmsDealerOfferArea[ubCnt].fActive )
{ {
++ubItemCount; ++count;
} }
} }
return( ubItemCount ); return( count );
} }
INT8 GetSlotNumberForMerc( UINT8 ubProfile ) INT8 GetSlotNumberForMerc( UINT8 ubProfile )
@@ -5659,8 +5636,8 @@ void EvaluateItemAddedToPlayersOfferArea( INT8 bSlotID, BOOLEAN fFirstOne )
//if the dealer repairs //if the dealer repairs
if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer == ARMS_DEALER_REPAIRS ) if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer == ARMS_DEALER_REPAIRS )
{ {
UINT32 uiNumberOfItemsInForRepairs = CountTotalItemsRepairDealerHasInForRepairs( gbSelectedArmsDealerID ); int uiNumberOfItemsInForRepairs = CountTotalItemsRepairDealerHasInForRepairs( gbSelectedArmsDealerID );
UINT32 uiNumberOfItemsAlreadyEvaluated = CountNumberOfItemsInTheArmsDealersOfferArea(); int uiNumberOfItemsAlreadyEvaluated = CountNumberOfItemsInTheArmsDealersOfferArea();
//Get the number of items being evaluated //Get the number of items being evaluated
ubNumberOfItemsAddedToRepairDuringThisEvaluation = PlayersOfferArea[ bSlotID ].ItemObject.ubNumberOfObjects; ubNumberOfItemsAddedToRepairDuringThisEvaluation = PlayersOfferArea[ bSlotID ].ItemObject.ubNumberOfObjects;
@@ -5687,10 +5664,8 @@ void EvaluateItemAddedToPlayersOfferArea( INT8 bSlotID, BOOLEAN fFirstOne )
//if the item is damaged, or is a rocket rifle (which always "need repairing" even at 100%, to reset imprinting) //if the item is damaged, or is a rocket rifle (which always "need repairing" even at 100%, to reset imprinting)
if( ( PlayersOfferArea[ bSlotID ].ItemObject[0]->data.objectStatus < 100 ) || fRocketRifleWasEvaluated ) if( ( PlayersOfferArea[ bSlotID ].ItemObject[0]->data.objectStatus < 100 ) || fRocketRifleWasEvaluated )
{ {
INT16 bSlotAddedTo;
// Move the item to the Dealer's Offer Area // Move the item to the Dealer's Offer Area
bSlotAddedTo = AddItemToArmsDealerOfferArea( &PlayersOfferArea[ bSlotID ], PlayersOfferArea[ bSlotID ].bSlotIdInOtherLocation ); INT16 bSlotAddedTo = AddItemToArmsDealerOfferArea( &PlayersOfferArea[ bSlotID ], PlayersOfferArea[ bSlotID ].bSlotIdInOtherLocation );
if( bSlotAddedTo != -1 ) if( bSlotAddedTo != -1 )
{ {
@@ -5706,7 +5681,7 @@ void EvaluateItemAddedToPlayersOfferArea( INT8 bSlotID, BOOLEAN fFirstOne )
ArmsDealerOfferArea[ bSlotAddedTo ].uiFlags &= ~ARMS_INV_ITEM_SELECTED; ArmsDealerOfferArea[ bSlotAddedTo ].uiFlags &= ~ARMS_INV_ITEM_SELECTED;
//increment the number of items being added //increment the number of items being added
ubNumberOfItemsAddedToRepairDuringThisEvaluation++; ++ubNumberOfItemsAddedToRepairDuringThisEvaluation;
// check if the item is really badly damaged // check if the item is really badly damaged
if( Item[ ArmsDealerOfferArea[ bSlotAddedTo ].sItemIndex ].usItemClass != IC_AMMO ) if( Item[ ArmsDealerOfferArea[ bSlotAddedTo ].sItemIndex ].usItemClass != IC_AMMO )
@@ -6010,16 +5985,17 @@ BOOLEAN WillShopKeeperRejectObjectsFromPlayer( INT8 bDealerId, INT8 bSlotId )
void CheckAndHandleClearingOfPlayerOfferArea( void ) void CheckAndHandleClearingOfPlayerOfferArea( void )
{ {
INT32 iCounter = 0;
BOOLEAN fActiveSlot = FALSE; BOOLEAN fActiveSlot = FALSE;
// find out if all the player trade slots/offer area is empty // find out if all the player trade slots/offer area is empty
for ( iCounter = 0; iCounter<gPlayersOfferActiveRegions; ++iCounter ) for ( int iCounter = 0; iCounter<gPlayersOfferActiveRegions; ++iCounter )
{ {
if( PlayersOfferArea[ iCounter ].fActive == TRUE ) if( PlayersOfferArea[ iCounter ].fActive == TRUE )
{ {
// nope, there is an active slot // nope, there is an active slot
fActiveSlot = TRUE; fActiveSlot = TRUE;
break;
} }
} }
@@ -6055,10 +6031,9 @@ BOOLEAN CanShopkeeperOverrideDialogue( void )
INT16 GetNumberOfItemsInPlayerOfferArea( void ) INT16 GetNumberOfItemsInPlayerOfferArea( void )
{ {
INT16 sCounter = 0; INT16 sCounter = 0;
INT32 iCounter = 0;
// find number of active slot in player offer area // find number of active slot in player offer area
for ( iCounter = 0; iCounter < gPlayersOfferActiveRegions; ++iCounter ) for ( int iCounter = 0; iCounter < gPlayersOfferActiveRegions; ++iCounter )
{ {
if( PlayersOfferArea[ iCounter ].fActive ) if( PlayersOfferArea[ iCounter ].fActive )
{ {
@@ -6245,7 +6220,7 @@ void DeleteShopKeeperItemDescBox()
EnableAllDealersInventorySlots(); EnableAllDealersInventorySlots();
EnableAllDealersOfferSlots(); EnableAllDealersOfferSlots();
for ( INT32 iCnt = 0; iCnt < gPlayersOfferActiveRegions; ++iCnt ) for ( int iCnt = 0; iCnt < gPlayersOfferActiveRegions; ++iCnt )
{ {
MSYS_EnableRegion( &gPlayersOfferSlotsMouseRegions[ iCnt ] ); MSYS_EnableRegion( &gPlayersOfferSlotsMouseRegions[ iCnt ] );
MSYS_EnableRegion( &gPlayersOfferSlotsSmallFaceMouseRegions[ iCnt ] ); MSYS_EnableRegion( &gPlayersOfferSlotsSmallFaceMouseRegions[ iCnt ] );
@@ -6261,11 +6236,10 @@ BOOLEAN OfferObjectToDealer( OBJECTTYPE *pComplexObject, UINT8 ubOwnerProfileId,
{ {
UINT8 ubRepairableSubObjects; UINT8 ubRepairableSubObjects;
UINT8 ubNonRepairableSubObjects; UINT8 ubNonRepairableSubObjects;
UINT8 ubDealerOfferAreaSlotsNeeded; int ubDealerOfferAreaSlotsNeeded;
UINT8 ubPlayerOfferAreaSlotsNeeded; int ubPlayerOfferAreaSlotsNeeded;
UINT8 ubDiff; int ubDiff;
UINT8 ubHowManyMoreItemsCanDealerTake; int ubHowManyMoreItemsCanDealerTake;
UINT8 ubSubObject;
BOOLEAN fFirstOne = TRUE; BOOLEAN fFirstOne = TRUE;
BOOLEAN fSuccess = FALSE; BOOLEAN fSuccess = FALSE;
@@ -6307,7 +6281,7 @@ BOOLEAN OfferObjectToDealer( OBJECTTYPE *pComplexObject, UINT8 ubOwnerProfileId,
if ( ubDealerOfferAreaSlotsNeeded > 0 ) if ( ubDealerOfferAreaSlotsNeeded > 0 )
{ {
// we need at least one EXTRA empty slot in player's area to pass repairable objects through for their evaluation // we need at least one EXTRA empty slot in player's area to pass repairable objects through for their evaluation
ubPlayerOfferAreaSlotsNeeded++; ++ubPlayerOfferAreaSlotsNeeded;
} }
//this is a silly assert, was it meant to be something else? //this is a silly assert, was it meant to be something else?
@@ -6332,7 +6306,7 @@ BOOLEAN OfferObjectToDealer( OBJECTTYPE *pComplexObject, UINT8 ubOwnerProfileId,
} }
// we have room, so move them all to the appropriate slots // we have room, so move them all to the appropriate slots
for ( ubSubObject = 0; ubSubObject < subObjects.size(); ubSubObject++ ) for ( size_t ubSubObject = 0; ubSubObject < subObjects.size(); ++ubSubObject )
{ {
// if it's the main item itself (always in the very first subobject), and it has no other subobjects // if it's the main item itself (always in the very first subobject), and it has no other subobjects
if ( ( ubSubObject == 0 ) && ( subObjects.size() == 1) ) if ( ( ubSubObject == 0 ) && ( subObjects.size() == 1) )