From 8546984b6fd1e479b2884e23202d3395ab6a77d4 Mon Sep 17 00:00:00 2001 From: MaddMugsy Date: Thu, 8 Jun 2006 17:47:52 +0000 Subject: [PATCH] -reverted most AI changes -spreadsheet update git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@200 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- TacticalAI/AIInternals.h | 24 -- TacticalAI/AIUtils.cpp | 161 ------------- TacticalAI/DecideAction.cpp | 454 ++++------------------------------- TacticalAI/FindLocations.cpp | 341 +------------------------- 4 files changed, 60 insertions(+), 920 deletions(-) diff --git a/TacticalAI/AIInternals.h b/TacticalAI/AIInternals.h index 2ef701b10..8069c2651 100644 --- a/TacticalAI/AIInternals.h +++ b/TacticalAI/AIInternals.h @@ -224,31 +224,7 @@ BOOLEAN ArmySeesOpponents( void ); void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN suppressionFire); -void AskForNoise( SOLDIERTYPE * pSoldier, INT16 *sNoiseGridno, UINT8 *ubNoiseVolume, INT8 *bNoiseLevel, INT8 bDist ); -INT32 RangeToClosestOpponent( SOLDIERTYPE *pSoldier ); -INT16 FindClimbGridNo( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 bMaxActionPoints ); -//BOOLEAN IsTooFarFromFriends( SOLDIERTYPE *pSoldier ); INT16 FindBestCoverNearTheGridNo(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubSearchRadius ); -INT16 FindRoofBetweenGridNos( INT16 sFGridNo, INT16 sSGridNo ); INT8 FindDirectionForClimbing( INT16 sGridNo ); -enum -{ - TM_OUTOFRANGE = 0, - TM_HASFIRED, - TM_TRIED_TO_CLIMB, - TM_TRIED_TO_CLIMBDOWN, - TM_LAST_DEST_GRID, - TM_LOOKED_FOR_COVER, -// TM_LOOKFORROOF, - MAX_NUMBER_OF_TM -}; - -extern INT32 gpTurnMem[ MAX_NUMBER_OF_TM ]; - -UINT32 CountRatingOfTeamMatesDensity( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT32 iDist ); -UINT32 CountRatingOfOpponentsDensity( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT32 iDist ); -UINT8 NeedTimeToReadyGun_IfAlreadyReady( SOLDIERTYPE *pSoldier ); -SOLDIERTYPE* FindFriendFarthestFromEnemies( SOLDIERTYPE * pSoldier ); - diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp index da5928a21..ab8f7ae18 100644 --- a/TacticalAI/AIUtils.cpp +++ b/TacticalAI/AIUtils.cpp @@ -2517,165 +2517,4 @@ BOOLEAN ArmySeesOpponents( void ) } -void AskForNoise( SOLDIERTYPE * pSoldier, INT16 *sNoiseGridno, UINT8 *ubNoiseVolume, INT8 *bNoiseLevel, INT8 bDist ) -{ - UINT32 uiLoop; - SOLDIERTYPE *pFriend; - - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pFriend = MercSlots[ uiLoop ]; - - // it's me! Next merc - if( pFriend == pSoldier ) - continue; - - // if this merc is inactive, at base, on assignment, dead, unconscious - if (!pFriend || (pFriend->bLife < OKLIFE)) - { - continue; // next merc - } - - if ( pSoldier->bTeam != pFriend->bTeam ) - { - continue; // next merc - } - - if( pFriend->sNoiseGridno != NOWHERE && GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pFriend->sGridNo ) / 10 <= bDist ) - { - *sNoiseGridno = pFriend->sNoiseGridno; - *ubNoiseVolume = pFriend->ubNoiseVolume; - *bNoiseLevel = pFriend->bNoiseLevel; - return; - } - - } -} - -INT32 RangeToClosestOpponent( SOLDIERTYPE *pSoldier ) -{ - INT16 sClosestDisturbance; - //BOOLEAN fClimb; - sClosestDisturbance = ClosestKnownOpponent(pSoldier, 0, 0); - if( sClosestDisturbance != NOWHERE ) - return GetRangeFromGridNoDiff( pSoldier->sGridNo, sClosestDisturbance ); - else - return 128; -} - - -UINT8 NeedTimeToReadyGun_IfAlreadyReady( SOLDIERTYPE *pSoldier ) -{ - UINT16 usAnimState = PickSoldierReadyAnimation( pSoldier, FALSE ); - - if( usAnimState == INVALID_ANIMATION || GetAPsToReadyWeapon( pSoldier, usAnimState ) == 0 ) - { - if( pSoldier->inv[HANDPOS].usItem != NOTHING && Item[pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_GUN ) - return Weapon[ Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex ].ubReadyTime; - } - - return 0; -} - - - -UINT32 CountRatingOfTeamMatesDensity( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT32 iDist ) -{ - //UINT8 X, Y , ubWhoIsThere; - DOUBLE ddCount; - -// INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown; -// INT16 iGridNo; - DOUBLE ddDistance; - UINT32 uiLoop; - SOLDIERTYPE *pFriend; - DOUBLE ddMaxDistance = iDist; - - ddCount = 0; - - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pFriend = MercSlots[ uiLoop ]; - - // it's me! Next merc - if( pFriend == pSoldier ) - continue; - - - // if this merc is inactive, at base, on assignment, dead, unconscious - if (!pFriend || (pFriend->bLife < OKLIFE)) - { - continue; // next merc - } - - // if this man is neutral / on the same side - if ( pSoldier->bSide != pFriend->bSide ) - { - continue; // next merc - } - - - ddDistance = (INT32)(GetRangeInCellCoordsFromGridNoDiff( sGridNo, pFriend->sGridNo ) / 10); - - if( ddDistance > ddMaxDistance) - ddDistance = ddMaxDistance; - -// if( ddDistance ) -// ddDistance = iDist + 1 - ddDistance; - - ddCount += max( 0, ddMaxDistance - ddDistance ); - } - - return( ddCount ); -} - -UINT32 CountRatingOfOpponentsDensity( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT32 iDist ) -{ - //UINT8 X, Y , ubWhoIsThere; - DOUBLE ddCount; - -// INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown; -// INT16 iGridNo; - DOUBLE ddDistance; - UINT32 uiLoop; - SOLDIERTYPE *pOpponent; - DOUBLE ddMaxDistance = iDist; - - ddCount = 0; - - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pOpponent = MercSlots[ uiLoop ]; - - // it's me! Next merc - if( pOpponent == pSoldier ) - continue; - - - // if this merc is inactive, at base, on assignment, dead, unconscious - if (!pOpponent || (pOpponent->bLife < OKLIFE)) - { - continue; // next merc - } - - // if this man is neutral / on the same side - if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) - { - continue; // next merc - } - - - ddDistance = (INT32)(GetRangeInCellCoordsFromGridNoDiff( sGridNo, pOpponent->sGridNo ) / 10); - - if( ddDistance > ddMaxDistance) - ddDistance = ddMaxDistance; - -// if( ddDistance ) -// ddDistance = iDist + 1 - ddDistance; - - ddCount += max( 0, ddMaxDistance - ddDistance ); - } - - return( ddCount ); -} diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index 02bb448a0..e9fd539da 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -23,89 +23,9 @@ // #include "Air Raid.h" #endif -INT32 gpTurnMem[ MAX_NUMBER_OF_TM ]; extern BOOLEAN InternalIsValidStance( SOLDIERTYPE *pSoldier, INT8 bDirection, INT8 bNewStance ); extern BOOLEAN gfHiddenInterrupt; extern BOOLEAN gfUseAlternateQueenPosition; -#define BONUS_FOR_THROW_CHANCE_TO_HIT ((INT32)50) - -#define ADD_MAN_ON_ROOF_ON_EACH_N_SQUARE 1//18 -#define MAX_DISTANCE_TO_ASK_NOISE 10 -#define CHANCE_TO_STAY_ON_ROOF 95 -#define MIN_RANGE_TO_ENEMY_TO_DO_SOMETHING 5 - -#define MIN_OVERALL_ROOF_BONUS 7 -#define MIN_PENALTY_TO_ATTACK_ENEMY_ROOF 9 -#define MAX_HIT_CHANCE_TO_ATTACK_ENEMY_ROOF 60 - -#define COST_OF_READY_AP 2 - -#define EXTRA_CHANCE_OF_BURST_IF_CAN_FIRE_WITH_SAME_AIM_TIME 50 - -static INT8 DecideActionOnClimbSpot( SOLDIERTYPE* pSoldier ) -{ -// INT8 bRightDir = FindDirectionForClimbing( pSoldier->sGridNo ); -// INT8 bAPForLook = 0; -// INT8 bAPForStandUp = 0; - -// if( pSoldier->bDirection != bRightDir ) bAPForLook = 1; -// if( PTR_CROUCHED ) bAPForStandUp = 2; -// if( PTR_PRONE ) bAPForStandUp = 4; - - pSoldier->bAction = AI_ACTION_CLIMB_ROOF; -// pSoldier->bActionPoints -= bAPForStandUp + bAPForLook; - if( IsActionAffordable(pSoldier) ) - { - // pSoldier->bActionPoints += bAPForStandUp + bAPForLook; - -/// gpTurnMem[ TM_TRIED_TO_CLIMB ] = TRUE; - -// if( bAPForStandUp == 4 ) -// pSoldier->usActionData = ANIM_CROUCH; -// if( bAPForStandUp == 2 ) -// pSoldier->usActionData = ANIM_STAND; - -// if( bAPForStandUp ) -// return AI_ACTION_CHANGE_STANCE; - -/* if( bAPForLook ) - { - pSoldier->usActionData = bRightDir; - return(AI_ACTION_CHANGE_FACING); - }*/ - - return AI_ACTION_CLIMB_ROOF; - }//else -// pSoldier->bActionPoints += bAPForStandUp + bAPForLook; - -/* if( pSoldier->bActionPoints > 2 && PTR_STANDING && pSoldier->bDirection != bRightDir ) - { - pSoldier->usActionData = bRightDir; - return(AI_ACTION_CHANGE_FACING); - }else - if( pSoldier->bActionPoints > 6 && PTR_CROUCHED && pSoldier->bDirection != bRightDir ) - { - pSoldier->usActionData = bRightDir; - return(AI_ACTION_CHANGE_FACING); - }*/ - - if( pSoldier->bActionPoints > 1 && PTR_STANDING ) - { - pSoldier->usActionData = ANIM_CROUCH; - return( AI_ACTION_CHANGE_STANCE ); - } - - if( pSoldier->bLevel && pSoldier->bActionPoints > 1 && PTR_CROUCHED ) - { - pSoldier->usActionData = ANIM_PRONE; - return( AI_ACTION_CHANGE_STANCE ); - } - - return AI_ACTION_NONE; -} - - - // global status time counters to determine what takes the most time @@ -116,11 +36,6 @@ UINT32 guiRedSeekTimeTotal = 0, guiRedHelpTimeTotal = 0, guiRedHideTimeTotal = 0 UINT32 guiRedSeekCounter = 0, guiRedHelpCounter = 0; guiRedHideCounter = 0; #endif -// maximum strength bonus or penalty for chance tofire burst -#define BURST_MAX_STRENGTH_BONUS 25 -#define BURST_BONUS_PER_AP 3 -#define OUT_OF_RANGE_GET_CLOSE_BASE_CHANCE 50 - #define CENTER_OF_RING 11237 #define MAX_FLANKS_RED 15 @@ -131,10 +46,6 @@ UINT32 guiRedSeekCounter = 0, guiRedHelpCounter = 0; guiRedHideCounter = 0; #define MIN_FLANK_DIST_RED 10 * STRAIGHT_RATIO #define MAX_FLANK_DIST_RED 40 * STRAIGHT_RATIO -extern UINT8 CountFriendWithoutATarger( SOLDIERTYPE * pSoldier ); - -extern UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady ); - void DoneScheduleAction( SOLDIERTYPE * pSoldier ) { @@ -764,7 +675,6 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier) BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); BOOLEAN fCivilianOrMilitia = PTR_CIV_OR_MILITIA; - if( pSoldier->sNoiseGridno == NOWHERE )AskForNoise( pSoldier, &pSoldier->sNoiseGridno, &pSoldier->ubNoiseVolume, &pSoldier->bNoiseLevel, MAX_DISTANCE_TO_ASK_NOISE); gubNPCPathCount = 0; @@ -1317,7 +1227,6 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) STR16 tempstr; #endif - if( pSoldier->sNoiseGridno == NOWHERE )AskForNoise( pSoldier, &pSoldier->sNoiseGridno, &pSoldier->ubNoiseVolume, &pSoldier->bNoiseLevel, MAX_DISTANCE_TO_ASK_NOISE); if (fCivilian) { @@ -1381,11 +1290,9 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) { // set base chance according to orders if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD)) - iChance = 60; + iChance = 50; else // all other orders - iChance = 35; - if(pSoldier->bOrders == SEEKENEMY) - iChance = -15; + iChance = 25; if (pSoldier->bAttitude == DEFENSIVE) iChance += 15; @@ -1415,7 +1322,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) ) { // base chance depends on how much new info we have to radio to the others - iChance = 5 * 5 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 5 * for YELLOW alert + iChance = 5 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 5 * for YELLOW alert // if I actually know something they don't and I ain't swimming (deep water) if (iChance && !DeepWater( pSoldier->sGridNo )) @@ -1437,7 +1344,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) case RNDPTPATROL: case POINTPATROL: break; case FARPATROL: iChance += -10; break; - case SEEKENEMY: iChance += 40; break; + case SEEKENEMY: iChance += -20; break; } // modify base chance according to attitude @@ -1810,7 +1717,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) if (!SkipCoverCheck ) // && gfTurnBasedAI) // only do in turnbased { // remember that noise value is negative, and closer to 0 => more important! - iChance = 55; + iChance = 25; iSneaky = 30; // set base chance according to orders @@ -1867,7 +1774,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) //////////////////////////////////////////////////////////////////////////// // SWITCH TO GREEN: determine if soldier acts as if nothing at all was wrong //////////////////////////////////////////////////////////////////////////// - if ((INT16)PreRandom(100) < 30 ) + if ((INT16)PreRandom(100) < 50 ) { #ifdef RECORDNET fprintf(NetDebugFile,"\tDecideActionYellow: guynum %d ignores noise, switching to GREEN AI...\n",pSoldier->ubID); @@ -1942,23 +1849,6 @@ INT32 iCoverPercentBetter; (pSoldier->bNeutral && gTacticalStatus.fCivGroupHostile[pSoldier->ubCivilianGroup] == CIV_GROUP_NEUTRAL) || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); - double ddRatingDiff = CountRatingOfOpponentsDensity( pSoldier, pSoldier->sGridNo, MAX_DIST )==0?CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ):(CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ) / CountRatingOfOpponentsDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ) ); - - if( !ddRatingDiff )ddRatingDiff = 0.000000001; - - if( pSoldier->sNoiseGridno == NOWHERE )AskForNoise( pSoldier, &pSoldier->sNoiseGridno, &pSoldier->ubNoiseVolume, &pSoldier->bNoiseLevel, MAX_DISTANCE_TO_ASK_NOISE); - - if( !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition && (pSoldier->bActionPoints >= AP_RADIO) && !fCivilian ) - { - return(AI_ACTION_RED_ALERT); - } - - if( gfTurnBasedAI ) - if( gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition ) - { - RadioSightings(pSoldier,EVERYBODY,pSoldier->bTeam); - } - // if we have absolutely no action points, we can't do a thing under RED! if (!pSoldier->bActionPoints) { @@ -2108,28 +1998,6 @@ INT32 iCoverPercentBetter; } } - if (ubCanMove && RangeToClosestOpponent( pSoldier ) > MIN_RANGE_TO_ENEMY_TO_DO_SOMETHING && - !CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, 10 ) && - ddRatingDiff < 1 ) -{ - //////////////////////////////////////////////////////////////////////// - // RUN AWAY TO A FRIEND FARTHEST FROM KNOWN THREATS - //////////////////////////////////////////////////////////////////////// - - SOLDIERTYPE* pFriend = FindFriendFarthestFromEnemies( pSoldier ); - - if( pFriend ) - { - pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,pFriend->sGridNo,AI_ACTION_SEEK_OPPONENT); - if( pSoldier->usActionData != NOWHERE ) - { - if( CountRatingOfOpponentsDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ) >= CountRatingOfOpponentsDensity( pSoldier, pSoldier->usActionData, MAX_DIST ) ) - return(AI_ACTION_RUN_AWAY); - } - } -} - - //////////////////////////////////////////////////////////////////////////// // WHEN IN THE LIGHT, GET OUT OF THERE! //////////////////////////////////////////////////////////////////////////// @@ -2506,7 +2374,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: calculate morale"); return(AI_ACTION_RUN_AWAY); } } -/* + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); //////////////////////////////////////////////////////////////////////////// @@ -2588,7 +2456,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); } } } -*/ + if ( !TANK( pSoldier ) ) { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: main red ai"); @@ -2685,7 +2553,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); // if we can move at least 1 square's worth // and have more APs than we want to reserve - if (ubCanMove && pSoldier->bActionPoints > MAX_AP_CARRIED && !fCivilian) + if (ubCanMove && pSoldier->bActionPoints > MAX_AP_CARRIED) { if (fCivilian) { @@ -2709,8 +2577,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); // modify RED movement tendencies according to morale switch (pSoldier->bAIMorale) { - case MORALE_HOPELESS: bSeekPts = -99; bHelpPts = -99; bHidePts = +1; bWatchPts = -99; break; - case MORALE_WORRIED: bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += 1; break; + case MORALE_HOPELESS: bSeekPts = -99; bHelpPts = -99; bHidePts = +2; bWatchPts = -99; break; + case MORALE_WORRIED: bSeekPts += -2; bHelpPts += 0; bHidePts += +2; bWatchPts += 1; break; case MORALE_NORMAL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; case MORALE_CONFIDENT: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; case MORALE_FEARLESS: bSeekPts += +1; bHelpPts += 0; bHidePts = -1; bWatchPts += 0; break; @@ -2719,14 +2587,14 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); // modify tendencies according to orders switch (pSoldier->bOrders) { - case STATIONARY: bSeekPts += -1; bHelpPts += +1; bHidePts += +1; bWatchPts += +1; break; - case ONGUARD: bSeekPts += -1; bHelpPts += +1; bHidePts += +1; bWatchPts += +1; break; - case CLOSEPATROL: bSeekPts += 0; bHelpPts += +1; bHidePts += 0; bWatchPts += 0; break; - case RNDPTPATROL: bSeekPts += 0; bHelpPts += +1; bHidePts += 0; bWatchPts += 0; break; - case POINTPATROL: bSeekPts += 0; bHelpPts += +1; bHidePts += 0; bWatchPts += 0; break; - case FARPATROL: bSeekPts += 0; bHelpPts += +1; bHidePts += 0; bWatchPts += 0; break; + case STATIONARY: bSeekPts += -1; bHelpPts += -1; bHidePts += +1; bWatchPts += +1; break; + case ONGUARD: bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += +1; break; + case CLOSEPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case RNDPTPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case POINTPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case FARPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; case ONCALL: bSeekPts += 0; bHelpPts += +1; bHidePts += -1; bWatchPts += 0; break; - case SEEKENEMY: bSeekPts += +1; bHelpPts += +1; bHidePts += +1; bWatchPts += -1; break; + case SEEKENEMY: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += -1; break; } // modify tendencies according to attitude @@ -2753,9 +2621,6 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); // don't search for cover bHidePts = -99; } - else - bHelpPts = -99; - // while one of the three main RED REACTIONS remains viable while ((bSeekPts > -90) || (bHelpPts > -90) || (bHidePts > -90) ) @@ -2767,17 +2632,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); #ifdef AI_TIMING_TESTS uiStartTime = GetJA2Clock(); #endif - - // get the location of the closest reachable opponent - sClosestDisturbance = ClosestReachableDisturbance(pSoldier,ubUnconsciousOK, &fClimb); - - if( sClosestDisturbance == NOWHERE ) - { - INT32 iNV; - BOOLEAN fR; - sClosestDisturbance = MostImportantNoiseHeard( pSoldier, &iNV, &fClimb, &fR ); - } - + #ifdef AI_TIMING_TESTS uiEndTime = GetJA2Clock(); guiRedSeekTimeTotal += (uiEndTime - uiStartTime); @@ -3130,10 +2985,12 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't hide"); } } + ///////////////////////////////////////////////////////////////////////////// // GET TO BETTER COVER ///////////////////////////////////////////////////////////////////////////// - + } + if ( ubCanMove && ( ClosestReachableDisturbance(pSoldier, TRUE, &fClimb) == NOWHERE) ) { sBestCover = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iCoverPercentBetter); @@ -3144,7 +3001,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); } } - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: nothing to do!"); + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: nothing to do!"); //////////////////////////////////////////////////////////////////////////// // NOTHING USEFUL POSSIBLE! IF NPC IS CURRENTLY UNDER FIRE, TRY TO RUN AWAY //////////////////////////////////////////////////////////////////////////// @@ -3206,7 +3064,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); } } - } + } } @@ -3442,7 +3300,6 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); // DO NOTHING: Not enough points left to move, so save them for next turn //////////////////////////////////////////////////////////////////////////// - } #ifdef DEBUGDECISIONS AINameMessage(pSoldier,"- DOES NOTHING (RED)",1000); #endif @@ -3475,33 +3332,14 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) UINT8 ubBurstAPs; UINT8 ubOpponentDir; INT16 sCheckGridNo; - INT16 sCGridNo; - INT8 bLevel; -// INT8 bIndex; - INT8 bRealActionPoints; - - double ddRatingDiff = CountRatingOfOpponentsDensity( pSoldier, pSoldier->sGridNo, MAX_DIST )==0?CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ):(CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ) / CountRatingOfOpponentsDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ) ); BOOLEAN fAllowCoverCheck = FALSE; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack"); - if( !ddRatingDiff )ddRatingDiff = 0.000000001; - if( gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition ) - { - RadioSightings(pSoldier,EVERYBODY,pSoldier->bTeam); - } - - - if( !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition ) - if( (pSoldier->bActionPoints >= AP_RADIO) && !fCivilian ) - { - return(AI_ACTION_RED_ALERT); - } // once we hit status black, reset flanking status //pSoldier->numFlanks = 0; - if( pSoldier->sNoiseGridno == NOWHERE )AskForNoise( pSoldier, &pSoldier->sNoiseGridno, &pSoldier->ubNoiseVolume, &pSoldier->bNoiseLevel, MAX_DISTANCE_TO_ASK_NOISE); // if we have absolutely no action points, we can't do a thing under BLACK! if (!pSoldier->bActionPoints) @@ -4168,153 +4006,6 @@ bCanAttack = FALSE; } - if (ubCanMove && RangeToClosestOpponent( pSoldier ) > MIN_RANGE_TO_ENEMY_TO_DO_SOMETHING && - !CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, 10 ) && - ddRatingDiff < 1 ) -{ - //////////////////////////////////////////////////////////////////////// - // RUN AWAY TO A FRIEND FARTHEST FROM KNOWN THREATS - //////////////////////////////////////////////////////////////////////// - - SOLDIERTYPE* pFriend = FindFriendFarthestFromEnemies( pSoldier ); - - if( pFriend ) - { - pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,pFriend->sGridNo,AI_ACTION_SEEK_OPPONENT); - if( pSoldier->usActionData != NOWHERE ) - { - if( CountRatingOfOpponentsDensity( pSoldier, pSoldier->sGridNo, MAX_DIST ) >= CountRatingOfOpponentsDensity( pSoldier, pSoldier->usActionData, MAX_DIST ) ) - return(AI_ACTION_RUN_AWAY); - } - } -} - - - - - //////////////////////////////////////////////////////////////////////////// - // IF THE TARGET IS OUT OF WEAPON RANGE - //////////////////////////////////////////////////////////////////////////// - - if( gpTurnMem[TM_LAST_DEST_GRID] && gpTurnMem[TM_OUTOFRANGE] ) - { - if( gpTurnMem[TM_LAST_DEST_GRID] != pSoldier->sGridNo && ( !BestAttack.ubPossible || BestAttack.ubChanceToReallyHit < 80 ) ) - { - pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,gpTurnMem[TM_LAST_DEST_GRID],AI_ACTION_SEEK_OPPONENT); - if( pSoldier->usActionData != NOWHERE ) - return AI_ACTION_GET_CLOSER; - } - } - else - if( ubCanMove && ubBestAttackAction == AI_ACTION_FIRE_GUN - && Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_GUN - && RangeToClosestOpponent( pSoldier ) > MIN_RANGE_TO_ENEMY_TO_DO_SOMETHING - && pSoldier->bActionPoints > 5 + NeedTimeToReadyGun_IfAlreadyReady( pSoldier ) - && BestAttack.ubChanceToReallyHit < 90 ) -{ - WEAPONTYPE WeapBuf = Weapon[ Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex ]; - - int iDistance = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, BestAttack.sTarget ); - -// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld %ld %ld %ld", pSoldier->ubID, iDistance, BestAttack.ubChanceToReallyHit, ddRatingDiff / 10); - - if( ( iDistance > WeapBuf.usRange && BestAttack.ubChanceToReallyHit < min( 90, 70 * ddRatingDiff ) ) || - ( BestAttack.ubChanceToReallyHit < min( 70, 30 * ddRatingDiff ) ) ) - { - sClosestDisturbance = ClosestKnownOpponent( pSoldier, 0, &bLevel ); - - iChance = OUT_OF_RANGE_GET_CLOSE_BASE_CHANCE * iDistance / WeapBuf.usRange + 100 - BestAttack.ubChanceToReallyHit; - - switch (pSoldier->bAttitude) - { - case DEFENSIVE: iChance += -50; break; - case BRAVESOLO: iChance += -10; break; - case BRAVEAID: iChance += -5; break; - case CUNNINGSOLO: iChance += -40; break; - case CUNNINGAID: iChance += -30; break; - case AGGRESSIVE: iChance += -10; break; - case ATTACKSLAYONLY:iChance += 0; break; - } - - iChance -= NeedTimeToReadyGun_IfAlreadyReady( pSoldier ) * COST_OF_READY_AP; - - - if( sClosestDisturbance != NOWHERE /*&& iChance > Random( 100 )*/ ) - { - // try to move towards him - - bRealActionPoints = pSoldier->bActionPoints; - - if( iDistance <= WeapBuf.usRange ) - pSoldier->bActionPoints = min( 4 + 2 * iDistance/10 * ( (30 - BestAttack.ubChanceToReallyHit) / 30.0 ), bRealActionPoints ); - else - pSoldier->bActionPoints = min( 9 + (iDistance - WeapBuf.usRange) / 10, bRealActionPoints ); - - - pSoldier->usActionData = GoAsFarAsPossibleTowards( pSoldier, sClosestDisturbance, AI_ACTION_SEEK_OPPONENT ); - - pSoldier->bActionPoints = bRealActionPoints; - - if (pSoldier->usActionData != NOWHERE) - { - sCGridNo = FindClimbGridNo( pSoldier, pSoldier->usActionData, -1 ); - - if( sCGridNo == pSoldier->sGridNo ) - return DecideActionOnClimbSpot( pSoldier ); - - if ( sCGridNo != NOWHERE && - ( !pSoldier->bLevel && !InARoom( pSoldier->sGridNo, NULL ) && !gpTurnMem[ TM_TRIED_TO_CLIMBDOWN ]/*|| CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, 5 ) > 5 */) ) - { - gpTurnMem[ TM_OUTOFRANGE ] = TRUE; - gpTurnMem[ TM_TRIED_TO_CLIMBDOWN ] = TRUE; - - pSoldier->usActionData = sCGridNo; - pSoldier->usUIMovementMode = RUNNING; - pSoldier->fUIMovementFast = TRUE; - return( AI_ACTION_MOVE_TO_CLIMB ); - }else - { - - - pSoldier->usActionData = FindBestCoverNearTheGridNo( pSoldier, pSoldier->usActionData, 5 ); - pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,pSoldier->usActionData,AI_ACTION_SEEK_OPPONENT); - -/* if( iDistance <= WeapBuf.usRange ) - switch(pSoldier->usAnimState) - { - case ANIM_PRONE: - pSoldier->usUIMovementMode = CRAWLING; - pSoldier->fUIMovementFast = FALSE; - break; - case ANIM_CROUCH: - pSoldier->usUIMovementMode = SWATTING; - pSoldier->fUIMovementFast = FALSE; - break; - case ANIM_STAND: - pSoldier->usUIMovementMode = RUNNING; - break; - }*/ - gpTurnMem[TM_LAST_DEST_GRID] = pSoldier->usActionData; - gpTurnMem[ TM_OUTOFRANGE ] = TRUE; - return( AI_ACTION_GET_CLOSER ); - } - }else if( ( pSoldier->usActionData = FindClimbGridNo( pSoldier, sClosestDisturbance, -1 ) ) != NOWHERE - && ( !pSoldier->bLevel && !InARoom( pSoldier->sGridNo, NULL ) ) && !gpTurnMem[ TM_TRIED_TO_CLIMBDOWN ] ) - { - if( pSoldier->usActionData == pSoldier->sGridNo ) - return DecideActionOnClimbSpot( pSoldier ); - - gpTurnMem[ TM_OUTOFRANGE ] = TRUE; - gpTurnMem[ TM_TRIED_TO_CLIMBDOWN ] = TRUE; - - pSoldier->usUIMovementMode = RUNNING; - pSoldier->fUIMovementFast = TRUE; - return( AI_ACTION_MOVE_TO_CLIMB ); - } - } - - } -} DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW"); //////////////////////////////////////////////////////////////////////////// // LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW @@ -4345,11 +4036,6 @@ bCanAttack = FALSE; { // gotta compare their merits and select the more desirable option iOffense = BestAttack.ubChanceToReallyHit; - if( !gpTurnMem[ TM_LOOKED_FOR_COVER ] && BestAttack.ubChanceToReallyHit < 80 ) - { - iDefense = 100 + iCoverPercentBetter; - gpTurnMem[ TM_LOOKED_FOR_COVER ] = TRUE; - }else iDefense = iCoverPercentBetter; // based on how we feel about the situation, decide whether to attack first @@ -4390,12 +4076,12 @@ bCanAttack = FALSE; switch (pSoldier->bAttitude) { - case DEFENSIVE: iDefense += 20; break; - case BRAVESOLO: iDefense -= 10; break; - case BRAVEAID: iDefense -= 10; break; - case CUNNINGSOLO: iDefense += 10; break; - case CUNNINGAID: iDefense += 10; break; - case AGGRESSIVE: iOffense += 20; break; + case DEFENSIVE: iDefense += 30; break; + case BRAVESOLO: iDefense -= 0; break; + case BRAVEAID: iDefense -= 0; break; + case CUNNINGSOLO: iDefense += 20; break; + case CUNNINGAID: iDefense += 20; break; + case AGGRESSIVE: iOffense += 10; break; case ATTACKSLAYONLY:iOffense += 30; break; } @@ -4603,6 +4289,7 @@ bCanAttack = FALSE; case ATTACKSLAYONLY:iChance += 30; break; } + if ( pSoldier->inv[BestAttack.bWeaponIn].ubGunShotsLeft > 50 ) iChance += 30; @@ -4718,7 +4405,7 @@ bCanAttack = FALSE; DebugAI( tempstr); #endif - gpTurnMem[ TM_HASFIRED ] =TRUE; + DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("DecideActionBlack: Check for GL Bursts, is launcher capable? = %d, rtpcombat? = %d, bestattackaction = %d",IsGunBurstCapable( pSoldier, BestAttack.bWeaponIn, FALSE ),pSoldier->bRTPCombat,ubBestAttackAction )); if (ubBestAttackAction == AI_ACTION_TOSS_PROJECTILE && IsGunBurstCapable( pSoldier, BestAttack.bWeaponIn, FALSE ) && (pSoldier->bTeam != gbPlayerNum || pSoldier->bRTPCombat == RTP_COMBAT_AGGRESSIVE) ) @@ -4823,20 +4510,6 @@ bCanAttack = FALSE; pSoldier->usActionData = sBestCover; return(AI_ACTION_TAKE_COVER); - - //////////////////////////////////////////////////////////////////////////// - // PICKUP A NEARBY ITEM THAT'S USEFUL - //////////////////////////////////////////////////////////////////////////// - - if ( ubCanMove && !pSoldier->bNeutral && (gfTurnBasedAI || pSoldier->bTeam == ENEMY_TEAM ) ) - { - - pSoldier->bAction = SearchForItems( pSoldier, SEARCH_GENERAL_ITEMS, pSoldier->inv[HANDPOS].usItem ); - - if (pSoldier->bAction != AI_ACTION_NONE) - { - return( pSoldier->bAction ); - } } @@ -5000,33 +4673,8 @@ bCanAttack = FALSE; } } - //////////////////////////////////////////////////////////////////////////// - // CROUCH OR PRONE, IF THERE'S NOTHING TO DO ELSE - //////////////////////////////////////////////////////////////////////////// + // if a militia has absofreaking nothing else to do, maybe they should radio in a report! -if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND ) - if( pSoldier->bActionPoints >= GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) - && IsValidStance( pSoldier, ANIM_CROUCH ) ) - { - pSoldier->usActionData = ANIM_CROUCH; - return(AI_ACTION_CHANGE_STANCE); - } - -if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH ) - if( pSoldier->bActionPoints >= GetAPsToChangeStance( pSoldier, ANIM_PRONE ) - && IsValidStance( pSoldier, ANIM_PRONE ) ) - { - sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL); - - if(sClosestOpponent == NOWHERE || GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sClosestOpponent ) / 10 > 10) - { - pSoldier->usActionData = ANIM_PRONE; - return(AI_ACTION_CHANGE_STANCE); - } - } -} -/* -// if a militia has absofreaking nothing else to do, maybe they should radio in a report! //////////////////////////////////////////////////////////////////////////// // RADIO RED ALERT: determine %chance to call others and report contact //////////////////////////////////////////////////////////////////////////// @@ -5036,8 +4684,10 @@ if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH ) // if there hasn't been an initial RED ALERT yet in this sector if ( !(gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) || NeedToRadioAboutPanicTrigger() ) - // since I'm at STATUS RED, I obviously know we're being invaded! - iChance = gbDiff[DIFF_RADIO_RED_ALERT][ SoldierDifficultyLevel( pSoldier ) ]; + { // since I'm at STATUS RED, I obviously know we're being invaded! + DebugMsg(TOPIC_JA2AI,DBG_LEVEL_3,String("DecideActionBlack: check chance to radio contact")); + iChance = gbDiff[DIFF_RADIO_RED_ALERT][ SoldierDifficultyLevel( pSoldier ) ]; + } else // subsequent radioing (only to update enemy positions, request help) // base chance depends on how much new info we have to radio to the others iChance = 10 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 10 * for RED alert @@ -5055,7 +4705,7 @@ if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH ) case RNDPTPATROL: case POINTPATROL: iChance += -5; break; case FARPATROL: iChance += -10; break; - case SEEKENEMY: iChance += 40; break; + case SEEKENEMY: iChance += -20; break; } // modify base chance according to attitude @@ -5104,7 +4754,7 @@ if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH ) } } } -*/ + //////////////////////////////////////////////////////////////////////////// // LEAVE THE SECTOR //////////////////////////////////////////////////////////////////////////// @@ -5116,13 +4766,15 @@ if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH ) //////////////////////////////////////////////////////////////////////////// #ifdef DEBUGDECISIONS -AINameMessage(pSoldier,"- DOES NOTHING (BLACK)",1000); + AINameMessage(pSoldier,"- DOES NOTHING (BLACK)",1000); #endif -// by default, if everything else fails, just stand in place and wait -pSoldier->usActionData = NOWHERE; -return(AI_ACTION_NONE); + // by default, if everything else fails, just stand in place and wait + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); + } + INT8 DecideAction(SOLDIERTYPE *pSoldier) { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideAction"); @@ -5239,14 +4891,14 @@ INT8 DecideAction(SOLDIERTYPE *pSoldier) - #ifdef DEBUGDECISIONS - sprintf((CHAR *) tempstr,"DecideAction: selected action %d, actionData %d\n\n",bAction,pSoldier->usActionData); - DebugAI((STR) tempstr ); - #endif +#ifdef DEBUGDECISIONS + sprintf((CHAR *) tempstr,"DecideAction: selected action %d, actionData %d\n\n",bAction,pSoldier->usActionData); + DebugAI((STR) tempstr ); +#endif - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideAction done"); - - return(bAction); +DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideAction done"); + + return(bAction); } INT8 DecideActionEscort(SOLDIERTYPE *pSoldier) diff --git a/TacticalAI/FindLocations.cpp b/TacticalAI/FindLocations.cpp index 5312d7cf5..0db54efee 100644 --- a/TacticalAI/FindLocations.cpp +++ b/TacticalAI/FindLocations.cpp @@ -27,9 +27,6 @@ #include "PathAIDebug.h" -#define MINIMUM_DISTANCE_BETWEEN_TEAMMATES 10 -#define MAX_NEAREST_ROOF_SEARCH_RADIUS 15 - #ifdef _DEBUG INT16 gsCoverValue[WORLD_MAX]; INT16 gsBestCover; @@ -526,8 +523,6 @@ UINT8 NumberOfTeamMatesAdjacent( SOLDIERTYPE * pSoldier, INT16 sGridNo ) return( ubCount ); } -static INT16 gsDesiredGridNo = NOWHERE; - INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentBetter) { DebugMsg(TOPIC_JA2AI,DBG_LEVEL_3,String("FindBestNearbyCover")); @@ -559,7 +554,6 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB UINT8 ubBackgroundLightPercent = 0; UINT8 ubLightPercentDifference; BOOLEAN fNight; - UINT16 usTmDistRatingBuffer; switch( FindObj( pSoldier, GASMASK ) ) { @@ -716,14 +710,8 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB iThreatCertainty = ThreatPercent[*pbPublOL - OLDEST_HEARD_VALUE]; } - sThreatLoc = pOpponent->sGridNo; - iThreatCertainty = 100; - // calculate how far away this threat is (in adjusted pixels) //iThreatRange = AdjPixelsAway(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sThreatLoc),CenterY(sThreatLoc)); - if( gsDesiredGridNo != NOWHERE ) - iThreatRange = GetRangeInCellCoordsFromGridNoDiff( gsDesiredGridNo, sThreatLoc ); - else iThreatRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sThreatLoc ); //NumMessage("Threat Range = ",iThreatRange); @@ -733,7 +721,7 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB #endif // if this opponent is believed to be too far away to really be a threat - if (iThreatRange > iMaxThreatRange + Weapon[ Item[pOpponent->inv[HANDPOS].usItem].ubClassIndex ].usRange + GetRangeBonus(&pOpponent->inv[HANDPOS])) + if (iThreatRange > iMaxThreatRange) { #ifdef DEBUGCOVER // AINameMessage(pOpponent,"is too far away to be a threat",1000); @@ -793,51 +781,13 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB if (Threat[uiLoop].iOrigRange <= MAX_THREAT_RANGE) { // add this opponent's cover value to our current total cover value - if( gsDesiredGridNo == NOWHERE ) iCurrentCoverValue += CalcCoverValue(pSoldier,pSoldier->sGridNo,iMyThreatValue,pSoldier->bActionPoints,uiLoop,Threat[uiLoop].iOrigRange,morale,&iCurrentScale); - else - iCurrentCoverValue += CalcCoverValue(pSoldier,gsDesiredGridNo,iMyThreatValue,pSoldier->bActionPoints,uiLoop,Threat[uiLoop].iOrigRange,morale,&iCurrentScale); } //sprintf((CHAR *)tempstr,"iCurrentCoverValue after opponent %d is now %d",iLoop,iCurrentCoverValue); //PopMessage(tempstr); } -// iCurrentCoverValue -= (iCurrentCoverValue / 10) * NumberOfTeamMatesAdjacent( pSoldier, pSoldier->sGridNo ); - - - if( gsDesiredGridNo == NOWHERE ) - usTmDistRatingBuffer = CountRatingOfTeamMatesDensity( pSoldier, pSoldier->sGridNo, MINIMUM_DISTANCE_BETWEEN_TEAMMATES ); - else - usTmDistRatingBuffer = CountRatingOfTeamMatesDensity( pSoldier, gsDesiredGridNo, MINIMUM_DISTANCE_BETWEEN_TEAMMATES ); - usTmDistRatingBuffer *= usTmDistRatingBuffer; - -// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld:%ld", sGridNo, usTmDistRatingBuffer ); - - if ( iCurrentCoverValue >= 0 ) - { - iCurrentCoverValue -= (iCurrentCoverValue / 10) * usTmDistRatingBuffer; - } - else - { - // when negative, must add a negative to decrease the total - iCurrentCoverValue += (iCurrentCoverValue / 10) * usTmDistRatingBuffer; - } - - - // It's better to be in a room...I guess... - - if ( gsDesiredGridNo == NOWHERE ? InARoom( pSoldier->sGridNo, NULL ) : InARoom( gsDesiredGridNo, NULL ) ) - { - if ( iCurrentCoverValue >= 0 ) - { - iCurrentCoverValue += 2*iCurrentCoverValue; - } - else - { - iCurrentCoverValue -= 2*iCurrentCoverValue; - } - } - + iCurrentCoverValue -= (iCurrentCoverValue / 10) * NumberOfTeamMatesAdjacent( pSoldier, pSoldier->sGridNo ); #ifdef DEBUGCOVER // AINumMessage("Search Range = ",iSearchRange); @@ -932,11 +882,7 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB //HandleMyMouseCursor(KEYBOARDALSO); // calculate the next potential gridno - if( gsDesiredGridNo == NOWHERE ) sGridNo = pSoldier->sGridNo + sXOffset + (MAXCOL * sYOffset); - else - sGridNo = gsDesiredGridNo + sXOffset + (MAXCOL * sYOffset); - if ( !(sGridNo >=0 && sGridNo < WORLD_MAX) ) { continue; @@ -983,9 +929,6 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB } iPathCost = gubAIPathCosts[AI_PATHCOST_RADIUS + sXOffset][AI_PATHCOST_RADIUS + sYOffset]; - - if( iPathCost <= pSoldier->bActionPoints )iPathCost = 0; - /* // water is OK, if the only good hiding place requires us to get wet, OK iPathCost = LegalNPCDestination(pSoldier,sGridNo,ENSURE_PATH_COST,WATEROK); @@ -1032,25 +975,14 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB // reduce cover for each person adjacent to this gridno who is on our team, // by 10% (so locations next to several people will be very much frowned upon - - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld", iCoverValue ); - -// if( !iCoverValue ) -// iCoverValue -= 100; - - usTmDistRatingBuffer = CountRatingOfTeamMatesDensity( pSoldier, sGridNo, MINIMUM_DISTANCE_BETWEEN_TEAMMATES ); - usTmDistRatingBuffer *= usTmDistRatingBuffer; - -// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld:%ld", sGridNo, usTmDistRatingBuffer ); - if ( iCoverValue >= 0 ) { - iCoverValue -= (iCoverValue / 10) * usTmDistRatingBuffer; + iCoverValue -= (iCoverValue / 10) * NumberOfTeamMatesAdjacent( pSoldier, sGridNo ); } else { // when negative, must add a negative to decrease the total - iCoverValue += (iCoverValue / 10) * usTmDistRatingBuffer; + iCoverValue += (iCoverValue / 10) * NumberOfTeamMatesAdjacent( pSoldier, sGridNo ); } if ( fNight && !( InARoom( sGridNo, NULL ) ) ) // ignore in buildings in case placed there @@ -1061,31 +993,15 @@ INT16 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB ubLightPercentDifference = (gbLightSighting[ 0 ][ LightTrueLevel( sGridNo, pSoldier->bLevel ) ] - ubBackgroundLightPercent ); if ( iCoverValue >= 0 ) { - iCoverValue -= (iCoverValue / 20) * ubLightPercentDifference; + iCoverValue -= (iCoverValue / 100) * ubLightPercentDifference; } else { - iCoverValue += (iCoverValue / 20) * ubLightPercentDifference; + iCoverValue += (iCoverValue / 100) * ubLightPercentDifference; } } - // It's better to be in a room...I guess... - - if ( InARoom( sGridNo, NULL ) ) - { - if ( iCoverValue >= 0 ) - { - iCoverValue += 2*iCoverValue; - } - else - { - iCoverValue -= 2*iCoverValue; - } - } - - - #ifdef DEBUGCOVER // if there ARE multiple opponents if (uiThreatCnt > 1) @@ -1700,7 +1616,7 @@ INT16 FindNearbyDarkerSpot( SOLDIERTYPE *pSoldier ) // CJC: here, unfortunately, we must calculate a path so we have an AP cost - sPathCost = LegalNPCDestination(pSoldier,sGridNo,ENSURE_PATH_COST,WATEROK,0); + sPathCost = LegalNPCDestination(pSoldier,sGridNo,ENSURE_PATH_COST,NOWATER,0); if (!sPathCost) { @@ -2864,246 +2780,3 @@ BOOLEAN CanClimbFromHere (SOLDIERTYPE * pSoldier, BOOLEAN fUp ) return FALSE; } */ -extern BUILDING gBuildings[ MAX_BUILDINGS ]; -extern UINT8 gubNumberOfBuildings; - -BOOLEAN IsItValidClimbSpot( INT16 sGridNo, INT8 bLevel ) -{ - UINT16 usBuildingID; - UINT16 usClimbSpotIndex; - - for( usBuildingID = 1; usBuildingID <= gubNumberOfBuildings ; ++usBuildingID ) - for( usClimbSpotIndex = 0; usClimbSpotIndex < gBuildings[ usBuildingID ].ubNumClimbSpots ; ++usClimbSpotIndex ) - if( gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ] == sGridNo && !bLevel ) - { - if( WhoIsThere2( gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ], 1 ) == NOBODY ) - return TRUE; - }else if( gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ] == sGridNo && bLevel ) - { - if( WhoIsThere2( gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ], 0 ) == NOBODY ) - return TRUE; - } - return FALSE; -} - -BOOLEAN AreGridsAdjacent( INT16 sFGridNo, INT16 sSGridNo ) -{ - return sFGridNo == sSGridNo - 1 || - sFGridNo == sSGridNo + 1 || - sFGridNo == sSGridNo - MAXCOL || - sFGridNo == sSGridNo + MAXCOL; -} - -INT16 FindClimbGridNo( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 bMaxActionPoints ) -{ - BOOLEAN fClimbingNecessary; - INT16 sCGridNo; - INT16 sActionPointsNeeded = EstimatePathCostToLocation( pSoldier, sGridNo, 1, FALSE, &fClimbingNecessary, &sCGridNo ); - - if( sActionPointsNeeded != 0 && fClimbingNecessary ) - { - if( IsItValidClimbSpot( pSoldier->sGridNo, pSoldier->bLevel ) && AreGridsAdjacent( pSoldier->sGridNo, sCGridNo ) ) return pSoldier->sGridNo; - - if( bMaxActionPoints < 0 || ( bMaxActionPoints >= 0 && sActionPointsNeeded <= bMaxActionPoints ) ) - return sCGridNo; - else - return NOWHERE; - } - - return NOWHERE; -} - -INT16 FindBestCoverNearTheGridNo(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubSearchRadius ) -{ - INT32 iPercentBetter; -// INT16 sTrueGridNo; - INT16 sResultGridNo; - INT8 bRealWisdom = pSoldier->bWisdom; - -// sTrueGridNo = pSoldier->sGridNo; -// pSoldier->sGridNo = sGridNo; - gsDesiredGridNo = sGridNo; - pSoldier->bWisdom = 8 * ubSearchRadius;// 5 tiles - - sResultGridNo = FindBestNearbyCover( pSoldier, MORALE_NORMAL, &iPercentBetter); - - pSoldier->bWisdom = bRealWisdom; -// pSoldier->sGridNo = sTrueGridNo; - - gsDesiredGridNo = NOWHERE; - - if( sResultGridNo != NOWHERE ) - return sResultGridNo; - else - return sGridNo; - -} - -INT16 FindRoofBetweenGridNos( INT16 sFGridNo, INT16 sSGridNo ) -{ - INT16 sGridNo; - INT16 sCurrX, sCurrY; - INT16 sFGX, sFGY, sSGX, sSGY; - - ConvertGridNoToXY( sFGridNo, &sFGX, &sFGY ); - ConvertGridNoToXY( sSGridNo, &sSGX, &sSGY ); - -// if( pSoldier->bLevel ) -// return NOWHERE; - -// if ( gbWorldSectorZ > 0 ) -// return NOWHERE; - - - if( sFGX == sSGX ) - { - sCurrX = sFGX; - - if( sFGY < sSGY ) - for( sCurrY = sFGY; sCurrY < sSGY ; ++sCurrY ) - { - sGridNo = sCurrX + (MAXCOL * sCurrY); - if( gubBuildingInfo[ sGridNo ] ) - return sGridNo; - }else - if( sFGY > sSGY ) - for( sCurrY = sFGY; sCurrY > sSGY ; --sCurrY ) - { - sGridNo = sCurrX + (MAXCOL * sCurrY); - if( gubBuildingInfo[ sGridNo ] ) - return sGridNo; - } - - }else - if( sFGX < sSGX ) - for( sCurrX = sFGX;sCurrX < sSGX ; ++sCurrX ) - { - sCurrY = sFGY + ( sSGY - sFGY ) * ( (FLOAT)(sCurrX - sFGX) / (FLOAT)(sSGX - sFGX) ); - sGridNo = sCurrX + (MAXCOL * sCurrY); - - if( gubBuildingInfo[ sGridNo ] ) - return sGridNo; - }else - if( sFGX > sSGX ) - for( sCurrX = sFGX;sCurrX > sSGX ; --sCurrX ) - { - sCurrY = sFGY + ( sSGY - sFGY ) * ( (FLOAT)(sCurrX - sFGX) / (FLOAT)(sSGX - sFGX) ); - sGridNo = sCurrX + (MAXCOL * sCurrY); - - if( gubBuildingInfo[ sGridNo ] ) - return sGridNo; - } - - return NOWHERE; -} - -INT8 FindDirectionForClimbing( INT16 sGridNo ) -{ - UINT16 usBuildingID; - UINT16 usClimbSpotIndex; - - for( usBuildingID = 0; usBuildingID < gubNumberOfBuildings ; ++usBuildingID ) - for( usClimbSpotIndex = 0; usClimbSpotIndex < gBuildings[ usBuildingID ].ubNumClimbSpots ; ++usClimbSpotIndex ) - if( gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ] == sGridNo ) - { - if( WhoIsThere2( gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ], 1 ) == NOBODY ) - return atan8(CenterX(sGridNo),CenterY(sGridNo),CenterX(gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ]),CenterY(gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ])); - }else if( gBuildings[ usBuildingID ].sDownClimbSpots[ usClimbSpotIndex ] == sGridNo ) - { - if( WhoIsThere2( gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ], 0 ) == NOBODY ) - return atan8(CenterX(sGridNo),CenterY(sGridNo),CenterX(gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ]),CenterY(gBuildings[ usBuildingID ].sUpClimbSpots[ usClimbSpotIndex ])); - } - return DIRECTION_IRRELEVANT; -} - - -SOLDIERTYPE* FindFriendFarthestFromEnemies( SOLDIERTYPE * pSoldier ) -{ - UINT32 uiLoop; - SOLDIERTYPE *pFriend; - SOLDIERTYPE *pBestFriend = 0; - UINT16 uiBestEnemyDensity = 0xFFFF; - UINT16 uiCurrEnemyDensity; - - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pFriend = MercSlots[ uiLoop ]; - - // it's me! Next merc - if( pFriend == pSoldier ) - continue; - - // if this merc is inactive, at base, on assignment, dead, unconscious - if (!pFriend || (pFriend->bLife < OKLIFE)) - { - continue; // next merc - } - - // if this man is neutral / on the same side - if ( pSoldier->bSide != pFriend->bSide ) - { - continue; // next merc - } - - uiCurrEnemyDensity = CountRatingOfOpponentsDensity( pFriend, pFriend->sGridNo, MAX_DIST ); - - if( uiCurrEnemyDensity < uiBestEnemyDensity ) - { - uiBestEnemyDensity = uiCurrEnemyDensity; - pBestFriend = pFriend; - } - } - - if( pBestFriend == pSoldier ) - return 0; - - return pBestFriend; -} - -INT8 DetermineNearestRoof( SOLDIERTYPE *pSoldier ) -{ - INT32 iSearchRange; - INT16 sGridNo, sCGridNo, sBestCGridNo = NOWHERE; - INT8 sBestRoof = NO_BUILDING; - INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset; - UINT8 ubBestDist = 255; - - { - iSearchRange = MAX_NEAREST_ROOF_SEARCH_RADIUS; - - // determine maximum horizontal limits - sMaxLeft = min(iSearchRange,(pSoldier->sGridNo % MAXCOL)); - sMaxRight = min(iSearchRange,MAXCOL - ((pSoldier->sGridNo % MAXCOL) + 1)); - - // determine maximum vertical limits - sMaxUp = min(iSearchRange,(pSoldier->sGridNo / MAXROW)); - sMaxDown = min(iSearchRange,MAXROW - ((pSoldier->sGridNo / MAXROW) + 1)); - - - for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++) - { - for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++) - { - sGridNo = pSoldier->sGridNo + sXOffset + (MAXCOL * sYOffset); - - if( gubBuildingInfo[ sGridNo ] ) - { - sCGridNo = FindClimbGridNo( pSoldier, sGridNo, -1 ); - if( sCGridNo != NOWHERE && GetRangeFromGridNoDiff( pSoldier->sGridNo, sCGridNo ) < ubBestDist ) - { - ubBestDist = GetRangeFromGridNoDiff( pSoldier->sGridNo, sCGridNo ); - sBestCGridNo = sCGridNo; - sBestRoof = gubBuildingInfo[ sGridNo ]; - - } - } - - } - } - - if( sBestRoof ) - return sBestRoof; - } - - return NO_BUILDING; -}