#ifndef __AI_H #define __AI_H #include "types.h" #include "worlddef.h" #include "Soldier Control.h" #include "Isometric Utils.h" #include "Rotting Corpses.h" #define TESTAICONTROL extern INT16 gubAIPathCosts[19][19]; #define AI_PATHCOST_RADIUS 9 extern BOOLEAN gfDisplayCoverValues; //extern INT16 gsCoverValue[WORLD_MAX]; extern INT16 * gsCoverValue; // AI actions enum CreatureCalls { CALL_NONE = 0, CALL_1_PREY, CALL_MULTIPLE_PREY, CALL_ATTACKED, CALL_CRIPPLED, NUM_CREATURE_CALLS } ; #define DONTFORCE 0 #define FORCE 1 // ANY NEW ACTIONS ADDED - UPDATE OVERHEAD.C ARRAY WITH ACTION'S STRING VALUE #define FIRST_MOVEMENT_ACTION AI_ACTION_RANDOM_PATROL #define LAST_MOVEMENT_ACTION AI_ACTION_MOVE_TO_CLIMB typedef enum { AI_ACTION_NONE = 0, // maintain current position & facing // actions that involve a move to another tile AI_ACTION_RANDOM_PATROL, // move towards a random destination AI_ACTION_SEEK_FRIEND, // move towards friend in trouble AI_ACTION_SEEK_OPPONENT, // move towards a reported opponent AI_ACTION_TAKE_COVER, // run for nearest cover from threat AI_ACTION_GET_CLOSER, // move closer to a strategic location AI_ACTION_POINT_PATROL, // move towards next patrol point AI_ACTION_LEAVE_WATER_GAS, // seek nearest spot of ungassed land AI_ACTION_SEEK_NOISE, // seek most important noise heard AI_ACTION_ESCORTED_MOVE, // go where told to by escortPlayer AI_ACTION_RUN_AWAY, // run away from nearby opponent(s) AI_ACTION_KNIFE_MOVE, // preparing to stab an opponent AI_ACTION_APPROACH_MERC, // move up to a merc in order to talk with them; RT AI_ACTION_TRACK, // track a scent AI_ACTION_EAT, // monster eats corpse AI_ACTION_PICKUP_ITEM, // grab things lying on the ground AI_ACTION_SCHEDULE_MOVE, // move according to schedule AI_ACTION_WALK, // walk somewhere (NPC stuff etc) AI_ACTION_RUN, // run somewhere (NPC stuff etc) AI_ACTION_WITHDRAW, // back off AI_ACTION_FLANK_LEFT, // move to the left AI_ACTION_FLANK_RIGHT, // move to the right AI_ACTION_MOVE_TO_CLIMB, // move to edge of roof/building // miscellaneous movement actions AI_ACTION_CHANGE_FACING, // turn to face a different direction AI_ACTION_CHANGE_STANCE, // stand, crouch, or go prone // actions related to items and attacks AI_ACTION_YELLOW_ALERT, // tell friends opponent(s) heard AI_ACTION_RED_ALERT, // tell friends opponent(s) seen AI_ACTION_CREATURE_CALL, // creature communication AI_ACTION_PULL_TRIGGER, // go off to activate a panic trigger AI_ACTION_USE_DETONATOR, // grab detonator and set off bomb(s) AI_ACTION_FIRE_GUN, // shoot at nearby opponent AI_ACTION_TOSS_PROJECTILE, // throw grenade at/near opponent(s) AI_ACTION_KNIFE_STAB, // during the actual knifing attack AI_ACTION_THROW_KNIFE, // throw a knife AI_ACTION_GIVE_AID, // help injured/dying friend AI_ACTION_WAIT, // RT: don't do anything for a certain length of time AI_ACTION_PENDING_ACTION, // RT: wait for pending action (pickup, door open, etc) to finish AI_ACTION_DROP_ITEM, // duh AI_ACTION_COWER, // for civilians: cower in fear and stay there! AI_ACTION_STOP_COWERING, // stop cowering AI_ACTION_OPEN_OR_CLOSE_DOOR, // schedule-provoked; open or close door AI_ACTION_UNLOCK_DOOR, // schedule-provoked; unlock door (don't open) AI_ACTION_LOCK_DOOR, // schedule-provoked; lock door (close if necessary) AI_ACTION_LOWER_GUN, // lower gun prior to throwing knife AI_ACTION_ABSOLUTELY_NONE, // like "none" but can't be converted to a wait by realtime AI_ACTION_CLIMB_ROOF, // climb up or down roof AI_ACTION_END_TURN, // end turn (after final stance change) AI_ACTION_END_COWER_AND_MOVE, // sort of dummy value, special for civilians who are to go somewhere at end of battle 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 AI_ACTION_RELOAD_GUN, AI_ACTION_JUMP_WINDOW, // added by Flugente: jump through a window AI_ACTION_FREE_PRISONER, // added by Flugente: free a prisoner AI_ACTION_USE_SKILL, // added by Flugente: perform a skill, which one is stored in usAISkillUse AI_ACTION_DOCTOR, // added by Flugente: AI-ONLY! bandage/surgery on fellow AI. DO NOT USE THIS FOR MERCS!!! AI_ACTION_DOCTOR_SELF, // added by Flugente: AI-ONLY! bandage/surgery on self. DO NOT USE THIS FOR MERCS!!! AI_ACTION_SELFDETONATE, // added by Flugente: blow up an explosive in own inventory AI_ACTION_STOP_MEDIC, // sevenfm: stop giving aid animation AI_ACTION_LAST = AI_ACTION_STOP_MEDIC } ActionType; enum QuoteActionType { QUOTE_ACTION_ID_CHECKFORDEST = 1, QUOTE_ACTION_ID_TURNTOWARDSPLAYER, QUOTE_ACTION_ID_DRAWGUN, QUOTE_ACTION_ID_LOWERGUN, QUOTE_ACTION_ID_TRAVERSE_EAST, QUOTE_ACTION_ID_TRAVERSE_SOUTH, QUOTE_ACTION_ID_TRAVERSE_WEST, QUOTE_ACTION_ID_TRAVERSE_NORTH, } ; #define RTP_COMBAT_AGGRESSIVE 1 #define RTP_COMBAT_CONSERVE 2 #define RTP_COMBAT_REFRAIN 3 // NB THESE THREE FLAGS SHOULD BE REMOVED FROM CODE #define AI_RTP_OPTION_CAN_RETREAT 0x01 #define AI_RTP_OPTION_CAN_SEEK_COVER 0x02 #define AI_RTP_OPTION_CAN_HELP 0x04 #define AI_CAUTIOUS 0x08 #define AI_HANDLE_EVERY_FRAME 0x10 #define AI_ASLEEP 0x20 #define AI_LOCK_DOOR_INCLUDES_CLOSE 0x40 #define AI_CHECK_SCHEDULE 0x80 #define NOT_NEW_SITUATION 0 #define WAS_NEW_SITUATION 1 #define IS_NEW_SITUATION 2 #define DIFF_ENEMY_EQUIP_MOD 0 #define DIFF_ENEMY_TO_HIT_MOD 1 #define DIFF_ENEMY_INTERRUPT_MOD 2 #define DIFF_RADIO_RED_ALERT 3 #define DIFF_MAX_COVER_RANGE 4 #define MAX_DIFF_PARMS 5 // how many different difficulty variables? extern INT8 gbDiff[MAX_DIFF_PARMS][5]; enum{ ADVANCE_SPOT_SIGHT_COVER, ADVANCE_SPOT_PRONE_COVER, ADVANCE_SPOT_ANY_COVER }; void ActionDone(SOLDIERTYPE *pSoldier); INT16 ActionInProgress(SOLDIERTYPE *pSoldier); INT8 CalcMorale(SOLDIERTYPE *pSoldier); INT32 CalcPercentBetter(INT32 iOldValue, INT32 iNewValue, INT32 iOldScale, INT32 iNewScale); void CallAvailableEnemiesTo(INT32 sGridNo); void CallAvailableKingpinMenTo( INT32 sGridNo ); void CallAvailableTeamEnemiesTo( INT32 sGridNo, INT8 bTeam ); void CallEldinTo( INT32 sGridNo ); void CancelAIAction(SOLDIERTYPE *pSoldier, UINT8 ubForce); void CheckForChangingOrders(SOLDIERTYPE *pSoldier ); INT8 ClosestPanicTrigger( SOLDIERTYPE * pSoldier ); INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel, SoldierID *pubOpponentID = NULL); INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); INT32 ClosestUnDisguisedPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); // Flugente: like ClosestPC(...), but does not account for covert or not visible mercs BOOLEAN CanAutoBandage( BOOLEAN fDoFullCheck ); void DebugAI( STR szOutput ); enum { AI_MSG_START, AI_MSG_DECIDE, AI_MSG_INFO, AI_MSG_TOPIC }; void DebugAI(INT8 bMsgType, SOLDIERTYPE *pSoldier, STR szOutput, INT8 bAction = -1); void DebugQuestInfo(STR szOutput); INT8 DecideAction(SOLDIERTYPE *pSoldier); INT8 DecideActionBlack(SOLDIERTYPE *pSoldier); INT8 DecideActionEscort(SOLDIERTYPE *pSoldier); INT8 DecideActionGreen(SOLDIERTYPE *pSoldier); INT8 DecideActionRed(SOLDIERTYPE *pSoldier); INT8 DecideActionYellow(SOLDIERTYPE *pSoldier); INT16 DistanceToClosestFriend( SOLDIERTYPE * pSoldier ); void EndAIDeadlock(void); void EndAIGuysTurn( SOLDIERTYPE *pSoldier ); INT8 ExecuteAction(SOLDIERTYPE *pSoldier); INT32 FindAdjacentSpotBeside(SOLDIERTYPE *pSoldier, INT32 sGridNo); INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *pPercentBetter); INT32 FindClosestDoor( SOLDIERTYPE * pSoldier ); INT32 FindNearbyPointOnEdgeOfMap( SOLDIERTYPE * pSoldier, INT8 * pbDirection ); INT32 FindNearestEdgePoint( INT32 sGridNo ); INT32 FindNearestPassableSpot( INT32 sGridNo, UINT8 usSearchRadius = 5 ); //Kris: Added these as I need specific searches on certain sides. enum { NORTH_EDGEPOINT_SEARCH, EAST_EDGEPOINT_SEARCH, SOUTH_EDGEPOINT_SEARCH, WEST_EDGEPOINT_SEARCH, }; INT32 FindNearestEdgepointOnSpecifiedEdge( INT32 sGridNo, INT8 bEdgeCode ); INT32 FindNearestUngassedLand(SOLDIERTYPE *pSoldier); BOOLEAN FindRoofClimbingPoints( SOLDIERTYPE * pSoldier, INT16 sDesiredSpot ); INT32 FindSpotMaxDistFromOpponents(SOLDIERTYPE *pSoldier); INT32 FindSweetCoverSpot(SOLDIERTYPE *pSoldier); void FreeUpNPCFromAttacking(SoldierID ubID); void FreeUpNPCFromPendingAction( SOLDIERTYPE * pSoldier ); void FreeUpNPCFromTurning(SOLDIERTYPE *pSoldier, INT8 bLook); void FreeUpNPCFromStanceChange(SOLDIERTYPE *pSoldier ); void FreeUpNPCFromLoweringGun( SOLDIERTYPE *pSoldier ); void FreeUpNPCFromRoofClimb(SOLDIERTYPE *pSoldier ); UINT8 GetClosestOpponent( SOLDIERTYPE *pSoldier ); SoldierID GetMostThreateningOpponent( SOLDIERTYPE *pSoldier ); void HandleSoldierAI( SOLDIERTYPE *pSoldier ); void HandleInitialRedAlert( INT8 bTeam, UINT8 ubCommunicate); void InitPanicSystem(); INT16 InWaterOrGas(SOLDIERTYPE *pSoldier, INT32 sGridno); BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier, INT8 bAction = AI_ACTION_NONE); BOOLEAN InitAI( void ); void MakeClosestEnemyChosenOne(); void ManChecksOnFriends(SOLDIERTYPE *pSoldier); void NewDest(SOLDIERTYPE *pSoldier, INT32 sGridNo); INT32 NextPatrolPoint(SOLDIERTYPE *pSoldier); INT8 PanicAI(SOLDIERTYPE *pSoldier, UINT8 ubCanMove); void HaltMoveForSoldierOutOfPoints(SOLDIERTYPE *pSoldier); INT32 RandDestWithinRange(SOLDIERTYPE *pSoldier); INT16 RandomFriendWithin(SOLDIERTYPE *pSoldier); INT16 RoamingRange(SOLDIERTYPE *pSoldier, INT32 *pFromGridNo); void SetCivilianDestination(SoldierID ubWho, INT32 sGridNo); void SetNewSituation( SOLDIERTYPE * pSoldier ); UINT8 SoldierDifficultyLevel( SOLDIERTYPE * pSoldier ); void SoldierTriesToContinueAlongPath(SOLDIERTYPE *pSoldier); void StartNPCAI(SOLDIERTYPE *pSoldier); void TempHurt(SOLDIERTYPE *pVictim, SOLDIERTYPE *pAttacker); int TryToResumeMovement(SOLDIERTYPE *pSoldier, INT32 sGridNo); BOOLEAN ValidCreatureTurn( SOLDIERTYPE * pCreature, INT8 bNewDirection ); BOOLEAN WearGasMaskIfAvailable( SOLDIERTYPE * pSoldier ); INT16 WhatIKnowThatPublicDont(SOLDIERTYPE *pSoldier, UINT8 ubInSightOnly); INT32 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp ); INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction ); BOOLEAN CanClimbFromHere (SOLDIERTYPE * pSoldier, BOOLEAN fUp ); // HEADROCK HAM 3.6: Adding includes for A* cover calculations INT8 CalcWorstCTGTForPosition( SOLDIERTYPE * pSoldier, SoldierID ubOppID, INT32 sOppGridNo, INT8 bLevel, INT32 iMyAPsLeft ); INT8 CalcBestCTGT( SOLDIERTYPE *pSoldier, SoldierID ubOppID, INT32 sOppGridNo, INT8 bLevel, INT32 iMyAPsLeft ); INT8 CalcAverageCTGTForPosition( SOLDIERTYPE * pSoldier, SoldierID ubOppID, INT32 sOppGridNo, INT8 bLevel, INT32 iMyAPsLeft ); UINT8 NumberOfTeamMatesAdjacent( SOLDIERTYPE * pSoldier, INT32 sGridNo ); // Flugente: get the id of the closest soldier (coser than x tiles) of a specific team with a specific flag that we can currently see SoldierID GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag, BOOLEAN fCheckSight = TRUE ); // get the id of the closest soldier (closer than x tiles) of a specific team that is wounded that we can currently see SoldierID GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam ); // get the id of the closest medic (closer than x tiles) of a specific team SoldierID GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam ); // sevenfm: BOOLEAN NightLight(void); BOOLEAN DuskLight(void); BOOLEAN InSmokeNearby(INT32 sGridNo, INT8 bLevel); INT16 MaxNormalVisionDistance( void ); UINT8 MinFlankDirections( SOLDIERTYPE *pSoldier ); UINT16 CountFriendsInDirection( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo ); BOOLEAN GuySawEnemy( SOLDIERTYPE * pSoldier, UINT8 ubMax = SEEN_3_TURNS_AGO ); UINT16 CountNearbyFriends( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance ); UINT8 CountNearbyFriendsLastAttackHit( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance ); UINT8 CountFriendsFlankSameSpot(SOLDIERTYPE *pSoldier, INT32 sSpot = NOWHERE); UINT8 CountFriendsBlack( SOLDIERTYPE *pSoldier, INT32 sClosestOpponent = NOWHERE ); UINT16 CountTeamUnderAttack(INT8 bTeam, INT32 sGridNo, INT16 sDistance); UINT16 CountPublicKnownEnemies(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 sDistance); UINT16 CountPublicKnownEnemies(SOLDIERTYPE *pSoldier); UINT8 SectorCurfew(BOOLEAN fNight); UINT8 TeamPercentKilled(INT8 bTeam); BOOLEAN TeamHighPercentKilled(INT8 bTeam); UINT8 ArmyPercentKilled(void); UINT8 ArmyPercentKilledTolerance(void); BOOLEAN EnemySeenSoldierRecently( SOLDIERTYPE *pSoldier, UINT8 ubMax = SEEN_3_TURNS_AGO ); UINT16 CountTeamSeeSoldier( INT8 bTeam, SOLDIERTYPE *pSoldier ); BOOLEAN AICheckFriendsNoContact( SOLDIERTYPE *pSoldier ); BOOLEAN AICheckIsFlanking( SOLDIERTYPE *pSoldier ); INT8 CalcMoraleNew(SOLDIERTYPE *pSoldier); UINT32 PrepareThreatlist(SOLDIERTYPE *pSoldier); SoldierID ClosestSeenThreatID(SOLDIERTYPE *pSoldier, UINT32 uiThreatCnt, UINT8 ubMax = SEEN_CURRENTLY); // first call PrepareThreatlist to make threat list SoldierID ClosestKnownThreatID(SOLDIERTYPE *pSoldier, UINT32 uiThreatCnt); // first call PrepareThreatlist to make threat list BOOLEAN ProneSightCoverAtSpot(SOLDIERTYPE *pSoldier, INT32 sSpot, BOOLEAN fUnlimited); BOOLEAN SightCoverAtSpot(SOLDIERTYPE *pSoldier, INT32 sSpot, BOOLEAN fUnlimited); BOOLEAN AnyCoverAtSpot(SOLDIERTYPE *pSoldier, INT32 sSpot); BOOLEAN AnyCoverFromSpot(INT32 sSpot, INT8 bLevel, INT32 sThreatLoc, INT8 bThreatLevel); INT32 FindAdvanceSpot(SOLDIERTYPE *pSoldier, INT32 sTargetSpot, INT8 bAction, UINT8 ubType, BOOLEAN fUnlimited); INT32 FindRetreatSpot(SOLDIERTYPE *pSoldier); BOOLEAN CheckDoorAtGridno(UINT32 usGridNo); BOOLEAN CheckDoorNearGridno(UINT32 usGridNo); BOOLEAN FindBombNearby( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance ); UINT8 RedSmokeDanger(INT32 sGridNo, INT8 bLevel); BOOLEAN CheckArtilleryStrike(void); BOOLEAN CheckRoof(INT32 sGridNo); UINT8 TerrainDensity(INT32 sSpot, INT8 bLevel, UINT8 ubDistance, BOOLEAN fGrass); BOOLEAN FindNearbyExplosiveStructure(INT32 sSpot, INT8 bLevel); INT16 DistanceToClosestActiveOpponent(SOLDIERTYPE *pSoldier, INT32 sSpot); BOOLEAN ValidOpponent(SOLDIERTYPE* pSoldier, SOLDIERTYPE* pOpponent); UINT16 CountSeenEnemiesLastTurn( SOLDIERTYPE *pSoldier ); BOOLEAN FindObstacleNearSpot(INT32 sSpot, INT8 bLevel); BOOLEAN CheckNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo); UINT8 SpotDangerLevel(SOLDIERTYPE *pSoldier, INT32 sGridNo); BOOLEAN AllowDeepWaterFlanking(SOLDIERTYPE *pSoldier); BOOLEAN AICheckUnderground(void); INT32 RandomizeLocation(INT32 sSpot, INT8 bLevel, UINT8 ubTimes, SOLDIERTYPE *pSightSoldier); INT32 RandomizeOpponentLocation(INT32 sSpot, SOLDIERTYPE *pOpponent, INT16 sMaxDistance); BOOLEAN CorpseWarning(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel); BOOLEAN CorpseEnemyTeam(ROTTING_CORPSE *pCorpse); BOOLEAN CorpseMilitiaTeam(ROTTING_CORPSE *pCorpse); BOOLEAN NorthSpot(INT32 sSpot, INT8 bLevel); BOOLEAN SoldierAI(SOLDIERTYPE *pSoldier); BOOLEAN WeAttack(INT8 bTeam); BOOLEAN CheckSuppressionDirection(SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bTargetLevel); UINT8 AIDirection(INT32 sSpot1, INT32 sSpot2); BOOLEAN AIGunScoped(SOLDIERTYPE *pSoldier); BOOLEAN AIGunInHandScoped(SOLDIERTYPE *pSoldier); UINT16 AIGunRange(SOLDIERTYPE *pSoldier); // gun range in tiles UINT16 AIGunClass(SOLDIERTYPE *pSoldier); UINT16 AIGunType(SOLDIERTYPE *pSoldier); UINT16 AIGunAmmo(SOLDIERTYPE *pSoldier); BOOLEAN AIGunAutofireCapable(SOLDIERTYPE *pSoldier); UINT8 AIGunDeadliness(SOLDIERTYPE *pSoldier); BOOLEAN AICheckNVG(SOLDIERTYPE *pSoldier); BOOLEAN AICheckHasWeaponOfType(SOLDIERTYPE *pSoldier, UINT8 ubWeaponType); BOOLEAN AICheckHasGun(SOLDIERTYPE *pSoldier); BOOLEAN AICheckShortWeaponRange(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsSniper(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsMarksman(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsMachinegunner(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsRadioOperator(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsMedic(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsMortarOperator(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsGLOperator(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsOfficer(SOLDIERTYPE *pSoldier); BOOLEAN AICheckIsCommander(SOLDIERTYPE *pSoldier); BOOLEAN AICheckSpecialRole(SOLDIERTYPE *pSoldier); // ************************************************************* // Knowledge functions // ************************************************************* INT8 Knowledge(SOLDIERTYPE *pSoldier, SoldierID ubOpponentID); INT32 KnownLocation(SOLDIERTYPE *pSoldier, SoldierID ubOpponentID); INT8 KnownLevel(SOLDIERTYPE *pSoldier, SoldierID ubOpponentID); BOOLEAN UsePersonalKnowledge(SOLDIERTYPE *pSoldier, SoldierID ubOpponentID); INT8 PersonalKnowledge(SOLDIERTYPE *pSoldier, SoldierID ubOpponentID); INT32 KnownPersonalLocation(SOLDIERTYPE *pSoldier, SoldierID ubOpponentID); INT8 KnownPersonalLevel(SOLDIERTYPE *pSoldier, SoldierID ubOpponentID); INT8 PublicKnowledge(UINT8 bTeam, SoldierID ubOpponentID); INT32 KnownPublicLocation(UINT8 bTeam, SoldierID ubOpponentID); INT8 KnownPublicLevel(UINT8 bTeam, SoldierID ubOpponentID); #define MAX_FLANKS_RED 25 #define MAX_FLANKS_YELLOW 25 #define MAX_TILES_MOVE_TURN (APBPConstants[AP_MAXIMUM] / (APBPConstants[AP_MOVEMENT_FLAT] + APBPConstants[AP_MODIFIER_RUN])) // vision range defines #define MAX_VISION_RANGE (gGameExternalOptions.ubStraightSightRange * STRAIGHT_RATIO * 4) #define DAY_VISION_RANGE (gGameExternalOptions.ubStraightSightRange * STRAIGHT_RATIO * 2) #define NIGHT_VISION_RANGE (gGameExternalOptions.ubStraightSightRange * STRAIGHT_RATIO ) #define VISION_RANGE MaxNormalVisionDistance() // sevenfm: limit min/max flank distance depending on sight range and time of day #define MIN_FLANK_DIST_YELLOW (DAY_VISION_RANGE/2) #define MAX_FLANK_DIST_YELLOW (VISION_RANGE + 20) #define MIN_FLANK_DIST_RED (DAY_VISION_RANGE/2) #define MAX_FLANK_DIST_RED (VISION_RANGE + 20) // sevenfm: distance for tactical AI checks, roughly equal to normal day vision range #define TACTICAL_RANGE (gGameExternalOptions.ubStraightSightRange * STRAIGHT_RATIO * 2) #define BOMB_DETECTION_RANGE (TACTICAL_RANGE / 4) #endif