1 #ifndef __SOLDER_CONTROL_H
2 #define __SOLDER_CONTROL_H
3 
4 
5 //Kris:  November 10, 1997
6 //Please don't change this value from 10.  It will invalidate all of the maps and soldiers.
7 #define MAXPATROLGRIDS  10  // *** THIS IS A DUPLICATION - MUST BE MOVED !
8 
9 #include "Animation_Cache.h"
10 #include "JA2Types.h"
11 #include "Overhead_Types.h"
12 #include "Item_Types.h"
13 
14 #include <string_theory/string>
15 
16 
17 // ANDREW: these are defines for OKDestanation usage - please move to approprite file
18 #define IGNOREPEOPLE					0
19 #define PEOPLETOO					1
20 #define ALLPEOPLE					2
21 #define FALLINGTEST					3
22 
23 #define LOCKED_NO_NEWGRIDNO				2
24 
25 #define NO_PROFILE					200
26 
27 #define BATTLE_SND_LOWER_VOLUME			1
28 
29 #define TAKE_DAMAGE_GUNFIRE				1
30 #define TAKE_DAMAGE_BLADE				2
31 #define TAKE_DAMAGE_HANDTOHAND				3
32 #define TAKE_DAMAGE_FALLROOF				4
33 #define TAKE_DAMAGE_BLOODLOSS				5
34 #define TAKE_DAMAGE_EXPLOSION				6
35 #define TAKE_DAMAGE_ELECTRICITY			7
36 #define TAKE_DAMAGE_GAS				8
37 #define TAKE_DAMAGE_TENTACLES				9
38 #define TAKE_DAMAGE_STRUCTURE_EXPLOSION		10
39 #define TAKE_DAMAGE_OBJECT				11
40 
41 
42 #define SOLDIER_MULTI_SELECTED				0x00000004
43 #define SOLDIER_PC					0x00000008
44 #define SOLDIER_ATTACK_NOTICED				0x00000010
45 #define SOLDIER_PCUNDERAICONTROL			0x00000020
46 #define SOLDIER_UNDERAICONTROL				0x00000040
47 #define SOLDIER_DEAD					0x00000080
48 #define SOLDIER_LOOKFOR_ITEMS				0x00000200
49 #define SOLDIER_ENEMY					0x00000400
50 #define SOLDIER_ENGAGEDINACTION			0x00000800
51 #define SOLDIER_ROBOT					0x00001000
52 #define SOLDIER_MONSTER				0x00002000
53 #define SOLDIER_ANIMAL					0x00004000
54 #define SOLDIER_VEHICLE				0x00008000
55 #define SOLDIER_MULTITILE				0x00020000
56 #define SOLDIER_TURNINGFROMHIT				0x00080000
57 #define SOLDIER_BOXER					0x00100000
58 #define SOLDIER_LOCKPENDINGACTIONCOUNTER		0x00200000
59 #define SOLDIER_COWERING				0x00400000
60 #define SOLDIER_MUTE					0x00800000
61 #define SOLDIER_GASSED					0x01000000
62 #define SOLDIER_OFF_MAP				0x02000000
63 #define SOLDIER_PAUSEANIMOVE				0x04000000
64 #define SOLDIER_DRIVER					0x08000000
65 #define SOLDIER_PASSENGER				0x10000000
66 #define SOLDIER_NPC_DOING_PUNCH			0x20000000
67 #define SOLDIER_NPC_SHOOTING				0x40000000
68 #define SOLDIER_LOOK_NEXT_TURNSOLDIER			0x80000000
69 
70 
71 /*
72 #define SOLDIER_TRAIT_LOCKPICKING			0x0001
73 #define SOLDIER_TRAIT_HANDTOHAND			0x0002
74 #define SOLDIER_TRAIT_ELECTRONICS			0x0004
75 #define SOLDIER_TRAIT_NIGHTOPS				0x0008
76 #define SOLDIER_TRAIT_THROWING				0x0010
77 #define SOLDIER_TRAIT_TEACHING				0x0020
78 #define SOLDIER_TRAIT_HEAVY_WEAPS			0x0040
79 #define SOLDIER_TRAIT_AUTO_WEAPS			0x0080
80 #define SOLDIER_TRAIT_STEALTHY				0x0100
81 #define SOLDIER_TRAIT_AMBIDEXT				0x0200
82 #define SOLDIER_TRAIT_THIEF				0x0400
83 #define SOLDIER_TRAIT_MARTIALARTS			0x0800
84 #define SOLDIER_TRAIT_KNIFING				0x1000
85 */
86 #define HAS_SKILL_TRAIT(s, t)				((s)->ubSkillTrait1 == (t) || (s)->ubSkillTrait2 == (t))
87 #define NUM_SKILL_TRAITS(s, t)				(((s)->ubSkillTrait1 == (t)) + ((s)->ubSkillTrait2 == (t)))
88 
89 #define SOLDIER_QUOTE_SAID_IN_SHIT			0x0001
90 #define SOLDIER_QUOTE_SAID_LOW_BREATH			0x0002
91 #define SOLDIER_QUOTE_SAID_BEING_PUMMELED		0x0004
92 #define SOLDIER_QUOTE_SAID_NEED_SLEEP			0x0008
93 #define SOLDIER_QUOTE_SAID_LOW_MORAL			0x0010
94 #define SOLDIER_QUOTE_SAID_MULTIPLE_CREATURES		0x0020
95 #define SOLDIER_QUOTE_SAID_ANNOYING_MERC		0x0040
96 #define SOLDIER_QUOTE_SAID_LIKESGUN			0x0080
97 #define SOLDIER_QUOTE_SAID_DROWNING			0x0100
98 #define SOLDIER_QUOTE_SAID_SPOTTING_CREATURE_ATTACK	0x0400
99 #define SOLDIER_QUOTE_SAID_SMELLED_CREATURE		0x0800
100 #define SOLDIER_QUOTE_SAID_ANTICIPATING_DANGER		0x1000
101 #define SOLDIER_QUOTE_SAID_WORRIED_ABOUT_CREATURES	0x2000
102 #define SOLDIER_QUOTE_SAID_PERSONALITY			0x4000
103 #define SOLDIER_QUOTE_SAID_FOUND_SOMETHING_NICE	0x8000
104 
105 #define SOLDIER_QUOTE_SAID_EXT_HEARD_SOMETHING	0x0001
106 #define SOLDIER_QUOTE_SAID_EXT_SEEN_CREATURE_ATTACK	0x0002
107 #define SOLDIER_QUOTE_SAID_EXT_USED_BATTLESOUND_HIT	0x0004
108 #define SOLDIER_QUOTE_SAID_EXT_CLOSE_CALL		0x0008
109 #define SOLDIER_QUOTE_SAID_EXT_MIKE			0x0010
110 #define SOLDIER_QUOTE_SAID_DONE_ASSIGNMENT		0x0020
111 #define SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED		0x0040
112 #define SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED		0x0080
113 #define SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED		0x0100
114 
115 
116 #define SOLDIER_CONTRACT_RENEW_QUOTE_NOT_USED		0
117 #define SOLDIER_CONTRACT_RENEW_QUOTE_89_USED		1
118 #define SOLDIER_CONTRACT_RENEW_QUOTE_115_USED		2
119 
120 
121 #define SOLDIER_MISC_HEARD_GUNSHOT			0x01
122 // make sure soldiers (esp tanks) are not hurt multiple times by explosions
123 #define SOLDIER_MISC_HURT_BY_EXPLOSION			0x02
124 // should be revealed due to xrays
125 #define SOLDIER_MISC_XRAYED				0x04
126 
127 #define NOBLOOD					40
128 #define MIN_BLEEDING_THRESHOLD				12 // you're OK while <4 Yellow life bars
129 
130 #define BANDAGED( s )					(s->bLifeMax - s->bLife - s->bBleeding)
131 
132 // amount of time a stats is to be displayed differently, due to change
133 #define CHANGE_STAT_RECENTLY_DURATION			60000
134 
135 
136 #define NO_PENDING_ACTION				255
137 #define NO_PENDING_ANIMATION				32001
138 #define NO_PENDING_DIRECTION				253
139 #define NO_PENDING_STANCE				254
140 #define NO_DESIRED_HEIGHT				255
141 
142 
143 //ENUMERATIONS FOR ACTIONS
144 enum
145 {
146 	MERC_OPENDOOR,
147 	MERC_OPENSTRUCT,
148 	MERC_PICKUPITEM,
149 	MERC_PUNCH,
150 	MERC_KNIFEATTACK,
151 	MERC_GIVEAID,
152 	MERC_GIVEITEM,
153 	MERC_WAITFOROTHERSTOTRIGGER,
154 	MERC_CUTFFENCE,
155 	MERC_DROPBOMB,
156 	MERC_STEAL,
157 	MERC_TALK,
158 	MERC_ENTER_VEHICLE,
159 	MERC_REPAIR,
160 	MERC_RELOADROBOT,
161 	MERC_TAKEBLOOD,
162 	MERC_ATTACH_CAN,
163 	MERC_FUEL_VEHICLE,
164 };
165 
166 // ENUMERATIONS FOR THROW ACTIONS
167 enum
168 {
169 	NO_THROW_ACTION,
170 	THROW_ARM_ITEM,
171 	THROW_TARGET_MERC_CATCH,
172 };
173 
174 // An enumeration for playing battle sounds
175 enum BattleSound
176 {
177 	BATTLE_SOUND_OK1,
178 	BATTLE_SOUND_OK2,
179 	BATTLE_SOUND_COOL1,
180 	BATTLE_SOUND_CURSE1,
181 	BATTLE_SOUND_HIT1,
182 	BATTLE_SOUND_HIT2,
183 	BATTLE_SOUND_LAUGH1,
184 	BATTLE_SOUND_ATTN1,
185 	BATTLE_SOUND_DIE1,
186 	BATTLE_SOUND_HUMM,
187 	BATTLE_SOUND_NOTHING,
188 	BATTLE_SOUND_GOTIT,
189 	BATTLE_SOUND_LOWMARALE_OK1,
190 	BATTLE_SOUND_LOWMARALE_OK2,
191 	BATTLE_SOUND_LOWMARALE_ATTN1,
192 	BATTLE_SOUND_LOCKED,
193 	BATTLE_SOUND_ENEMY,
194 	NUM_MERC_BATTLE_SOUNDS
195 };
196 
197 
198 //different kinds of merc
199 enum
200 {
201 	MERC_TYPE__PLAYER_CHARACTER,
202 	MERC_TYPE__AIM_MERC,
203 	MERC_TYPE__MERC,
204 	MERC_TYPE__NPC,
205 	MERC_TYPE__EPC,
206 	MERC_TYPE__NPC_WITH_UNEXTENDABLE_CONTRACT,
207 	MERC_TYPE__VEHICLE,
208 };
209 
210 // I don't care if this isn't intuitive!  The hand positions go right
211 // before the big pockets so we can loop through them that way. --CJC
212 #define NO_SLOT -1
213 
214 // vehicle/human path structure
215 struct PathSt
216 {
217 	UINT32 uiSectorId;
218 	PathSt* pNext;
219 	PathSt* pPrev;
220 };
221 
222 
223 enum InvSlotPos
224 {
225 	HELMETPOS = 0,
226 	VESTPOS,
227 	LEGPOS,
228 	HEAD1POS,
229 	HEAD2POS,
230 	HANDPOS,
231 	SECONDHANDPOS,
232 	BIGPOCK1POS,
233 	BIGPOCK2POS,
234 	BIGPOCK3POS,
235 	BIGPOCK4POS,
236 	SMALLPOCK1POS,
237 	SMALLPOCK2POS,
238 	SMALLPOCK3POS,
239 	SMALLPOCK4POS,
240 	SMALLPOCK5POS,
241 	SMALLPOCK6POS,
242 	SMALLPOCK7POS,
243 	SMALLPOCK8POS, // = 18, so 19 pockets needed
244 
245 	NUM_INV_SLOTS,
246 };
247 
248 //used for color codes, but also shows the enemy type for debugging purposes
249 enum SoldierClass
250 {
251 	SOLDIER_CLASS_NONE,
252 	SOLDIER_CLASS_ADMINISTRATOR,
253 	SOLDIER_CLASS_ELITE,
254 	SOLDIER_CLASS_ARMY,
255 	SOLDIER_CLASS_GREEN_MILITIA,
256 	SOLDIER_CLASS_REG_MILITIA,
257 	SOLDIER_CLASS_ELITE_MILITIA,
258 	SOLDIER_CLASS_CREATURE,
259 	SOLDIER_CLASS_MINER,
260 };
261 
262 #define SOLDIER_CLASS_ENEMY( bSoldierClass )		( ( bSoldierClass >= SOLDIER_CLASS_ADMINISTRATOR ) && ( bSoldierClass <= SOLDIER_CLASS_ARMY ) )
263 #define SOLDIER_CLASS_MILITIA( bSoldierClass )		( ( bSoldierClass >= SOLDIER_CLASS_GREEN_MILITIA ) && ( bSoldierClass <= SOLDIER_CLASS_ELITE_MILITIA ) )
264 
265 // This macro should be used whenever we want to see if someone is neutral
266 // IF WE ARE CONSIDERING ATTACKING THEM.  Creatures & bloodcats will attack neutrals
267 // but they can't attack empty vehicles!!
268 #define CONSIDERED_NEUTRAL(me, them)			((them)->bNeutral && ((me)->bTeam != CREATURE_TEAM || (them)->uiStatusFlags & SOLDIER_VEHICLE))
269 
270 struct KEY_ON_RING
271 {
272 	UINT8 ubKeyID;
273 	UINT8 ubNumber;
274 };
275 
276 
277 struct THROW_PARAMS
278 {
279 	float dX;
280 	float dY;
281 	float dZ;
282 	float dForceX;
283 	float dForceY;
284 	float dForceZ;
285 	float dLifeSpan;
286 	UINT8 ubActionCode;
287 	SOLDIERTYPE *target;
288 };
289 
290 #define DELAYED_MOVEMENT_FLAG_PATH_THROUGH_PEOPLE	0x01
291 
292 // reasons for being unable to continue movement
293 enum
294 {
295 	REASON_STOPPED_NO_APS,
296 	REASON_STOPPED_SIGHT,
297 };
298 
299 
300 enum
301 {
302 	HIT_BY_TEARGAS = 0x01,
303 	HIT_BY_MUSTARDGAS = 0x02,
304 	HIT_BY_CREATUREGAS = 0x04,
305 };
306 
307 
308 #define SOLDIERTYPE_NAME_LENGTH 10
309 
310 
311 struct SOLDIERTYPE
312 {
313 	// ID
314 	UINT8 ubID;
315 
316 	// DESCRIPTION / STATS, ETC
317 	UINT8 ubBodyType;
318 	INT8 bActionPoints;
319 	INT8 bInitialActionPoints;
320 
321 	UINT32 uiStatusFlags;
322 
323 	OBJECTTYPE inv[ NUM_INV_SLOTS ];
324 	OBJECTTYPE *pTempObject;
325 	KEY_ON_RING *pKeyRing;
326 
327 	INT8 bOldLife; // life at end of last turn, recorded for monster AI
328 	// attributes
329 	UINT8 bInSector;
330 	INT8 bFlashPortraitFrame;
331 	INT16 sFractLife; // fraction of life pts (in hundreths)
332 	INT8 bBleeding; // blood loss control variable
333 	INT8 bBreath; // current breath value
334 	INT8 bBreathMax; // max breath, affected by fatigue/sleep
335 	INT8 bStealthMode;
336 
337 	INT16 sBreathRed; // current breath value
338 	BOOLEAN fDelayedMovement;
339 
340 	UINT8 ubWaitActionToDo;
341 	INT8 ubInsertionDirection;
342 	// skills
343 	SOLDIERTYPE* opponent;
344 	INT8 bLastRenderVisibleValue;
345 	UINT8 ubAttackingHand;
346 	// traits
347 	INT16 sWeightCarriedAtTurnStart;
348 	ST::string name;
349 
350 	INT8 bVisible; // to render or not to render...
351 
352 
353 	INT8 bActive;
354 
355 	INT8 bTeam; // Team identifier
356 
357 	//NEW MOVEMENT INFORMATION for Strategic Movement
358 	UINT8 ubGroupID; //the movement group the merc is currently part of.
359 	BOOLEAN fBetweenSectors; //set when the group isn't actually in a sector.
360 	//sSectorX and sSectorY will reflect the sector the
361 	//merc was at last.
362 
363 	UINT8 ubMovementNoiseHeard;// 8 flags by direction
364 
365 	// 23 bytes so far
366 
367 	// WORLD POSITION STUFF
368 	FLOAT dXPos;
369 	FLOAT dYPos;
370 	INT16 sInitialGridNo;
371 	INT16 sGridNo;
372 	UINT8 bDirection;
373 	INT16 sHeightAdjustment;
374 	INT16 sDesiredHeight;
375 	INT16 sTempNewGridNo; // New grid no for advanced animations
376 	INT8 bOverTerrainType;
377 
378 	INT8 bCollapsed; // collapsed due to being out of APs
379 	INT8 bBreathCollapsed; // collapsed due to being out of APs
380 	// 50 bytes so far
381 
382 
383 	UINT8 ubDesiredHeight;
384 	UINT16 usPendingAnimation;
385 	UINT8 ubPendingStanceChange;
386 	UINT16 usAnimState;
387 	BOOLEAN fNoAPToFinishMove;
388 	BOOLEAN fPausedMove;
389 	BOOLEAN fUIdeadMerc; // UI Flags for removing a newly dead merc
390 	BOOLEAN fUICloseMerc; // UI Flags for closing panels
391 
392 
393 
394 	TIMECOUNTER UpdateCounter;
395 	TIMECOUNTER DamageCounter;
396 	TIMECOUNTER AICounter;
397 	TIMECOUNTER FadeCounter;
398 
399 	UINT8 ubSkillTrait1;
400 	UINT8 ubSkillTrait2;
401 
402 	INT8 bDexterity; // dexterity (hand coord) value
403 	INT8 bWisdom;
404 	SOLDIERTYPE* attacker;
405 	SOLDIERTYPE* previous_attacker;
406 	SOLDIERTYPE* next_to_previous_attacker;
407 	BOOLEAN fTurnInProgress;
408 
409 	BOOLEAN fIntendedTarget; // intentionally shot?
410 	BOOLEAN fPauseAllAnimation;
411 
412 	INT8 bExpLevel; // general experience level
413 	INT16 sInsertionGridNo;
414 
415 	BOOLEAN fContinueMoveAfterStanceChange;
416 
417 	// 60
418 	AnimationSurfaceCacheType AnimCache; // will be 9 bytes once changed to pointers
419 
420 	INT8 bLife; // current life (hit points or health)
421 	UINT8 bSide;
422 	INT8 bNewOppCnt;
423 
424 	UINT16 usAniCode;
425 	UINT16 usAniFrame;
426 	INT16 sAniDelay;
427 
428 	// MOVEMENT TO NEXT TILE HANDLING STUFF
429 	INT8 bAgility; // agility (speed) value
430 	INT16 sDelayedMovementCauseGridNo;
431 	INT16 sReservedMovementGridNo;
432 
433 	INT8 bStrength;
434 
435 	// Weapon Stuff
436 	INT16 sTargetGridNo;
437 	INT8 bTargetLevel;
438 	INT8 bTargetCubeLevel;
439 	INT16 sLastTarget;
440 	INT8 bTilesMoved;
441 	INT8 bLeadership;
442 	FLOAT dNextBleed;
443 	BOOLEAN fWarnedAboutBleeding;
444 	BOOLEAN fDyingComment;
445 
446 	UINT8 ubTilesMovedPerRTBreathUpdate;
447 	UINT16 usLastMovementAnimPerRTBreathUpdate;
448 
449 	BOOLEAN fTurningToShoot;
450 	BOOLEAN fTurningUntilDone;
451 	BOOLEAN fGettingHit;
452 	BOOLEAN fInNonintAnim;
453 	BOOLEAN fFlashLocator;
454 	INT16 sLocatorFrame;
455 	BOOLEAN fShowLocator;
456 	BOOLEAN fFlashPortrait;
457 	INT8 bMechanical;
458 	INT8 bLifeMax; // maximum life for this merc
459 
460 	FACETYPE* face;
461 
462 
463 	// PALETTE MANAGEMENT STUFF
464 	ST::string HeadPal;
465 	ST::string PantsPal;
466 	ST::string VestPal;
467 	ST::string SkinPal;
468 
469 	UINT16 *pShades[ NUM_SOLDIER_SHADES ]; // Shading tables
470 	UINT16 *pGlowShades[ 20 ]; //
471 	INT8 bMedical;
472 	BOOLEAN fBeginFade;
473 	UINT8 ubFadeLevel;
474 	UINT8 ubServiceCount;
475 	SOLDIERTYPE* service_partner;
476 	INT8 bMarksmanship;
477 	INT8 bExplosive;
478 	THROW_PARAMS *pThrowParams;
479 	BOOLEAN fTurningFromPronePosition;
480 	INT8 bReverse;
481 	LEVELNODE* pLevelNode;
482 
483 	// WALKING STUFF
484 	INT8 bDesiredDirection;
485 	INT16 sDestXPos;
486 	INT16 sDestYPos;
487 	INT16 sDestination;
488 	INT16 sFinalDestination;
489 	INT8 bLevel;
490 
491 	// PATH STUFF
492 	UINT8 ubPathingData[ MAX_PATH_LIST_SIZE ];
493 	UINT8 ubPathDataSize;
494 	UINT8 ubPathIndex;
495 	INT16 sBlackList;
496 	INT8 bAimTime;
497 	INT8 bShownAimTime;
498 	INT8 bPathStored; // good for AI to reduct redundancy
499 	INT8 bHasKeys; // allows AI controlled dudes to open locked doors
500 
501 	UINT8 ubStrategicInsertionCode;
502 	UINT16 usStrategicInsertionData;
503 
504 	LIGHT_SPRITE* light;
505 	LIGHT_SPRITE* muzzle_flash;
506 	INT8 bMuzFlashCount;
507 
508 	INT16 sX;
509 	INT16 sY;
510 
511 	UINT16 usOldAniState;
512 	INT16 sOldAniCode;
513 
514 	INT8 bBulletsLeft;
515 	UINT8 ubSuppressionPoints;
516 
517 	// STUFF FOR RANDOM ANIMATIONS
518 	UINT32 uiTimeOfLastRandomAction;
519 
520 	// AI STUFF
521 	INT8 bOppList[MAX_NUM_SOLDIERS]; // AI knowledge database
522 	INT8 bLastAction;
523 	INT8 bAction;
524 	UINT16 usActionData;
525 	INT8 bNextAction;
526 	UINT16 usNextActionData;
527 	INT8 bActionInProgress;
528 	INT8 bAlertStatus;
529 	INT8 bOppCnt;
530 	INT8 bNeutral;
531 	INT8 bNewSituation;
532 	INT8 bNextTargetLevel;
533 	INT8 bOrders;
534 	INT8 bAttitude;
535 	INT8 bUnderFire;
536 	INT8 bShock;
537 	INT8 bBypassToGreen;
538 	INT8 bDominantDir; // AI main direction to face...
539 	INT8 bPatrolCnt; // number of patrol gridnos
540 	INT8 bNextPatrolPnt; // index to next patrol gridno
541 	INT16 usPatrolGrid[MAXPATROLGRIDS];// AI list for ptr->orders==PATROL
542 	INT16 sNoiseGridno;
543 	UINT8 ubNoiseVolume;
544 	INT8 bLastAttackHit;
545 	SOLDIERTYPE* xrayed_by;
546 	FLOAT dHeightAdjustment;
547 	INT8 bMorale;
548 	INT8 bTeamMoraleMod;
549 	INT8 bTacticalMoraleMod;
550 	INT8 bStrategicMoraleMod;
551 	INT8 bAIMorale;
552 	UINT8 ubPendingAction;
553 	UINT8 ubPendingActionAnimCount;
554 	UINT32 uiPendingActionData1;
555 	INT16 sPendingActionData2;
556 	INT8 bPendingActionData3;
557 	INT8 ubDoorHandleCode;
558 	UINT32 uiPendingActionData4;
559 	INT8 bInterruptDuelPts;
560 	INT8 bPassedLastInterrupt;
561 	INT8 bIntStartAPs;
562 	INT8 bMoved;
563 	INT8 bHunting;
564 	UINT8 ubCaller;
565 	INT16 sCallerGridNo;
566 	UINT8 bCallPriority;
567 	INT8 bCallActedUpon;
568 	INT8 bFrenzied;
569 	INT8 bNormalSmell;
570 	INT8 bMonsterSmell;
571 	INT8 bMobility;
572 	INT8 fAIFlags;
573 
574 	BOOLEAN fDontChargeReadyAPs;
575 	UINT16 usAnimSurface;
576 	UINT16 sZLevel;
577 	BOOLEAN fPrevInWater;
578 	BOOLEAN fGoBackToAimAfterHit;
579 
580 	INT16 sWalkToAttackGridNo;
581 	INT16 sWalkToAttackWalkToCost;
582 
583 	BOOLEAN fForceShade;
584 	UINT16 *pForcedShade;
585 
586 	INT8 bDisplayDamageCount;
587 	INT8 fDisplayDamage;
588 	INT16 sDamage;
589 	INT16 sDamageX;
590 	INT16 sDamageY;
591 	INT8 bDoBurst;
592 	INT16 usUIMovementMode;
593 	BOOLEAN fUIMovementFast;
594 
595 	TIMECOUNTER BlinkSelCounter;
596 	TIMECOUNTER PortraitFlashCounter;
597 	BOOLEAN fDeadSoundPlayed;
598 	UINT8 ubProfile;
599 	UINT8 ubQuoteRecord;
600 	UINT8 ubQuoteActionID;
601 	UINT8 ubBattleSoundID;
602 
603 	BOOLEAN fClosePanel;
604 	BOOLEAN fClosePanelToDie;
605 	UINT8 ubClosePanelFrame;
606 	BOOLEAN fDeadPanel;
607 	UINT8 ubDeadPanelFrame;
608 
609 	INT16 sPanelFaceX;
610 	INT16 sPanelFaceY;
611 
612 	// QUOTE STUFF
613 	INT8 bNumHitsThisTurn;
614 	UINT16 usQuoteSaidFlags;
615 	INT8 fCloseCall;
616 	INT8 bLastSkillCheck;
617 	INT8 ubSkillCheckAttempts;
618 
619 	INT8 bStartFallDir;
620 	INT8 fTryingToFall;
621 
622 	UINT8 ubPendingDirection;
623 	UINT32 uiAnimSubFlags;
624 
625 	UINT8 bAimShotLocation;
626 	UINT8 ubHitLocation;
627 
628 	UINT16* effect_shade; // Shading table for effects
629 
630 	INT16 sSpreadLocations[ 6 ];
631 	BOOLEAN fDoSpread;
632 	INT16 sStartGridNo;
633 	INT16 sEndGridNo;
634 	INT16 sForcastGridno;
635 	INT16 sZLevelOverride;
636 	INT8 bMovedPriorToInterrupt;
637 	INT32 iEndofContractTime; // time, in global time(resolution, minutes) that merc will leave, or if its a M.E.R.C. merc it will be set to -1. -2 for NPC and player generated
638 	INT32 iStartContractTime;
639 	INT32 iTotalContractLength; // total time of AIM mercs contract or the time since last paid for a M.E.R.C. merc
640 	INT32 iNextActionSpecialData; // AI special action data record for the next action
641 	UINT8 ubWhatKindOfMercAmI; //Set to the type of character it is
642 	INT8 bAssignment; // soldiers current assignment
643 	BOOLEAN fForcedToStayAwake; // forced by player to stay awake, reset to false, the moment they are set to rest or sleep
644 	INT8 bTrainStat; // current stat soldier is training
645 	INT16 sSectorX; // X position on the Stategic Map
646 	INT16 sSectorY; // Y position on the Stategic Map
647 	INT8 bSectorZ; // Z sector location
648 	INT32 iVehicleId; // the id of the vehicle the char is in
649 	PathSt* pMercPath; // Path Structure
650 	UINT8 fHitByGasFlags; // flags
651 	UINT16 usMedicalDeposit; // is there a medical deposit on merc
652 	UINT16 usLifeInsurance; // is there life insurance taken out on merc
653 
654 	INT32 iStartOfInsuranceContract;
655 	UINT32 uiLastAssignmentChangeMin; // timestamp of last assignment change in minutes
656 	INT32 iTotalLengthOfInsuranceContract;
657 
658 	UINT8 ubSoldierClass; //admin, elite, troop (creature types?)
659 	UINT8 ubAPsLostToSuppression;
660 	BOOLEAN fChangingStanceDueToSuppression;
661 	SOLDIERTYPE* suppressor;
662 
663 	UINT8 ubCivilianGroup;
664 
665 	// time changes...when a stat was changed according to GetJA2Clock();
666 	UINT32 uiChangeLevelTime;
667 	UINT32 uiChangeHealthTime;
668 	UINT32 uiChangeStrengthTime;
669 	UINT32 uiChangeDexterityTime;
670 	UINT32 uiChangeAgilityTime;
671 	UINT32 uiChangeWisdomTime;
672 	UINT32 uiChangeLeadershipTime;
673 	UINT32 uiChangeMarksmanshipTime;
674 	UINT32 uiChangeExplosivesTime;
675 	UINT32 uiChangeMedicalTime;
676 	UINT32 uiChangeMechanicalTime;
677 
678 	UINT32 uiUniqueSoldierIdValue; // the unique value every instance of a soldier gets - 1 is the first valid value
679 	INT8 bBeingAttackedCount; // Being attacked counter
680 
681 	INT8 bNewItemCount[ NUM_INV_SLOTS ];
682 	INT8 bNewItemCycleCount[ NUM_INV_SLOTS ];
683 	BOOLEAN fCheckForNewlyAddedItems;
684 	INT8 bEndDoorOpenCode;
685 
686 	UINT8 ubScheduleID;
687 	INT16 sEndDoorOpenCodeData;
688 	TIMECOUNTER NextTileCounter;
689 	BOOLEAN fBlockedByAnotherMerc;
690 	INT8 bBlockedByAnotherMercDirection;
691 	UINT16 usAttackingWeapon;
692 	SOLDIERTYPE* target;
693 	INT8 bWeaponMode;
694 	INT8 bAIScheduleProgress;
695 	INT16 sOffWorldGridNo;
696 	ANITILE* pAniTile;
697 	INT8 bCamo;
698 	INT16 sAbsoluteFinalDestination;
699 	UINT8 ubHiResDirection;
700 	UINT8 ubLastFootPrintSound;
701 	INT8 bVehicleID;
702 	INT8 fPastXDest;
703 	INT8 fPastYDest;
704 	INT8 bMovementDirection;
705 	INT16 sOldGridNo;
706 	UINT16 usDontUpdateNewGridNoOnMoveAnimChange;
707 	INT16 sBoundingBoxWidth;
708 	INT16 sBoundingBoxHeight;
709 	INT16 sBoundingBoxOffsetX;
710 	INT16 sBoundingBoxOffsetY;
711 	UINT32 uiTimeSameBattleSndDone;
712 	INT8 bOldBattleSnd;
713 	BOOLEAN fContractPriceHasIncreased;
714 	UINT32 uiBurstSoundID;
715 	BOOLEAN fFixingSAMSite;
716 	BOOLEAN fFixingRobot;
717 	INT8 bSlotItemTakenFrom;
718 	BOOLEAN fSignedAnotherContract;
719 	SOLDIERTYPE* auto_bandaging_medic;
720 	BOOLEAN fDontChargeTurningAPs;
721 	SOLDIERTYPE* robot_remote_holder;
722 	UINT32 uiTimeOfLastContractUpdate;
723 	INT8 bTypeOfLastContract;
724 	INT8 bTurnsCollapsed;
725 	INT8 bSleepDrugCounter;
726 	UINT8 ubMilitiaKills;
727 
728 	INT8 bFutureDrugEffect[2]; // value to represent effect of a needle
729 	INT8 bDrugEffectRate[2]; // represents rate of increase and decrease of effect
730 	INT8 bDrugEffect[2]; // value that affects AP & morale calc ( -ve is poorly )
731 	INT8 bDrugSideEffectRate[2]; // duration of negative AP and morale effect
732 	INT8 bDrugSideEffect[2]; // duration of negative AP and morale effect
733 
734 	INT8 bBlindedCounter;
735 	BOOLEAN fMercCollapsedFlag;
736 	BOOLEAN fDoneAssignmentAndNothingToDoFlag;
737 	BOOLEAN fMercAsleep;
738 	BOOLEAN fDontChargeAPsForStanceChange;
739 
740 	UINT8 ubTurnsUntilCanSayHeardNoise;
741 	UINT16 usQuoteSaidExtFlags;
742 
743 	UINT16 sContPathLocation;
744 	INT8 bGoodContPath;
745 	INT8 bNoiseLevel;
746 	INT8 bRegenerationCounter;
747 	INT8 bRegenBoostersUsedToday;
748 	INT8 bNumPelletsHitBy;
749 	INT16 sSkillCheckGridNo;
750 	UINT8 ubLastEnemyCycledID;
751 
752 	UINT8 ubPrevSectorID;
753 	UINT8 ubNumTilesMovesSinceLastForget;
754 	INT8 bTurningIncrement;
755 	UINT32 uiBattleSoundID;
756 
757 	BOOLEAN fSoldierWasMoving;
758 	BOOLEAN fSayAmmoQuotePending;
759 	UINT16 usValueGoneUp;
760 
761 	UINT8 ubNumLocateCycles;
762 	UINT8 ubDelayedMovementFlags;
763 	BOOLEAN fMuzzleFlash;
764 	const SOLDIERTYPE* CTGTTarget;
765 
766 	TIMECOUNTER PanelAnimateCounter;
767 
768 	INT8 bCurrentCivQuote;
769 	INT8 bCurrentCivQuoteDelta;
770 	UINT8 ubMiscSoldierFlags;
771 	UINT8 ubReasonCantFinishMove;
772 
773 	INT16 sLocationOfFadeStart;
774 	UINT8 bUseExitGridForReentryDirection;
775 
776 	UINT32 uiTimeSinceLastSpoke;
777 	UINT8 ubContractRenewalQuoteCode;
778 	INT16 sPreTraversalGridNo;
779 	UINT32 uiXRayActivatedTime;
780 	INT8 bTurningFromUI;
781 	INT8 bPendingActionData5;
782 
783 	INT8 bDelayedStrategicMoraleMod;
784 	UINT8 ubDoorOpeningNoise;
785 
786 	UINT8 ubLeaveHistoryCode;
787 	BOOLEAN fDontUnsetLastTargetFromTurn;
788 	INT8 bOverrideMoveSpeed;
789 	BOOLEAN fUseMoverrideMoveSpeed;
790 
791 	UINT32 uiTimeSoldierWillArrive;
792 	BOOLEAN fUseLandingZoneForArrival;
793 	BOOLEAN fFallClockwise;
794 	INT8 bVehicleUnderRepairID;
795 	INT32 iTimeCanSignElsewhere;
796 	INT8 bHospitalPriceModifier;
797 	UINT32 uiStartTimeOfInsuranceContract;
798 	BOOLEAN fRTInNonintAnim;
799 	BOOLEAN fDoingExternalDeath;
800 	INT8 bCorpseQuoteTolerance;
801 	INT32 iPositionSndID;
802 	UINT32 uiTuringSoundID;
803 	UINT8 ubLastDamageReason;
804 	BOOLEAN fComplainedThatTired;
805 	INT16 sLastTwoLocations[2];
806 	INT32 uiTimeSinceLastBleedGrunt;
807 };
808 
809 #define BASE_FOR_EACH_SOLDIER_INV_SLOT(type, iter, soldier) \
810 	for (type* iter = (soldier).inv, * const iter##__end = endof((soldier).inv); iter != iter##__end; ++iter)
811 #define FOR_EACH_SOLDIER_INV_SLOT(iter, soldier) \
812 	BASE_FOR_EACH_SOLDIER_INV_SLOT(OBJECTTYPE,       iter, soldier)
813 #define CFOR_EACH_SOLDIER_INV_SLOT(iter, soldier) \
814 	BASE_FOR_EACH_SOLDIER_INV_SLOT(OBJECTTYPE const, iter, soldier)
815 
816 #define HEALTH_INCREASE					0x0001
817 #define STRENGTH_INCREASE				0x0002
818 #define DEX_INCREASE					0x0004
819 #define AGIL_INCREASE					0x0008
820 #define WIS_INCREASE					0x0010
821 #define LDR_INCREASE					0x0020
822 
823 #define MRK_INCREASE					0x0040
824 #define MED_INCREASE					0x0080
825 #define EXP_INCREASE					0x0100
826 #define MECH_INCREASE					0x0200
827 
828 #define LVL_INCREASE					0x0400
829 
830 
831 enum WeaponModes
832 {
833 	WM_NORMAL = 0,
834 	WM_BURST,
835 	WM_ATTACHED,
836 	NUM_WEAPON_MODES
837 };
838 
839 // TYPEDEFS FOR ANIMATION PROFILES
840 struct ANIM_PROF_TILE
841 {
842 	UINT16 usTileFlags;
843 	INT8   bTileX;
844 	INT8   bTileY;
845 };
846 
847 struct ANIM_PROF_DIR
848 {
849 	UINT8 ubNumTiles;
850 	ANIM_PROF_TILE *pTiles;
851 };
852 
853 struct ANIM_PROF
854 {
855 	ANIM_PROF_DIR Dirs[8];
856 };
857 
858 
859 struct PaletteReplacementType
860 {
861 	UINT8            ubType;
862 	ST::string       ID;
863 	UINT8            ubPaletteSize;
864 	SGPPaletteEntry* rgb;
865 };
866 
867 
868 // VARIABLES FOR PALETTE REPLACEMENTS FOR HAIR, ETC
869 extern UINT8*                  gubpNumReplacementsPerRange;
870 extern PaletteReplacementType* gpPalRep;
871 
872 extern UINT8 bHealthStrRanges[];
873 
874 
875 void DeleteSoldier(SOLDIERTYPE&);
876 void DeleteSoldierLight(SOLDIERTYPE*);
877 
878 void CreateSoldierCommon(SOLDIERTYPE&);
879 
880 
881 // Soldier Management functions, called by Event Pump.c
882 void EVENT_InitNewSoldierAnim(SOLDIERTYPE*, UINT16 new_state, UINT16 starting_ani_code, BOOLEAN force);
883 
884 void ChangeSoldierState(SOLDIERTYPE* pSoldier, UINT16 usNewState, UINT16 usStartingAniCode, BOOLEAN fForce);
885 
886 enum SetSoldierPosFlags
887 {
888 	SSP_NONE          = 0,
889 	SSP_NO_DEST       = 1U << 0,
890 	SSP_NO_FINAL_DEST = 1U << 1,
891 	SSP_FORCE_DELETE  = 1U << 2
892 };
893 ENUM_BITSET(SetSoldierPosFlags)
894 
895 void EVENT_SetSoldierPosition(SOLDIERTYPE* s, GridNo gridno, SetSoldierPosFlags flags);
896 void EVENT_SetSoldierPositionNoCenter(SOLDIERTYPE* s, GridNo gridno, SetSoldierPosFlags flags);
897 void EVENT_SetSoldierPositionXY(SOLDIERTYPE* s, FLOAT dNewXPos, FLOAT dNewYPos, SetSoldierPosFlags flags);
898 
899 void EVENT_GetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGridNo, UINT16 usMovementAnim );
900 BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGridNo, UINT16 usMovementAnim, BOOLEAN fFromUI, BOOLEAN fForceRestart );
901 
902 void EVENT_SetSoldierDirection( SOLDIERTYPE *pSoldier, UINT16	usNewDirection );
903 void EVENT_SetSoldierDesiredDirection( SOLDIERTYPE *pSoldier, UINT16	usNewDirection );
904 void EVENT_SetSoldierDesiredDirectionForward(SOLDIERTYPE* s, UINT16 new_direction);
905 void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo );
906 void EVENT_SoldierGotHit(SOLDIERTYPE* pSoldier, UINT16 usWeaponIndex, INT16 sDamage, INT16 sBreathLoss, UINT16 bDirection, UINT16 sRange, SOLDIERTYPE* att, UINT8 ubSpecial, UINT8 ubHitLocation, INT16 sLocationGrid);
907 void EVENT_SoldierBeginBladeAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
908 void EVENT_SoldierBeginPunchAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
909 void EVENT_SoldierBeginFirstAid( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
910 void EVENT_StopMerc(SOLDIERTYPE*);
911 void EVENT_StopMerc(SOLDIERTYPE*, GridNo, INT8 direction);
912 void EVENT_SoldierBeginCutFence( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
913 void EVENT_SoldierBeginRepair(SOLDIERTYPE&, GridNo, UINT8 direction);
914 void EVENT_SoldierBeginRefuel( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
915 
916 
917 BOOLEAN SoldierReadyWeapon(SOLDIERTYPE* pSoldier, GridNo tgt_pos, BOOLEAN fEndReady);
918 void SetSoldierHeight(SOLDIERTYPE*, FLOAT new_height);
919 void BeginSoldierClimbUpRoof( SOLDIERTYPE *pSoldier );
920 void BeginSoldierClimbDownRoof(SOLDIERTYPE*);
921 void BeginSoldierClimbFence(SOLDIERTYPE*);
922 void BeginSoldierClimbWindow(SOLDIERTYPE*);
923 
924 BOOLEAN CheckSoldierHitRoof( SOLDIERTYPE *pSoldier );
925 void BeginSoldierGetup( SOLDIERTYPE *pSoldier );
926 
927 // Soldier Management functions called by Overhead.c
928 BOOLEAN ConvertAniCodeToAniFrame( SOLDIERTYPE *pSoldier, UINT16 usAniFrame );
929 void TurnSoldier( SOLDIERTYPE *pSold);
930 void EVENT_BeginMercTurn(SOLDIERTYPE&);
931 void ChangeSoldierStance( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance );
932 void ModifySoldierAniSpeed( SOLDIERTYPE *pSoldier );
933 void StopSoldier( SOLDIERTYPE *pSoldier );
934 UINT8 SoldierTakeDamage(SOLDIERTYPE* pSoldier, INT16 sLifeDeduct, INT16 sBreathLoss, UINT8 ubReason, SOLDIERTYPE* attacker);
935 void ReviveSoldier( SOLDIERTYPE *pSoldier );
936 
937 
938 // Palette functions for soldiers
939 void  CreateSoldierPalettes(SOLDIERTYPE&);
940 UINT8 GetPaletteRepIndexFromID(const ST::string& pal_rep);
941 void SetPaletteReplacement(SGPPaletteEntry* p8BPPPalette, const ST::string& aPalRep);
942 void  LoadPaletteData(void);
943 void  DeletePaletteData(void);
944 
945 // UTILITY FUNCTUIONS
946 void MoveMerc( SOLDIERTYPE *pSoldier, FLOAT dMovementChange, FLOAT dAngle, BOOLEAN fCheckRange );
947 void MoveMercFacingDirection( SOLDIERTYPE *pSoldier, BOOLEAN fReverse, FLOAT dMovementDist );
948 INT16 GetDirectionFromGridNo(INT16 sGridNo, const SOLDIERTYPE* pSoldier);
949 UINT8 atan8( INT16 sXPos, INT16 sYPos, INT16 sXPos2, INT16 sYPos2 );
950 INT8 CalcActionPoints(const SOLDIERTYPE*);
951 INT16 GetDirectionToGridNoFromGridNo( INT16 sGridNoDest, INT16 sGridNoSrc );
952 void ReleaseSoldiersAttacker( SOLDIERTYPE *pSoldier );
953 BOOLEAN MercInWater(const SOLDIERTYPE* pSoldier);
954 UINT16 GetMoveStateBasedOnStance(const SOLDIERTYPE*, UINT8 ubStanceHeight);
955 void SoldierGotoStationaryStance( SOLDIERTYPE *pSoldier );
956 void ReCreateSoldierLight(SOLDIERTYPE*);
957 
958 
959 void    MakeCharacterDialogueEventDoBattleSound(SOLDIERTYPE& s, BattleSound, UINT32 delay);
960 BOOLEAN DoMercBattleSound(SOLDIERTYPE*, BattleSound);
961 BOOLEAN InternalDoMercBattleSound(SOLDIERTYPE*, BattleSound, INT8 bSpecialCode);
962 
963 
964 UINT32 SoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, INT16 sKitPts, INT16 sStatus );
965 void ReceivingSoldierCancelServices( SOLDIERTYPE *pSoldier );
966 void GivingSoldierCancelServices( SOLDIERTYPE *pSoldier );
967 void InternalGivingSoldierCancelServices( SOLDIERTYPE *pSoldier, BOOLEAN fPlayEndAnim );
968 
969 
970 // WRAPPERS FOR SOLDIER EVENTS
971 void SendGetNewSoldierPathEvent(SOLDIERTYPE*, UINT16 sDestGridNo);
972 void SendSoldierSetDesiredDirectionEvent(const SOLDIERTYPE* pSoldier, UINT16 usDesiredDirection);
973 void SendBeginFireWeaponEvent( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo );
974 
975 void HaultSoldierFromSighting( SOLDIERTYPE *pSoldier, BOOLEAN fFromSightingEnemy );
976 void ReLoadSoldierAnimationDueToHandItemChange( SOLDIERTYPE *pSoldier, UINT16 usOldItem, UINT16 usNewItem );
977 
978 bool CheckForBreathCollapse(SOLDIERTYPE&);
979 
IsOnCivTeam(const SOLDIERTYPE * const s)980 static inline BOOLEAN IsOnCivTeam(const SOLDIERTYPE* const s)
981 {
982 	return s->bTeam == CIV_TEAM;
983 }
984 
985 #define PTR_CROUCHED					(gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH)
986 #define PTR_STANDING					(gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_STAND)
987 #define PTR_PRONE					(gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_PRONE)
988 
989 
990 void EVENT_SoldierBeginGiveItem( SOLDIERTYPE *pSoldier );
991 
992 void DoNinjaAttack( SOLDIERTYPE *pSoldier );
993 
994 BOOLEAN InternalSoldierReadyWeapon( SOLDIERTYPE *pSoldier, UINT8 sFacingDir, BOOLEAN fEndReady );
995 
996 void RemoveSoldierFromGridNo(SOLDIERTYPE&);
997 
998 void PositionSoldierLight( SOLDIERTYPE *pSoldier );
999 
1000 void EVENT_InternalSetSoldierDestination( SOLDIERTYPE *pSoldier, UINT16	usNewDirection, BOOLEAN fFromMove, UINT16 usAnimState );
1001 
1002 void ChangeToFallbackAnimation( SOLDIERTYPE *pSoldier, INT8 bDirection );
1003 
1004 void EVENT_SoldierBeginKnifeThrowAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
1005 void EVENT_SoldierBeginUseDetonator( SOLDIERTYPE *pSoldier );
1006 void EVENT_SoldierBeginDropBomb( SOLDIERTYPE *pSoldier );
1007 void EVENT_SoldierEnterVehicle(SOLDIERTYPE&, GridNo);
1008 
1009 
1010 void SetSoldierCowerState( SOLDIERTYPE *pSoldier, BOOLEAN fOn );
1011 
1012 BOOLEAN PlayerSoldierStartTalking( SOLDIERTYPE *pSoldier, UINT8 ubTargetID, BOOLEAN fValidate );
1013 
1014 void CalcNewActionPoints( SOLDIERTYPE *pSoldier );
1015 
1016 BOOLEAN InternalIsValidStance(const SOLDIERTYPE* pSoldier, INT8 bDirection, INT8 bNewStance);
1017 
1018 void AdjustNoAPToFinishMove( SOLDIERTYPE *pSoldier, BOOLEAN fSet );
1019 
1020 
1021 void UpdateRobotControllerGivenController( SOLDIERTYPE *pSoldier );
1022 void UpdateRobotControllerGivenRobot( SOLDIERTYPE *pSoldier );
1023 const SOLDIERTYPE *GetRobotController( const SOLDIERTYPE *pSoldier );
1024 BOOLEAN CanRobotBeControlled(const SOLDIERTYPE* pSoldier);
1025 BOOLEAN ControllingRobot(const SOLDIERTYPE* s);
1026 
1027 void EVENT_SoldierBeginReloadRobot( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection, UINT8 ubMercSlot );
1028 
1029 void EVENT_SoldierBeginTakeBlood( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
1030 
1031 void EVENT_SoldierBeginAttachCan( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDirection );
1032 
1033 void PickDropItemAnimation( SOLDIERTYPE *pSoldier );
1034 
1035 bool IsValidSecondHandShot(SOLDIERTYPE const*);
1036 bool IsValidSecondHandShotForReloadingPurposes(SOLDIERTYPE const*);
1037 
1038 void CrowsFlyAway( UINT8 ubTeam );
1039 
1040 void DebugValidateSoldierData(void);
1041 
1042 void BeginTyingToFall( SOLDIERTYPE *pSoldier );
1043 
1044 void SetSoldierAsUnderAiControl( SOLDIERTYPE *pSoldier );
1045 void HandlePlayerTogglingLightEffects( BOOLEAN fToggleValue );
1046 
1047 void HandleSystemNewAISituation(SOLDIERTYPE*);
1048 void SetSoldierAniSpeed(SOLDIERTYPE* pSoldier);
1049 void PlaySoldierFootstepSound(SOLDIERTYPE* pSoldier);
1050 void PlayStealthySoldierFootstepSound(SOLDIERTYPE* pSoldier);
1051 
1052 // DO NOT CALL UNLESS THROUGH EVENT_SetSoldierPosition
1053 UINT16 PickSoldierReadyAnimation(SOLDIERTYPE* pSoldier, BOOLEAN fEndReady);
1054 
1055 extern BOOLEAN gfGetNewPathThroughPeople;
1056 
1057 void FlashSoldierPortrait(SOLDIERTYPE*);
1058 
IsWearingHeadGear(SOLDIERTYPE const & s,UINT16 const item)1059 static inline bool IsWearingHeadGear(SOLDIERTYPE const& s, UINT16 const item)
1060 {
1061 	return s.inv[HEAD1POS].usItem == item || s.inv[HEAD2POS].usItem == item;
1062 }
1063 
1064 #endif
1065