mirror of
https://github.com/1dot13/source.git
synced 2026-08-19 14:20:30 +02:00
Add optional InOut parameter to ClosestKnownOpponent
distanceInCellCoords will return the distance between pSoldier and closest known opponent. We're often calculating same range after the call using PythSpacesAway and this way it's no longer necessary in most cases.
This commit is contained in:
+25
-17
@@ -134,18 +134,17 @@ INT8 OKToAttack(SOLDIERTYPE * pSoldier, int target)
|
|||||||
|
|
||||||
BOOLEAN ConsiderProne( SOLDIERTYPE * pSoldier )
|
BOOLEAN ConsiderProne( SOLDIERTYPE * pSoldier )
|
||||||
{
|
{
|
||||||
INT32 sOpponentGridNo;
|
INT32 sOpponentGridNo;
|
||||||
INT8 bOpponentLevel;
|
INT8 bOpponentLevel;
|
||||||
INT32 iRange;
|
INT32 iRangeInCellCoords;
|
||||||
|
|
||||||
if (pSoldier->aiData.bAIMorale >= MORALE_NORMAL)
|
if (pSoldier->aiData.bAIMorale >= MORALE_NORMAL)
|
||||||
{
|
{
|
||||||
return( FALSE );
|
return( FALSE );
|
||||||
}
|
}
|
||||||
// We don't want to go prone if there is a nearby enemy
|
// We don't want to go prone if there is a nearby enemy
|
||||||
ClosestKnownOpponent( pSoldier, &sOpponentGridNo, &bOpponentLevel );
|
ClosestKnownOpponent( pSoldier, &sOpponentGridNo, &bOpponentLevel, nullptr, &iRangeInCellCoords);
|
||||||
iRange = PythSpacesAway( pSoldier->sGridNo, sOpponentGridNo );
|
if ( iRangeInCellCoords > 10*CELL_X_SIZE)
|
||||||
if (iRange > 10)
|
|
||||||
{
|
{
|
||||||
return( TRUE );
|
return( TRUE );
|
||||||
}
|
}
|
||||||
@@ -397,7 +396,11 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
// sevenfm: movement mode tweaks
|
// sevenfm: movement mode tweaks
|
||||||
if (gGameExternalOptions.fAIMovementMode)
|
if (gGameExternalOptions.fAIMovementMode)
|
||||||
{
|
{
|
||||||
INT32 sClosestThreat = ClosestKnownOpponent(pSoldier, NULL, NULL);
|
INT32 distanceToThreat;
|
||||||
|
const INT32 sClosestThreat = ClosestKnownOpponent(pSoldier, NULL, NULL, NULL, &distanceToThreat);
|
||||||
|
const auto mediumRange = TACTICAL_RANGE_CELL_COORDS / 2;
|
||||||
|
const auto close = TACTICAL_RANGE_CELL_COORDS / 4;
|
||||||
|
const auto reallyClose = TACTICAL_RANGE_CELL_COORDS / 8;
|
||||||
|
|
||||||
// use walking mode if no enemy known
|
// use walking mode if no enemy known
|
||||||
if (pSoldier->aiData.bAlertStatus < STATUS_RED &&
|
if (pSoldier->aiData.bAlertStatus < STATUS_RED &&
|
||||||
@@ -423,6 +426,7 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
(pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == MILITIA_TEAM))
|
(pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == MILITIA_TEAM))
|
||||||
{
|
{
|
||||||
INT16 sDistanceVisible = VISION_RANGE;
|
INT16 sDistanceVisible = VISION_RANGE;
|
||||||
|
const auto beyondVisionRange = (CELL_X_SIZE * 3 * sDistanceVisible) / 2;
|
||||||
INT32 iRCD = RangeChangeDesire(pSoldier);
|
INT32 iRCD = RangeChangeDesire(pSoldier);
|
||||||
|
|
||||||
// use running when in light at night
|
// use running when in light at night
|
||||||
@@ -445,7 +449,7 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
!GuySawEnemy(pSoldier) &&
|
!GuySawEnemy(pSoldier) &&
|
||||||
(NightTime() || gAnimControl[pSoldier->usAnimState].ubEndHeight <= ANIM_CROUCH) &&
|
(NightTime() || gAnimControl[pSoldier->usAnimState].ubEndHeight <= ANIM_CROUCH) &&
|
||||||
CountNearbyFriends(pSoldier, pSoldier->sGridNo, TACTICAL_RANGE / 4) < 3 &&
|
CountNearbyFriends(pSoldier, pSoldier->sGridNo, TACTICAL_RANGE / 4) < 3 &&
|
||||||
PythSpacesAway(pSoldier->sGridNo, sClosestThreat) < 3 * sDistanceVisible / 2 &&
|
distanceToThreat < beyondVisionRange &&
|
||||||
CountFriendsBlack(pSoldier) == 0 &&
|
CountFriendsBlack(pSoldier) == 0 &&
|
||||||
bAction == AI_ACTION_SEEK_OPPONENT)
|
bAction == AI_ACTION_SEEK_OPPONENT)
|
||||||
{
|
{
|
||||||
@@ -454,7 +458,7 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
|
|
||||||
// use swatting for taking cover
|
// use swatting for taking cover
|
||||||
if (pSoldier->aiData.bAlertStatus >= STATUS_RED &&
|
if (pSoldier->aiData.bAlertStatus >= STATUS_RED &&
|
||||||
PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > (INT16)TACTICAL_RANGE / 8 &&
|
distanceToThreat > reallyClose &&
|
||||||
(pSoldier->aiData.bUnderFire && iRCD < 4 ||
|
(pSoldier->aiData.bUnderFire && iRCD < 4 ||
|
||||||
pSoldier->aiData.bShock > 2 * iRCD ||
|
pSoldier->aiData.bShock > 2 * iRCD ||
|
||||||
pSoldier->aiData.bShock > 0 && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE) &&
|
pSoldier->aiData.bShock > 0 && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE) &&
|
||||||
@@ -466,9 +470,9 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
|
|
||||||
// use SWATTING when under fire
|
// use SWATTING when under fire
|
||||||
if (pSoldier->aiData.bAlertStatus >= STATUS_RED &&
|
if (pSoldier->aiData.bAlertStatus >= STATUS_RED &&
|
||||||
(pSoldier->aiData.bShock > iRCD && PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > (INT16)TACTICAL_RANGE / 2 ||
|
(pSoldier->aiData.bShock > iRCD && distanceToThreat > mediumRange ||
|
||||||
pSoldier->aiData.bShock > 0 && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE && PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > (INT16)TACTICAL_RANGE / 4) &&
|
pSoldier->aiData.bShock > 0 && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE && distanceToThreat > close) &&
|
||||||
PythSpacesAway(pSoldier->sGridNo, sClosestThreat) < 3 * sDistanceVisible / 2 &&
|
distanceToThreat < beyondVisionRange &&
|
||||||
gAnimControl[pSoldier->usAnimState].ubEndHeight <= ANIM_CROUCH &&
|
gAnimControl[pSoldier->usAnimState].ubEndHeight <= ANIM_CROUCH &&
|
||||||
!pSoldier->aiData.bLastAttackHit &&
|
!pSoldier->aiData.bLastAttackHit &&
|
||||||
(bAction == AI_ACTION_SEEK_OPPONENT ||
|
(bAction == AI_ACTION_SEEK_OPPONENT ||
|
||||||
@@ -485,7 +489,7 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
(pSoldier->aiData.bOrders == SNIPER ||
|
(pSoldier->aiData.bOrders == SNIPER ||
|
||||||
pSoldier->aiData.bOrders == STATIONARY ||
|
pSoldier->aiData.bOrders == STATIONARY ||
|
||||||
(GuySawEnemy(pSoldier) || pSoldier->aiData.bShock > 0) && iRCD < 4) &&
|
(GuySawEnemy(pSoldier) || pSoldier->aiData.bShock > 0) && iRCD < 4) &&
|
||||||
PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > (INT16)TACTICAL_RANGE / 4 &&
|
distanceToThreat > close &&
|
||||||
(bAction == AI_ACTION_SEEK_OPPONENT ||
|
(bAction == AI_ACTION_SEEK_OPPONENT ||
|
||||||
bAction == AI_ACTION_GET_CLOSER ||
|
bAction == AI_ACTION_GET_CLOSER ||
|
||||||
bAction == AI_ACTION_SEEK_FRIEND ||
|
bAction == AI_ACTION_SEEK_FRIEND ||
|
||||||
@@ -501,7 +505,7 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
(pSoldier->aiData.bOrders == SNIPER ||
|
(pSoldier->aiData.bOrders == SNIPER ||
|
||||||
pSoldier->aiData.bOrders == STATIONARY ||
|
pSoldier->aiData.bOrders == STATIONARY ||
|
||||||
pSoldier->aiData.bShock > 0 && iRCD < 4) &&
|
pSoldier->aiData.bShock > 0 && iRCD < 4) &&
|
||||||
PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > (INT16)TACTICAL_RANGE / 4 &&
|
distanceToThreat > close &&
|
||||||
(bAction == AI_ACTION_SEEK_OPPONENT ||
|
(bAction == AI_ACTION_SEEK_OPPONENT ||
|
||||||
bAction == AI_ACTION_GET_CLOSER ||
|
bAction == AI_ACTION_GET_CLOSER ||
|
||||||
bAction == AI_ACTION_SEEK_FRIEND ||
|
bAction == AI_ACTION_SEEK_FRIEND ||
|
||||||
@@ -515,7 +519,7 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
if (!pSoldier->aiData.bUnderFire &&
|
if (!pSoldier->aiData.bUnderFire &&
|
||||||
bAction == AI_ACTION_TAKE_COVER &&
|
bAction == AI_ACTION_TAKE_COVER &&
|
||||||
pSoldier->bInitialActionPoints > APBPConstants[AP_MINIMUM] &&
|
pSoldier->bInitialActionPoints > APBPConstants[AP_MINIMUM] &&
|
||||||
(!InARoom(pSoldier->sGridNo, NULL) || PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > sDistanceVisible * 2) &&
|
(!InARoom(pSoldier->sGridNo, NULL) || distanceToThreat > sDistanceVisible * 20) &&
|
||||||
pSoldier->aiData.bAIMorale >= MORALE_NORMAL &&
|
pSoldier->aiData.bAIMorale >= MORALE_NORMAL &&
|
||||||
pSoldier->bBreath > 25 &&
|
pSoldier->bBreath > 25 &&
|
||||||
pSoldier->pathing.bLevel == 0 &&
|
pSoldier->pathing.bLevel == 0 &&
|
||||||
@@ -539,14 +543,14 @@ UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction )
|
|||||||
else if (gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_CROUCH)
|
else if (gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_CROUCH)
|
||||||
{
|
{
|
||||||
if (WeaponReady(pSoldier) && !pSoldier->aiData.bUnderFire && pSoldier->aiData.bAlertStatus == STATUS_BLACK ||
|
if (WeaponReady(pSoldier) && !pSoldier->aiData.bUnderFire && pSoldier->aiData.bAlertStatus == STATUS_BLACK ||
|
||||||
pSoldier->aiData.bUnderFire && PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > (INT16)TACTICAL_RANGE / 8)
|
pSoldier->aiData.bUnderFire && distanceToThreat > reallyClose )
|
||||||
return SWATTING;
|
return SWATTING;
|
||||||
else
|
else
|
||||||
return RUNNING;
|
return RUNNING;
|
||||||
}
|
}
|
||||||
else if (gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE)
|
else if (gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE)
|
||||||
{
|
{
|
||||||
if (pSoldier->aiData.bUnderFire && !pSoldier->aiData.bLastAttackHit && PythSpacesAway(pSoldier->sGridNo, sClosestThreat) > (INT16)TACTICAL_RANGE / 8)
|
if (pSoldier->aiData.bUnderFire && !pSoldier->aiData.bLastAttackHit && distanceToThreat > reallyClose )
|
||||||
return SWATTING;
|
return SWATTING;
|
||||||
else
|
else
|
||||||
return RUNNING;
|
return RUNNING;
|
||||||
@@ -1379,7 +1383,7 @@ INT32 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, BOOLEAN * pfChangeLevel
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, SoldierID * pubOpponentID)
|
INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, SoldierID * pubOpponentID, INT32 * distanceInCellCoords)
|
||||||
{
|
{
|
||||||
INT32 *psLastLoc,sGridNo, sClosestOpponent = NOWHERE;
|
INT32 *psLastLoc,sGridNo, sClosestOpponent = NOWHERE;
|
||||||
UINT32 uiLoop;
|
UINT32 uiLoop;
|
||||||
@@ -1503,6 +1507,10 @@ INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLev
|
|||||||
{
|
{
|
||||||
*pubOpponentID = pClosestOpponent->ubID;
|
*pubOpponentID = pClosestOpponent->ubID;
|
||||||
}
|
}
|
||||||
|
if ( distanceInCellCoords )
|
||||||
|
{
|
||||||
|
*distanceInCellCoords = iClosestRange;
|
||||||
|
}
|
||||||
return( sClosestOpponent );
|
return( sClosestOpponent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -844,7 +844,8 @@ INT8 CreatureDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
|||||||
{
|
{
|
||||||
// determine the location of the known closest opponent
|
// determine the location of the known closest opponent
|
||||||
// (don't care if he's conscious, don't care if he's reachable at all)
|
// (don't care if he's conscious, don't care if he's reachable at all)
|
||||||
sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL);
|
INT32 distanceToThreat;
|
||||||
|
sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL, NULL, &distanceToThreat);
|
||||||
|
|
||||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||||
{
|
{
|
||||||
@@ -854,9 +855,9 @@ INT8 CreatureDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
|||||||
// if soldier is not already facing in that direction,
|
// if soldier is not already facing in that direction,
|
||||||
// and the opponent is close enough that he could possibly be seen
|
// and the opponent is close enough that he could possibly be seen
|
||||||
// note, have to change this to use the level returned from ClosestKnownOpponent
|
// note, have to change this to use the level returned from ClosestKnownOpponent
|
||||||
sDistVisible = pSoldier->GetMaxDistanceVisible(sClosestOpponent, 0 );
|
sDistVisible = pSoldier->GetMaxDistanceVisible(sClosestOpponent, 0 ) * CELL_X_SIZE;
|
||||||
|
|
||||||
if ((pSoldier->ubDirection != ubOpponentDir) && (PythSpacesAway(pSoldier->sGridNo,sClosestOpponent) <= sDistVisible))
|
if ((pSoldier->ubDirection != ubOpponentDir) && (distanceToThreat <= sDistVisible))
|
||||||
{
|
{
|
||||||
// set base chance according to orders
|
// set base chance according to orders
|
||||||
if ((pSoldier->aiData.bOrders == STATIONARY) || (pSoldier->aiData.bOrders == ONGUARD))
|
if ((pSoldier->aiData.bOrders == STATIONARY) || (pSoldier->aiData.bOrders == ONGUARD))
|
||||||
@@ -1380,11 +1381,12 @@ INT8 CreatureDecideActionBlack( SOLDIERTYPE * pSoldier )
|
|||||||
{
|
{
|
||||||
// determine the location of the known closest opponent
|
// determine the location of the known closest opponent
|
||||||
// (don't care if he's conscious, don't care if he's reachable at all)
|
// (don't care if he's conscious, don't care if he's reachable at all)
|
||||||
sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL);
|
INT32 distanceToThreat;
|
||||||
|
sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL, NULL, &distanceToThreat);
|
||||||
// if we have a closest reachable opponent
|
// if we have a closest reachable opponent
|
||||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||||
{
|
{
|
||||||
if ( ubCanMove && PythSpacesAway( pSoldier->sGridNo, sClosestOpponent ) > 2 )
|
if ( ubCanMove && distanceToThreat > 20 ) // 2 tiles -> 20 in fractional Cell Coordinates
|
||||||
{
|
{
|
||||||
if ( bSpitIn != NO_SLOT )
|
if ( bSpitIn != NO_SLOT )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9637,7 +9637,8 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
|
|||||||
{
|
{
|
||||||
// determine the location of the known closest opponent
|
// determine the location of the known closest opponent
|
||||||
// (don't care if he's conscious, don't care if he's reachable at all)
|
// (don't care if he's conscious, don't care if he's reachable at all)
|
||||||
sClosestOpponent = ClosestKnownOpponent( pSoldier, NULL, NULL );
|
INT32 distanceToOpponent;
|
||||||
|
sClosestOpponent = ClosestKnownOpponent( pSoldier, NULL, NULL, NULL, &distanceToOpponent );
|
||||||
|
|
||||||
if ( !TileIsOutOfBounds( sClosestOpponent ) )
|
if ( !TileIsOutOfBounds( sClosestOpponent ) )
|
||||||
{
|
{
|
||||||
@@ -9647,9 +9648,9 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
|
|||||||
// if soldier is not already facing in that direction,
|
// if soldier is not already facing in that direction,
|
||||||
// and the opponent is close enough that he could possibly be seen
|
// and the opponent is close enough that he could possibly be seen
|
||||||
// note, have to change this to use the level returned from ClosestKnownOpponent
|
// note, have to change this to use the level returned from ClosestKnownOpponent
|
||||||
sDistVisible = pSoldier->GetMaxDistanceVisible( sClosestOpponent, 0, CALC_FROM_ALL_DIRS );
|
sDistVisible = pSoldier->GetMaxDistanceVisible( sClosestOpponent, 0, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;
|
||||||
|
|
||||||
if ( (pSoldier->ubDirection != ubOpponentDir) && (PythSpacesAway( pSoldier->sGridNo, sClosestOpponent ) <= sDistVisible) )
|
if ( (pSoldier->ubDirection != ubOpponentDir) && (distanceToOpponent <= sDistVisible) )
|
||||||
{
|
{
|
||||||
// set base chance according to orders
|
// set base chance according to orders
|
||||||
if ( (pSoldier->aiData.bOrders == STATIONARY) || (pSoldier->aiData.bOrders == ONGUARD) )
|
if ( (pSoldier->aiData.bOrders == STATIONARY) || (pSoldier->aiData.bOrders == ONGUARD) )
|
||||||
|
|||||||
+2
-1
@@ -171,7 +171,7 @@ void CheckForChangingOrders(SOLDIERTYPE *pSoldier );
|
|||||||
|
|
||||||
INT8 ClosestPanicTrigger( SOLDIERTYPE * pSoldier );
|
INT8 ClosestPanicTrigger( SOLDIERTYPE * pSoldier );
|
||||||
|
|
||||||
INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, SoldierID *pubOpponentID = NULL);
|
INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, SoldierID *pubOpponentID = NULL, INT32 * distanceInCellCoords = NULL);
|
||||||
INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance );
|
INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance );
|
||||||
INT32 ClosestUnDisguisedPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); // Flugente: like ClosestPC(...), but does not account for covert or not visible mercs
|
INT32 ClosestUnDisguisedPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); // Flugente: like ClosestPC(...), but does not account for covert or not visible mercs
|
||||||
BOOLEAN CanAutoBandage( BOOLEAN fDoFullCheck );
|
BOOLEAN CanAutoBandage( BOOLEAN fDoFullCheck );
|
||||||
@@ -431,6 +431,7 @@ INT8 KnownPublicLevel(UINT8 bTeam, SoldierID ubOpponentID);
|
|||||||
|
|
||||||
// sevenfm: distance for tactical AI checks, roughly equal to normal day vision range
|
// sevenfm: distance for tactical AI checks, roughly equal to normal day vision range
|
||||||
#define TACTICAL_RANGE (gGameExternalOptions.ubStraightSightRange * STRAIGHT_RATIO * 2)
|
#define TACTICAL_RANGE (gGameExternalOptions.ubStraightSightRange * STRAIGHT_RATIO * 2)
|
||||||
|
#define TACTICAL_RANGE_CELL_COORDS TACTICAL_RANGE*CELL_X_SIZE
|
||||||
#define BOMB_DETECTION_RANGE (TACTICAL_RANGE / 4)
|
#define BOMB_DETECTION_RANGE (TACTICAL_RANGE / 4)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user