mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
AI:
- new option AI_SAFE_SUPPRESSION adds additional checks for AI to avoid hitting friends when using suppression fire. - chance to use suppression fire depends on actual chance to hit and SUPPRESSION_EFFECTIVENESS option - reduced short burst to 2 bullets. - improved code to use short burst git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8901 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -2306,6 +2306,7 @@ void LoadGameExternalOptions()
|
||||
gGameExternalOptions.fAIPathTweaks = iniReader.ReadBoolean("Tactical AI Settings", "AI_PATH_TWEAKS", TRUE);
|
||||
gGameExternalOptions.fAIDecisionInfo = iniReader.ReadBoolean("Tactical AI Settings", "AI_DECISION_INFO", FALSE);
|
||||
gGameExternalOptions.fAIShootUnseen = iniReader.ReadBoolean("Tactical AI Settings", "AI_SHOOT_UNSEEN", FALSE);
|
||||
gGameExternalOptions.fAISafeSuppression = iniReader.ReadBoolean("Tactical AI Settings", "AI_SAFE_SUPPRESSION", TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1566,6 +1566,7 @@ typedef struct
|
||||
BOOLEAN fAIPathTweaks;
|
||||
BOOLEAN fAIDecisionInfo;
|
||||
BOOLEAN fAIShootUnseen;
|
||||
BOOLEAN fAISafeSuppression;
|
||||
|
||||
} GAME_EXTERNAL_OPTIONS;
|
||||
|
||||
|
||||
@@ -6138,3 +6138,41 @@ UINT8 CountPublicKnownEnemies(SOLDIERTYPE *pSoldier)
|
||||
|
||||
return ubNum;
|
||||
}
|
||||
|
||||
// sevenfm: check if suppression is possible (count friends in the fire direction)
|
||||
BOOLEAN CheckSuppressionDirection(SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bTargetLevel)
|
||||
{
|
||||
SOLDIERTYPE * pFriend;
|
||||
UINT8 ubShootingDir;
|
||||
UINT32 uiLoop;
|
||||
|
||||
CHECKF(pSoldier);
|
||||
CHECKF(!TileIsOutOfBounds(sTargetGridNo));
|
||||
|
||||
ubShootingDir = AIDirection(pSoldier->sGridNo, sTargetGridNo);
|
||||
|
||||
for (uiLoop = 0; uiLoop < guiNumMercSlots; ++uiLoop)
|
||||
{
|
||||
pFriend = MercSlots[uiLoop];
|
||||
|
||||
if (pFriend &&
|
||||
pFriend != pSoldier &&
|
||||
pFriend->bActive &&
|
||||
pFriend->bVisible == TRUE &&
|
||||
pFriend->stats.bLife >= OKLIFE &&
|
||||
(pFriend->bSide == pSoldier->bSide || CONSIDERED_NEUTRAL(pSoldier, pFriend)) &&
|
||||
(pFriend->pathing.bLevel == pSoldier->pathing.bLevel || pFriend->pathing.bLevel == bTargetLevel) &&
|
||||
ubShootingDir == AIDirection(pSoldier->sGridNo, pFriend->sGridNo) &&
|
||||
PythSpacesAway(pSoldier->sGridNo, pFriend->sGridNo) > 1 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, pFriend->sGridNo) < 2 * TACTICAL_RANGE &&
|
||||
(gAnimControl[pFriend->usAnimState].ubHeight == ANIM_STAND || gGameExternalOptions.fAllowTargetHeadAndLegIfProne) &&
|
||||
//!pFriend->IsCowering() &&
|
||||
AISoldierToSoldierChanceToGetThrough(pSoldier, pFriend) > 25)
|
||||
//LocationToLocationLineOfSightTest(pSoldier->sGridNo, pSoldier->pathing.bLevel, pFriend->sGridNo, pFriend->pathing.bLevel, TRUE, NO_DISTANCE_LIMIT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3006,6 +3006,8 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
pSoldier->aiData.bOrders != SNIPER &&
|
||||
BestShot.ubFriendlyFireChance <= MIN_CHANCE_TO_ACCIDENTALLY_HIT_SOMEONE &&
|
||||
!AICheckIsFlanking(pSoldier) &&
|
||||
(Chance(BestShot.ubChanceToReallyHit) || Chance(gGameExternalOptions.sSuppressionEffectiveness)) &&
|
||||
(!gGameExternalOptions.fAISafeSuppression || CheckSuppressionDirection(pSoldier, BestShot.sTarget, BestShot.bTargetLevel)) &&
|
||||
!pSoldier->RetreatCounterValue() &&
|
||||
// check cover
|
||||
(fAnyCover || // safe position
|
||||
@@ -6152,12 +6154,20 @@ L_NEWAIM:
|
||||
}
|
||||
|
||||
pSoldier->bDoAutofire--;
|
||||
if(!UsingNewCTHSystem() && pSoldier->bDoAutofire < 3 && pSoldier->aiData.bAimTime > 0 && pSoldier->inv[BestAttack.bWeaponIn][0]->data.gun.ubGunShotsLeft >= 3)//dnl ch69 130913 let try increase autofire rate for aim cost
|
||||
|
||||
//dnl ch69 130913 let try increase autofire rate for aim cost
|
||||
if(!UsingNewCTHSystem() &&
|
||||
pSoldier->bDoAutofire < 3 &&
|
||||
pSoldier->aiData.bAimTime > 0 &&
|
||||
pSoldier->inv[BestAttack.bWeaponIn][0]->data.gun.ubGunShotsLeft >= 3 &&
|
||||
Chance(gGameExternalOptions.sSuppressionEffectiveness) &&
|
||||
(!gGameExternalOptions.fAISafeSuppression || CheckSuppressionDirection(pSoldier, BestShot.sTarget, BestShot.bTargetLevel)))
|
||||
{
|
||||
pSoldier->aiData.bAimTime--;
|
||||
sActualAimAP = CalcAPCostForAiming(pSoldier, BestAttack.sTarget, (INT8)pSoldier->aiData.bAimTime);
|
||||
goto L_NEWAIM;
|
||||
}
|
||||
|
||||
if (pSoldier->bDoAutofire > 0)
|
||||
{
|
||||
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire, pSoldier );
|
||||
@@ -6218,18 +6228,27 @@ L_NEWAIM:
|
||||
//dnl ch69 140913 return aiming for autofire with halfautofire fix
|
||||
pSoldier->bDoBurst = 1;
|
||||
INT16 ubHalfBurstAPs = 256;
|
||||
if(pSoldier->inv[BestAttack.bWeaponIn][0]->data.gun.ubGunShotsLeft < 4)
|
||||
if (pSoldier->inv[BestAttack.bWeaponIn][0]->data.gun.ubGunShotsLeft < 4)
|
||||
{
|
||||
iChance = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ubHalfBurstAPs = CalcAPsToAutofire(pSoldier->CalcActionPoints(), &pSoldier->inv[BestAttack.bWeaponIn], 4, pSoldier);
|
||||
if(Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto)
|
||||
iChance = 35;
|
||||
ubHalfBurstAPs = CalcAPsToAutofire(pSoldier->CalcActionPoints(), &pSoldier->inv[BestAttack.bWeaponIn], 2, pSoldier);
|
||||
|
||||
if (!CheckSuppressionDirection(pSoldier, BestAttack.sTarget, BestAttack.bTargetLevel))
|
||||
iChance = 100;
|
||||
else
|
||||
iChance = BestAttack.ubChanceToReallyHit / 2;
|
||||
|
||||
if (Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto || pSoldier->aiData.bOppCnt > 1)
|
||||
iChance += (100 - iChance) / 2;
|
||||
}
|
||||
if((INT32)PreRandom(100) < iChance && pSoldier->bActionPoints > (2 * BestAttack.ubAPCost + ubHalfBurstAPs + sActualAimAP))
|
||||
|
||||
if(Chance(iChance) && pSoldier->bActionPoints >= (2 * BestAttack.ubAPCost + ubHalfBurstAPs + sActualAimAP))
|
||||
{
|
||||
// Try short autofire to enhance chance of hitting
|
||||
pSoldier->bDoAutofire = 4;
|
||||
pSoldier->bDoAutofire = 2;
|
||||
BestAttack.ubAPCost += ubHalfBurstAPs + sActualAimAP;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -351,6 +351,8 @@ BOOLEAN CorpseMilitiaTeam(ROTTING_CORPSE *pCorpse);
|
||||
BOOLEAN NorthSpot(INT32 sSpot, INT8 bLevel);
|
||||
BOOLEAN SoldierAI(SOLDIERTYPE *pSoldier);
|
||||
|
||||
BOOLEAN CheckSuppressionDirection(SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bTargetLevel);
|
||||
|
||||
UINT8 AIDirection(INT32 sSpot1, INT32 sSpot2);
|
||||
|
||||
BOOLEAN AIGunScoped(SOLDIERTYPE *pSoldier);
|
||||
|
||||
Reference in New Issue
Block a user