Fix AI units to reload/rechamber off-hand when necessary

Fix to prevent soldiers from climbing the wrong building while moving toward a disturbance
Fix to prevent soldiers from doing nothing when a climb point is not nearby
Fix improper indexing of directions

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1533 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Overhaul
2007-10-20 08:19:17 +00:00
parent dd0d6ea66d
commit 035359edf0
7 changed files with 205 additions and 142 deletions
+1 -1
View File
@@ -226,5 +226,5 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s
INT16 FindBestCoverNearTheGridNo(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubSearchRadius );
INT8 FindDirectionForClimbing( INT16 sGridNo );
INT8 FindDirectionForClimbing( INT16 sGridNo, INT8 bLevel);
+11 -7
View File
@@ -130,7 +130,7 @@ BOOLEAN InitAI( void )
#ifdef _DEBUG
if (gfDisplayCoverValues)
{
memset( gsCoverValue, 0x7F, sizeof( INT16 ) * WORLD_MAX );
//memset( gsCoverValue, 0x7F, sizeof( INT16 ) * WORLD_MAX );
}
#endif
@@ -411,6 +411,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier )
if ( gTacticalStatus.ubAttackBusyCount > 0 )
{
fProcessNewSituation = FALSE;
#if 0
// HACK!!
if ( pSoldier->bAction == AI_ACTION_FIRE_GUN )
{
@@ -432,6 +433,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier )
fProcessNewSituation = TRUE;
}
}
#endif
}
else
{
@@ -2076,6 +2078,8 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
case AI_ACTION_CHANGE_FACING: // turn this way & that to look
// as long as we don't see anyone new, cover won't have changed
// if we see someone new, it will cause a new situation & remove this
// 0verhaul: If turning and not moving, set the final destination to the current position
pSoldier->sFinalDestination = pSoldier->sGridNo;
SkipCoverCheck = TRUE;
#ifdef DEBUGDECISIONS
@@ -2850,14 +2854,14 @@ void SetNewSituation( SOLDIERTYPE * pSoldier )
if ( pSoldier->ubQuoteRecord == 0 && !gTacticalStatus.fAutoBandageMode && !(pSoldier->bNeutral && gTacticalStatus.uiFlags & ENGAGED_IN_CONV) )
{
// allow new situation to be set
if (gTacticalStatus.ubAttackBusyCount > 0)
{
DebugAttackBusy( "@#!% NOT setting NewSituation because still busy attacking.\n" );
}
else
//if (gTacticalStatus.ubAttackBusyCount > 0)
//{
// DebugAttackBusy( "@#!% NOT setting NewSituation because still busy attacking.\n" );
//}
//else
{
// 0verhaul: Let's see if we can do without this.
// pSoldier->bNewSituation = IS_NEW_SITUATION;
pSoldier->bNewSituation = IS_NEW_SITUATION;
}
if ( gTacticalStatus.ubAttackBusyCount != 0 )
+9 -3
View File
@@ -101,7 +101,11 @@ INT8 OKToAttack(SOLDIERTYPE * pSoldier, int target)
return(NOSHOOT_NOLOAD);
}
}
else if (pSoldier->inv[HANDPOS].ItemData.Gun.ubGunShotsLeft == 0 /*SB*/ || !(pSoldier->inv[HANDPOS].ItemData.Gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER))
else if (pSoldier->inv[HANDPOS].ItemData.Gun.ubGunShotsLeft == 0 /*SB*/ ||
!(pSoldier->inv[HANDPOS].ItemData.Gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER) ||
(IsValidSecondHandShotForReloadingPurposes( pSoldier) &&
(pSoldier->inv[SECONDHANDPOS].ItemData.Gun.ubGunShotsLeft == 0 ||
!(pSoldier->inv[SECONDHANDPOS].ItemData.Gun.ubGunState & GS_CARTRIDGE_IN_CHAMBER))))
{
return(NOSHOOT_NOAMMO);
}
@@ -448,7 +452,7 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
{
INT8 bMinPointsNeeded = 0;
INT8 bAPForStandUp = 0;
INT8 bAPToLookAtWall = ( FindDirectionForClimbing( pSoldier->sGridNo ) == pSoldier->ubDirection ) ? 0 : 1;
INT8 bAPToLookAtWall = ( FindDirectionForClimbing( pSoldier->sGridNo, pSoldier->bLevel ) == pSoldier->ubDirection ) ? 0 : 1;
//NumMessage("AffordableAction - Guy#",pSoldier->ubID);
@@ -2315,7 +2319,9 @@ void RearrangePocket(SOLDIERTYPE *pSoldier, INT8 bPocket1, INT8 bPocket2, UINT8
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"RearrangePocket");
// NB there's no such thing as a temporary swap for now...
SwapObjs( &(pSoldier->inv[bPocket1]), &(pSoldier->inv[bPocket2]) );
//SwapObjs( &(pSoldier->inv[bPocket1]), &(pSoldier->inv[bPocket2]) );
SwapObjs( pSoldier, bPocket1, bPocket2 );
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"RearrangePocket done");
}
+18 -5
View File
@@ -2773,7 +2773,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if (!fUp)
DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d is climbing down",pSoldier->ubID) );
if ( CanClimbFromHere ( pSoldier, fUp ) )
// As mentioned in the next part, the sClosestDisturbance IS the climb point desired. So the
// check here should be "Am I aready there?" If so, THEN possibly climb. This previous check
// would have a soldier climbing any building, even if it was not the desired building. So
// WRONG WRONG WRONG
//if ( CanClimbFromHere ( pSoldier, fUp ) )
if (pSoldier->sGridNo == sClosestDisturbance)
{
if (IsActionAffordable(pSoldier) && pSoldier->bActionPoints >= ( AP_CLIMBROOF + MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST)))
{
@@ -2782,9 +2787,16 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
}
else
{
pSoldier->usActionData = FindClosestClimbPoint(pSoldier, pSoldier->sGridNo , sClosestDisturbance , fUp );
if ( pSoldier->usActionData != NOWHERE )
// Do not overwrite the usActionData here. If there's no nearby climb point, the action data
// would become NOWHERE, and then the SEEK_ENEMY fallback would also fail.
// In fact, sClosestDisturbance has ALREADY calculated the closest climb point when climbing is
// necessary. The returned grid # in sClosestDisturbance is that climb point. So if climb is
// set, then use sClosestDisturbance as is.
//INT16 usClimbPoint = FindClosestClimbPoint(pSoldier, pSoldier->sGridNo , sClosestDisturbance , fUp );
INT16 usClimbPoint = sClosestDisturbance;
if ( usClimbPoint != NOWHERE )
{
pSoldier->usActionData = usClimbPoint;
return( AI_ACTION_MOVE_TO_CLIMB );
}
}
@@ -2996,9 +3008,10 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
}
else
{
pSoldier->usActionData = FindClosestClimbPoint(pSoldier, pSoldier->sGridNo , sClosestFriend , fUp );
if ( pSoldier->usActionData != NOWHERE )
INT16 sClimbPoint = FindClosestClimbPoint(pSoldier, pSoldier->sGridNo , sClosestFriend , fUp );
if ( sClimbPoint != NOWHERE )
{
pSoldier->usActionData = sClimbPoint;
return( AI_ACTION_MOVE_TO_CLIMB );
}
}
+161 -121
View File
@@ -194,9 +194,9 @@ INT8 CalcBestCTGT( SOLDIERTYPE *pSoldier, UINT8 ubOppID, INT16 sOppGridNo, INT8
// using only ints for maximum execution speed here
// CJC: Well, so much for THAT idea!
INT16 sCentralGridNo, sAdjSpot, sNorthGridNo, sSouthGridNo, sCheckSpot, sOKTest;
INT16 sCentralGridNo, sAdjSpot, sNorthGridNo, sSouthGridNo, sCheckSpot, sOKTest;
INT8 bThisCTGT, bBestCTGT = 0;
UINT8 sDir = 0;
sCheckSpot = -1;
@@ -210,7 +210,7 @@ INT8 CalcBestCTGT( SOLDIERTYPE *pSoldier, UINT8 ubOppID, INT16 sOppGridNo, INT8
// look into all 8 adjacent tiles & determine where the cover is the worst
// Lalien: shouldn't this start at 0 than?
for (sDir = 0; sDir < NUM_WORLD_DIRECTIONS; sDir++)
for (UINT8 sDir = 0; sDir < NUM_WORLD_DIRECTIONS; sDir++)
{
// get the gridno of the adjacent spot lying in that direction
sAdjSpot = NewGridNo( sCentralGridNo, DirectionInc( sDir ) );
@@ -588,7 +588,7 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
iBestCoverValue = -1;
#if defined( _DEBUG ) && !defined( PATHAI_VISIBLE_DEBUG )
#if defined( _DEBUG ) && defined( COVER_DEBUG )
if (gfDisplayCoverValues)
{
memset( gsCoverValue, 0x7F, sizeof( INT16 ) * WORLD_MAX );
@@ -794,15 +794,15 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
#endif
// determine maximum horizontal limits
sMaxLeft = min(iSearchRange,(pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min(iSearchRange,(pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min(iSearchRange,MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min(iSearchRange,MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min(iSearchRange,(pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min(iSearchRange,(pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min(iSearchRange,MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min(iSearchRange,MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
iRoamRange = RoamingRange(pSoldier,&sOrigin);
@@ -1007,7 +1007,7 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
}
#endif
#if defined( _DEBUG ) && !defined( PATHAI_VISIBLE_DEBUG )
#if defined( _DEBUG ) && defined( COVER_DEBUG )
if (gfDisplayCoverValues)
{
gsCoverValue[sGridNo] = (INT16) (iCoverValue / 100);
@@ -1244,20 +1244,20 @@ INT16 FindSpotMaxDistFromOpponents(SOLDIERTYPE *pSoldier)
//gubNPCAPBudget = gubNPCAPBudget = __min( gubNPCAPBudget, gubNPCAPBudget - GetAPsToChangeStance( pSoldier, ANIM_STAND ) );
// Lesh: will be using this form
if ( gubNPCAPBudget > GetAPsToChangeStance( pSoldier, ANIM_STAND ) )
gubNPCAPBudget = gubNPCAPBudget - GetAPsToChangeStance( pSoldier, ANIM_STAND );
gubNPCAPBudget = gubNPCAPBudget - (UINT8) GetAPsToChangeStance( pSoldier, ANIM_STAND );
//NumMessage("Search Range = ",iSearchRange);
//NumMessage("gubNPCAPBudget = ",gubNPCAPBudget);
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
// Call FindBestPath to set flags in all locations that we can
@@ -1404,15 +1404,15 @@ INT16 FindNearestUngassedLand(SOLDIERTYPE *pSoldier)
//NumMessage("Trying iSearchRange = ", iSearchRange);
// determine maximum horizontal limits
sMaxLeft = min(iSearchRange,(pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min(iSearchRange,(pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min(iSearchRange,MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min(iSearchRange,MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min(iSearchRange,(pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min(iSearchRange,(pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min(iSearchRange,MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min(iSearchRange,MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
// Call FindBestPath to set flags in all locations that we can
@@ -1469,7 +1469,7 @@ INT16 FindNearestUngassedLand(SOLDIERTYPE *pSoldier)
// CJC: here, unfortunately, we must calculate a path so we have an AP cost
// obviously, we're looking for LAND, so water is out!
sPathCost = LegalNPCDestination(pSoldier,sGridNo,ENSURE_PATH_COST,NOWATER,0);
sPathCost = (INT16) LegalNPCDestination(pSoldier,sGridNo,ENSURE_PATH_COST,NOWATER,0);
if (!sPathCost)
{
@@ -1517,15 +1517,15 @@ INT16 FindNearbyDarkerSpot( SOLDIERTYPE *pSoldier )
for (iSearchRange = 5; iSearchRange <= 15; iSearchRange += 5)
{
// determine maximum horizontal limits
sMaxLeft = min(iSearchRange,(pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min(iSearchRange,(pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min(iSearchRange,MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min(iSearchRange,MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min(iSearchRange,(pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min(iSearchRange,(pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min(iSearchRange,MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min(iSearchRange,MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
// Call FindBestPath to set flags in all locations that we can
@@ -1599,7 +1599,7 @@ INT16 FindNearbyDarkerSpot( SOLDIERTYPE *pSoldier )
// CJC: here, unfortunately, we must calculate a path so we have an AP cost
sPathCost = LegalNPCDestination(pSoldier,sGridNo,ENSURE_PATH_COST,NOWATER,0);
sPathCost = (INT16) LegalNPCDestination(pSoldier,sGridNo,ENSURE_PATH_COST,NOWATER,0);
if (!sPathCost)
{
@@ -1694,15 +1694,15 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
iSearchRange /= 2;
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
// Call FindBestPath to set flags in all locations that we can
@@ -1990,15 +1990,15 @@ INT16 FindClosestDoor( SOLDIERTYPE * pSoldier )
iSearchRange = 5;
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
// SET UP DOUBLE-LOOP TO STEP THROUGH POTENTIAL GRID #s
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
@@ -2163,15 +2163,15 @@ INT16 FindNearbyPointOnEdgeOfMap( SOLDIERTYPE * pSoldier, INT8 * pbDirection )
iSearchRange = EDGE_OF_MAP_SEARCH;
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
// reset the "reachable" flags in the region we're looking at
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
@@ -2261,9 +2261,9 @@ INT16 FindClosestBoxingRingSpot( SOLDIERTYPE * pSoldier, BOOLEAN fInRing )
iSearchRange = 7;
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
if ( (pSoldier->bTeam == gbPlayerNum) && (fInRing == FALSE) )
@@ -2273,9 +2273,9 @@ INT16 FindClosestBoxingRingSpot( SOLDIERTYPE * pSoldier, BOOLEAN fInRing )
}
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
{
@@ -2315,15 +2315,15 @@ INT16 FindNearestOpenableNonDoor( INT16 sStartGridNo )
iSearchRange = 7;
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (sStartGridNo % MAXCOL));
sMaxLeft = (INT16) min( iSearchRange, (sStartGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((sStartGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((sStartGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (sStartGridNo / MAXROW));
sMaxUp = (INT16) min( iSearchRange, (sStartGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((sStartGridNo / MAXROW) + 1));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((sStartGridNo / MAXROW) + 1));
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
{
@@ -2410,7 +2410,7 @@ INT16 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT16 sPos, INT8 bAction )
// }
//}
gubNPCAPBudget=iSearchRange*3;
gubNPCAPBudget=(UINT8) (iSearchRange*3);
// assume we have to stand up and turn
// use the min macro here to make sure we don't wrap the UINT8 to 255...
@@ -2422,15 +2422,15 @@ INT16 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT16 sPos, INT8 bAction )
// stay away from the edges
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxLeft = (INT16) min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxUp = (INT16) min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
// Call FindBestPath to set flags in all locations that we can
@@ -2497,7 +2497,7 @@ INT16 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT16 sPos, INT8 bAction )
// calculate the next potential gridno
sGridNo = pSoldier->sGridNo + sXOffset + (MAXCOL * sYOffset);
sTempDir = GetDirectionFromGridNo ( sGridNo, pSoldier );
sTempDist = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sGridNo );
sTempDist = (INT16) GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sGridNo );
//NumMessage("Testing gridno #",gridno);
if ( !(sGridNo >=0 && sGridNo < WORLD_MAX) )
@@ -2565,9 +2565,8 @@ INT16 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT16 sPos, INT8 bAction )
INT16 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp )
{
INT16 sGridNo;
INT32 iSearchRange = 20;
INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset;
INT16 sBestSpot = NOWHERE;
//DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , "FindClosestClimbPoint");
@@ -2575,69 +2574,87 @@ INT16 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp )
//NumMessage("Search Range = ",iSearchRange);
//NumMessage("gubNPCAPBudget = ",gubNPCAPBudget);
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// 0verhaul: This function is optimized to take advantage of the new climb point info.
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
//DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("Max: Left %d Right %d Up %d Down %d", sMaxLeft, sMaxRight, sMaxUp, sMaxDown ) );
INT16 sClimbGridNo=NOWHERE, sBestSpot=NOWHERE;
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
if (fClimbUp)
{
for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++)
// For the climb up case, search the nearby limits for a climb up point and take the closest.
INT16 sGridNo;
static const INT32 iSearchRange = 20;
INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset;
UINT8 ubTestDir;
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
//NumMessage("sMaxLeft = ",sMaxLeft);
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
//NumMessage("sMaxRight = ",sMaxRight);
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
//NumMessage("sMaxUp = ",sMaxUp);
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
//NumMessage("sMaxDown = ",sMaxDown);
//DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("Max: Left %d Right %d Up %d Down %d", sMaxLeft, sMaxRight, sMaxUp, sMaxDown ) );
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
{
// calculate the next potential gridno
sGridNo = pSoldier->sGridNo + sXOffset + (MAXCOL * sYOffset);
//DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("Checking grid %d" , sGridNo ));
//NumMessage("Testing gridno #",gridno);
if ( !(sGridNo >=0 && sGridNo < WORLD_MAX) )
for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++)
{
continue;
}
// calculate the next potential gridno
sGridNo = pSoldier->sGridNo + sXOffset + (MAXCOL * sYOffset);
//DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("Checking grid %d" , sGridNo ));
if ( sGridNo == pSoldier->sBlackList )
{
continue;
}
// exclude locations with tear/mustard gas (at this point, smoke is cool!)
if ( InGas( pSoldier, sGridNo ) )
{
continue;
}
// OK, this place shows potential. How useful is it as cover?
//NumMessage("Promising seems gridno #",gridno);
if ( FindBuilding ( sGridNo ) != NULL )
{
// DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("Building found at %d", sGridNo ));
sClimbGridNo = FindClosestClimbPoint( pSoldier, pSoldier->sGridNo, sGridNo, fClimbUp);
// DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("Closest climb point is %d" , sClimbGridNo ));
if ( sClimbGridNo != NOWHERE )
//NumMessage("Testing gridno #",gridno);
if ( !(sGridNo >=0 && sGridNo < WORLD_MAX) )
{
if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sClimbGridNo ) < GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sBestSpot ))
sBestSpot = sClimbGridNo;
continue;
}
if ( sGridNo == pSoldier->sBlackList )
{
continue;
}
// exclude locations with tear/mustard gas (at this point, smoke is cool!)
if ( InGas( pSoldier, sGridNo ) )
{
continue;
}
if (gpWorldLevelData[ sGridNo].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT)
{
// Search for the destination climb point on the roof
for (ubTestDir=0; ubTestDir < 8; ubTestDir += 2)
{
INT16 sTestGridNo = NewGridNo( sGridNo, DirectionInc( ubTestDir));
// And see if it or the ground location is occupied
if (gpWorldLevelData[ sTestGridNo ].ubExtFlags[1] & MAPELEMENT_EXT_CLIMBPOINT &&
(WhoIsThere2( sTestGridNo, 1 ) == NOBODY) &&
(WhoIsThere2( sGridNo, 0 ) == NOBODY) )
{
// Good climb point. Is it closer than the previous point?
if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sGridNo ) <
GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sBestSpot ))
{
// If not, we have a new winnar!
sBestSpot = sGridNo;
}
}
}
}
}
}
}
else
{
// Climbing down is easier. Just find the nearest climb point ;)
sBestSpot = FindClosestClimbPoint( pSoldier, pSoldier->sGridNo, pSoldier->sGridNo, fClimbUp);
}
// DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("FindClosestClimbPoint Returning %d", sBestSpot ));
// DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , String("FindClosestClimbPoint Returning %d", sBestSpot ));
return( sBestSpot );
}
@@ -2645,6 +2662,9 @@ INT16 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp )
BOOLEAN CanClimbFromHere (SOLDIERTYPE * pSoldier, BOOLEAN fUp )
{
#if 1
return FindDirectionForClimbing( pSoldier->sGridNo, pSoldier->bLevel) != DIRECTION_IRRELEVANT;
#else
BUILDING * pBuilding;
INT16 i;
INT32 iSearchRange = 1;
@@ -2654,12 +2674,12 @@ BOOLEAN CanClimbFromHere (SOLDIERTYPE * pSoldier, BOOLEAN fUp )
// determine maximum horizontal limits
sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxRight = min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
sMaxLeft = (INT16) min( iSearchRange, (pSoldier->sGridNo % MAXCOL));
sMaxRight = (INT16) min( iSearchRange, MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1));
// determine maximum vertical limits
sMaxUp = min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxDown = min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
sMaxUp = (INT16) min( iSearchRange, (pSoldier->sGridNo / MAXROW));
sMaxDown = (INT16) min( iSearchRange, MAXROW - ((pSoldier->sGridNo / MAXROW) + 1));
INT16 sGridNo=NOWHERE;
@@ -2720,6 +2740,7 @@ BOOLEAN CanClimbFromHere (SOLDIERTYPE * pSoldier, BOOLEAN fUp )
}
}
return FALSE;
#endif
}
// OK, this place shows potential. How useful is it as cover?
//NumMessage("Promising seems gridno #",gridno);
@@ -2783,22 +2804,41 @@ INT16 FindBestCoverNearTheGridNo(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubS
}
INT8 FindDirectionForClimbing( INT16 sGridNo )
INT8 FindDirectionForClimbing( INT16 sGridNo, INT8 bLevel )
{
UINT16 usBuildingID;
UINT16 usClimbSpotIndex;
UINT8 ubClimbDir;
INT16 sClimbSpot;
for( usBuildingID = 0; usBuildingID < gubNumberOfBuildings ; ++usBuildingID )
for( usClimbSpotIndex = 0; usClimbSpotIndex < gBuildings[ usBuildingID ].ubNumClimbSpots ; ++usClimbSpotIndex )
if( gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ] == sGridNo )
if (bLevel == 0)
{
if (gpWorldLevelData[ sGridNo].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT)
{
for (ubClimbDir=0; ubClimbDir<8; ubClimbDir+=2)
{
if( WhoIsThere2( gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ], 1 ) == NOBODY )
return atan8(CenterX(sGridNo),CenterY(sGridNo),CenterX(gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ]),CenterY(gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ]));
}else if( gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ] == sGridNo )
{
if( WhoIsThere2( gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ], 0 ) == NOBODY )
return atan8(CenterX(sGridNo),CenterY(sGridNo),CenterX(gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ]),CenterY(gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ]));
sClimbSpot = NewGridNo( sGridNo, DirectionInc( ubClimbDir));
if (gpWorldLevelData[ sClimbSpot].ubExtFlags[1] & MAPELEMENT_EXT_CLIMBPOINT &&
WhoIsThere2( sClimbSpot, 1 ) == NOBODY )
{
return ubClimbDir;
}
}
}
}
else if (bLevel == 1)
{
if (gpWorldLevelData[ sGridNo].ubExtFlags[1] & MAPELEMENT_EXT_CLIMBPOINT)
{
for (ubClimbDir=0; ubClimbDir<8; ubClimbDir+=2)
{
sClimbSpot = NewGridNo( sGridNo, DirectionInc( ubClimbDir));
if (gpWorldLevelData[ sClimbSpot].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT &&
WhoIsThere2( sClimbSpot, 0 ) == NOBODY )
{
return ubClimbDir;
}
}
}
}
return DIRECTION_IRRELEVANT;
}
+2 -2
View File
@@ -429,7 +429,7 @@ INT8 DecideAutoBandage( SOLDIERTYPE * pSoldier )
{
pSoldier->bSlotItemTakenFrom = bSlot;
SwapObjs( &(pSoldier->inv[HANDPOS]), &(pSoldier->inv[bSlot]) );
SwapObjs( pSoldier, HANDPOS, bSlot );
/*
memset( &TempObj, 0, sizeof( OBJECTTYPE ) );
// move the med kit out to temp obj
@@ -452,7 +452,7 @@ INT8 DecideAutoBandage( SOLDIERTYPE * pSoldier )
{
pSoldier->bSlotItemTakenFrom = bSlot;
SwapObjs( &(pSoldier->inv[HANDPOS]), &(pSoldier->inv[bSlot]) );
SwapObjs( pSoldier, HANDPOS, bSlot );
}
return( pSoldier->bAction );
}
+3 -3
View File
@@ -574,7 +574,7 @@ INT16 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT16 sDesGrid, IN
ubDirChecked[ubDirection] = TRUE;
// determine the gridno 1 tile away from current friend in this direction
sTempDest = NewGridNo(sDesGrid, DirectionInc( ubDirection + 1 ) );
sTempDest = NewGridNo(sDesGrid,DirectionInc( ubDirection ));
// if that's out of bounds, ignore it & check next direction
if (sTempDest == sDesGrid)
@@ -625,8 +625,8 @@ INT16 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT16 sDesGrid, IN
{
// what is the next gridno in the path?
//sTempDest = NewGridNo( sGoToGrid,DirectionInc( (pSoldier->usPathingData[sLoop] + 1) ) );
sTempDest = NewGridNo( sGoToGrid, DirectionInc( pSoldier->usPathingData[sLoop] ) );
//sTempDest = NewGridNo( sGoToGrid,DirectionInc( (INT16) (pSoldier->usPathingData[sLoop] + 1) ) );
sTempDest = NewGridNo( sGoToGrid,DirectionInc( (UINT8) (pSoldier->usPathingData[sLoop]) ) );
//NumMessage("sTempDest = ",sTempDest);
// this should NEVER be out of bounds