1 #include <vector>
2 
3 #include "Debug.h"
4 #include "FileMan.h"
5 #include "GameState.h"
6 #include "LoadSaveData.h"
7 #include "LoadSaveTacticalStatusType.h"
8 #include "Overhead.h"
9 
10 
ExtractTacticalStatusTypeFromFile(HWFILE const f,bool stracLinuxFormat)11 void ExtractTacticalStatusTypeFromFile(HWFILE const f, bool stracLinuxFormat)
12 {
13 	UINT32 dataSize = stracLinuxFormat ? TACTICAL_STATUS_TYPE_SIZE_STRAC_LINUX : TACTICAL_STATUS_TYPE_SIZE;
14 	std::vector<BYTE> data(dataSize);
15 	FileRead(f, data.data(), dataSize);
16 
17 	TacticalStatusType* const s = &gTacticalStatus;
18 	DataReader d{data.data()};
19 	EXTR_U32(d, s->uiFlags)
20 	FOR_EACH(TacticalTeamType, t, s->Team)
21 	{
22 		EXTR_U8(d, t->bFirstID)
23 		EXTR_U8(d, t->bLastID)
24 		EXTR_SKIP(d, 2)
25 		EXTR_U32(d, t->RadarColor)
26 		EXTR_I8(d, t->bSide)
27 		EXTR_I8(d, t->bMenInSector)
28 		EXTR_SOLDIER(d, t->last_merc_to_radio)
29 		EXTR_SKIP(d, 1)
30 		EXTR_I8(d, t->bAwareOfOpposition)
31 		EXTR_I8(d, t->bHuman)
32 		EXTR_SKIP(d, 2)
33 	}
34 	EXTR_U8(d, s->ubCurrentTeam)
35 	EXTR_SKIP(d, 1)
36 	EXTR_I16(d, s->sSlideTarget)
37 	EXTR_SKIP(d, 4)
38 	EXTR_U32(d, s->uiTimeSinceMercAIStart)
39 	EXTR_I8(d, s->fPanicFlags)
40 	EXTR_SKIP(d, 5)
41 	EXTR_U8(d, s->ubSpottersCalledForBy)
42 	EXTR_SOLDIER(d, s->the_chosen_one)
43 	EXTR_U32(d, s->uiTimeOfLastInput)
44 	EXTR_U32(d, s->uiTimeSinceDemoOn)
45 	EXTR_SKIP(d, 7)
46 	EXTR_BOOLA(d, s->fCivGroupHostile, lengthof(s->fCivGroupHostile))
47 	EXTR_U8(d, s->ubLastBattleSectorX)
48 	EXTR_U8(d, s->ubLastBattleSectorY)
49 	EXTR_BOOL(d, s->fLastBattleWon)
50 	EXTR_SKIP(d, 2)
51 	EXTR_BOOL(d, s->fVirginSector)
52 	EXTR_BOOL(d, s->fEnemyInSector)
53 	EXTR_BOOL(d, s->fInterruptOccurred)
54 	EXTR_I8(d, s->bRealtimeSpeed)
55 	EXTR_SKIP(d, 2)
56 	EXTR_SOLDIER(d, s->enemy_sighting_on_their_turn_enemy)
57 	EXTR_SKIP(d, 1)
58 	EXTR_BOOL(d, s->fEnemySightingOnTheirTurn)
59 	EXTR_BOOL(d, s->fAutoBandageMode)
60 	EXTR_U8(d, s->ubAttackBusyCount)
61 	EXTR_SKIP(d, 1)
62 	EXTR_U8(d, s->ubEngagedInConvFromActionMercID)
63 	EXTR_SKIP(d, 1)
64 	EXTR_U16(d, s->usTactialTurnLimitCounter)
65 	EXTR_BOOL(d, s->fInTopMessage)
66 	EXTR_U8(d, s->ubTopMessageType)
67 	if(stracLinuxFormat)
68 	{
69 		EXTR_SKIP(d, 82);
70 	}
71 	else
72 	{
73 		EXTR_SKIP(d, 40);
74 	}
75 	EXTR_U16(d, s->usTactialTurnLimitMax)
76 	if(stracLinuxFormat)
77 	{
78 		EXTR_SKIP(d, 2);
79 	}
80 	EXTR_U32(d, s->uiTactialTurnLimitClock)
81 	EXTR_BOOL(d, s->fTactialTurnLimitStartedBeep)
82 	EXTR_I8(d, s->bBoxingState)
83 	EXTR_I8(d, s->bConsNumTurnsNotSeen)
84 	EXTR_U8(d, s->ubArmyGuysKilled)
85 	EXTR_I16A(d, s->sPanicTriggerGridNo, lengthof(s->sPanicTriggerGridNo))
86 	EXTR_I8A(d, s->bPanicTriggerIsAlarm, lengthof(s->bPanicTriggerIsAlarm))
87 	EXTR_U8A(d, s->ubPanicTolerance, lengthof(s->ubPanicTolerance))
88 	EXTR_BOOL(d, s->fAtLeastOneGuyOnMultiSelect)
89 	EXTR_SKIP(d, 2)
90 	EXTR_BOOL(d, s->fKilledEnemyOnAttack)
91 	EXTR_SOLDIER(d, s->enemy_killed_on_attack)
92 	EXTR_I8(d, s->bEnemyKilledOnAttackLevel)
93 	EXTR_U16(d, s->ubEnemyKilledOnAttackLocation)
94 	EXTR_BOOL(d, s->fItemsSeenOnAttack)
95 	EXTR_SOLDIER(d, s->items_seen_on_attack_soldier)
96 	EXTR_SKIP(d, 2)
97 	EXTR_U16(d, s->usItemsSeenOnAttackGridNo)
98 	EXTR_BOOL(d, s->fLockItemLocators)
99 	EXTR_U8(d, s->ubLastQuoteSaid)
100 	EXTR_U8(d, s->ubLastQuoteProfileNUm)
101 	EXTR_BOOL(d, s->fCantGetThrough)
102 	EXTR_I16(d, s->sCantGetThroughGridNo)
103 	EXTR_I16(d, s->sCantGetThroughSoldierGridNo)
104 	EXTR_SOLDIER(d, s->cant_get_through)
105 	EXTR_BOOL(d, s->fDidGameJustStart)
106 	EXTR_SKIP(d, 1)
107 	EXTR_U8(d, s->ubLastRequesterTargetID)
108 	EXTR_SKIP(d, 1)
109 	EXTR_U8(d, s->ubNumCrowsPossible)
110 	EXTR_SKIP(d, 4)
111 	EXTR_BOOL(d, s->fUnLockUIAfterHiddenInterrupt)
112 	EXTR_I8A(d, s->bNumFoughtInBattle, lengthof(s->bNumFoughtInBattle))
113 	EXTR_SKIP(d, 1)
114 	EXTR_U32(d, s->uiDecayBloodLastUpdate)
115 	EXTR_U32(d, s->uiTimeSinceLastInTactical)
116 	EXTR_BOOL(d, s->fHasAGameBeenStarted)
117 	EXTR_I8(d, s->bConsNumTurnsWeHaventSeenButEnemyDoes)
118 	EXTR_BOOL(d, s->fSomeoneHit)
119 	EXTR_SKIP(d, 1)
120 	EXTR_U32(d, s->uiTimeSinceLastOpplistDecay)
121 	EXTR_I8(d, s->bMercArrivingQuoteBeingUsed)
122 	EXTR_SOLDIER(d, s->enemy_killed_on_attack_killer)
123 	EXTR_BOOL(d, s->fCountingDownForGuideDescription)
124 	EXTR_I8(d, s->bGuideDescriptionCountDown)
125 	EXTR_U8(d, s->ubGuideDescriptionToUse)
126 	EXTR_I8(d, s->bGuideDescriptionSectorX)
127 	EXTR_I8(d, s->bGuideDescriptionSectorY)
128 	EXTR_I8(d, s->fEnemyFlags)
129 	EXTR_BOOL(d, s->fAutoBandagePending)
130 	EXTR_BOOL(d, s->fHasEnteredCombatModeSinceEntering)
131 	EXTR_BOOL(d, s->fDontAddNewCrows)
132 	EXTR_SKIP(d, 1)
133 	EXTR_U16(d, s->sCreatureTenseQuoteDelay)
134 	EXTR_SKIP(d, 2)
135 	EXTR_U32(d, s->uiCreatureTenseQuoteLastUpdate)
136 	Assert(d.getConsumed() == dataSize);
137 
138 	if (!GameState::getInstance()->debugging())
139 	{
140 		// Prevent restoring of debug UI modes
141 		s->uiFlags &= ~(DEBUGCLIFFS | SHOW_Z_BUFFER);
142 	}
143 }
144 
145 
InjectTacticalStatusTypeIntoFile(HWFILE const f)146 void InjectTacticalStatusTypeIntoFile(HWFILE const f)
147 {
148 	BYTE data[316];
149 	DataWriter d{data};
150 	TacticalStatusType* const s = &gTacticalStatus;
151 	INJ_U32(d, s->uiFlags)
152 	FOR_EACH(TacticalTeamType const, t, s->Team)
153 	{
154 		INJ_U8(d, t->bFirstID)
155 		INJ_U8(d, t->bLastID)
156 		INJ_SKIP(d, 2)
157 		INJ_U32(d, t->RadarColor)
158 		INJ_I8(d, t->bSide)
159 		INJ_I8(d, t->bMenInSector)
160 		INJ_SOLDIER(d, t->last_merc_to_radio)
161 		INJ_SKIP(d, 1)
162 		INJ_I8(d, t->bAwareOfOpposition)
163 		INJ_I8(d, t->bHuman)
164 		INJ_SKIP(d, 2)
165 	}
166 	INJ_U8(d, s->ubCurrentTeam)
167 	INJ_SKIP(d, 1)
168 	INJ_I16(d, s->sSlideTarget)
169 	INJ_SKIP(d, 4)
170 	INJ_U32(d, s->uiTimeSinceMercAIStart)
171 	INJ_I8(d, s->fPanicFlags)
172 	INJ_SKIP(d, 5)
173 	INJ_U8(d, s->ubSpottersCalledForBy)
174 	INJ_SOLDIER(d, s->the_chosen_one)
175 	INJ_U32(d, s->uiTimeOfLastInput)
176 	INJ_U32(d, s->uiTimeSinceDemoOn)
177 	INJ_SKIP(d, 7)
178 	INJ_BOOLA(d, s->fCivGroupHostile, lengthof(s->fCivGroupHostile))
179 	INJ_U8(d, s->ubLastBattleSectorX)
180 	INJ_U8(d, s->ubLastBattleSectorY)
181 	INJ_BOOL(d, s->fLastBattleWon)
182 	INJ_SKIP(d, 2)
183 	INJ_BOOL(d, s->fVirginSector)
184 	INJ_BOOL(d, s->fEnemyInSector)
185 	INJ_BOOL(d, s->fInterruptOccurred)
186 	INJ_I8(d, s->bRealtimeSpeed)
187 	INJ_SKIP(d, 2)
188 	INJ_SOLDIER(d, s->enemy_sighting_on_their_turn_enemy)
189 	INJ_SKIP(d, 1)
190 	INJ_BOOL(d, s->fEnemySightingOnTheirTurn)
191 	INJ_BOOL(d, s->fAutoBandageMode)
192 	INJ_U8(d, s->ubAttackBusyCount)
193 	INJ_SKIP(d, 1)
194 	INJ_U8(d, s->ubEngagedInConvFromActionMercID)
195 	INJ_SKIP(d, 1)
196 	INJ_U16(d, s->usTactialTurnLimitCounter)
197 	INJ_BOOL(d, s->fInTopMessage)
198 	INJ_U8(d, s->ubTopMessageType)
199 	INJ_SKIP(d, 40)
200 	INJ_U16(d, s->usTactialTurnLimitMax)
201 	INJ_U32(d, s->uiTactialTurnLimitClock)
202 	INJ_BOOL(d, s->fTactialTurnLimitStartedBeep)
203 	INJ_I8(d, s->bBoxingState)
204 	INJ_I8(d, s->bConsNumTurnsNotSeen)
205 	INJ_U8(d, s->ubArmyGuysKilled)
206 	INJ_I16A(d, s->sPanicTriggerGridNo, lengthof(s->sPanicTriggerGridNo))
207 	INJ_I8A(d, s->bPanicTriggerIsAlarm, lengthof(s->bPanicTriggerIsAlarm))
208 	INJ_U8A(d, s->ubPanicTolerance, lengthof(s->ubPanicTolerance))
209 	INJ_BOOL(d, s->fAtLeastOneGuyOnMultiSelect)
210 	INJ_SKIP(d, 2)
211 	INJ_BOOL(d, s->fKilledEnemyOnAttack)
212 	INJ_SOLDIER(d, s->enemy_killed_on_attack)
213 	INJ_I8(d, s->bEnemyKilledOnAttackLevel)
214 	INJ_U16(d, s->ubEnemyKilledOnAttackLocation)
215 	INJ_BOOL(d, s->fItemsSeenOnAttack)
216 	INJ_SOLDIER(d, s->items_seen_on_attack_soldier)
217 	INJ_SKIP(d, 2)
218 	INJ_U16(d, s->usItemsSeenOnAttackGridNo)
219 	INJ_BOOL(d, s->fLockItemLocators)
220 	INJ_U8(d, s->ubLastQuoteSaid)
221 	INJ_U8(d, s->ubLastQuoteProfileNUm)
222 	INJ_BOOL(d, s->fCantGetThrough)
223 	INJ_I16(d, s->sCantGetThroughGridNo)
224 	INJ_I16(d, s->sCantGetThroughSoldierGridNo)
225 	INJ_SOLDIER(d, s->cant_get_through)
226 	INJ_BOOL(d, s->fDidGameJustStart)
227 	INJ_SKIP(d, 1)
228 	INJ_U8(d, s->ubLastRequesterTargetID)
229 	INJ_SKIP(d, 1)
230 	INJ_U8(d, s->ubNumCrowsPossible)
231 	INJ_SKIP(d, 4)
232 	INJ_BOOL(d, s->fUnLockUIAfterHiddenInterrupt)
233 	INJ_I8A(d, s->bNumFoughtInBattle, lengthof(s->bNumFoughtInBattle))
234 	INJ_SKIP(d, 1)
235 	INJ_U32(d, s->uiDecayBloodLastUpdate)
236 	INJ_U32(d, s->uiTimeSinceLastInTactical)
237 	INJ_BOOL(d, s->fHasAGameBeenStarted)
238 	INJ_I8(d, s->bConsNumTurnsWeHaventSeenButEnemyDoes)
239 	INJ_BOOL(d, s->fSomeoneHit)
240 	INJ_SKIP(d, 1)
241 	INJ_U32(d, s->uiTimeSinceLastOpplistDecay)
242 	INJ_I8(d, s->bMercArrivingQuoteBeingUsed)
243 	INJ_SOLDIER(d, s->enemy_killed_on_attack_killer)
244 	INJ_BOOL(d, s->fCountingDownForGuideDescription)
245 	INJ_I8(d, s->bGuideDescriptionCountDown)
246 	INJ_U8(d, s->ubGuideDescriptionToUse)
247 	INJ_I8(d, s->bGuideDescriptionSectorX)
248 	INJ_I8(d, s->bGuideDescriptionSectorY)
249 	INJ_I8(d, s->fEnemyFlags)
250 	INJ_BOOL(d, s->fAutoBandagePending)
251 	INJ_BOOL(d, s->fHasEnteredCombatModeSinceEntering)
252 	INJ_BOOL(d, s->fDontAddNewCrows)
253 	INJ_SKIP(d, 1)
254 	INJ_U16(d, s->sCreatureTenseQuoteDelay)
255 	INJ_SKIP(d, 2)
256 	INJ_U32(d, s->uiCreatureTenseQuoteLastUpdate)
257 	Assert(d.getConsumed() == lengthof(data));
258 
259 	FileWrite(f, data, sizeof(data));
260 }
261