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
This commit is contained in:
Sevenfm
2022-04-08 21:00:58 +00:00
parent 89e0fd33ec
commit 186a722519
3 changed files with 33 additions and 14 deletions
+5 -9
View File
@@ -457,7 +457,6 @@ BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BO
UINT16 usMapSector = 0; UINT16 usMapSector = 0;
BOOLEAN fWasPlayerControlled = FALSE; BOOLEAN fWasPlayerControlled = FALSE;
INT8 bTownId = 0; INT8 bTownId = 0;
UINT8 ubTheftChance;
UINT8 ubSectorID; UINT8 ubSectorID;
//KM : August 6, 1999 Patch fix //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 // 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 ) 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! // Enemies can steal items left lying about, each one can carry out up to X kg (defined in RemoveRandomItemsInSector).
ubTheftChance = 5 * NumEnemiesInAnySector( sMapX, sMapY, bMapZ ); // Don't care underground sectors here -- we are in overground code branch.
// max 90%, some stuff may just simply not get found UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, ubNumTanks, ubNumJeeps;
if (ubTheftChance > 90 ) GetNumberOfStationaryEnemiesInSector( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumRobots, &ubNumTanks, &ubNumJeeps );
{ RemoveRandomItemsInSector( sMapX, sMapY, bMapZ, (UINT32)ubNumAdmins + ubNumTroops + ubNumElites );
ubTheftChance = 90;
}
RemoveRandomItemsInSector( sMapX, sMapY, bMapZ, ubTheftChance );
} }
// don't touch fPlayer flag for a surface sector lost to the enemies! // don't touch fPlayer flag for a surface sector lost to the enemies!
+27 -4
View File
@@ -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 // remove random items in sector
UINT32 uiNumberOfItems = 0, iCounter = 0; UINT32 uiNumberOfItems = 0, iCounter = 0, uiStackWeight = 0;
UINT32 uiWeightToSteal = uiCarryWeightPerSoldier * uiNumEnemies;
std::vector<WORLDITEM> pItemList;//dnl ch75 271013 std::vector<WORLDITEM> pItemList;//dnl ch75 271013
UINT32 uiNewTotal = 0; UINT32 uiNewTotal = 0;
CHAR16 wSectorName[ 128 ]; 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 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 ( pItemList[ iCounter ].fExists && pItemList[ iCounter ].bVisible == TRUE && pItemList[ iCounter ].usFlags & WORLD_ITEM_REACHABLE )
{ {
if ( Chance( ubChance ) ) if ( CanRemoveWorldItem( &pItemList[iCounter], uiWeightToSteal, &uiStackWeight ) )
{ {
// remove // remove
--uiNewTotal; --uiNewTotal;
pItemList[ iCounter ].fExists = FALSE; pItemList[ iCounter ].fExists = FALSE;
uiWeightToSteal -= uiStackWeight;
// debug message // debug message
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s stolen in %s!", ItemNames[ pItemList[ iCounter ].object.usItem ], wSectorName ); 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... // 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 ( gWorldItems[ iCounter ].fExists && gWorldItems[ iCounter ].bVisible == TRUE )
{ {
if ( Chance( ubChance ) ) if ( CanRemoveWorldItem( &gWorldItems[iCounter], uiWeightToSteal, &uiStackWeight ) )
{ {
RemoveItemFromPool( gWorldItems[ iCounter ].sGridNo , iCounter, gWorldItems[ iCounter ].ubLevel ); RemoveItemFromPool( gWorldItems[ iCounter ].sGridNo , iCounter, gWorldItems[ iCounter ].ubLevel );
uiWeightToSteal -= uiStackWeight;
// debug message // debug message
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s stolen in %s!", ItemNames[ gWorldItems[ iCounter ].object.usItem ], wSectorName ); ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s stolen in %s!", ItemNames[ gWorldItems[ iCounter ].object.usItem ], wSectorName );
} }
+1 -1
View File
@@ -137,7 +137,7 @@ BOOLEAN HandleLoyaltyAdjustmentForRobbery( SOLDIERTYPE *pSoldier );
void HandleLoyaltyForDemolitionOfBuilding( SOLDIERTYPE *pSoldier, INT16 sPointsDmg ); void HandleLoyaltyForDemolitionOfBuilding( SOLDIERTYPE *pSoldier, INT16 sPointsDmg );
// remove random item from this sector // 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 // get the shortest distance between these two towns via roads
INT32 GetTownDistances( UINT8 ubTown, UINT8 ubTownA ); INT32 GetTownDistances( UINT8 ubTown, UINT8 ubTownA );