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:
Sevenfm
2020-02-16 14:08:47 +00:00
parent 8e9f9cb8a1
commit 0330e6c1a8
5 changed files with 227 additions and 114 deletions
+147 -10
View File
@@ -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;
}