Merge branch 'master' into ExtraMercs

This commit is contained in:
Asdow
2024-11-09 13:44:53 +02:00
371 changed files with 6539 additions and 13390 deletions
+38 -40
View File
@@ -52,9 +52,9 @@
#include "connect.h"
// needed to use the modularized tactical AI:
#include "ModularizedTacticalAI/include/Plan.h"
#include "ModularizedTacticalAI/include/PlanFactoryLibrary.h"
#include "ModularizedTacticalAI/include/AbstractPlanFactory.h"
#include "Plan.h"
#include "PlanFactoryLibrary.h"
#include "AbstractPlanFactory.h"
#ifdef JA2UB
#include "Ja25_Tactical.h"
@@ -217,7 +217,7 @@ void DebugAI( INT8 bMsgType, SOLDIERTYPE *pSoldier, STR szOutput, INT8 bAction )
CHAR8 msg[1024];
CHAR8 buf[1024];
if (!gfLogsEnabled)
if (!gfLogsEnabled || pSoldier == nullptr)
return;
memset(buf, 0, 1024 * sizeof(char));
@@ -235,17 +235,14 @@ void DebugAI( INT8 bMsgType, SOLDIERTYPE *pSoldier, STR szOutput, INT8 bAction )
sprintf(msg, "");
if (pSoldier)
{
sprintf(buf, "[%d] (%d)", pSoldier->ubID, pSoldier->sGridNo);
strcat(msg, buf);
sprintf(buf, "[%d] (%d)", pSoldier->ubID, pSoldier->sGridNo);
strcat(msg, buf);
if (pSoldier->ubProfile != NO_PROFILE)
{
wcstombs(buf, pSoldier->GetName(), 1024 - 1);
strcat(msg, " ");
strcat(msg, buf);
}
if (pSoldier->ubProfile != NO_PROFILE)
{
wcstombs(buf, pSoldier->GetName(), 1024 - 1);
strcat(msg, " ");
strcat(msg, buf);
}
strcat(msg, " ");
@@ -266,13 +263,10 @@ void DebugAI( INT8 bMsgType, SOLDIERTYPE *pSoldier, STR szOutput, INT8 bAction )
strcat(msg, " ");
strcat(msg, szAction[bAction]);
if (pSoldier)
{
sprintf(buf, " %d", pSoldier->aiData.usActionData);
strcat(msg, buf);
}
sprintf(buf, " %d", pSoldier->aiData.usActionData);
strcat(msg, buf);
if (pSoldier && pSoldier->aiData.bNextAction != AI_ACTION_NONE)
if (pSoldier->aiData.bNextAction != AI_ACTION_NONE)
{
strcat(msg, " ");
strcat(msg, szAction[pSoldier->aiData.bNextAction]);
@@ -756,7 +750,9 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) // FIXME - this function is named
if (pSoldier->aiData.bAction >= FIRST_MOVEMENT_ACTION && pSoldier->aiData.bAction <= LAST_MOVEMENT_ACTION && !pSoldier->flags.fDelayedMovement)
{
if (pSoldier->pathing.usPathIndex == pSoldier->pathing.usPathDataSize)
{
{
INT8 bEscapeDirection = NOWHERE;
if (!TileIsOutOfBounds(pSoldier->sAbsoluteFinalDestination))
{
if ( !ACTING_ON_SCHEDULE( pSoldier ) && SpacesAway( pSoldier->sGridNo, pSoldier->sAbsoluteFinalDestination ) < 4 )
@@ -797,7 +793,8 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) // FIXME - this function is named
}
}
// for regular guys still have to check for leaving the map
else if (pSoldier->ubQuoteActionID >= QUOTE_ACTION_ID_TRAVERSE_EAST && pSoldier->ubQuoteActionID <= QUOTE_ACTION_ID_TRAVERSE_NORTH)
else if (pSoldier->ubQuoteActionID >= QUOTE_ACTION_ID_TRAVERSE_EAST && pSoldier->ubQuoteActionID <= QUOTE_ACTION_ID_TRAVERSE_NORTH &&
GridNoOnEdgeOfMap(pSoldier->sGridNo, &bEscapeDirection) && EscapeDirectionIsValid(&bEscapeDirection))
{
HandleAITacticalTraversal( pSoldier );
return;
@@ -1891,7 +1888,7 @@ UINT32 GetTankCannonIndex()
{
for ( UINT32 i = 0; i < gMAXITEMS_READ; ++i )
{
if (Item[i].cannon)
if (ItemIsCannon(i))
{
return Item[i].uiIndex;
}
@@ -2242,23 +2239,24 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
// fall through
case AI_ACTION_FIRE_GUN: // shoot at nearby opponent
case AI_ACTION_THROW_KNIFE: // throw knife at nearby opponent
// randomly decide whether to say civ quote
if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_GUN )
PossiblyStartEnemyTaunt( pSoldier, TAUNT_FIRE_GUN, pSoldier->ubOppNum );
else if (Item[pSoldier->inv[HANDPOS].usItem].grenadelauncher || Item[pSoldier->inv[HANDPOS].usItem].mortar || Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher )
PossiblyStartEnemyTaunt( pSoldier, TAUNT_FIRE_LAUNCHER, pSoldier->ubOppNum );
else if (pSoldier->aiData.bAction == AI_ACTION_TOSS_PROJECTILE && Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_THROWN && !Item[pSoldier->inv[HANDPOS].usItem].flare )
PossiblyStartEnemyTaunt( pSoldier, TAUNT_THROW_KNIFE, pSoldier->ubOppNum );
else if (pSoldier->aiData.bAction == AI_ACTION_KNIFE_MOVE )
{
if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_BLADE )
PossiblyStartEnemyTaunt( pSoldier, TAUNT_CHARGE_BLADE );
else if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_PUNCH )
PossiblyStartEnemyTaunt( pSoldier, TAUNT_CHARGE_HTH );
}
case AI_ACTION_THROW_KNIFE: // throw knife at nearby opponent
// randomly decide whether to say civ quote
{
UINT16 usItem = pSoldier->inv[HANDPOS].usItem;
if (Item[usItem].usItemClass == IC_GUN)
PossiblyStartEnemyTaunt(pSoldier, TAUNT_FIRE_GUN, pSoldier->ubOppNum);
else if (ItemIsGrenadeLauncher(usItem) || ItemIsMortar(usItem) || ItemIsRocketLauncher(usItem))
PossiblyStartEnemyTaunt(pSoldier, TAUNT_FIRE_LAUNCHER, pSoldier->ubOppNum);
else if (pSoldier->aiData.bAction == AI_ACTION_TOSS_PROJECTILE && Item[usItem].usItemClass == IC_THROWN && !ItemIsFlare(usItem))
PossiblyStartEnemyTaunt(pSoldier, TAUNT_THROW_KNIFE, pSoldier->ubOppNum);
else if (pSoldier->aiData.bAction == AI_ACTION_KNIFE_MOVE)
{
if (Item[usItem].usItemClass == IC_BLADE)
PossiblyStartEnemyTaunt(pSoldier, TAUNT_CHARGE_BLADE);
else if (Item[usItem].usItemClass == IC_PUNCH)
PossiblyStartEnemyTaunt(pSoldier, TAUNT_CHARGE_HTH);
}
}
// CC, ATE here - I put in some TEMP randomness...
if (!is_networked)
{
+7 -7
View File
@@ -102,7 +102,7 @@ INT8 OKToAttack(SOLDIERTYPE * pSoldier, int target)
if ( Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_GUN)
{
if ( Item[pSoldier->inv[HANDPOS].usItem].cannon )
if (ItemIsCannon(pSoldier->inv[HANDPOS].usItem))
{
// look for another tank shell ELSEWHERE IN INVENTORY
if ( FindLaunchable( pSoldier, pSoldier->inv[HANDPOS].usItem ) == NO_SLOT )
@@ -144,7 +144,7 @@ BOOLEAN ConsiderProne( SOLDIERTYPE * pSoldier )
}
// We don't want to go prone if there is a nearby enemy
ClosestKnownOpponent( pSoldier, &sOpponentGridNo, &bOpponentLevel );
iRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, sOpponentGridNo );
iRange = PythSpacesAway( pSoldier->sGridNo, sOpponentGridNo );
if (iRange > 10)
{
return( TRUE );
@@ -2724,7 +2724,7 @@ INT32 CalcManThreatValue( SOLDIERTYPE *pEnemy, INT32 sMyGrid, UINT8 ubReduceForC
else
{
// ADD 5% if man's already facing me
if (pEnemy->ubDirection == atan8(CenterX(pEnemy->sGridNo),CenterY(pEnemy->sGridNo),CenterX(sMyGrid),CenterY(sMyGrid)))
if (pEnemy->ubDirection == GetDirectionFromCenterCellXYGridNo(pEnemy->sGridNo, sMyGrid))
{
iThreatValue += (iThreatValue / 20);
}
@@ -3619,13 +3619,13 @@ UINT16 CountFriendsInDirection( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
CHECKF(pSoldier);
ubMyDir = atan8(CenterX(sTargetGridNo),CenterY(sTargetGridNo),CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo));
ubMyDir = GetDirectionFromCenterCellXYGridNo(sTargetGridNo, pSoldier->sGridNo);
// Run through each friendly.
for ( UINT16 iCounter = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID ; iCounter <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID ; iCounter ++ )
{
pFriend = MercPtrs[ iCounter ];
ubFriendDir = atan8(CenterX(sTargetGridNo),CenterY(sTargetGridNo),CenterX(pFriend->sGridNo),CenterY(pFriend->sGridNo));
ubFriendDir = GetDirectionFromCenterCellXYGridNo(sTargetGridNo, pFriend->sGridNo);
if (pFriend != pSoldier &&
pFriend->bActive &&
@@ -4811,7 +4811,7 @@ BOOLEAN AnyCoverFromSpot( INT32 sSpot, INT8 bLevel, INT32 sThreatLoc, INT8 bThre
return FALSE;
}
ubDirection = atan8(CenterX(sSpot), CenterY(sSpot), CenterX(sThreatLoc), CenterY(sThreatLoc));
ubDirection = GetDirectionFromCenterCellXYGridNo(sSpot, sThreatLoc);
sCoverSpot = NewGridNo( sSpot, DirectionInc( ubDirection ) );
if ( TileIsOutOfBounds( sCoverSpot ) )
@@ -5001,7 +5001,7 @@ UINT8 AIDirection(INT32 sSpot1, INT32 sSpot2)
return DIRECTION_IRRELEVANT;
}
return atan8(CenterX(sSpot1), CenterY(sSpot1), CenterX(sSpot2), CenterY(sSpot2));
return GetDirectionFromCenterCellXYGridNo(sSpot1, sSpot2);
}
BOOLEAN AICheckIsSniper(SOLDIERTYPE *pSoldier)
+36 -42
View File
@@ -63,7 +63,7 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier)
usInHand = GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS]);
// if he's got a MORTAR in his hand, make sure he has a MORTARSHELL avail.
if (Item[usInHand].mortar )
if (ItemIsMortar(usInHand))
{
// bPayloadPocket = FindObj( pSoldier, MORTAR_SHELL );
bPayloadPocket = FindLaunchable( pSoldier, usInHand );
@@ -76,7 +76,7 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier)
}
}
// if he's got a GL in his hand, make sure he has some type of GRENADE avail.
else if (Item[usInHand].grenadelauncher )
else if (ItemIsGrenadeLauncher(usInHand))
{
bPayloadPocket = FindGLGrenade( pSoldier );
if (bPayloadPocket == NO_SLOT || FindNonSmokeLaunchableAttachment( &pSoldier->inv[HANDPOS],usInHand ) != 0 )
@@ -88,7 +88,7 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier)
}
}
// if he's got a RPG7 in his hand, make sure he has some type of RPG avail.
else if (Item[usInHand].rocketlauncher && !Item[usInHand].singleshotrocketlauncher )
else if (ItemIsRocketLauncher(usInHand) && !ItemIsSingleShotRocketLauncher(usInHand))
{
bPayloadPocket = FindLaunchable (pSoldier, usInHand );
if (bPayloadPocket == NO_SLOT)
@@ -96,7 +96,7 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier)
return; // no grenades, can't fire
}
}
else if (Item[usInHand].cannon )
else if (ItemIsCannon(usInHand))
{
bPayloadPocket = FindLaunchable( pSoldier, usInHand );
if (bPayloadPocket == NO_SLOT)
@@ -444,7 +444,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot)
// sevenfm: take into account direction when checking stance
// sevenfm: shoot heavy guns in standing stance only when using hip fire
if (pSoldier->InternalIsValidStance(AIDirection(pSoldier->sGridNo, sTarget), ubStance) &&
(pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD || !Weapon[pSoldier->usAttackingWeapon].HeavyGun || !Item[pSoldier->usAttackingWeapon].twohanded || !gGameExternalOptions.ubAllowAlternativeWeaponHolding))
(pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD || !Weapon[pSoldier->usAttackingWeapon].HeavyGun || !ItemIsTwoHanded(pSoldier->usAttackingWeapon) || !gGameExternalOptions.ubAllowAlternativeWeaponHolding))
{
sStanceAPcost = GetAPsToChangeStance(pSoldier, ubStance);
if(sStanceAPcost)
@@ -783,7 +783,6 @@ BOOLEAN CloseEnoughForGrenadeToss( INT32 sGridNo, INT32 sGridNo2 )
{
INT32 sTempGridNo;
UINT8 ubDirection;
INT16 sXPos, sYPos, sXPos2, sYPos2;
UINT8 ubMovementCost;
if (sGridNo == sGridNo2 )
@@ -815,13 +814,7 @@ BOOLEAN CloseEnoughForGrenadeToss( INT32 sGridNo, INT32 sGridNo2 )
// so we can now do a loop safely
sTempGridNo = sGridNo;
sXPos = CenterX( sGridNo );
sYPos = CenterY( sGridNo );
sXPos2 = CenterX( sGridNo2 );
sYPos2 = CenterY( sGridNo2 );
ubDirection = atan8( sXPos, sYPos, sXPos2, sYPos2 );
ubDirection = GetDirectionFromCenterCellXYGridNo(sGridNo, sGridNo2);
// For each step of the loop, we are checking for door or obstacle movement costs. If we
// find we're blocked, then this is no good for grenade tossing!
do
@@ -894,7 +887,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
}
// if he's got a MORTAR in his hand, make sure he has a MORTARSHELL avail.
if (Item[usInHand].mortar )
if (ItemIsMortar(usInHand))
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow: buddy's got a mortar");
bPayloadPocket = FindNonSmokeLaunchable(pSoldier, usInHand);
@@ -918,7 +911,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
fMortar = TRUE;
}
// if he's got a GL in his hand, make sure he has some type of GRENADE avail.
else if (Item[usInHand].grenadelauncher )
else if (ItemIsGrenadeLauncher(usInHand))
{
// use up pocket 2 first, they get left as drop items
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow: buddy's got a GL");
@@ -950,7 +943,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
}
fGrenadeLauncher = TRUE;
}
else if ( Item[usInHand].rocketlauncher )
else if (ItemIsRocketLauncher(usInHand))
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow: buddy's got a rocket launcher");
@@ -959,7 +952,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// put in hand
bPayloadPocket = HANDPOS;//dnl ch63 240813
if (Item[usInHand].singleshotrocketlauncher)
if (ItemIsSingleShotRocketLauncher(usInHand))
{
// sevenfm: for single shot rocket launchers, use buddy item instead
if (Item[usInHand].usBuddyItem && Item[Item[usInHand].usBuddyItem].usItemClass & IC_EXPLOSV)
@@ -990,7 +983,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
}
fRocketLauncher = TRUE;
}
else if (Item[usInHand].cannon )
else if (ItemIsCannon(usInHand))
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow: buddy's got a tank");
bPayloadPocket = FindNonSmokeLaunchable(pSoldier, usInHand);
@@ -1015,7 +1008,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
usGrenade = pSoldier->inv[bPayloadPocket].usItem;
ubSafetyMargin = (UINT8)(1 + max(Explosive[Item[usGrenade].ubClassIndex].ubRadius, min((UINT8)TACTICAL_RANGE / 4, Explosive[Item[usGrenade].ubClassIndex].ubFragRange / CELL_X_SIZE)));
if ( Item[usGrenade].flare )
if (ItemIsFlare(usGrenade))
{
// JA2Gold: light isn't as nasty as explosives
ubSafetyMargin /= 2;
@@ -1039,7 +1032,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// use flares only at night
if (usGrenade != NOTHING &&
Item[usGrenade].flare &&
ItemIsFlare(usGrenade) &&
!NightLight())
{
return;
@@ -1128,7 +1121,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// limit explosives type when attacking zombies
if (usGrenade != NOTHING &&
!Item[usGrenade].flare &&
!ItemIsFlare(usGrenade) &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_NORMAL &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS &&
@@ -1150,7 +1143,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// limit explosives type when attacking robots, vehicles and tanks
if (usGrenade != NOTHING &&
!Item[usGrenade].flare &&
!ItemIsFlare(usGrenade) &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_NORMAL &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS &&
@@ -1168,7 +1161,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// limit explosives type when attacking collapsed enemies
if (usGrenade != NOTHING &&
!Item[usGrenade].flare &&
!ItemIsFlare(usGrenade) &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_NORMAL &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS &&
@@ -1180,7 +1173,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// don't use flare if soldier is in light
if (usGrenade != NOTHING &&
Item[usGrenade].flare &&
ItemIsFlare(usGrenade) &&
InLightAtNight(pOpponent->sGridNo, pOpponent->pathing.bLevel))
{
continue;
@@ -1188,13 +1181,13 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// don't use flares against opponents on roof
if (usGrenade != NOTHING &&
Item[usGrenade].flare &&
ItemIsFlare(usGrenade) &&
pOpponent->pathing.bLevel > 0)
{
continue;
}
if (Item[usInHand].mortar)
if (ItemIsMortar(usInHand))
{
// active KNOWN opponent, remember where he is so that we DO blow him up!
if (bPersonalKnowledge == SEEN_CURRENTLY ||
@@ -1216,7 +1209,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
continue; // next soldier
}
}
else if (Item[usInHand].rocketlauncher)
else if (ItemIsRocketLauncher(usInHand))
{
if (bPersonalKnowledge == SEEN_CURRENTLY || bPublicKnowledge == SEEN_CURRENTLY)
{
@@ -1238,7 +1231,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
continue;
}
}
else if( Item[usInHand].grenadelauncher )
else if(ItemIsGrenadeLauncher(usInHand))
{
if (bPersonalKnowledge == SEEN_CURRENTLY || bPublicKnowledge == SEEN_CURRENTLY)
{
@@ -1269,7 +1262,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
else if ((bKnowledge == SEEN_THIS_TURN || bKnowledge == SEEN_LAST_TURN || bKnowledge == HEARD_THIS_TURN || bKnowledge == HEARD_LAST_TURN) &&
!TileIsOutOfBounds(KnownLocation(pSoldier, pOpponent->ubID)) &&
CloseEnoughForGrenadeToss(pOpponent->sGridNo, KnownLocation(pSoldier, pOpponent->ubID)) &&
(usGrenade != NOTHING && Item[usGrenade].flare || pSoldier->aiData.bUnderFire || pSoldier->aiData.bShock))
(usGrenade != NOTHING && ItemIsFlare(usGrenade) || pSoldier->aiData.bUnderFire || pSoldier->aiData.bShock))
{
sOpponentTile[ubOpponentCnt] = KnownLocation(pSoldier, pOpponent->ubID);
bOpponentLevel[ubOpponentCnt] = KnownLevel(pSoldier, pOpponent->ubID);
@@ -1306,7 +1299,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// don't spare non lethal grenades
if (usGrenade != NOTHING &&
(Item[usGrenade].flare ||
(ItemIsFlare(usGrenade) ||
Explosive[Item[usGrenade].ubClassIndex].ubType == EXPLOSV_STUN ||
Explosive[Item[usGrenade].ubClassIndex].ubType == EXPLOSV_SMOKE ||
Explosive[Item[usGrenade].ubClassIndex].ubType == EXPLOSV_TEARGAS ||
@@ -1335,7 +1328,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// militia always try to spare grenades unless under attack or using flares
if (pSoldier->bTeam == MILITIA_TEAM &&
!pSoldier->aiData.bUnderFire &&
!Item[usGrenade].flare &&
!ItemIsFlare(usGrenade) &&
!fRocketLauncher)
{
fSpare = TRUE;
@@ -1570,7 +1563,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
ubChanceToGetThrough = 100 - (UINT8) uiPenalty;
}
}
else if (Item[usInHand].mortar &&
else if (ItemIsMortar(usInHand) &&
usGrenade != NOTHING &&
Explosive[Item[usGrenade].ubClassIndex].ubType == EXPLOSV_NORMAL &&
bOpponentLevel[ubLoop] == 0 &&
@@ -1596,7 +1589,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// this is try to minimize enemies wasting their (few) mortar shells or LAWs
// they won't use them on less than 2 targets as long as half life left
if ((Item[usInHand].mortar || Item[usInHand].rocketlauncher) && (ubOppsInRange < 2) &&
if ((ItemIsMortar(usInHand) || ItemIsRocketLauncher(usInHand)) && (ubOppsInRange < 2) &&
(!gGameExternalOptions.fEnemyTanksDontSpareShells || !ARMED_VEHICLE(pSoldier)) &&
!gGameExternalOptions.fEnemiesDontSpareLaunchables)
{
@@ -1604,7 +1597,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
}
// limit RPG use, unless can hit several enemies, shooting at tank or opponent is in a room
if (Item[usInHand].rocketlauncher &&
if (ItemIsRocketLauncher(usInHand) &&
ubOppsInRange < 2 &&
!ARMED_VEHICLE(MercPtrs[ubOpponentID[ubLoop]]) &&
(!InARoom(sOpponentTile[ubLoop], NULL) || pSoldier->bTeam != ENEMY_TEAM))
@@ -1694,7 +1687,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// this is try to minimize enemies wasting their (limited) toss attacks:
UINT8 ubMinChanceToReallyHit;
if( usGrenade != NOTHING && Item[usGrenade].flare )
if( usGrenade != NOTHING && ItemIsFlare(usGrenade) )
{
ubMinChanceToReallyHit = 30;
}
@@ -2312,11 +2305,12 @@ INT32 EstimateThrowDamage( SOLDIERTYPE *pSoldier, UINT8 ubItemPos, SOLDIERTYPE *
// ubExplosiveIndex = Item[ C1 ].ubClassIndex;
// break;
//default:
if ( Item[pSoldier->inv[ ubItemPos ].usItem].singleshotrocketlauncher )
UINT16 usItem = pSoldier->inv[ubItemPos].usItem;
if (ItemIsSingleShotRocketLauncher(usItem))
ubExplosiveIndex = Item[ C1 ].ubClassIndex;
else if ( Item[pSoldier->inv[ ubItemPos ].usItem].rocketlauncher || Item[pSoldier->inv[ ubItemPos ].usItem].grenadelauncher || Item[pSoldier->inv[ ubItemPos ].usItem].mortar )
else if (ItemIsRocketLauncher(usItem) || ItemIsGrenadeLauncher(usItem) || ItemIsMortar(usItem) )
{
OBJECTTYPE* pAttachment = FindLaunchableAttachment(&pSoldier->inv[ ubItemPos ],pSoldier->inv[ ubItemPos ].usItem ) ;
OBJECTTYPE* pAttachment = FindLaunchableAttachment(&pSoldier->inv[ ubItemPos ],usItem ) ;
if ( pAttachment->exists() )
ubExplosiveIndex = Item[pAttachment->usItem].ubClassIndex;
else
@@ -2338,7 +2332,7 @@ INT32 EstimateThrowDamage( SOLDIERTYPE *pSoldier, UINT8 ubItemPos, SOLDIERTYPE *
// break;
//}
// JA2Gold: added
if ( Item[pSoldier->inv[ubItemPos].usItem].flare )
if (ItemIsFlare(pSoldier->inv[ubItemPos].usItem))
{
return( 5 * ( LightTrueLevel( pOpponent->sGridNo, pOpponent->pathing.bLevel ) - NORMAL_LIGHTLEVEL_DAY ) );
}
@@ -2503,7 +2497,7 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT16 u
{
if (gGameOptions.fNewTraitSystem)
{
if (!pSoldier->usAttackingWeapon || Item[usItem].brassknuckles)
if (!pSoldier->usAttackingWeapon || ItemIsBrassKnuckles(usItem))
{
// add bonus for martial arts
if (HAS_SKILL_TRAIT(pSoldier, MARTIAL_ARTS_NT))
@@ -2772,13 +2766,13 @@ INT8 CanNPCAttack(SOLDIERTYPE *pSoldier)
RearrangePocket( pSoldier, HANDPOS, bWeaponIn, FOREVER );
// look for another weapon if this one is 1-handed
// if ( (Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ HANDPOS ].usItem ].fFlags & ITEM_TWO_HANDED ) )
if ( (Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ HANDPOS ].usItem ].twohanded ) )
if ( (Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN) && !ItemIsTwoHanded(pSoldier->inv[ HANDPOS ].usItem) )
{
// look for another pistol/SMG if available
// CHRISL: Change final parameter to use dynamic pocket definition
bWeaponIn = FindAIUsableObjClassWithin( pSoldier, IC_WEAPON, BIGPOCKSTART, NUM_INV_SLOTS );
// if (bWeaponIn != NO_SLOT && (Item[ pSoldier->inv[ bWeaponIn ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ bWeaponIn ].usItem ].fFlags & ITEM_TWO_HANDED ) )
if (bWeaponIn != NO_SLOT && (Item[ pSoldier->inv[ bWeaponIn ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ bWeaponIn ].usItem ].twohanded ) )
if (bWeaponIn != NO_SLOT && (Item[ pSoldier->inv[ bWeaponIn ].usItem ].usItemClass == IC_GUN) && !ItemIsTwoHanded(pSoldier->inv[ bWeaponIn ].usItem) )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"cannpcattack: swapping weapon into holster");
RearrangePocket( pSoldier, SECONDHANDPOS, bWeaponIn, FOREVER );
+3 -3
View File
@@ -481,7 +481,7 @@ INT8 CreatureDecideActionYellow( SOLDIERTYPE * pSoldier )
if (pSoldier->aiData.bMobility != CREATURE_IMMOBILE)
{
// determine direction from this soldier in which the noise lies
ubNoiseDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sNoiseGridNo),CenterY(sNoiseGridNo));
ubNoiseDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sNoiseGridNo);
// if soldier is not already facing in that direction,
// and the noise source is close enough that it could possibly be seen
@@ -849,7 +849,7 @@ INT8 CreatureDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if (!TileIsOutOfBounds(sClosestOpponent))
{
// determine direction from this soldier to the closest opponent
ubOpponentDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
// if soldier is not already facing in that direction,
// and the opponent is close enough that he could possibly be seen
@@ -1410,7 +1410,7 @@ INT8 CreatureDecideActionBlack( SOLDIERTYPE * pSoldier )
}
else if (GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints) // turn to face enemy
{
bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
bDirection = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
// if we're not facing towards him
if (pSoldier->ubDirection != bDirection && ValidCreatureTurn( pSoldier, bDirection ) )
+42 -43
View File
@@ -473,8 +473,7 @@ INT8 DecideActionSchedule( SOLDIERTYPE * pSoldier )
switch( pSoldier->bAIScheduleProgress )
{
case 0:
sX = CenterX( pSoldier->sOffWorldGridNo );
sY = CenterY( pSoldier->sOffWorldGridNo );
ConvertGridNoToCenterCellXY(pSoldier->sOffWorldGridNo, &sX, &sY);
pSoldier->EVENT_SetSoldierPosition( sX, sY );
pSoldier->bInSector = TRUE;
MoveSoldierFromAwayToMercSlot( pSoldier );
@@ -565,7 +564,7 @@ INT8 DecideActionBoxerEnteringRing(SOLDIERTYPE *pSoldier)
if (!TileIsOutOfBounds(sDesiredMercLoc))
{
// see if we are facing this person
ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sDesiredMercLoc),CenterY(sDesiredMercLoc));
ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sDesiredMercLoc);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir && pSoldier->InternalIsValidStance( ubDesiredMercDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) )
@@ -626,7 +625,7 @@ INT8 DecideActionNamedNPC( SOLDIERTYPE * pSoldier )
}
// see if we are facing this person
ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sDesiredMercLoc),CenterY(sDesiredMercLoc));
ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sDesiredMercLoc);
// if not already facing in that direction,
if (pSoldier->ubDirection != ubDesiredMercDir && pSoldier->InternalIsValidStance( ubDesiredMercDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) )
@@ -782,7 +781,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
UINT8 ubRingDir;
// face ring!
ubRingDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(CENTER_OF_RING),CenterY(CENTER_OF_RING));
ubRingDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, CENTER_OF_RING);
if ( gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints )
{
if ( pSoldier->ubDirection != ubRingDir )
@@ -966,7 +965,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
{
// see if we are facing this person
UINT8 ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(MercPtrs[ubPerson]->sGridNo),CenterY(MercPtrs[ubPerson]->sGridNo));
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -1495,8 +1494,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
UINT8 ubNoiseDir;
if (TileIsOutOfBounds(sNoiseGridNo) ||
(ubNoiseDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sNoiseGridNo),CenterY(sNoiseGridNo))
) == pSoldier->ubDirection )
( ubNoiseDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sNoiseGridNo) ) == pSoldier->ubDirection )
{
pSoldier->aiData.usActionData = PreRandom(8);
@@ -1668,7 +1666,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
{
// see if we are facing this person
UINT8 ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(MercPtrs[ubPerson]->sGridNo),CenterY(MercPtrs[ubPerson]->sGridNo));
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -1721,7 +1719,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
{
// see if we are facing this person
UINT8 ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(MercPtrs[ubPerson]->sGridNo),CenterY(MercPtrs[ubPerson]->sGridNo));
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -1798,7 +1796,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
////////////////////////////////////////////////////////////////////////////
// determine direction from this soldier in which the noise lies
ubNoiseDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sNoiseGridNo),CenterY(sNoiseGridNo));
ubNoiseDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sNoiseGridNo);
// if soldier is not already facing in that direction,
// and the noise source is close enough that it could possibly be seen
@@ -2737,15 +2735,16 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if (BestThrow.ubPossible)
{
// 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"));
ubOpponentDir = AIDirection(pSoldier->sGridNo, BestThrow.sTarget);
@@ -3293,7 +3292,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
{
// see if we are facing this person
UINT8 ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(MercPtrs[ubPerson]->sGridNo),CenterY(MercPtrs[ubPerson]->sGridNo));
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -3341,7 +3340,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
{
// see if we are facing this person
UINT8 ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(MercPtrs[ubPerson]->sGridNo),CenterY(MercPtrs[ubPerson]->sGridNo));
UINT8 ubDesiredMercDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo);
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
@@ -4521,7 +4520,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if (!TileIsOutOfBounds(sClosestOpponent))
{
// determine direction from this soldier to the closest opponent
ubOpponentDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
// if soldier is not already facing in that direction,
// and the opponent is close enough that he could possibly be seen
@@ -4625,7 +4624,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if (!TileIsOutOfBounds(sClosestDisturbance))
{
ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestDisturbance ), CenterY( sClosestDisturbance ) );
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestDisturbance);
if ( pSoldier->ubDirection == ubOpponentDir )
{
ubOpponentDir = (UINT8) PreRandom( NUM_WORLD_DIRECTIONS );
@@ -4768,7 +4767,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if (!gfTurnBasedAI || (GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) + GetAPsToChangeStance( pSoldier, ANIM_CROUCH )) <= pSoldier->bActionPoints)
{
// determine direction from this soldier to the closest opponent
ubOpponentDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
if (!WeaponReady(pSoldier) &&
pSoldier->ubDirection == ubOpponentDir &&
@@ -4802,7 +4801,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
if (!TileIsOutOfBounds(sClosestDisturbance))
{
ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestDisturbance ), CenterY( sClosestDisturbance ) );
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestDisturbance);
if ( pSoldier->ubDirection != ubOpponentDir )
{
if ( !gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints )
@@ -5505,7 +5504,7 @@ INT16 ubMinAPCost;
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);
@@ -6325,7 +6324,7 @@ INT16 ubMinAPCost;
}
// 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
@@ -6442,7 +6441,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
@@ -6994,7 +6993,7 @@ L_NEWAIM:
if(!TileIsOutOfBounds(pSoldier->sLastTarget))
sClosestOpponent = pSoldier->sLastTarget;
pSoldier->aiData.bNextAction = AI_ACTION_CHANGE_FACING;
pSoldier->aiData.usNextActionData = atan8(CenterX(sBestCover),CenterY(sBestCover),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
pSoldier->aiData.usNextActionData = GetDirectionFromCenterCellXYGridNo(sBestCover, sClosestOpponent);
}
return(AI_ACTION_TAKE_COVER);
}
@@ -7088,7 +7087,7 @@ L_NEWAIM:
// if we have a closest seen opponent
if (!TileIsOutOfBounds(sClosestOpponent))
{
bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
bDirection = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
// if we're not facing towards him
if (pSoldier->ubDirection != bDirection)
@@ -7149,7 +7148,7 @@ L_NEWAIM:
{
if(!TileIsOutOfBounds(pSoldier->sLastTarget))//dnl ch58 150913
sClosestOpponent = pSoldier->sLastTarget;
bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
bDirection = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
// if we're not facing towards him
if ( pSoldier->ubDirection != bDirection && pSoldier->InternalIsValidStance( bDirection, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) )
@@ -7801,7 +7800,7 @@ INT8 ArmedVehicleDecideActionGreen( SOLDIERTYPE *pSoldier )
UINT8 ubNoiseDir;
if ( TileIsOutOfBounds( sNoiseGridNo ) ||
(ubNoiseDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sNoiseGridNo ), CenterY( sNoiseGridNo ) )
(ubNoiseDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sNoiseGridNo)
) == pSoldier->ubDirection )
{
@@ -7904,7 +7903,7 @@ INT8 ArmedVehicleDecideActionYellow( SOLDIERTYPE *pSoldier )
////////////////////////////////////////////////////////////////////////////
// determine direction from this soldier in which the noise lies
ubNoiseDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sNoiseGridNo ), CenterY( sNoiseGridNo ) );
ubNoiseDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sNoiseGridNo);
// if soldier is not already facing in that direction,
// and the noise source is close enough that it could possibly be seen
@@ -8405,10 +8404,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 );
@@ -9153,7 +9152,7 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
if ( bHighestWatchLoc != -1 )
{
// see if we need turn to face that location
ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( gsWatchedLoc[pSoldier->ubID][bHighestWatchLoc] ), CenterY( gsWatchedLoc[pSoldier->ubID][bHighestWatchLoc] ) );
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, gsWatchedLoc[pSoldier->ubID][bHighestWatchLoc]);
// if soldier is not already facing in that direction,
// and the opponent is close enough that he could possibly be seen
@@ -9339,7 +9338,7 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
if ( !TileIsOutOfBounds( sClosestOpponent ) )
{
// determine direction from this soldier to the closest opponent
ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestOpponent ), CenterY( sClosestOpponent ) );
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
// if soldier is not already facing in that direction,
// and the opponent is close enough that he could possibly be seen
@@ -9384,7 +9383,7 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
if ( !TileIsOutOfBounds( sClosestDisturbance ) )
{
ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestDisturbance ), CenterY( sClosestDisturbance ) );
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestDisturbance);
if ( pSoldier->ubDirection == ubOpponentDir )
{
ubOpponentDir = (UINT8)PreRandom( NUM_WORLD_DIRECTIONS );
@@ -9435,7 +9434,7 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier)
if ( !TileIsOutOfBounds( sClosestDisturbance ) )
{
ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestDisturbance ), CenterY( sClosestDisturbance ) );
ubOpponentDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestDisturbance);
if ( pSoldier->ubDirection != ubOpponentDir )
{
if ( !gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints )
@@ -9801,7 +9800,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 );
@@ -10019,7 +10018,7 @@ INT8 ArmedVehicleDecideActionBlack( SOLDIERTYPE *pSoldier )
if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical )
{
// first get the direction, as we will need to pass that in to ShootingStanceChange
bDirection = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( BestAttack.sTarget ), CenterY( BestAttack.sTarget ) );
bDirection = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, BestAttack.sTarget);
// Change facing
if ( pSoldier->ubDirection != bDirection && pSoldier->InternalIsValidStance( bDirection, gAnimControl[pSoldier->usAnimState].ubEndHeight ) )
@@ -10306,7 +10305,7 @@ INT8 ArmedVehicleDecideActionBlack( SOLDIERTYPE *pSoldier )
{
if ( !TileIsOutOfBounds( pSoldier->sLastTarget ) )//dnl ch58 150913
sClosestOpponent = pSoldier->sLastTarget;
bDirection = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestOpponent ), CenterY( sClosestOpponent ) );
bDirection = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sClosestOpponent);
// if we're not facing towards him
if ( pSoldier->ubDirection != bDirection && pSoldier->InternalIsValidStance( bDirection, gAnimControl[pSoldier->usAnimState].ubEndHeight ) )
+3 -3
View File
@@ -1988,7 +1988,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
if ( pItem->usItemClass == IC_GUN && (*pObj)[0]->data.objectStatus >= MINIMUM_REQUIRED_STATUS )
{
// maybe this gun has ammo (adjust for whether it is better than ours!)
if ( (*pObj)[0]->data.gun.bGunAmmoStatus < 0 || (*pObj)[0]->data.gun.ubGunShotsLeft == 0 || (Item[pObj->usItem].fingerprintid && (*pObj)[0]->data.ubImprintID != NOBODY && (*pObj)[0]->data.ubImprintID != pSoldier->ubID) )
if ( (*pObj)[0]->data.gun.bGunAmmoStatus < 0 || (*pObj)[0]->data.gun.ubGunShotsLeft == 0 || (ItemHasFingerPrintID(pObj->usItem) && (*pObj)[0]->data.ubImprintID != NOBODY && (*pObj)[0]->data.ubImprintID != pSoldier->ubID) )
{
iTempValue = 0;
}
@@ -2029,7 +2029,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
if (pItem->usItemClass & IC_WEAPON && (*pObj)[0]->data.objectStatus >= MINIMUM_REQUIRED_STATUS )
{
DebugAI(AI_MSG_INFO, pSoldier, String("weapon has good status"));
if ( (pItem->usItemClass & IC_GUN) && ((*pObj)[0]->data.gun.bGunAmmoStatus < 0 || (*pObj)[0]->data.gun.ubGunShotsLeft == 0 || (( Item[pObj->usItem].fingerprintid ) && (*pObj)[0]->data.ubImprintID != NOBODY && (*pObj)[0]->data.ubImprintID != pSoldier->ubID) ) )
if ( (pItem->usItemClass & IC_GUN) && ((*pObj)[0]->data.gun.bGunAmmoStatus < 0 || (*pObj)[0]->data.gun.ubGunShotsLeft == 0 || (ItemHasFingerPrintID(pObj->usItem) && (*pObj)[0]->data.ubImprintID != NOBODY && (*pObj)[0]->data.ubImprintID != pSoldier->ubID) ) )
{
// jammed or out of ammo, skip it!
DebugAI(AI_MSG_INFO, pSoldier, String("jammed or out of ammo, skip it!"));
@@ -2080,7 +2080,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
if ( pItem->usItemClass & IC_WEAPON && (*pObj)[0]->data.objectStatus >= MINIMUM_REQUIRED_STATUS )
{
DebugAI(AI_MSG_INFO, pSoldier, String("gun has good status"));
if ( (pItem->usItemClass & IC_GUN) && ((*pObj)[0]->data.gun.bGunAmmoStatus < 0 || (*pObj)[0]->data.gun.ubGunShotsLeft == 0 || (( Item[pObj->usItem].fingerprintid ) && (*pObj)[0]->data.ubImprintID != NOBODY && (*pObj)[0]->data.ubImprintID != pSoldier->ubID) ) )
if ( (pItem->usItemClass & IC_GUN) && ((*pObj)[0]->data.gun.bGunAmmoStatus < 0 || (*pObj)[0]->data.gun.ubGunShotsLeft == 0 || (ItemHasFingerPrintID(pObj->usItem) && (*pObj)[0]->data.ubImprintID != NOBODY && (*pObj)[0]->data.ubImprintID != pSoldier->ubID) ) )
{
// jammed or out of ammo, skip it!
DebugAI(AI_MSG_INFO, pSoldier, String("jammed or out of ammo, skip it!"));
+7 -7
View File
@@ -808,7 +808,7 @@ INT32 GetEffectiveApproachValue( UINT8 usProfile, UINT8 usApproach, CHAR16* apSt
if ( apStr )
{
swprintf( atStr, szLaptopStatText[0], threateneffectiveness );
swprintf( atStr, szLaptopStatText[LAPTOP_STAT_TEXT_THREATEN_EFFECTIVENESS], threateneffectiveness );
wcscat( apStr, atStr );
}
@@ -818,7 +818,7 @@ INT32 GetEffectiveApproachValue( UINT8 usProfile, UINT8 usApproach, CHAR16* apSt
{
if ( apStr )
{
swprintf( atStr, szLaptopStatText[1], gMercProfiles[usProfile].bLeadership );
swprintf( atStr, szLaptopStatText[LAPTOP_STAT_TEXT_LEADERSHIP], gMercProfiles[usProfile].bLeadership );
wcscat( apStr, atStr );
}
@@ -829,7 +829,7 @@ INT32 GetEffectiveApproachValue( UINT8 usProfile, UINT8 usApproach, CHAR16* apSt
if ( apStr )
{
swprintf( atStr, szLaptopStatText[2], approachfactor );
swprintf( atStr, szLaptopStatText[LAPTOP_STAT_TEXT_APPROACH_MODIFIER], approachfactor );
wcscat( apStr, atStr );
}
@@ -855,7 +855,7 @@ INT32 GetEffectiveApproachValue( UINT8 usProfile, UINT8 usApproach, CHAR16* apSt
if ( apStr )
{
swprintf( atStr, szLaptopStatText[3], bgmodifier );
swprintf( atStr, szLaptopStatText[LAPTOP_STAT_TEXT_BACKGROUND_MODIFIER], bgmodifier );
wcscat( apStr, atStr );
}
@@ -868,7 +868,7 @@ INT32 GetEffectiveApproachValue( UINT8 usProfile, UINT8 usApproach, CHAR16* apSt
swprintf( atStr, L" \n" );
wcscat( apStr, atStr );
swprintf( atStr, szLaptopStatText[4] );
swprintf( atStr, szLaptopStatText[LAPTOP_STAT_TEXT_ASSERTIVE] );
wcscat( apStr, atStr );
}
else if ( DoesMercHavePersonality( pSoldier, CHAR_TRAIT_MALICIOUS ) )
@@ -876,7 +876,7 @@ INT32 GetEffectiveApproachValue( UINT8 usProfile, UINT8 usApproach, CHAR16* apSt
swprintf( atStr, L" \n" );
wcscat( apStr, atStr );
swprintf( atStr, szLaptopStatText[5] );
swprintf( atStr, szLaptopStatText[LAPTOP_STAT_TEXT_MALICIOUS] );
wcscat( apStr, atStr );
}
}
@@ -1149,7 +1149,7 @@ UINT8 NPCConsiderReceivingItemFromMerc( UINT8 ubNPC, UINT8 ubMerc, OBJECTTYPE *
ubLastQuoteRecord = NUM_NPC_QUOTE_RECORDS - 1;
usItemToConsider = pObj->usItem;
if ( Item[ usItemToConsider ].usItemClass == IC_GUN && !Item[usItemToConsider].rocketlauncher )
if ( Item[ usItemToConsider ].usItemClass == IC_GUN && !ItemIsRocketLauncher(usItemToConsider) )
{
UINT8 ubWeaponClass;
+1
View File
@@ -10,6 +10,7 @@
#include "Queen Command.h"
void MakeClosestEnemyChosenOne()
{
UINT32 cnt;
+3 -3
View File
@@ -13,9 +13,9 @@
#include "Quests.h"
#include "GameSettings.h"
// needed to use the modularized tactical AI:
#include "ModularizedTacticalAI/include/Plan.h"
#include "ModularizedTacticalAI/include/PlanFactoryLibrary.h"
#include "ModularizedTacticalAI/include/AbstractPlanFactory.h"
#include "Plan.h"
#include "PlanFactoryLibrary.h"
#include "AbstractPlanFactory.h"
UINT16 RealtimeDelay( SOLDIERTYPE * pSoldier )