mirror of
https://github.com/1dot13/source.git
synced 2026-08-26 14:30:26 +02:00
************************************************************
* Merged Source Code from Development Trunk: Revision 4063 * ************************************************************ - Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP - This will be the Source for the Beta 2011 Test git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -236,3 +236,14 @@ INT8 FindDirectionForClimbing( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel
|
||||
INT16 AssessTacticalSituation( INT8 bSide );
|
||||
BOOLEAN TeamSeesOpponent( INT8 bSide, SOLDIERTYPE * pOpponent );
|
||||
INT32 CalcStraightThreatValue( SOLDIERTYPE *pEnemy );
|
||||
|
||||
// SANDRO - added following functions
|
||||
BOOLEAN DoctorIsPresent( SOLDIERTYPE * pPatient, BOOLEAN fOnDoctorAssignmentCheck );
|
||||
BOOLEAN AIDetermineStealingWeaponAttempt( SOLDIERTYPE * pSoldier, SOLDIERTYPE * ubOpponent );
|
||||
|
||||
// HEADROCK HAM 4: Calculate average recoil offset for a shot.
|
||||
FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubShotNum);
|
||||
|
||||
|
||||
// HEADROCK HAM 4: Calculate average recoil offset for a shot.
|
||||
FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubShotNum);
|
||||
|
||||
+93
-3
@@ -55,6 +55,7 @@
|
||||
#include "Queen Command.h"
|
||||
#include "cheats.h"
|
||||
#include "points.h"
|
||||
#include "Soldier Functions.h" // added by SANDRO
|
||||
#endif
|
||||
|
||||
#include "connect.h"
|
||||
@@ -2043,6 +2044,23 @@ void AIDecideRadioAnimation( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 GetTankCannonIndex()
|
||||
{
|
||||
UINT32 tankCannonIndex = 0;
|
||||
|
||||
for (UINT32 i = 0; i < MAXITEMS; i++)
|
||||
{
|
||||
if (Item[i].cannon)
|
||||
{
|
||||
tankCannonIndex = Item[i].uiIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tankCannonIndex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
@@ -2056,8 +2074,29 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
// reset this field, too
|
||||
pSoldier->aiData.bLastAttackHit = FALSE;
|
||||
|
||||
// WANNE.TANK: Choose cannon or rocket
|
||||
UINT16 usHandItem = pSoldier->inv[HANDPOS].usItem;
|
||||
|
||||
if (TANK(pSoldier))
|
||||
{
|
||||
// No cannon selected to fire
|
||||
if (!Item[pSoldier->inv[HANDPOS].usItem].cannon)
|
||||
{
|
||||
// 50 % chance, that the tank fires with the explosive cannon
|
||||
UINT32 fireWithCannon = GetRndNum(2);
|
||||
if (fireWithCannon)
|
||||
{
|
||||
UINT32 tankCannonIndex = GetTankCannonIndex();
|
||||
if (tankCannonIndex > 0)
|
||||
{
|
||||
usHandItem = tankCannonIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT16 usSoldierIndex; // added by SANDRO
|
||||
|
||||
#ifdef TESTAICONTROL
|
||||
if (gfTurnBasedAI || gTacticalStatus.fAutoBandageMode)
|
||||
{
|
||||
@@ -2065,7 +2104,7 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
#endif
|
||||
|
||||
DebugAI( String( "%d does %s (a.d. %d) at time %ld", pSoldier->ubID, gzActionStr[pSoldier->aiData.bAction], pSoldier->aiData.usActionData, GetJA2Clock() ) );
|
||||
DebugAI( String( "%d does %s (a.d. %d) at time %lu", pSoldier->ubID, gzActionStr[pSoldier->aiData.bAction], pSoldier->aiData.usActionData, GetJA2Clock() ) );
|
||||
|
||||
// 0verhaul: The decideaction stage does so many path plots and overrides that
|
||||
// relying on a stored path from there is a bad idea.
|
||||
@@ -2183,7 +2222,17 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
case AI_ACTION_LEAVE_WATER_GAS: // seek nearest spot of ungassed land
|
||||
case AI_ACTION_SEEK_NOISE: // seek most important noise heard
|
||||
case AI_ACTION_RUN_AWAY: // run away from nearby opponent(s)
|
||||
|
||||
// SANDRO - ENEMY TAUNTS
|
||||
if (gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] == TRUE && pSoldier->bTeam == ENEMY_TEAM && SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) && pSoldier->bVisible != -1 )
|
||||
{
|
||||
if ( Random( 5 ) == 0 )
|
||||
{
|
||||
if (pSoldier->aiData.bAction == AI_ACTION_SEEK_NOISE )
|
||||
StartEnemyTaunt( pSoldier, TAUNT_SEEK_NOISE );
|
||||
else if (pSoldier->aiData.bAction == AI_ACTION_RUN_AWAY )
|
||||
StartEnemyTaunt( pSoldier, TAUNT_RUN_AWAY );
|
||||
}
|
||||
}
|
||||
case AI_ACTION_APPROACH_MERC: // walk up to someone to talk
|
||||
case AI_ACTION_TRACK: // track by ground scent
|
||||
case AI_ACTION_EAT: // monster approaching corpse
|
||||
@@ -2400,8 +2449,28 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
// ATE: Make sure it's a person :)
|
||||
if ( IS_MERC_BODY_TYPE( pSoldier ) && pSoldier->ubProfile == NO_PROFILE )
|
||||
{
|
||||
// SANDRO - SOLDIER TAUNTS
|
||||
if (gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] == TRUE && pSoldier->bTeam == ENEMY_TEAM && SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) )
|
||||
{
|
||||
if ( Random( 8 ) == 0 )
|
||||
{
|
||||
if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_GUN )
|
||||
StartEnemyTaunt( pSoldier, TAUNT_FIRE_GUN );
|
||||
else if (Item[pSoldier->inv[HANDPOS].usItem].grenadelauncher || Item[pSoldier->inv[HANDPOS].usItem].mortar || Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher )
|
||||
StartEnemyTaunt( pSoldier, TAUNT_FIRE_LAUNCHER );
|
||||
else if (pSoldier->aiData.bAction == AI_ACTION_TOSS_PROJECTILE && Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_THROWN && !Item[pSoldier->inv[HANDPOS].usItem].flare )
|
||||
StartEnemyTaunt( pSoldier, TAUNT_THROW );
|
||||
else if (pSoldier->aiData.bAction == AI_ACTION_KNIFE_MOVE )
|
||||
{
|
||||
if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_BLADE )
|
||||
StartEnemyTaunt( pSoldier, TAUNT_CHARGE_KNIFE );
|
||||
//else if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_PUNCH )
|
||||
// StartEnemyTaunt( pSoldier, TAUNT_CHARGE_HTH );
|
||||
}
|
||||
}
|
||||
}
|
||||
// CC, ATE here - I put in some TEMP randomness...
|
||||
if ( Random( 50 ) == 0 )
|
||||
else if ( Random( 50 ) == 0 )
|
||||
{
|
||||
StartCivQuote( pSoldier );
|
||||
}
|
||||
@@ -2489,6 +2558,15 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
HandleInitialRedAlert(pSoldier->bTeam, TRUE);
|
||||
}
|
||||
|
||||
// SANDRO - ENEMY TAUNTS
|
||||
if (gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] == TRUE && pSoldier->bTeam == ENEMY_TEAM && SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) && pSoldier->bVisible != -1 )
|
||||
{
|
||||
if ( Random( 4 ) == 0 )
|
||||
{
|
||||
StartEnemyTaunt( pSoldier, TAUNT_ALERT );
|
||||
}
|
||||
}
|
||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Debug: AI radios your position!" );
|
||||
// DROP THROUGH HERE!
|
||||
case AI_ACTION_YELLOW_ALERT: // tell friends opponent(s) heard
|
||||
@@ -2679,6 +2757,18 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
// start the offer of surrender!
|
||||
StartCivQuote( pSoldier );
|
||||
break;
|
||||
/////////////////////////////////////////////////////////////
|
||||
// SANDRO - added a possibility for enemies to try to steal your gun
|
||||
case AI_ACTION_STEAL_MOVE: // preparing to steal opponents weapon
|
||||
|
||||
pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
|
||||
pSoldier->usUIMovementMode = DetermineMovementMode( pSoldier, AI_ACTION_KNIFE_MOVE );
|
||||
usSoldierIndex = WhoIsThere2( pSoldier->aiData.usActionData, pSoldier->bTargetLevel);
|
||||
if ( usSoldierIndex != NOBODY )
|
||||
MercStealFromMerc( pSoldier, MercPtrs[usSoldierIndex] );
|
||||
|
||||
break;
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
default:
|
||||
#ifdef BETAVERSION
|
||||
|
||||
+29
-15
@@ -23,8 +23,14 @@
|
||||
#include "environment.h"
|
||||
#include "lighting.h"
|
||||
#include "Soldier Create.h"
|
||||
#include "SkillCheck.h" // added by SANDRO
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - In this file, all APBPConstants[AP_CROUCH] and APBPConstants[AP_PRONE] were changed to GetAPsCrouch() and GetAPsProne()
|
||||
// On the bottom here, there are these functions made
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// CJC's DG->JA2 conversion notes
|
||||
//
|
||||
@@ -151,9 +157,9 @@ UINT8 StanceChange( SOLDIERTYPE * pSoldier, INT16 ubAttackAPCost )
|
||||
|
||||
if (PTR_STANDING)
|
||||
{
|
||||
if (pSoldier->bActionPoints - ubAttackAPCost >= APBPConstants[AP_CROUCH])
|
||||
if (pSoldier->bActionPoints - ubAttackAPCost >= GetAPsCrouch(pSoldier, TRUE))
|
||||
{
|
||||
if ( (pSoldier->bActionPoints - ubAttackAPCost >= APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE]) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
|
||||
if ( (pSoldier->bActionPoints - ubAttackAPCost >= GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE)) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
|
||||
{
|
||||
return( ANIM_PRONE );
|
||||
}
|
||||
@@ -165,7 +171,7 @@ UINT8 StanceChange( SOLDIERTYPE * pSoldier, INT16 ubAttackAPCost )
|
||||
}
|
||||
else if (PTR_CROUCHED)
|
||||
{
|
||||
if ( (pSoldier->bActionPoints - ubAttackAPCost >= APBPConstants[AP_PRONE]) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
|
||||
if ( (pSoldier->bActionPoints - ubAttackAPCost >= GetAPsProne(pSoldier, TRUE)) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
|
||||
{
|
||||
return( ANIM_PRONE );
|
||||
}
|
||||
@@ -192,7 +198,7 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b
|
||||
uiCurrChanceOfDamage = 0;
|
||||
|
||||
bAPsAfterAttack = pSoldier->bActionPoints - MinAPsToAttack( pSoldier, pAttack->sTarget, ADDTURNCOST, 1);
|
||||
if (bAPsAfterAttack < APBPConstants[AP_CROUCH])
|
||||
if (bAPsAfterAttack < GetAPsCrouch(pSoldier, TRUE))
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
@@ -220,7 +226,7 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b
|
||||
for (bLoop = 0; bLoop < 3; bLoop++)
|
||||
{
|
||||
bStanceDiff = abs( bLoop - bStanceNum );
|
||||
if (bStanceDiff == 2 && bAPsAfterAttack < APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE])
|
||||
if (bStanceDiff == 2 && bAPsAfterAttack < GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE))
|
||||
{
|
||||
// can't consider this!
|
||||
continue;
|
||||
@@ -487,7 +493,7 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
|
||||
break;
|
||||
|
||||
case AI_ACTION_PICKUP_ITEM: // grab things lying on the ground
|
||||
bMinPointsNeeded = __max( MinPtsToMove( pSoldier ), APBPConstants[AP_PICKUP_ITEM] );
|
||||
bMinPointsNeeded = __max( MinPtsToMove( pSoldier ), GetBasicAPsToPickupItem( pSoldier ) ); // SANDRO
|
||||
break;
|
||||
|
||||
case AI_ACTION_OPEN_OR_CLOSE_DOOR:
|
||||
@@ -497,7 +503,7 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
|
||||
break;
|
||||
|
||||
case AI_ACTION_DROP_ITEM:
|
||||
bMinPointsNeeded = APBPConstants[AP_PICKUP_ITEM];
|
||||
bMinPointsNeeded = GetBasicAPsToPickupItem( pSoldier ); // SANDRO
|
||||
break;
|
||||
|
||||
case AI_ACTION_FIRE_GUN: // shoot at nearby opponent
|
||||
@@ -534,7 +540,7 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
|
||||
break;
|
||||
|
||||
case AI_ACTION_CHANGE_STANCE: // crouch
|
||||
bMinPointsNeeded = APBPConstants[AP_CROUCH];
|
||||
bMinPointsNeeded = GetAPsCrouch(pSoldier, TRUE);
|
||||
break;
|
||||
|
||||
case AI_ACTION_GIVE_AID: // help injured/dying friend
|
||||
@@ -542,16 +548,17 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
|
||||
break;
|
||||
|
||||
case AI_ACTION_CLIMB_ROOF:
|
||||
// SANDRO - improved this a bit
|
||||
if (pSoldier->pathing.bLevel == 0)
|
||||
{
|
||||
if( PTR_CROUCHED ) bAPForStandUp = 2;
|
||||
if( PTR_PRONE ) bAPForStandUp = 4;
|
||||
bMinPointsNeeded = APBPConstants[AP_CLIMBROOF] + bAPForStandUp + bAPToLookAtWall;
|
||||
if( PTR_CROUCHED ) bAPForStandUp = (INT8)(GetAPsCrouch(pSoldier, TRUE));
|
||||
if( PTR_PRONE ) bAPForStandUp = GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE);
|
||||
bMinPointsNeeded = GetAPsToClimbRoof( pSoldier, FALSE ) + bAPForStandUp + bAPToLookAtWall;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !PTR_CROUCHED ) bAPForStandUp = 2;
|
||||
bMinPointsNeeded = APBPConstants[AP_CLIMBOFFROOF] + bAPForStandUp + bAPToLookAtWall;
|
||||
if( !PTR_CROUCHED ) bAPForStandUp = (INT8)(GetAPsCrouch(pSoldier, TRUE));
|
||||
bMinPointsNeeded = GetAPsToClimbRoof( pSoldier, TRUE ) + bAPForStandUp + bAPToLookAtWall;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -564,6 +571,10 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
|
||||
bMinPointsNeeded = 0;
|
||||
break;
|
||||
|
||||
case AI_ACTION_STEAL_MOVE: // added by SANDRO
|
||||
//bMinPointsNeeded = GetAPsToStealItem( pSoldier, NULL, pSoldier->aiData.usActionData );;
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef BETAVERSION
|
||||
//NumMessage("AffordableAction - Illegal action type = ",pSoldier->aiData.bAction);
|
||||
@@ -2084,6 +2095,9 @@ INT8 CalcMorale(SOLDIERTYPE *pSoldier)
|
||||
(pSoldier->aiData.bAttitude == BRAVESOLO || pSoldier->aiData.bAttitude == BRAVEAID))
|
||||
bMoraleCategory = MORALE_WORRIED;
|
||||
|
||||
// SANDRO - on Insane difficulty enemy morale cannot go below worried
|
||||
if (bMoraleCategory == MORALE_HOPELESS && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
bMoraleCategory = MORALE_WORRIED;
|
||||
|
||||
#ifdef DEBUGDECISIONS
|
||||
STR tempstr;
|
||||
@@ -2128,7 +2142,7 @@ INT32 CalcManThreatValue( SOLDIERTYPE *pEnemy, INT32 sMyGrid, UINT8 ubReduceForC
|
||||
else
|
||||
{
|
||||
// ADD twice the man's level (2-20)
|
||||
iThreatValue += pEnemy->stats.bExpLevel;
|
||||
iThreatValue += EffectiveExpLevel(pEnemy); // SANDRO - find precise effective exp level
|
||||
|
||||
// ADD man's total action points (10-35)
|
||||
iThreatValue += pEnemy->CalcActionPoints();
|
||||
@@ -2725,7 +2739,7 @@ INT32 CalcStraightThreatValue( SOLDIERTYPE *pEnemy )
|
||||
else
|
||||
{
|
||||
// ADD twice the man's level (2-20)
|
||||
iThreatValue += pEnemy->stats.bExpLevel;
|
||||
iThreatValue += EffectiveExpLevel(pEnemy); // SANDRO - find precise effective exp level
|
||||
|
||||
// ADD man's total action points (10-35)
|
||||
iThreatValue += pEnemy->CalcActionPoints();
|
||||
|
||||
+326
-32
@@ -21,6 +21,7 @@
|
||||
#include "environment.h"
|
||||
#include "lighting.h"
|
||||
#include "Sound Control.h"
|
||||
#include "message.h"
|
||||
#endif
|
||||
|
||||
extern INT16 DirIncrementer[8];
|
||||
@@ -115,6 +116,36 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
}
|
||||
|
||||
// FROM SB JA2005
|
||||
void ResetWeaponMode( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
// ATE: Don't do this if in a fire amimation.....
|
||||
if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIRE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pSoldier->bWeaponMode = WM_NORMAL;
|
||||
|
||||
//<DR>
|
||||
pSoldier->aiData.bShownAimTime = REFINE_AIM_1;
|
||||
|
||||
//!pSoldier->aiData.ubBurstAP = 0; //SB reset long burst length
|
||||
//^^^^òàêîãî ñâîéñòâà íåò, äîáàâëÿòü â ñîëæåð êîíòðîë.õ
|
||||
// gfDisplayFullCountRing = FALSE;
|
||||
// gfDisplayFullCountRingBurst = FALSE;
|
||||
//</DR>
|
||||
// pSoldier->bDoBurst = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].mode[WM_NORMAL].usROF > 0;
|
||||
|
||||
// DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
|
||||
// gfUIForceReExamineCursorData = TRUE;
|
||||
|
||||
// gfShowBurstLength = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].mode[pSoldier->bWeaponMode].usROF > 0;
|
||||
// gfShowBurstLength = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].mode[pSoldier->bWeaponMode].ubBullets > 1;
|
||||
|
||||
}
|
||||
//</SB>
|
||||
|
||||
void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUnseen)
|
||||
{
|
||||
UINT32 uiLoop;
|
||||
@@ -254,9 +285,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
|
||||
|
||||
if ( TANK( pSoldier ) )
|
||||
{
|
||||
// HEADROCK HAM 3.6: Calculation must take into account APBP constants and other aiming modifications!
|
||||
INT8 bAPsLeft = pSoldier->bActionPoints - ubMinAPcost;
|
||||
ubMaxPossibleAimTime = CalcAimingLevelsAvailableWithAP( pSoldier, pOpponent->sGridNo, bAPsLeft );
|
||||
ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost;
|
||||
|
||||
// always burst
|
||||
if ( ubMaxPossibleAimTime < ubBurstAPs )
|
||||
@@ -291,11 +320,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
|
||||
//sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit);
|
||||
//PopMessage(tempstr);
|
||||
|
||||
// HEADROCK HAM 3.6: Actual aiming time is no longer 1AP per level... Failure to take this into account
|
||||
// may yield skewed results in favour of high-aim targets.
|
||||
INT16 sActualAimTime = CalcAPCostForAiming( pSoldier, pOpponent->sGridNo, (INT8)ubAimTime );
|
||||
|
||||
iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + sActualAimTime);
|
||||
iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime);
|
||||
//NumMessage("hitRate = ",iHitRate);
|
||||
|
||||
// if aiming for this amount of time produces a better hit rate
|
||||
@@ -501,7 +526,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
|
||||
if ( EXPLOSIVE_GUN( usInHand ) )
|
||||
{
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"explosive gun");
|
||||
iTossRange = Weapon[ usInHand ].usRange / CELL_X_SIZE;
|
||||
iTossRange = GetModifiedGunRange(usInHand) / CELL_X_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1068,7 +1093,8 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
|
||||
}
|
||||
|
||||
// calculate the maximum possible aiming time
|
||||
ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPcost);
|
||||
// HEADROCK HAM 4: Required for new Aiming Level Limits function
|
||||
ubMaxPossibleAimTime = min( AllowedAimingLevels(pSoldier, sGridNo), pSoldier->bActionPoints - ubMinAPcost);
|
||||
DebugMsg(TOPIC_JA2 , DBG_LEVEL_3 , String("Max Possible Aim Time = %d",ubMaxPossibleAimTime ));
|
||||
|
||||
// calc next attack's minimum AP cost (excludes readying & turning)
|
||||
@@ -1282,7 +1308,8 @@ void CalcBestStab(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab, BOOLEAN fBladeAt
|
||||
iBestHitRate = 0; // reset best hit rate to minimum
|
||||
|
||||
// calculate the maximum possible aiming time
|
||||
ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPCost);
|
||||
// HEADROCK HAM 4: Required for new Aiming Level Limits function
|
||||
ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier, pOpponent->sGridNo),pSoldier->bActionPoints - ubMinAPCost);
|
||||
//NumMessage("Max Possible Aim Time = ",ubMaxPossibleAimTime);
|
||||
|
||||
// consider the various aiming times
|
||||
@@ -1433,8 +1460,9 @@ void CalcTentacleAttack(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab )
|
||||
if (pSoldier->pathing.bLevel != pOpponent->pathing.bLevel)
|
||||
continue; // next merc
|
||||
|
||||
UINT16 usRange = GetModifiedGunRange(CREATURE_QUEEN_TENTACLES);
|
||||
// if this opponent is outside the range of our tentacles
|
||||
if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ) > Weapon[ CREATURE_QUEEN_TENTACLES].usRange )
|
||||
if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ) > usRange )
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
@@ -1609,10 +1637,16 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT16 ub
|
||||
// calculate distance to target, obtain his gun's maximum range rating
|
||||
|
||||
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo );
|
||||
iMaxRange = Weapon[usItem].usRange;
|
||||
// SANDRO - added specific range calculation
|
||||
if ( Item[ usItem ].usItemClass & IC_GUN )
|
||||
iMaxRange = GunRange( pObj, pSoldier );
|
||||
else
|
||||
iMaxRange = GetModifiedGunRange(usItem);
|
||||
|
||||
// bullet loses speed and penetrating power, 50% loss per maximum range
|
||||
iPowerLost = ((50 * iRange) / iMaxRange);
|
||||
// SANDRO - you know, 50% is a lot, it often leads to negative damage values in the end
|
||||
// while there is no true effect of this in game !!! Made it 25%!
|
||||
iPowerLost = ((25 * iRange) / iMaxRange);
|
||||
|
||||
// up to 50% extra impact for making particularly accurate successful shots
|
||||
ubBonus = ubChanceToHit / 4; // /4 is really /2 and /2 again
|
||||
@@ -1641,7 +1675,7 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT16 ub
|
||||
|
||||
// check for ceramic plates; these do affect monster spit
|
||||
for (attachmentList::iterator iter = pOpponent->inv[VESTPOS][0]->attachments.begin(); iter != pOpponent->inv[VESTPOS][0]->attachments.end(); ++iter) {
|
||||
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
|
||||
if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists() )
|
||||
{
|
||||
iTorsoProt += (INT32) Armour[Item[iter->usItem].ubClassIndex].ubProtection *
|
||||
(INT32) (*iter)[0]->data.objectStatus / 100;
|
||||
@@ -1745,7 +1779,7 @@ INT32 EstimateThrowDamage( SOLDIERTYPE *pSoldier, UINT8 ubItemPos, SOLDIERTYPE *
|
||||
else if ( Item[pSoldier->inv[ ubItemPos ].usItem].rocketlauncher || Item[pSoldier->inv[ ubItemPos ].usItem].grenadelauncher || Item[pSoldier->inv[ ubItemPos ].usItem].mortar )
|
||||
{
|
||||
OBJECTTYPE* pAttachment = FindLaunchableAttachment(&pSoldier->inv[ ubItemPos ],pSoldier->inv[ ubItemPos ].usItem ) ;
|
||||
if ( pAttachment )
|
||||
if ( pAttachment->exists() )
|
||||
ubExplosiveIndex = Item[pAttachment->usItem].ubClassIndex;
|
||||
else
|
||||
return 0;
|
||||
@@ -1843,21 +1877,44 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
|
||||
}
|
||||
else
|
||||
{
|
||||
// NB martial artists don't get a bonus for using brass knuckles!
|
||||
if (pSoldier->usAttackingWeapon && !( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS ) ) )
|
||||
// this all was a little changed for enhanced close combat system - SANDRO
|
||||
if ( gGameExternalOptions.fEnhancedCloseCombatSystem )
|
||||
{
|
||||
iImpact = GetDamage(&pSoldier->inv[HANDPOS]);
|
||||
iImpact = EffectiveStrength( pSoldier ) / 5; // 0 to 20 for strength, adjusted by damage taken
|
||||
|
||||
if ( pSoldier->usAttackingWeapon )
|
||||
{
|
||||
iImpact += GetDamage(&pSoldier->inv[HANDPOS]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// base HTH damage
|
||||
iImpact += 4; // Slightly reduced for we can now attack to head for bigger damage - SANDRO
|
||||
// Add melee damage multiplier to bare HtH attacks as well - SANDRO
|
||||
// actually I make the influence a little lesser, because to the blades and so,
|
||||
// only the item impact is multiplied, not the level and strength bonus, but here it does
|
||||
iImpact += iImpact * gGameExternalOptions.iMeleeDamageModifier / 120;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// base HTH damage
|
||||
iImpact = 5;
|
||||
|
||||
// NB martial artists don't get a bonus for using brass knuckles!
|
||||
if (pSoldier->usAttackingWeapon && !( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) ) )
|
||||
{
|
||||
iImpact = GetDamage(&pSoldier->inv[HANDPOS]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// base HTH damage
|
||||
iImpact = 5;
|
||||
}
|
||||
iImpact += EffectiveStrength( pSoldier ) / 5; // 0 to 20 for strength, adjusted by damage taken
|
||||
}
|
||||
iImpact += EffectiveStrength( pSoldier ) / 5; // 0 to 20 for strength, adjusted by damage taken
|
||||
}
|
||||
|
||||
|
||||
iImpact += (pSoldier->stats.bExpLevel / 2); // 0 to 4 for level
|
||||
iImpact += (EffectiveExpLevel( pSoldier ) / 2); // 0 to 4 for level // SANDRO - added effective level calc
|
||||
|
||||
iFluke = 0;
|
||||
iBonus = ubChanceToHit / 4; // up to 50% extra impact for accurate attacks
|
||||
@@ -1867,17 +1924,81 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
|
||||
if (!fBladeAttack)
|
||||
{
|
||||
// add bonuses for hand-to-hand and martial arts
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS ) )
|
||||
// Check for new traits - SANDRO
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
iImpact = iImpact * (100 + gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS ) ) / 100;
|
||||
if (!pSoldier->usAttackingWeapon || Item[pSoldier->inv[HANDPOS].usItem].brassknuckles)
|
||||
{
|
||||
// add bonuses for martial arts
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
|
||||
{
|
||||
// also add breath damage bonus into consideration
|
||||
iImpact = (INT32)((iImpact * ( 100 + (gSkillTraitValues.ubMABonusDamageHandToHand + gSkillTraitValues.ubMABonusBreathDamageHandToHand) * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) ) / 100) + 0.5);
|
||||
|
||||
|
||||
// The Spinning kicks or aimed punch bonus - SANDRO
|
||||
//if (pSoldier->usAnimState == NINJA_SPINKICK || (pSoldier->aiData.bAimTime > 0))
|
||||
//{
|
||||
// iImpact += (iImpact * gSkillTraitValues.usMAAimedPunchDamageBonus * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) ) / 100; // +75% damage per trait
|
||||
//}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// +30% damage of blunt weapons for melee character
|
||||
if (HAS_SKILL_TRAIT( pSoldier, MELEE_NT ))
|
||||
{
|
||||
iImpact = (INT32)((iImpact * (100 + gSkillTraitValues.ubMEDamageBonusBlunt)/100) + 0.5);
|
||||
|
||||
//if (pSoldier->aiData.bAimTime > 0)
|
||||
//{
|
||||
// iImpact += (iImpact * (100 + gSkillTraitValues.usMEAimedMeleeAttackDamageBonus) / 100); // 50% incresed damage if focused melee attack
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND ) )
|
||||
else
|
||||
{
|
||||
iImpact = iImpact * (100 + gbSkillTraitBonus[HANDTOHAND] * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND ) ) / 100;
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) )
|
||||
{
|
||||
iImpact = (INT32)((iImpact * (100 + gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT ) ) / 100) + 0.5);
|
||||
}
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
|
||||
{
|
||||
iImpact = (INT32)((iImpact * (100 + gbSkillTraitBonus[HANDTOHAND_OT] * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND_OT ) ) / 100) + 0.5);
|
||||
}
|
||||
}
|
||||
// SANDRO - Enhanced Close Combat System - aiming at body parts makes difference
|
||||
if (gGameExternalOptions.fEnhancedCloseCombatSystem && (gAnimControl[ pOpponent->usAnimState ].ubEndHeight == ANIM_PRONE))
|
||||
{
|
||||
iImpact = (INT32)(iImpact * 150 / 100); // 50% incresed damage to lying characters
|
||||
}
|
||||
// Here, if we're doing a bare-fisted attack,
|
||||
// we want to pay attention just to wounds inflicted
|
||||
iImpact = iImpact / PUNCH_REAL_DAMAGE_PORTION;
|
||||
// SANDRO - No, we may consider the breath damage as asort of "real" damage too, so only reduce it by half
|
||||
iImpact = iImpact / 2;
|
||||
//iImpact = iImpact / PUNCH_REAL_DAMAGE_PORTION;
|
||||
}
|
||||
// SANDRO - damage bonus to melee trait
|
||||
else
|
||||
{
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, MELEE_NT ) && (gGameOptions.fNewTraitSystem) )
|
||||
{
|
||||
iImpact += (iImpact * (100 + gSkillTraitValues.ubMEDamageBonusBlades ) / 100); // +30% damage
|
||||
|
||||
//if (pSoldier->aiData.bAimTime > 0)
|
||||
//{
|
||||
// iImpact += (iImpact * ( 100 + gSkillTraitValues.usMEAimedMeleeAttackDamageBonus ) / 100); // 50% incresed damage if focused melee attack
|
||||
//}
|
||||
}
|
||||
// SANDRO - Enhanced Close Combat System
|
||||
if (gGameExternalOptions.fEnhancedCloseCombatSystem)
|
||||
{
|
||||
if (gAnimControl[ pOpponent->usAnimState ].ubEndHeight == ANIM_PRONE)
|
||||
{
|
||||
iImpact = (INT32)(iImpact * 140 / 100); // 40% incresed damage to lying characters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (iImpact < 1)
|
||||
@@ -1914,7 +2035,24 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
(*pObj)[0]->data.gun.ubGunState |= GS_CARTRIDGE_IN_CHAMBER;
|
||||
|
||||
DeductPoints(pSoldier, Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually, 0);
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// STOMP traits - SANDRO
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
// Sniper trait makes chambering a round faster
|
||||
if (( Weapon[Item[(pObj)->usItem].ubClassIndex].ubWeaponType == GUN_SN_RIFLE || Weapon[Item[(pObj)->usItem].ubClassIndex].ubWeaponType == GUN_RIFLE ) && HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ))
|
||||
DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubSNChamberRoundAPsReduction * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )))/100) + 0.5), 0);
|
||||
// Ranger trait makes pumping shotguns faster
|
||||
else if (( Weapon[Item[(pObj)->usItem].ubClassIndex].ubWeaponType == GUN_SHOTGUN ) && HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
|
||||
DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubRAPumpShotgunsAPsReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT )))/100) + 0.5), 0);
|
||||
else
|
||||
DeductPoints(pSoldier, Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeductPoints(pSoldier, Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually, 0);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PlayJA2Sample( Weapon[ Item[pObj->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
|
||||
@@ -1942,7 +2080,24 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
(*pObj2)[0]->data.gun.ubGunState |= GS_CARTRIDGE_IN_CHAMBER;
|
||||
|
||||
DeductPoints(pSoldier, Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually, 0);
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// STOMP traits - SANDRO (well, I don't know any one-handed sniper rifle, but what the hell...)
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
// Sniper trait makes chambering a round faster
|
||||
if (( Weapon[Item[(pObj2)->usItem].ubClassIndex].ubWeaponType == GUN_SN_RIFLE || Weapon[Item[(pObj2)->usItem].ubClassIndex].ubWeaponType == GUN_RIFLE ) && HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ))
|
||||
DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubSNChamberRoundAPsReduction * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )))/100) + 0.5), 0);
|
||||
// Ranger trait makes pumping shotguns faster
|
||||
else if (( Weapon[Item[(pObj2)->usItem].ubClassIndex].ubWeaponType == GUN_SHOTGUN ) && HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
|
||||
DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubRAPumpShotgunsAPsReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT )))/100) + 0.5), 0);
|
||||
else
|
||||
DeductPoints(pSoldier, Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeductPoints(pSoldier, Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually, 0);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PlayJA2Sample( Weapon[ Item[pObj2->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
|
||||
@@ -2492,10 +2647,10 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s
|
||||
// (suppressionFire && IsGunAutofireCapable(&pSoldier->inv[pBestShot->bWeaponIn] ) && GetMagSize(pObj) > 30 && (*pObj)[0]->data.gun.ubGunShotsLeft > 20 ))
|
||||
BOOLEAN fEnableAISuppression = FALSE;
|
||||
|
||||
if ( gGameExternalOptions.fIncreaseAISuppressionFire && ((!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) ||
|
||||
if ( gGameExternalOptions.fIncreaseAISuppressionFire && ((!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj, pSoldier) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) || // SANDRO - added argument to GunRange()
|
||||
(suppressionFire && IsGunAutofireCapable(&pSoldier->inv[pBestShot->bWeaponIn]))) )
|
||||
fEnableAISuppression = TRUE;
|
||||
else if ( !gGameExternalOptions.fIncreaseAISuppressionFire && ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) ||
|
||||
else if ( !gGameExternalOptions.fIncreaseAISuppressionFire && ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj, pSoldier) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) || // SANDRO - added argument
|
||||
(suppressionFire && IsGunAutofireCapable(&pSoldier->inv[pBestShot->bWeaponIn] ) && GetMagSize(pObj) > 30 && (*pObj)[0]->data.gun.ubGunShotsLeft > 20 )))
|
||||
fEnableAISuppression = TRUE;
|
||||
|
||||
@@ -2523,3 +2678,142 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SANDRO - function to determine if we should try to steal the enemy gun
|
||||
BOOLEAN AIDetermineStealingWeaponAttempt( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent )
|
||||
{
|
||||
INT16 sChance = 0;
|
||||
UINT32 uiSuccessChance = 0;
|
||||
|
||||
if( pOpponent == NULL )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if( pOpponent->bTeam != gbPlayerNum )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if( pOpponent->bCollapsed || pOpponent->bBreathCollapsed )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
pSoldier->usUIMovementMode = RUNNING;
|
||||
if( pSoldier->bActionPoints < GetAPsToStealItem( pSoldier, NULL, pOpponent->sGridNo ) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if( (pOpponent->inv[HANDPOS].exists() != true) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
if ( !(Item[pOpponent->inv[HANDPOS].usItem].usItemClass & IC_WEAPON) )
|
||||
{
|
||||
UINT16 dfgvdfv = Item[pOpponent->inv[HANDPOS].usItem].usItemClass;
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
uiSuccessChance = CalcChanceToSteal(pSoldier, pOpponent, 0);
|
||||
if ( uiSuccessChance >= 100 )
|
||||
{
|
||||
sChance = 90;
|
||||
}
|
||||
else if ( uiSuccessChance >= 85 )
|
||||
{
|
||||
sChance = 75;
|
||||
}
|
||||
else if ( uiSuccessChance >= 70 )
|
||||
{
|
||||
sChance = 60;
|
||||
}
|
||||
else if ( uiSuccessChance >= 50 )
|
||||
{
|
||||
sChance = 40;
|
||||
}
|
||||
else if ( uiSuccessChance >= 25 )
|
||||
{
|
||||
sChance = 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
if( !HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
else if( NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) > 1 )
|
||||
{
|
||||
sChance += 50;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) && !HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
else if(( NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT ) > 1 ) || ( NUM_SKILL_TRAITS( pSoldier, HANDTOHAND_OT ) > 1 ))
|
||||
{
|
||||
sChance += 25;
|
||||
}
|
||||
}
|
||||
|
||||
if( pSoldier->stats.bLife < pSoldier->stats.bLifeMax )
|
||||
{
|
||||
sChance -= (pSoldier->stats.bLifeMax - pSoldier->stats.bLife);
|
||||
}
|
||||
if( pSoldier->bBreath < pSoldier->bBreathMax )
|
||||
{
|
||||
sChance -= ((pSoldier->bBreathMax - pSoldier->bBreath) / 2);
|
||||
}
|
||||
|
||||
if( pOpponent->stats.bLife < pOpponent->stats.bLifeMax )
|
||||
{
|
||||
sChance += (pOpponent->stats.bLifeMax - pOpponent->stats.bLife);
|
||||
}
|
||||
if( pOpponent->bBreath < pOpponent->bBreathMax )
|
||||
{
|
||||
sChance += ((pOpponent->bBreathMax - pOpponent->bBreath) / 2);
|
||||
}
|
||||
|
||||
if( pSoldier->bActionPoints > (GetAPsToStealItem( pSoldier, NULL, pOpponent->sGridNo ) + (2 * ApsToPunch( pSoldier ))) )
|
||||
{
|
||||
sChance += 35;
|
||||
}
|
||||
else if ( pSoldier->bActionPoints > (GetAPsToStealItem( pSoldier, NULL, pOpponent->sGridNo ) + ApsToPunch( pSoldier )) )
|
||||
{
|
||||
sChance += 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
sChance -= 10;
|
||||
}
|
||||
|
||||
if( Chance( sChance ) )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
// HEADROCK HAM 4: This is required for the AI to be able to assess the length of autofire volleys using the new
|
||||
// recoil system.
|
||||
FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubShotNum)
|
||||
{
|
||||
INT8 bRecoilX = 0;
|
||||
INT8 bRecoilY = 0;
|
||||
GetRecoil( pWeapon, &bRecoilX, &bRecoilY, ubShotNum );
|
||||
// Return average shooter's ability to control this gun.
|
||||
// HEADROCK HAM 4: TODO: Incorporate items that alter max counter-force.
|
||||
FLOAT AverageRecoil = __max(0, ((FLOAT)sqrt( (FLOAT)(bRecoilX * bRecoilX) + (FLOAT)(bRecoilY * bRecoilY) ) - (gGameCTHConstants.RECOIL_MAX_COUNTER_FORCE * 0.7f) ) );
|
||||
return AverageRecoil;
|
||||
}
|
||||
+324
-94
@@ -36,6 +36,11 @@
|
||||
#include "connect.h"
|
||||
#include "Text.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - In this file, all APBPConstants[AP_CROUCH] and APBPConstants[AP_PRONE] were changed to GetAPsCrouch() and GetAPsProne()
|
||||
// On the bottom here, there are these functions made
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern BOOLEAN gfHiddenInterrupt;
|
||||
extern BOOLEAN gfUseAlternateQueenPosition;
|
||||
|
||||
@@ -845,9 +850,36 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
|
||||
|
||||
}
|
||||
|
||||
//ddd{
|
||||
if(gGameExternalOptions.bNewTacticalAIBehavior
|
||||
&& !( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
|
||||
&& pSoldier->bTeam == ENEMY_TEAM)
|
||||
{
|
||||
|
||||
INT32 cnt;
|
||||
ROTTING_CORPSE * pCorpse;
|
||||
|
||||
|
||||
for ( cnt = 0; cnt < giNumRottingCorpse; cnt++ )
|
||||
{
|
||||
pCorpse = &(gRottingCorpse[ cnt ] );
|
||||
|
||||
if ( pCorpse->fActivated && pCorpse->def.ubAIWarningValue > 0 )
|
||||
if ( PythSpacesAway( pSoldier->sGridNo, pCorpse->def.sGridNo ) <= 5 )//ïðèäåëàòü ñðàâíåíèå ïåðåìåííî äàëüíîñòè âèäåíèÿ (smaxvid ?)
|
||||
{
|
||||
//ïðîâåðèòü, íàõîäèòñÿ ëè òðóï â ïîëå çðåíèÿ äðàíèêà.ìåíòà?
|
||||
//CHRISL: Shouldn't we be using the corpse's bLevel? Otherwise a soldier inside a building can see a corpse on the roof of that building
|
||||
//if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
|
||||
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pCorpse->def.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
|
||||
{
|
||||
ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, L"Warning: enemy corpse found!!!" );
|
||||
//pCorpse->def.ubAIWarningValue=0;
|
||||
gRottingCorpse[ cnt ].def.ubAIWarningValue=0;
|
||||
return( AI_ACTION_RED_ALERT );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//ddd}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// POINT PATROL: move towards next point unless getting a bit winded
|
||||
@@ -2204,7 +2236,10 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
if (BestThrow.ubPossible)
|
||||
{
|
||||
// if firing mortar make sure we have room
|
||||
if ( Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar )
|
||||
//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 )
|
||||
{
|
||||
ubOpponentDir = GetDirectionFromGridNo( BestThrow.sTarget, pSoldier );
|
||||
|
||||
@@ -2311,7 +2346,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
OBJECTTYPE * gun = &pSoldier->inv[BestShot.bWeaponIn];
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: men in sector %d, ubspotters called by %d, nobody %d",gTacticalStatus.Team[pSoldier->bTeam].bMenInSector,gTacticalStatus.ubSpottersCalledForBy,NOBODY ));
|
||||
//if ( ( ( IsScoped(gun) && GunRange(gun) > pSoldier->GetMaxDistanceVisible(BestShot.sTarget, BestShot.bTargetLevel) ) || pSoldier->aiData.bOrders == SNIPER ) &&
|
||||
if ( ( ( IsScoped(gun) && GunRange(gun) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) &&
|
||||
if ( ( ( IsScoped(gun) && GunRange(gun, pSoldier) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) && // SANDRO - added argument
|
||||
(gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) &&
|
||||
(gTacticalStatus.ubSpottersCalledForBy == NOBODY))
|
||||
|
||||
@@ -2360,17 +2395,30 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
pSoldier->aiData.usActionData = BestShot.sTarget;
|
||||
//pSoldier->aiData.bAimTime = BestShot.ubAimTime;
|
||||
INT16 ubBurstAPs = 0;
|
||||
FLOAT dTotalRecoil = 0;
|
||||
|
||||
pSoldier->bDoAutofire = 0;
|
||||
do
|
||||
{
|
||||
pSoldier->bDoAutofire++;
|
||||
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
if(UsingNewCTHSystem() == true){
|
||||
do
|
||||
{
|
||||
INT8 bRecoilX = 0;
|
||||
INT8 bRecoilY = 0;
|
||||
pSoldier->bDoAutofire++;
|
||||
dTotalRecoil += AICalcRecoilForShot( pSoldier, &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
}
|
||||
while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire
|
||||
&& dTotalRecoil <= 10.0f );
|
||||
} else {
|
||||
do
|
||||
{
|
||||
pSoldier->bDoAutofire++;
|
||||
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
}
|
||||
while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs &&
|
||||
pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
|
||||
GetAutoPenalty(&pSoldier->inv[ pSoldier->ubAttackingHand ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80 );
|
||||
}
|
||||
while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs &&
|
||||
pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
|
||||
GetAutoPenalty(&pSoldier->inv[ pSoldier->ubAttackingHand ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80 );
|
||||
|
||||
|
||||
pSoldier->bDoAutofire--;
|
||||
|
||||
@@ -2385,7 +2433,8 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
pSoldier->bDoBurst = 1;
|
||||
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[ MSG113_SUPPRESSIONFIRE ] );
|
||||
Menptr[BestShot.ubOpponent].ubSuppressionPoints += pSoldier->bDoAutofire;
|
||||
// HEADROCK HAM 4: This is the stupidest thing ever.
|
||||
// Menptr[BestShot.ubOpponent].ubSuppressionPoints += pSoldier->bDoAutofire;
|
||||
Menptr[BestShot.ubOpponent].ubSuppressorID = pSoldier->ubID;
|
||||
return( AI_ACTION_FIRE_GUN );
|
||||
}
|
||||
@@ -2463,6 +2512,11 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
if ( ubCanMove && InLightAtNight( pSoldier->sGridNo, pSoldier->pathing.bLevel ) && pSoldier->aiData.bOrders != STATIONARY )
|
||||
{
|
||||
//ddd ÷òîáû óáåãàëè, êîãäà ïîäñâåòÿò ôàëüøâåéåðîì íî÷üþ
|
||||
if(gGameExternalOptions.bNewTacticalAIBehavior)
|
||||
pSoldier->aiData.bAction = AI_ACTION_LEAVE_WATER_GAS;
|
||||
//ddd
|
||||
|
||||
pSoldier->aiData.usActionData = FindNearbyDarkerSpot( pSoldier );
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
@@ -2687,12 +2741,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: stop flanking");
|
||||
if (PythSpacesAway ( pSoldier->sGridNo, tempGridNo ) > MIN_FLANK_DIST_RED * 2 )
|
||||
{
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,tempGridNo,APBPConstants[AP_PRONE],AI_ACTION_SEEK_OPPONENT,0);
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,tempGridNo,GetAPsProne( pSoldier, TRUE),AI_ACTION_SEEK_OPPONENT,0);
|
||||
|
||||
if ( LocationToLocationLineOfSightTest( pSoldier->aiData.usActionData, pSoldier->pathing.bLevel, tempGridNo, pSoldier->pathing.bLevel, TRUE) )
|
||||
{
|
||||
// reserve APs for a possible crouch plus a shot
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, tempGridNo, (INT8) (MinAPsToAttack( pSoldier, tempGridNo, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, tempGridNo, (INT8) (MinAPsToAttack( pSoldier, tempGridNo, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
@@ -2815,7 +2869,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// try to move towards him
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,APBPConstants[AP_CROUCH],AI_ACTION_SEEK_OPPONENT,0);
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,GetAPsCrouch( pSoldier, TRUE),AI_ACTION_SEEK_OPPONENT,0);
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
@@ -2917,12 +2971,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
|
||||
if (TileIsOutOfBounds(pSoldier->aiData.usActionData) || pSoldier->numFlanks >= MAX_FLANKS_RED )
|
||||
{
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,APBPConstants[AP_CROUCH], AI_ACTION_SEEK_OPPONENT,0);
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,GetAPsCrouch( pSoldier, TRUE), AI_ACTION_SEEK_OPPONENT,0);
|
||||
//pSoldier->numFlanks = 0;
|
||||
if ( PythSpacesAway( pSoldier->aiData.usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->aiData.usActionData, pSoldier->pathing.bLevel, sClosestDisturbance, pSoldier->pathing.bLevel, TRUE ) )
|
||||
{
|
||||
// reserve APs for a possible crouch plus a shot
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
@@ -2960,7 +3014,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
if ( PythSpacesAway( pSoldier->aiData.usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->aiData.usActionData, pSoldier->pathing.bLevel, sClosestDisturbance, pSoldier->pathing.bLevel, TRUE ) )
|
||||
{
|
||||
// reserve APs for a possible crouch plus a shot
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
@@ -3058,7 +3112,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GO DIRECTLY TOWARDS CLOSEST FRIEND UNDER FIRE OR WHO LAST RADIOED
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestFriend,APBPConstants[AP_CROUCH], AI_ACTION_SEEK_OPPONENT,0);
|
||||
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestFriend,GetAPsCrouch( pSoldier, TRUE), AI_ACTION_SEEK_OPPONENT,0);
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
@@ -3148,7 +3202,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
{
|
||||
// either moving significantly closer or into very close range
|
||||
// ensure will we have enough APs for a possible crouch plus a shot
|
||||
if ( InternalGoAsFarAsPossibleTowards( pSoldier, pSoldier->aiData.usActionData, (INT8) (MinAPsToAttack( pSoldier, sClosestOpponent, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_TAKE_COVER, 0 ) == pSoldier->aiData.usActionData )
|
||||
if ( InternalGoAsFarAsPossibleTowards( pSoldier, pSoldier->aiData.usActionData, (INT8) (MinAPsToAttack( pSoldier, sClosestOpponent, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_TAKE_COVER, 0 ) == pSoldier->aiData.usActionData )
|
||||
{
|
||||
return(AI_ACTION_TAKE_COVER);
|
||||
}
|
||||
@@ -3425,7 +3479,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
if ( pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD )
|
||||
{
|
||||
// reduce bleeding by 1 point per AP (in RT, APs will get recalculated so it's okay)
|
||||
pSoldier->bBleeding = __max( 0, pSoldier->bBleeding - pSoldier->bActionPoints );
|
||||
pSoldier->bBleeding = __max( 0, pSoldier->bBleeding - (pSoldier->bActionPoints/2) );
|
||||
return( AI_ACTION_NONE ); // will end-turn/wait depending on whether we're in TB or realtime
|
||||
}
|
||||
#ifdef RECORDNET
|
||||
@@ -3936,7 +3990,9 @@ INT16 ubMinAPCost;
|
||||
{
|
||||
// look around for a worthy target (which sets BestShot.ubPossible)
|
||||
BOOLEAN shootUnseen = FALSE;
|
||||
if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM )
|
||||
///ddd
|
||||
//if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM ) //comm by ddd
|
||||
if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM || gGameExternalOptions.bNewTacticalAIBehavior)
|
||||
shootUnseen = TRUE;
|
||||
|
||||
CalcBestShot(pSoldier,&BestShot,shootUnseen);
|
||||
@@ -4125,6 +4181,107 @@ INT16 ubMinAPCost;
|
||||
RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY);
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - even if we don't have any blade, calculate how much damage we could do unarmed
|
||||
else if ( !TANK( pSoldier) )
|
||||
{
|
||||
bWeaponIn = FindAIUsableObjClass( pSoldier, IC_PUNCH );
|
||||
if (bWeaponIn == NO_SLOT) // if no punch-type weapon found, just calculate it with empty hands
|
||||
{
|
||||
bWeaponIn = FindEmptySlotWithin( pSoldier, HANDPOS, NUM_INV_SLOTS );
|
||||
}
|
||||
if (bWeaponIn != NO_SLOT)
|
||||
{
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"try to punch");
|
||||
BestStab.bWeaponIn = bWeaponIn;
|
||||
// if it's in his holster, swap it into his hand temporarily
|
||||
if (bWeaponIn != HANDPOS)
|
||||
{
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: about to rearrange pocket before punch check");
|
||||
RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY);
|
||||
}
|
||||
|
||||
// get the minimum cost to attack with punch
|
||||
ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,DONTADDTURNCOST);
|
||||
// if we can afford the minimum AP cost to punch
|
||||
if (pSoldier->bActionPoints >= ubMinAPCost)
|
||||
{
|
||||
// then look around for a worthy target (which sets BestStab.ubPossible)
|
||||
CalcBestStab(pSoldier,&BestStab, FALSE);
|
||||
|
||||
if (BestStab.ubPossible)
|
||||
{
|
||||
// if we have not enough APs to deal at least two or three punches,
|
||||
// reduce the attack value as one punch ain't much
|
||||
if( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
// if we are not specialized, reduce the attack attractiveness generaly
|
||||
if ( !HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
|
||||
{
|
||||
BestStab.iAttackValue /= 4;
|
||||
// if too far and not having APs for at least 3 hits no way to attack
|
||||
if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + (2 * (ApsToPunch( pSoldier )))) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1) )
|
||||
{
|
||||
BestStab.ubPossible = 0;
|
||||
BestStab.iAttackValue = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1)
|
||||
{
|
||||
BestStab.iAttackValue = (BestStab.iAttackValue * 2);
|
||||
}
|
||||
// if too far and not having APs for at least 2 hits
|
||||
else if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + ApsToPunch( pSoldier )) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1))
|
||||
{
|
||||
BestStab.iAttackValue /= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) && !HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
|
||||
{
|
||||
// if we are not specialized, reduce the attack attractiveness generaly
|
||||
BestStab.iAttackValue /= 4;
|
||||
// if too far and not having APs for at least 3 hits
|
||||
if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + (2 * (ApsToPunch( pSoldier )))) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget <= 1)) )
|
||||
{
|
||||
BestStab.ubPossible = 0;
|
||||
BestStab.iAttackValue = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BestStab.iAttackValue = ((BestStab.iAttackValue * 3)/2);
|
||||
|
||||
if (PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1)
|
||||
{
|
||||
BestStab.iAttackValue = ((BestStab.iAttackValue * 3)/2);
|
||||
}
|
||||
// if too far and not having APs for at least 2 hits
|
||||
else if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + ApsToPunch( pSoldier )) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget <= 1)) )
|
||||
{
|
||||
BestStab.iAttackValue /= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
// now we KNOW FOR SURE that we will do something (stab, at least)
|
||||
NPCDoesAct(pSoldier);
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to punch");
|
||||
}
|
||||
|
||||
}
|
||||
// if it was in his holster, swap it back into his holster for now
|
||||
if (bWeaponIn != HANDPOS)
|
||||
{
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to rearrange pocket after punch check");
|
||||
RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY);
|
||||
}
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CHOOSE THE BEST TYPE OF ATTACK OUT OF THOSE FOUND TO BE POSSIBLE
|
||||
@@ -4148,11 +4305,27 @@ INT16 ubMinAPCost;
|
||||
ubBestAttackAction = AI_ACTION_THROW_KNIFE;
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw knife");
|
||||
}
|
||||
else
|
||||
else if ( Item[ pSoldier->inv[BestStab.bWeaponIn].usItem ].usItemClass & IC_BLADE ) // SANDRO - check specifically for blade attack
|
||||
{
|
||||
ubBestAttackAction = AI_ACTION_KNIFE_MOVE;
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to stab");
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - added a chance to try to steal merc's gun from hands
|
||||
else
|
||||
{
|
||||
if (AIDetermineStealingWeaponAttempt( pSoldier, MercPtrs[BestStab.ubOpponent] ) == TRUE)
|
||||
{
|
||||
ubBestAttackAction = AI_ACTION_STEAL_MOVE;
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to steal weapon");
|
||||
}
|
||||
else
|
||||
{
|
||||
ubBestAttackAction = AI_ACTION_KNIFE_MOVE;
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to punch");
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
if (BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE)))
|
||||
{
|
||||
@@ -4223,6 +4396,10 @@ INT16 ubMinAPCost;
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = stab with a knife");
|
||||
memcpy(&BestAttack,&BestStab,sizeof(BestAttack));
|
||||
break;
|
||||
case AI_ACTION_STEAL_MOVE: // added by SANDRO
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = try to steal weapon");
|
||||
memcpy(&BestAttack,&BestStab,sizeof(BestAttack));
|
||||
break;
|
||||
|
||||
default:
|
||||
// set to empty
|
||||
@@ -4233,12 +4410,14 @@ INT16 ubMinAPCost;
|
||||
}
|
||||
|
||||
// NB a desire of 4 or more is only achievable by brave/aggressive guys with high morale
|
||||
UINT16 usRange = GetModifiedGunRange(pSoldier->inv[ BestAttack.bWeaponIn ].usItem);
|
||||
|
||||
if ( (pSoldier->bActionPoints == pSoldier->bInitialActionPoints) &&
|
||||
(ubBestAttackAction == AI_ACTION_FIRE_GUN) &&
|
||||
(pSoldier->aiData.bShock == 0) &&
|
||||
(pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2) &&
|
||||
(BestAttack.ubChanceToReallyHit < 30) &&
|
||||
(PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) > Weapon[ pSoldier->inv[ BestAttack.bWeaponIn ].usItem ].usRange / CELL_X_SIZE ) &&
|
||||
(PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) > usRange / CELL_X_SIZE ) &&
|
||||
(RangeChangeDesire( pSoldier ) >= 4) )
|
||||
{
|
||||
// okay, really got to wonder about this... could taking cover be an option?
|
||||
@@ -4383,7 +4562,7 @@ INT16 ubMinAPCost;
|
||||
if (ubBestAttackAction == AI_ACTION_FIRE_GUN)
|
||||
{
|
||||
// Do we need to change stance? NB We'll have to ready our gun again
|
||||
if ( !TANK( pSoldier ) && ( pSoldier->bActionPoints >= BestAttack.ubAPCost + APBPConstants[AP_CROUCH] + MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST, 1 ) ) )
|
||||
if ( !TANK( pSoldier ) && ( pSoldier->bActionPoints >= BestAttack.ubAPCost + GetAPsCrouch( pSoldier, TRUE) + MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST, 1 ) ) )
|
||||
{
|
||||
// since the AI considers shooting chance from standing primarily, if we are not
|
||||
// standing we should always consider a stance change
|
||||
@@ -4484,13 +4663,13 @@ INT16 ubMinAPCost;
|
||||
iChance = (25 / max((BestAttack.ubAimTime + 1),1));
|
||||
switch (pSoldier->aiData.bAttitude)
|
||||
{
|
||||
case DEFENSIVE: iChance += -5; break;
|
||||
case BRAVESOLO: iChance += 5; break;
|
||||
case BRAVEAID: iChance += 5; break;
|
||||
case CUNNINGSOLO: iChance += 0; break;
|
||||
case CUNNINGAID: iChance += 0; break;
|
||||
case AGGRESSIVE: iChance += 10; break;
|
||||
case ATTACKSLAYONLY:iChance += 30; break;
|
||||
case DEFENSIVE: iChance += -5; break;
|
||||
case BRAVESOLO: iChance += 5; break;
|
||||
case BRAVEAID: iChance += 5; break;
|
||||
case CUNNINGSOLO: iChance += 0; break;
|
||||
case CUNNINGAID: iChance += 0; break;
|
||||
case AGGRESSIVE: iChance += 10; break;
|
||||
case ATTACKSLAYONLY:iChance += 30; break;
|
||||
}
|
||||
|
||||
// HEADROCK HAM B2.6: Allows control over increased enemy burstfire.
|
||||
@@ -4510,10 +4689,10 @@ INT16 ubMinAPCost;
|
||||
iChance += 5 * ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) );
|
||||
}
|
||||
}
|
||||
|
||||
// HEADROCK HAM 3.6: due to the "else", this part of the formula is NEVER hit. Removing.
|
||||
//else if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY )
|
||||
if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY )
|
||||
|
||||
{
|
||||
iChance += 100;
|
||||
}
|
||||
@@ -4535,20 +4714,33 @@ INT16 ubMinAPCost;
|
||||
if (IsGunAutofireCapable( &pSoldier->inv[BestAttack.bWeaponIn] ) &&
|
||||
!(Menptr[BestShot.ubOpponent].stats.bLife < OKLIFE) && // don't burst at downed targets
|
||||
(( pSoldier->inv[BestAttack.bWeaponIn][0]->data.gun.ubGunShotsLeft > 1 &&
|
||||
BestAttack.ubAimTime != BURSTING ) || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) )
|
||||
!pSoldier->bDoBurst ) || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) )
|
||||
{
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: ENOUGH APs TO AUTOFIRE, RANDOM CHANCE OF DOING SO");
|
||||
|
||||
FLOAT dTotalRecoil = 0.0f;
|
||||
pSoldier->bDoAutofire = 0;
|
||||
do
|
||||
{
|
||||
pSoldier->bDoAutofire++;
|
||||
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
if(UsingNewCTHSystem() == true){
|
||||
do
|
||||
{
|
||||
INT8 bRecoilX = 0;
|
||||
INT8 bRecoilY = 0;
|
||||
pSoldier->bDoAutofire++;
|
||||
dTotalRecoil += AICalcRecoilForShot( pSoldier, &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
}
|
||||
while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs + sActualAimTime && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire
|
||||
&& dTotalRecoil <= 10.0f );
|
||||
} else {
|
||||
do
|
||||
{
|
||||
pSoldier->bDoAutofire++;
|
||||
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
}
|
||||
while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs &&
|
||||
pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
|
||||
GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80);
|
||||
}
|
||||
while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs &&
|
||||
pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
|
||||
GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80);
|
||||
|
||||
|
||||
|
||||
pSoldier->bDoAutofire--;
|
||||
if (pSoldier->bDoAutofire > 0)
|
||||
@@ -4606,20 +4798,24 @@ INT16 ubMinAPCost;
|
||||
|
||||
if ((INT32) PreRandom( 100 ) < iChance || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto)
|
||||
{
|
||||
BestAttack.ubAimTime = AUTOFIRING + pSoldier->bDoAutofire;
|
||||
BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire );
|
||||
pSoldier->aiData.bAimTime = BestAttack.ubAimTime ;
|
||||
pSoldier->bDoBurst = 1;
|
||||
BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire ) + sActualAimTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSoldier->bDoAutofire = 0;
|
||||
pSoldier->bDoBurst = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// HEADROCK HAM 3.6: No no no! This line removes all aiming from a potentially deadly single-shot! Commenting out.
|
||||
//pSoldier->aiData.bAimTime = 0;
|
||||
pSoldier->aiData.bAimTime = BestAttack.ubAimTime;
|
||||
pSoldier->bDoBurst = 0;
|
||||
pSoldier->bDoAutofire = 0;
|
||||
// not enough aps - do somthing else
|
||||
}
|
||||
}
|
||||
|
||||
if (!pSoldier->bDoBurst)
|
||||
{
|
||||
pSoldier->aiData.bAimTime = BestAttack.ubAimTime;
|
||||
pSoldier->bDoBurst = 0;
|
||||
pSoldier->bDoAutofire = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -4629,6 +4825,10 @@ INT16 ubMinAPCost;
|
||||
|
||||
|
||||
|
||||
// HEADROCK HAM 4: No longer necessary to do here. The conditions above already handle this, specifically
|
||||
// WITHOUT messing with the BestAttack.ubAimTime variable, since that can apply now even when bursting
|
||||
// or autofiring!!
|
||||
/*
|
||||
if (BestAttack.ubAimTime == BURSTING)
|
||||
{
|
||||
pSoldier->aiData.bAimTime = 0;
|
||||
@@ -4642,7 +4842,7 @@ INT16 ubMinAPCost;
|
||||
pSoldier->bDoAutofire = BestAttack.ubAimTime-AUTOFIRING;
|
||||
|
||||
BestAttack.ubAimTime = AUTOFIRING;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
else // defaults already set
|
||||
@@ -4669,6 +4869,32 @@ INT16 ubMinAPCost;
|
||||
}
|
||||
|
||||
}
|
||||
// SANDRO - chance to make aimed punch/stab for martial arts/melee
|
||||
else if (ubBestAttackAction == AI_ACTION_KNIFE_MOVE && gGameOptions.fNewTraitSystem)
|
||||
{
|
||||
pSoldier->aiData.bAimTime = 0;
|
||||
|
||||
if (Item[pSoldier->inv[BestAttack.bWeaponIn].usItem].usItemClass == IC_PUNCH)
|
||||
{
|
||||
if (HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT))
|
||||
{
|
||||
if( PreRandom( (gGameExternalOptions.fEnhancedCloseCombatSystem ? 2 : 0) + 2 * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT) ) > 2 )
|
||||
{
|
||||
pSoldier->aiData.bAimTime = (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HAS_SKILL_TRAIT( pSoldier, MELEE_NT))
|
||||
{
|
||||
if( PreRandom( gGameExternalOptions.fEnhancedCloseCombatSystem ? 3 : 1 ) > 0 )
|
||||
{
|
||||
pSoldier->aiData.bAimTime = (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// OTHERWISE, JUST GO AHEAD & ATTACK!
|
||||
@@ -4889,59 +5115,63 @@ INT16 ubMinAPCost;
|
||||
// if not in water and not already crouched, try to crouch down first
|
||||
if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints)
|
||||
{
|
||||
if ( !fCivilian && !gfHiddenInterrupt && IsValidStance( pSoldier, ANIM_CROUCH ) )
|
||||
if ( !fCivilian && !gfHiddenInterrupt && IsValidStance( pSoldier, ANIM_CROUCH ) && ubBestAttackAction != AI_ACTION_KNIFE_MOVE && ubBestAttackAction != AI_ACTION_KNIFE_STAB && ubBestAttackAction != AI_ACTION_STEAL_MOVE) // SANDRO - if knife attack don't crouch
|
||||
{
|
||||
pSoldier->aiData.usActionData = StanceChange( pSoldier, BestAttack.ubAPCost );
|
||||
if (pSoldier->aiData.usActionData != 0)
|
||||
// determine the location of the known closest opponent
|
||||
// (don't care if he's conscious, don't care if he's reachable at all)
|
||||
|
||||
sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL);
|
||||
// SANDRO - don't crouch if in close combat distance (we got penalties that way)
|
||||
if (PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) > 1 )
|
||||
{
|
||||
if (pSoldier->aiData.usActionData == ANIM_PRONE)
|
||||
pSoldier->aiData.usActionData = StanceChange( pSoldier, BestAttack.ubAPCost );
|
||||
if (pSoldier->aiData.usActionData != 0)
|
||||
{
|
||||
// we might want to turn before lying down!
|
||||
if ( (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints - GetAPsToChangeStance( pSoldier, (INT8) pSoldier->aiData.usActionData )) &&
|
||||
(((pSoldier->aiData.bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) )
|
||||
if (pSoldier->aiData.usActionData == ANIM_PRONE)
|
||||
{
|
||||
// determine the location of the known closest opponent
|
||||
// (don't care if he's conscious, don't care if he's reachable at all)
|
||||
|
||||
sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL);
|
||||
// if we have a closest seen opponent
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
// we might want to turn before lying down!
|
||||
if ( (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints - GetAPsToChangeStance( pSoldier, (INT8) pSoldier->aiData.usActionData )) &&
|
||||
(((pSoldier->aiData.bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) )
|
||||
{
|
||||
bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
|
||||
|
||||
// if we're not facing towards him
|
||||
if (pSoldier->ubDirection != bDirection)
|
||||
// if we have a closest seen opponent
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
{
|
||||
if ( pSoldier->InternalIsValidStance( bDirection, (INT8) pSoldier->aiData.usActionData) )
|
||||
bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
|
||||
|
||||
// if we're not facing towards him
|
||||
if (pSoldier->ubDirection != bDirection)
|
||||
{
|
||||
// change direction, THEN change stance!
|
||||
pSoldier->aiData.bNextAction = AI_ACTION_CHANGE_STANCE;
|
||||
pSoldier->aiData.usNextActionData = pSoldier->aiData.usActionData;
|
||||
pSoldier->aiData.usActionData = bDirection;
|
||||
if ( pSoldier->InternalIsValidStance( bDirection, (INT8) pSoldier->aiData.usActionData) )
|
||||
{
|
||||
// change direction, THEN change stance!
|
||||
pSoldier->aiData.bNextAction = AI_ACTION_CHANGE_STANCE;
|
||||
pSoldier->aiData.usNextActionData = pSoldier->aiData.usActionData;
|
||||
pSoldier->aiData.usActionData = bDirection;
|
||||
#ifdef DEBUGDECISIONS
|
||||
sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->aiData.usActionData);
|
||||
AIPopMessage(tempstr);
|
||||
sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->aiData.usActionData);
|
||||
AIPopMessage(tempstr);
|
||||
#endif
|
||||
return(AI_ACTION_CHANGE_FACING);
|
||||
}
|
||||
else if ( (pSoldier->aiData.usActionData == ANIM_PRONE) && (pSoldier->InternalIsValidStance( bDirection, ANIM_CROUCH) ) )
|
||||
{
|
||||
// we shouldn't go prone, since we can't turn to shoot
|
||||
pSoldier->aiData.usActionData = ANIM_CROUCH;
|
||||
pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
|
||||
return( AI_ACTION_CHANGE_STANCE );
|
||||
return(AI_ACTION_CHANGE_FACING);
|
||||
}
|
||||
else if ( (pSoldier->aiData.usActionData == ANIM_PRONE) && (pSoldier->InternalIsValidStance( bDirection, ANIM_CROUCH) ) )
|
||||
{
|
||||
// we shouldn't go prone, since we can't turn to shoot
|
||||
pSoldier->aiData.usActionData = ANIM_CROUCH;
|
||||
pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
|
||||
return( AI_ACTION_CHANGE_STANCE );
|
||||
}
|
||||
}
|
||||
// else we are facing in the right direction
|
||||
|
||||
}
|
||||
// else we are facing in the right direction
|
||||
|
||||
// else we don't know any enemies
|
||||
}
|
||||
// else we don't know any enemies
|
||||
}
|
||||
|
||||
// we don't want to turn
|
||||
// we don't want to turn
|
||||
}
|
||||
pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
|
||||
return( AI_ACTION_CHANGE_STANCE );
|
||||
}
|
||||
pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
|
||||
return( AI_ACTION_CHANGE_STANCE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
|
||||
#include "PathAIDebug.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - all "APBPConstants[AP_CROUCH]" and "APBPConstants[AP_PRONE]" here
|
||||
// were changed to GetAPsCrouch() and GetAPsProne()
|
||||
// - also all "APBPConstants[AP_PICKUP_ITEM]" were replaced by GetBasicAPsToPickupItem()
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
INT16 * gsCoverValue = NULL;
|
||||
#ifdef _DEBUG
|
||||
|
||||
@@ -128,13 +134,13 @@ INT8 CalcWorstCTGTForPosition( SOLDIERTYPE * pSoldier, UINT8 ubOppID, INT32 sOpp
|
||||
switch (bCubeLevel)
|
||||
{
|
||||
case 1:
|
||||
if (iMyAPsLeft < APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE])
|
||||
if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE) + GetAPsProne(pSoldier,TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (iMyAPsLeft < APBPConstants[AP_CROUCH])
|
||||
if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -168,13 +174,13 @@ INT8 CalcAverageCTGTForPosition( SOLDIERTYPE * pSoldier, UINT8 ubOppID, INT32 sO
|
||||
switch (bCubeLevel)
|
||||
{
|
||||
case 1:
|
||||
if (iMyAPsLeft < APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE])
|
||||
if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE) + GetAPsProne(pSoldier,TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (iMyAPsLeft < APBPConstants[AP_CROUCH])
|
||||
if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -430,7 +436,7 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
|
||||
{
|
||||
// if I CAN'T crouch when I get there, that makes it significantly less
|
||||
// appealing a spot (how much depends on range), so that's a penalty to me
|
||||
if (iMyAPsLeft < APBPConstants[AP_CROUCH])
|
||||
if (iMyAPsLeft < GetAPsCrouch(pMe,TRUE))
|
||||
// subtract another 1 % penalty for NOT being able to crouch per tile
|
||||
// the farther away we are, the bigger a difference crouching will make!
|
||||
iMyPosValue -= ((iMyPosValue * (AIM_PENALTY_TARGET_CROUCHED + (iRange / CELL_X_SIZE))) / 100);
|
||||
@@ -1662,7 +1668,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
|
||||
return AI_ACTION_NONE;
|
||||
}
|
||||
|
||||
if (pSoldier->bActionPoints < APBPConstants[AP_PICKUP_ITEM])
|
||||
if (pSoldier->bActionPoints < GetBasicAPsToPickupItem( pSoldier ))
|
||||
{
|
||||
return( AI_ACTION_NONE );
|
||||
}
|
||||
@@ -1719,7 +1725,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
|
||||
|
||||
// set an AP limit too, to our APs less the cost of picking up an item
|
||||
// and less the cost of dropping an item since we might need to do that
|
||||
gubNPCAPBudget = pSoldier->bActionPoints - APBPConstants[AP_PICKUP_ITEM];
|
||||
gubNPCAPBudget = pSoldier->bActionPoints - GetBasicAPsToPickupItem( pSoldier );
|
||||
|
||||
// reset the "reachable" flags in the region we're looking at
|
||||
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
|
||||
@@ -1922,7 +1928,12 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
|
||||
// WANNE: Fix a vanilla bug: When an enemy soldier is looking for items and finds a non-helmet/vest/leggings piece of armour it was incorrectly considered for pickup.
|
||||
// Fixed by Tron (Stracciatella): Revision: 5719
|
||||
// break;
|
||||
continue;
|
||||
// continue; <- silversurfer: bad idea, this causes the game to hang
|
||||
// to make sure that the item isn't considered set iTempValue to zero and get out
|
||||
{
|
||||
iTempValue = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1959,7 +1970,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
|
||||
//if (pSoldier->inv[HANDPOS].exists() == true && PlaceInAnyPocket(pSoldier, &pSoldier->inv[HANDPOS], false) == false)
|
||||
if (FindBetterSpotForItem( pSoldier, HANDPOS ) == FALSE)
|
||||
{
|
||||
if (pSoldier->bActionPoints < APBPConstants[AP_PICKUP_ITEM] + APBPConstants[AP_PICKUP_ITEM])
|
||||
if (pSoldier->bActionPoints < GetBasicAPsToPickupItem( pSoldier ) + GetBasicAPsToPickupItem( pSoldier ))
|
||||
{
|
||||
return( AI_ACTION_NONE );
|
||||
}
|
||||
@@ -1968,7 +1979,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
|
||||
// destroy this item!
|
||||
DebugAI( String( "%d decides he must drop %S first so destroys it", pSoldier->ubID, ItemNames[ pSoldier->inv[HANDPOS].usItem ] ) );
|
||||
DeleteObj( &(pSoldier->inv[HANDPOS]) );
|
||||
DeductPoints( pSoldier, APBPConstants[AP_PICKUP_ITEM], 0 );
|
||||
DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include "Buildings.h"
|
||||
#include "worldman.h"
|
||||
#include "Assignments.h"
|
||||
// added by SANDRO
|
||||
#include "Soldier Profile.h"
|
||||
#include "GameSettings.h"
|
||||
#endif
|
||||
|
||||
//forward declarations of common classes to eliminate includes
|
||||
@@ -465,3 +468,47 @@ INT8 DecideAutoBandage( SOLDIERTYPE * pSoldier )
|
||||
// do nothing
|
||||
return( AI_ACTION_NONE );
|
||||
}
|
||||
|
||||
// SANDRO - added a function
|
||||
BOOLEAN DoctorIsPresent( SOLDIERTYPE * pPatient, BOOLEAN fOnDoctorAssignmentCheck )
|
||||
{
|
||||
SOLDIERTYPE * pMedic = NULL;
|
||||
UINT8 cnt;
|
||||
INT8 bSlot;
|
||||
BOOLEAN fDoctorHasBeenFound = FALSE;
|
||||
|
||||
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
|
||||
for ( pMedic = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pMedic++)
|
||||
{
|
||||
if ( !(pMedic->bActive) || !(pMedic->bInSector) || ( pMedic->flags.uiStatusFlags & SOLDIER_VEHICLE ) || (pMedic->bAssignment == VEHICLE ) )
|
||||
{
|
||||
// is nowhere around!
|
||||
continue; // NEXT!!!
|
||||
}
|
||||
|
||||
if ( pPatient->ubID == pMedic->ubID )
|
||||
{
|
||||
// cannot make surgery on self!
|
||||
continue; // NEXT!!!
|
||||
}
|
||||
if ( fOnDoctorAssignmentCheck && pMedic->bAssignment != DOCTOR )
|
||||
{
|
||||
// not on the right assignment!
|
||||
continue; // NEXT!!!
|
||||
}
|
||||
|
||||
bSlot = FindMedKit( pMedic );
|
||||
if (bSlot == NO_SLOT)
|
||||
{
|
||||
// no medical kit!
|
||||
continue; // NEXT!!!
|
||||
}
|
||||
|
||||
if (pMedic->stats.bLife > OKLIFE && !(pMedic->bCollapsed) && pMedic->stats.bMedical > 0 && (NUM_SKILL_TRAITS( pMedic, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery))
|
||||
{
|
||||
fDoctorHasBeenFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return( fDoctorHasBeenFound );
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "overhead.h"
|
||||
#include "worldman.h"
|
||||
#include "pathai.h"
|
||||
#include "points.h"
|
||||
//#include "points.h"
|
||||
#include "message.h"
|
||||
#include "Smell.h"
|
||||
#include "mapscreen.h"
|
||||
@@ -720,7 +720,7 @@ INT32 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT32 sDesGrid, IN
|
||||
|
||||
if (pSoldier->usUIMovementMode == RUNNING)
|
||||
{
|
||||
sAPCost += APBPConstants[AP_START_RUN_COST];
|
||||
sAPCost += GetAPsStartRun( pSoldier ); // changed by SANDRO
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+160
-24
@@ -47,15 +47,21 @@
|
||||
#include "Scheduling.h"
|
||||
#include "Tactical Save.h"
|
||||
#include "Campaign Types.h"
|
||||
#include "GameSettings.h" // added by SANDRO
|
||||
#include "Soldier Profile.h"
|
||||
#endif
|
||||
|
||||
#include "Soldier Profile.h"
|
||||
//forward declarations of common classes to eliminate includes
|
||||
class OBJECTTYPE;
|
||||
class SOLDIERTYPE;
|
||||
|
||||
// WANNE - BMP: DONE!
|
||||
//SB: new .npc format
|
||||
#define NPCEX_SIGNATURE 0x00070000
|
||||
#define _MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((UINT32)(UINT8)(ch0) | ((UINT32)(UINT8)(ch1) << 8) | \
|
||||
((UINT32)(UINT8)(ch2) << 16) | ((UINT32)(UINT8)(ch3) << 24 ))
|
||||
|
||||
#define NPCEX_SIGNATURE _MAKEFOURCC('B','1','1','3')
|
||||
|
||||
#define NUM_CIVQUOTE_SECTORS 20
|
||||
#define MINERS_CIV_QUOTE_INDEX 16
|
||||
@@ -143,7 +149,9 @@ NPCQuoteInfo * LoadQuoteFile( UINT8 ubNPC )
|
||||
// use a copy of Herve's data file instead!
|
||||
sprintf( zFileName, "NPCData\\%03d.npc", HERVE );
|
||||
}
|
||||
else if ( ubNPC < FIRST_RPC || ubNPC >= GASTON || (ubNPC < FIRST_NPC && gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) )
|
||||
//else if ( ubNPC < FIRST_RPC || ubNPC >= GASTON || (ubNPC < FIRST_NPC && gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) )
|
||||
//new profiles by Jazz
|
||||
else if ( gProfilesIMP[ubNPC].ProfilId == ubNPC || gProfilesAIM[ubNPC].ProfilId == ubNPC || gProfilesMERC[ubNPC].ProfilId == ubNPC || ( gProfilesRPC[ubNPC].ProfilId == ubNPC && gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) )
|
||||
{
|
||||
sprintf( zFileName, "NPCData\\000.npc", ubNPC );
|
||||
}
|
||||
@@ -257,7 +265,7 @@ NPCQuoteInfo& NPCQuoteInfo::operator=(const _old_NPCQuoteInfo& src)
|
||||
ubLastDay = src.ubLastDay;
|
||||
ubApproachRequired = src.ubApproachRequired;
|
||||
ubOpinionRequired = src.ubOpinionRequired;
|
||||
ubUnused = 0;
|
||||
usUnused = 0;
|
||||
ubQuoteNum = src.ubQuoteNum;
|
||||
ubNumQuotes = src.ubNumQuotes;
|
||||
ubStartQuest = src.ubStartQuest;
|
||||
@@ -305,7 +313,9 @@ BOOLEAN EnsureQuoteFileLoaded( UINT8 ubNPC )
|
||||
fLoadFile = TRUE;
|
||||
}
|
||||
|
||||
if ( ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC )
|
||||
// if ( ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC )
|
||||
//new profiles by Jazz
|
||||
if ( ( gProfilesRPC[ubNPC].ProfilId == ubNPC ) )
|
||||
{
|
||||
if (gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED)
|
||||
{
|
||||
@@ -415,20 +425,31 @@ BOOLEAN RefreshNPCScriptRecord( UINT8 ubNPC, UINT8 ubRecord )
|
||||
{
|
||||
// we have some work to do...
|
||||
// loop through all PCs, and refresh their copy of this record
|
||||
for ( ubLoop = 0; ubLoop < FIRST_RPC; ubLoop++ ) // need more finesse here
|
||||
//for ( ubLoop = 0; ubLoop < FIRST_RPC; ubLoop++ ) // need more finesse here
|
||||
//new profiles by Jazz
|
||||
for ( ubLoop = 0; ubLoop < NUM_PROFILES; ubLoop++ ) // need more finesse here
|
||||
{
|
||||
//new profiles by Jazz
|
||||
if ( gProfilesIMP[ubLoop].ProfilId == ubLoop || gProfilesAIM[ubLoop].ProfilId == ubLoop || gProfilesMERC[ubLoop].ProfilId == ubLoop )
|
||||
RefreshNPCScriptRecord( ubLoop, ubRecord );
|
||||
}
|
||||
for ( ubLoop = GASTON; ubLoop < NUM_PROFILES; ubLoop++ ) // need more finesse here
|
||||
{
|
||||
RefreshNPCScriptRecord( ubLoop, ubRecord );
|
||||
}
|
||||
for ( ubLoop = FIRST_RPC; ubLoop < FIRST_NPC; ubLoop++ )
|
||||
|
||||
//for ( ubLoop = GASTON; ubLoop < NUM_PROFILES; ubLoop++ ) // need more finesse here
|
||||
//{
|
||||
// RefreshNPCScriptRecord( ubLoop, ubRecord );
|
||||
//}
|
||||
|
||||
//new profiles by Jazz
|
||||
//for ( ubLoop = FIRST_RPC; ubLoop < FIRST_NPC; ubLoop++ )
|
||||
for ( ubLoop = 0; ubLoop < NUM_PROFILES; ubLoop++ )
|
||||
{
|
||||
if ( gProfilesRPC[ubLoop].ProfilId == ubLoop )
|
||||
{
|
||||
if ( gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED && gpBackupNPCQuoteInfoArray[ ubNPC ] != NULL )
|
||||
{
|
||||
RefreshNPCScriptRecord( ubLoop, ubRecord );
|
||||
}
|
||||
}
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
@@ -462,21 +483,87 @@ NPCQuoteInfo * LoadCivQuoteFile( UINT8 ubIndex )
|
||||
NPCQuoteInfo * pFileData;
|
||||
UINT32 uiBytesRead;
|
||||
UINT32 uiFileSize;
|
||||
DWORD uiSignature = 0; // SB // WANNE - BMP: DONE!
|
||||
|
||||
if ( ubIndex == MINERS_CIV_QUOTE_INDEX )
|
||||
{
|
||||
sprintf( zFileName, "NPCData\\miners.npc" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( zFileName, "NPCData\\%c%d.npc", 'A' + ( gsCivQuoteSector[ ubIndex ][ 1 ] - 1 ), gsCivQuoteSector[ ubIndex ][ 0 ] );
|
||||
}
|
||||
if ( ubIndex == MINERS_CIV_QUOTE_INDEX )
|
||||
{
|
||||
sprintf( zFileName, "NPCData\\miners.npc" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( zFileName, "NPCData\\%c%d.npc", 'A' + ( gsCivQuoteSector[ ubIndex ][ 1 ] - 1 ), gsCivQuoteSector[ ubIndex ][ 0 ] );
|
||||
}
|
||||
|
||||
CHECKN( FileExists( zFileName ) );
|
||||
|
||||
hFile = FileOpen( zFileName, FILE_ACCESS_READ, FALSE );
|
||||
CHECKN( hFile );
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// WANNE: This fixes the bug, that NPCs do not give hints
|
||||
// Problem was, the missing conversion from old to new NPC structure!
|
||||
if (!FileRead( hFile, &uiSignature, sizeof(uiSignature), &uiBytesRead ) || uiBytesRead != sizeof(uiSignature) )
|
||||
return NULL;
|
||||
|
||||
if(uiSignature == NPCEX_SIGNATURE)//new fmt
|
||||
{
|
||||
uiFileSize = sizeof( NPCQuoteInfo ) * NUM_NPC_QUOTE_RECORDS;
|
||||
pFileData = (NPCQuoteInfo *)MemAlloc( uiFileSize );
|
||||
if (pFileData)
|
||||
{
|
||||
if (!FileRead( hFile, pFileData, uiFileSize, &uiBytesRead ) || uiBytesRead != uiFileSize )
|
||||
{
|
||||
MemFree( pFileData );
|
||||
pFileData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FileClose( hFile );
|
||||
}
|
||||
else //old fmt - make conversion
|
||||
{
|
||||
int iRecord;
|
||||
_old_NPCQuoteInfo * pFileData_old_;
|
||||
uiFileSize = sizeof( _old_NPCQuoteInfo ) * NUM_NPC_QUOTE_RECORDS;
|
||||
pFileData_old_ = ( _old_NPCQuoteInfo * )MemAlloc( uiFileSize );
|
||||
FileSeek(hFile, 0, FILE_SEEK_FROM_START);
|
||||
if (pFileData_old_)
|
||||
{
|
||||
if (!FileRead( hFile, pFileData_old_, uiFileSize, &uiBytesRead ) || uiBytesRead != uiFileSize )
|
||||
{
|
||||
MemFree( pFileData_old_ );
|
||||
pFileData_old_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FileClose( hFile );
|
||||
//check for Russian script & make a runtime conversion of it to International
|
||||
if( *(DWORD*)pFileData_old_ == 0x00350039 )
|
||||
{
|
||||
//just offset records 4 bytes backward
|
||||
_old_NPCQuoteInfo * pEnglishScript = ( _old_NPCQuoteInfo * )MemAlloc( uiFileSize );
|
||||
memcpy( pEnglishScript, ((char*)pFileData_old_)+4, uiFileSize-4 );
|
||||
MemFree( pFileData_old_ );
|
||||
pFileData_old_ = pEnglishScript;
|
||||
}
|
||||
|
||||
// Now it's time for conversion
|
||||
uiFileSize = sizeof(NPCQuoteInfo) * NUM_NPC_QUOTE_RECORDS;
|
||||
pFileData = (NPCQuoteInfo*)MemAlloc(uiFileSize);
|
||||
for(iRecord=0; iRecord<NUM_NPC_QUOTE_RECORDS; iRecord++)
|
||||
pFileData[iRecord] = pFileData_old_[iRecord];//dnl ch46 021009
|
||||
MemFree(pFileData_old_);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
//
|
||||
//</SB> new script format
|
||||
return( pFileData );
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// WANNE: This is old vanilla JA2 code without conversion of NPC data to new format used for Big Maps project
|
||||
/*
|
||||
uiFileSize = sizeof( NPCQuoteInfo ) * NUM_NPC_QUOTE_RECORDS;
|
||||
pFileData = (NPCQuoteInfo *)MemAlloc( uiFileSize );
|
||||
if (pFileData)
|
||||
@@ -491,6 +578,8 @@ NPCQuoteInfo * LoadCivQuoteFile( UINT8 ubIndex )
|
||||
FileClose( hFile );
|
||||
|
||||
return( pFileData );
|
||||
// -----------------------------------------------------------
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -578,8 +667,12 @@ BOOLEAN ReloadAllQuoteFiles( void )
|
||||
{
|
||||
UINT8 ubProfile, ubLoop;
|
||||
|
||||
for ( ubProfile = FIRST_RPC; ubProfile < GASTON; ubProfile++ )
|
||||
//for ( ubProfile = FIRST_RPC; ubProfile < GASTON; ubProfile++ )
|
||||
//new profiles by Jazz
|
||||
for ( ubProfile = 0; ubProfile < NUM_PROFILES; ubProfile++ )
|
||||
{
|
||||
if ( gProfilesRPC[ubProfile].ProfilId == ubProfile || gProfilesNPC[ubProfile].ProfilId == ubProfile )
|
||||
{
|
||||
// zap backup if any
|
||||
if ( gpBackupNPCQuoteInfoArray[ ubProfile ] != NULL )
|
||||
{
|
||||
@@ -587,6 +680,7 @@ BOOLEAN ReloadAllQuoteFiles( void )
|
||||
gpBackupNPCQuoteInfoArray[ ubProfile ] = NULL;
|
||||
}
|
||||
ReloadQuoteFileIfLoaded( ubProfile );
|
||||
}
|
||||
}
|
||||
// reload all civ quote files
|
||||
for ( ubLoop = 0; ubLoop < NUM_CIVQUOTE_SECTORS; ubLoop++ )
|
||||
@@ -642,6 +736,12 @@ INT32 CalcThreateningEffectiveness( UINT8 ubMerc )
|
||||
iDeadliness = -30;
|
||||
}
|
||||
|
||||
// SANDRO - bonus for threatening for assertive people
|
||||
if ( gGameOptions.fNewTraitSystem && gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
|
||||
{
|
||||
iDeadliness += 50;
|
||||
}
|
||||
|
||||
return( (EffectiveLeadership( pSoldier ) + iStrength + iDeadliness) / 3 ); //Trail minor bug fix.
|
||||
}
|
||||
|
||||
@@ -661,6 +761,15 @@ UINT8 CalcDesireToTalk( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach )
|
||||
iPersonalVal += pNPCProfile->bMercOpinion[ubMerc];
|
||||
}
|
||||
|
||||
// SANDRO - bonus for communication with people for assertive people
|
||||
if ( gGameOptions.fNewTraitSystem && bApproach != APPROACH_THREATEN)
|
||||
{
|
||||
if ( pMercProfile->bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
|
||||
iPersonalVal += 50;
|
||||
else if ( pMercProfile->bCharacterTrait == CHAR_TRAIT_MALICIOUS )
|
||||
iPersonalVal -= 50;
|
||||
}
|
||||
|
||||
// ARM: NOTE - for towns which don't use loyalty (San Mona, Estoni, Tixa, Orta )
|
||||
// loyalty will always remain 0 (this was OKed by Ian)
|
||||
iTownVal = gTownLoyalty[ pNPCProfile->bTown ].ubRating;
|
||||
@@ -1215,7 +1324,9 @@ UINT8 NPCConsiderReceivingItemFromMerc( UINT8 ubNPC, UINT8 ubMerc, OBJECTTYPE *
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ( usItemToConsider == MONEY && (ubNPC == SKYRIDER || (ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC) ) )
|
||||
//if ( usItemToConsider == MONEY && (ubNPC == SKYRIDER || (ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC) ) )
|
||||
//new profiles by Jazz
|
||||
if ( usItemToConsider == MONEY && (ubNPC == SKYRIDER || ( gProfilesRPC[ubNPC].ProfilId == ubNPC ) ) )
|
||||
{
|
||||
if ( gMercProfiles[ ubNPC ].iBalance < 0 && pNPCQuoteInfo->sActionData != NPC_ACTION_DONT_ACCEPT_ITEM )
|
||||
{
|
||||
@@ -1603,14 +1714,23 @@ void ResetOncePerConvoRecordsForNPC( UINT8 ubNPC )
|
||||
void ResetOncePerConvoRecordsForAllNPCsInLoadedSector( void )
|
||||
{
|
||||
UINT8 ubLoop;
|
||||
|
||||
UINT8 IDnpc;
|
||||
|
||||
if ( gWorldSectorX == 0 || gWorldSectorY == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ubLoop = FIRST_RPC; ubLoop < GASTON; ubLoop++ )
|
||||
//for ( ubLoop = FIRST_RPC; ubLoop < GASTON; ubLoop++ )
|
||||
//new profiles by Jazz
|
||||
for ( IDnpc = 0; IDnpc < NUM_PROFILES; IDnpc++ )
|
||||
{
|
||||
|
||||
if ( gProfilesRPC[IDnpc].ProfilId == IDnpc || gProfilesNPC[IDnpc].ProfilId == IDnpc)
|
||||
{
|
||||
ubLoop = IDnpc;
|
||||
|
||||
|
||||
if ( gMercProfiles[ ubLoop ].sSectorX == gWorldSectorX &&
|
||||
gMercProfiles[ ubLoop ].sSectorY == gWorldSectorY &&
|
||||
gMercProfiles[ ubLoop ].bSectorZ == gbWorldSectorZ &&
|
||||
@@ -1618,6 +1738,9 @@ void ResetOncePerConvoRecordsForAllNPCsInLoadedSector( void )
|
||||
{
|
||||
ResetOncePerConvoRecordsForNPC( ubLoop );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1695,7 +1818,15 @@ void Converse( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach, UINT32 uiApproachData
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pNPCQuoteInfoArray = gpNPCQuoteInfoArray[ubNPC];
|
||||
|
||||
//Legion jazz
|
||||
if (zHiddenNames[ubNPC].Hidden == TRUE)
|
||||
{
|
||||
zHiddenNames[ubNPC].Hidden = FALSE;
|
||||
}
|
||||
|
||||
|
||||
pProfile = &(gMercProfiles[ubNPC]);
|
||||
switch( bApproach )
|
||||
@@ -1849,7 +1980,7 @@ void Converse( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach, UINT32 uiApproachData
|
||||
break;
|
||||
case TRIGGER_NPC:
|
||||
// if triggering, pass in the approach data as the record to consider
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "Handling trigger %S/%d at %ld", gMercProfiles[ ubNPC ].zNickname, (UINT8)uiApproachData, GetJA2Clock() ) );
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "Handling trigger %S/%d at %lu", gMercProfiles[ ubNPC ].zNickname, (UINT8)uiApproachData, GetJA2Clock() ) );
|
||||
NPCConsiderTalking( ubNPC, ubMerc, bApproach, (UINT8)uiApproachData, pNPCQuoteInfoArray, &pQuotePtr, &ubRecordNum );
|
||||
break;
|
||||
default:
|
||||
@@ -2242,6 +2373,11 @@ void Converse( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach, UINT32 uiApproachData
|
||||
case APPROACH_DECLARATION_OF_HOSTILITY:
|
||||
case APPROACH_INITIAL_QUOTE:
|
||||
case APPROACH_GIVINGITEM:
|
||||
// SANDRO - new records - NPCs discovered
|
||||
if ( pProfile->ubLastDateSpokenTo == 0 && FindSoldierByProfileID( ubMerc, TRUE ) != NULL )
|
||||
{
|
||||
gMercProfiles[ubMerc].records.usNPCsDiscovered++;
|
||||
}
|
||||
pProfile->ubLastDateSpokenTo = (UINT8) GetWorldDay();
|
||||
break;
|
||||
default:
|
||||
|
||||
+7
-3
@@ -90,8 +90,6 @@ public:
|
||||
|
||||
// conditions
|
||||
INT16 sRequiredItem; // item NPC must have to say quote
|
||||
INT32 sRequiredGridNo; // location for NPC req'd to say quote
|
||||
|
||||
UINT16 usFactMustBeTrue; // ...before saying quote
|
||||
UINT16 usFactMustBeFalse; // ...before saying quote
|
||||
UINT8 ubQuest; // quest must be current to say quote
|
||||
@@ -99,7 +97,6 @@ public:
|
||||
UINT8 ubLastDay; // last day quote can be said
|
||||
UINT8 ubApproachRequired; // must use this approach to generate quote
|
||||
UINT8 ubOpinionRequired; // opinion needed for this quote
|
||||
UINT8 ubUnused;
|
||||
|
||||
// quote to say (if any)
|
||||
UINT8 ubQuoteNum; // this is the quote to say
|
||||
@@ -110,10 +107,17 @@ public:
|
||||
UINT8 ubEndQuest;
|
||||
UINT8 ubTriggerNPC;
|
||||
UINT8 ubTriggerNPCRec;
|
||||
UINT8 ubFiller;
|
||||
UINT16 usSetFactTrue;
|
||||
UINT16 usGiftItem; // item NPC gives to merc after saying quote
|
||||
UINT16 usUnused;
|
||||
INT16 sActionData; // special action value
|
||||
|
||||
INT32 sRequiredGridNo; // location for NPC req'd to say quote
|
||||
INT32 usGoToGridNo;
|
||||
UINT16 usSourceDialogueLevel; // reserved for future use
|
||||
UINT16 usDestDialogueLevel; // reserved for future use
|
||||
|
||||
public:
|
||||
NPCQuoteInfo& operator=(const _old_NPCQuoteInfo& src);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,431 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Name="TacticalAI"
|
||||
ProjectGUID="{27A49DAF-3F5A-4FF2-B943-9559F0B63032}"
|
||||
RootNamespace="TacticalAI"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Debug.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D "_CRT_SECURE_NO_DEPRECATE""
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D "_CRT_SECURE_NO_DEPRECATE""
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
|
||||
RuntimeLibrary="0"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MapEditor|Win32"
|
||||
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D "_CRT_SECURE_NO_DEPRECATE""
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
|
||||
RuntimeLibrary="0"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MapEditorD|Win32"
|
||||
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D "_CRT_SECURE_NO_DEPRECATE""
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4100"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release_WithDebugInfo|Win32"
|
||||
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D "_CRT_SECURE_NO_DEPRECATE""
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
|
||||
RuntimeLibrary="0"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AI All.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ai.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AIInternals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AIList.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NPC.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\QuestDebug.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AIList.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AIMain.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AIUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Attacks.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CreatureDecideAction.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DecideAction.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FindLocations.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Knowledge.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Medical.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Movement.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NPC.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\PanicButtons.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\QuestDebug.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Realtime.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -21,7 +21,7 @@
|
||||
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Debug.vsprops"
|
||||
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Debug.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
@@ -83,7 +83,7 @@
|
||||
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2_VS2008.vsprops"
|
||||
InheritedPropertySheets="..\ja2.vsprops"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
@@ -147,7 +147,7 @@
|
||||
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Editor.vsprops"
|
||||
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
@@ -211,7 +211,7 @@
|
||||
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Editor.vsprops"
|
||||
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
@@ -273,7 +273,7 @@
|
||||
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
|
||||
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\ja2_VS2008.vsprops"
|
||||
InheritedPropertySheets="..\ja2.vsprops"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MapEditorD|Win32">
|
||||
<Configuration>MapEditorD</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MapEditor|Win32">
|
||||
<Configuration>MapEditor</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Relese_WithDebugInfo|Win32">
|
||||
<Configuration>Relese_WithDebugInfo</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AI All.h" />
|
||||
<ClInclude Include="ai.h" />
|
||||
<ClInclude Include="AIInternals.h" />
|
||||
<ClInclude Include="AIList.h" />
|
||||
<ClInclude Include="NPC.h" />
|
||||
<ClInclude Include="QuestDebug.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AIList.cpp" />
|
||||
<ClCompile Include="AIMain.cpp" />
|
||||
<ClCompile Include="AIUtils.cpp" />
|
||||
<ClCompile Include="Attacks.cpp" />
|
||||
<ClCompile Include="CreatureDecideAction.cpp" />
|
||||
<ClCompile Include="DecideAction.cpp" />
|
||||
<ClCompile Include="FindLocations.cpp" />
|
||||
<ClCompile Include="Knowledge.cpp" />
|
||||
<ClCompile Include="Medical.cpp" />
|
||||
<ClCompile Include="Movement.cpp" />
|
||||
<ClCompile Include="NPC.cpp" />
|
||||
<ClCompile Include="PanicButtons.cpp" />
|
||||
<ClCompile Include="QuestDebug.cpp" />
|
||||
<ClCompile Include="Realtime.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B369A125-E62E-46AE-9285-58003D688301}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>TacticalAI</RootNamespace>
|
||||
<ProjectName>TacticalAI</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\ja2.props" />
|
||||
<Import Project="..\ja2_Debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\ja2.props" />
|
||||
<Import Project="..\ja2_Debug.props" />
|
||||
<Import Project="..\ja2_Editor.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\ja2.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\ja2.props" />
|
||||
<Import Project="..\ja2_Editor.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\ja2.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
|
||||
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
|
||||
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
|
||||
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
|
||||
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>
|
||||
</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>
|
||||
</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>
|
||||
</PrecompiledHeaderOutputFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>
|
||||
</PrecompiledHeaderOutputFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>
|
||||
</PrecompiledHeaderOutputFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{2552d0a1-b3ed-43af-a06c-d0737ce6a63f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{0f98d0d9-dbab-4dc2-8aa6-ee517a6ceab6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AI All.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ai.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AIInternals.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AIList.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NPC.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="QuestDebug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AIList.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AIMain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AIUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Attacks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CreatureDecideAction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DecideAction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FindLocations.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Knowledge.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Medical.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Movement.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NPC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PanicButtons.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QuestDebug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Realtime.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -97,6 +97,7 @@ typedef enum
|
||||
AI_ACTION_TRAVERSE_DOWN, // move down a level
|
||||
AI_ACTION_OFFER_SURRENDER, // offer surrender to the player
|
||||
AI_ACTION_RAISE_GUN,
|
||||
AI_ACTION_STEAL_MOVE, // added by SANDRO
|
||||
} ActionType;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user