1 #include "Local.h"
2 #include "GameLoop.h"
3 #include "VSurface.h"
4 #include "WorldDef.h"
5 #include "Input.h"
6 #include "Font.h"
7 #include "Screens.h"
8 #include "Overhead.h"
9 #include "SysUtil.h"
10 #include "Event_Pump.h"
11 #include "Font_Control.h"
12 #include "Debug_Pages.h"
13 #include "Timer_Control.h"
14 #include "Radar_Screen.h"
15 #include "Render_Dirty.h"
16 #include "Interface.h"
17 #include "Handle_UI.h"
18 #include "Cursors.h"
19 #include "VObject_Blitters.h"
20 #include "Button_System.h"
21 #include "RenderWorld.h"
22 #include "Sys_Globals.h"
23 #include "Environment.h"
24 #include "Bullets.h"
25 #include "Assignments.h"
26 #include "Message.h"
27 #include "Overhead_Map.h"
28 #include "Strategic_Exit_GUI.h"
29 #include "Strategic_Movement.h"
30 #include "Tactical_Placement_GUI.h"
31 #include "Game_Clock.h"
32 #include "Game_Init.h"
33 #include "Interface_Control.h"
34 #include "Physics.h"
35 #include "Fade_Screen.h"
36 #include "Dialogue_Control.h"
37 #include "Soldier_Macros.h"
38 #include "Faces.h"
39 #include "StrategicMap.h"
40 #include "GameScreen.h"
41 #include "Cursor_Control.h"
42 #include "Strategic_Turns.h"
43 #include "Merc_Entering.h"
44 #include "Soldier_Create.h"
45 #include "Soldier_Init_List.h"
46 #include "Interface_Panels.h"
47 #include "Map_Information.h"
48 #include "Squads.h"
49 #include "Interface_Dialogue.h"
50 #include "Auto_Bandage.h"
51 #include "Meanwhile.h"
52 #include "Strategic_AI.h"
53 #include "HelpScreen.h"
54 #include "PreBattle_Interface.h"
55 #include "Sound_Control.h"
56 #include "Text.h"
57 #include "Debug.h"
58 #include "Video.h"
59 #include "JAScreens.h"
60 #include "UILayout.h"
61 #include "GameState.h"
62 #include "EditScreen.h"
63 #include "Logger.h"
64
65 #define ARE_IN_FADE_IN( ) ( gfFadeIn || gfFadeInitialized )
66
67 BOOLEAN gfTacticalDoHeliRun = FALSE;
68
69
70 // VIDEO OVERLAYS
71 VIDEO_OVERLAY* g_fps_overlay = NULL;
72 VIDEO_OVERLAY* g_counter_period_overlay = NULL;
73
74
75 BOOLEAN gfGameScreenLocateToSoldier = FALSE;
76 BOOLEAN gfEnteringMapScreen = FALSE;
77 SOLDIERTYPE* gPreferredInitialSelectedGuy = NULL;
78
79 static BOOLEAN gfTacticalIsModal = FALSE;
80 static MOUSE_REGION gTacticalDisableRegion;
81 static BOOLEAN gfTacticalDisableRegionActive = FALSE;
82 MODAL_HOOK gModalDoneCallback;
83 BOOLEAN gfBeginEndTurn = FALSE;
84 extern BOOLEAN gfFirstHeliRun;
85 extern BOOLEAN gfRenderFullThisFrame;
86
87
88 // The InitializeGame function is responsible for setting up all data and Gaming Engine
89 // tasks which will run the game
90 static RENDER_HOOK gRenderOverride = 0;
91
92
93 static ScreenID guiTacticalLeaveScreenID = ERROR_SCREEN; // XXX TODO001A had no explicit initialisation
94 static BOOLEAN guiTacticalLeaveScreen = FALSE;
95
96
BlitMFont(VIDEO_OVERLAY * const ovr)97 static void BlitMFont(VIDEO_OVERLAY* const ovr)
98 {
99 SetFontAttributes(ovr->uiFontID, ovr->ubFontFore, DEFAULT_SHADOW, ovr->ubFontBack);
100 SGPVSurface::Lock l(ovr->uiDestBuff);
101 MPrintBuffer(l.Buffer<UINT16>(), l.Pitch(), ovr->sX, ovr->sY, ovr->codepoints);
102 }
103
104
MainGameScreenInit(void)105 void MainGameScreenInit(void)
106 {
107 // all blit functions expect z-buffer pitch to match framebuffer pitch
108 gZBufferPitch = FRAME_BUFFER->surface_->pitch / FRAME_BUFFER->surface_->format->BytesPerPixel;
109 gpZBuffer = InitZBuffer(gZBufferPitch, SCREEN_HEIGHT);
110 gZBufferPitch *= sizeof(*gpZBuffer);
111 InitializeBackgroundRects();
112
113 //EnvSetTimeInHours(ENV_TIME_12);
114
115 SetRenderFlags(RENDER_FLAG_FULL);
116
117 // Init Video Overlays
118 // FIRST, FRAMERATE
119 g_fps_overlay = RegisterVideoOverlay(
120 BlitMFont,
121 DEBUG_PAGE_SCREEN_OFFSET_X,
122 DEBUG_PAGE_SCREEN_OFFSET_Y,
123 DEBUG_PAGE_FONT,
124 DEBUG_PAGE_TEXT_COLOR,
125 0,
126 L"90"
127 );
128 EnableVideoOverlay(false, g_fps_overlay);
129
130 // SECOND, PERIOD COUNTER
131 g_counter_period_overlay = RegisterVideoOverlay(
132 BlitMFont,
133 DEBUG_PAGE_SCREEN_OFFSET_X,
134 DEBUG_PAGE_SCREEN_OFFSET_Y+DEBUG_PAGE_LINE_HEIGHT,
135 DEBUG_PAGE_FONT,
136 DEBUG_PAGE_TEXT_COLOR,
137 0,
138 L"Levelnodes: 100000"
139 );
140 EnableVideoOverlay(false, g_counter_period_overlay);
141 }
142
143
144 // The ShutdownGame function will free up/undo all things that were started in InitializeGame()
145 // It will also be responsible to making sure that all Gaming Engine tasks exit properly
MainGameScreenShutdown(void)146 void MainGameScreenShutdown(void)
147 {
148 ShutdownZBuffer(gpZBuffer);
149 RemoveVideoOverlay(g_fps_overlay);
150 RemoveVideoOverlay(g_counter_period_overlay);
151 ShutdownBackgroundRects();
152 }
153
154
FadeInGameScreen()155 void FadeInGameScreen( )
156 {
157 fFirstTimeInGameScreen = TRUE;
158
159 FadeInNextFrame( );
160 }
161
FadeOutGameScreen()162 void FadeOutGameScreen( )
163 {
164 FadeOutNextFrame( );
165 }
166
167
EnterTacticalScreen(void)168 void EnterTacticalScreen(void)
169 {
170 guiTacticalLeaveScreen = FALSE;
171
172 SetPositionSndsActive( );
173
174 // Set pending screen
175 SetPendingNewScreen( GAME_SCREEN );
176
177 // Set as active...
178 gTacticalStatus.uiFlags |= ACTIVE;
179
180 fInterfacePanelDirty = DIRTYLEVEL2;
181
182 //Disable all faces
183 SetAllAutoFacesInactive( );
184
185 // CHECK IF OURGUY IS NOW OFF DUTY
186 const SOLDIERTYPE* sel = GetSelectedMan();
187 if (sel != NULL)
188 {
189 if (!OK_CONTROLLABLE_MERC(sel))
190 {
191 SelectNextAvailSoldier(sel);
192 sel = GetSelectedMan();
193 }
194 // ATE: If the current guy is sleeping, change....
195 if (sel != NULL && sel->fMercAsleep) SelectNextAvailSoldier(sel);
196 }
197 else
198 {
199 // otherwise, make sure interface is team panel...
200 SetCurrentInterfacePanel(TEAM_PANEL);
201 }
202
203 if (!gfTacticalPlacementGUIActive) gRadarRegion.Enable();
204 gViewportRegion.Enable();
205
206 // set default squad on sector entry
207 // ATE: moved these 2 call after initalizing the interface!
208 //SetDefaultSquadOnSectorEntry( FALSE );
209 //ExamineCurrentSquadLights( );
210
211 // Init interface ( ALWAYS TO TEAM PANEL. DEF changed it to go back to the previous panel )
212 if( !gfTacticalPlacementGUIActive )
213 {
214 //make sure the gsCurInterfacePanel is valid
215 if( gsCurInterfacePanel < 0 || gsCurInterfacePanel >= NUM_UI_PANELS )
216 gsCurInterfacePanel = TEAM_PANEL;
217
218 SetCurrentInterfacePanel(gsCurInterfacePanel);
219 }
220
221 // set default squad on sector entry
222 SetDefaultSquadOnSectorEntry( FALSE );
223 ExamineCurrentSquadLights( );
224
225
226
227 fFirstTimeInGameScreen = FALSE;
228
229 // Make sure it gets re-created....
230 DirtyTopMessage( );
231
232 // Set compression to normal!
233 //SetGameTimeCompressionLevel( TIME_COMPRESS_X1 );
234
235 // Select current guy...
236 //gfGameScreenLocateToSoldier = TRUE;
237
238 // Locate if in meanwhile...
239 if ( AreInMeanwhile( ) )
240 {
241 LocateToMeanwhileCharacter( );
242 }
243
244 if ( gTacticalStatus.uiFlags & IN_DEIDRANNA_ENDGAME )
245 {
246 InternalLocateGridNo( 4561, TRUE );
247 }
248
249 // Clear tactical message q
250 ClearTacticalMessageQueue( );
251
252 // ATE: Enable messages again...
253 EnableScrollMessages( );
254 }
255
256
LeaveTacticalScreen(ScreenID const uiNewScreen)257 void LeaveTacticalScreen(ScreenID const uiNewScreen)
258 {
259 guiTacticalLeaveScreenID = uiNewScreen;
260 guiTacticalLeaveScreen = TRUE;
261 }
262
263
InternalLeaveTacticalScreen(ScreenID const uiNewScreen)264 void InternalLeaveTacticalScreen(ScreenID const uiNewScreen)
265 {
266 gpCustomizableTimerCallback = NULL;
267
268 // unload the sector they teleported out of
269 if ( !gfAutomaticallyStartAutoResolve )
270 {
271 CheckAndHandleUnloadingOfCurrentWorld();
272 }
273
274 SetPositionSndsInActive( );
275
276 // Turn off active flag
277 gTacticalStatus.uiFlags &= ( ~ACTIVE );
278
279 fFirstTimeInGameScreen = TRUE;
280
281 SetPendingNewScreen( uiNewScreen );
282
283 //Disable all faces
284 SetAllAutoFacesInactive( );
285
286 ResetInterfaceAndUI( );
287
288 // Remove cursor and reset height....
289 gsGlobalCursorYOffset = 0;
290 SetCurrentCursorFromDatabase( VIDEO_NO_CURSOR );
291
292 // Shutdown panel
293 ShutdownCurrentPanel( );
294
295 //disable the radar map
296 gRadarRegion.Disable();
297 //gViewportRegion.Disable();
298
299 // We are leaving... turn off pedning autobadage...
300 SetAutoBandagePending( FALSE );
301
302 // ATE: Disable messages....
303 DisableScrollMessages( );
304
305
306 if ( uiNewScreen == MAINMENU_SCREEN )
307 {
308 //We want to reinitialize the game
309 ReStartingGame();
310 }
311
312 if ( uiNewScreen != MAP_SCREEN )
313 {
314 StopAnyCurrentlyTalkingSpeech( );
315 }
316
317 // If we have some disabled screens up.....remove...
318 CheckForDisabledRegionRemove( );
319
320 // ATE: Record last time we were in tactical....
321 gTacticalStatus.uiTimeSinceLastInTactical = GetWorldTotalMin( );
322
323 FinishAnySkullPanelAnimations( );
324 }
325
326
327 static void HandleModalTactical(void);
328 static void TacticalScreenLocateToSoldier(void);
329
330
MainGameScreenHandle(void)331 ScreenID MainGameScreenHandle(void)
332 {
333 //DO NOT MOVE THIS FUNCTION CALL!!!
334 //This determines if the help screen should be active
335 // if( ( !gfTacticalDoHeliRun && !gfFirstHeliRun ) && ShouldTheHelpScreenComeUp( HELP_SCREEN_TACTICAL, FALSE ) )
336 if( !gfPreBattleInterfaceActive && ShouldTheHelpScreenComeUp( HELP_SCREEN_TACTICAL, FALSE ) )
337 {
338 // handle the help screen
339 HelpScreenHandler();
340 return( GAME_SCREEN );
341 }
342
343
344 if ( HandleAutoBandage( ) )
345 {
346 #ifndef VISIBLE_AUTO_BANDAGE
347 return( GAME_SCREEN );
348 #endif
349 }
350
351 if ( gfBeginEndTurn )
352 {
353 UIHandleEndTurn( NULL );
354 gfBeginEndTurn = FALSE;
355 }
356
357 if ( gfTacticalIsModal )
358 {
359 if ( gfTacticalIsModal == 1 )
360 {
361 gfTacticalIsModal++;
362 }
363 else
364 {
365 HandleModalTactical( );
366
367 return( GAME_SCREEN );
368 }
369 }
370
371 // OK, this is the pause system for when we see a guy...
372 if ( !ARE_IN_FADE_IN( ) )
373 {
374 if ( gTacticalStatus.fEnemySightingOnTheirTurn )
375 {
376 if ( ( GetJA2Clock( ) - gTacticalStatus.uiTimeSinceDemoOn ) > 3000 )
377 {
378 SOLDIERTYPE* const s = gTacticalStatus.enemy_sighting_on_their_turn_enemy;
379 if ( gTacticalStatus.ubCurrentTeam != OUR_TEAM )
380 {
381 AdjustNoAPToFinishMove(s, FALSE);
382 }
383 s->fPauseAllAnimation = FALSE;
384
385 gTacticalStatus.fEnemySightingOnTheirTurn = FALSE;
386 }
387 }
388 }
389
390 // see if the helicopter is coming in this time for the initial entrance by the mercs
391 InitHelicopterEntranceByMercs( );
392
393 // Handle Environment controller here
394 EnvironmentController( TRUE );
395
396 if ( !ARE_IN_FADE_IN( ) )
397 {
398 HandleWaitTimerForNPCTrigger( );
399
400 // Check timer that could have been set to do anything
401 CheckCustomizableTimer();
402
403 // HAndle physics engine
404 SimulateWorld( );
405
406 // Handle strategic engine
407 HandleStrategicTurn( );
408 }
409
410 if ( gfTacticalDoHeliRun )
411 {
412 gfGameScreenLocateToSoldier = FALSE;
413 InternalLocateGridNo( gMapInformation.sNorthGridNo, TRUE );
414
415 // Start heli Run...
416 StartHelicopterRun( gMapInformation.sNorthGridNo );
417
418 // Update clock by one so that our DidGameJustStatrt() returns now false for things like LAPTOP, etc...
419 SetGameTimeCompressionLevel( TIME_COMPRESS_X1 );
420 //UpdateClock( 1 );
421
422 gfTacticalDoHeliRun = FALSE;
423 //SetMusicMode( MUSIC_TACTICAL_NOTHING );
424 }
425
426
427 if ( InOverheadMap( ) )
428 {
429 HandleOverheadMap( );
430 return( GAME_SCREEN );
431 }
432
433 if ( gfGameScreenLocateToSoldier )
434 {
435 TacticalScreenLocateToSoldier( );
436 gfGameScreenLocateToSoldier = FALSE;
437 }
438
439 if ( fFirstTimeInGameScreen )
440 {
441 EnterTacticalScreen( );
442
443 // Select a guy if he hasn;'
444 if( !gfTacticalPlacementGUIActive )
445 {
446 SOLDIERTYPE* const sel = GetSelectedMan();
447 if (sel != NULL && OK_INTERRUPT_MERC(sel))
448 {
449 SelectSoldier(sel, SELSOLDIER_FORCE_RESELECT);
450 }
451 }
452 }
453
454 if ( HandleFadeOutCallback( ) )
455 {
456 return( GAME_SCREEN );
457 }
458
459 if ( guiCurrentScreen != MSG_BOX_SCREEN )
460 {
461 if ( HandleBeginFadeOut( GAME_SCREEN ) )
462 {
463 return( GAME_SCREEN );
464 }
465 }
466
467
468 HandleHeliDrop( );
469
470 if ( !ARE_IN_FADE_IN( ) )
471 {
472 HandleAutoBandagePending( );
473 }
474
475
476 // ATE: CHRIS_C LOOK HERE FOR GETTING AI CONSTANTLY GOING
477 // if ( !(gTacticalStatus.uiFlags & ENEMYS_TURN) )
478 // {
479 // EndTurn( );
480 // }
481
482
483 if (!ARE_IN_FADE_IN())
484 {
485 UpdateBullets();
486
487 // Execute Tactical Overhead
488 ExecuteOverhead();
489 }
490
491 // Handle animated cursors
492 if (gfWorldLoaded)
493 {
494 HandleAnimatedCursors();
495
496 // Handle Interface
497 ScreenID const uiNewScreen = HandleTacticalUI();
498
499 HandleTalkingAutoFaces();
500
501 if (uiNewScreen != GAME_SCREEN) return uiNewScreen;
502 }
503 else if (gfIntendOnEnteringEditor && GameState::getInstance()->isEditorMode())
504 {
505 SLOGI("Aborting normal game mode and entering editor mode...");
506 SetPendingNewScreen(NO_PENDING_SCREEN);
507 return EDIT_SCREEN;
508 }
509 else if (!gfEnteringMapScreen)
510 {
511 gfEnteringMapScreen = TRUE;
512 }
513
514 // Deque all game events
515 if (!ARE_IN_FADE_IN())
516 {
517 DequeAllGameEvents();
518 }
519
520
521 HandleTopMessages( );
522
523 if (!gfScrollPending && !g_scroll_inertia)
524 {
525 // Handle Interface Stuff
526 SetUpInterface( );
527 HandleTacticalPanelSwitch( );
528 }
529
530 // Handle Scroll Of World
531 ScrollWorld( );
532
533 //SetRenderFlags( RENDER_FLAG_FULL );
534
535 RenderWorld( );
536
537 if ( gRenderOverride != NULL )
538 {
539 gRenderOverride( );
540 }
541
542 if (gfScrollPending || g_scroll_inertia)
543 {
544 RenderTacticalInterfaceWhileScrolling( );
545 }
546 else
547 {
548 // Handle Interface Stuff
549 //RenderTacticalInterface( );
550 }
551
552 // Render Interface
553 RenderTopmostTacticalInterface( );
554
555 // Render view window
556 RenderRadarScreen( );
557
558 ResetInterface( );
559
560 if ( gfScrollPending )
561 {
562 AllocateVideoOverlaysArea( );
563 SaveVideoOverlaysArea( FRAME_BUFFER );
564 ExecuteVideoOverlays( );
565 }
566 else
567 {
568 ExecuteVideoOverlays( );
569 }
570
571 // Adding/deleting of video overlays needs to be done below
572 // ExecuteVideoOverlays( )....
573
574 // Handle dialogue queue system
575 if ( !ARE_IN_FADE_IN( ) )
576 {
577 HandleDialogue( );
578 }
579
580 //Don't render if we have a scroll pending!
581 if (!gfScrollPending && !g_scroll_inertia && !gfRenderFullThisFrame)
582 {
583 RenderButtonsFastHelp( );
584 }
585
586 // Display Framerate
587 DisplayFrameRate( );
588
589 CheckForMeanwhileOKStart( );
590
591 ScrollString( );
592
593 ExecuteBaseDirtyRectQueue( );
594
595 //KillBackgroundRects( );
596
597 /////////////////////////////////////////////////////
598 EndFrameBufferRender( );
599
600
601 if ( HandleFadeInCallback( ) )
602 {
603 // Re-render the scene!
604 SetRenderFlags( RENDER_FLAG_FULL );
605 fInterfacePanelDirty = DIRTYLEVEL2;
606 }
607
608 if ( HandleBeginFadeIn( GAME_SCREEN ) )
609 {
610 guiTacticalLeaveScreenID = FADE_SCREEN;
611 }
612
613 if ( guiTacticalLeaveScreen )
614 {
615 guiTacticalLeaveScreen = FALSE;
616
617 InternalLeaveTacticalScreen( guiTacticalLeaveScreenID );
618 }
619
620 // Check if we are to enter map screen
621 if ( gfEnteringMapScreen == 2 )
622 {
623 gfEnteringMapScreen = FALSE;
624 LeaveTacticalScreen(MAP_SCREEN);
625 }
626
627
628 // Are we entering map screen? if so, wait a frame!
629 if ( gfEnteringMapScreen > 0 )
630 {
631 gfEnteringMapScreen++;
632 }
633
634 return( GAME_SCREEN );
635
636 }
637
638
SetRenderHook(RENDER_HOOK pRenderOverride)639 void SetRenderHook( RENDER_HOOK pRenderOverride )
640 {
641 gRenderOverride = pRenderOverride;
642 }
643
644
EnableFPSOverlay(BOOLEAN fEnable)645 void EnableFPSOverlay(BOOLEAN fEnable)
646 {
647 EnableVideoOverlay(fEnable, g_fps_overlay);
648 EnableVideoOverlay(fEnable, g_counter_period_overlay);
649 }
650
651
TacticalScreenLocateToSoldier(void)652 static void TacticalScreenLocateToSoldier(void)
653 {
654 SOLDIERTYPE* const prefer = gPreferredInitialSelectedGuy;
655 if (prefer != NULL)
656 {
657 gPreferredInitialSelectedGuy = NULL;
658 if (OK_CONTROLLABLE_MERC(prefer) && OK_INTERRUPT_MERC(prefer))
659 {
660 LocateSoldier(prefer, 10);
661 SelectSoldier(prefer, SELSOLDIER_FORCE_RESELECT);
662 return;
663 }
664 }
665
666 // Set locator to first merc
667 FOR_EACH_IN_TEAM(s, OUR_TEAM)
668 {
669 if (OkControllableMerc(s) && OK_INTERRUPT_MERC(s))
670 {
671 LocateSoldier(s, 10);
672 SelectSoldier(s, SELSOLDIER_FORCE_RESELECT);
673 break;
674 }
675 }
676 }
677
678
UpdateTeamPanelAssignments()679 void UpdateTeamPanelAssignments( )
680 {
681 // Remove all players
682 RemoveAllPlayersFromSlot( );
683
684 FOR_EACH_IN_TEAM(s, OUR_TEAM)
685 {
686 // Setup team interface
687 CheckForAndAddMercToTeamPanel(s);
688 }
689 }
690
691
EnterModalTactical(INT8 bMode)692 void EnterModalTactical( INT8 bMode )
693 {
694 gfTacticalIsModal = TRUE;
695
696 if (bMode == TACTICAL_MODAL_NOMOUSE)
697 {
698 if ( !gfTacticalDisableRegionActive )
699 {
700 gfTacticalDisableRegionActive = TRUE;
701
702 MSYS_DefineRegion(&gTacticalDisableRegion, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_HIGH, VIDEO_NO_CURSOR, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK);
703 }
704 }
705
706 UpdateSaveBuffer();
707
708 }
709
EndModalTactical()710 void EndModalTactical( )
711 {
712 if ( gfTacticalDisableRegionActive )
713 {
714 MSYS_RemoveRegion( &gTacticalDisableRegion );
715
716 gfTacticalDisableRegionActive = FALSE;
717 }
718
719
720 if ( gModalDoneCallback != NULL )
721 {
722 gModalDoneCallback( );
723
724 gModalDoneCallback = NULL;
725 }
726
727 gfTacticalIsModal = FALSE;
728
729 SetRenderFlags( RENDER_FLAG_FULL );
730 }
731
732
HandleModalTactical(void)733 static void HandleModalTactical(void)
734 {
735 RestoreBackgroundRects();
736
737 RenderWorld( );
738 RenderRadarScreen( );
739 ExecuteVideoOverlays( );
740
741 // Handle dialogue queue system
742 HandleDialogue( );
743
744 HandleTalkingAutoFaces( );
745
746 // Handle faces
747 HandleAutoFaces( );
748
749 if ( gfInSectorExitMenu )
750 {
751 RenderSectorExitMenu( );
752 }
753 RenderButtons();
754
755 SaveBackgroundRects( );
756 RenderButtonsFastHelp( );
757 RenderPausedGameBox( );
758
759 ExecuteBaseDirtyRectQueue( );
760 EndFrameBufferRender( );
761
762 }
763
764
InitHelicopterEntranceByMercs(void)765 void InitHelicopterEntranceByMercs( void )
766 {
767 if( DidGameJustStart() )
768 {
769 // Update clock ahead from STARTING_TIME to make mercs arrive!
770 WarpGameTime( FIRST_ARRIVAL_DELAY, WARPTIME_PROCESS_EVENTS_NORMALLY );
771
772 gfTacticalDoHeliRun = TRUE;
773 gfFirstHeliRun = TRUE;
774
775 gTacticalStatus.fDidGameJustStart = FALSE;
776 }
777 }
778