1 #include "Game_Init.h"
2 #include "Arms_Dealer_Init.h"
3 #include "BloodCatPlacementsModel.h"
4 #include "BloodCatSpawnsModel.h"
5 #include "BobbyR.h"
6 #include "Campaign_Init.h"
7 #include "Campaign_Types.h"
8 #include "Cheats.h"
9 #include "ContentManager.h"
10 #include "ContentMusic.h"
11 #include "Creature_Spreading.h"
12 #include "Dialogue_Control.h"
13 #include "EMail.h"
14 #include "Finances.h"
15 #include "Game_Clock.h"
16 #include "Game_Event_Hook.h"
17 #include "GameInstance.h"
18 #include "GameLoop.h"
19 #include "GamePolicy.h"
20 #include "GameSettings.h"
21 #include "HelpScreen.h"
22 #include "Interface.h"
23 #include "Interface_Dialogue.h"
24 #include "Laptop.h"
25 #include "Logger.h"
26 #include "Map_Screen_Helicopter.h"
27 #include "Map_Screen_Interface.h"
28 #include "Map_Screen_Interface_Border.h"
29 #include "Map_Screen_Interface_Map.h"
30 #include "MapScreen.h"
31 #include "Meanwhile.h"
32 #include "Merc_Entering.h"
33 #include "Message.h"
34 #include "Music_Control.h"
35 #include "NPC.h"
36 #include "NpcPlacementModel.h"
37 #include "OppList.h"
38 #include "Overhead.h"
39 #include "Overhead_Types.h"
40 #include "PreBattle_Interface.h"
41 #include "Queen_Command.h"
42 #include "Quests.h"
43 #include "Random.h"
44 #include "SAM_Sites.h"
45 #include "ScreenIDs.h"
46 #include "ShopKeeper_Interface.h"
47 #include "Soldier_Control.h"
48 #include "Soldier_Create.h"
49 #include "Soldier_Profile.h"
50 #include "Soldier_Profile_Type.h"
51 #include "SoundMan.h"
52 #include "Squads.h"
53 #include "Strategic_AI.h"
54 #include "Strategic_Mines.h"
55 #include "Strategic_Movement.h"
56 #include "Strategic_Town_Loyalty.h"
57 #include "StrategicMap.h"
58 #include "StrategicMap_Secrets.h"
59 #include "Tactical_Save.h"
60 #include "Timer_Control.h"
61 #include "Vehicles.h"
62 #include "WorldDef.h"
63 #include <stdexcept>
64 #include <string_theory/format>
65
66 void InitScriptingEngine();
67
68 UINT8 gubScreenCount=0;
69
70
InitNPCs()71 static void InitNPCs()
72 {
73 for (auto p : GCM->listNpcPlacements())
74 {
75 const NpcPlacementModel* placement = p.second;
76 if (placement->isSciFiOnly && !gGameOptions.fSciFi)
77 {
78 continue;
79 }
80
81 UINT8 sector = placement->pickPlacementSector();
82 if (placement->useAlternateMap)
83 {
84 SectorInfo[sector].uiFlags |= SF_USE_ALTERNATE_MAP;
85 STLOGD("Alternate map in {}", SECTOR_SHORT_STRING(sector));
86 }
87 if (placement->isPlacedAtStart)
88 {
89 MERCPROFILESTRUCT& merc = GetProfile(placement->profileId);
90 merc.sSectorX = SECTORX(sector);
91 merc.sSectorY = SECTORY(sector);
92 merc.bSectorZ = 0;
93 STLOGD("{} in {}", merc.zNickname, SECTOR_SHORT_STRING(sector));
94 }
95 }
96
97 gfPlayerTeamSawJoey = FALSE;
98
99 if (!gGameOptions.fSciFi)
100 { //not scifi, so use alternate map in Tixa's b1 level that doesn't have the stairs going down to the caves.
101 UNDERGROUND_SECTORINFO *pSector;
102 pSector = FindUnderGroundSector( TIXA_SECTOR_X, TIXA_SECTOR_Y, 1 ); //j9_b1
103 if( pSector )
104 {
105 pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
106 }
107 }
108
109 // init hospital variables
110 giHospitalTempBalance = 0;
111 giHospitalRefund = 0;
112 gbHospitalPriceModifier = 0;
113
114 // set up Devin so he will be placed ASAP
115 gMercProfiles[ DEVIN ].bNPCData = 3;
116 }
117
InitBloodCatSectors()118 void InitBloodCatSectors()
119 {
120 INT32 i;
121 for( i = 0; i < 255; i++ )
122 {
123 SectorInfo[ i ].bBloodCats = -1;
124 };
125 for (auto placements : GCM->getBloodCatPlacements())
126 {
127 UINT8 sectorId = placements->sectorId;
128 SectorInfo[ sectorId ].bBloodCatPlacements = placements->bloodCatPlacements;
129 }
130 for (auto spawns : GCM->getBloodCatSpawns())
131 {
132 UINT8 sectorId = spawns->sectorId;
133 INT8 spawnsCount = spawns->getSpawnsByDifficulty(gGameOptions.ubDifficultyLevel);
134 SectorInfo[ sectorId ].bBloodCatPlacements = spawnsCount;
135 SectorInfo[ sectorId ].bBloodCats = spawnsCount;
136 }
137 }
138
139
InitStrategicLayer(void)140 void InitStrategicLayer( void )
141 {
142 // Clear starategic layer!
143 SetupNewStrategicGame();
144 InitQuestEngine();
145
146 //Setup a new campaign via the enemy perspective.
147 InitNewCampaign();
148 // Init Squad Lists
149 InitSquads();
150 // Init vehicles
151 InitVehicles( );
152 // init town loyalty
153 InitTownLoyalty();
154 // init the mine management system
155 InitializeMines();
156 // initialize map screen flags
157 InitMapScreenFlags();
158 // initialize NPCs, select alternate maps, etc
159 InitNPCs();
160 // init Skyrider and his helicopter
161 InitializeHelicopter();
162 //Clear out the vehicle list
163 ClearOutVehicleList();
164
165 InitBloodCatSectors();
166
167 InitializeSAMSites();
168
169 // make Orta, Tixa, SAM sites not found
170 InitMapSecrets();
171
172
173 // free up any leave list arrays that were left allocated
174 ShutDownLeaveList( );
175 // re-set up leave list arrays for dismissed mercs
176 InitLeaveList( );
177
178 // reset time compression mode to X0 (this will also pause it)
179 SetGameTimeCompressionLevel( TIME_COMPRESS_X0 );
180
181 // Select the start sector as the initial selected sector
182 ChangeSelectedMapSector(SECTORX(START_SECTOR), SECTORY(START_SECTOR), 0);
183
184 // Reset these flags or mapscreen could be disabled and cause major headache.
185 fDisableDueToBattleRoster = FALSE;
186 fDisableMapInterfaceDueToBattle = FALSE;
187 }
188
ShutdownStrategicLayer()189 void ShutdownStrategicLayer()
190 {
191 DeleteAllStrategicEvents();
192 RemoveAllGroups();
193 TrashUndergroundSectorInfo();
194 DeleteCreatureDirectives();
195 KillStrategicAI();
196 }
197
198
InitNewGame()199 void InitNewGame()
200 {
201 uiMeanWhileFlags = 0;
202 SetSelectedMan(0);
203
204 RESET_CHEAT_LEVEL();
205
206 if (gubScreenCount == 0)
207 {
208 LoadMercProfiles();
209 InitAllArmsDealers();
210 InitBobbyRayInventory();
211 }
212
213 ClearTacticalMessageQueue();
214 FreeGlobalMessageList(); // Clear mapscreen messages
215
216 InitScriptingEngine();
217
218 if (gubScreenCount == 0)
219 { // Our first time, go into laptop
220 InitLaptopAndLaptopScreens();
221 InitStrategicLayer();
222 SetLaptopNewGameFlag();
223
224 // This is for the "mercs climbing down from a rope" animation, NOT Skyrider
225 ResetHeliSeats();
226
227 UINT32 const now = GetWorldTotalMin();
228 AddPreReadEmail(OLD_ENRICO_1, OLD_ENRICO_1_LENGTH, MAIL_ENRICO, now);
229 AddPreReadEmail(OLD_ENRICO_2, OLD_ENRICO_2_LENGTH, MAIL_ENRICO, now);
230 AddPreReadEmail(RIS_REPORT, RIS_REPORT_LENGTH, RIS_EMAIL, now);
231 AddPreReadEmail(OLD_ENRICO_3, OLD_ENRICO_3_LENGTH, MAIL_ENRICO, now);
232 AddEmail(IMP_EMAIL_INTRO, IMP_EMAIL_INTRO_LENGTH, CHAR_PROFILE_SITE, now);
233
234 // ATE: Set starting cash
235 INT32 starting_cash;
236 switch (gGameOptions.ubDifficultyLevel)
237 {
238 case DIF_LEVEL_EASY: starting_cash = gamepolicy(starting_cash_easy); break;
239 case DIF_LEVEL_MEDIUM: starting_cash = gamepolicy(starting_cash_medium); break;
240 case DIF_LEVEL_HARD: starting_cash = gamepolicy(starting_cash_hard); break;
241 default: throw std::logic_error("invalid difficulty level");
242 }
243 AddTransactionToPlayersBook(ANONYMOUS_DEPOSIT, 0, now, starting_cash);
244
245 // random day between min and max days, inclusive
246 UINT8 ubMin = gamepolicy(merc_online_min_days);
247 UINT8 ubMax = gamepolicy(merc_online_max_days);
248 UINT32 const days_time_merc_site_available = Random(ubMax - ubMin + 1) + ubMin;
249 if (days_time_merc_site_available == 0)
250 {
251 // M.E.R.C. is already online
252 AddEmail(MERC_INTRO, MERC_INTRO_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin());
253 }
254 else
255 {
256 // Schedule email for message from Speck at 7am on a random day in the future
257 AddFutureDayStrategicEvent(EVENT_DAY3_ADD_EMAIL_FROM_SPECK, 60 * 7, 0, days_time_merc_site_available);
258 }
259
260 SetLaptopExitScreen(INIT_SCREEN);
261 SetPendingNewScreen(LAPTOP_SCREEN);
262 gubScreenCount = 1;
263
264 // Set the fact the game is in progress
265 gTacticalStatus.fHasAGameBeenStarted = TRUE;
266 }
267 else if (gubScreenCount == 1)
268 {
269 gubScreenCount = 2;
270 }
271 }
272
273
AnyMercsHired()274 BOOLEAN AnyMercsHired( )
275 {
276 CFOR_EACH_IN_TEAM(s, OUR_TEAM)
277 {
278 return TRUE;
279 }
280 return FALSE;
281 }
282
283
284 //This function is called when the game is REstarted. Things that need to be reinited are placed in here
ReStartingGame()285 void ReStartingGame()
286 {
287 //Pause the game
288 gfGamePaused = TRUE;
289
290 //Reset the sectors
291 SetWorldSectorInvalid();
292
293 SetMusicMode(MUSIC_NONE);
294 SoundStopAll();
295
296 //we are going to restart a game so initialize the variable so we can initialize a new game
297 gubScreenCount = 0;
298
299 InitTacticalSave();
300
301 //Loop through all the soldier and delete them all
302 FOR_EACH_SOLDIER(i) TacticalRemoveSoldier(*i);
303
304 // Re-init overhead...
305 InitOverhead( );
306
307 //Reset the email list
308 ShutDownEmailList();
309
310 //Reinit the laptopn screen variables
311 InitLaptopAndLaptopScreens();
312 LaptopScreenInit();
313
314 //Reload the Merc profiles
315 LoadMercProfiles( );
316
317 // Reload quote files
318 ReloadAllQuoteFiles();
319
320 //Initialize the ShopKeeper Interface ( arms dealer inventory, etc. )
321 ShopKeeperScreenInit();
322
323 //Delete the world info
324 TrashWorld();
325
326 //Init the help screen system
327 InitHelpScreenSystem();
328
329 EmptyDialogueQueue( );
330
331
332 //Make sure the game starts in the TEAM panel ( it wasnt being reset )
333 gsCurInterfacePanel = TEAM_PANEL;
334
335 //Delete all the strategic events
336 DeleteAllStrategicEvents();
337
338 //Delete creature lair, if any
339 DeleteCreatureDirectives();
340
341 //This function gets called when ur in a game a click the quit to main menu button, therefore no game is in progress
342 gTacticalStatus.fHasAGameBeenStarted = FALSE;
343
344 // Reset timer callbacks
345 gpCustomizableTimerCallback = NULL;
346
347 RESET_CHEAT_LEVEL();
348 }
349