mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
Improved code to avoid dangerous locations.
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8756 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+147
-10
@@ -945,16 +945,22 @@ INT16 RandomFriendWithin(SOLDIERTYPE *pSoldier)
|
||||
continue;
|
||||
}
|
||||
|
||||
// if our movement range is NOT restricted
|
||||
if (!fRangeRestricted || (SpacesAway(usOrigin,usDest) <= usMaxDist))
|
||||
if (SpacesAway(usOrigin, usDest) > usMaxDist)
|
||||
{
|
||||
if (LegalNPCDestination(pSoldier,usDest,ENSURE_PATH,NOWATER, 0))
|
||||
{
|
||||
fFound = TRUE; // found a spot
|
||||
pSoldier->aiData.usActionData = usDest; // store this->pathing.sDestination
|
||||
pSoldier->pathing.bPathStored = TRUE; // optimization - Ian
|
||||
break; // stop checking in other directions
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!CheckNPCDestination(pSoldier, usDest, TRUE, TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LegalNPCDestination(pSoldier, usDest, ENSURE_PATH, NOWATER, 0))
|
||||
{
|
||||
fFound = TRUE; // found a spot
|
||||
pSoldier->aiData.usActionData = usDest; // store this->pathing.sDestination
|
||||
pSoldier->pathing.bPathStored = TRUE; // optimization - Ian
|
||||
break; // stop checking in other directions
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1109,6 +1115,12 @@ INT32 RandDestWithinRange(SOLDIERTYPE *pSoldier)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!CheckNPCDestination(pSoldier, sRandDest, TRUE, TRUE))
|
||||
{
|
||||
sRandDest = NOWHERE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!LegalNPCDestination(pSoldier,sRandDest,ENSURE_PATH,NOWATER,0))
|
||||
{
|
||||
sRandDest = NOWHERE;
|
||||
@@ -4212,6 +4224,47 @@ UINT8 CountTeamSeeSoldier( INT8 bTeam, SOLDIERTYPE *pSoldier )
|
||||
return ubFriends;
|
||||
}
|
||||
|
||||
BOOLEAN CheckDoorAtGridno(UINT32 usGridNo)
|
||||
{
|
||||
STRUCTURE *pStructure;
|
||||
|
||||
pStructure = FindStructure(usGridNo, STRUCTURE_ANYDOOR);
|
||||
if (pStructure != NULL)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN CheckDoorNearGridno(UINT32 usGridNo)
|
||||
{
|
||||
UINT8 ubMovementCost;
|
||||
INT32 sTempGridNo;
|
||||
UINT8 ubDirection;
|
||||
|
||||
if (CheckDoorAtGridno(usGridNo))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (ubDirection = 0; ubDirection < NUM_WORLD_DIRECTIONS; ubDirection++)
|
||||
{
|
||||
sTempGridNo = NewGridNo(usGridNo, DirectionInc(ubDirection));
|
||||
|
||||
if (sTempGridNo != usGridNo)
|
||||
{
|
||||
ubMovementCost = gubWorldMovementCosts[sTempGridNo][ubDirection][0];
|
||||
if (IS_TRAVELCOST_DOOR(ubMovementCost))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN FindBombNearby( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance )
|
||||
{
|
||||
UINT32 uiBombIndex;
|
||||
@@ -4361,6 +4414,34 @@ BOOLEAN CheckRoof(INT32 sGridNo)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN FindNearbyExplosiveStructure(INT32 sSpot, INT8 bLevel)
|
||||
{
|
||||
INT32 sTempGridNo;
|
||||
UINT8 ubDirection;
|
||||
|
||||
if (TileIsOutOfBounds(sSpot))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check adjacent reachable tiles
|
||||
for (ubDirection = 0; ubDirection < NUM_WORLD_DIRECTIONS; ubDirection++)
|
||||
{
|
||||
sTempGridNo = NewGridNo(sSpot, DirectionInc(ubDirection));
|
||||
|
||||
if (sTempGridNo != sSpot)
|
||||
{
|
||||
if (FindStructFlag(sTempGridNo, bLevel, STRUCTURE_EXPLOSIVE))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT8 TerrainDensity(INT32 sSpot, INT8 bLevel, UINT8 ubDistance, BOOLEAN fGrass)
|
||||
{
|
||||
if (TileIsOutOfBounds(sSpot))
|
||||
@@ -4619,4 +4700,60 @@ BOOLEAN SoldierAI(SOLDIERTYPE *pSoldier)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 SpotDangerLevel(SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fCheckWater, BOOLEAN fCheckLight)
|
||||
{
|
||||
if (!pSoldier)
|
||||
return 0;
|
||||
|
||||
if (TileIsOutOfBounds(sGridNo))
|
||||
return 0;
|
||||
|
||||
BOOLEAN fCautious = FALSE;
|
||||
BOOLEAN fGreen = FALSE;
|
||||
UINT8 ubLevel = 0;
|
||||
|
||||
if ((pSoldier->aiData.bAlertStatus >= STATUS_RED || pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE))
|
||||
fCautious = TRUE;
|
||||
|
||||
if (pSoldier->aiData.bAlertStatus < STATUS_YELLOW)
|
||||
fGreen = TRUE;
|
||||
|
||||
if (!gGameExternalOptions.fAITacticalRetreat && NorthSpot(sGridNo, pSoldier->pathing.bLevel) ||
|
||||
pSoldier->ubProfile == NO_PROFILE && fGreen && CheckDoorNearGridno(sGridNo))
|
||||
ubLevel = 1;
|
||||
|
||||
if (fCautious && (fCheckLight && InLightAtNight(sGridNo, pSoldier->pathing.bLevel) || FindNearbyExplosiveStructure(sGridNo, pSoldier->pathing.bLevel)))
|
||||
ubLevel = 2;
|
||||
|
||||
if (fCheckWater && DeepWater(sGridNo, pSoldier->pathing.bLevel) ||
|
||||
RedSmokeDanger(sGridNo, pSoldier->pathing.bLevel))
|
||||
ubLevel = 3;
|
||||
|
||||
if (InGas(pSoldier, sGridNo) ||
|
||||
FindBombNearby(pSoldier, sGridNo, BOMB_DETECTION_RANGE))
|
||||
ubLevel = 4;
|
||||
|
||||
return ubLevel;
|
||||
}
|
||||
|
||||
BOOLEAN CheckNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fCheckWater, BOOLEAN fCheckLight)
|
||||
{
|
||||
if (!pSoldier)
|
||||
return FALSE;
|
||||
|
||||
if (TileIsOutOfBounds(sGridNo))
|
||||
return FALSE;
|
||||
|
||||
// find current danger level
|
||||
UINT8 ubLevel = SpotDangerLevel(pSoldier, pSoldier->sGridNo, fCheckWater, fCheckLight);
|
||||
// find danger level at target spot
|
||||
UINT8 ubTargetLevel = SpotDangerLevel(pSoldier, sGridNo, fCheckWater, fCheckLight);
|
||||
|
||||
// avoid moving into dangerous spot
|
||||
if (ubTargetLevel > 0 && ubTargetLevel >= ubLevel)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+17
-104
@@ -1499,19 +1499,7 @@ INT32 FindSpotMaxDistFromOpponents(SOLDIERTYPE *pSoldier)
|
||||
continue;
|
||||
}
|
||||
|
||||
//Madd: skip lighted spots
|
||||
if ( InLightAtNight( sGridNo, pSoldier->pathing.bLevel ) )
|
||||
continue;
|
||||
|
||||
// sevenfm: avoid staying at north edge
|
||||
if (!gGameExternalOptions.fAITacticalRetreat &&
|
||||
NorthSpot(sGridNo, pSoldier->pathing.bLevel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: avoid red smoke
|
||||
if (RedSmokeDanger(sGridNo, pSoldier->pathing.bLevel))
|
||||
if (!CheckNPCDestination(pSoldier, sGridNo, TRUE, TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1665,38 +1653,7 @@ INT32 FindNearestUngassedLand(SOLDIERTYPE *pSoldier)
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: check for gas
|
||||
if (InGas(pSoldier, sGridNo))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for deep water
|
||||
if (DeepWater(pSoldier->sGridNo, pSoldier->pathing.bLevel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for bombs nearby
|
||||
if (FindBombNearby(pSoldier, sGridNo, BOMB_DETECTION_RANGE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for red smoke
|
||||
if (RedSmokeDanger(sGridNo, pSoldier->pathing.bLevel) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: avoid staying at north edge
|
||||
if (NorthSpot(sGridNo, pSoldier->pathing.bLevel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for red smoke
|
||||
if (RedSmokeDanger(sGridNo, pSoldier->pathing.bLevel) > 0)
|
||||
if (!CheckNPCDestination(pSoldier, sGridNo, TRUE, FALSE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1839,18 +1796,12 @@ INT32 FindNearbyDarkerSpot(SOLDIERTYPE *pSoldier)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FindBombNearby(pSoldier, sGridNo, BOMB_DETECTION_RANGE))
|
||||
if (!CheckNPCDestination(pSoldier, sGridNo, TRUE, TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: avoid staying at north edge
|
||||
if (NorthSpot(sGridNo, pSoldier->pathing.bLevel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RedSmokeDanger(sGridNo, pSoldier->pathing.bLevel))
|
||||
if (InLightAtNight(sGridNo, pSoldier->pathing.bLevel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -2026,24 +1977,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
|
||||
continue;
|
||||
}
|
||||
|
||||
// exclude locations with tear/mustard gas (at this point, smoke is cool!)
|
||||
if (InGas(pSoldier, sGridNo))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FindBombNearby(pSoldier, sGridNo, BOMB_DETECTION_RANGE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: avoid staying at north edge
|
||||
/*if (NorthSpot(sGridNo, pSoldier->pathing.bLevel))
|
||||
{
|
||||
continue;
|
||||
}*/
|
||||
|
||||
if (RedSmokeDanger(sGridNo, pSoldier->pathing.bLevel))
|
||||
if (!CheckNPCDestination(pSoldier, sGridNo, TRUE, FALSE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -2775,16 +2709,6 @@ INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction )
|
||||
continue;
|
||||
}
|
||||
|
||||
// exclude locations with tear/mustard gas (at this point, smoke is cool!)
|
||||
if ( InGas( pSoldier, sGridNo ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Madd: skip lighted spots
|
||||
if ( InLightAtNight( sGridNo, pSoldier->pathing.bLevel ) )
|
||||
continue;
|
||||
|
||||
// sevenfm: skip tiles too close to edge
|
||||
if ( PythSpacesAway( FindNearestEdgePoint ( sGridNo ), sGridNo ) <= 2 )
|
||||
{
|
||||
@@ -2806,8 +2730,13 @@ INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction )
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: avoid staying at north edge
|
||||
if (NorthSpot(sGridNo, pSoldier->pathing.bLevel))
|
||||
// avoid fresh corpses
|
||||
if (GetNearestRottingCorpseAIWarning(sGridNo) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!CheckNPCDestination(pSoldier, sGridNo, FALSE, TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -2823,20 +2752,16 @@ INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction )
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: penalize locations near fresh corpses
|
||||
if( GetNearestRottingCorpseAIWarning( sGridNo ) > 0 )
|
||||
// sevenfm: penalize locations too far from noise gridno
|
||||
if (PythSpacesAway(sGridNo, sPos) > MAX_FLANK_DIST_RED)
|
||||
{
|
||||
sTempDist = sTempDist / 2;
|
||||
}
|
||||
|
||||
if (FindBombNearby(pSoldier, sGridNo, BOMB_DETECTION_RANGE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RedSmokeDanger(sGridNo, pSoldier->pathing.bLevel))
|
||||
// sevenfm: try to flank closer to vision distance limit for faster flanking
|
||||
if (PythSpacesAway(sGridNo, sPos) > sDistanceVisible + 10)
|
||||
{
|
||||
continue;
|
||||
sTempDist = sTempDist / 2;
|
||||
}
|
||||
|
||||
// sevenfm: penalize locations with no sight cover from noise gridno (supposed that we are sneaking)
|
||||
@@ -2847,18 +2772,6 @@ INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction )
|
||||
sTempDist = sTempDist / 2;
|
||||
}
|
||||
|
||||
// sevenfm: penalize locations too far from noise gridno
|
||||
if( PythSpacesAway( sGridNo, sPos) > MAX_FLANK_DIST_RED )
|
||||
{
|
||||
sTempDist = sTempDist / 2;
|
||||
}
|
||||
|
||||
// sevenfm: try to flank closer to vision distance limit for faster flanking
|
||||
if( PythSpacesAway( sGridNo, sPos) > sDistanceVisible + 10 )
|
||||
{
|
||||
sTempDist = sTempDist / 2;
|
||||
}
|
||||
|
||||
// allow extra directions for flanking
|
||||
if ( bAction == AI_ACTION_FLANK_LEFT )
|
||||
{
|
||||
|
||||
@@ -296,17 +296,23 @@ INT8 CalcMoraleNew(SOLDIERTYPE *pSoldier);
|
||||
BOOLEAN ProneSightCoverAtSpot( SOLDIERTYPE *pSoldier, INT32 sSpot );
|
||||
BOOLEAN SightCoverAtSpot( SOLDIERTYPE *pSoldier, INT32 sSpot );
|
||||
|
||||
BOOLEAN CheckDoorAtGridno(UINT32 usGridNo);
|
||||
BOOLEAN CheckDoorNearGridno(UINT32 usGridNo);
|
||||
BOOLEAN FindBombNearby( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance );
|
||||
UINT8 RedSmokeDanger(INT32 sGridNo, INT8 bLevel);
|
||||
BOOLEAN CheckArtilleryStrike(void);
|
||||
BOOLEAN CheckRoof(INT32 sGridNo);
|
||||
UINT8 TerrainDensity(INT32 sSpot, INT8 bLevel, UINT8 ubDistance, BOOLEAN fGrass);
|
||||
BOOLEAN FindNearbyExplosiveStructure(INT32 sSpot, INT8 bLevel);
|
||||
INT16 DistanceToClosestActiveOpponent(SOLDIERTYPE *pSoldier, INT32 sSpot);
|
||||
BOOLEAN ValidOpponent(SOLDIERTYPE* pSoldier, SOLDIERTYPE* pOpponent);
|
||||
|
||||
BOOLEAN AnyCoverFromSpot( INT32 sSpot, INT8 bLevel, INT32 sThreatLoc, INT8 bThreatLevel );
|
||||
UINT8 CountSeenEnemiesLastTurn( SOLDIERTYPE *pSoldier );
|
||||
|
||||
BOOLEAN CheckNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fCheckWater, BOOLEAN fCheckLight);
|
||||
UINT8 SpotDangerLevel(SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fCheckWater, BOOLEAN fCheckLight);
|
||||
|
||||
BOOLEAN NorthSpot(INT32 sSpot, INT8 bLevel);
|
||||
BOOLEAN SoldierAI(SOLDIERTYPE *pSoldier);
|
||||
|
||||
|
||||
@@ -1478,6 +1478,59 @@ BOOLEAN RemoveStruct( INT32 iMapIndex, UINT16 usIndex )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
BOOLEAN FindStruct(INT32 sSpot, INT8 bLevel, UINT16 usIndex)
|
||||
{
|
||||
if (TileIsOutOfBounds(sSpot))
|
||||
return FALSE;
|
||||
|
||||
LEVELNODE *pStruct = NULL;
|
||||
LEVELNODE *pOldStruct = NULL;
|
||||
|
||||
if (bLevel == 0)
|
||||
{
|
||||
pStruct = gpWorldLevelData[sSpot].pStructHead;
|
||||
}
|
||||
else
|
||||
{
|
||||
pStruct = gpWorldLevelData[sSpot].pOnRoofHead;
|
||||
}
|
||||
|
||||
// Look through all structs
|
||||
while (pStruct != NULL)
|
||||
{
|
||||
if (pStruct->usIndex == usIndex)
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
pOldStruct = pStruct;
|
||||
pStruct = pStruct->pNext;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN FindStructFlag(INT32 sSpot, INT8 bLevel, UINT32 uiFlag)
|
||||
{
|
||||
if (bLevel > 0)
|
||||
return FALSE;
|
||||
|
||||
if (TileIsOutOfBounds(sSpot))
|
||||
return FALSE;
|
||||
|
||||
STRUCTURE * pStructure;
|
||||
|
||||
pStructure = FindStructure(sSpot, uiFlag);
|
||||
|
||||
if (pStructure)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// same as RemoveStruct(...), except that this focuses on .pOnRoofHead instead of .pStructHead
|
||||
BOOLEAN RemoveOnRoofStruct( INT32 iMapIndex, UINT16 usIndex )
|
||||
{
|
||||
|
||||
@@ -170,4 +170,8 @@ void SetTreeTopStateForMap();
|
||||
BOOLEAN IsOknoLevel( INT32 sGridNo );
|
||||
BOOLEAN IsLegionLevel( INT32 sGridNo );
|
||||
|
||||
// sevenfm
|
||||
BOOLEAN FindStruct(INT32 sSpot, INT8 bLevel, UINT16 usIndex);
|
||||
BOOLEAN FindStructFlag(INT32 sSpot, INT8 bLevel, UINT32 uiFlag);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user