1 #include "Types.h"
2 #include "Overhead.h"
3 #include "Random.h"
4 #include "Points.h"
5 
6 
7 extern BOOLEAN gfTurnBasedAI;
8 
9 // THIS IS AN ITEM #  - AND FOR NOW JUST COMPLETELY FAKE...
10 
11 #define MAX_TOSS_SEARCH_DIST    1       // must throw within this of opponent
12 #define NPC_TOSS_SAFETY_MARGIN  4       // all friends must be this far away
13 
14 #define ACTING_ON_SCHEDULE( p ) ( (p)->fAIFlags & AI_CHECK_SCHEDULE )
15 
16 // the AI should try to have this many APs before climbing a roof, if possible
17 #define AI_AP_CLIMBROOF 15
18 
19 #define TEMPORARILY     0
20 #define FOREVER         1
21 
22 #define IGNORE_PATH             0
23 #define ENSURE_PATH             1
24 #define ENSURE_PATH_COST        2
25 
26 //Kris:  November 10, 1997
27 //Please don't change this value from 10.  It will invalidate all of the maps and soldiers.
28 #define MAXPATROLGRIDS  10
29 
30 #define NOWATER         0
31 #define WATEROK         1
32 
33 #define DONTADDTURNCOST 0
34 #define ADDTURNCOST     1
35 
36 enum
37 {
38 	URGENCY_LOW = 0,
39 	URGENCY_MED,
40 	URGENCY_HIGH,
41 	NUM_URGENCY_STATES
42 };
43 
44 #define NOWATER         0
45 #define WATEROK         1
46 
47 #define IGNORE_PATH             0
48 #define ENSURE_PATH             1
49 #define ENSURE_PATH_COST        2
50 
51 #define MAX_ROAMING_RANGE       WORLD_COLS
52 
53 #define PTR_CIV_OR_MILITIA (IsOnCivTeam(pSoldier) || pSoldier->bTeam == MILITIA_TEAM)
54 
55 #define REALTIME_AI_DELAY (10000 + Random( 1000 ))
56 #define REALTIME_CIV_AI_DELAY ( 1000 * (gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector + gTacticalStatus.Team[ CIV_TEAM ].bMenInSector) + 5000 + 2000 * Random( 3 ) )
57 #define REALTIME_CREATURE_AI_DELAY ( 10000 + 1000 * Random( 3 ) )
58 
59 #define NOSHOOT_WAITABIT        -1
60 #define NOSHOOT_WATER           -2
61 #define NOSHOOT_MYSELF          -3
62 #define NOSHOOT_HURT            -4
63 #define NOSHOOT_NOAMMO          -5
64 #define NOSHOOT_NOLOAD          -6
65 #define NOSHOOT_NOWEAPON        -7
66 
67 #define PERCENT_TO_IGNORE_THREAT        50      // any less, use threat value
68 #define ACTION_TIMEOUT_CYCLES	50	// # failed cycles through AI
69 #define MAX_THREAT_RANGE  	400	// 30 tiles worth
70 #define MIN_PERCENT_BETTER	5	// 5% improvement in cover is good
71 
72 
73 #define TOSSES_PER_10TURNS      18      // max # of grenades tossable in 10 turns
74 #define SHELLS_PER_10TURNS      13      // max # of shells   firable  in 10 turns
75 
76 #define SEE_THRU_COVER_THRESHOLD        5      // min chance to get through
77 
78 struct THREATTYPE
79 {
80 	SOLDIERTYPE *pOpponent;
81 	INT16       sGridNo;
82 	INT32       iValue;
83 	INT32       iAPs;
84 	INT32       iCertainty;
85 	INT32       iOrigRange;
86 };
87 
88 // define for bAimTime for bursting
89 #define BURSTING 5
90 
91 struct ATTACKTYPE
92 {
93 	SOLDIERTYPE* opponent;     // which soldier is the victim?
94 	UINT8 ubPossible;          // is this attack form possible?  T/F
95 	UINT8 ubAimTime;           // how many extra APs to spend on aiming
96 	UINT8 ubChanceToReallyHit; // chance to hit * chance to get through cover
97 	INT32 iAttackValue;        // relative worthiness of this type of attack
98 	INT16 sTarget;             // target gridno of this attack
99 	INT8  bTargetLevel;        // target level of this attack
100 	UINT8 ubAPCost;            // how many APs the attack will use up
101 	INT8  bWeaponIn;           // the inv slot of the weapon in question
102 };
103 
104 extern THREATTYPE Threat[MAXMERCS];
105 extern int ThreatPercent[10];
106 extern UINT8 SkipCoverCheck;
107 
108 enum ItemSearchReason
109 {
110 	SEARCH_GENERAL_ITEMS,
111 	SEARCH_AMMO,
112 	SEARCH_WEAPONS
113 };
114 
115 // go as far as possible flags
116 #define FLAG_CAUTIOUS		0x01
117 #define FLAG_STOPSHORT	0x02
118 
119 #define STOPSHORTDIST 5
120 
121 INT16 AdvanceToFiringRange( SOLDIERTYPE * pSoldier, INT16 sClosestOpponent );
122 
123 void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot);
124 void CalcBestStab(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab, BOOLEAN fBladeAttack);
125 void CalcTentacleAttack(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab );
126 
127 INT16 CalcSpreadBurst( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT8 bTargetLevel );
128 INT32 CalcManThreatValue(SOLDIERTYPE *pSoldier, INT16 sMyGrid, UINT8 ubReduceForCover, SOLDIERTYPE * pMe );
129 INT8 CanNPCAttack(SOLDIERTYPE *pSoldier);
130 void CheckIfTossPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow);
131 BOOLEAN ClimbingNecessary( SOLDIERTYPE * pSoldier, INT16 sDestGridNo, INT8 bDestLevel );
132 INT8 ClosestPanicTrigger( SOLDIERTYPE * pSoldier );
133 INT16 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK, BOOLEAN * pfChangeLevel );
134 INT16 ClosestReachableFriendInTrouble(SOLDIERTYPE *pSoldier, BOOLEAN * pfClimbingNecessary);
135 INT16 ClosestSeenOpponent(SOLDIERTYPE *pSoldier, INT16 * psGridNo, INT8 * pbLevel);
136 void CreatureCall( SOLDIERTYPE * pCaller );
137 INT8 CreatureDecideAction( SOLDIERTYPE * pCreature );
138 void CreatureDecideAlertStatus( SOLDIERTYPE *pCreature );
139 INT8 CrowDecideAction( SOLDIERTYPE * pSoldier );
140 void DecideAlertStatus( SOLDIERTYPE *pSoldier );
141 INT8 DecideAutoBandage( SOLDIERTYPE * pSoldier );
142 UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction );
143 
144 INT16 EstimatePathCostToLocation( SOLDIERTYPE * pSoldier, INT16 sDestGridNo, INT8 bDestLevel, BOOLEAN fAddCostAfterClimbingUp, BOOLEAN * pfClimbingNecessary, INT16 * psClimbGridNo );
145 
146 bool FindBetterSpotForItem(SOLDIERTYPE&, INT8 slot);
147 INT16 FindClosestBoxingRingSpot( SOLDIERTYPE * pSoldier, BOOLEAN fInRing );
148 INT16 GetInterveningClimbingLocation( SOLDIERTYPE * pSoldier, INT16 sDestGridNo, INT8 bDestLevel, BOOLEAN * pfClimbingNecessary );
149 UINT8 GetTraversalQuoteActionID( INT8 bDirection );
150 INT16 GoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT16 sDesGrid, INT8 bAction);
151 
152 INT8 HeadForTheStairCase( SOLDIERTYPE * pSoldier );
153 
154 bool InGas(SOLDIERTYPE const*, GridNo);
155 bool InGasOrSmoke(SOLDIERTYPE const*, GridNo);
156 bool InWaterGasOrSmoke(SOLDIERTYPE const*, GridNo);
157 
158 void InitAttackType(ATTACKTYPE *pAttack);
159 
160 INT16 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT16 sDesGrid, INT8 bReserveAPs, INT8 bAction, INT8 fFlags );
161 
162 int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubPathMode, UINT8 ubWaterOK, UINT8 fFlags);
163 void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier);
164 INT16 MostImportantNoiseHeard( SOLDIERTYPE *pSoldier, INT32 *piRetValue, BOOLEAN * pfClimbingNecessary, BOOLEAN * pfReachable );
165 void NPCDoesAct(SOLDIERTYPE *pSoldier);
166 INT8 OKToAttack(const SOLDIERTYPE *ptr, int target);
167 BOOLEAN NeedToRadioAboutPanicTrigger( void );
168 INT8 PointPatrolAI(SOLDIERTYPE *pSoldier);
169 void PossiblyMakeThisEnemyChosenOne( SOLDIERTYPE * pSoldier );
170 INT8 RandomPointPatrolAI(SOLDIERTYPE *pSoldier);
171 INT32 RangeChangeDesire( const SOLDIERTYPE * pSoldier );
172 UINT16 RealtimeDelay( SOLDIERTYPE * pSoldier );
173 void RearrangePocket(SOLDIERTYPE *pSoldier, INT8 bPocket1, INT8 bPocket2, UINT8 bPermanent);
174 void RTHandleAI( SOLDIERTYPE * pSoldier );
175 INT8  SearchForItems(SOLDIERTYPE&, ItemSearchReason, UINT16 usItem);
176 UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 bDesiredDirection );
177 UINT8 StanceChange( SOLDIERTYPE * pSoldier, UINT8 ubAttackAPCost );
178 INT16 TrackScent( SOLDIERTYPE * pSoldier );
179 void RefreshAI(SOLDIERTYPE *pSoldier);
180 BOOLEAN InLightAtNight( INT16 sGridNo, INT8 bLevel );
181 INT16 FindNearbyDarkerSpot( SOLDIERTYPE *pSoldier );
182 
183 BOOLEAN ArmySeesOpponents( void );
184