mirror of
https://github.com/1dot13/source.git
synced 2026-08-05 14:00:23 +02:00
- new option: ENEMY_JAMS in [Tactical Gameplay Settings] allows enemy gun jams
- take into account unjam AP cost for jammed weapon - improved AI_BETTER_COVER option git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8409 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -4026,3 +4026,73 @@ BOOLEAN FindBombNearby( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance )
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN AnyCoverFromSpot( INT32 sSpot, INT8 bLevel, INT32 sThreatLoc, INT8 bThreatLevel )
|
||||
{
|
||||
UINT8 ubDirection;
|
||||
INT32 sCoverSpot;
|
||||
INT8 bCoverHeight;
|
||||
|
||||
if( TileIsOutOfBounds( sSpot ) || TileIsOutOfBounds(sThreatLoc) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ubDirection = atan8(CenterX(sSpot), CenterY(sSpot), CenterX(sThreatLoc), CenterY(sThreatLoc));
|
||||
sCoverSpot = NewGridNo( sSpot, DirectionInc( ubDirection ) );
|
||||
|
||||
if ( TileIsOutOfBounds( sCoverSpot ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( WhoIsThere2( sCoverSpot, bLevel ) != NOBODY )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( IsLocationSittable( sCoverSpot, bLevel ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bCoverHeight = GetTallestStructureHeight( sCoverSpot, bLevel );
|
||||
|
||||
if ( bCoverHeight >= 2 )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT8 CountSeenEnemiesLastTurn( SOLDIERTYPE* pSoldier )
|
||||
{
|
||||
CHECKF(pSoldier);
|
||||
|
||||
UINT8 ubTeamLoop;
|
||||
UINT8 ubIDLoop;
|
||||
UINT8 cnt = 0;
|
||||
|
||||
for( ubTeamLoop = 0; ubTeamLoop < MAXTEAMS; ubTeamLoop++ )
|
||||
{
|
||||
if( !gTacticalStatus.Team[ubTeamLoop].bTeamActive )
|
||||
continue;
|
||||
|
||||
if( gTacticalStatus.Team[ ubTeamLoop ].bSide != pSoldier->bSide )
|
||||
{
|
||||
// consider guys in this team, which isn't on our side
|
||||
for( ubIDLoop = gTacticalStatus.Team[ ubTeamLoop ].bFirstID; ubIDLoop <= gTacticalStatus.Team[ ubTeamLoop ].bLastID; ubIDLoop++ )
|
||||
{
|
||||
// if this guy SAW an enemy recently...
|
||||
if( pSoldier->aiData.bOppList[ ubIDLoop ] >= SEEN_CURRENTLY &&
|
||||
pSoldier->aiData.bOppList[ ubIDLoop ] <= SEEN_LAST_TURN )
|
||||
{
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -293,11 +293,21 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
|
||||
INT32 iRangeChange, iRangeFactor, iRangeFactorMultiplier;
|
||||
SOLDIERTYPE *pHim;
|
||||
|
||||
// sevenfm
|
||||
INT8 bHisLevel;
|
||||
INT8 bMyLevel;
|
||||
INT32 sDist;
|
||||
UINT8 ubCoverReduction;
|
||||
|
||||
dMyX = dMyY = dHisX = dHisY = -1.0;
|
||||
|
||||
pHim = Threat[uiThreatIndex].pOpponent;
|
||||
sHisGridNo = Threat[uiThreatIndex].sGridNo;
|
||||
|
||||
// sevenfm
|
||||
bHisLevel = pHim->pathing.bLevel;
|
||||
bMyLevel = pMe->pathing.bLevel;
|
||||
|
||||
// THE FOLLOWING STUFF IS *VEERRRY SCAARRRY*, BUT SHOULD WORK. IF YOU REALLY
|
||||
// HATE IT, THEN CHANGE ChanceToGetThrough() TO WORK FROM A GRIDNO TO GRIDNO
|
||||
|
||||
@@ -418,6 +428,24 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
|
||||
iHisPosValue = bHisCTGT * Threat[uiThreatIndex].iValue * Threat[uiThreatIndex].iAPs;
|
||||
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
|
||||
if( gGameExternalOptions.fAIBetterCover )
|
||||
{
|
||||
if( AnyCoverFromSpot(sMyGridNo, bMyLevel, sHisGridNo, bHisLevel) )
|
||||
{
|
||||
ubCoverReduction = 25;
|
||||
|
||||
sDist = PythSpacesAway(sMyGridNo, sHisGridNo);
|
||||
|
||||
if( sDist < DAY_VISION_RANGE / 2 )
|
||||
{
|
||||
ubCoverReduction = ubCoverReduction * 2 * sDist / DAY_VISION_RANGE;
|
||||
}
|
||||
iHisPosValue -= iHisPosValue * ubCoverReduction / 100;
|
||||
iMyPosValue += iMyPosValue * ubCoverReduction / 100;
|
||||
}
|
||||
}
|
||||
|
||||
// try to account for who outnumbers who: the side with the advantage thus
|
||||
// (hopefully) values offense more, while those in trouble will play defense
|
||||
@@ -461,6 +489,16 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
|
||||
//iRangeFactor = (iRangeChange * (morale - 1)) / 4;
|
||||
iRangeFactor = (iRangeChange * iRangeFactorMultiplier) / 2;
|
||||
|
||||
// sevenfm: reduce range bonus depending on cover
|
||||
if( gGameExternalOptions.fAIBetterCover )
|
||||
{
|
||||
if( !AnyCoverFromSpot(sMyGridNo, bMyLevel, sHisGridNo, bHisLevel) &&
|
||||
CountSeenEnemiesLastTurn(pMe) > CountNearbyFriends(pMe, sMyGridNo, DAY_VISION_RANGE / 2) )
|
||||
{
|
||||
iRangeFactor = iRangeFactor * (100 - bHisCTGT * __min(Threat[uiThreatIndex].iAPs, APBPConstants[AP_MAXIMUM]) / APBPConstants[AP_MAXIMUM]) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGCOVER
|
||||
DebugAI( String( "CalcCoverValue: iRangeChange %d, iRangeFactor %d\n", iRangeChange, iRangeFactor ) );
|
||||
#endif
|
||||
@@ -808,7 +846,8 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
|
||||
// sevenfm: sight test
|
||||
if( gGameExternalOptions.fAIBetterCover )
|
||||
{
|
||||
if ( SoldierToVirtualSoldierLineOfSightTest( Threat[uiLoop].pOpponent, pSoldier->sGridNo, pSoldier->pathing.bLevel, ANIM_PRONE, TRUE, -1 ) != 0 )
|
||||
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 ( SoldierToVirtualSoldierLineOfSightTest( Threat[uiLoop].pOpponent, pSoldier->sGridNo, pSoldier->pathing.bLevel, ANIM_PRONE, TRUE, NO_DISTANCE_LIMIT ) )
|
||||
{
|
||||
fProneCover = FALSE;
|
||||
}
|
||||
@@ -1040,7 +1079,8 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
|
||||
// sevenfm: sight test
|
||||
if( gGameExternalOptions.fAIBetterCover )
|
||||
{
|
||||
if ( SoldierToVirtualSoldierLineOfSightTest( Threat[uiLoop].pOpponent, sGridNo, pSoldier->pathing.bLevel, ANIM_PRONE, TRUE, -1 ) != 0 )
|
||||
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 ( SoldierToVirtualSoldierLineOfSightTest( Threat[uiLoop].pOpponent, sGridNo, pSoldier->pathing.bLevel, ANIM_PRONE, TRUE, -1 ) != 0 )
|
||||
{
|
||||
fProneCover = FALSE;
|
||||
}
|
||||
|
||||
@@ -297,6 +297,9 @@ BOOLEAN SightCoverAtSpot( SOLDIERTYPE *pSoldier, INT32 sSpot );
|
||||
|
||||
BOOLEAN FindBombNearby( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance );
|
||||
|
||||
BOOLEAN AnyCoverFromSpot( INT32 sSpot, INT8 bLevel, INT32 sThreatLoc, INT8 bThreatLevel );
|
||||
UINT8 CountSeenEnemiesLastTurn( SOLDIERTYPE *pSoldier );
|
||||
|
||||
#define MAX_FLANKS_RED 25
|
||||
#define MAX_FLANKS_YELLOW 25
|
||||
|
||||
|
||||
Reference in New Issue
Block a user