This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Commando/combatgmode.cpp

1591 lines
No EOL
44 KiB
C++

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Commando/combatgmode.cpp $*
* *
* $Author:: Steve_t $*
* *
* $Modtime:: 2/23/02 2:04p $*
* *
* $Revision:: 267 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "combatgmode.h"
#include "level.h"
#include "input.h"
#include "cnetwork.h"
#include "AudibleSound.H"
#include "debug.h"
#include "registry.h"
#include "_globals.h"
#include "console.h"
#include "radar.h"
#include "spawn.h"
#include "ccamera.h"
#include "scorescreen.h"
#include "devoptions.h"
#include "useroptions.h"
#include "systemsettings.h"
#include "gameobjmanager.h"
#include "building.h"
#include "saveloadstatus.h"
#include "playertype.h"
#include "bitpackids.h"
#include "vehicle.h"
#include "doors.h"
#include "elevator.h"
#include "msgloop.h"
#include "assetmgr.h"
#include "font3d.h"
#include "wwprofile.h"
#include "gametype.h"
#include "messagewindow.h"
#include "objectives.h"
#include "multihud.h"
#include "textureloader.h"
#include "wolgmode.h"
#include "renegadedialogmgr.h"
#include "textdisplay.h"
#include "playermanager.h"
#include "teammanager.h"
#include "consolefunction.h"
#include "overlay.h"
#include "gameinitmgr.h"
#include "campaign.h"
#include "diaglog.h"
#include "god.h"
#include "sbbomanager.h"
#include "savegame.h"
#include "commandosaveload.h"
#include "dlgmpingamechat.h"
#include "loadingevent.h"
#include "cheatmgr.h"
#include "menubackdrop.h"
#include "translatedb.h"
#include "thread.h"
#include "dlgcncteaminfo.h"
#include "dlgcncbattleinfo.h"
#include "bandwidthgraph.h"
#include "suicideevent.h"
#include "assetstatus.h"
#include "stylemgr.h"
#include "gametype.h"
#include "wwmemlog.h"
#include "directinput.h"
#include "cncmodesettings.h"
#include "announceevent.h"
#include "fastallocator.h"
#include "dlgcncserverinfo.h"
#include "radiocommanddisplay.h"
#include "hudinfo.h"
#include "string_ids.h"
#include "radiocommanddisplay.h"
#include "consolemode.h"
#include "specialbuilds.h"
#include <wwlib\realcrc.h>
#include "demosupport.h"
#include "natter.h"
#include "gamespyadmin.h"
#include "dialogtests.h"
#include "dialogmgr.h"
#include "GameSpy_QnR.h"
/*
**
*/
extern bool g_is_loading;
bool g_b_core_restart;//TSS081401
bool g_client_quit = false;
AudibleSoundClass * CombatGameModeClass::BackgroundMusic = NULL;
int CombatGameModeClass::IsHudShown = true;
static int ForceGod = false;
static bool ForceGodPending = true;
static int DefaultToFirstPerson = true;
static bool PendingCampaignContinue = false;
/*
**
*/
class CombatGameMiscHandlerClass : public CombatMiscHandlerClass {
public:
virtual void Mission_Complete( bool success );
virtual void Star_Killed( void );
};
CombatGameMiscHandlerClass GameMiscHandler;
/*
**
*/
static void Combat_To_Menu (RenegadeDialogMgrClass::LOCATION location)
{
//
// Remember: Combat and Menu are not mutually exclusive.
// Therefore this function may be called when menu is already active.
//
if (!GameModeManager::Find("Menu")->Is_Active()) {
//
// Do not suspend Combat in Multiplayer game!
//
if (IS_SOLOPLAY) {
GameModeManager::Find( "Combat" )->Suspend(); // suspend Combat Mode
}
//if (IS_SOLOPLAY) {
if (IS_MISSION) {
RenegadeDialogMgrClass::Goto_Location (location);
} else {
RenegadeDialogMgrClass::Goto_Location (RenegadeDialogMgrClass::LOC_CNC_REFERENCE);
}
}
}
/*
**
*/
static void Start_In_Game_Help(void)
{
//
// Remember: Combat and Menu are not mutually exclusive.
// Therefore this function may be called when menu is already active.
//
if (!GameModeManager::Find("Menu")->Is_Active()) {
//
// Do not suspend Combat in Multiplayer game!
//
if (IS_SOLOPLAY) {
GameModeManager::Find( "Combat" )->Suspend(); // suspend Combat Mode
}
RenegadeDialogMgrClass::Goto_Location (RenegadeDialogMgrClass::LOC_IN_GAME_HELP);
}
}
void CombatGameModeClass::Combat_Keyboard( void )
{
WWPROFILE( "Combat_Keyboard" );
#ifdef ATI_DEMO_HACK
// HACK: Make double-ESC exit back to desktop
static unsigned esc_pressed_time=0x7ffff;
if ( Input::Get_State( INPUT_FUNCTION_MENU_TOGGLE ) ) {
unsigned current_time=WW3D::Get_Sync_Time();
if ((current_time-esc_pressed_time)<5000) {
cDevOptions::QuickFullExit.Set(true);
esc_pressed_time=0x7ffff;
}
else {
Get_Text_Display()->Print_System( "Press ESC again to exit to desktop...\n" );
}
esc_pressed_time=current_time;
}
// HACK: In ATI demo toggle the statistics display using TAB
if ( Input::Get_State( INPUT_FUNCTION_EVA_MISSION_OBJECTIVES_TOGGLE ) ) {
if (StatisticsDisplayManager::Is_Current_Display( "fps" )) {
StatisticsDisplayManager::Set_Display( "off" );
}
else {
StatisticsDisplayManager::Set_Display( "fps" );
}
}
#else
bool to_menu=Input::Get_State( INPUT_FUNCTION_MENU_TOGGLE );
// If game doesn't have a focus and combat is active, suspend combat by entering menu
if (!GameInFocus) {
if (IS_SOLOPLAY && COMBAT_CAMERA && !COMBAT_CAMERA->Is_In_Cinematic() ) {
to_menu|=GameModeManager::Find( "Combat" )->Is_Active();
}
}
if ( to_menu ) {
Combat_To_Menu( RenegadeDialogMgrClass::LOC_ENCYCLOPEDIA );
}
//
// Handle the in-game EVA mission objectives window
//
if ( IS_MISSION && Input::Get_State( INPUT_FUNCTION_EVA_MISSION_OBJECTIVES_TOGGLE ) ) {
if ( ObjectiveManager::Is_Viewer_Displayed() ) {
ObjectiveManager::Page_Down_Viewer();
} else {
ObjectiveManager::Display_Viewer( true );
}
}
#endif
if ( Input::Get_State( INPUT_FUNCTION_HELP_SCREEN ) ) {
Start_In_Game_Help();
}
if ( IS_SOLOPLAY && Input::Get_State( INPUT_FUNCTION_EVA_OBJECTIVES_SCREEN ) ) {
Combat_To_Menu( RenegadeDialogMgrClass::LOC_OBJECTIVES );
}
if ( IS_SOLOPLAY && Input::Get_State( INPUT_FUNCTION_EVA_MAP_SCREEN ) ) {
Combat_To_Menu( RenegadeDialogMgrClass::LOC_MAP );
}
//
// Display the server info screen
//
if (!IS_MISSION && Input::Get_State( INPUT_FUNCTION_SERVER_INFO_TOGGLE )) {
START_DIALOG (CNCServerInfoDialogClass);
}
//
// Display the team information page
//
if (!IS_MISSION && cNetwork::I_Am_Client() && COMBAT_STAR != NULL) {
if (Input::Get_State( INPUT_FUNCTION_TEAM_INFO_TOGGLE )) {
START_DIALOG (CNCTeamInfoDialogClass);
} else if (Input::Get_State( INPUT_FUNCTION_BATTLE_INFO_TOGGLE )) {
START_DIALOG (CNCBattleInfoDialogClass);
}/* else if (Input::Get_State( INPUT_FUNCTION_SERVER_INFO_TOGGLE )) {
START_DIALOG (CNCServerInfoDialogClass);
}*/
// Handle radio commands
for (int radioCmdIndex = INPUT_FUNCTION_RADIO_CMD_01; radioCmdIndex <= INPUT_FUNCTION_RADIO_CMD_30; ++radioCmdIndex) {
if (Input::Get_State((InputFunction)radioCmdIndex)) {
CNCModeSettingsDef* cncDef = CNCModeSettingsDef::Get_Instance();
if (cncDef) {
int radioCmdNum = (radioCmdIndex - INPUT_FUNCTION_RADIO_CMD_01);
int radioCmd = cncDef->Get_Radio_Command(radioCmdNum);
if (radioCmd) {
CSAnnouncement* announce = new CSAnnouncement;
assert(announce != NULL);
announce->Init(cNetwork::Get_My_Team_Number(), radioCmd, ANNOUNCEMENT_TEAM, radioCmdNum);
RadioCommandDisplayClass::Reset_Display_Timer();
}
}
break;
}
}
}
if (!IS_MISSION && Input::Get_State( INPUT_FUNCTION_EVA_MISSION_OBJECTIVES_TOGGLE )) {
//MultiHUDClass::Toggle_Verbose_Lists();
MultiHUDClass::Next_Playerlist_Format();
}
#ifdef WWDEBUG
if ( Input::Get_State( INPUT_FUNCTION_QUICK_FULL_EXIT ) ) {
cDevOptions::QuickFullExit.Set(true);
WWDEBUG_SAY(("Quick full exit requested by keypress.\n"));
}
if (cDevOptions::QuickFullExit.Is_True()) {
GameInitMgrClass::End_Game();
GameInitMgrClass::End_Client_Server();
extern void Stop_Main_Loop (int exitCode);
Stop_Main_Loop (EXIT_SUCCESS);
}
#endif
if ( (The_Game() != NULL &&
(Input::Get_State(INPUT_FUNCTION_BEGIN_PUBLIC_MESSAGE) ||
(Input::Get_State(INPUT_FUNCTION_BEGIN_TEAM_MESSAGE) && cNetwork::I_Am_Client()))) &&
!IS_MISSION)
{
MPIngameChatPopupClass * p_dialog = new MPIngameChatPopupClass;
WWASSERT(p_dialog != NULL);
//
// Configure the dialog
//
if (Input::Get_State(INPUT_FUNCTION_BEGIN_PUBLIC_MESSAGE)) {
p_dialog->Set_Default_Type(TEXT_MESSAGE_PUBLIC);
} else {
p_dialog->Set_Default_Type(TEXT_MESSAGE_TEAM);
}
p_dialog->Start_Dialog();
REF_PTR_RELEASE (p_dialog);
}
if ( Input::Get_State( INPUT_FUNCTION_QUICKSAVE )) {
// Only for singeplay
if ( IS_MISSION ) {
Quick_Save();
}
}
}
/*
** called when the mode is activated
*/
void CombatGameModeClass::Init()
{
Debug_Say(("CombatGameModeClass::Init\n"));
if (!IS_MISSION) {
MultiHUDClass::Init();
}
PendingCampaignContinue = false;
//
// Initialize the radio command display window
//
RadioCommandDisplayClass::Initialize ();
//
// Notify combat about the state of the CameraLockedToTurret user option.
//
VehicleGameObj::Set_Camera_Locked_To_Turret(cUserOptions::CameraLockedToTurret.Get());
}
/*
** called when the mode is deactivated
*/
void CombatGameModeClass::Shutdown()
{
Debug_Say(("CombatGameModeClass::Shutdown\n"));
Core_Shutdown();
//
// Shutdown the radio command display window
//
RadioCommandDisplayClass::Shutdown ();
return ;
}
class LoadingScreenClass
{
MenuBackDropClass backdrop;
Render2DSentenceClass backdropText;
Render2DSentenceClass backdropText2; // The BIG text
float LoadTime;
float LoadPercentage;
float LoadPercentageDrawn;
float LoadPercentageClamp;
float LoadPercentageRate;
public:
LoadingScreenClass()
{
int color = 0xFFFFFFFF;
WWMEMLOG(MEM_GAMEDATA);
backdropText.Set_Texture_Size_Hint( 256 );
backdropText2.Set_Texture_Size_Hint( 256 );
LoadTime = 0.001f;
LoadPercentage = 0;
LoadPercentageDrawn = 0;
LoadPercentageRate = 0;
FontCharsClass *font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_TXT );
backdropText.Set_Font( font );
font = StyleMgrClass::Peek_Font( StyleMgrClass::FONT_INGAME_BIG_TXT );
backdropText2.Set_Font( font );
// Parse Descriptions
int count = CampaignManager::Get_Backdrop_Description_Count();
for ( int i = 0; i < count; i++ ) {
const char * read = CampaignManager::Get_Backdrop_Description( i );
// Debug_Say(( "Parse %s\n", read ));
StringClass desc = read;
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
while ( desc.Get_Length() && desc[desc.Get_Length()-1]<=' ' ) desc.Erase(desc.Get_Length()-1, 1 );
// Parse Big Translated Text
if ( ::strnicmp( "Text2", desc, 5 ) == 0 ) {
desc.Erase( 0, 5 );
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
float x,y;
::sscanf( desc, "%f,%f,", &x, &y );
const char * str = ::strchr( desc, ',' );
if ( str != NULL ) {
str = ::strchr( str+1, ',' );
if ( str != NULL ) {
WideStringClass wide_str = TranslateDBClass::Get_String( str+1 );
backdropText2.Build_Sentence( wide_str );
// Scale
x *= Render2DClass::Get_Screen_Resolution().Right / 640.0f;
y *= Render2DClass::Get_Screen_Resolution().Bottom / 480.0f;
backdropText2.Set_Location( Vector2( (int)x, (int)y ) );
backdropText2.Draw_Sentence( color );
color=0xFFFFFFFF;
backdropText2.Set_Wrapping_Width( 0 );
}
}
}
// Parse Translated Text
if ( ::strnicmp( "Text", desc, 4 ) == 0 ) {
desc.Erase( 0, 4 );
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
float x,y;
::sscanf( desc, "%f,%f,", &x, &y );
const char * str = ::strchr( desc, ',' );
if ( str != NULL ) {
str = ::strchr( str+1, ',' );
if ( str != NULL ) {
WideStringClass wide_str = TranslateDBClass::Get_String( str+1 );
backdropText.Build_Sentence( wide_str );
// Scale
x *= Render2DClass::Get_Screen_Resolution().Right / 640.0f;
y *= Render2DClass::Get_Screen_Resolution().Bottom / 480.0f;
backdropText.Set_Location( Vector2( (int)x, (int)y ) );
backdropText.Draw_Sentence( color );
color=0xFFFFFFFF;
backdropText.Set_Wrapping_Width( 0 );
}
}
}
// Set Big Wrapping Width
if ( ::strnicmp( "Wrap2", desc, 5 ) == 0 ) {
desc.Erase( 0, 5 );
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
float w;
::sscanf( desc, "%f,", &w );
// Scale
w *= Render2DClass::Get_Screen_Resolution().Right / 640.0f;
backdropText2.Set_Wrapping_Width( w );
}
// Set Wrapping Width
if ( ::strnicmp( "Wrap", desc, 4 ) == 0 ) {
desc.Erase( 0, 4 );
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
float w;
::sscanf( desc, "%f,", &w );
// Scale
w *= Render2DClass::Get_Screen_Resolution().Right / 640.0f;
backdropText.Set_Wrapping_Width( w );
}
// Parse test Text
if ( ::strnicmp( "Test", desc, 4 ) == 0 ) {
desc.Erase( 0, 4 );
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
float x,y;
::sscanf( desc, "%f,%f,", &x, &y );
const char * str = ::strchr( desc, ',' );
if ( str != NULL ) {
str = ::strchr( str+1, ',' );
if ( str != NULL ) {
WideStringClass wide_str;
wide_str.Convert_From( str+1 );
backdropText.Build_Sentence( wide_str );
// Scale
x *= Render2DClass::Get_Screen_Resolution().Right / 640.0f;
y *= Render2DClass::Get_Screen_Resolution().Bottom / 480.0f;
backdropText.Set_Location( Vector2( (int)x, (int)y ) );
backdropText.Draw_Sentence( color );
color=0xFFFFFFFF;
backdropText.Set_Wrapping_Width( 0 );
}
}
}
// Parse back model
if ( ::strnicmp( "Model", desc, 5 ) == 0 ) {
desc.Erase( 0, 5 );
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
backdrop.Set_Model(desc);
StringClass anim_name;
anim_name.Format( "%s.%s", desc, desc );
backdrop.Set_Animation( anim_name );
backdrop.Set_Animation_Percentage( 0 );
}
if ( ::strnicmp( "Color", desc, 5 ) == 0 ) {
desc.Erase( 0, 5 );
while ( desc.Get_Length() && desc[0] <= ' ' ) desc.Erase( 0, 1 );
float r,g,b;
::sscanf( desc, "%f,%f,%f", &r, &g, &b );
Vector3 c( r/255.0f, g/255.0f, b/255.0f );
color = c.Convert_To_ARGB();
}
}
SaveLoadStatus::Reset_Status_Count();
}
~LoadingScreenClass()
{
}
float Get_Predicted_Percentage( int state )
{
switch( state )
{
#define TOTAL (18.0f)
case 0: return 0.1f / TOTAL;
case 1: return 0.2f / TOTAL;
case 2: return 0.3f / TOTAL;
case 3: return 0.7f / TOTAL;
case 4: return 3.8f / TOTAL;
case 5: return 15.5f / TOTAL;
case 6: return 17.6f / TOTAL;
default: return 1.0f;
}
}
void Render(bool update_network = false)
{
TimeManager::Update_Frame_Time();
LoadTime += TimeManager::Get_Frame_Seconds();
WW3D::Begin_Render( true, true, Vector3(0.0f,0.0f,0.0f), update_network ? &cNetwork::Update : NULL);
backdrop.Render();
backdropText.Render();
backdropText2.Render();
static int last_count = -1;
static int _last_percent_drawn = -1;
if ( last_count != CombatManager::Get_Load_Progress() ) {
last_count = CombatManager::Get_Load_Progress();
Debug_Say(( " ****** Status Count %d at %f\n", last_count, LoadTime ));
LoadPercentage = Get_Predicted_Percentage( last_count );
LoadPercentageRate = LoadPercentage / LoadTime;
LoadPercentageClamp = Get_Predicted_Percentage( last_count+1 );
}
LoadPercentage += LoadPercentageRate * TimeManager::Get_Frame_Seconds();
LoadPercentage = WWMath::Clamp( LoadPercentage, 0, LoadPercentageClamp );
LoadPercentageDrawn += ( LoadPercentage - LoadPercentageDrawn ) * 0.1f;
backdrop.Set_Animation_Percentage( LoadPercentageDrawn );
if (ConsoleBox.Is_Exclusive() && _last_percent_drawn != LoadPercentageDrawn) {
_last_percent_drawn = LoadPercentageDrawn;
ConsoleBox.Print("Load %d%% complete\r", (int)(LoadPercentageDrawn * 100.0f));
}
#if 0
StringClass txt=SaveLoadStatus::Get_Status_Text(0);
txt=SaveLoadStatus::Get_Status_Text(1);
#endif
WW3D::End_Render();
}
};
#define LOADTIME_NETWORK_UPDATE if (!IS_SOLOPLAY) cNetwork::Update()
/*
**
*/
void CombatGameModeClass::Load_Level( void )
{
WWLOG_PREPARE_TIME_AND_MEMORY("CombatGameModeClass::Load_Level");
WWMEMLOG(MEM_GAMEDATA);
Debug_Say(("CombatGameModeClass::Load_Level\n"));
ConsoleBox.Print("Loading level %s\n", The_Game()->Get_Map_Name());
CombatManager::Set_Load_Progress(0);
LoadingScreenClass loading_screen; // Try moving this to very start of loading
loading_screen.Render(true);
// Hack load reg for default first person. Is dont again later.
Load_Registry_Keys();
WWLOG_INTERMEDIATE("Load_REgistry_Keys");
// Flush out current level
INIT_STATUS("Release current level");
LevelManager::Release_Level();
WWLOG_INTERMEDIATE("Releasing old level");
if (!ConsoleBox.Is_Exclusive()) {
WW3D::_Invalidate_Textures();
WWLOG_INTERMEDIATE("WW3D::_Invalidate_Textures()");
AssetStatusClass::Peek_Instance()->Enable_Load_On_Demand_Reporting(false);
}
// LoadingScreenClass loading_screen;
// loading_screen.Render(true);
PendingCampaignContinue = false;
g_is_loading = true;
//
// Stop the network layer from processing packets. This is needed in case a packet import or export accesses the datasafe
// from the main thread while the loader thread is loading stuff into the datasafe. This won't shut off packet acks so no-one
// will be disconnected as a result of this.
//
if (cNetwork::PServerConnection) {
cNetwork::PServerConnection->Allow_Packet_Processing(false);
}
if (!IS_SOLOPLAY && cNetwork::PClientConnection != NULL) {
cNetwork::PClientConnection->Allow_Extra_Timeout_For_Loading();
}
CombatManager::Pre_Load_Level(ConsoleBox.Is_Exclusive() ? false : true);
INIT_STATUS("Apply system settings");
SystemSettings::Apply_All();
CombatManager::Set_Combat_Misc_Handler( &GameMiscHandler );
// Flush out current level
// INIT_STATUS("Release current level");
// LevelManager::Release_Level();
WWASSERT(PTheGameData != NULL);
StringClass map_name(The_Game()->Get_Map_Name(),true);
WWASSERT( !map_name.Is_Empty() );
bool preload_assets = true;
#ifdef WWDEBUG
preload_assets = cDevOptions::PreloadAssets.Get();
#endif
DIAG_LOG(( "LOAD", "%s", map_name ));
NetworkObjectMgrClass::Set_Is_Level_Loading (true);
TextureLoader::Suspend_Texture_Load();
CombatManager::Load_Level_Threaded( map_name, preload_assets );
WWLOG_INTERMEDIATE("Level load preprocessing");
while (!CombatManager::Is_Load_Level_Complete() ) {
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
ThreadClass::Sleep_Ms(50);
}
WWLOG_INTERMEDIATE("Threaded level load");
GenericDataSafeClass::Set_Preferred_Thread(GetCurrentThreadId());
TextureLoader::Continue_Texture_Load();
WWLOG_INTERMEDIATE("TextureLoader::Continue_Texture_Load()");
LOADTIME_NETWORK_UPDATE;
// Post load processing ----------------------------------------------------
INIT_STATUS("Post_Load_Processing");
loading_screen.Render(true);
Windows_Message_Handler();
SaveLoadSystemClass::Post_Load_Processing(IS_SOLOPLAY ? NULL : &cNetwork::Update);
NetworkObjectMgrClass::Set_Is_Level_Loading (false);
WWLOG_INTERMEDIATE("SaveLoadSystemClass::Post_Load_Processing(&cNetwork::Update)");
INIT_STATUS("Post_Load_Level");
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
CombatManager::Post_Load_Level();
WWLOG_INTERMEDIATE("CombatManager::Post_Load_Level()");
INIT_STATUS("Post_Load_Id_Uniqueness_Check");
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
Post_Load_Id_Uniqueness_Check();
WWLOG_INTERMEDIATE("Post_Load_Id_Uniqueness_Check()");
INIT_STATUS("Post_Load_Dynamic_Object_Filtering");
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
Post_Load_Dynamic_Object_Filtering();
WWLOG_INTERMEDIATE("Post_Load_Dynamic_Object_Filtering()");
// Spawn point validation --------------------------------------------------
INIT_STATUS("Spawn_Point_Validation");
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
Spawn_Point_Validation();
WWLOG_INTERMEDIATE("Spawn_Point_Validation()");
// -------------------------------------------------------------------------
//DefinitionMgrClass::List_Available_Definitions();
INIT_STATUS("Compute world size");
Compute_World_Size();
WWLOG_INTERMEDIATE("Compute_World_Size()");
//
// Set precision for other stuff
// This stuff should be placed elsewhere... when there are a few
// more of them.
//
ControlClass::Set_Precision();
//SoldierGameObj::Set_Precision();
HumanStateClass::Set_Precision();
VehicleGameObj::Set_Precision();
DoorPhysClass::Set_Precision();
ElevatorPhysClass::Set_Precision();
DefenseObjectClass::Set_Precision();
BuildingGameObj::Set_Precision();
// Override background color if this is a dedicated server
if (cNetwork::I_Am_Only_Server()) {
GameModeManager::Set_Background_Color( Vector3( 0.0f, 0.0f, 0.4f ) );
}
INIT_STATUS("Registry keys");
Load_Registry_Keys();
Save_Registry_Keys();
WWLOG_INTERMEDIATE("SaveLoadRegistry");
// Radar init --------------------------------------------------------------
INIT_STATUS("Init radar class"); // Init the radar after the game is loaded (so we have the global settings
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
RadarManager::Init();
WWASSERT(PTheGameData != NULL);
RadarManager::Set_Radar_Mode(The_Game()->Get_Radar_Mode());
WWLOG_INTERMEDIATE("Init Radar");
// -------------------------------------------------------------------------
const bool is_reloaded = true;
The_Game()->Reset_Game(is_reloaded);
WWLOG_INTERMEDIATE("The_Game()->Reset_Game(is_reloaded)");
// Buildings init ----------------------------------------------------------
// After the level loads, the buildings collect all of their components
INIT_STATUS("Init_Buildings");
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
GameObjManager::Init_Buildings();
WWLOG_INTERMEDIATE("GameObjManager::Init_Buildings()");
// -------------------------------------------------------------------------
// Update texture loader ---------------------------------------------------
// This is needed here as we want to apply all textures that may have changed
// during the game loading before the game actually starts.
INIT_STATUS("Init_Textures");
loading_screen.Render(true);
Windows_Message_Handler();
LOADTIME_NETWORK_UPDATE;
TextureLoader::Update(IS_SOLOPLAY ? NULL : &cNetwork::Update);
WWLOG_INTERMEDIATE("TextureLoader::Update(&cNetwork::Update)");
// -------------------------------------------------------------------------
// Notify the game of "game start"
WWASSERT(PTheGameData != NULL);
The_Game()->On_Game_Begin();
WWLOG_INTERMEDIATE("The_Game()->On_Game_Begin()");
ForceGodPending = ForceGod != 0;
/* if ( GameModeManager::Find( "Overlay3D" ) ) {
((Overlay3DGameModeClass*)GameModeManager::Find( "Overlay3D" ))->Start_Intro();
}
*/
LOADTIME_NETWORK_UPDATE;
AssetStatusClass::Peek_Instance()->Enable_Load_On_Demand_Reporting(true);
g_is_loading = false;
ConsoleBox.Print("Load %d%% complete\n", 100);
ConsoleBox.Print("Level loaded OK\n");
GameSpyQnR.Init();
//
// Re-enable packet processing.
//
if (cNetwork::PServerConnection) {
cNetwork::PServerConnection->Allow_Packet_Processing(true);
}
if (!ConsoleBox.Is_Exclusive()) {
unsigned ffheap=FastAllocatorGeneral::Get_Allocator()->Get_Total_Heap_Size();
unsigned ffuse=FastAllocatorGeneral::Get_Allocator()->Get_Total_Allocated_Size();
unsigned actualuse=FastAllocatorGeneral::Get_Allocator()->Get_Total_Actual_Memory_Usage();
unsigned count=FastAllocatorGeneral::Get_Allocator()->Get_Total_Allocation_Count();
StringClass working_string(0,true);
working_string.Format(
"\nMalloc count: %d\n"
"Free count: %d\n"
"FF Heap: %d.%3.3d.%3.3d (%d Mb)\n"
"FF Use: %d.%3.3d.%3.3d (%d Mb)\n"
"Actual Use: %d.%3.3d.%3.3d (%d Mb)\n"
"FF Count: %d\n"
,
WW3D::Get_Last_Frame_Memory_Allocation_Count(),
WW3D::Get_Last_Frame_Memory_Free_Count(),
ffheap/(1000*1000),(ffheap/1000)%1000,ffheap%1000, ffheap/(1024*1024),
ffuse/(1000*1000),(ffuse/10000)%1000,ffuse%1000, ffuse/(1024*1024),
actualuse/(1000*1000),(actualuse/1000)%1000,actualuse%1000, actualuse/(1024*1024),
count);
WWDEBUG_SAY((working_string));
}
}
void CombatGameModeClass::Core_Shutdown()
{
Debug_Say(("CombatGameModeClass::Core_Shutdown\n"));
//
// Switch to the in-game sound page to ensure all those sounds get freed
// as we're shutting down the level.
//
WWAudioClass::Get_Instance ()->Push_Active_Sound_Page (WWAudioClass::PAGE_PRIMARY);
MultiHUDClass::Shutdown();
//cPlayerManager::Shutdown();
//cTeamManager::Shutdown();
// Shutdown the sound library
if (BackgroundMusic != NULL) {
BackgroundMusic->Stop ();
BackgroundMusic->Release_Ref ();
BackgroundMusic = NULL;
}
if (IS_MISSION) {
//
// Keep the GOD manager from offering a respawn when the star is gone
//
cGod::Exit();
}
CombatManager::Unload_Level();
LevelManager::Release_Level();
RadarManager::Shutdown();
//
// Restore the current sound page
//
WWAudioClass::Get_Instance ()->Pop_Active_Sound_Page ();
}
//-----------------------------------------------------------------------------
void CombatGameModeClass::Post_Load_Id_Uniqueness_Check(void)
{
bool list_ids = false;
//
// Make sure no 2 phys objects have the same id.
//
// Debug_Say(("Testing id uniqueness for physical objects:\n"));
int phys_obj_count = 0;
SLNode<BaseGameObj> * objnode;
for (objnode = GameObjManager::Get_Game_Obj_List()->Head(); objnode; objnode = objnode->Next()) {
WWASSERT(objnode->Data() != NULL);
PhysicalGameObj * p_phys_obj = objnode->Data()->As_PhysicalGameObj();
if (p_phys_obj != NULL) {
phys_obj_count++;
if (list_ids) {
Debug_Say((" Object %d, model %s\n",
p_phys_obj->Get_ID(),
p_phys_obj->Peek_Model()->Get_Name()));
}
SLNode<BaseGameObj> * objnode2;
for (objnode2 = GameObjManager::Get_Game_Obj_List()->Head(); objnode2; objnode2 = objnode2->Next()) {
WWASSERT(objnode2->Data() != NULL);
PhysicalGameObj * p_phys_obj_2 = objnode2->Data()->As_PhysicalGameObj();
if (p_phys_obj_2 != NULL &&
p_phys_obj_2->Get_ID() == p_phys_obj->Get_ID()) {
//WWASSERT(p_phys_obj_2 == p_phys_obj);
if (p_phys_obj_2 != p_phys_obj) {
Debug_Say(("Level file error: Two phys objects found with id %d.\n",
p_phys_obj_2->Get_ID()));
DIE;
}
}
}
}
}
// Debug_Say((" %d unique physical objects were loaded.\n", phys_obj_count));
//
// Make sure no 2 static objects have the same id.
//
// Debug_Say(("Testing id uniqueness for static objects:\n"));
WWASSERT(COMBAT_SCENE != NULL);
int static_obj_count = 0;
RefPhysListIterator iter_1 = COMBAT_SCENE->Get_Static_Object_Iterator();
for (iter_1.First(); !iter_1.Is_Done(); iter_1.Next()) {
//StaticPhysClass * p_obj_1 = (StaticPhysClass *) iter_1.Peek_Obj();
PhysClass * p_obj_1 = iter_1.Peek_Obj();
WWASSERT(p_obj_1 != NULL);
int object_id_1 = p_obj_1->Get_ID();
static_obj_count++;
if (list_ids) {
//Debug_Say((" Object %d\n", object_id_1));
Debug_Say((" Object %d, model %s\n",
p_obj_1->Get_ID(),
p_obj_1->Peek_Model()->Get_Name()));
}
RefPhysListIterator iter_2 = COMBAT_SCENE->Get_Static_Object_Iterator();
for (iter_2.First(); !iter_2.Is_Done(); iter_2.Next()) {
//StaticPhysClass * p_obj_2 = (StaticPhysClass *) iter_2.Peek_Obj();
PhysClass * p_obj_2 = iter_2.Peek_Obj();
WWASSERT(p_obj_2 != NULL);
int object_id_2 = p_obj_2->Get_ID();
//
//
// DO NOT DISABLE THIS
//
//
if (object_id_1 == object_id_2 && p_obj_1 != p_obj_2) {
Debug_Say(("Fatal level file error: Two static objects found with id %d.\n",
object_id_1));
DIE;
}
}
}
// Debug_Say((" %d unique static objects were loaded.\n", static_obj_count));
}
//-----------------------------------------------------------------------------
void CombatGameModeClass::Post_Load_Dynamic_Object_Filtering(void)
{
//
// Look through the soldiers and remove any that aren't
// appropriate for this particular game type.
//
//
// Any commando's that are tagged as having human players must be removed.
// The player id field is not valid...
// The exception is the commando belonging to the first player.
//
// Remove any soldiers with invalid player types for this game.
//
// Remove any grunts unless this is a mission.
//
WWASSERT(PTheGameData != NULL);
SLNode<SmartGameObj> * objnode;
for (objnode = GameObjManager::Get_Smart_Game_Obj_List()->Head(); objnode; objnode = objnode->Next()) {
SmartGameObj * p_smart_obj = objnode->Data();
WWASSERT(p_smart_obj != NULL);
if (p_smart_obj->As_SoldierGameObj() != NULL) {
if (p_smart_obj->Has_Player() && (p_smart_obj->Get_Control_Owner() > 1 ||
(!cNetwork::I_Am_Client()))) {
Debug_Say(("* Removing loaded soldier belonging to another player.\n"));
p_smart_obj->Set_Delete_Pending();
}
if (!p_smart_obj->Is_Delete_Pending() &&
!The_Game()->Is_Valid_Player_Type(p_smart_obj->Get_Player_Type())) {
Debug_Say(("* Removing loaded soldier due to invalid playertype for this game.\n"));
p_smart_obj->Set_Delete_Pending();
}
if (!p_smart_obj->Is_Delete_Pending() && !p_smart_obj->Has_Player() &&
!IS_SOLOPLAY) {
Debug_Say(("* Removing loaded soldier grunt in non-mission game (id = %d).\n",
p_smart_obj->Get_ID()));
p_smart_obj->Set_Delete_Pending();
}
}
}
}
//-----------------------------------------------------------------------------
void CombatGameModeClass::Compute_World_Size(void)
{
//
// Tell networking system about the size of the world, to be used
// in filtering.
//
Vector3 min;
Vector3 max;
WWASSERT(PhysicsSceneClass::Get_Instance() != NULL);
PhysicsSceneClass::Get_Instance()->Get_Level_Extents(min, max);
//Debug_Say(("World extends from (%5.2f, %5.2f, %5.2f) to (%5.2f, %5.2f, %5.2f)\n",
// min.X, min.Y, min.Z, max.X, max.Y, max.Z));
Vector3 longest_distance = max - min;
//Debug_Say(("Longest distance is %5.2fm\n", longest_distance.Length()));
WWASSERT(PTheGameData != NULL);
The_Game()->Set_Maximum_World_Distance(longest_distance.Length());
double margin = 1; // comfort zone
//
// Also, set encoding precision for positional information
//
cEncoderList::Set_Precision(BITPACK_WORLD_POSITION_X,
min.X - margin, max.X + margin, 0.2);
cEncoderList::Set_Precision(BITPACK_WORLD_POSITION_Y,
min.Y - margin, max.Y + margin, 0.2);
cEncoderList::Set_Precision(BITPACK_WORLD_POSITION_Z,
min.Z - margin, max.Z + margin, 0.2);
cEncoderList::Set_Precision(BITPACK_BUILDING_RADIUS,
0.0, 50.0, 0.1);
}
//-----------------------------------------------------------------------------
#define ADD_CASE(exp) case exp: return #exp; break;
static LPCSTR Playertype_To_String(int player_type)
{
switch (player_type) {
ADD_CASE(PLAYERTYPE_MUTANT);
ADD_CASE(PLAYERTYPE_NEUTRAL);
ADD_CASE(PLAYERTYPE_RENEGADE);
ADD_CASE(PLAYERTYPE_NOD);
ADD_CASE(PLAYERTYPE_GDI);
default:
DIE;
return "ERROR"; // to avoid compiler warning
}
}
//-----------------------------------------------------------------------------
void CombatGameModeClass::Spawn_Point_Validation(void)
{
if (cNetwork::I_Am_Server()) {
bool is_spawners_valid = true;
for (int spawn_type = PLAYERTYPE_RENEGADE; spawn_type <= PLAYERTYPE_LAST; spawn_type++) {
if ( !SpawnManager::Spawner_Exists( spawn_type ) ) {
Debug_Say((" Error: No spawn point(s) of type %s found.\n",
Playertype_To_String(spawn_type)));
is_spawners_valid = false;
} else {
Debug_Say((" Spawn point(s) of type %s found.\n",
Playertype_To_String(spawn_type)));
}
}
if (!IS_SOLOPLAY) {
WWASSERT(is_spawners_valid);
}
}
}
//-----------------------------------------------------------------------------
void CombatGameModeClass::Core_Restart(void)
{
Debug_Say(("CombatGameModeClass::Core_Restart\n"));
Core_Shutdown();
GameModeManager::Safely_Deactivate();
INIT_STATUS("Reloading...");
if ( IS_MISSION ) {
#ifndef MULTIPLAYERDEMO
StringClass new_name;
WWASSERT(PTheGameData != NULL);
new_name = CombatManager::Get_Last_LSD_Name();
// convert .LSD to .MIX
if ( new_name.Get_Length() > 4 &&
::stricmp( &new_name[new_name.Get_Length() - 4], ".LSD" ) == 0 ) {
new_name.Erase( new_name.Get_Length() - 4, 4 );
new_name += ".MIX";
}
The_Game()->Set_Map_Name( new_name );
#endif // !MULTIPLAYERDEMO
} else {
//
// Reset the timer system if we are a dedicated server and there is no-one in the game.
// ST - 1/30/2002 12:44PM
//
if (The_Game() && The_Game()->IsDedicated.Is_True()) {
if (cNetwork::PServerConnection && cNetwork::PServerConnection->Get_Num_RHosts() == 0) {
GameModeClass *game_mode = GameModeManager::Find("LAN");
//
// Don't do this if the NAT thread is busy since it uses timers extensively.
//
if ((game_mode && game_mode->Is_Active()) || WOLNATInterface.Is_NAT_Thread_Busy() == false) {
//
// Danger! Danger!
// This could cause code that uses time deltas to fail. Hopefully there isn't any code doing that right now.
//
SystemTime.Reset();
TimeManager::Reset();
GenericDataSafeClass::Reset_Timers();
GameModeClass* game_mode = GameModeManager::Find("WOL");
if (game_mode && game_mode->Is_Active()) {
WolGameModeClass* wol_game = reinterpret_cast<WolGameModeClass*>(game_mode);
wol_game->System_Timer_Reset();
}
}
}
}
}
//
// Reset packet optimizer bandwidth stats.
//
PacketManager.Reset_Stats();
Load_Level();
#ifdef WW3D_COMPILE_WITH_DX8__
DX8MeshRendererContainerClass::Invalidate_All();
#endif
}
//-----------------------------------------------------------------------------
/*
**
*/
void CombatGameModeClass::Load_Registry_Keys(void)
{
RegistryClass * registry = new RegistryClass( APPLICATION_SUB_KEY_NAME_OPTIONS );
WWASSERT( registry );
if ( registry->Is_Valid() ) {
IsHudShown = registry->Get_Int( "IsHudShown", IsHudShown );
ForceGod = registry->Get_Int( "ForceGod", ForceGod );
//TSS
DefaultToFirstPerson = registry->Get_Int( "DefaultToFirstPerson", DefaultToFirstPerson );
CombatManager::Set_First_Person_Default(DefaultToFirstPerson == TRUE);
}
delete registry;
}
void CombatGameModeClass::Save_Registry_Keys(void)
{
RegistryClass * registry = new RegistryClass( APPLICATION_SUB_KEY_NAME_OPTIONS );
WWASSERT( registry );
if ( registry->Is_Valid() ) {
registry->Set_Int( "IsHudShown", IsHudShown );
registry->Set_Int( "ForceGod", ForceGod );
//TSS
DefaultToFirstPerson = CombatManager::Get_First_Person_Default();
registry->Set_Int( "DefaultToFirstPerson", DefaultToFirstPerson );
}
delete registry;
}
/*
** called each time through the main loop when active
*/
void CombatGameModeClass::Think()
{
WWPROFILE( "Combat Think" );
if ( !Is_Active() ) {
return;
}
Combat_Keyboard();
//
// Test again to see if we are active, because quick exit may inactivate us.
//
if ( !Is_Active() ) {
return;
}
CombatManager::Generate_Control();
//
// Network Update needs to be between input and think
//
float time_1;
{
WWMeasureItClass net_upd_time_s(&time_1);
cNetwork::Update();
}
float time_2;
{
WWMeasureItClass combat_think_time_s(&time_2);
CombatManager::Think();
}
if (cNetwork::I_Am_Server())
{
WWPROFILE( "cSbboManager stuff" );
cSbboManager::Increment_Accum_Time_S_Net_Update(time_1);
cSbboManager::Increment_Accum_Time_S_Combat_Think(time_2);
cSbboManager::Think();
}
DEMO_SECURITY_CHECK;
if ( COMBAT_STAR ) {
WWPROFILE( "Stuff 1" );
Vector3 pos;
COMBAT_STAR->Get_Position( &pos );
float facing = COMBAT_STAR->Get_Facing();
Get_Console()->Set_Player_Position( pos, facing );
if ( ForceGodPending ) {
ForceGodPending = false;
ConsoleFunctionManager::Parse_Input( "God" );
}
}
MultiHUDClass::Think();
cPlayerManager::Think();
cTeamManager::Think();
if ( PendingCampaignContinue ) {
WWPROFILE( "Stuff 2" );
PendingCampaignContinue = false;
Debug_Say(( "Handle Pending Campaign Continue\n" ));
CampaignManager::Continue();
}
#ifdef MULTIPLAYERDEMO
//
// Security check. Randomly every few minutes, check to see if a special
// MP demo object (id 100277) exists. If it doesn't, assume someone has hacked in
// a different map. Bail.
//
if ((::rand() % 10131 == 939) && (NetworkObjectMgrClass::Find_Object(100277) == NULL)) {
WWDEBUG_SAY(("MP DEMO OBJECT NOT FOUND... BAILING.\n"));
Suspend();
GameInitMgrClass::End_Game();
extern void Stop_Main_Loop (int);
Stop_Main_Loop(EXIT_SUCCESS);
}
#endif // MULTIPLAYERDEMO
if (g_b_core_restart) {
WWPROFILE( "g_b_core_restart" );
g_b_core_restart = false;
//Core_Restart();
cPlayer * p_me = cNetwork::Get_My_Player_Object();
if (p_me != NULL) {// && cNetwork::I_Am_Only_Client()) {
p_me->Set_Is_In_Game(false);
cLoadingEvent * p_loading_1 = new cLoadingEvent;
p_loading_1->Init(true);
Core_Restart();
p_me->Set_Is_In_Game(true);
cLoadingEvent * p_loading_2 = new cLoadingEvent;
p_loading_2->Init(false);
} else {
Core_Restart();
}
if (!IS_MISSION) {
MultiHUDClass::Init();
}
cNetwork::Enable_Waiting_Players();
/*
#if(0)
WWDEBUG_SAY(("****** CombatGameModeClass::Think On_Game_Begin()\n"));
WWASSERT(The_Game() != NULL);
// The_Game()->On_Game_End();
The_Game()->Reset_Game(false);
The_Game()->On_Game_Begin();//TSS091201
#endif
*/
}
// Autosave, after one run throught main loop
if ( CombatManager::Is_Autosave_Requested() ) {
WWPROFILE( "Autosaving" );
Debug_Say(( "Autosaving\n" ));
int time=TIMEGETTIME();
CombatManager::Request_Autosave( false );
SaveGameManager::Set_Description( TRANSLATE( IDS_SAVE_AUTOSAVE ) );
SaveGameManager::Save_Game( "save\\autosave.sav", &_CommandoSaveLoad, NULL );
time=TIMEGETTIME()-time;
Debug_Say(( "Autosaving Complete, took %d.%2.2d seconds\n",time/1000,(time/10)%100 ));
}
//TSS090401
if (g_client_quit)
{
WWPROFILE( "g_client_quit" );
//
// This becomes true when the connection to the server breaks
//
g_client_quit = false;
Suspend();
GameInitMgrClass::End_Game();
//GAMESPY
if (cGameSpyAdmin::Get_Is_Launched_From_Gamespy())
{
#ifdef MULTIPLAYERDEMO
DialogMgrClass::Flush_Dialogs ();
START_DIALOG (SplashOutroMenuDialogClass);
#else
extern void Stop_Main_Loop (int);
Stop_Main_Loop(EXIT_SUCCESS);
#endif // MULTIPLAYERDEMO
}
else
{
GameInitMgrClass::Display_End_Game_Menu();
}
}
}
void CombatGameModeClass::Render()
{
if ( !Is_Active() ) {
return;
}
if (cNetwork::I_Am_Client()) {
/*
** In multi-play, only render the combatmanager when we have a valid camera and the menu is not active
*/
bool menu_active = false;
GameModeClass * menu_mode = GameModeManager::Find( "Menu" ); // Activate the main menu
if ((menu_mode != NULL) && (menu_mode->Get_State() == GAME_MODE_ACTIVE)) {
menu_active = true;
}
if ( COMBAT_CAMERA && COMBAT_CAMERA->Is_Valid() && (menu_active == false)) {
CombatManager::Render();
}
}
MultiHUDClass::Render();
cBandwidthGraph::Render();
cPlayerManager::Render();
cTeamManager::Render();
WWASSERT(PTheGameData != NULL);
The_Game()->Render();
RadioCommandDisplayClass::Render ();
}
//-----------------------------------------------------------------------------
void CombatGameModeClass::Toggle_Multi_Hud(void)
{
MultiHUDClass::Toggle();
}
// --------------------------------------------------------------
void CombatGameMiscHandlerClass::Mission_Complete( bool success )
{
if (IS_MISSION) {
if ( success ) {
PendingCampaignContinue = true;
} else {
cGod::Mission_Failed();
}
#if 0
GameModeManager::Find("Combat")->Suspend();
// GameModeManager::Find("Combat")->Deactivate();
// GameModeManager::Find("ScoreScreen")->Activate();
// ((ScoreScreenGameModeClass*)GameModeManager::Find("ScoreScreen"))->Set_Success( success );
if ( GameModeManager::Find( "Overlay3D" ) ) {
((Overlay3DGameModeClass*)GameModeManager::Find( "Overlay3D" ))->Start_End_Screen();
}
#endif
}
}
void CombatGameMiscHandlerClass::Star_Killed( void )
{
cGod::Star_Killed();
}
void CombatGameModeClass::Resume(void)
{
//
// Show the message window (if necessary)
//
if ( CombatManager::Get_Message_Window () != NULL &&
CombatManager::Get_Message_Window ()->Has_Data ())
{
CombatManager::Get_Message_Window ()->Force_Display (true);
}
GameMajorModeClass::Resume();
return ;
}
void CombatGameModeClass::Suspend(void)
{
//
// Hide the message window
//
if (CombatManager::Get_Message_Window () != NULL) {
CombatManager::Get_Message_Window ()->Force_Display (false);
}
//
// Hide the objective viewer
//
ObjectiveManager::Display_Viewer (false);
GameMajorModeClass::Suspend();
return ;
}
/*
**
*/
void CombatGameModeClass::Quick_Save( void )
{
bool saveA = true;
RegistryClass * registry = new RegistryClass( APPLICATION_SUB_KEY_NAME_OPTIONS );
WWASSERT( registry );
if ( registry->Is_Valid() ) {
saveA = registry->Get_Bool( "QuicksaveA", saveA );
}
#define SAVEGAME_NAME_A "save\\quicksaveA.sav"
#define SAVEGAME_NAME_B "save\\quicksaveB.sav"
// Check for a missing file
if ( !cMiscUtil::File_Exists(SAVEGAME_NAME_B) ) {
saveA = false;
}
if ( !cMiscUtil::File_Exists(SAVEGAME_NAME_A) ) {
saveA = true;
}
if ( saveA ) {
SaveGameManager::Set_Description( TRANSLATE(IDS_SAVE_QUICKSAVE_A) );
SaveGameManager::Save_Game( SAVEGAME_NAME_A, &_CommandoSaveLoad, NULL );
Debug_Say(( "Quicksaved A\n" ));
} else {
SaveGameManager::Set_Description( TRANSLATE(IDS_SAVE_QUICKSAVE_B) );
SaveGameManager::Save_Game( SAVEGAME_NAME_B, &_CommandoSaveLoad, NULL );
Debug_Say(( "Quicksaved B\n" ));
}
saveA = !saveA;
if ( registry->Is_Valid() ) {
registry->Set_Bool( "QuicksaveA", saveA );
}
delete registry;
// Display "Quick Saved"
HUDInfo::Set_HUD_Help_Text( TRANSLATE( IDS_M00DSGN_DSGN1017I1DSGN_TXT ), Vector3( 0,1,0 ) );
}
/**/
/*
if (::rand() % 10131 == 939)) {
bool bail = true;
ScriptableGameObj * p_obj = GameObjManager::Find_ScriptableGameObj(100277);
if (p_obj != NULL && p_obj->Get_Definition().Get_Name()) {
bail = false;
}
if (bail) {
Suspend();
GameInitMgrClass::End_Game();
extern void Stop_Main_Loop (int);
Stop_Main_Loop(EXIT_SUCCESS);
}
}
*/