Merge branch 'master' into decideaction

This commit is contained in:
Asdow
2025-12-25 18:58:41 +02:00
853 changed files with 134439 additions and 148932 deletions
+130 -125
View File
@@ -1,32 +1,32 @@
#include "ai.h"
#include "AIInternals.h"
#include "Isometric utils.h"
#include "Isometric Utils.h"
#include "Points.h"
#include "overhead.h"
#include "Overhead.h"
#include "opplist.h"
#include "items.h"
#include "Items.h"
#include "Weapons.h"
#include "NPC.h"
#include "Soldier Functions.h"
#include "worldman.h"
#include "Scheduling.h"
#include "Message.h"
#include "message.h"
#include "Structure Wrap.h"
#include "Keys.h"
#include "pathai.h"
#include "PATHAI.H"
#include "Render Fun.h"
#include "Boxing.h"
// #include "Air Raid.h"
#include "Soldier Profile.h"
#include "soldier profile type.h"
#include "Soldier macros.h"
#include "los.h"
#include "LOS.h"
#include "Buildings.h"
#include "strategicmap.h"
#include "Quests.h"
#include "Map Screen Interface Map.h"
#include "soldier ani.h"
#include "rotting corpses.h"
#include "Soldier Ani.h"
#include "Rotting Corpses.h"
#include "GameSettings.h"
#include "Dialogue Control.h"
#include "connect.h"
@@ -44,7 +44,7 @@ extern bool gLogDecideActionRed;
extern BOOLEAN gfHiddenInterrupt;
extern BOOLEAN gfUseAlternateQueenPosition;
extern UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady, BOOLEAN fHipStance );
extern void IncrementWatchedLoc(UINT8 ubID, INT32 sGridNo, INT8 bLevel);
extern void IncrementWatchedLoc(UINT16 ubID, INT32 sGridNo, INT8 bLevel);
void LogDecideInfo(SOLDIERTYPE *pSoldier, bool doLog = true);
void LogKnowledgeInfo(SOLDIERTYPE *pSoldier, bool doLog);
INT8 DecideActionWearGasmask(SOLDIERTYPE* pSoldier);
@@ -598,10 +598,10 @@ INT8 DecideActionBoxerEnteringRing(SOLDIERTYPE *pSoldier)
INT8 DecideActionNamedNPC( SOLDIERTYPE * pSoldier )
{
INT32 sDesiredMercLoc;
UINT8 ubDesiredMercDir;
UINT8 ubDesiredMerc;
INT32 sDesiredMercDist;
INT32 sDesiredMercLoc;
UINT8 ubDesiredMercDir;
SoldierID ubDesiredMerc;
INT32 sDesiredMercDist;
#ifdef DEBUGDECISIONS
STR16 tempstr;
#endif
@@ -757,9 +757,9 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
{
// WANNE: This should fix the bug if any merc are still under PC control. This could happen after boxing in SAN MONA.
SOLDIERTYPE *pTeamSoldier;
for (INT8 bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++)
for ( SoldierID bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++bLoop )
{
pTeamSoldier=MercPtrs[bLoop];
pTeamSoldier = bLoop;
if (pTeamSoldier->flags.uiStatusFlags & SOLDIER_PCUNDERAICONTROL)
pTeamSoldier->flags.uiStatusFlags &= (~SOLDIER_PCUNDERAICONTROL);
@@ -930,7 +930,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
// 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 )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
if ( ubPerson != NOBODY )
{
@@ -942,7 +942,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
// if we are a doctor with medical gear, we might be able to help a wounded ally
if ( pSoldier->CanMedicAI() )
{
UINT8 ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
SoldierID ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
// are we ourselves the patient?
if ( ubPerson == pSoldier->ubID )
@@ -959,10 +959,10 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
}
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
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -984,7 +984,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
}
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))
{
@@ -996,13 +996,13 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
// if we are not a medic, but are wounded, seek a medic
else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount )
{
UINT8 ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
SoldierID ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
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))
{
@@ -1016,14 +1016,14 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD )
{
// 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 )
{
// 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 ) )
{
@@ -1652,18 +1652,18 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
// Flugente: if we see one of our buddies captured, it is a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
if ( ubPerson != NOBODY )
{
// if we are close, we can release this guy
// 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
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -1677,7 +1677,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
}
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))
{
@@ -1696,7 +1696,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
// if we are a doctor with medical gear, we might be able to help a wounded ally
if ( pSoldier->CanMedicAI() )
{
UINT8 ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
SoldierID ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
// are we ourselves the patient?
if ( ubPerson == pSoldier->ubID )
@@ -1713,10 +1713,10 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
}
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
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, ubPerson->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -1738,7 +1738,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
}
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))
{
@@ -1750,13 +1750,13 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
// if we are not a medic, but are wounded, seek a medic
else if ( pSoldier->iHealableInjury >= gGameExternalOptions.sEnemyMedicsWoundMinAmount )
{
UINT8 ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
SoldierID ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
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))
{
@@ -1770,14 +1770,14 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
if ( pSoldier->usSoldierFlagMask & SOLDIER_BODYGUARD )
{
// 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 )
{
// 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 ) )
{
@@ -2546,32 +2546,35 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
}
// if we're an alerted enemy, and there are panic bombs or a trigger around
if ( (!PTR_CIVILIAN || pSoldier->ubProfile == WARDEN) && ( ( gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || (pSoldier->ubID == gTacticalStatus.ubTheChosenOne) || (pSoldier->ubProfile == WARDEN) ) &&
(gTacticalStatus.fPanicFlags & (PANIC_BOMBS_HERE | PANIC_TRIGGERS_HERE ) ) ) )
if ( !ENEMYROBOT(pSoldier) )
{
if ( pSoldier->ubProfile == WARDEN && gTacticalStatus.ubTheChosenOne == NOBODY )
if ( (!PTR_CIVILIAN || pSoldier->ubProfile == WARDEN) && ( ( gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || (pSoldier->ubID == gTacticalStatus.ubTheChosenOne) || (pSoldier->ubProfile == WARDEN) ) &&
(gTacticalStatus.fPanicFlags & (PANIC_BOMBS_HERE | PANIC_TRIGGERS_HERE ) ) ) )
{
PossiblyMakeThisEnemyChosenOne( pSoldier );
if ( pSoldier->ubProfile == WARDEN && gTacticalStatus.ubTheChosenOne == NOBODY )
{
PossiblyMakeThisEnemyChosenOne( pSoldier );
}
// do some special panic AI decision making
bActionReturned = PanicAI(pSoldier,ubCanMove);
// if we decided on an action while in there, we're done
if (bActionReturned != -1)
return(bActionReturned);
}
// do some special panic AI decision making
bActionReturned = PanicAI(pSoldier,ubCanMove);
// if we decided on an action while in there, we're done
if (bActionReturned != -1)
return(bActionReturned);
}
if ( pSoldier->ubProfile != NO_PROFILE )
{
if ( (pSoldier->ubProfile == QUEEN || pSoldier->ubProfile == JOE) && ubCanMove )
if ( pSoldier->ubProfile != NO_PROFILE )
{
if ( gWorldSectorX == 3 && gWorldSectorY == MAP_ROW_P && gbWorldSectorZ == 0 && !gfUseAlternateQueenPosition )
if ( (pSoldier->ubProfile == QUEEN || pSoldier->ubProfile == JOE) && ubCanMove )
{
bActionReturned = HeadForTheStairCase( pSoldier );
if ( bActionReturned != AI_ACTION_NONE )
if ( gWorldSectorX == 3 && gWorldSectorY == MAP_ROW_P && gbWorldSectorZ == 0 && !gfUseAlternateQueenPosition )
{
return( bActionReturned );
bActionReturned = HeadForTheStairCase( pSoldier );
if ( bActionReturned != AI_ACTION_NONE )
{
return( bActionReturned );
}
}
}
}
@@ -2722,15 +2725,16 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
{
DebugAI(AI_MSG_INFO, pSoldier, String("throw possible"), gLogDecideActionRed);
// sevenfm: allow using mortars, grenade launchers, flares and grenades in RED state
if (Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].mortar ||
//Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].cannon ||
Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].rocketlauncher ||
Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].grenadelauncher ||
Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].flare ||
Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].usItemClass & IC_GRENADE)
UINT16 usItem = pSoldier->inv[BestThrow.bWeaponIn].usItem;
if (ItemIsMortar(usItem) ||
//Item[usItem].cannon ||
ItemIsRocketLauncher(usItem) ||
ItemIsGrenadeLauncher(usItem) ||
ItemIsFlare(usItem) ||
Item[usItem].usItemClass & IC_GRENADE)
{
// if firing mortar make sure we have room
if (Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].mortar)
if (ItemIsMortar(usItem))
{
DebugAI(AI_MSG_INFO, pSoldier, String("using mortar, check room to deploy"), gLogDecideActionRed);
ubOpponentDir = AIDirection(pSoldier->sGridNo, BestThrow.sTarget);
@@ -2875,7 +2879,7 @@ 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), gLogDecideActionRed);
// 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), gLogDecideActionRed);
MercPtrs[BestThrow.ubOpponent]->RetreatCounterStart(2);
@@ -3032,8 +3036,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
// check valid target
!TileIsOutOfBounds(BestShot.sTarget) &&
BestShot.ubOpponent != NOBODY &&
MercPtrs[BestShot.ubOpponent] &&
Chance(100 - MercPtrs[BestShot.ubOpponent]->ShockLevelPercent() / 2) &&
Chance(100 - BestShot.ubOpponent->ShockLevelPercent() / 2) &&
// check weapon/ammo requirements
IsGunAutofireCapable(&pSoldier->inv[BestShot.bWeaponIn]) &&
GetMagSize(&pSoldier->inv[BestShot.bWeaponIn]) >= gGameExternalOptions.ubAISuppressionMinimumMagSize &&
@@ -3050,16 +3053,16 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
!fCanBeSeen && NightLight() && CountFriendsFlankSameSpot(pSoldier, sClosestOpponent) && Chance(50) ||
ARMED_VEHICLE(pSoldier) || // tanks don't need 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
//SoldierToSoldierLineOfSightTest(pSoldier, MercPtrs[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
//SoldierToSoldierLineOfSightTest(pSoldier, BestShot.ubOpponent, TRUE, 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
(AICheckIsMachinegunner(pSoldier) ||
ARMED_VEHICLE(pSoldier) ||
ENEMYROBOT(pSoldier) ||
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))) &&
// check that we have spare ammo
(fExtraClip || pSoldier->inv[BestShot.bWeaponIn][0]->data.gun.ubGunShotsLeft >= gGameExternalOptions.ubAISuppressionMinimumMagSize))
@@ -3153,7 +3156,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
DebugAI(AI_MSG_INFO, pSoldier, String("Change stance before shooting"), gLogDecideActionRed);
// 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]);
return(AI_ACTION_CHANGE_STANCE);
@@ -3163,7 +3166,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
pSoldier->aiData.usActionData = BestShot.sTarget;
// 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]);
DebugAI(AI_MSG_INFO, pSoldier, String("Suppression fire!"), gLogDecideActionRed);
@@ -3297,7 +3300,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
{
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Free friendly POWs]"), gLogDecideActionRed);
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
SoldierID ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW, TRUE );
if ( ubPerson != NOBODY )
{
@@ -3305,14 +3308,14 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
// if we are close, we can release this guy
// 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 )
{
DebugAI(AI_MSG_INFO, pSoldier, String("I am close enough to free POW"), gLogDecideActionRed);
// 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 ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -3328,7 +3331,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
}
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))
{
@@ -3350,7 +3353,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
{
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Provide medical aid]"), gLogDecideActionRed);
UINT8 ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
SoldierID ubPerson = GetClosestWoundedSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius, pSoldier->bTeam);
// are we ourselves the patient?
if ( ubPerson == pSoldier->ubID )
@@ -3372,12 +3375,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
{
DebugAI(AI_MSG_INFO, pSoldier, String("Someone else is injured"), gLogDecideActionRed);
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
if ( PythSpacesAway(pSoldier->sGridNo, ubPerson->sGridNo) < 2 )
{
DebugAI(AI_MSG_INFO, pSoldier, String("Wounded soldier is nearby"), gLogDecideActionRed);
// 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 ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -3403,7 +3406,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
else
{
DebugAI(AI_MSG_INFO, pSoldier, String("Wounded soldier is far"), gLogDecideActionRed);
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))
{
@@ -3418,15 +3421,15 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
{
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Seek medical aid]"), gLogDecideActionRed);
UINT8 ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
SoldierID ubPerson = GetClosestMedicSoldierID( pSoldier, gGameExternalOptions.sEnemyMedicsSearchRadius / 2, pSoldier->bTeam);
if ( ubPerson != NOBODY )
{
DebugAI(AI_MSG_INFO, pSoldier, String("Found a medic!"), gLogDecideActionRed);
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))
{
@@ -3475,16 +3478,16 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
{
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Bodyguard]"), gLogDecideActionRed);
// 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 )
{
DebugAI(AI_MSG_INFO, pSoldier, String("VIP found"), gLogDecideActionRed);
// 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 )
{
DebugAI(AI_MSG_INFO, pSoldier, String("Attempt to get close "), gLogDecideActionRed);
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 ) )
{
@@ -5283,13 +5286,16 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
// offer surrender?
#ifndef JA2UB
if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( pSoldier ) )
if ( !is_networked ) // No surrender in multiplayer
{
if ( gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector == 0 && gTacticalStatus.Team[ CREATURE_TEAM ].bMenInSector == 0 && NumPCsInSector() < 4 && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector >= NumPCsInSector() * 3 )
if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( pSoldier ) )
{
if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)
if ( gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector == 0 && gTacticalStatus.Team[ CREATURE_TEAM ].bMenInSector == 0 && NumPCsInSector() < 4 && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector >= NumPCsInSector() * 3 )
{
return( AI_ACTION_OFFER_SURRENDER );
if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)
{
return( AI_ACTION_OFFER_SURRENDER );
}
}
}
}
@@ -5646,7 +5652,7 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
if (BestThrow.ubPossible)
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"good throw possible");
if ( Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar )
if (ItemIsMortar(pSoldier->inv[ BestThrow.bWeaponIn ].usItem))
{
ubOpponentDir = AIDirection(pSoldier->sGridNo, BestThrow.sTarget);
@@ -5906,10 +5912,9 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
BOXER(pSoldier) &&
SpacesAway(pSoldier->sGridNo, BestStab.sTarget) > 2 &&
BestStab.ubOpponent != NOBODY &&
MercPtrs[BestStab.ubOpponent] &&
AIDirection(pSoldier->sGridNo, MercPtrs[BestStab.ubOpponent]->sGridNo) != MercPtrs[BestStab.ubOpponent]->ubDirection &&
AIDirection(pSoldier->sGridNo, MercPtrs[BestStab.ubOpponent]->sGridNo) != gOneCDirection[MercPtrs[BestStab.ubOpponent]->ubDirection] &&
AIDirection(pSoldier->sGridNo, MercPtrs[BestStab.ubOpponent]->sGridNo) != gOneCCDirection[MercPtrs[BestStab.ubOpponent]->ubDirection] &&
AIDirection(pSoldier->sGridNo, BestStab.ubOpponent->sGridNo) != BestStab.ubOpponent->ubDirection &&
AIDirection(pSoldier->sGridNo, BestStab.ubOpponent->sGridNo) != gOneCDirection[BestStab.ubOpponent->ubDirection] &&
AIDirection(pSoldier->sGridNo, BestStab.ubOpponent->sGridNo) != gOneCCDirection[BestStab.ubOpponent->ubDirection] &&
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))
{
@@ -5923,10 +5928,9 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
BOXER(pSoldier) &&
SpacesAway(pSoldier->sGridNo, BestStab.sTarget) > 1 &&
BestStab.ubOpponent != NOBODY &&
MercPtrs[BestStab.ubOpponent] &&
gAnimControl[MercPtrs[BestStab.ubOpponent]->usAnimState].ubEndHeight == ANIM_STAND &&
MercPtrs[BestStab.ubOpponent]->bActionPoints > 0 &&
Chance(EffectiveAgility(MercPtrs[BestStab.ubOpponent], FALSE) * (100 + MercPtrs[BestStab.ubOpponent]->bBreath) * EffectiveWisdom(pSoldier) / (100 * 200)))
gAnimControl[BestStab.ubOpponent->usAnimState].ubEndHeight == ANIM_STAND &&
BestStab.ubOpponent->bActionPoints > 0 &&
Chance(EffectiveAgility(BestStab.ubOpponent, FALSE) * (100 + BestStab.ubOpponent->bBreath) * EffectiveWisdom(pSoldier) / (100 * 200)))
{
// find closest spot around opponent, avoid front direction
UINT8 ubMovementCost;
@@ -5946,7 +5950,7 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
if (ubMovementCost < TRAVELCOST_BLOCKED &&
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);
if (TileIsOutOfBounds(sBestSpot) || sPathCost < sBestPathCost)
@@ -5984,7 +5988,7 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
// SANDRO - added a chance to try to steal merc's gun from hands
else
{
if (AIDetermineStealingWeaponAttempt( pSoldier, MercPtrs[BestStab.ubOpponent] ) == TRUE)
if (AIDetermineStealingWeaponAttempt( pSoldier, BestStab.ubOpponent ) == TRUE)
{
ubBestAttackAction = AI_ACTION_STEAL_MOVE;
DebugAI(AI_MSG_INFO, pSoldier, String("best action = move to steal weapon, iAttackValue = %d", BestStab.iAttackValue));
@@ -6479,7 +6483,7 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
}
// SANDRO: more likely to burst when firing from hip
if ( BestAttack.bScopeMode == USE_ALT_WEAPON_HOLD && Item[pSoldier->inv[BestAttack.bWeaponIn].usItem].twohanded )
if ( BestAttack.bScopeMode == USE_ALT_WEAPON_HOLD && ItemIsTwoHanded(pSoldier->inv[BestAttack.bWeaponIn].usItem) )
iChance += 40;
// CHRISL: Changed from a simple flag to two externalized values for more modder control over AI suppression
@@ -6598,7 +6602,7 @@ L_NEWAIM:
}
// SANDRO: more likely to burst when firing from hip
if ( BestAttack.bScopeMode == USE_ALT_WEAPON_HOLD && Item[pSoldier->inv[BestAttack.bWeaponIn].usItem].twohanded )
if ( BestAttack.bScopeMode == USE_ALT_WEAPON_HOLD && ItemIsTwoHanded(pSoldier->inv[BestAttack.bWeaponIn].usItem) )
iChance += 40;
// CHRISL: Changed from a simple flag to two externalized values for more modder control over AI suppression
@@ -7007,13 +7011,11 @@ L_NEWAIM:
{
DebugAI(AI_MSG_TOPIC, pSoldier, String("[Make boxer close if possible]"));
UINT8 ubOpponentID;
SoldierID ubOpponentID;
sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL, &ubOpponentID);
DebugAI(AI_MSG_INFO, pSoldier, String("boxer: found closest opponent [%d] at %d", ubOpponentID, sClosestOpponent));
if (!TileIsOutOfBounds(sClosestOpponent) &&
ubOpponentID != NOBODY &&
MercPtrs[ubOpponentID])
if ( !TileIsOutOfBounds(sClosestOpponent) && ubOpponentID != NOBODY )
{
if (pSoldier->bActionPoints > 0)
{
@@ -7050,7 +7052,7 @@ L_NEWAIM:
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData) &&
(pSoldier->bBreath < OKBREATH ||
pSoldier->bBreath < pSoldier->bBreathMax &&
pSoldier->bBreath < MercPtrs[ubOpponentID]->bBreath &&
pSoldier->bBreath < ubOpponentID->bBreath &&
Chance((100 - pSoldier->bBreath) * (100 - pSoldier->bBreath) / (2 * 100 * 100))))
{
DebugAI(AI_MSG_INFO, pSoldier, String("boxer: restore breath"));
@@ -7074,7 +7076,7 @@ L_NEWAIM:
}
else if (pSoldier->bBreath < OKBREATH ||
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
UINT8 ubOpponentDir = AIDirection(pSoldier->sGridNo, sClosestOpponent);
@@ -8581,10 +8583,10 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
if ( BestThrow.ubPossible )
{
// if firing mortar make sure we have room
//if ( Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar ) //comm by ddd
if ( Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].mortar
|| Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].grenadelauncher
|| Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].flare )
UINT16 usItem = pSoldier->inv[BestThrow.bWeaponIn].usItem;
if (ItemIsMortar(usItem)
|| ItemIsGrenadeLauncher(usItem)
|| ItemIsFlare(usItem) )
{
ubOpponentDir = GetDirectionFromGridNo( BestThrow.sTarget, pSoldier );
@@ -8756,9 +8758,9 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
//&& Menptr[BestShot.ubOpponent].pathing.bLevel == 0
&& pSoldier->aiData.bOrders != SNIPER &&
BestShot.ubFriendlyFireChance < 5 &&
!MercPtrs[BestShot.ubOpponent]->IsCowering() &&
!BestShot.ubOpponent->IsCowering() &&
!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
(fExtraClip || pSoldier->inv[BestShot.bWeaponIn][0]->data.gun.ubGunShotsLeft > gGameExternalOptions.ubAISuppressionMinimumMagSize) )
{
@@ -9758,13 +9760,16 @@ INT8 ArmedVehicleDecideActionBlack( SOLDIERTYPE *pSoldier )
// offer surrender?
#ifndef JA2UB
if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( pSoldier ) )
if ( !is_networked ) // No surrender in multiplayer
{
if ( gTacticalStatus.Team[MILITIA_TEAM].bMenInSector == 0 && gTacticalStatus.Team[CREATURE_TEAM].bMenInSector == 0 && NumPCsInSector( ) < 4 && gTacticalStatus.Team[ENEMY_TEAM].bMenInSector >= NumPCsInSector( ) * 3 )
if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( pSoldier ) )
{
if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)
if ( gTacticalStatus.Team[MILITIA_TEAM].bMenInSector == 0 && gTacticalStatus.Team[CREATURE_TEAM].bMenInSector == 0 && NumPCsInSector() < 4 && gTacticalStatus.Team[ENEMY_TEAM].bMenInSector >= NumPCsInSector() * 3 )
{
return(AI_ACTION_OFFER_SURRENDER);
if ( gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED )
{
return(AI_ACTION_OFFER_SURRENDER);
}
}
}
}
@@ -9977,7 +9982,7 @@ INT8 ArmedVehicleDecideActionBlack( SOLDIERTYPE *pSoldier )
if ( BestThrow.ubPossible )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "good throw possible" );
if ( Item[pSoldier->inv[BestThrow.bWeaponIn].usItem].mortar )
if (ItemIsMortar(pSoldier->inv[BestThrow.bWeaponIn].usItem))
{
ubOpponentDir = (UINT8)GetDirectionFromGridNo( BestThrow.sTarget, pSoldier );