1 #ifndef _ROTTING_CORPSES_H
2 #define _ROTTING_CORPSES_H
3 
4 #include "Debug.h"
5 #include "Overhead_Types.h"
6 #include "Tile_Animation.h"
7 
8 #include <string_theory/string>
9 
10 
11 #define NUM_CORPSE_SHADES				17
12 
13 enum RottingCorpseDefines
14 {
15 	NO_CORPSE,
16 	SMERC_JFK,
17 	SMERC_BCK,
18 	SMERC_FWD,
19 	SMERC_DHD,
20 	SMERC_PRN,
21 	SMERC_WTR,
22 	SMERC_FALL,
23 	SMERC_FALLF,
24 
25 	MMERC_JFK,
26 	MMERC_BCK,
27 	MMERC_FWD,
28 	MMERC_DHD,
29 	MMERC_PRN,
30 	MMERC_WTR,
31 	MMERC_FALL,
32 	MMERC_FALLF,
33 
34 	FMERC_JFK,
35 	FMERC_BCK,
36 	FMERC_FWD,
37 	FMERC_DHD,
38 	FMERC_PRN,
39 	FMERC_WTR,
40 	FMERC_FALL,
41 	FMERC_FALLF,
42 
43 	// CIVS
44 	M_DEAD1,
45 	K_DEAD1,
46 	H_DEAD1,
47 	FT_DEAD1,
48 	S_DEAD1,
49 	W_DEAD1,
50 	C_DEAD1,
51 	M_DEAD2,
52 	K_DEAD2,
53 	H_DEAD2,
54 
55 	FT_DEAD2,
56 	S_DEAD2,
57 	W_DEAD2,
58 	C_DEAD2,
59 	BLOODCAT_DEAD,
60 	COW_DEAD,
61 	ADULTMONSTER_DEAD,
62 	INFANTMONSTER_DEAD,
63 	LARVAEMONSTER_DEAD,
64 	ROTTING_STAGE2,
65 
66 	TANK1_DEAD,
67 	TANK2_DEAD,
68 	HUMMER_DEAD,
69 	ICECREAM_DEAD,
70 	QUEEN_MONSTER_DEAD,
71 	ROBOT_DEAD,
72 	BURNT_DEAD,
73 	EXPLODE_DEAD,
74 
75 	NUM_CORPSES
76 };
77 
78 
79 #define ROTTING_CORPSE_FIND_SWEETSPOT_FROM_GRIDNO	0x01 //Find the closest spot to the given gridno
80 #define ROTTING_CORPSE_USE_NORTH_ENTRY_POINT		0x02 //Find the spot closest to the north entry grid
81 #define ROTTING_CORPSE_USE_SOUTH_ENTRY_POINT		0x04 //Find the spot closest to the south entry grid
82 #define ROTTING_CORPSE_USE_EAST_ENTRY_POINT		0x08 //Find the spot closest to the east entry grid
83 #define ROTTING_CORPSE_USE_WEST_ENTRY_POINT		0x10 //Find the spot closest to the west entry grid
84 #define ROTTING_CORPSE_USE_CAMO_PALETTE		0x20 //We use camo palette here....
85 #define ROTTING_CORPSE_VEHICLE				0x40 //Vehicle Corpse
86 
87 struct ROTTING_CORPSE_DEFINITION
88 {
89 	UINT8   ubType;
90 	UINT8   ubBodyType;
91 	INT16   sGridNo;
92 	INT16   sHeightAdjustment;
93 
94 	ST::string HeadPal; // Palette reps
95 	ST::string PantsPal;
96 	ST::string VestPal;
97 	ST::string SkinPal;
98 
99 	INT8    bDirection;
100 	UINT32  uiTimeOfDeath;
101 
102 	UINT16  usFlags;
103 
104 	INT8    bLevel;
105 
106 	INT8    bVisible;
107 	INT8    bNumServicingCrows;
108 	UINT8   ubProfile;
109 	BOOLEAN fHeadTaken;
110 	UINT8   ubAIWarningValue;
111 };
112 
113 
114 struct ROTTING_CORPSE
115 {
116 	ROTTING_CORPSE_DEFINITION def;
117 	BOOLEAN fActivated;
118 
119 	ANITILE *pAniTile;
120 
121 	UINT16  *pShades[ NUM_CORPSE_SHADES ];
122 };
123 
124 
125 ROTTING_CORPSE* AddRottingCorpse(ROTTING_CORPSE_DEFINITION* pCorpseDef);
126 
127 void RemoveCorpses(void);
128 
129 
130 BOOLEAN TurnSoldierIntoCorpse(SOLDIERTYPE&);
131 
132 INT16 FindNearestRottingCorpse( SOLDIERTYPE *pSoldier );
133 
134 INT16 FindNearestAvailableGridNoForCorpse( ROTTING_CORPSE_DEFINITION *pCorpseDef, INT8 ubRadius );
135 
136 
137 void HandleRottingCorpses(void);
138 
139 void VaporizeCorpse( INT16 sGridNo, UINT16 usStructureID );
140 void CorpseHit( INT16 sGridNo, UINT16 usStructureID );
141 
142 void HandleCrowLeave( SOLDIERTYPE *pSoldier );
143 
144 void HandleCrowFlyAway( SOLDIERTYPE *pSoldier );
145 
146 #define MAX_ROTTING_CORPSES				100
147 
148 extern ROTTING_CORPSE gRottingCorpse[ MAX_ROTTING_CORPSES ];
149 extern INT32 giNumRottingCorpse;
150 extern UINT8 gb4DirectionsFrom8[8];
151 
Corpse2ID(const ROTTING_CORPSE * const c)152 static inline UINT32 Corpse2ID(const ROTTING_CORPSE* const c)
153 {
154 	Assert(gRottingCorpse <= c && c < endof(gRottingCorpse));
155 	Assert(c->fActivated);
156 	return (UINT32)(c - gRottingCorpse);
157 }
158 
ID2Corpse(const UINT32 id)159 static inline ROTTING_CORPSE* ID2Corpse(const UINT32 id)
160 {
161 	Assert(id < lengthof(gRottingCorpse));
162 	ROTTING_CORPSE* const c = &gRottingCorpse[id];
163 	Assert(c->fActivated);
164 	return c;
165 }
166 
167 #define CORPSE2ID(c) (Corpse2ID((c)))
168 #define ID2CORPSE(i) (ID2Corpse((i)))
169 
170 #define BASE_FOR_EACH_ROTTING_CORPSE(type, iter)                      \
171 	for (type* iter = gRottingCorpse,                      \
172 		* const end__##iter = gRottingCorpse + giNumRottingCorpse; \
173 		iter != end__##iter;                                           \
174 		++iter)                                                        \
175 		if (!iter->fActivated) continue; else
176 #define  FOR_EACH_ROTTING_CORPSE(iter) BASE_FOR_EACH_ROTTING_CORPSE(      ROTTING_CORPSE, iter)
177 #define CFOR_EACH_ROTTING_CORPSE(iter) BASE_FOR_EACH_ROTTING_CORPSE(const ROTTING_CORPSE, iter)
178 
179 ROTTING_CORPSE *GetCorpseAtGridNo( INT16 sGridNo , INT8 bLevel );
180 BOOLEAN IsValidDecapitationCorpse(const ROTTING_CORPSE* c);
181 void DecapitateCorpse(INT16 sGridNo, INT8 bLevel);
182 
183 void GetBloodFromCorpse( SOLDIERTYPE *pSoldier );
184 
185 UINT16 GetCorpseStructIndex(const ROTTING_CORPSE_DEFINITION* pCorpseDef, BOOLEAN fForImage);
186 
187 void LookForAndMayCommentOnSeeingCorpse( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubLevel );
188 
189 INT16 GetGridNoOfCorpseGivenProfileID( UINT8 ubProfileID );
190 
191 void DecayRottingCorpseAIWarnings( void );
192 UINT8 GetNearestRottingCorpseAIWarning( INT16 sGridNo );
193 
194 void ReduceAmmoDroppedByNonPlayerSoldiers(SOLDIERTYPE const&, OBJECTTYPE& ammo);
195 
196 #endif
197