mirror of
https://github.com/1dot13/source.git
synced 2026-09-09 14:46:05 +02:00
Move decision if stuck in water or gas into its own function
This commit is contained in:
+71
-57
@@ -47,6 +47,7 @@ extern void IncrementWatchedLoc(UINT8 ubID, INT32 sGridNo, INT8 bLevel);
|
|||||||
void LogDecideInfo(SOLDIERTYPE *pSoldier);
|
void LogDecideInfo(SOLDIERTYPE *pSoldier);
|
||||||
void LogKnowledgeInfo(SOLDIERTYPE *pSoldier);
|
void LogKnowledgeInfo(SOLDIERTYPE *pSoldier);
|
||||||
INT8 DecideActionWearGasmask(SOLDIERTYPE* pSoldier);
|
INT8 DecideActionWearGasmask(SOLDIERTYPE* pSoldier);
|
||||||
|
ActionType DecideActionStuckInWaterOrGas(SOLDIERTYPE* pSoldier, BOOLEAN ubCanMove, BOOLEAN bInWater, BOOLEAN bInDeepWater, BOOLEAN bInGas);
|
||||||
|
|
||||||
// global status time counters to determine what takes the most time
|
// global status time counters to determine what takes the most time
|
||||||
|
|
||||||
@@ -4401,7 +4402,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
|
|||||||
{
|
{
|
||||||
// look for best place to RUN AWAY to (farthest from the closest threat)
|
// look for best place to RUN AWAY to (farthest from the closest threat)
|
||||||
pSoldier->aiData.usActionData = FindSpotMaxDistFromOpponents(pSoldier);
|
pSoldier->aiData.usActionData = FindSpotMaxDistFromOpponents(pSoldier);
|
||||||
|
|
||||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||||
{
|
{
|
||||||
#ifdef DEBUGDECISIONS
|
#ifdef DEBUGDECISIONS
|
||||||
@@ -4861,7 +4862,6 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
|
|||||||
INT32 sClosestOpponent = NOWHERE,sBestCover = NOWHERE;//dnl ch58 160813
|
INT32 sClosestOpponent = NOWHERE,sBestCover = NOWHERE;//dnl ch58 160813
|
||||||
INT32 sClosestDisturbance;
|
INT32 sClosestDisturbance;
|
||||||
INT16 ubMinAPCost;
|
INT16 ubMinAPCost;
|
||||||
UINT8 ubCanMove;
|
|
||||||
INT8 bDirection;
|
INT8 bDirection;
|
||||||
UINT8 ubBestAttackAction = AI_ACTION_NONE;
|
UINT8 ubBestAttackAction = AI_ACTION_NONE;
|
||||||
INT8 bCanAttack,bActionReturned;
|
INT8 bCanAttack,bActionReturned;
|
||||||
@@ -4877,7 +4877,6 @@ INT16 ubMinAPCost;
|
|||||||
|
|
||||||
ATTACKTYPE BestShot, BestThrow, BestStab ,BestAttack;//dnl ch69 150913
|
ATTACKTYPE BestShot, BestThrow, BestStab ,BestAttack;//dnl ch69 150913
|
||||||
BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->aiData.bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) );
|
BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->aiData.bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) );
|
||||||
BOOLEAN fClimb;
|
|
||||||
INT16 ubBurstAPs;
|
INT16 ubBurstAPs;
|
||||||
UINT8 ubOpponentDir;
|
UINT8 ubOpponentDir;
|
||||||
INT32 sCheckGridNo;
|
INT32 sCheckGridNo;
|
||||||
@@ -4912,7 +4911,7 @@ INT16 ubMinAPCost;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// can this guy move to any of the neighbouring squares ? (sets TRUE/FALSE)
|
// can this guy move to any of the neighbouring squares ? (sets TRUE/FALSE)
|
||||||
ubCanMove = (pSoldier->bActionPoints >= MinPtsToMove(pSoldier));
|
UINT8 ubCanMove = (pSoldier->bActionPoints >= MinPtsToMove(pSoldier));
|
||||||
|
|
||||||
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
{
|
{
|
||||||
@@ -5019,6 +5018,7 @@ INT16 ubMinAPCost;
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
bInGas = DecideActionWearGasmask(pSoldier);
|
bInGas = DecideActionWearGasmask(pSoldier);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// IF GASSED, OR REALLY TIRED (ON THE VERGE OF COLLAPSING), TRY TO RUN AWAY
|
// IF GASSED, OR REALLY TIRED (ON THE VERGE OF COLLAPSING), TRY TO RUN AWAY
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -5060,58 +5060,10 @@ INT16 ubMinAPCost;
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// STUCK IN WATER OR GAS, NO COVER, GO TO NEAREST SPOT OF UNGASSED LAND
|
// STUCK IN WATER OR GAS, NO COVER, GO TO NEAREST SPOT OF UNGASSED LAND
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
auto decision = DecideActionStuckInWaterOrGas(pSoldier, ubCanMove, bInWater, bInDeepWater, bInGas);
|
||||||
// when in deep water, move to closest opponent
|
if (decision != AI_ACTION_LAST)
|
||||||
if (ubCanMove && bInDeepWater && !pSoldier->aiData.bNeutral && pSoldier->aiData.bOrders == SEEKENEMY)
|
|
||||||
{
|
{
|
||||||
// find closest reachable opponent, excluding opponents in deep water
|
return decision;
|
||||||
pSoldier->aiData.usActionData = ClosestReachableDisturbance(pSoldier, &fClimb);
|
|
||||||
|
|
||||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
|
||||||
{
|
|
||||||
return(AI_ACTION_LEAVE_WATER_GAS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if soldier in water/gas has enough APs left to move at least 1 square
|
|
||||||
if (ubCanMove && (bInGas || bInDeepWater || FindBombNearby(pSoldier, pSoldier->sGridNo, BOMB_DETECTION_RANGE) || RedSmokeDanger(pSoldier->sGridNo, pSoldier->pathing.bLevel)))
|
|
||||||
{
|
|
||||||
pSoldier->aiData.usActionData = FindNearestUngassedLand(pSoldier);
|
|
||||||
|
|
||||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
|
||||||
{
|
|
||||||
#ifdef DEBUGDECISIONS
|
|
||||||
sprintf(tempstr,"%s - SEEKING NEAREST UNGASSED LAND at grid %d",pSoldier->name,pSoldier->aiData.usActionData);
|
|
||||||
AIPopMessage(tempstr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return(AI_ACTION_LEAVE_WATER_GAS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// couldn't find ANY land within 25 tiles(!), this should never happen...
|
|
||||||
|
|
||||||
// look for best place to RUN AWAY to (farthest from the closest threat)
|
|
||||||
pSoldier->aiData.usActionData = FindSpotMaxDistFromOpponents(pSoldier);
|
|
||||||
|
|
||||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
|
||||||
{
|
|
||||||
#ifdef DEBUGDECISIONS
|
|
||||||
sprintf(tempstr,"%s - NO LAND NEAR, RUNNING AWAY to grid %d",pSoldier->name,pSoldier->aiData.usActionData);
|
|
||||||
AIPopMessage(tempstr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return(AI_ACTION_RUN_AWAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GIVE UP ON LIFE! MERCS MUST HAVE JUST CORNERED A HELPLESS ENEMY IN A
|
|
||||||
// GAS FILLED ROOM (OR IN WATER MORE THAN 25 TILES FROM NEAREST LAND...)
|
|
||||||
if ( bInGas && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
|
||||||
{
|
|
||||||
pSoldier->bBreath = pSoldier->bBreathMax;
|
|
||||||
pSoldier->aiData.bAIMorale = MORALE_FEARLESS; // Can't move, can't get away, go nuts instead...
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pSoldier->aiData.bAIMorale = MORALE_HOPELESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// offer surrender?
|
// offer surrender?
|
||||||
@@ -5432,7 +5384,8 @@ INT16 ubMinAPCost;
|
|||||||
(pSoldier->aiData.bAttitude != AGGRESSIVE || Chance((100 - BestShot.ubChanceToReallyHit) / 2)))
|
(pSoldier->aiData.bAttitude != AGGRESSIVE || Chance((100 - BestShot.ubChanceToReallyHit) / 2)))
|
||||||
{
|
{
|
||||||
// get the location of the closest CONSCIOUS reachable opponent
|
// get the location of the closest CONSCIOUS reachable opponent
|
||||||
sClosestDisturbance = ClosestReachableDisturbance(pSoldier, &fClimb);
|
BOOLEAN fClimbDummy;
|
||||||
|
sClosestDisturbance = ClosestReachableDisturbance(pSoldier, &fClimbDummy);
|
||||||
|
|
||||||
// if we found one
|
// if we found one
|
||||||
if (!TileIsOutOfBounds(sClosestDisturbance))
|
if (!TileIsOutOfBounds(sClosestDisturbance))
|
||||||
@@ -5950,7 +5903,8 @@ INT16 ubMinAPCost;
|
|||||||
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Black cover advance]"));
|
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Black cover advance]"));
|
||||||
DebugAI(AI_MSG_INFO, pSoldier, String("find cover advance spot"));
|
DebugAI(AI_MSG_INFO, pSoldier, String("find cover advance spot"));
|
||||||
|
|
||||||
INT32 sClosestDisturbance = ClosestReachableDisturbance(pSoldier, &fClimb);
|
BOOLEAN fClimbDummy;
|
||||||
|
INT32 sClosestDisturbance = ClosestReachableDisturbance(pSoldier, &fClimbDummy);
|
||||||
|
|
||||||
if (!TileIsOutOfBounds(sClosestDisturbance))
|
if (!TileIsOutOfBounds(sClosestDisturbance))
|
||||||
{
|
{
|
||||||
@@ -10382,3 +10336,63 @@ INT8 DecideActionWearGasmask(SOLDIERTYPE *pSoldier)
|
|||||||
|
|
||||||
return bInGas;
|
return bInGas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActionType DecideActionStuckInWaterOrGas(SOLDIERTYPE *pSoldier, BOOLEAN ubCanMove, BOOLEAN bInWater, BOOLEAN bInDeepWater, BOOLEAN bInGas)
|
||||||
|
{
|
||||||
|
// when in deep water, move to closest opponent
|
||||||
|
if (ubCanMove && (bInDeepWater || bInWater) && !pSoldier->aiData.bNeutral && pSoldier->aiData.bOrders == SEEKENEMY)
|
||||||
|
{
|
||||||
|
// find closest reachable opponent, excluding opponents in deep water
|
||||||
|
BOOLEAN fClimb;
|
||||||
|
pSoldier->aiData.usActionData = ClosestReachableDisturbance(pSoldier, &fClimb);
|
||||||
|
|
||||||
|
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||||
|
{
|
||||||
|
return(AI_ACTION_LEAVE_WATER_GAS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if soldier in water/gas has enough APs left to move at least 1 square
|
||||||
|
if (ubCanMove && (bInGas || bInWater || bInDeepWater || FindBombNearby(pSoldier, pSoldier->sGridNo, BOMB_DETECTION_RANGE) || RedSmokeDanger(pSoldier->sGridNo, pSoldier->pathing.bLevel)))
|
||||||
|
{
|
||||||
|
pSoldier->aiData.usActionData = FindNearestUngassedLand(pSoldier);
|
||||||
|
|
||||||
|
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||||
|
{
|
||||||
|
#ifdef DEBUGDECISIONS
|
||||||
|
sprintf(tempstr, "%s - SEEKING NEAREST UNGASSED LAND at grid %d", pSoldier->name, pSoldier->aiData.usActionData);
|
||||||
|
AIPopMessage(tempstr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(AI_ACTION_LEAVE_WATER_GAS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// couldn't find ANY land within 25 tiles(!), this should never happen...
|
||||||
|
|
||||||
|
// look for best place to RUN AWAY to (farthest from the closest threat)
|
||||||
|
pSoldier->aiData.usActionData = FindSpotMaxDistFromOpponents(pSoldier);
|
||||||
|
|
||||||
|
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||||
|
{
|
||||||
|
#ifdef DEBUGDECISIONS
|
||||||
|
sprintf(tempstr, "%s - NO LAND NEAR, RUNNING AWAY to grid %d", pSoldier->name, pSoldier->aiData.usActionData);
|
||||||
|
AIPopMessage(tempstr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(AI_ACTION_RUN_AWAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GIVE UP ON LIFE! MERCS MUST HAVE JUST CORNERED A HELPLESS ENEMY IN A
|
||||||
|
// GAS FILLED ROOM (OR IN WATER MORE THAN 25 TILES FROM NEAREST LAND...)
|
||||||
|
if ((bInGas || bInWater || bInDeepWater) && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE)
|
||||||
|
{
|
||||||
|
pSoldier->bBreath = pSoldier->bBreathMax;
|
||||||
|
pSoldier->aiData.bAIMorale = MORALE_FEARLESS; // Can't move, can't get away, go nuts instead...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pSoldier->aiData.bAIMorale = MORALE_HOPELESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return AI_ACTION_LAST;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user