Files
source/Ja2/gamescreen.cpp
T
2024-11-30 17:06:11 +02:00

1222 lines
29 KiB
C++

#include "builddefines.h"
#include <stdio.h>
#include <time.h>
#include "sgp.h"
#include "gameloop.h"
#include "vobject.h"
#include "worlddef.h"
#include "renderworld.h"
#include "font.h"
#include "screenids.h"
#include "screens.h"
#include "overhead.h"
#include "Isometric Utils.h"
#include "sysutil.h"
#include "input.h"
#include "Event Pump.h"
#include "Font Control.h"
#include "Timer Control.h"
#include "Radar Screen.h"
#include "Render Dirty.h"
#include "Interface.h"
#include "Handle UI.h"
#include <wchar.h>
#include <tchar.h>
#include "cursors.h"
#include "vobject_blitters.h"
#include "Button System.h"
#include "lighting.h"
#include "renderworld.h"
#include "sys globals.h"
#include "environment.h"
#include "bullets.h"
#include "Assignments.h"
#include "message.h"
#include <string.h>
#include "overhead map.h"
#include "Strategic Exit GUI.h"
#include "strategic movement.h"
#include "Tactical Placement GUI.h"
#include "Air raid.h"
#include "Game Clock.h"
#include "game init.h"
//DEF: Test Code
#ifdef NETWORKED
#include "Networking.h"
#endif
#include "interface control.h"
#include "game clock.h"
#include "physics.h"
#include "fade screen.h"
#include "dialogue control.h"
#include "soldier macros.h"
#include "faces.h"
#include "strategicmap.h"
#include "gamescreen.h"
#include "interface.h"
#include "cursor control.h"
#include "strategic turns.h"
#include "merc entering.h"
#include "soldier create.h"
#include "Soldier Init List.h"
#include "interface panels.h"
#include "Map Information.h"
#include "environment.h"
#include "Squads.h"
#include "interface dialogue.h"
#include "auto bandage.h"
#include "meanwhile.h"
#include "strategic ai.h"
#include "HelpScreen.h"
#include "PreBattle Interface.h"
#include "Sound Control.h"
#include "MessageBoxScreen.h"
#include "Text.h"
#include "GameSettings.h"
#include "Random.h"
#include "editscreen.h"
#include "Scheduling.h"
#include "Animated ProgressBar.h"
#include "connect.h"
#ifdef JA2UB
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#include "ub_config.h"
#endif
#define ARE_IN_FADE_IN( ) ( gfFadeIn || gfFadeInitialized )
BOOLEAN fDirtyRectangleMode = FALSE;
UINT16 *gpFPSBuffer=NULL;
// MarkNote
// extern ScrollStringStPtr pStringS=NULL;
UINT32 counter=0;
UINT32 count=0;
BOOLEAN gfTacticalDoHeliRun = FALSE;
BOOLEAN gfPlayAttnAfterMapLoad = FALSE;
// VIDEO OVERLAYS
INT32 giFPSOverlay = 0;
INT32 giCounterPeriodOverlay = 0;
BOOLEAN gfExitToNewSector = FALSE;
//UINT8 gubNewSectorExitDirection;
BOOLEAN gfGameScreenLocateToSoldier = FALSE;
BOOLEAN gfEnteringMapScreen = FALSE;
UINT32 uiOldMouseCursor;
SoldierID gubPreferredInitialSelectedGuy = NOBODY;
BOOLEAN gfTacticalIsModal = FALSE;
MOUSE_REGION gTacticalDisableRegion;
BOOLEAN gfTacticalDisableRegionActive = FALSE;
INT8 gbTacticalDisableMode = FALSE;
MODAL_HOOK gModalDoneCallback;
BOOLEAN gfBeginEndTurn = FALSE;
extern BOOLEAN gfTopMessageDirty;
extern BOOLEAN gfFailedToSaveGameWhenInsideAMessageBox;
extern BOOLEAN gfFirstHeliRun;
extern BOOLEAN gfRenderFullThisFrame;
#ifdef JA2UB
extern void HandleCannotAffordNpcMsgBox();
extern BOOLEAN gfDisplayMsgBoxSayingCantAffordNPC;
#endif
// The InitializeGame function is responsible for setting up all data and Gaming Engine
// tasks which will run the game
RENDER_HOOK gRenderOverride = NULL;
#define NOINPUT_DELAY 60000
#define DEMOPLAY_DELAY 40000
#define RESTART_DELAY 6000
void TacticalScreenLocateToSoldier( );
UINT32 guiTacticalLeaveScreenID;
BOOLEAN guiTacticalLeaveScreen = FALSE;
void HandleModalTactical( );
extern void CheckForDisabledRegionRemove( );
extern void InternalLocateGridNo( INT32 sGridNo, BOOLEAN fForce );
UINT32 MainGameScreenInit(void)
{
VIDEO_OVERLAY_DESC VideoOverlayDesc;
UINT32 uiDestPitchBYTES;
UINT8 *pDestBuf=NULL;
/* If any 1 have time please calculate how big this buffer should be
* any questions? joker
*/
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
gpZBuffer=InitZBuffer( uiDestPitchBYTES, SCREEN_HEIGHT);
UnLockVideoSurface( FRAME_BUFFER);
InitializeBackgroundRects();
InitializeBaseDirtyRectQueue();
//EnvSetTimeInHours(ENV_TIME_12);
SetRenderFlags(RENDER_FLAG_FULL);
// WDS - bug fix: VideoOverlayDesc must be initialized! - 07/16/2007
memset( &VideoOverlayDesc, 0, sizeof( VIDEO_OVERLAY_DESC ) );
// Init Video Overlays
// FIRST, FRAMERATE
VideoOverlayDesc.sLeft = 0;
VideoOverlayDesc.sTop = 0;
VideoOverlayDesc.uiFontID = SMALLFONT1;
VideoOverlayDesc.ubFontBack = FONT_MCOLOR_BLACK ;
VideoOverlayDesc.ubFontFore = FONT_MCOLOR_DKGRAY ;
VideoOverlayDesc.sX = VideoOverlayDesc.sLeft;
VideoOverlayDesc.sY = VideoOverlayDesc.sTop;
swprintf( VideoOverlayDesc.pzText, L"90" );
VideoOverlayDesc.BltCallback = BlitMFont;
giFPSOverlay = RegisterVideoOverlay( ( VOVERLAY_STARTDISABLED | VOVERLAY_DIRTYBYTEXT ), &VideoOverlayDesc );
// SECOND, PERIOD COUNTER
VideoOverlayDesc.sLeft = 0;
VideoOverlayDesc.sTop = 12;
VideoOverlayDesc.sX = VideoOverlayDesc.sLeft;
VideoOverlayDesc.sY = VideoOverlayDesc.sTop;
swprintf( VideoOverlayDesc.pzText, L"Levelnodes: 100000" );
VideoOverlayDesc.BltCallback = BlitMFont;
giCounterPeriodOverlay = RegisterVideoOverlay( ( VOVERLAY_STARTDISABLED | VOVERLAY_DIRTYBYTEXT ), &VideoOverlayDesc );
// register debug topics
// RegisterJA2DebugTopic( TOPIC_JA2, "Reg JA2 Debug" );
return TRUE;
}
// The ShutdownGame function will free up/undo all things that were started in InitializeGame()
// It will also be responsible to making sure that all Gaming Engine tasks exit properly
UINT32 MainGameScreenShutdown(void)
{
ShutdownZBuffer(gpZBuffer);
ShutdownBackgroundRects();
// Remove video Overlays
RemoveVideoOverlay( giFPSOverlay );
// WANNE: Plug a vanilla one-time memory leak.
// Fixed by Tron (Stracciatella): Revision: 6933
RemoveVideoOverlay( giCounterPeriodOverlay );
return TRUE;
}
void FadeInGameScreen( )
{
fFirstTimeInGameScreen = TRUE;
FadeInNextFrame( );
}
void FadeOutGameScreen( )
{
FadeOutNextFrame( );
}
void EnterTacticalScreen( )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen"));
guiTacticalLeaveScreen = FALSE;
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: setpositionsndsactive"));
SetPositionSndsActive( );
// Set pending screen
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: setpendingnewscreen"));
SetPendingNewScreen( GAME_SCREEN );
// Set as active...
gTacticalStatus.uiFlags |= ACTIVE;
fInterfacePanelDirty = DIRTYLEVEL2;
//Disable all faces
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: setallautofacesinactive"));
SetAllAutoFacesInactive( );
// CHECK IF OURGUY IS NOW OFF DUTY
if ( gusSelectedSoldier != NOBODY )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: check our guy"));
if ( !OK_CONTROLLABLE_MERC( gusSelectedSoldier ) )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: SelectNextAvailSoldier, merc not controllable"));
SelectNextAvailSoldier( gusSelectedSoldier );
}
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: who is selected? %d", gusSelectedSoldier));
// ATE: If the current guy is sleeping, change....
if ( gusSelectedSoldier != NOBODY && gusSelectedSoldier->flags.fMercAsleep )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: SelectNextAvailSoldier, merc asleep"));
SelectNextAvailSoldier( gusSelectedSoldier );
}
}
else
{
// otherwise, make sure interface is team panel...
SetCurrentInterfacePanel( (UINT8)TEAM_PANEL );
}
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen:enable viewport region"));
if( !gfTacticalPlacementGUIActive )
{
MSYS_EnableRegion(&gRadarRegion);
}
MSYS_EnableRegion( &gViewportRegion );
// set default squad on sector entry
// ATE: moved these 2 call after initalizing the interface!
//SetDefaultSquadOnSectorEntry( FALSE );
//ExamineCurrentSquadLights( );
//UpdateMercsInSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: Init Interface"));
// Init interface ( ALWAYS TO TEAM PANEL. DEF changed it to go back to the previous panel )
if( !gfTacticalPlacementGUIActive )
{
//make sure the gsCurInterfacePanel is valid
if( gsCurInterfacePanel < 0 || gsCurInterfacePanel >= NUM_UI_PANELS )
gsCurInterfacePanel = TEAM_PANEL;
SetCurrentInterfacePanel( (UINT8)gsCurInterfacePanel );
}
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: settacticalinterfaceflags"));
SetTacticalInterfaceFlags( 0 );
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: fix oversized squads"));
//SQUAD10: Check for squads that are oversized at current resolution and move them to another squad
FixOversizedSquadsInSector( );
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: set default squad on sector entry"));
// set default squad on sector entry
SetDefaultSquadOnSectorEntry( FALSE );
ExamineCurrentSquadLights( );
fFirstTimeInGameScreen = FALSE;
// Make sure it gets re-created....
DirtyTopMessage( );
// Set compression to normal!
//SetGameTimeCompressionLevel( TIME_COMPRESS_X1 );
// Select current guy...
//gfGameScreenLocateToSoldier = TRUE;
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: check meanwhile"));
#ifdef JA2UB
/* Ja25 No meanwhiles */
#else
// Locate if in meanwhile...
if ( AreInMeanwhile( ) )
{
LocateToMeanwhileCharacter( );
}
#endif
if ( gTacticalStatus.uiFlags & IN_DEIDRANNA_ENDGAME )
{
InternalLocateGridNo( 4561, TRUE );
}
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: clear messages"));
// Clear tactical message q
ClearTacticalMessageQueue( );
// ATE: Enable messages again...
EnableScrollMessages( );
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EnterTacticalScreen: done"));
}
void LeaveTacticalScreen( UINT32 uiNewScreen )
{
guiTacticalLeaveScreenID = uiNewScreen;
guiTacticalLeaveScreen = TRUE;
}
void InternalLeaveTacticalScreen( UINT32 uiNewScreen )
{
gpCustomizableTimerCallback = NULL;
// unload the sector they teleported out of
if ( !gfAutomaticallyStartAutoResolve )
{
CheckAndHandleUnloadingOfCurrentWorld();
}
SetPositionSndsInActive( );
// Turn off active flag
gTacticalStatus.uiFlags &= ( ~ACTIVE );
fFirstTimeInGameScreen = TRUE;
SetPendingNewScreen( uiNewScreen );
//Disable all faces
SetAllAutoFacesInactive( );
ResetInterfaceAndUI( );
// Remove cursor and reset height....
gsGlobalCursorYOffset = 0;
SetCurrentCursorFromDatabase( VIDEO_NO_CURSOR );
// Shutdown panel
ShutdownCurrentPanel( );
//disable the radar map
MSYS_DisableRegion(&gRadarRegion);
//MSYS_DisableRegion( &gViewportRegion );
// We are leaving... turn off pedning autobadage...
SetAutoBandagePending( FALSE );
// ATE: Disable messages....
DisableScrollMessages( );
if ( uiNewScreen == MAINMENU_SCREEN )
{
//We want to reinitialize the game
ReStartingGame();
}
if ( uiNewScreen != MAP_SCREEN )
{
StopAnyCurrentlyTalkingSpeech( );
}
// If we have some disabled screens up.....remove...
CheckForDisabledRegionRemove( );
// ATE: Record last time we were in tactical....
gTacticalStatus.uiTimeSinceLastInTactical = GetWorldTotalMin( );
FinishAnySkullPanelAnimations( );
}
extern INT32 iInterfaceDialogueBox;
#ifdef JA2BETAVERSION
extern BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode );
extern BOOLEAN gfDoDialogOnceGameScreenFadesIn;
#endif
UINT32 MainGameScreenHandle(void)
{
UINT32 uiNewScreen = GAME_SCREEN;
//DO NOT MOVE THIS FUNCTION CALL!!!
//This determines if the help screen should be active
// if( ( !gfTacticalDoHeliRun && !gfFirstHeliRun ) && ShouldTheHelpScreenComeUp( HELP_SCREEN_TACTICAL, FALSE ) )
// WANNE: Never show the helpscreen when leaving editor and going to the tactical game
#ifndef JA2EDITOR
if( !gfPreBattleInterfaceActive && ShouldTheHelpScreenComeUp( HELP_SCREEN_TACTICAL, FALSE ) )
{
// handle the help screen
HelpScreenHandler();
return( GAME_SCREEN );
}
#endif
#ifdef JA2BETAVERSION
DebugValidateSoldierData( );
#endif
if ( HandleAutoBandage( ) )
{
#ifndef VISIBLE_AUTO_BANDAGE
return( GAME_SCREEN );
#endif
}
#ifdef JA2UB
//jA25 UB
//Handle the strategic AI
JA25_HandleUpdateOfStrategicAi();
#endif
#if 0
{
PTR pData, pDestBuf;
UINT32 uiPitch, uiDestPitchBYTES;
pData = LockMouseBuffer( &uiPitch );
pDestBuf = LockVideoSurface(guiRENDERBUFFER, &uiDestPitchBYTES);
Blt16BPPTo16BPP((UINT16 *)pDestBuf, uiDestPitchBYTES,
(UINT16 *)pData, uiPitch,
0 , 0,
0 , 0,
64, 64 );
UnlockMouseBuffer( );
UnLockVideoSurface(guiRENDERBUFFER);
InvalidateRegion( 0, 0, 64, 64 );
//mprintf( 0, 55, L"W: %dH: %d", gsCurMouseWidth, gsCurMouseHeight );
}
#endif
if ( gfBeginEndTurn )
{
UIHandleEndTurn( NULL );
gfBeginEndTurn = FALSE;
}
/*
if ( gfExitToNewSector )
{
// Shade screen one frame
if ( gfExitToNewSector == 1 )
{
// Disable any saved regions!
EmptyBackgroundRects( );
// Remove cursor
uiOldMouseCursor = gViewportRegion.Cursor;
SetCurrentCursorFromDatabase( VIDEO_NO_CURSOR );
//Shadow area
ShadowVideoSurfaceRect( FRAME_BUFFER, 0, 0, 640, 480 );
InvalidateScreen( );
// Next frame please
gfExitToNewSector++;
return( GAME_SCREEN );
}
else
{
// Go into sector
JumpIntoAdjacentSector( gubNewSectorExitDirection );
gfExitToNewSector = FALSE;
// Restore mouse
SetCurrentCursorFromDatabase( uiOldMouseCursor );
}
}
*/
// The gfFailedToSaveGameWhenInsideAMessageBox flag will only be set at this point if the game fails to save during
// a quick save and when the game was already in a message box.
//If the game failed to save when in a message box, pop up a message box stating an error occured
if( gfFailedToSaveGameWhenInsideAMessageBox )
{
gfFailedToSaveGameWhenInsideAMessageBox = FALSE;
DoMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_SAVE_GAME_ERROR], GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL );
return( GAME_SCREEN );
}
// Check if we are in bar animation...
if ( InTopMessageBarAnimation( ) )
{
ExecuteBaseDirtyRectQueue( );
EndFrameBufferRender( );
return( GAME_SCREEN );
}
if ( gfTacticalIsModal )
{
if ( gfTacticalIsModal == 1 )
{
gfTacticalIsModal++;
}
else
{
HandleModalTactical( );
return( GAME_SCREEN );
}
}
// OK, this is the pause system for when we see a guy...
if ( !ARE_IN_FADE_IN( ) )
{
if ( gTacticalStatus.fEnemySightingOnTheirTurn )
{
if ( (( GetJA2Clock( ) - gTacticalStatus.uiTimeSinceDemoOn ) > 3000) || is_client)//unpause straight away if in MP
{
if ( gTacticalStatus.ubCurrentTeam != gbPlayerNum )
{
gTacticalStatus.ubEnemySightingOnTheirTurnEnemyID->AdjustNoAPToFinishMove( FALSE );
}
gTacticalStatus.ubEnemySightingOnTheirTurnEnemyID->flags.fPauseAllAnimation = FALSE;
gTacticalStatus.fEnemySightingOnTheirTurn = FALSE;
}
}
}
// see if the helicopter is coming in this time for the initial entrance by the mercs
InitHelicopterEntranceByMercs( );
// Handle Environment controller here
EnvironmentController( TRUE );
if ( !ARE_IN_FADE_IN( ) )
{
HandleWaitTimerForNPCTrigger( );
// Check timer that could have been set to do anything
CheckCustomizableTimer();
// Handle physics engine
SimulateWorld( );
// Handle strategic engine
HandleStrategicTurn( );
}
if ( gfTacticalDoHeliRun )
{
gfGameScreenLocateToSoldier = FALSE;
#ifdef JA2UB
//if it is the first time in the game, and we are doing the heli crash code, locate to a different spot
if( gfFirstTimeInGameHeliCrash && gGameUBOptions.InGameHeli == FALSE )
{
InternalLocateGridNo( gGameUBOptions.LOCATEGRIDNO, TRUE ); // 15427
}
else
{
if ( gGameUBOptions.InGameHeliCrash == TRUE )
//InternalLocateGridNo( gMapInformation.sNorthGridNo, TRUE );
InternalLocateGridNo( gGameUBOptions.LOCATEGRIDNO, TRUE );
else
InternalLocateGridNo( gGameUBOptions.LOCATEGRIDNO, TRUE );
}
#else
if (gfFirstHeliRun)
{
InternalLocateGridNo( gGameExternalOptions.iInitialMercArrivalLocation, TRUE );
}
else
{
InternalLocateGridNo(gMapInformation.sCenterGridNo, TRUE);
}
#endif
// Flugente: we might have reloaded the game, so we are currently not dropping mercs out of a helicopter
gfIngagedInDrop = FALSE;
// Start heli Run...
StartHelicopterRun();
// Update clock by one so that our DidGameJustStatrt() returns now false for things like LAPTOP, etc...
SetGameTimeCompressionLevel( TIME_COMPRESS_X1 );
//UpdateClock( 1 );
gfTacticalDoHeliRun = FALSE;
//SetMusicMode( MUSIC_TACTICAL_NOTHING );
}
if ( InOverheadMap( ) )
{
HandleOverheadMap( );
return( GAME_SCREEN );
}
#ifdef JA2UB
if ( !ARE_IN_FADE_IN( ) )
{
// HandleAirRaid( );
HandlePowerGenAlarm();
}
#endif
if ( gfGameScreenLocateToSoldier )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("maingamescreenhandle: tacticalscreenlocatetosoldier"));
TacticalScreenLocateToSoldier( );
gfGameScreenLocateToSoldier = FALSE;
}
if ( fFirstTimeInGameScreen )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("maingamescreenhandle: entertacticalscreen"));
EnterTacticalScreen( );
ShowLoadScreenHintInTacticalLog();
// Select a guy if he hasn;'
if( !gfTacticalPlacementGUIActive )
{
if ( gusSelectedSoldier != NOBODY && OK_INTERRUPT_MERC( gusSelectedSoldier ) )
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("maingamescreenhandle: selectsoldier"));
SelectSoldier( gusSelectedSoldier, FALSE, TRUE );
}
}
}
// ATE: check that this flag is not set.... display message if so
if ( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN )
{
// Unset
guiTacticalInterfaceFlags &= (~INTERFACE_MAPSCREEN );
#ifdef JA2BETAVERSION
ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"MAPSCREEN_INTERFACE flag set: Please remember how you entered Tactical." );
#endif
}
if ( HandleFadeOutCallback( ) )
{
return( GAME_SCREEN );
}
if ( guiCurrentScreen != MSG_BOX_SCREEN && guiCurrentScreen != MP_CHAT_SCREEN )
{
if ( HandleBeginFadeOut( GAME_SCREEN ) )
{
return( GAME_SCREEN );
}
}
#ifdef JA2UB
//if we are to display a mesg box about cant afford biggens
if( gfDisplayMsgBoxSayingCantAffordNPC )
{
HandleCannotAffordNpcMsgBox();
}
#endif
#ifdef JA2BETAVERSION
if( gfDoDialogOnceGameScreenFadesIn )
{
ValidateSoldierInitLinks( 4 );
}
#endif
HandleHeliDrop( );
if ( !ARE_IN_FADE_IN( ) )
{
HandleAutoBandagePending( );
#ifdef JA2UB
HandleThePlayerBeNotifiedOfSomeoneElseInSector();
#endif
}
// ATE: CHRIS_C LOOK HERE FOR GETTING AI CONSTANTLY GOING
//if ( gTacticalStatus.uiFlags & TURNBASED )
//{
// if ( !(gTacticalStatus.uiFlags & ENEMYS_TURN) )
// {
// EndTurn( );
// }
//}
// if ( gfScrollInertia == FALSE )
{
if ( !ARE_IN_FADE_IN( ) )
{
UpdateBullets( );
// Execute Tactical Overhead
ExecuteOverhead( );
}
// Handle animated cursors
if( gfWorldLoaded )
{
HandleAnimatedCursors( );
// Handle Interface
uiNewScreen = HandleTacticalUI( );
// called to handle things like face panels changeing due to team panel, squad changes, etc
// To be done AFTER HandleUI and before ExecuteOverlays( )
HandleDialogueUIAdjustments( );
HandleTalkingAutoFaces( );
}
#ifdef JA2EDITOR
else if( gfIntendOnEnteringEditor )
{
OutputDebugString( "Aborting normal game mode and entering editor mode...\n" );
SetPendingNewScreen( 0xffff ); //NO_SCREEN
return EDIT_SCREEN;
}
#endif
else if( !gfEnteringMapScreen )
{
gfEnteringMapScreen = TRUE;
}
if ( uiNewScreen != GAME_SCREEN )
{
return( uiNewScreen );
}
// Deque all game events
if ( !ARE_IN_FADE_IN( ) )
{
DequeAllGameEvents( TRUE );
}
}
/////////////////////////////////////////////////////
StartFrameBufferRender( );
HandleTopMessages( );
if ( gfScrollPending || gfScrollInertia )
{
}
else
{
// Handle Interface Stuff
SetUpInterface( );
HandleTacticalPanelSwitch( );
}
// Handle Scroll Of World
ScrollWorld( );
//SetRenderFlags( RENDER_FLAG_FULL );
RenderWorld( );
if ( gRenderOverride != NULL )
{
gRenderOverride( );
}
if ( gfScrollPending || gfScrollInertia )
{
RenderTacticalInterfaceWhileScrolling( );
}
else
{
// Handle Interface Stuff
//RenderTacticalInterface( );
}
#ifdef NETWORKED
// DEF: Test Code
PrintNetworkInfo();
#endif
// Render Interface
RenderTopmostTacticalInterface( );
#ifdef JA2TESTVERSION
if ( gTacticalStatus.uiFlags & ENGAGED_IN_CONV )
{
SetFont( MILITARYFONT1 );
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_LTGREEN );
mprintf( 0, 0, L"IN CONVERSATION %d", giNPCReferenceCount );
gprintfdirty( 0, 0, L"IN CONVERSATION %d", giNPCReferenceCount );
}
#ifdef JA2BETAVERSION
if ( GamePaused() == TRUE )
{
SetFont( MILITARYFONT1 );
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_LTGREEN );
mprintf( 0, 10, L"Game Clock Paused" );
gprintfdirty( 0, 10, L"Game Clock Paused" );
}
#endif
if ( gTacticalStatus.uiFlags & SHOW_ALL_MERCS )
{
INT32 iSchedules;
SCHEDULENODE *curr;
SetFont( MILITARYFONT1 );
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_LTGREEN );
mprintf( 0, 15, L"Attacker Busy Count: %d", gTacticalStatus.ubAttackBusyCount );
gprintfdirty( 0, 15, L"Attacker Busy Count: %d", gTacticalStatus.ubAttackBusyCount );
curr = gpScheduleList;
iSchedules = 0;
while( curr )
{
iSchedules++;
curr = curr->next;
}
mprintf( 0, 25, L"Schedules: %d", iSchedules );
gprintfdirty( 0, 25, L"Schedules: %d", iSchedules );
}
#endif
// Render view window
RenderRadarScreen( );
ResetInterface( );
if ( gfScrollPending )
{
DeleteVideoOverlaysArea( );
AllocateVideoOverlaysArea( );
SaveVideoOverlaysArea( FRAME_BUFFER );
ExecuteVideoOverlays( );
}
else
{
ExecuteVideoOverlays( );
}
// Adding/deleting of video overlays needs to be done below
// ExecuteVideoOverlays( )....
// Handle dialogue queue system
if ( !ARE_IN_FADE_IN( ) )
{
if ( gfPlayAttnAfterMapLoad )
{
gfPlayAttnAfterMapLoad = FALSE;
if ( gusSelectedSoldier != NOBODY )
{
if( !gGameSettings.fOptions[ TOPTION_MUTE_CONFIRMATIONS ] )
gusSelectedSoldier->DoMercBattleSound( BATTLE_SOUND_ATTN1 );
}
}
HandleDialogue( );
}
//Don't render if we have a scroll pending!
if ( !gfScrollPending && !gfScrollInertia && !gfRenderFullThisFrame )
{
RenderButtonsFastHelp( );
}
// Display Framerate
DisplayFrameRate( );
//UB
#ifdef JA2UB
/* JA2UB */
#else
CheckForMeanwhileOKStart( );
#endif
ScrollString( );
ExecuteBaseDirtyRectQueue( );
//KillBackgroundRects( );
/////////////////////////////////////////////////////
EndFrameBufferRender( );
if ( HandleFadeInCallback( ) )
{
// Re-render the scene!
SetRenderFlags( RENDER_FLAG_FULL );
fInterfacePanelDirty = DIRTYLEVEL2;
}
if ( HandleBeginFadeIn( GAME_SCREEN ) )
{
guiTacticalLeaveScreenID = FADE_SCREEN;
}
if ( guiTacticalLeaveScreen )
{
guiTacticalLeaveScreen = FALSE;
InternalLeaveTacticalScreen( guiTacticalLeaveScreenID );
}
// Check if we are to enter map screen
if ( gfEnteringMapScreen == 2 )
{
gfEnteringMapScreen = FALSE;
EnterMapScreen( );
}
// Are we entering map screen? if so, wait a frame!
if ( gfEnteringMapScreen > 0 )
{
gfEnteringMapScreen++;
}
return( GAME_SCREEN );
}
void SetRenderHook( RENDER_HOOK pRenderOverride )
{
gRenderOverride = pRenderOverride;
}
void DisableFPSOverlay( BOOLEAN fEnable )
{
VIDEO_OVERLAY_DESC VideoOverlayDesc;
memset( &VideoOverlayDesc, 0, sizeof( VideoOverlayDesc ) );
VideoOverlayDesc.fDisabled = fEnable;
VideoOverlayDesc.uiFlags = VOVERLAY_DESC_DISABLED;
UpdateVideoOverlay( &VideoOverlayDesc, giFPSOverlay, FALSE );
UpdateVideoOverlay( &VideoOverlayDesc, giCounterPeriodOverlay, FALSE );
}
void TacticalScreenLocateToSoldier( )
{
BOOLEAN fPreferedGuyUsed = FALSE;
if ( gubPreferredInitialSelectedGuy != NOBODY )
{
// ATE: Put condition here...
if ( OK_CONTROLLABLE_MERC( gubPreferredInitialSelectedGuy ) && OK_INTERRUPT_MERC( gubPreferredInitialSelectedGuy ) )
{
LocateSoldier( gubPreferredInitialSelectedGuy, 10 );
SelectSoldier( gubPreferredInitialSelectedGuy, FALSE, TRUE );
fPreferedGuyUsed = TRUE;
}
gubPreferredInitialSelectedGuy = NOBODY;
}
if ( !fPreferedGuyUsed )
{
// Set locator to first merc
SoldierID Soldier = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
SoldierID bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
for ( ; Soldier <= bLastTeamID; ++Soldier)
{
if ( OK_CONTROLLABLE_MERC( Soldier ) && OK_INTERRUPT_MERC( Soldier ) )
{
LocateSoldier( Soldier, 10 );
SelectSoldier( Soldier, FALSE, TRUE );
break;
}
}
}
}
void EnterMapScreen( )
{
// ATE: These flags well get set later on in mapscreen....
//SetTacticalInterfaceFlags( INTERFACE_MAPSCREEN );
//fInterfacePanelDirty = DIRTYLEVEL2;
LeaveTacticalScreen( MAP_SCREEN );
}
void UpdateTeamPanelAssignments( )
{
// Remove all players
RemoveAllPlayersFromSlot( );
// Set locator to first merc
SoldierID Soldier = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
SoldierID bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
for ( ; Soldier <= bLastTeamID; ++Soldier)
{
// Setup team interface
CheckForAndAddMercToTeamPanel( Soldier );
}
}
void EnterModalTactical( INT8 bMode )
{
gbTacticalDisableMode = bMode;
gfTacticalIsModal = TRUE;
if ( gbTacticalDisableMode == TACTICAL_MODAL_NOMOUSE )
{
if ( !gfTacticalDisableRegionActive )
{
gfTacticalDisableRegionActive = TRUE;
MSYS_DefineRegion( &gTacticalDisableRegion, 0, 0 ,SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_HIGH,
VIDEO_NO_CURSOR, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK );
// Add region
MSYS_AddRegion( &gTacticalDisableRegion );
}
}
UpdateSaveBuffer();
}
void EndModalTactical( )
{
if ( gfTacticalDisableRegionActive )
{
MSYS_RemoveRegion( &gTacticalDisableRegion );
gfTacticalDisableRegionActive = FALSE;
}
if ( gModalDoneCallback != NULL )
{
gModalDoneCallback( );
gModalDoneCallback = NULL;
}
gfTacticalIsModal = FALSE;
SetRenderFlags( RENDER_FLAG_FULL );
}
void HandleModalTactical( )
{
StartFrameBufferRender( );
RestoreBackgroundRects();
RenderWorld( );
RenderRadarScreen( );
ExecuteVideoOverlays( );
// Handle dialogue queue system
HandleDialogue( );
HandleTalkingAutoFaces( );
// Handle faces
HandleAutoFaces( );
if ( gfInSectorExitMenu )
{
RenderSectorExitMenu( );
}
RenderButtons();
SaveBackgroundRects( );
RenderButtonsFastHelp( );
RenderPausedGameBox( );
ExecuteBaseDirtyRectQueue( );
EndFrameBufferRender( );
}
void InitHelicopterEntranceByMercs( void )
{
if( DidGameJustStart() )
{
AIR_RAID_DEFINITION AirRaidDef;
// Update clock ahead from STARTING_TIME to make mercs arrive!
WarpGameTime( gGameExternalOptions.iFirstArrivalDelay, WARPTIME_PROCESS_EVENTS_NORMALLY );
// WANNE: fix HOT DAY in night at arrival by night.
// Explanation: If game starting time + first arrival delay < 07:00 (111600) -> we arrive before the sun rises or
// if game starting time + first arrival delay >= 21:00 (162000) -> we arrive after the sun goes down
if( (gGameExternalOptions.iGameStartingTime + gGameExternalOptions. iFirstArrivalDelay) < 111600 ||
(gGameExternalOptions.iGameStartingTime + gGameExternalOptions.iFirstArrivalDelay >= 162000))
{
gubEnvLightValue = 12;
}
else
{
// Default: Day
gubEnvLightValue = 3;
}
LightSetBaseLevel(gubEnvLightValue);
AirRaidDef.sSectorX = 9;
AirRaidDef.sSectorY = 1;
AirRaidDef.sSectorZ = 0;
AirRaidDef.bIntensity = 2;
AirRaidDef.uiFlags = AIR_RAID_BEGINNING_GAME;
AirRaidDef.ubNumMinsFromCurrentTime = Random(5) + 1;
// Madd - nevermind initial air strike. It just seems silly, since Deidranna doesn't know the mercs are there.
//if ( gGameOptions.fAirStrikes )
// ScheduleAirRaid( &AirRaidDef );
#ifdef JA2UB
if ( gGameUBOptions.InGameHeli == FALSE )
HandleInitialEventsInHeliCrash(); //JA25 UB
#endif
gfTacticalDoHeliRun = TRUE;
gfFirstHeliRun = TRUE;
#ifdef JA2UB
SetHelicopterDroppoint( gGameUBOptions.LOCATEGRIDNO );
#else
SetHelicopterDroppoint( gGameExternalOptions.iInitialMercArrivalLocation );
#endif
SetHelicopterDropDirection(NORTH);
gTacticalStatus.fDidGameJustStart = FALSE;
}
}