From 02d2c92f66ae3268d2a71132656c35ae21130631 Mon Sep 17 00:00:00 2001 From: Sevenfm Date: Tue, 27 Apr 2021 04:00:07 +0000 Subject: [PATCH] ASD deployment fix (by rftr): - fix: robots, jeeps, and tanks now appear in garrison reinforcement and patrol groups (if the ASD and these units are enabled) - fix: ASD continues to purchase jeeps if tanks are disabled - removed some magic numbers in Strategic AI.cpp git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8982 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/ASD.cpp | 2 +- Strategic/Strategic AI.cpp | 62 ++++++++++++++++++++++++-------------- Strategic/Strategic AI.h | 12 ++++++++ 3 files changed, 52 insertions(+), 24 deletions(-) diff --git a/Strategic/ASD.cpp b/Strategic/ASD.cpp index 92c3256e2..f7da6a464 100644 --- a/Strategic/ASD.cpp +++ b/Strategic/ASD.cpp @@ -257,7 +257,7 @@ void ASDDecideOnPurchases() needed_jeep = min( 10, 2 + highestplayerprogress / 10 ); // if we already unlocked tanks, we no longer want jeeps - they are replaced by tanks - if ( gASD_Flags & ASDFACT_TANK_UNLOCKED ) + if ( (gASD_Flags & ASDFACT_TANK_UNLOCKED) && gGameExternalOptions.fASDAssignsTanks ) { needed_jeep = 0; } diff --git a/Strategic/Strategic AI.cpp b/Strategic/Strategic AI.cpp index bf1044d2d..79289e6ff 100644 --- a/Strategic/Strategic AI.cpp +++ b/Strategic/Strategic AI.cpp @@ -423,6 +423,8 @@ BOOLEAN AdjacentSectorIsImportantAndUndefended( UINT8 ubSectorID ); BOOLEAN HandleEmptySectorNoticedByPatrolGroup( GROUP *pGroup, UINT8 ubEmptySectorID ); void HandleEmptySectorNoticedByGarrison( UINT8 ubGarrisonSectorID, UINT8 ubEmptySectorID ); +UINT16 GetOffensePoints(const ENEMYGROUP* pEnemyGroup); +UINT16 GetOffensePoints(const SECTORINFO* pSectorInfo); BOOLEAN PlayerForceTooStrong( UINT8 ubSectorID, UINT16 usOffensePoints, UINT16 *pusDefencePoints ); void RequestAttackOnSector( UINT8 ubSectorID, UINT16 usDefencePoints ); void RequestHighPriorityStagingGroupReinforcements( GROUP *pGroup ); @@ -627,7 +629,26 @@ INT32 ReinforcementsAvailable( INT32 iGarrisonID ) return iReinforcementsAvailable; } -// +UINT16 GetOffensePoints(const ENEMYGROUP* pEnemyGroup) +{ + return pEnemyGroup->ubNumAdmins * ADMIN_POINTS_MODIFIER + + pEnemyGroup->ubNumTroops * REGULAR_POINTS_MODIFIER + + pEnemyGroup->ubNumElites * ELITE_POINTS_MODIFIER + + pEnemyGroup->ubNumRobots * ROBOT_POINTS_MODIFIER + + pEnemyGroup->ubNumTanks * TANK_POINTS_MODIFIER + + pEnemyGroup->ubNumJeeps * JEEP_POINTS_MODIFIER; +} + +UINT16 GetOffensePoints(const SECTORINFO* pSectorInfo) +{ + return pSectorInfo->ubNumAdmins * ADMIN_POINTS_MODIFIER + + pSectorInfo->ubNumTroops * REGULAR_POINTS_MODIFIER + + pSectorInfo->ubNumElites * ELITE_POINTS_MODIFIER + + pSectorInfo->ubNumRobots * ROBOT_POINTS_MODIFIER + + pSectorInfo->ubNumTanks * TANK_POINTS_MODIFIER + + pSectorInfo->ubNumJeeps * JEEP_POINTS_MODIFIER; +} + BOOLEAN PlayerForceTooStrong( UINT8 ubSectorID, UINT16 usOffensePoints, UINT16 *pusDefencePoints ) { SECTORINFO *pSector; @@ -639,9 +660,9 @@ BOOLEAN PlayerForceTooStrong( UINT8 ubSectorID, UINT16 usOffensePoints, UINT16 * // SANDRO - EVALUATE THE STRENGTH OF MILITIA BASED ON INI SETTING *pusDefencePoints = PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 5; - *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, GREEN_MILITIA ) * 1 * (100 + gGameExternalOptions.sGreenMilitiaAutoresolveStrength) / 100); - *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, REGULAR_MILITIA ) * 2 * (100 + gGameExternalOptions.sRegularMilitiaAutoresolveStrength) / 100); - *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, ELITE_MILITIA ) * 3 * (100 + gGameExternalOptions.sVeteranMilitiaAutoresolveStrength) / 100); + *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, GREEN_MILITIA ) * GREEN_MILITIA_POINTS_MODIFIER * (100 + gGameExternalOptions.sGreenMilitiaAutoresolveStrength) / 100); + *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, REGULAR_MILITIA ) * REGULAR_MILITIA_POINTS_MODIFIER * (100 + gGameExternalOptions.sRegularMilitiaAutoresolveStrength) / 100); + *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, ELITE_MILITIA ) * ELITE_MILITIA_POINTS_MODIFIER * (100 + gGameExternalOptions.sVeteranMilitiaAutoresolveStrength) / 100); if( *pusDefencePoints > usOffensePoints ) { @@ -1849,12 +1870,7 @@ BOOLEAN HandlePlayerGroupNoticedByPatrolGroup( GROUP *pPlayerGroup, GROUP *pEnem UINT8 ubSectorID; ubSectorID = (BOOLEAN)SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY ); - usOffensePoints = pEnemyGroup->pEnemyGroup->ubNumAdmins * 2 + - pEnemyGroup->pEnemyGroup->ubNumTroops * 4 + - pEnemyGroup->pEnemyGroup->ubNumElites * 6 + - pEnemyGroup->pEnemyGroup->ubNumRobots * 15 + - pEnemyGroup->pEnemyGroup->ubNumTanks * 20 + - pEnemyGroup->pEnemyGroup->ubNumJeeps * 12; + usOffensePoints = GetOffensePoints(pEnemyGroup->pEnemyGroup); if( PlayerForceTooStrong( ubSectorID, usOffensePoints, &usDefencePoints ) ) { RequestAttackOnSector( ubSectorID, usDefencePoints ); @@ -1904,12 +1920,7 @@ void HandlePlayerGroupNoticedByGarrison( GROUP *pPlayerGroup, UINT8 ubSectorID ) { return; } - usOffensePoints = pSector->ubNumAdmins * 2 + - pSector->ubNumTroops * 4 + - pSector->ubNumElites * 6 + - pSector->ubNumRobots * 15 + - pSector->ubNumTanks * 20 + - pSector->ubNumJeeps * 12; + usOffensePoints = GetOffensePoints(pSector); if( PlayerForceTooStrong( ubSectorID, usOffensePoints, &usDefencePoints ) ) { RequestAttackOnSector( ubSectorID, usDefencePoints ); @@ -1963,12 +1974,7 @@ BOOLEAN HandleMilitiaNoticedByPatrolGroup( UINT8 ubSectorID, GROUP *pEnemyGroup UINT16 usOffensePoints, usDefencePoints; UINT8 ubSectorX = SECTORX( ubSectorID ); UINT8 ubSectorY = SECTORY( ubSectorID ); - usOffensePoints = pEnemyGroup->pEnemyGroup->ubNumAdmins * 2 + - pEnemyGroup->pEnemyGroup->ubNumTroops * 4 + - pEnemyGroup->pEnemyGroup->ubNumElites * 6 + - pEnemyGroup->pEnemyGroup->ubNumRobots * 15 + - pEnemyGroup->pEnemyGroup->ubNumTanks * 20 + - pEnemyGroup->pEnemyGroup->ubNumJeeps * 12; + usOffensePoints = GetOffensePoints(pEnemyGroup->pEnemyGroup); if( PlayerForceTooStrong( ubSectorID, usOffensePoints, &usDefencePoints ) ) { RequestAttackOnSector( ubSectorID, usDefencePoints ); @@ -3140,6 +3146,7 @@ BOOLEAN SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoi pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, (UINT8)iReinforcementsApproved, 0, 0, 0, 0 ); ConvertGroupTroopsToComposition( pGroup, gGarrisonGroup[ iDstGarrisonID ].ubComposition ); pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY ); + InitializeGroup(GROUP_TYPE_PATROL, (UINT8)iReinforcementsApproved, *pGroup->pEnemyGroup, Random(10) < gGameOptions.ubDifficultyLevel ); //Madd: unlimited reinforcements? if ( !gfUnlimitedTroops ) giReinforcementPool -= iReinforcementsApproved; @@ -3229,6 +3236,7 @@ BOOLEAN SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoi pGroup = CreateNewEnemyGroupDepartingFromSector( gGarrisonGroup[ iSrcGarrisonID ].ubSectorID, 0, (UINT8)iReinforcementsApproved, 0, 0, 0, 0 ); ConvertGroupTroopsToComposition( pGroup, gGarrisonGroup[ iDstGarrisonID ].ubComposition ); + InitializeGroup(GROUP_TYPE_PATROL, (UINT8)iReinforcementsApproved, *pGroup->pEnemyGroup, Random(10) < gGameOptions.ubDifficultyLevel ); RemoveSoldiersFromGarrisonBasedOnComposition( iSrcGarrisonID, pGroup->ubGroupSize ); pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY ); pGroup->ubMoveType = ONE_WAY; @@ -3319,6 +3327,7 @@ BOOLEAN SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup ) iReinforcementsApproved = min( iReinforcementsRequested, giReinforcementPool ); pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, (UINT8)iReinforcementsApproved, 0, 0, 0, 0 ); pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY ); + InitializeGroup(GROUP_TYPE_PATROL, iReinforcementsApproved, *pGroup->pEnemyGroup, Random(10) < gGameOptions.ubDifficultyLevel); //Madd: unlimited reinforcements? if ( !gfUnlimitedTroops ) @@ -3371,6 +3380,7 @@ BOOLEAN SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup ) pGroup = CreateNewEnemyGroupDepartingFromSector( gGarrisonGroup[ iSrcGarrisonID ].ubSectorID, 0, (UINT8)iReinforcementsApproved, 0, 0, 0, 0 ); pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY ); gPatrolGroup[ iPatrolID ].ubPendingGroupID = pGroup->ubGroupID; + InitializeGroup(GROUP_TYPE_PATROL, iReinforcementsApproved, *pGroup->pEnemyGroup, Random(10) < gGameOptions.ubDifficultyLevel); RemoveSoldiersFromGarrisonBasedOnComposition( iSrcGarrisonID, pGroup->ubGroupSize ); @@ -5910,6 +5920,7 @@ void RequestHighPriorityGarrisonReinforcements( INT32 iGarrisonID, UINT8 ubSoldi pGroup->pEnemyGroup->ubIntention = REINFORCEMENTS; gGarrisonGroup[ iGarrisonID ].ubPendingGroupID = pGroup->ubGroupID; pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY ); + InitializeGroup(GROUP_TYPE_PATROL, pGroup->pEnemyGroup->ubNumTroops, *pGroup->pEnemyGroup, Random(10) < gGameOptions.ubDifficultyLevel ); //Madd: unlimited reinforcements? if ( !gfUnlimitedTroops ) @@ -7036,6 +7047,11 @@ GROUP* FindPendingGroupForGarrisonSector( UINT8 ubSectorID ) return NULL; } +void InitializeGroup( const GROUP_TYPE groupType, const UINT8 groupSize, ENEMYGROUP& enemyGroup, const BOOLEAN asdUpgrade ) +{ + InitializeGroup( groupType, groupSize, enemyGroup.ubNumTroops, enemyGroup.ubNumElites, enemyGroup.ubNumRobots, enemyGroup.ubNumJeeps, enemyGroup.ubNumTanks, asdUpgrade ); +} + void InitializeGroup( const GROUP_TYPE groupType, const UINT8 groupSize, UINT8 &troopCount, UINT8 &eliteCount, UINT8 &robotCount, UINT8 &jeepCount, UINT8 &tankCount, const BOOLEAN asdUpgrade ) { troopCount = groupSize; @@ -7069,7 +7085,7 @@ void InitializeGroup( const GROUP_TYPE groupType, const UINT8 groupSize, UINT8 & if ( gGameExternalOptions.fASDAssignsRobots && ASDSoldierUpgradeToRobot() ) { - const int numRobots = Random(difficultyMod); + const int numRobots = 1 + Random(difficultyMod); troopCount -= numRobots; robotCount += numRobots; } diff --git a/Strategic/Strategic AI.h b/Strategic/Strategic AI.h index 7c5541ddb..3f2d3b80f 100644 --- a/Strategic/Strategic AI.h +++ b/Strategic/Strategic AI.h @@ -81,6 +81,7 @@ enum GROUP_TYPE GROUP_TYPE_PATROL }; +void InitializeGroup(const GROUP_TYPE groupType, const UINT8 groupSize, ENEMYGROUP& enemyGroup, const BOOLEAN asdUpgrade); void InitializeGroup(const GROUP_TYPE groupType, const UINT8 groupSize, UINT8 &troopCount, UINT8 &eliteCount, UINT8 &robotCount, UINT8 &jeepCount, UINT8 &tankCount, const BOOLEAN asdUpgrade); extern BOOLEAN gfDisplayStrategicAILogs; @@ -166,4 +167,15 @@ typedef struct GARRISON_GROUP #define MAX_PATROL_GROUPS 50 #define MAX_ARMY_COMPOSITIONS 60 +// attack/defense point modifiers, used to determine if the AI should attack a sector +#define ADMIN_POINTS_MODIFIER 2 +#define REGULAR_POINTS_MODIFIER 4 +#define ELITE_POINTS_MODIFIER 6 +#define ROBOT_POINTS_MODIFIER 15 +#define JEEP_POINTS_MODIFIER 12 +#define TANK_POINTS_MODIFIER 20 +#define GREEN_MILITIA_POINTS_MODIFIER 1 +#define REGULAR_MILITIA_POINTS_MODIFIER 2 +#define ELITE_MILITIA_POINTS_MODIFIER 3 + #endif \ No newline at end of file