From 186a72251950a655d19f88eeaa3ddfb5e5f66a9d Mon Sep 17 00:00:00 2001 From: Sevenfm Date: Fri, 8 Apr 2022 21:00:58 +0000 Subject: [PATCH] Fix, improv.: NO_REMOVE_RANDOM_SECTOR_ITEMS (by sun_alf). fix: it was using doubled number of arrived enemies (NumEnemiesInAnySector counts the same enemies twice if called prior to RemovePGroup.) improvement: * chance to steal a WORLDITEM is it's coolness * 10%. * looters can steal up to "3 kg * numEnemies" of items in total, and no more. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9362 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Player Command.cpp | 14 +++++-------- Strategic/Strategic Town Loyalty.cpp | 31 ++++++++++++++++++++++++---- Strategic/Strategic Town Loyalty.h | 2 +- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Strategic/Player Command.cpp b/Strategic/Player Command.cpp index 34581458..5da09c71 100644 --- a/Strategic/Player Command.cpp +++ b/Strategic/Player Command.cpp @@ -457,7 +457,6 @@ BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BO UINT16 usMapSector = 0; BOOLEAN fWasPlayerControlled = FALSE; INT8 bTownId = 0; - UINT8 ubTheftChance; UINT8 ubSectorID; //KM : August 6, 1999 Patch fix @@ -558,14 +557,11 @@ BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BO // stealing should fail anyway 'cause there shouldn't be a temp file for unvisited sectors, but let's check anyway if ( GetSectorFlagStatus( sMapX, sMapY, ( UINT8 ) bMapZ, SF_ALREADY_VISITED ) == TRUE ) { - // enemies can steal items left lying about (random chance). The more there are, the more they take! - ubTheftChance = 5 * NumEnemiesInAnySector( sMapX, sMapY, bMapZ ); - // max 90%, some stuff may just simply not get found - if (ubTheftChance > 90 ) - { - ubTheftChance = 90; - } - RemoveRandomItemsInSector( sMapX, sMapY, bMapZ, ubTheftChance ); + // Enemies can steal items left lying about, each one can carry out up to X kg (defined in RemoveRandomItemsInSector). + // Don't care underground sectors here -- we are in overground code branch. + UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, ubNumTanks, ubNumJeeps; + GetNumberOfStationaryEnemiesInSector( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumRobots, &ubNumTanks, &ubNumJeeps ); + RemoveRandomItemsInSector( sMapX, sMapY, bMapZ, (UINT32)ubNumAdmins + ubNumTroops + ubNumElites ); } // don't touch fPlayer flag for a surface sector lost to the enemies! diff --git a/Strategic/Strategic Town Loyalty.cpp b/Strategic/Strategic Town Loyalty.cpp index 2427201b..8fb982ad 100644 --- a/Strategic/Strategic Town Loyalty.cpp +++ b/Strategic/Strategic Town Loyalty.cpp @@ -1106,10 +1106,30 @@ void HandleLoyaltyForDemolitionOfBuilding( SOLDIERTYPE *pSoldier, INT16 sPointsD } -void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT8 ubChance ) +static BOOLEAN CanRemoveWorldItem( WORLDITEM *worlditem, UINT32 uiMaxWeight, UINT32 *pStackWeight ) { + BOOLEAN result = FALSE; + UINT32 uiChance = 10UL * Item[worlditem->object.usItem].ubCoolness; + + UINT32 uiStackWeight = 0; + for ( int objIndex = 0; objIndex < worlditem->object.ubNumberOfObjects; objIndex++ ) + uiStackWeight += worlditem->object.GetWeightOfObjectInStack( objIndex ); + + if ( Chance( uiChance ) && uiStackWeight <= uiMaxWeight ) + result = TRUE; + + *pStackWeight = uiStackWeight; + return result; +} + + +void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT32 uiNumEnemies ) +{ + const UINT32 uiCarryWeightPerSoldier = 30; // 3 kg + // remove random items in sector - UINT32 uiNumberOfItems = 0, iCounter = 0; + UINT32 uiNumberOfItems = 0, iCounter = 0, uiStackWeight = 0; + UINT32 uiWeightToSteal = uiCarryWeightPerSoldier * uiNumEnemies; std::vector pItemList;//dnl ch75 271013 UINT32 uiNewTotal = 0; CHAR16 wSectorName[ 128 ]; @@ -1149,11 +1169,12 @@ void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, //if the item exists, and is visible and reachable, see if it should be stolen if ( pItemList[ iCounter ].fExists && pItemList[ iCounter ].bVisible == TRUE && pItemList[ iCounter ].usFlags & WORLD_ITEM_REACHABLE ) { - if ( Chance( ubChance ) ) + if ( CanRemoveWorldItem( &pItemList[iCounter], uiWeightToSteal, &uiStackWeight ) ) { // remove --uiNewTotal; pItemList[ iCounter ].fExists = FALSE; + uiWeightToSteal -= uiStackWeight; // debug message ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s stolen in %s!", ItemNames[ pItemList[ iCounter ].object.usItem ], wSectorName ); @@ -1174,9 +1195,11 @@ void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, // note, can't do reachable test here because we'd have to do a path call... if ( gWorldItems[ iCounter ].fExists && gWorldItems[ iCounter ].bVisible == TRUE ) { - if ( Chance( ubChance ) ) + if ( CanRemoveWorldItem( &gWorldItems[iCounter], uiWeightToSteal, &uiStackWeight ) ) { RemoveItemFromPool( gWorldItems[ iCounter ].sGridNo , iCounter, gWorldItems[ iCounter ].ubLevel ); + uiWeightToSteal -= uiStackWeight; + // debug message ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s stolen in %s!", ItemNames[ gWorldItems[ iCounter ].object.usItem ], wSectorName ); } diff --git a/Strategic/Strategic Town Loyalty.h b/Strategic/Strategic Town Loyalty.h index abee6506..2cde0c52 100644 --- a/Strategic/Strategic Town Loyalty.h +++ b/Strategic/Strategic Town Loyalty.h @@ -137,7 +137,7 @@ BOOLEAN HandleLoyaltyAdjustmentForRobbery( SOLDIERTYPE *pSoldier ); void HandleLoyaltyForDemolitionOfBuilding( SOLDIERTYPE *pSoldier, INT16 sPointsDmg ); // remove random item from this sector -void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT8 ubChance ); +void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT32 uiNumEnemies ); // get the shortest distance between these two towns via roads INT32 GetTownDistances( UINT8 ubTown, UINT8 ubTownA );