mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Use TACTICAL_RANGE instead of DAY_VISION_RANGE for AI calculations.
Implemented Black cover advance code for AI: try to get closer to enemy using cover if soldier has low CTH or enemy too far for shooting or soldier has high morale or no cover at spot. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8931 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -4115,7 +4115,7 @@ UINT8 CountFriendsBlack( SOLDIERTYPE *pSoldier, INT32 sClosestOpponent )
|
||||
//sFriendClosestOpponent = ClosestKnownOpponent( pFriend, NULL, NULL );
|
||||
sFriendClosestOpponent = ClosestSeenOpponent( pFriend, NULL, NULL );
|
||||
if(!TileIsOutOfBounds(sFriendClosestOpponent) &&
|
||||
PythSpacesAway( sClosestOpponent, sFriendClosestOpponent ) < (INT16)DAY_VISION_RANGE / 4 &&
|
||||
PythSpacesAway( sClosestOpponent, sFriendClosestOpponent ) < (INT16)TACTICAL_RANGE / 4 &&
|
||||
pFriend->aiData.bAlertStatus == STATUS_BLACK &&
|
||||
pFriend->stats.bLife > pFriend->stats.bLifeMax / 2 &&
|
||||
( GetNearestRottingCorpseAIWarning( pFriend->sGridNo ) == 0 && !InLightAtNight(pFriend->sGridNo, pFriend->pathing.bLevel) ||
|
||||
@@ -4506,7 +4506,7 @@ UINT8 RedSmokeDanger(INT32 sGridNo, INT8 bLevel)
|
||||
UINT32 uiCnt;
|
||||
INT32 sDist;
|
||||
INT32 sClosestDist;
|
||||
INT32 sMaxDist = min(gSkillTraitValues.usVOMortarRadius, DAY_VISION_RANGE);
|
||||
INT32 sMaxDist = min(gSkillTraitValues.usVOMortarRadius, TACTICAL_RANGE);
|
||||
INT32 sClosestSmoke = NOWHERE;
|
||||
UINT8 ubDangerPercent = 0;
|
||||
|
||||
@@ -5011,7 +5011,7 @@ BOOLEAN AICheckIsSniper(SOLDIERTYPE *pSoldier)
|
||||
return FALSE;
|
||||
}*/
|
||||
|
||||
if ((AIGunRange(pSoldier) > DAY_VISION_RANGE || AICheckHasWeaponOfType(pSoldier, GUN_SN_RIFLE)) &&
|
||||
if ((AIGunRange(pSoldier) > TACTICAL_RANGE || AICheckHasWeaponOfType(pSoldier, GUN_SN_RIFLE)) &&
|
||||
AIGunScoped(pSoldier) &&
|
||||
pSoldier->stats.bMarksmanship > 90 &&
|
||||
gGameOptions.fNewTraitSystem &&
|
||||
@@ -5044,7 +5044,7 @@ BOOLEAN AICheckIsMarksman(SOLDIERTYPE *pSoldier)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (AIGunRange(pSoldier) >= DAY_VISION_RANGE &&
|
||||
if (AIGunRange(pSoldier) >= TACTICAL_RANGE &&
|
||||
(AIGunScoped(pSoldier) || pSoldier->stats.bMarksmanship > 90 || gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT(pSoldier, SNIPER_NT)))
|
||||
{
|
||||
return TRUE;
|
||||
@@ -5633,7 +5633,7 @@ BOOLEAN AICheckShortWeaponRange(SOLDIERTYPE *pSoldier)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (AIGunRange(pSoldier) < DAY_VISION_RANGE / 2)
|
||||
if (AIGunRange(pSoldier) < TACTICAL_RANGE / 2)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3929,13 +3929,13 @@ void CheckTossFriendSmoke(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
|
||||
bFriendLevel = pFriend->pathing.bLevel;
|
||||
sClosestOpponent = ClosestKnownOpponent(pFriend, NULL, NULL);
|
||||
|
||||
if (PythSpacesAway(sSpot, sFriendSpot) <= (INT16)DAY_VISION_RANGE &&
|
||||
PythSpacesAway(sSpot, sFriendSpot) > (INT16)DAY_VISION_RANGE / 4 &&
|
||||
if (PythSpacesAway(sSpot, sFriendSpot) <= (INT16)TACTICAL_RANGE &&
|
||||
PythSpacesAway(sSpot, sFriendSpot) > (INT16)TACTICAL_RANGE / 4 &&
|
||||
!InSmoke(sFriendSpot, bFriendLevel) &&
|
||||
(!NightLight() || InLightAtNight(sFriendSpot, bFriendLevel)) &&
|
||||
!Water(sFriendSpot, bFriendLevel) &&
|
||||
!TileIsOutOfBounds(sClosestOpponent) &&
|
||||
PythSpacesAway(sFriendSpot, sClosestOpponent) > (INT16)DAY_VISION_RANGE / 4 &&
|
||||
PythSpacesAway(sFriendSpot, sClosestOpponent) > (INT16)TACTICAL_RANGE / 4 &&
|
||||
!ProneSightCoverAtSpot(pFriend, sFriendSpot, TRUE) &&
|
||||
//!SightCoverAtSpot(pFriend, sFriendSpot, FALSE) &&
|
||||
//!AnyCoverAtSpot(pFriend, sFriendSpot) &&
|
||||
|
||||
+169
-13
@@ -2861,7 +2861,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
!AICheckIsSniper(pSoldier) &&
|
||||
!AICheckIsMachinegunner(pSoldier) &&
|
||||
!AICheckIsMortarOperator(pSoldier) &&
|
||||
Chance(100 - min(100, 10 * CountPublicKnownEnemies(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE))) &&
|
||||
Chance(100 - min(100, 10 * CountPublicKnownEnemies(pSoldier, pSoldier->sGridNo, TACTICAL_RANGE))) &&
|
||||
!GuySawEnemy(pSoldier, SEEN_LAST_TURN))
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("check if we can cover friend with smoke"));
|
||||
@@ -3079,11 +3079,11 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
|
||||
// reserve APs to hide if no cover or enemy is close
|
||||
if (!AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget) < DAY_VISION_RANGE / 2)
|
||||
if (!AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget) < TACTICAL_RANGE / 2)
|
||||
{
|
||||
sReserveAP = APBPConstants[AP_MINIMUM] / 2;
|
||||
}
|
||||
if (PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget) > DAY_VISION_RANGE || AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || pSoldier->aiData.bUnderFire)
|
||||
if (PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget) > TACTICAL_RANGE || AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || pSoldier->aiData.bUnderFire)
|
||||
{
|
||||
ubMinAuto *= 2;
|
||||
}
|
||||
@@ -3606,7 +3606,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
RangeChangeDesire(pSoldier) <= 2 &&
|
||||
(!NightLight() || InLightAtNight(pSoldier->sGridNo, pSoldier->pathing.bLevel)) &&
|
||||
!TileIsOutOfBounds(sClosestOpponent) &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) > DAY_VISION_RANGE / 4 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) > TACTICAL_RANGE / 4 &&
|
||||
(!fProneSightCover && !AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || pSoldier->TakenLargeHit()) &&
|
||||
(pSoldier->TakenLargeHit() || pSoldier->ShockLevelPercent() > 20 + Random(80)))
|
||||
{
|
||||
@@ -3817,7 +3817,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
!GuySawEnemy(pSoldier) &&
|
||||
!TileIsOutOfBounds(sClosestDisturbance) &&
|
||||
//!fSeekClimb &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) < DAY_VISION_RANGE &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) < TACTICAL_RANGE &&
|
||||
(pSoldier->aiData.bOrders == STATIONARY || pSoldier->aiData.bOrders == SNIPER || RangeChangeDesire(pSoldier) < 4) &&
|
||||
!SoldierToVirtualSoldierLineOfSightTest(pSoldier, sClosestDisturbance, pSoldier->pathing.bLevel, ANIM_STAND, TRUE, CALC_FROM_ALL_DIRS) &&
|
||||
CountFriendsBlack(pSoldier, sClosestDisturbance) == 0)
|
||||
@@ -3930,7 +3930,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
// sevenfm: don't watch when overcrowded and not in a building
|
||||
if (!InARoom(pSoldier->sGridNo, NULL))
|
||||
{
|
||||
bWatchPts -= CountNearbyFriends(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE / 8);
|
||||
bWatchPts -= CountNearbyFriends(pSoldier, pSoldier->sGridNo, TACTICAL_RANGE / 8);
|
||||
}
|
||||
|
||||
// sevenfm: don't help if seen enemy recently or under fire
|
||||
@@ -4055,7 +4055,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
//}
|
||||
|
||||
BOOLEAN fOvercrowded = FALSE;
|
||||
if( CountNearbyFriends(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE/4) > 2 )
|
||||
if( CountNearbyFriends(pSoldier, pSoldier->sGridNo, TACTICAL_RANGE / 4) > 2 )
|
||||
{
|
||||
fOvercrowded = TRUE;
|
||||
}
|
||||
@@ -4465,8 +4465,8 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
if (fCivilian &&
|
||||
//pSoldier->CheckInitialAP() &&
|
||||
(pSoldier->aiData.bUnderFire ||
|
||||
!TileIsOutOfBounds(sClosestOpponent) && PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) < DAY_VISION_RANGE / 2))
|
||||
//!TileIsOutOfBounds( sClosestNoise ) && PythSpacesAway(pSoldier->sGridNo, sClosestNoise) < DAY_VISION_RANGE / 2) )
|
||||
!TileIsOutOfBounds(sClosestOpponent) && PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) < TACTICAL_RANGE / 2))
|
||||
//!TileIsOutOfBounds( sClosestNoise ) && PythSpacesAway(pSoldier->sGridNo, sClosestNoise) < TACTICAL_RANGE / 2) )
|
||||
//CorpseWarning(pSoldier, pSoldier->sGridNo, pSoldier->pathing.bLevel)
|
||||
{
|
||||
DebugAI(AI_MSG_TOPIC, pSoldier, String("[civilians run away]"));
|
||||
@@ -5287,7 +5287,7 @@ INT16 ubMinAPCost;
|
||||
RangeChangeDesire(pSoldier) <= 2 &&
|
||||
(!NightLight() || InLightAtNight(pSoldier->sGridNo, pSoldier->pathing.bLevel)) &&
|
||||
!TileIsOutOfBounds(sClosestOpponent) &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) > DAY_VISION_RANGE / 4 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) > TACTICAL_RANGE / 4 &&
|
||||
(!ProneSightCoverAtSpot(pSoldier, pSoldier->sGridNo, FALSE) && !AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || pSoldier->TakenLargeHit()) &&
|
||||
(pSoldier->TakenLargeHit() || pSoldier->ShockLevelPercent() > 20 + Random(80)))
|
||||
{
|
||||
@@ -5953,6 +5953,163 @@ INT16 ubMinAPCost;
|
||||
}
|
||||
}
|
||||
|
||||
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Black cover advance]"));
|
||||
// Black cover advance
|
||||
if (SoldierAI(pSoldier) &&
|
||||
gfTurnBasedAI &&
|
||||
!pSoldier->bActionPoints == pSoldier->bInitialActionPoints &&
|
||||
pSoldier->bInitialActionPoints > APBPConstants[AP_MINIMUM] &&
|
||||
!gfHiddenInterrupt &&
|
||||
!gTacticalStatus.fInterruptOccurred &&
|
||||
!InARoom(pSoldier->sGridNo, NULL) &&
|
||||
!TileIsOutOfBounds(sClosestOpponent) &&
|
||||
//!InARoom(pSoldier->sGridNo, NULL) &&
|
||||
pSoldier->aiData.bOrders != STATIONARY &&
|
||||
pSoldier->aiData.bOrders != ONGUARD &&
|
||||
!AICheckSpecialRole(pSoldier) &&
|
||||
(ubBestAttackAction == AI_ACTION_NONE || ubBestAttackAction == AI_ACTION_FIRE_GUN && BestAttack.ubChanceToReallyHit < 5 * RangeChangeDesire(pSoldier)) &&
|
||||
AIGunRange(pSoldier) < DAY_VISION_RANGE &&
|
||||
pSoldier->aiData.bAIMorale >= MORALE_CONFIDENT &&
|
||||
(!AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || !ProneSightCoverAtSpot(pSoldier, pSoldier->sGridNo, FALSE) || AIGunRange(pSoldier) < PythSpacesAway(pSoldier->sGridNo, sClosestOpponent)) &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) < MAX_VISION_RANGE &&
|
||||
DetermineMovementMode(pSoldier, AI_ACTION_GET_CLOSER) != CRAWLING &&
|
||||
pSoldier->aiData.bShock < RangeChangeDesire(pSoldier) * 2 &&
|
||||
(AIGunRange(pSoldier) < PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) ||
|
||||
pSoldier->aiData.bLastAttackHit && pSoldier->sLastTarget != NOWHERE ||
|
||||
pSoldier->aiData.bAIMorale == MORALE_FEARLESS ||
|
||||
ubBestAttackAction == AI_ACTION_NONE ||
|
||||
ubBestAttackAction == AI_ACTION_FIRE_GUN && BestAttack.ubChanceToReallyHit == 1 ||
|
||||
!AnyCoverAtSpot(pSoldier, pSoldier->sGridNo)))
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("find cover advance spot"));
|
||||
|
||||
INT32 sClosestDisturbance = ClosestReachableDisturbance(pSoldier, &fClimb);
|
||||
|
||||
if (!TileIsOutOfBounds(sClosestDisturbance))
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("closest reachable disturbance %d", sClosestDisturbance));
|
||||
|
||||
INT32 sAdvanceSpot = NOWHERE;
|
||||
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("search for any cover advance spot"));
|
||||
sAdvanceSpot = FindAdvanceSpot(pSoldier, sClosestDisturbance, AI_ACTION_GET_CLOSER, ADVANCE_SPOT_ANY_COVER, FALSE);
|
||||
|
||||
if (!TileIsOutOfBounds(sAdvanceSpot))
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("found cover advance spot %d", sAdvanceSpot));
|
||||
|
||||
// check that we can reach desired location
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sAdvanceSpot, 0, AI_ACTION_GET_CLOSER, 0);
|
||||
if (pSoldier->aiData.usActionData == sAdvanceSpot)
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("cover advance spot ok"));
|
||||
pSoldier->aiData.usActionData = sAdvanceSpot;
|
||||
|
||||
//ScreenMsg(FONT_MCOLOR_LTGREEN, MSG_INTERFACE, L"[%d] found cover advance spot %d", pSoldier->ubID, sAdvanceSpot);
|
||||
//BeginMultiPurposeLocator(sAdvanceSpot, pSoldier->pathing.bLevel, FALSE);
|
||||
|
||||
return AI_ACTION_GET_CLOSER;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("cannot reach cover advance spot!"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("cannot find cover advance spot"));
|
||||
|
||||
// try to use smoke to cover advance movement
|
||||
//gubNPCAPBudget = pSoldier->bActionPoints;
|
||||
gubNPCAPBudget = 0;
|
||||
gubNPCDistLimit = 0;
|
||||
|
||||
// check path to closest disturbance
|
||||
if (gfTurnBasedAI &&
|
||||
pSoldier->bActionPoints >= APBPConstants[AP_MINIMUM] &&
|
||||
pSoldier->bActionPoints == pSoldier->bInitialActionPoints &&
|
||||
!TileIsOutOfBounds(sClosestDisturbance) &&
|
||||
RangeChangeDesire(pSoldier) > 3 &&
|
||||
!AICheckIsSniper(pSoldier) &&
|
||||
!AICheckIsMachinegunner(pSoldier) &&
|
||||
pSoldier->aiData.bOrders != STATIONARY &&
|
||||
(pSoldier->aiData.bUnderFire ||
|
||||
pSoldier->aiData.bShock > 0 ||
|
||||
pSoldier->stats.bLife < pSoldier->stats.bLifeMax * 3 / 4 ||
|
||||
CountTeamUnderAttack(pSoldier->bTeam, pSoldier->sGridNo, DAY_VISION_RANGE / 2) > CountNearbyFriends(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE / 2) / 2 ||
|
||||
CountSeenEnemiesLastTurn(pSoldier) > CountNearbyFriends(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE / 2)) &&
|
||||
(Chance(SoldierDifficultyLevel(pSoldier) * 10) || Chance(TeamPercentKilled(pSoldier->bTeam)) || Chance(CountTeamUnderAttack(pSoldier->bTeam, pSoldier->sGridNo, DAY_VISION_RANGE / 2))) &&
|
||||
FindBestPath(pSoldier, sClosestDisturbance, pSoldier->pathing.bLevel, RUNNING, COPYROUTE, 0))
|
||||
{
|
||||
INT16 sLoop;
|
||||
INT32 sCoverSpot = NOWHERE;
|
||||
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("found path to %d, path size %d ", sClosestDisturbance, pSoldier->pathing.usPathDataSize));
|
||||
|
||||
sCheckGridNo = pSoldier->sGridNo;
|
||||
|
||||
for (sLoop = pSoldier->pathing.usPathIndex; sLoop < pSoldier->pathing.usPathDataSize; sLoop++)
|
||||
{
|
||||
sCheckGridNo = NewGridNo(sCheckGridNo, DirectionInc((UINT8)(pSoldier->pathing.usPathingData[sLoop])));
|
||||
|
||||
if (!TileIsOutOfBounds(sCheckGridNo) &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sCheckGridNo) < TACTICAL_RANGE / 2 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sCheckGridNo) > TACTICAL_RANGE / 4 &&
|
||||
!Water(sCheckGridNo, pSoldier->pathing.bLevel) &&
|
||||
!InSmokeNearby(sCheckGridNo, pSoldier->pathing.bLevel) &&
|
||||
!InSmoke(sCheckGridNo, pSoldier->pathing.bLevel) &&
|
||||
(CorpseWarning(pSoldier, sCheckGridNo, pSoldier->pathing.bLevel) || InLightAtNight(sCheckGridNo, pSoldier->pathing.bLevel)) &&
|
||||
SightCoverAtSpot(pSoldier, sCheckGridNo, FALSE))
|
||||
{
|
||||
CheckTossGrenadeAt(pSoldier, &BestThrow, sCheckGridNo, pSoldier->pathing.bLevel, EXPLOSV_SMOKE);
|
||||
|
||||
if (BestThrow.ubPossible)
|
||||
{
|
||||
sCoverSpot = sCheckGridNo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!TileIsOutOfBounds(sCoverSpot))
|
||||
{
|
||||
CheckTossGrenadeAt(pSoldier, &BestThrow, sCoverSpot, pSoldier->pathing.bLevel, EXPLOSV_SMOKE);
|
||||
|
||||
if (BestThrow.ubPossible)
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("prepare throw at spot %d level %d aimtime %d", BestThrow.sTarget, BestThrow.bTargetLevel, BestThrow.ubAimTime));
|
||||
|
||||
// if necessary, swap the usItem from holster into the hand position
|
||||
if (BestThrow.bWeaponIn != HANDPOS)
|
||||
{
|
||||
DebugAI(AI_MSG_INFO, pSoldier, String("rearrange pocket"));
|
||||
RearrangePocket(pSoldier, HANDPOS, BestThrow.bWeaponIn, FOREVER);
|
||||
}
|
||||
|
||||
// stand up before throwing if needed
|
||||
if (gAnimControl[pSoldier->usAnimState].ubEndHeight < BestThrow.ubStance &&
|
||||
pSoldier->InternalIsValidStance(AIDirection(pSoldier->sGridNo, BestThrow.sTarget), BestThrow.ubStance))
|
||||
{
|
||||
pSoldier->aiData.usActionData = BestThrow.ubStance;
|
||||
pSoldier->aiData.bNextAction = AI_ACTION_TOSS_PROJECTILE;
|
||||
pSoldier->aiData.usNextActionData = BestThrow.sTarget;
|
||||
pSoldier->aiData.bNextTargetLevel = BestThrow.bTargetLevel;
|
||||
pSoldier->aiData.bAimTime = BestThrow.ubAimTime;
|
||||
return AI_ACTION_CHANGE_STANCE;
|
||||
}
|
||||
|
||||
pSoldier->aiData.usActionData = BestThrow.sTarget;
|
||||
pSoldier->bTargetLevel = BestThrow.bTargetLevel;
|
||||
pSoldier->aiData.bAimTime = BestThrow.ubAimTime;
|
||||
|
||||
return(AI_ACTION_TOSS_PROJECTILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
gubNPCAPBudget = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( (pSoldier->bActionPoints == pSoldier->bInitialActionPoints) &&
|
||||
(ubBestAttackAction == AI_ACTION_FIRE_GUN) &&
|
||||
(pSoldier->aiData.bShock == 0) &&
|
||||
@@ -5984,7 +6141,6 @@ INT16 ubMinAPCost;
|
||||
|
||||
}
|
||||
|
||||
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW");
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW
|
||||
@@ -8736,7 +8892,7 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
|
||||
// sevenfm: don't watch when overcrowded and not in a building
|
||||
if ( !InARoom( pSoldier->sGridNo, NULL ) )
|
||||
{
|
||||
bWatchPts -= CountNearbyFriends( pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE / 8 );
|
||||
bWatchPts -= CountNearbyFriends( pSoldier, pSoldier->sGridNo, TACTICAL_RANGE / 8 );
|
||||
}
|
||||
|
||||
// sevenfm: don't help if seen enemy recently or under fire
|
||||
@@ -8806,7 +8962,7 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
|
||||
#endif
|
||||
|
||||
BOOLEAN fOvercrowded = FALSE;
|
||||
if ( CountNearbyFriends( pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE / 4 ) > 2 )
|
||||
if ( CountNearbyFriends( pSoldier, pSoldier->sGridNo, TACTICAL_RANGE / 4 ) > 2 )
|
||||
{
|
||||
fOvercrowded = TRUE;
|
||||
}
|
||||
|
||||
@@ -442,28 +442,28 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
|
||||
// sevenfm: special calculations for zombies: zombie is very dangerous at close range
|
||||
if (pHim->IsZombie() || !AICheckHasGun(pHim))
|
||||
{
|
||||
if (sDist < (INT32)(DAY_VISION_RANGE / 2))
|
||||
if (sDist < (INT32)(TACTICAL_RANGE / 2))
|
||||
{
|
||||
// 100 - 25
|
||||
bHisCTGT = 100 - 150 * sDist / DAY_VISION_RANGE;
|
||||
bHisCTGT = 100 - 150 * sDist / TACTICAL_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 25 - 0
|
||||
bHisCTGT = 100 * DAY_VISION_RANGE * DAY_VISION_RANGE / (16 * sDist * sDist);
|
||||
bHisCTGT = 100 * TACTICAL_RANGE * TACTICAL_RANGE / (16 * sDist * sDist);
|
||||
}
|
||||
}
|
||||
|
||||
// sevenfm: if soldier has no gun, use different calculation
|
||||
if (pMe->IsZombie() || !AICheckHasGun(pMe))
|
||||
{
|
||||
if (sDist < (INT32)(DAY_VISION_RANGE / 2))
|
||||
if (sDist < (INT32)(TACTICAL_RANGE / 2))
|
||||
{
|
||||
bMyCTGT = 100 - 150 * sDist / DAY_VISION_RANGE;
|
||||
bMyCTGT = 100 - 150 * sDist / TACTICAL_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bMyCTGT = 100 * DAY_VISION_RANGE * DAY_VISION_RANGE / (16 * sDist * sDist);
|
||||
bMyCTGT = 100 * TACTICAL_RANGE * TACTICAL_RANGE / (16 * sDist * sDist);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -473,13 +473,13 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
|
||||
iMyPosValue = bMyCTGT * iMyThreat * iMyAPsLeft;
|
||||
|
||||
// add penalty to enemy position, bonus to my position if soldier has cover at spot
|
||||
// max 25% at DAY_VISION_RANGE/2, 0 at zero range
|
||||
// max 25% at TACTICAL_RANGE / 2, 0 at zero range
|
||||
if( gGameExternalOptions.fAIBetterCover )
|
||||
{
|
||||
UINT8 ubCoverBonus = 25;
|
||||
if (sDist < (INT32)(DAY_VISION_RANGE / 2))
|
||||
if (sDist < (INT32)(TACTICAL_RANGE / 2))
|
||||
{
|
||||
ubCoverBonus = ubCoverBonus * 2 * sDist / DAY_VISION_RANGE;
|
||||
ubCoverBonus = ubCoverBonus * 2 * sDist / TACTICAL_RANGE;
|
||||
}
|
||||
if (!pHim->IsZombie() && AICheckHasGun(pHim) && AnyCoverFromSpot(sMyGridNo, bMyLevel, sHisGridNo, bHisLevel))
|
||||
{
|
||||
@@ -536,7 +536,7 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
|
||||
if (gGameExternalOptions.fAIBetterCover)
|
||||
{
|
||||
if (!AnyCoverFromSpot(sMyGridNo, bMyLevel, sHisGridNo, bHisLevel) &&
|
||||
CountSeenEnemiesLastTurn(pMe) > CountNearbyFriends(pMe, sMyGridNo, DAY_VISION_RANGE / 2))
|
||||
CountSeenEnemiesLastTurn(pMe) > CountNearbyFriends(pMe, sMyGridNo, TACTICAL_RANGE / 2))
|
||||
{
|
||||
iRangeFactor = iRangeFactor * (100 - bHisCTGT * __min(Threat[uiThreatIndex].iAPs, APBPConstants[AP_MAXIMUM]) / APBPConstants[AP_MAXIMUM]) / 100;
|
||||
}
|
||||
@@ -787,7 +787,7 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
|
||||
// sevenfm: sight test
|
||||
if( gGameExternalOptions.fAIBetterCover )
|
||||
{
|
||||
if ( LocationToLocationLineOfSightTest( Threat[uiLoop].sGridNo, Threat[uiLoop].pOpponent->pathing.bLevel, pSoldier->sGridNo, pSoldier->pathing.bLevel, TRUE, DAY_VISION_RANGE * 2, STANDING_LOS_POS, PRONE_LOS_POS ) )
|
||||
if ( LocationToLocationLineOfSightTest( Threat[uiLoop].sGridNo, Threat[uiLoop].pOpponent->pathing.bLevel, pSoldier->sGridNo, pSoldier->pathing.bLevel, TRUE, MAX_VISION_RANGE, STANDING_LOS_POS, PRONE_LOS_POS ) )
|
||||
//if ( SoldierToVirtualSoldierLineOfSightTest( Threat[uiLoop].pOpponent, pSoldier->sGridNo, pSoldier->pathing.bLevel, ANIM_PRONE, TRUE, NO_DISTANCE_LIMIT ) )
|
||||
{
|
||||
fProneCover = FALSE;
|
||||
@@ -1053,7 +1053,7 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
|
||||
// sevenfm: sight test
|
||||
if( gGameExternalOptions.fAIBetterCover )
|
||||
{
|
||||
if ( LocationToLocationLineOfSightTest( Threat[uiLoop].sGridNo, Threat[uiLoop].pOpponent->pathing.bLevel, sGridNo, pSoldier->pathing.bLevel, TRUE, DAY_VISION_RANGE * 2, STANDING_LOS_POS, PRONE_LOS_POS ) )
|
||||
if ( LocationToLocationLineOfSightTest( Threat[uiLoop].sGridNo, Threat[uiLoop].pOpponent->pathing.bLevel, sGridNo, pSoldier->pathing.bLevel, TRUE, MAX_VISION_RANGE, STANDING_LOS_POS, PRONE_LOS_POS ) )
|
||||
//if ( SoldierToVirtualSoldierLineOfSightTest( Threat[uiLoop].pOpponent, sGridNo, pSoldier->pathing.bLevel, ANIM_PRONE, TRUE, -1 ) != 0 )
|
||||
{
|
||||
fProneCover = FALSE;
|
||||
@@ -3329,7 +3329,7 @@ INT32 FindAdvanceSpot(SOLDIERTYPE *pSoldier, INT32 sTargetSpot, INT8 bAction, UI
|
||||
}
|
||||
|
||||
// skip locations too close to target spot
|
||||
if (PythSpacesAway(sGridNo, sTargetSpot) < (INT16)(DAY_VISION_RANGE / 4))
|
||||
if (PythSpacesAway(sGridNo, sTargetSpot) < (INT16)(TACTICAL_RANGE / 4))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -3613,7 +3613,7 @@ INT32 FindRetreatSpot(SOLDIERTYPE *pSoldier)
|
||||
// skip if too close to enemy
|
||||
//sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL);
|
||||
sDistance = PythSpacesAway(sGridNo, sClosestOpponent);
|
||||
if (sDistance < (INT16)(DAY_VISION_RANGE / 2))
|
||||
if (sDistance < (INT16)(TACTICAL_RANGE / 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -691,8 +691,8 @@ INT8 ZombieDecideActionRed(SOLDIERTYPE *pSoldier)
|
||||
|
||||
// sevenfm: try to advance using sight cover
|
||||
if( gfTurnBasedAI &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) < DAY_VISION_RANGE * 2 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) > DAY_VISION_RANGE / 4 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) < TACTICAL_RANGE * 2 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) > TACTICAL_RANGE / 4 &&
|
||||
!SightCoverAtSpot(pSoldier, pSoldier->aiData.usActionData, TRUE))
|
||||
{
|
||||
INT32 sAdvanceSpot = FindAdvanceSpot(pSoldier, sClosestDisturbance, AI_ACTION_SEEK_OPPONENT, ADVANCE_SPOT_SIGHT_COVER, TRUE);
|
||||
@@ -1169,8 +1169,8 @@ INT8 ZombieDecideActionBlack(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
// sevenfm: try to advance using sight cover
|
||||
if( gfTurnBasedAI &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) < DAY_VISION_RANGE * 2 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) > DAY_VISION_RANGE / 4 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) < TACTICAL_RANGE * 2 &&
|
||||
PythSpacesAway(pSoldier->sGridNo, sClosestDisturbance) > TACTICAL_RANGE / 4 &&
|
||||
!SightCoverAtSpot(pSoldier, pSoldier->aiData.usActionData, TRUE))
|
||||
{
|
||||
DebugAI( AI_MSG_INFO, pSoldier, String("[advance spot]"));
|
||||
|
||||
Reference in New Issue
Block a user