Use SoldierID

This commit is contained in:
Asdow
2024-11-30 15:20:18 +02:00
parent d960403514
commit 24656f2810
12 changed files with 113 additions and 118 deletions
+2 -2
View File
@@ -1142,9 +1142,9 @@ void EnemyHeliSAMCheck( INT16 id )
if ( ubBestSAMOperatorID != NOBODY ) if ( ubBestSAMOperatorID != NOBODY )
{ {
if ( fHit ) if ( fHit )
StatChange( MercPtrs[ubBestSAMOperatorID], EXPERAMT, fDestroyed ? 30 : 10, TRUE ); StatChange( ubBestSAMOperatorID, EXPERAMT, fDestroyed ? 30 : 10, TRUE );
StatChange( MercPtrs[ubBestSAMOperatorID], MECHANAMT, 5, TRUE ); StatChange( ubBestSAMOperatorID, MECHANAMT, 5, TRUE );
} }
} }
} }
+4 -4
View File
@@ -2018,7 +2018,7 @@ void GetAPChargeForShootOrStabWRTGunRaises( SOLDIERTYPE *pSoldier, INT32 sGridNo
// Given a gridno here, check if we are on a guy - if so - get his gridno // Given a gridno here, check if we are on a guy - if so - get his gridno
if ( FindSoldier( sGridNo, &usTargID, &uiMercFlags, FIND_SOLDIER_GRIDNO ) ) if ( FindSoldier( sGridNo, &usTargID, &uiMercFlags, FIND_SOLDIER_GRIDNO ) )
{ {
sGridNo = MercPtrs[ usTargID ]->sGridNo; sGridNo = usTargID->sGridNo;
} }
ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier );
@@ -2230,7 +2230,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime,
// Given a gridno here, check if we are on a guy - if so - get his gridno // Given a gridno here, check if we are on a guy - if so - get his gridno
if ( FindSoldier( sGridNo, &usTargID, &uiMercFlags, FIND_SOLDIER_GRIDNO ) ) if ( FindSoldier( sGridNo, &usTargID, &uiMercFlags, FIND_SOLDIER_GRIDNO ) )
{ {
sGridNo = MercPtrs[ usTargID ]->sGridNo; sGridNo = usTargID->sGridNo;
} }
//usRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, sGridNo ); //usRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, sGridNo );
} }
@@ -2473,12 +2473,12 @@ INT16 MinAPsToPunch(SOLDIERTYPE *pSoldier, INT32 sGridNo)
// sevenfm: check enemy only if we have correct gridNo // sevenfm: check enemy only if we have correct gridNo
if( !TileIsOutOfBounds(sGridNo) ) if( !TileIsOutOfBounds(sGridNo) )
{ {
UINT16 usTargID = WhoIsThere2(sGridNo, pSoldier->bTargetLevel); SoldierID usTargID = WhoIsThere2(sGridNo, pSoldier->bTargetLevel);
// Given a gridno here, check if we are on a guy - if so - get his gridno // Given a gridno here, check if we are on a guy - if so - get his gridno
if(usTargID != NOBODY) if(usTargID != NOBODY)
{ {
// Check if target is prone, if so, calc cost... // Check if target is prone, if so, calc cost...
if(gAnimControl[MercPtrs[usTargID]->usAnimState].ubEndHeight == ANIM_PRONE) if(gAnimControl[usTargID->usAnimState].ubEndHeight == ANIM_PRONE)
bAPCost += GetAPsToChangeStance(pSoldier, ANIM_CROUCH); bAPCost += GetAPsToChangeStance(pSoldier, ANIM_CROUCH);
else else
bAPCost += GetAPsToChangeStance(pSoldier, ANIM_STAND); bAPCost += GetAPsToChangeStance(pSoldier, ANIM_STAND);
+8 -8
View File
@@ -190,7 +190,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
static BOOLEAN fValidDoubleClickPossible = FALSE; static BOOLEAN fValidDoubleClickPossible = FALSE;
static BOOLEAN fCanCheckForSpeechAdvance = FALSE; static BOOLEAN fCanCheckForSpeechAdvance = FALSE;
static INT32 sMoveClickGridNo = 0; static INT32 sMoveClickGridNo = 0;
UINT16 usSubjectSoldier = gusSelectedSoldier; SoldierID usSubjectSoldier = gusSelectedSoldier;
// LEFT MOUSE BUTTON // LEFT MOUSE BUTTON
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
@@ -208,7 +208,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
} }
if ( gusSelectedSoldier->flags.uiStatusFlags & SOLDIER_DRIVER ) if ( gusSelectedSoldier->flags.uiStatusFlags & SOLDIER_DRIVER )
{ {
pVehicle = GetSoldierStructureForVehicle( MercPtrs[ usSubjectSoldier ]->iVehicleId ); pVehicle = GetSoldierStructureForVehicle( usSubjectSoldier->iVehicleId );
usSubjectSoldier = pVehicle->ubID; usSubjectSoldier = pVehicle->ubID;
} }
} }
@@ -313,7 +313,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
if ( usSubjectSoldier != NOBODY ) if ( usSubjectSoldier != NOBODY )
{ {
if ( ( fResult = UIOKMoveDestination( MercPtrs[ usSubjectSoldier ], usMapPos ) ) == 1 ) if ( ( fResult = UIOKMoveDestination( usSubjectSoldier, usMapPos ) ) == 1 )
{ {
if ( gsCurrentActionPoints != 0 ) if ( gsCurrentActionPoints != 0 )
{ {
@@ -365,7 +365,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) ) if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) )
{ {
// Select guy // Select guy
if ( (uiMercFlags & SELECTED_MERC) && !( uiMercFlags & UNCONSCIOUS_MERC ) && !( MercPtrs[ usSoldierIndex ]->flags.uiStatusFlags & SOLDIER_VEHICLE ) ) if ( (uiMercFlags & SELECTED_MERC) && !( uiMercFlags & UNCONSCIOUS_MERC ) && !( usSoldierIndex->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
{ {
*puiNewEvent = M_CHANGE_TO_ADJPOS_MODE; *puiNewEvent = M_CHANGE_TO_ADJPOS_MODE;
} }
@@ -451,7 +451,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
//if ( gAnimControl[ gusSelectedSoldier->usAnimState ].uiFlags & ANIM_STATIONARY ) //if ( gAnimControl[ gusSelectedSoldier->usAnimState ].uiFlags & ANIM_STATIONARY )
//if ( gusSelectedSoldier->usAnimState == WALKING ) //if ( gusSelectedSoldier->usAnimState == WALKING )
{ {
MercPtrs[ usSubjectSoldier ]->flags.fUIMovementFast = TRUE; usSubjectSoldier->flags.fUIMovementFast = TRUE;
*puiNewEvent = C_MOVE_MERC; *puiNewEvent = C_MOVE_MERC;
} }
} }
@@ -595,13 +595,13 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
if ( usSubjectSoldier != NOBODY ) if ( usSubjectSoldier != NOBODY )
{ {
if ( MercPtrs[ usSubjectSoldier ]->usAnimState != RUNNING ) if ( usSubjectSoldier->usAnimState != RUNNING )
{ {
*puiNewEvent = C_MOVE_MERC; *puiNewEvent = C_MOVE_MERC;
} }
else else
{ {
MercPtrs[ usSubjectSoldier ]->flags.fUIMovementFast = 2; usSubjectSoldier->flags.fUIMovementFast = 2;
*puiNewEvent = C_MOVE_MERC; *puiNewEvent = C_MOVE_MERC;
} }
} }
@@ -792,7 +792,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
if ( usSubjectSoldier != NOBODY ) if ( usSubjectSoldier != NOBODY )
{ {
if ( ( fResult = UIOKMoveDestination( MercPtrs[ usSubjectSoldier ], usMapPos ) ) == 1 ) if ( ( fResult = UIOKMoveDestination( usSubjectSoldier, usMapPos ) ) == 1 )
{ {
if ( gfUIAllMoveOn ) if ( gfUIAllMoveOn )
{ {
+1 -1
View File
@@ -2924,7 +2924,7 @@ void CreateZombiefromCorpse( ROTTING_CORPSE * pCorpse, UINT16 usAnimState )
/* certain values have to be set afterwards - the alternative would be to edit each and every function that gets called from TacticalCreateSoldier() subsequently and /* certain values have to be set afterwards - the alternative would be to edit each and every function that gets called from TacticalCreateSoldier() subsequently and
* make an exception for zombies every time... * make an exception for zombies every time...
*/ */
SOLDIERTYPE* pNewSoldier = MercPtrs[ iNewIndex ]; SOLDIERTYPE* pNewSoldier = iNewIndex;
pNewSoldier->bActionPoints = 60; pNewSoldier->bActionPoints = 60;
pNewSoldier->bInitialActionPoints = 60; pNewSoldier->bInitialActionPoints = 60;
+1 -1
View File
@@ -6625,7 +6625,7 @@ BOOLEAN CanMercInteractWithSelectedShopkeeper( SOLDIERTYPE *pSoldier )
Assert( gbSelectedArmsDealerID != -1 ); Assert( gbSelectedArmsDealerID != -1 );
if ( gusIDOfCivTrader != NOBODY ) if ( gusIDOfCivTrader != NOBODY )
pShopkeeper = MercPtrs[gusIDOfCivTrader]; pShopkeeper = gusIDOfCivTrader;
else else
pShopkeeper = FindSoldierByProfileID( armsDealerInfo[gbSelectedArmsDealerID].ubShopKeeperID, FALSE ); pShopkeeper = FindSoldierByProfileID( armsDealerInfo[gbSelectedArmsDealerID].ubShopKeeperID, FALSE );
+8 -8
View File
@@ -3299,17 +3299,17 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
// REFUELING A VEHICLE // REFUELING A VEHICLE
// THE GAS_CAN IS IN THE MERCS MAIN HAND AT THIS TIME // THE GAS_CAN IS IN THE MERCS MAIN HAND AT THIS TIME
{ {
UINT16 ubPerson;
SOLDIERTYPE *pVehicle;
// Get pointer to vehicle... // Get pointer to vehicle...
ubPerson = WhoIsThere2( pSoldier->aiData.sPendingActionData2, pSoldier->pathing.bLevel ); SoldierID ubPerson = WhoIsThere2( pSoldier->aiData.sPendingActionData2, pSoldier->pathing.bLevel );
pVehicle = MercPtrs[ ubPerson ]; if ( ubPerson != NOBODY )
{
SOLDIERTYPE *pVehicle = ubPerson;
// this is a ubID for soldiertype.... // this is a ubID for soldiertype....
AddFuelToVehicle( pSoldier, pVehicle ); AddFuelToVehicle( pSoldier, pVehicle );
fInterfacePanelDirty = DIRTYLEVEL2; fInterfacePanelDirty = DIRTYLEVEL2;
}
} }
break; break;
+2 -2
View File
@@ -1496,7 +1496,7 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
} }
BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, UINT16 ubOpponentID, INT8 bOldOppList) BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, SoldierID ubOpponentID, INT8 bOldOppList)
{ {
DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"StandardInterruptConditionsMet"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"StandardInterruptConditionsMet");
// UINT8 ubAniType; // UINT8 ubAniType;
@@ -1540,7 +1540,7 @@ BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, UINT16 ubOpponen
return(FALSE); return(FALSE);
} }
pOpponent = MercPtrs[ ubOpponentID ]; pOpponent = ubOpponentID;
} }
else // no opponent, so controller of 'ptr' makes the call instead else // no opponent, so controller of 'ptr' makes the call instead
{ {
+1 -1
View File
@@ -10,7 +10,7 @@ extern BOOLEAN gfHiddenTurnbased;
#define INTERRUPT_QUEUED (gubOutOfTurnPersons > 0) #define INTERRUPT_QUEUED (gubOutOfTurnPersons > 0)
extern BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, UINT16 ubOpponentID, INT8 bOldOppList); extern BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, SoldierID ubOpponentID, INT8 bOldOppList);
extern INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, SoldierID ubOpponentID, BOOLEAN fUseWatchSpots ); extern INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, SoldierID ubOpponentID, BOOLEAN fUseWatchSpots );
extern void EndAITurn( void ); extern void EndAITurn( void );
extern void DisplayHiddenInterrupt( SOLDIERTYPE * pSoldier ); extern void DisplayHiddenInterrupt( SOLDIERTYPE * pSoldier );
+11 -11
View File
@@ -7233,12 +7233,12 @@ void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection )
if ( gpCurrentTalkingFace != NULL ) if ( gpCurrentTalkingFace != NULL )
return; return;
UINT16 ubSourceMerc = gusSelectedSoldier; SoldierID ubSourceMerc = gusSelectedSoldier;
UINT16 ubTargetMerc; SoldierID ubTargetMerc;
INT32 iSourceFace; INT32 iSourceFace;
INT32 iTargetFace; INT32 iTargetFace;
UINT8 ubGroupID = pSoldier->ubGroupID; UINT8 ubGroupID = pSoldier->ubGroupID;
INT8 bOldPosition = GetTeamSlotFromPlayerID ( MercPtrs[ ubSourceMerc ]->ubID ); INT8 bOldPosition = GetTeamSlotFromPlayerID ( ubSourceMerc );
INT8 bNewPosition = bOldPosition + bDirection; INT8 bNewPosition = bOldPosition + bDirection;
SOLDIERTYPE TempMenptr = Menptr[ ubSourceMerc ]; SOLDIERTYPE TempMenptr = Menptr[ ubSourceMerc ];
@@ -7266,15 +7266,15 @@ void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection )
ubTargetMerc = gTeamPanel[ bNewPosition ].ubID; ubTargetMerc = gTeamPanel[ bNewPosition ].ubID;
// Hey, you're dead. I don't want to swap with you. // Hey, you're dead. I don't want to swap with you.
if ( MercPtrs[ubTargetMerc]->stats.bLife <= 0 ) if ( ubTargetMerc->stats.bLife <= 0 )
{ {
RebuildCurrentSquad( ); RebuildCurrentSquad( );
return; return;
} }
// store face indexes // store face indexes
iSourceFace = MercPtrs[ ubSourceMerc ]->iFaceIndex; iSourceFace = ubSourceMerc->iFaceIndex;
iTargetFace = MercPtrs[ ubTargetMerc ]->iFaceIndex; iTargetFace = ubTargetMerc->iFaceIndex;
FACETYPE TempFace = gFacesData[ iSourceFace ]; FACETYPE TempFace = gFacesData[ iSourceFace ];
// swap the data // swap the data
@@ -7299,11 +7299,11 @@ void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection )
Menptr[ ubTargetMerc ].iFaceIndex = iTargetFace; Menptr[ ubTargetMerc ].iFaceIndex = iTargetFace;
// update group info // update group info
RemovePlayerFromGroup( ubGroupID, MercPtrs[ ubSourceMerc ] ); RemovePlayerFromGroup( ubGroupID, ubSourceMerc );
RemovePlayerFromGroup( ubGroupID, MercPtrs[ ubTargetMerc ] ); RemovePlayerFromGroup( ubGroupID, ubTargetMerc );
AddPlayerToGroup( ubGroupID, MercPtrs[ ubSourceMerc ] ); AddPlayerToGroup( ubGroupID, ubSourceMerc );
AddPlayerToGroup( ubGroupID, MercPtrs[ ubTargetMerc ] ); AddPlayerToGroup( ubGroupID, ubTargetMerc );
SortSquadByID( MercPtrs[ ubSourceMerc ]->bAssignment ); SortSquadByID( ubSourceMerc->bAssignment );
RebuildCurrentSquad( ); RebuildCurrentSquad( );
// don't forget to renew selection of merc // don't forget to renew selection of merc
+7 -7
View File
@@ -1378,7 +1378,7 @@ INT32 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, BOOLEAN * pfChangeLevel
} }
INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, UINT16 * pubOpponentID) INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, SoldierID * pubOpponentID)
{ {
INT32 *psLastLoc,sGridNo, sClosestOpponent = NOWHERE; INT32 *psLastLoc,sGridNo, sClosestOpponent = NOWHERE;
UINT32 uiLoop; UINT32 uiLoop;
@@ -3445,9 +3445,9 @@ INT32 CalcStraightThreatValue( SOLDIERTYPE *pEnemy )
} }
// Flugente: get the id of the closest soldier with a specific flag that we can currently see // Flugente: get the id of the closest soldier with a specific flag that we can currently see
UINT16 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag, BOOLEAN fCheckSight ) SoldierID GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag, BOOLEAN fCheckSight )
{ {
UINT16 id = NOBODY; SoldierID id = NOBODY;
UINT32 uiLoop; UINT32 uiLoop;
SOLDIERTYPE * pFriend; SOLDIERTYPE * pFriend;
INT16 range = aRange; INT16 range = aRange;
@@ -3498,9 +3498,9 @@ UINT16 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 a
} }
// get the id of the closest soldier (closer than x tiles) of a specific team that is wounded that we can currently see // get the id of the closest soldier (closer than x tiles) of a specific team that is wounded that we can currently see
UINT16 GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam ) SoldierID GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam )
{ {
UINT16 id = NOBODY; SoldierID id = NOBODY;
UINT32 uiLoop; UINT32 uiLoop;
SOLDIERTYPE * pFriend; SOLDIERTYPE * pFriend;
INT16 range = aRange; INT16 range = aRange;
@@ -3547,9 +3547,9 @@ UINT16 GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 a
} }
// get the id of the closest medic (closer than x tiles) of a specific team // get the id of the closest medic (closer than x tiles) of a specific team
UINT16 GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam ) SoldierID GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam )
{ {
UINT16 id = NOBODY; SoldierID id = NOBODY;
UINT32 uiLoop; UINT32 uiLoop;
SOLDIERTYPE * pFriend; SOLDIERTYPE * pFriend;
INT16 range = aRange; INT16 range = aRange;
+64 -69
View File
@@ -933,7 +933,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
// Flugente: if we see one of our buddies in handcuffs, its a clear sign of enemy activity! // Flugente: if we see one of our buddies in handcuffs, its a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM && !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition ) if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM && !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition )
{ {
UINT16 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE ); SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
@@ -945,7 +945,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
// if we are a doctor with medical gear, we might be able to help a wounded ally // if we are a doctor with medical gear, we might be able to help a wounded ally
if ( pSoldier->CanMedicAI() ) if ( pSoldier->CanMedicAI() )
{ {
UINT16 ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam); SoldierID ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
// are we ourselves the patient? // are we ourselves the patient?
if ( ubPerson == pSoldier->ubID ) if ( ubPerson == pSoldier->ubID )
@@ -962,10 +962,10 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
} }
else if ( ubPerson != NOBODY ) else if ( ubPerson != NOBODY )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) < 2 )
{ {
// see if we are facing this person // see if we are facing this person
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo); UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction, // if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir ) if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -987,7 +987,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
} }
else else
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -999,13 +999,13 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
// if we are not a medic, but are wounded, seek a medic // if we are not a medic, but are wounded, seek a medic
else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount ) else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount )
{ {
UINT16 ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam); SoldierID ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) > 1 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) > 1 )
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -1019,14 +1019,14 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD ) if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD )
{ {
// is VIP still alive? // is VIP still alive?
UINT16 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 100, pSoldier->bTeam, SOLDIER_VIP, FALSE ); SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 100, pSoldier->bTeam, SOLDIER_VIP, FALSE );
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
// we want to stay close to him, but still be able to function properly... stay withing a 7-tile radius // we want to stay close to him, but still be able to function properly... stay withing a 7-tile radius
if ( SpacesAway( pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo ) > 7 ) if ( SpacesAway( pSoldier->sGridNo, ubPerson->sGridNo ) > 7 )
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards( pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0 ); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards( pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0 );
if ( !TileIsOutOfBounds( pSoldier->aiData.usActionData ) ) if ( !TileIsOutOfBounds( pSoldier->aiData.usActionData ) )
{ {
@@ -1655,18 +1655,18 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
// Flugente: if we see one of our buddies captured, it is a clear sign of enemy activity! // Flugente: if we see one of our buddies captured, it is a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM ) if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
{ {
UINT16 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE ); SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
// if we are close, we can release this guy // if we are close, we can release this guy
// possible only if not handcuffed (binders can be opened, handcuffs not) // possible only if not handcuffed (binders can be opened, handcuffs not)
if ( !HasItemFlag( (&(MercPtrs[ubPerson]->inv[HANDPOS]))->usItem, HANDCUFFS ) ) if ( !HasItemFlag( (&(ubPerson->inv[HANDPOS]))->usItem, HANDCUFFS ) )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) < 2 )
{ {
// see if we are facing this person // see if we are facing this person
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo); UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction, // if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir ) if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -1680,7 +1680,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
} }
else else
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -1699,7 +1699,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
// if we are a doctor with medical gear, we might be able to help a wounded ally // if we are a doctor with medical gear, we might be able to help a wounded ally
if ( pSoldier->CanMedicAI() ) if ( pSoldier->CanMedicAI() )
{ {
UINT16 ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam); SoldierID ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
// are we ourselves the patient? // are we ourselves the patient?
if ( ubPerson == pSoldier->ubID ) if ( ubPerson == pSoldier->ubID )
@@ -1716,10 +1716,10 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
} }
else if ( ubPerson != NOBODY ) else if ( ubPerson != NOBODY )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) < 2 )
{ {
// see if we are facing this person // see if we are facing this person
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo); UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction, // if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir ) if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -1741,7 +1741,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
} }
else else
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -1753,13 +1753,13 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
// if we are not a medic, but are wounded, seek a medic // if we are not a medic, but are wounded, seek a medic
else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount ) else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount )
{ {
UINT16 ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam); SoldierID ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) > 1 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) > 1 )
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -1773,14 +1773,14 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD ) if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD )
{ {
// is VIP still alive? // is VIP still alive?
UINT16 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 100, pSoldier->bTeam, SOLDIER_VIP, FALSE ); SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 100, pSoldier->bTeam, SOLDIER_VIP, FALSE );
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
// we want to stay close to him, but still be able to function properly... stay withing a 7-tile radius // we want to stay close to him, but still be able to function properly... stay withing a 7-tile radius
if ( SpacesAway( pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo ) > 7 ) if ( SpacesAway( pSoldier->sGridNo, ubPerson->sGridNo ) > 7 )
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards( pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0 ); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards( pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0 );
if ( !TileIsOutOfBounds( pSoldier->aiData.usActionData ) ) if ( !TileIsOutOfBounds( pSoldier->aiData.usActionData ) )
{ {
@@ -2883,10 +2883,10 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
DebugAI(AI_MSG_INFO, pSoldier, String("prepare throw at spot %d level %d aimtime %d", BestThrow.sTarget, BestThrow.bTargetLevel, BestThrow.ubAimTime)); DebugAI(AI_MSG_INFO, pSoldier, String("prepare throw at spot %d level %d aimtime %d", BestThrow.sTarget, BestThrow.bTargetLevel, BestThrow.ubAimTime));
// start retreating for several turns // start retreating for several turns
if (BestThrow.ubOpponent != NOBODY && !MercPtrs[BestThrow.ubOpponent]->IsFlanking()) if (BestThrow.ubOpponent != NOBODY && !BestThrow.ubOpponent->IsFlanking())
{ {
DebugAI(AI_MSG_INFO, pSoldier, String("start retreat counter for %d", BestThrow.ubOpponent)); DebugAI(AI_MSG_INFO, pSoldier, String("start retreat counter for %d", BestThrow.ubOpponent));
MercPtrs[BestThrow.ubOpponent]->RetreatCounterStart(2); BestThrow.ubOpponent->RetreatCounterStart(2);
} }
// if necessary, swap the usItem from holster into the hand position // if necessary, swap the usItem from holster into the hand position
@@ -3028,8 +3028,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
// check valid target // check valid target
!TileIsOutOfBounds(BestShot.sTarget) && !TileIsOutOfBounds(BestShot.sTarget) &&
BestShot.ubOpponent != NOBODY && BestShot.ubOpponent != NOBODY &&
MercPtrs[BestShot.ubOpponent] && Chance(100 - BestShot.ubOpponent->ShockLevelPercent() / 2) &&
Chance(100 - MercPtrs[BestShot.ubOpponent]->ShockLevelPercent() / 2) &&
// check weapon/ammo requirements // check weapon/ammo requirements
IsGunAutofireCapable(&pSoldier->inv[BestShot.bWeaponIn]) && IsGunAutofireCapable(&pSoldier->inv[BestShot.bWeaponIn]) &&
GetMagSize(&pSoldier->inv[BestShot.bWeaponIn]) >= gGameExternalOptions.ubAISuppressionMinimumMagSize && GetMagSize(&pSoldier->inv[BestShot.bWeaponIn]) >= gGameExternalOptions.ubAISuppressionMinimumMagSize &&
@@ -3046,16 +3045,16 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
!fCanBeSeen && NightLight() && CountFriendsFlankSameSpot(pSoldier, sClosestOpponent) && Chance(50) || !fCanBeSeen && NightLight() && CountFriendsFlankSameSpot(pSoldier, sClosestOpponent) && Chance(50) ||
ARMED_VEHICLE(pSoldier) || // tanks don't need cover ARMED_VEHICLE(pSoldier) || // tanks don't need cover
ENEMYROBOT(pSoldier) || // robots don't try to be in cover ENEMYROBOT(pSoldier) || // robots don't try to be in cover
pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || MercPtrs[BestShot.ubOpponent]->sLastTarget == pSoldier->sGridNo) || // return fire pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || BestShot.ubOpponent->sLastTarget == pSoldier->sGridNo) || // return fire
Chance((BestShot.ubChanceToReallyHit + 100) / 2) || // 50% chance to fire without cover Chance((BestShot.ubChanceToReallyHit + 100) / 2) || // 50% chance to fire without cover
//SoldierToSoldierLineOfSightTest(pSoldier, MercPtrs[BestShot.ubOpponent], TRUE, CALC_FROM_ALL_DIRS)) && // can see target after turning //SoldierToSoldierLineOfSightTest(pSoldier, BestShot.ubOpponent, TRUE, CALC_FROM_ALL_DIRS)) && // can see target after turning
LOS_Raised(pSoldier, MercPtrs[BestShot.ubOpponent], CALC_FROM_ALL_DIRS)) && // can see target after turning LOS_Raised(pSoldier, BestShot.ubOpponent, CALC_FROM_ALL_DIRS)) && // can see target after turning
// reduce chance to shoot if target is beyond weapon range // reduce chance to shoot if target is beyond weapon range
(AICheckIsMachinegunner(pSoldier) || (AICheckIsMachinegunner(pSoldier) ||
ARMED_VEHICLE(pSoldier) || ARMED_VEHICLE(pSoldier) ||
ENEMYROBOT(pSoldier) || ENEMYROBOT(pSoldier) ||
AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) ||
pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || MercPtrs[BestShot.ubOpponent]->sLastTarget == pSoldier->sGridNo) || // return fire pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || BestShot.ubOpponent->sLastTarget == pSoldier->sGridNo) || // return fire
Chance(100 * (GunRange(&pSoldier->inv[BestShot.bWeaponIn], pSoldier) / CELL_X_SIZE) / PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget))) && Chance(100 * (GunRange(&pSoldier->inv[BestShot.bWeaponIn], pSoldier) / CELL_X_SIZE) / PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget))) &&
// check that we have spare ammo // check that we have spare ammo
(fExtraClip || pSoldier->inv[BestShot.bWeaponIn][0]->data.gun.ubGunShotsLeft >= gGameExternalOptions.ubAISuppressionMinimumMagSize)) (fExtraClip || pSoldier->inv[BestShot.bWeaponIn][0]->data.gun.ubGunShotsLeft >= gGameExternalOptions.ubAISuppressionMinimumMagSize))
@@ -3149,7 +3148,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
DebugAI(AI_MSG_INFO, pSoldier, String("Change stance before shooting")); DebugAI(AI_MSG_INFO, pSoldier, String("Change stance before shooting"));
// show "suppression fire" message only if opponent cannot be seen after turning // show "suppression fire" message only if opponent cannot be seen after turning
if (!LOS_Raised(pSoldier, MercPtrs[BestShot.ubOpponent], CALC_FROM_ALL_DIRS)) if (!LOS_Raised(pSoldier, BestShot.ubOpponent, CALC_FROM_ALL_DIRS))
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_SUPPRESSIONFIRE]); ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_SUPPRESSIONFIRE]);
return(AI_ACTION_CHANGE_STANCE); return(AI_ACTION_CHANGE_STANCE);
@@ -3159,7 +3158,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
pSoldier->aiData.usActionData = BestShot.sTarget; pSoldier->aiData.usActionData = BestShot.sTarget;
// show "suppression fire" message only if opponent cannot be seen after turning // show "suppression fire" message only if opponent cannot be seen after turning
if (!LOS_Raised(pSoldier, MercPtrs[BestShot.ubOpponent], CALC_FROM_ALL_DIRS)) if (!LOS_Raised(pSoldier, BestShot.ubOpponent, CALC_FROM_ALL_DIRS))
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_SUPPRESSIONFIRE]); ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_SUPPRESSIONFIRE]);
return(AI_ACTION_FIRE_GUN); return(AI_ACTION_FIRE_GUN);
@@ -3281,18 +3280,18 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
// Flugente: if we see one of our buddies captured, it is a clear sign of enemy activity! // Flugente: if we see one of our buddies captured, it is a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM ) if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
{ {
UINT16 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE ); SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
// if we are close, we can release this guy // if we are close, we can release this guy
// possible only if not handcuffed (binders can be opened, handcuffs not) // possible only if not handcuffed (binders can be opened, handcuffs not)
if ( !HasItemFlag( (&(MercPtrs[ubPerson]->inv[HANDPOS]))->usItem, HANDCUFFS ) ) if ( !HasItemFlag( (&(ubPerson->inv[HANDPOS]))->usItem, HANDCUFFS ) )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) < 2 )
{ {
// see if we are facing this person // see if we are facing this person
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo); UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction, // if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir ) if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -3306,7 +3305,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
} }
else else
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -3320,7 +3319,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
// if we are a doctor with medical gear, we might be able to help a wounded ally // if we are a doctor with medical gear, we might be able to help a wounded ally
if ( pSoldier->CanMedicAI() ) if ( pSoldier->CanMedicAI() )
{ {
UINT16 ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam); SoldierID ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
// are we ourselves the patient? // are we ourselves the patient?
if ( ubPerson == pSoldier->ubID ) if ( ubPerson == pSoldier->ubID )
@@ -3337,10 +3336,10 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
} }
else if ( ubPerson != NOBODY ) else if ( ubPerson != NOBODY )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) < 2 )
{ {
// see if we are facing this person // see if we are facing this person
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo); UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction, // if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir ) if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -3362,7 +3361,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
} }
else else
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -3374,13 +3373,13 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
// if we are not a medic, but are wounded, seek a medic // if we are not a medic, but are wounded, seek a medic
else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount ) else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount )
{ {
UINT16 ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam); SoldierID ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) > 1 ) if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) > 1 )
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData)) if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{ {
@@ -3413,14 +3412,14 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD ) if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD )
{ {
// is VIP still alive? // is VIP still alive?
UINT16 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 100, pSoldier->bTeam, SOLDIER_VIP, FALSE ); SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 100, pSoldier->bTeam, SOLDIER_VIP, FALSE );
if ( ubPerson != NOBODY ) if ( ubPerson != NOBODY )
{ {
// we want to stay close to him, but still be able to function properly... stay withing a 7-tile radius // we want to stay close to him, but still be able to function properly... stay withing a 7-tile radius
if ( SpacesAway( pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo ) > 7 ) if ( SpacesAway( pSoldier->sGridNo, ubPerson->sGridNo ) > 7 )
{ {
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards( pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0 ); pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards( pSoldier, ubPerson->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0 );
if ( !TileIsOutOfBounds( pSoldier->aiData.usActionData ) ) if ( !TileIsOutOfBounds( pSoldier->aiData.usActionData ) )
{ {
@@ -5764,10 +5763,9 @@ INT16 ubMinAPCost;
(pSoldier->flags.uiStatusFlags & SOLDIER_BOXER) && (pSoldier->flags.uiStatusFlags & SOLDIER_BOXER) &&
SpacesAway(pSoldier->sGridNo, BestStab.sTarget) > 2 && SpacesAway(pSoldier->sGridNo, BestStab.sTarget) > 2 &&
BestStab.ubOpponent != NOBODY && BestStab.ubOpponent != NOBODY &&
MercPtrs[BestStab.ubOpponent] && AIDirection(pSoldier->sGridNo, BestStab.ubOpponent->sGridNo) != BestStab.ubOpponent->ubDirection &&
AIDirection(pSoldier->sGridNo, MercPtrs[BestStab.ubOpponent]->sGridNo) != MercPtrs[BestStab.ubOpponent]->ubDirection && AIDirection(pSoldier->sGridNo, BestStab.ubOpponent->sGridNo) != gOneCDirection[BestStab.ubOpponent->ubDirection] &&
AIDirection(pSoldier->sGridNo, MercPtrs[BestStab.ubOpponent]->sGridNo) != gOneCDirection[MercPtrs[BestStab.ubOpponent]->ubDirection] && AIDirection(pSoldier->sGridNo, BestStab.ubOpponent->sGridNo) != gOneCCDirection[BestStab.ubOpponent->ubDirection] &&
AIDirection(pSoldier->sGridNo, MercPtrs[BestStab.ubOpponent]->sGridNo) != gOneCCDirection[MercPtrs[BestStab.ubOpponent]->ubDirection] &&
pSoldier->bInitialActionPoints >= 2 * MinAPsToAttack(pSoldier, pSoldier->sLastTarget, FALSE, 0, 0) + APBPConstants[AP_MOVEMENT_FLAT] + APBPConstants[AP_MODIFIER_WALK] && pSoldier->bInitialActionPoints >= 2 * MinAPsToAttack(pSoldier, pSoldier->sLastTarget, FALSE, 0, 0) + APBPConstants[AP_MOVEMENT_FLAT] + APBPConstants[AP_MODIFIER_WALK] &&
pSoldier->bActionPoints < BestStab.ubAPCost + MinAPsToAttack(pSoldier, pSoldier->sLastTarget, FALSE, 0, 0)) pSoldier->bActionPoints < BestStab.ubAPCost + MinAPsToAttack(pSoldier, pSoldier->sLastTarget, FALSE, 0, 0))
{ {
@@ -5781,10 +5779,9 @@ INT16 ubMinAPCost;
(pSoldier->flags.uiStatusFlags & SOLDIER_BOXER) && (pSoldier->flags.uiStatusFlags & SOLDIER_BOXER) &&
SpacesAway(pSoldier->sGridNo, BestStab.sTarget) > 1 && SpacesAway(pSoldier->sGridNo, BestStab.sTarget) > 1 &&
BestStab.ubOpponent != NOBODY && BestStab.ubOpponent != NOBODY &&
MercPtrs[BestStab.ubOpponent] && gAnimControl[BestStab.ubOpponent->usAnimState].ubEndHeight == ANIM_STAND &&
gAnimControl[MercPtrs[BestStab.ubOpponent]->usAnimState].ubEndHeight == ANIM_STAND && BestStab.ubOpponent->bActionPoints > 0 &&
MercPtrs[BestStab.ubOpponent]->bActionPoints > 0 && Chance(EffectiveAgility(BestStab.ubOpponent, FALSE) * (100 + BestStab.ubOpponent->bBreath) * EffectiveWisdom(pSoldier) / (100 * 200)))
Chance(EffectiveAgility(MercPtrs[BestStab.ubOpponent], FALSE) * (100 + MercPtrs[BestStab.ubOpponent]->bBreath) * EffectiveWisdom(pSoldier) / (100 * 200)))
{ {
// find closest spot around opponent, avoid front direction // find closest spot around opponent, avoid front direction
UINT8 ubMovementCost; UINT8 ubMovementCost;
@@ -5804,7 +5801,7 @@ INT16 ubMinAPCost;
if (ubMovementCost < TRAVELCOST_BLOCKED && if (ubMovementCost < TRAVELCOST_BLOCKED &&
NewOKDestination(pSoldier, sTempGridNo, FALSE, pSoldier->pathing.bLevel) && NewOKDestination(pSoldier, sTempGridNo, FALSE, pSoldier->pathing.bLevel) &&
AIDirection(BestStab.sTarget, sTempGridNo) != MercPtrs[BestStab.ubOpponent]->ubDirection) AIDirection(BestStab.sTarget, sTempGridNo) != BestStab.ubOpponent->ubDirection)
{ {
sPathCost = PlotPath(pSoldier, sTempGridNo, FALSE, FALSE, FALSE, DetermineMovementMode(pSoldier, AI_ACTION_GET_CLOSER), pSoldier->bStealthMode, pSoldier->bReverse, 0); sPathCost = PlotPath(pSoldier, sTempGridNo, FALSE, FALSE, FALSE, DetermineMovementMode(pSoldier, AI_ACTION_GET_CLOSER), pSoldier->bStealthMode, pSoldier->bReverse, 0);
if (TileIsOutOfBounds(sBestSpot) || sPathCost < sBestPathCost) if (TileIsOutOfBounds(sBestSpot) || sPathCost < sBestPathCost)
@@ -5842,7 +5839,7 @@ INT16 ubMinAPCost;
// SANDRO - added a chance to try to steal merc's gun from hands // SANDRO - added a chance to try to steal merc's gun from hands
else else
{ {
if (AIDetermineStealingWeaponAttempt( pSoldier, MercPtrs[BestStab.ubOpponent] ) == TRUE) if (AIDetermineStealingWeaponAttempt( pSoldier, BestStab.ubOpponent ) == TRUE)
{ {
ubBestAttackAction = AI_ACTION_STEAL_MOVE; ubBestAttackAction = AI_ACTION_STEAL_MOVE;
DebugAI(AI_MSG_INFO, pSoldier, String("best action = move to steal weapon, iAttackValue = %d", BestStab.iAttackValue)); DebugAI(AI_MSG_INFO, pSoldier, String("best action = move to steal weapon, iAttackValue = %d", BestStab.iAttackValue));
@@ -6832,13 +6829,11 @@ L_NEWAIM:
{ {
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Make boxer close if possible]")); DebugAI(AI_MSG_TOPIC, pSoldier, String("[Make boxer close if possible]"));
UINT16 ubOpponentID; SoldierID ubOpponentID;
sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL, &ubOpponentID); sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL, &ubOpponentID);
DebugAI(AI_MSG_INFO, pSoldier, String("boxer: found closest opponent [%d] at %d", ubOpponentID, sClosestOpponent)); DebugAI(AI_MSG_INFO, pSoldier, String("boxer: found closest opponent [%d] at %d", ubOpponentID, sClosestOpponent));
if (!TileIsOutOfBounds(sClosestOpponent) && if ( !TileIsOutOfBounds(sClosestOpponent) && ubOpponentID != NOBODY )
ubOpponentID != NOBODY &&
MercPtrs[ubOpponentID])
{ {
if (pSoldier->bActionPoints > 0) if (pSoldier->bActionPoints > 0)
{ {
@@ -6875,7 +6870,7 @@ L_NEWAIM:
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData) && if (!TileIsOutOfBounds(pSoldier->aiData.usActionData) &&
(pSoldier->bBreath < OKBREATH || (pSoldier->bBreath < OKBREATH ||
pSoldier->bBreath < pSoldier->bBreathMax && pSoldier->bBreath < pSoldier->bBreathMax &&
pSoldier->bBreath < MercPtrs[ubOpponentID]->bBreath && pSoldier->bBreath < ubOpponentID->bBreath &&
Chance((100 - pSoldier->bBreath) * (100 - pSoldier->bBreath) / (2 * 100 * 100)))) Chance((100 - pSoldier->bBreath) * (100 - pSoldier->bBreath) / (2 * 100 * 100))))
{ {
DebugAI(AI_MSG_INFO, pSoldier, String("boxer: restore breath")); DebugAI(AI_MSG_INFO, pSoldier, String("boxer: restore breath"));
@@ -6899,7 +6894,7 @@ L_NEWAIM:
} }
else if (pSoldier->bBreath < OKBREATH || else if (pSoldier->bBreath < OKBREATH ||
pSoldier->bBreath < pSoldier->bBreathMax && pSoldier->bBreath < pSoldier->bBreathMax &&
(pSoldier->bBreath < MercPtrs[ubOpponentID]->bBreath || !pSoldier->aiData.bLastAttackHit && pSoldier->TakenLargeHit())) (pSoldier->bBreath < ubOpponentID->bBreath || !pSoldier->aiData.bLastAttackHit && pSoldier->TakenLargeHit()))
{ {
// maybe move away from opponent // maybe move away from opponent
UINT8 ubOpponentDir = AIDirection(pSoldier->sGridNo, sClosestOpponent); UINT8 ubOpponentDir = AIDirection(pSoldier->sGridNo, sClosestOpponent);
@@ -8579,9 +8574,9 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
//&& Menptr[BestShot.ubOpponent].pathing.bLevel == 0 //&& Menptr[BestShot.ubOpponent].pathing.bLevel == 0
&& pSoldier->aiData.bOrders != SNIPER && && pSoldier->aiData.bOrders != SNIPER &&
BestShot.ubFriendlyFireChance < 5 && BestShot.ubFriendlyFireChance < 5 &&
!MercPtrs[BestShot.ubOpponent]->IsCowering() && !BestShot.ubOpponent->IsCowering() &&
!AICheckIsFlanking( pSoldier ) && !AICheckIsFlanking( pSoldier ) &&
LocationToLocationLineOfSightTest( pSoldier->sGridNo, pSoldier->pathing.bLevel, MercPtrs[BestShot.ubOpponent]->sGridNo, MercPtrs[BestShot.ubOpponent]->pathing.bLevel, TRUE, NO_DISTANCE_LIMIT ) && LocationToLocationLineOfSightTest( pSoldier->sGridNo, pSoldier->pathing.bLevel, BestShot.ubOpponent->sGridNo, BestShot.ubOpponent->pathing.bLevel, TRUE, NO_DISTANCE_LIMIT ) &&
//Weapon[pSoldier->inv[BestShot.bWeaponIn].usItem].ubWeaponType == GUN_LMG ) && //Weapon[usInHand].ubWeaponClass == MGCLASS //Weapon[pSoldier->inv[BestShot.bWeaponIn].usItem].ubWeaponType == GUN_LMG ) && //Weapon[usInHand].ubWeaponClass == MGCLASS
(fExtraClip || pSoldier->inv[BestShot.bWeaponIn][0]->data.gun.ubGunShotsLeft > gGameExternalOptions.ubAISuppressionMinimumMagSize) ) (fExtraClip || pSoldier->inv[BestShot.bWeaponIn][0]->data.gun.ubGunShotsLeft > gGameExternalOptions.ubAISuppressionMinimumMagSize) )
{ {
+4 -4
View File
@@ -175,7 +175,7 @@ void CheckForChangingOrders(SOLDIERTYPE *pSoldier );
INT8 ClosestPanicTrigger( SOLDIERTYPE * pSoldier ); INT8 ClosestPanicTrigger( SOLDIERTYPE * pSoldier );
INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, UINT16 * pubOpponentID = NULL); INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, SoldierID *pubOpponentID = NULL);
INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance );
INT32 ClosestUnDisguisedPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); // Flugente: like ClosestPC(...), but does not account for covert or not visible mercs INT32 ClosestUnDisguisedPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); // Flugente: like ClosestPC(...), but does not account for covert or not visible mercs
BOOLEAN CanAutoBandage( BOOLEAN fDoFullCheck ); BOOLEAN CanAutoBandage( BOOLEAN fDoFullCheck );
@@ -277,13 +277,13 @@ INT8 CalcAverageCTGTForPosition( SOLDIERTYPE * pSoldier, SoldierID ubOppID, INT3
UINT8 NumberOfTeamMatesAdjacent( SOLDIERTYPE * pSoldier, INT32 sGridNo ); UINT8 NumberOfTeamMatesAdjacent( SOLDIERTYPE * pSoldier, INT32 sGridNo );
// Flugente: get the id of the closest soldier (coser than x tiles) of a specific team with a specific flag that we can currently see // Flugente: get the id of the closest soldier (coser than x tiles) of a specific team with a specific flag that we can currently see
UINT16 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag, BOOLEAN fCheckSight = TRUE ); SoldierID GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag, BOOLEAN fCheckSight = TRUE );
// get the id of the closest soldier (closer than x tiles) of a specific team that is wounded that we can currently see // get the id of the closest soldier (closer than x tiles) of a specific team that is wounded that we can currently see
UINT16 GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam ); SoldierID GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam );
// get the id of the closest medic (closer than x tiles) of a specific team // get the id of the closest medic (closer than x tiles) of a specific team
UINT16 GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam ); SoldierID GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam );
// sevenfm: // sevenfm:
BOOLEAN NightLight(void); BOOLEAN NightLight(void);