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