////////////////////////////////////////////////////////////////////// // // Game source code // // File: Game.cpp // // History: // -August 02,2001: Create by Alberto Demichelis // -Sep 24,2001 : Modified by Petar Kotevski // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include #include #include "Game.h" #include "XNetwork.h" #include "XServer.h" #include "XClient.h" #include "UIHud.h" #include "WeaponSystemEx.h" #include "WeaponClass.h" #include "XVehicleSystem.h" #include "PlayerSystem.h" #include "XServer.h" #include "XSystemBase.h" #include "UISystem.h" #include "Flock.h" #include "EntityClassRegistry.h" #include "ScriptObjectGame.h" #include "ScriptObjectInput.h" #include "ScriptObjectLanguage.h" #include "ScriptObjectPlayer.h" #include "ScriptObjectSpectator.h" // CScriptObjectSpectator #include "ScriptObjectAdvCamSystem.h" // CScriptObjectAdvCamSystem #include "ScriptObjectSynched2DTable.h" // CScriptObjectSynched2DTable #include "ScriptObjectVehicle.h" #include "ScriptObjectRenderer.h" #include "ScriptObjectStream.h" #include "ScriptObjectWeaponClass.h" #include "ScriptObjectAI.h" #include "ScriptObjectUI.h" #include "ScriptObjectBoids.h" #include "ScriptTimerMgr.h" #include "IngameDialog.h" #include #include #include "TagPoint.h" //#include "XPath.h" #include "XPlayer.h" #include "XVehicle.h" #include #include "CMovieUser.h" #include "TimeDemoRecorder.h" #include "GameMods.h" #ifdef WIN32 #include #include typedef std::basic_string< TCHAR > tstring; typedef std::vector< TCHAR > tvector; #endif ////////////////////////////////////////////////////////////////////////// // Pointer to Global ISystem. static ISystem* gISystem = 0; ISystem* GetISystem() { return gISystem; } ////////////////////////////////////////////////////////////////////////////////////////////// // DLL Interface ////////////////////////////////////////////////////////////////////// // interface of the DLL IGame* CreateGameInstance() { CXGame *pGame = new CXGame(); return pGame; } ////////////////////////////////////////////////////////////////////////////////////////////// // CTagPointManager class CTagPointManager : public ITagPointManager { public: CTagPointManager( IGame *pGame ) { m_pGame = (CXGame*) pGame; }; virtual ~CTagPointManager() {}; // This function creates a tag point in the game world virtual ITagPoint *CreateTagPoint(const string &name, const Vec3 &pos, const Vec3 &angles) { return m_pGame->CreateTagPoint( name, pos, angles ); }; // Retrieves a tag point by name virtual ITagPoint *GetTagPoint(const string &name) { return m_pGame->GetTagPoint( name ); } // Deletes a tag point from the game virtual void RemoveTagPoint(ITagPoint *pPoint) { m_pGame->RemoveTagPoint( pPoint ); } virtual void AddRespawnPoint(ITagPoint *pPoint) { m_pGame->AddRespawnPoint( pPoint ); } virtual void RemoveRespawnPoint(ITagPoint *pPoint) { m_pGame->RemoveRespawnPoint( pPoint ); } private: CXGame *m_pGame; }; ////////////////////////////////////////////////////////////////////////////////////////////// // CXGame //!constructor CXGame::CXGame() { m_pTimeDemoRecorder = NULL; m_pScriptObjectGame = NULL; m_pScriptTimerMgr = NULL; m_pScriptSystem = NULL; m_pServer = NULL; m_pClient = NULL; m_pLog = NULL; m_pServerSnooper = NULL; m_pNETServerSnooper = 0; m_pRConSystem = 0; m_pWeaponSystemEx = NULL; m_mapTagPoints.clear(); m_bMenuInitialized = false; m_pCurrentUI = 0; m_pIActionMapManager=NULL; m_pIngameDialogMgr = new CIngameDialogMgr(); m_pUISystem = 0; mp_model = 0; #if !defined(LINUX) // to avoid all references to movie user in this file m_pMovieUser = new CMovieUser(this); #endif m_nPlayerIconTexId = -1; m_nVehicleIconTexId = -1; m_nBuildingIconTexId = -1; m_nUnknownIconTexId = -1; m_bMenuOverlay = false; m_bUIOverlay = false; m_bUIExclusiveInput = false; m_bHideLocalPlayer = false; m_pCVarCheatMode=NULL; m_fTimeGran=m_fFixedStep=m_fTimeGran2FixedStep=m_frFixedStep = 0; m_iFixedStep2TimeGran = 0; g_language=0; g_playerprofile=0; g_serverprofile=0; m_tPlayerPersistentData.m_bDataSaved=false; m_fFadingStartTime=-1.0f; cv_game_physics_quality=NULL; m_bMapLoadedFromCheckpoint=false; m_bSynchronizing = false; //m_fTimeToSaveThumbnail = 0; m_pGameMods = NULL; m_bLastDoLateSwitch = 0; m_bLastCDAuthentication = 0; m_bAllowQuicksave = true; m_sGameName = "FarCry"; m_pTagPointManager = new CTagPointManager( this ); m_nDEBUG_TIMING = 0; m_fDEBUG_STARTTIMER = 0; } ////////////////////////////////////////////////////////////////////// //!destructor CXGame::~CXGame() { m_pScriptSystem->BeginCall("Shutdown"); m_pScriptSystem->PushFuncParam(0); m_pScriptSystem->EndCall(); if (m_pIngameDialogMgr) delete m_pIngameDialogMgr; m_pIngameDialogMgr=NULL; #if !defined(LINUX) if (m_pMovieUser) { if (m_pSystem) { IMovieSystem *pMovieSystem=m_pSystem->GetIMovieSystem(); if (pMovieSystem) { if (pMovieSystem->GetUser()==m_pMovieUser) pMovieSystem->SetUser(NULL); } } delete m_pMovieUser; } #endif m_pMovieUser=NULL; // shutdown the client if there is one ShutdownClient(); // shutdown the server if there is one ShutdownServer(); if (m_pUISystem) { m_pUISystem->Release(); } SAFE_DELETE(m_pUISystem); CScriptObjectUI::ReleaseTemplate(); CScriptObjectPlayer::ReleaseTemplate(); CScriptObjectFireParam::ReleaseTemplate(); CScriptObjectWeaponClass::ReleaseTemplate(); CScriptObjectVehicle::ReleaseTemplate(); CScriptObjectSpectator::ReleaseTemplate(); CScriptObjectAdvCamSystem::ReleaseTemplate(); CScriptObjectSynched2DTable::ReleaseTemplate(); CScriptObjectBoids::ReleaseTemplate(); CScriptObjectRenderer::ReleaseTemplate(); CScriptObjectGame::ReleaseTemplate(); CScriptObjectInput::ReleaseTemplate(); CScriptObjectLanguage::ReleaseTemplate(); CScriptObjectAI::ReleaseTemplate(); CScriptObjectServer::ReleaseTemplate(); CScriptObjectServerSlot::ReleaseTemplate(); CScriptObjectClient::ReleaseTemplate(); CScriptObjectStream::ReleaseTemplate(); cl_scope_flare->Release(); cl_ThirdPersonRange->Release(); cl_ThirdPersonOffs->Release(); cl_ThirdPersonOffsAngHor->Release(); cl_ThirdPersonOffsAngVert->Release(); cl_display_hud->Release(); cl_motiontracker->Release(); cl_hud_pickup_icons->Release(); cl_msg_notification->Release(); cl_hud_name->Release(); ai_num_of_bots->Release(); p_name->Release(); p_model->Release(); mp_model->Release(); p_color->Release(); p_always_run->Release(); g_language->Release(); g_playerprofile->Release(); g_serverprofile->Release(); g_GC_Frequence->Release(); p_speed_run->Release(); p_sprint_scale->Release(); p_sprint_decoy->Release(); p_sprint_restore_run->Release(); p_sprint_restore_idle->Release(); p_speed_walk->Release(); p_speed_crouch->Release(); p_speed_prone->Release(); p_jump_force->Release(); p_jump_run_time->Release(); p_jump_walk_time->Release(); // p_lean->Release(); p_lean_offset->Release(); p_bob_pitch->Release(); p_bob_roll->Release(); p_bob_length->Release(); p_bob_weapon->Release(); p_bob_fcoeff->Release(); p_weapon_switch->Release(); cv_game_physics_quality->Release(); m_jump_vel->Release(); m_jump_arc->Release(); b_camera->Release(); // f_update->Release(); // f_draw->Release(); // f_drawDbg->Release(); sv_timeout->Release(); cl_timeout->Release(); cl_loadtimeout->Release(); g_LevelName->Release(); g_GameType->Release(); g_LeftHanded->Release(); p_DeadBody->Release(); p_HitImpulse->Release(); p_RotateHead->Release(); a_DrawArea->Release(); a_LogArea->Release(); m_pCVarCheatMode->Release(); pl_JumpNegativeImpulse->Release(); if (m_pRenderer && (m_nPlayerIconTexId>=0)) m_pRenderer->RemoveTexture(m_nPlayerIconTexId); if (m_pRenderer && (m_nVehicleIconTexId>=0)) m_pRenderer->RemoveTexture(m_nVehicleIconTexId); if (m_pRenderer && (m_nBuildingIconTexId>=0)) m_pRenderer->RemoveTexture(m_nBuildingIconTexId); if (m_pRenderer && (m_nUnknownIconTexId>=0)) m_pRenderer->RemoveTexture(m_nUnknownIconTexId); SAFE_DELETE(m_pUIHud); SAFE_DELETE(m_pWeaponSystemEx); SAFE_DELETE(m_pVehicleSystem); SAFE_DELETE(m_pPlayerSystem); SAFE_DELETE(m_pFlockManager); CScriptObjectPlayer::ReleaseTemplate(); //shutdown script stuff SAFE_DELETE(m_pScriptObjectGame); SAFE_DELETE(m_pScriptObjectInput); SAFE_DELETE(m_pScriptObjectBoids); SAFE_DELETE(m_pScriptObjectLanguage); SAFE_DELETE(m_pScriptObjectAI); // Release the action map SAFE_RELEASE(m_pIActionMapManager); SAFE_DELETE(m_pScriptTimerMgr); // release the tags if (!m_mapTagPoints.empty()) { TagPointMap::iterator ti; for (ti=m_mapTagPoints.begin();ti!=m_mapTagPoints.end();ti++) delete ti->second; } SAFE_RELEASE(m_pServerSnooper); SAFE_RELEASE(m_pNETServerSnooper); SAFE_RELEASE(m_pRConSystem); SAFE_DELETE(m_pTimeDemoRecorder); SAFE_DELETE(m_pGameMods); delete m_pTagPointManager; } ////////////////////////////////////////////////////////////////////////// bool CXGame::InitClassRegistry() { m_EntityClassRegistry.Init( m_pSystem ); CPlayerSystem *pPlayerSystem = GetPlayerSystem(); CVehicleSystem *pVehicleSystem = GetVehicleSystem(); CWeaponSystemEx *pWeaponSystemEx = GetWeaponSystemEx(); // m10 assert( pPlayerSystem ); assert( pVehicleSystem ); assert( pWeaponSystemEx ); // Enumerate entity classes. EntityClass *entCls = NULL; m_EntityClassRegistry.MoveFirst(); do { entCls = m_EntityClassRegistry.Next(); if (entCls) { const char* entity_type = entCls->strGameType.c_str(); EntityClassId ClassId = entCls->ClassId; if(strcmp("Player",entity_type)==0) pPlayerSystem->AddPlayerClass(ClassId); if(strcmp("Vehicle",entity_type)==0) pVehicleSystem->AddVehicleClass(ClassId); if(strcmp("Projectile",entity_type)==0) { // cannot be loaded at that point - other scripts must be loaded before pWeaponSystemEx->AddProjectileClass(ClassId); } } } while (entCls); return true; } ////////////////////////////////////////////////////////////////////////// void CXGame::SoftReset() { m_pLog->Log("Soft Reset Begin"); //allow to reload scripts with(LoadScript) m_pScriptSystem->SetGlobalToNull("_localplayer"); if(m_pScriptSystem) m_pScriptSystem->UnloadScripts(); std::vector vLoadedWeapons; for (int i = 0; i != m_pWeaponSystemEx->GetNumWeaponClasses(); ++i) vLoadedWeapons.push_back(m_pWeaponSystemEx->GetWeaponClass(i)->GetName()); m_pWeaponSystemEx->Reset(); #if !defined(LINUX) if (m_pSystem->GetIMovieSystem()) m_pSystem->GetIMovieSystem()->StopAllSequences(); #endif m_pScriptObjectGame->Reset(); m_pScriptSystem->ForceGarbageCollection(); //m_p3DEngine->ClearRenderResources(); m_iLastCmdIdx = 0; m_pWeaponSystemEx->Init(this); for (std::vector::iterator i = vLoadedWeapons.begin(); i != vLoadedWeapons.end(); ++i) AddWeapon((*i).c_str()); //if (GetMyPlayer()) // GetMyPlayer()->SetNeedUpdate(true); if (m_pCurrentUI) { m_pCurrentUI->Reset(); m_pCurrentUI->Init(m_pScriptSystem); } m_pLog->Log("Soft Reset End"); } ////////////////////////////////////////////////////////////////////// //!reset the game before a level reloading //!this function allow the reloading of all scripts //!and wipe out all textures from the 3dengine void CXGame::Reset() { m_pEntitySystem->Reset(); // Unload all music. if (m_pSystem->GetIMusicSystem()) m_pSystem->GetIMusicSystem()->Unload(); //allow to reload scripts with(LoadScript) m_pScriptSystem->SetGlobalToNull("_localplayer"); if(m_pScriptSystem) m_pScriptSystem->UnloadScripts(); m_pWeaponSystemEx->Reset(); m_XSurfaceMgr.Reset(); m_XAreaMgr.Clear(); ClearTagPoints(); #if !defined(LINUX) if (m_pSystem->GetIMovieSystem()) m_pSystem->GetIMovieSystem()->Reset(false); #endif m_pScriptObjectGame->Reset(); m_pScriptSystem->ForceGarbageCollection(); m_p3DEngine->ClearRenderResources(); // Must reset all timers. m_pScriptTimerMgr->Reset(); //clen up the input buffer if (m_pSystem->GetIInput()) { m_pSystem->GetIInput()->Update(true); m_pSystem->GetIInput()->Update(true); } if (m_pIActionMapManager) m_pIActionMapManager->Reset(); m_iLastCmdIdx = 0; ////////////////////////////////////////////////////////////////////////// // Reset UI. ////////////////////////////////////////////////////////////////////////// if (m_pUISystem) { m_pUISystem->UnloadAllModels(); m_pUISystem->StopAllVideo(); m_p3DEngine->Enable(1); //m_pSystem->GetILog()->Log("UISystem: Enabled 3D Engine!"); } if (m_pCurrentUI) m_pCurrentUI->Reset(); if (m_pUIHud) m_pUIHud->Reset(); if (GetMyPlayer()) GetMyPlayer()->SetNeedUpdate(true); } IXSystem *CXGame::GetXSystem(){return m_pServer?m_pServer->m_pISystem:m_pClient?m_pClient->m_pISystem:NULL;} ////////////////////////////////////////////////////////////////////// //! Initialize the game. This must be called before calling other functions of this class. bool CXGame::Init(struct ISystem *pSystem,bool bDedicatedSrv,bool bInEditor,const char *szGameMod) { // Setup the system and 3D Engine pointers m_pSystem = pSystem; m_pGameMods = new CGameMods(this); gISystem = pSystem; m_bDedicatedServer=bDedicatedSrv; m_XAreaMgr.Init( pSystem ); m_bEditor=bInEditor; m_bRelaunch=false; m_bMovieSystemPaused = false; m_bIsLoadingLevelFromFile=false; m_bOK = false; m_bUpdateRet = true; m_pClient = NULL; m_pServer = NULL; m_pSystem->GetILog()->Log("Game Initialization"); #if !defined(LINUX) IMovieSystem *pMovieSystem=m_pSystem->GetIMovieSystem(); if (pMovieSystem) pMovieSystem->SetUser(m_pMovieUser); #endif if (!m_pTimeDemoRecorder) m_pTimeDemoRecorder = new CTimeDemoRecorder(pSystem); m_pUIHud = NULL; m_pNetwork= m_pSystem->GetINetwork(); m_pLog= m_pSystem->GetILog(); m_p3DEngine = m_pSystem->GetI3DEngine(); m_pRenderer = m_pSystem->GetIRenderer(); m_pScriptSystem=pSystem->GetIScriptSystem(); m_pEntitySystem=m_pSystem->GetIEntitySystem(); // Register game rendering callback. //[Timur] m_p3DEngine->SetRenderCallback( OnRenderCallback,this ); // init subsystems #ifndef _XBOX m_pServerSnooper=m_pNetwork->CreateServerSnooper(this); m_pNETServerSnooper=m_pNetwork->CreateNETServerSnooper(this); m_pRConSystem=m_pNetwork->CreateRConSystem(); #endif m_pWeaponSystemEx = new CWeaponSystemEx(); m_pVehicleSystem = new CVehicleSystem(); m_pPlayerSystem = new CPlayerSystem(); m_pFlockManager = new CFlockManager(m_pSystem); CScriptObjectUI::InitializeTemplate(m_pScriptSystem); // init is not necessary for now, but add here if it later is m_pScriptObjectGame=new CScriptObjectGame; CScriptObjectGame::InitializeTemplate(m_pScriptSystem); m_pScriptObjectInput=new CScriptObjectInput; CScriptObjectInput::InitializeTemplate(m_pScriptSystem); m_pScriptObjectLanguage=new CScriptObjectLanguage; CScriptObjectLanguage::InitializeTemplate(m_pScriptSystem); m_pScriptObjectBoids = new CScriptObjectBoids; CScriptObjectBoids::InitializeTemplate(m_pScriptSystem); m_pScriptObjectAI = new CScriptObjectAI; CScriptObjectAI::InitializeTemplate(m_pScriptSystem); CScriptObjectServer::InitializeTemplate(m_pScriptSystem); CScriptObjectPlayer::InitializeTemplate(m_pScriptSystem); CScriptObjectFireParam::InitializeTemplate(m_pScriptSystem); CScriptObjectWeaponClass::InitializeTemplate(m_pScriptSystem); CScriptObjectVehicle::InitializeTemplate(m_pScriptSystem); CScriptObjectSpectator::InitializeTemplate(m_pScriptSystem); CScriptObjectAdvCamSystem::InitializeTemplate(m_pScriptSystem); CScriptObjectSynched2DTable::InitializeTemplate(m_pScriptSystem); CScriptObjectRenderer::InitializeTemplate(m_pScriptSystem); m_pScriptObjectGame->Init(m_pScriptSystem, this); m_pScriptObjectInput->Init(m_pScriptSystem,this,m_pSystem); m_pScriptObjectBoids->Init(m_pScriptSystem,m_pSystem,m_pFlockManager); m_pScriptObjectLanguage->Init(m_pScriptSystem,&m_StringTableMgr); m_pScriptObjectAI->Init(m_pScriptSystem,m_pSystem,this); CScriptObjectServerSlot::InitializeTemplate(m_pScriptSystem); CScriptObjectClient::InitializeTemplate(m_pScriptSystem); CScriptObjectStream::InitializeTemplate(m_pScriptSystem); m_pScriptTimerMgr=new CScriptTimerMgr(m_pScriptSystem,m_pSystem->GetIEntitySystem(),this); // making some constants accessable to the script m_pScriptSystem->SetGlobalValue("FireActivation_OnPress",ePressing); m_pScriptSystem->SetGlobalValue("FireActivation_OnRelease",eReleasing); m_pScriptSystem->SetGlobalValue("FireActivation_OnHold",eHolding); m_pScriptSystem->SetGlobalValue("ENTITYTYPE_PLAYER", ENTITYTYPE_PLAYER); m_pScriptSystem->SetGlobalValue("ENTITYTYPE_WAYPOINT", ENTITYTYPE_WAYPOINT); m_pScriptSystem->SetGlobalValue("ENTITYTYPE_OWNTEAM", ENTITYTYPE_OWNTEAM); /* m_pScriptSystem->SetGlobalValue("CMD_GO", CMD_GO); m_pScriptSystem->SetGlobalValue("CMD_ATTACK", CMD_ATTACK); m_pScriptSystem->SetGlobalValue("CMD_DEFEND", CMD_DEFEND); m_pScriptSystem->SetGlobalValue("CMD_COVER", CMD_COVER); m_pScriptSystem->SetGlobalValue("CMD_BARRAGEFIRE", CMD_BARRAGEFIRE);*/ InitConsoleVars(); if (szGameMod && szGameMod[0]) { // apply the mod without restarting as the game just started! GetModsInterface()->SetCurrentMod(szGameMod,false); } InitClassRegistry(); // execute the "main"-script (to pre-load other scripts, etc.) m_pScriptSystem->ExecuteFile("scripts/main.lua"); m_pScriptSystem->BeginCall("Init"); m_pScriptSystem->PushFuncParam(0); m_pScriptSystem->EndCall(); // initialize the surface-manager m_XSurfaceMgr.Init(m_pScriptSystem,m_p3DEngine,GetSystem()->GetIPhysicalWorld()); // init key-bindings if(!m_bDedicatedServer) InitInputMap(); // create various console-commands/variables InitConsoleCommands(); // loading the main language-string-table if (!m_StringTableMgr.Load(GetSystem(),*m_pScriptObjectLanguage,g_language->GetString())) m_pLog->Log("cannot load language file [%s]",g_language->GetString()); // creating HUD interface m_pLog->Log("Initializing UI"); m_pUIHud = new CUIHud(this,m_pSystem); LoadConfiguration("","game.cfg"); ////////////////////////////////////////////////////////////////////////// // Materials // load materials (once before all, this info stays till we quit the game - no need to load material later) // first load normal materials m_XSurfaceMgr.LoadMaterials("scripts/materials"); if(!m_bDedicatedServer) { m_pSystem->GetIConsole()->ShowConsole(0); if (!bInEditor) { //------------------------------------------------------------------------------------------------- m_pUISystem = new CUISystem; if (m_pUISystem) { m_pUISystem->Create(this, m_pSystem, m_pScriptSystem, "Scripts/MenuScreens/UISystem.lua", 1); } else { m_pLog->Log("Failed to create UI System!"); } //------------------------------------------------------------------------------------------------- } //------------------------------------------------------------------------------------------------- if (m_pUISystem) { m_bMenuOverlay = 1; } //------------------------------------------------------------------------------------------------- } else m_pSystem->GetIConsole()->ShowConsole(true); // load textures used as icons by the mini-map if (m_pRenderer) { ITexPic *pPic; pPic=m_pRenderer->EF_LoadTexture("gui/map_player", FT_NOREMOVE, 0, eTT_Base); if (pPic && pPic->IsTextureLoaded()) m_nPlayerIconTexId=pPic->GetTextureID(); pPic=m_pRenderer->EF_LoadTexture("gui/map_vehicle", FT_NOREMOVE, 0, eTT_Base); if (pPic && pPic->IsTextureLoaded()) m_nVehicleIconTexId=pPic->GetTextureID(); pPic=m_pRenderer->EF_LoadTexture("gui/map_building", FT_NOREMOVE, 0, eTT_Base); if (pPic && pPic->IsTextureLoaded()) m_nBuildingIconTexId=pPic->GetTextureID(); pPic=m_pRenderer->EF_LoadTexture("gui/map_unknown", FT_NOREMOVE, 0, eTT_Base); if (pPic && pPic->IsTextureLoaded()) m_nUnknownIconTexId=pPic->GetTextureID(); } if(!bInEditor) m_pEntitySystem->SetDynamicEntityIdMode(true); #if !defined(_XBOX) && !defined(PS2) && !defined(LINUX) SetCursor(NULL); #endif ////////////////////////////////////////////////////////////////////////// DevModeInit(); m_bOK = true; e_deformable_terrain = NULL; return (true); } ////////////////////////////////////////////////////////////////////// //! game-mainloop bool CXGame::Run(bool &bRelaunch) { //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF); if(m_bDedicatedServer) { return Update(); } else { //static float fLastFrame=0; m_bRelaunch=false; while(1) { if (!Update()) break; } bRelaunch=m_bRelaunch; } return true; } #if !defined(_XBOX) && !defined(PS2) && !defined(LINUX) #include #include ".\game.h" #pragma comment (lib , "Winmm.lib") #else #define GetCurrentTime() ((unsigned int)(GetSystem()->GetITimer()->GetCurrTime() * 1000.f)) #endif ////////////////////////////////////////////////////////////////////////// bool CXGame::IsInPause(IProcess *pProcess) { bool bPause = (m_bMenuOverlay && (!IsMultiplayer())); //check if the game is in pause or in menu mode if ((pProcess->GetFlags() & PROC_MENU) && !IsMultiplayer()) bPause=true; return (bPause); } ////////////////////////////////////////////////////////////////////// //! update all game and children bool CXGame::Update() { if (!m_nDEBUG_TIMING) { m_fDEBUG_STARTTIMER = m_pSystem->GetITimer()->GetAsyncCurTime(); m_nDEBUG_TIMING = 1; } if (!m_bEditor) { if (!m_bMenuOverlay || !m_pUISystem || m_pUISystem->GetScriptObjectUI()->CanRenderGame()) { m_p3DEngine->Enable(1); } else { m_p3DEngine->Enable(0); } } bool bRenderFrame = (!m_pSystem->GetViewCamera().GetPos().IsZero() || m_bMenuOverlay || m_bUIOverlay) && g_Render->GetIVal() != 0; ////////////////////////////////////////////////////////////////////////// // Start Profiling frame m_pSystem->GetIProfileSystem()->StartFrame(); ////////////////////////////////////////////////////////////////////////// FUNCTION_PROFILER( m_pSystem,PROFILE_GAME ); ITimer *pTimer=m_pSystem->GetITimer(); pTimer->MeasureTime("EnterGameUp"); //Timur[10/2/2002] // Cannot Run Without System. assert( m_pSystem ); float maxFPS=g_maxfps->GetFVal(); if(maxFPS>0) { // float extraTime = pTimer->GetAsyncCurTime() + 1.0f/maxFPS - pTimer->GetFrameTime(); // while(extraTime - pTimer->GetAsyncCurTime() > 0) // ; DWORD extraTime = (DWORD)((1.0f/maxFPS - pTimer->GetFrameTime())*1000.0f); #if !defined(LINUX) if(extraTime>0&&extraTime<300)//thread sleep not process sleep Sleep(extraTime); #endif } PhysicsVars *pVars = m_pSystem->GetIPhysicalWorld()->GetPhysVars(); float fTimeGran=pVars->timeGranularity, fFixedStep=g_MP_fixed_timestep->GetFVal(); if (fTimeGran!=m_fTimeGran || fFixedStep!=m_fFixedStep) { m_fTimeGran = fTimeGran; m_fFixedStep = fFixedStep; if (fFixedStep>0) { m_fTimeGran2FixedStep = fTimeGran/fFixedStep; m_iFixedStep2TimeGran = (int)(fFixedStep/fTimeGran+0.5f); m_frFixedStep = 1.0f/fFixedStep; } else m_iFixedStep2TimeGran = 0; m_frTimeGran = 1.0f/fTimeGran; } pVars->bMultiplayer = IsMultiplayer() ? 1:0; //check what is the current process //bool bPause=false; IProcess *pProcess=m_pSystem->GetIProcess(); if (!pProcess) return false; bool bPause=IsInPause(pProcess); if (m_bIsLoadingLevelFromFile) bPause=false; #if !defined(LINUX) // Pauses or unpauses movie system. if (bPause != m_bMovieSystemPaused) { m_bMovieSystemPaused = bPause; if (bPause) m_pSystem->GetIMovieSystem()->Pause(); else m_pSystem->GetIMovieSystem()->Resume(); } #endif // [marco] check current sound and vis areas // for music etc. CheckSoundVisAreas(); //int nStartGC=m_pScriptSystem->GetCGCount(); pTimer->MeasureTime("SomeStuff"); // update system int nPauseMode=0; if (bPause) nPauseMode=1; // TODO: Add pause mode for a cutscene currently playing (pausemode 2) if (IsMultiplayer()) { pe_params_flags pf; pf.flagsOR = pef_update; for(ListOfPlayers::iterator pl=m_DeadPlayers.begin(); pl!=m_DeadPlayers.end(); pl++) if ((*pl)->GetEntity() && (*pl)->GetEntity()->GetPhysics()) (*pl)->GetEntity()->GetPhysics()->SetParams(&pf); } if (!m_pSystem->Update(IsMultiplayer() ? ESYSUPDATE_MULTIPLAYER:0, nPauseMode)) //Update returns false when quitting return (false); if (IsMultiplayer()) { pe_params_flags pf; pf.flagsAND = ~pef_update; for(ListOfPlayers::iterator pl=m_DeadPlayers.begin(); pl!=m_DeadPlayers.end(); pl++) if ((*pl)->GetEntity() && (*pl)->GetEntity()->GetPhysics()) (*pl)->GetEntity()->GetPhysics()->SetParams(&pf); } pTimer->MeasureTime("SysUpdate"); // [marco] after system update, retrigger areas if necessary if (!bPause) RetriggerAreas(); if (!bPause || (m_pClient && !m_pClient->IsConnected())) { // network start FRAME_PROFILER( "GameUpdate:Client",m_pSystem,PROFILE_GAME ); // update client if (m_pClient) { m_pClient->UpdateClientNetwork(); pTimer->MeasureTime("Net"); assert(m_pClient); m_pClient->Update(); if(m_pClient->DestructIfMarked()) // to make sure the client is only released in one place - here m_pClient=0; } pTimer->MeasureTime("ClServ Up"); ////////UPDATE THE NETWORK // [Anton] moved from after the rendering, so that the server has access to the most recent physics data // update server if (m_pServer) { FRAME_PROFILER( "GameUpdate:Server",m_pSystem,PROFILE_GAME ); m_pServer->Update(); } pTimer->MeasureTime("EndServUp"); } m_pNetwork->UpdateNetwork(); // used to update things like the UBI.com services DWORD dwCurrentTimeInMS=GetCurrentTime(); if (!m_pSystem->IsDedicated()) { if(m_pServerSnooper) m_pServerSnooper->Update(dwCurrentTimeInMS); if(m_pNETServerSnooper) m_pNETServerSnooper->Update(dwCurrentTimeInMS); } if(m_pRConSystem) { if (m_pClient) m_pRConSystem->Update( dwCurrentTimeInMS,m_pClient->GetNetworkClient() ); else m_pRConSystem->Update(dwCurrentTimeInMS); } // network end // system rendering if (bRenderFrame) { // render begin must be always called anyway to clear buffer, draw buttons etc. // even in menu mode m_pSystem->RenderBegin(); m_pSystem->Render(); pTimer->MeasureTime("3SysRend"); } // update the HUD if (m_pCurrentUI && !bPause && m_pClient && m_pClient->m_bDisplayHud) { FRAME_PROFILER( "GameUpdate:HUD",m_pSystem,PROFILE_GAME ); // update hud itself if(!m_pCurrentUI->Update()) m_bUpdateRet = false; // update ingame-dialog-manager if (m_pIngameDialogMgr) m_pIngameDialogMgr->Update(); pTimer->MeasureTime("HUD Up"); } if (m_pUISystem && m_pUISystem->IsEnabled()) { FRAME_PROFILER("GameUpdate:UI", m_pSystem, PROFILE_GAME); if (m_bMenuOverlay || m_bUIOverlay) { m_pUISystem->Update(); m_pUISystem->Draw(); } } if(a_DrawArea->GetIVal()) { m_XAreaMgr.DrawAreas( m_pSystem ); pTimer->MeasureTime("XAreaDraw"); } // print time profiling results #ifndef PS2 pTimer->MeasureTime((const char*)-1); #else pTimer->MeasureTime("Time"); #endif pTimer->MeasureTime("3TimeProf"); //NETWORK DEBUGGING if(m_pClient && m_pClient->cl_netstats->GetIVal()!=0) { m_pClient->DrawNetStats(); } if(m_pServer && m_pServer->sv_netstats->GetIVal()!=0) { m_pServer->DrawNetStats(m_pRenderer); } pTimer->MeasureTime("NetStats"); // end of frame if (bRenderFrame) { // same thing as for render begin if (m_pTimeDemoRecorder) m_pTimeDemoRecorder->RenderInfo(); m_pSystem->RenderEnd(); } pTimer->MeasureTime("3Rend Up"); // get messages from process //char *szProcessMessage = m_pSystem->GetIProcess()->GetPMessage(); // process messages from process { if (m_fFadingStartTime>0) { if (((m_pSystem->GetITimer()->GetCurrTime())-m_fFadingStartTime)>1.5f) { m_fFadingStartTime=-1; SendMessage(m_szLoadMsg); } } while(!m_qMessages.empty()) { string smsg=m_qMessages.front(); m_qMessages.pop(); ProcessPMessages(smsg.c_str()); } // the messages can switch the game to menu or viceversa bPause=IsInPause(pProcess); } //update script timers if(m_pScriptTimerMgr) m_pScriptTimerMgr->Update( (unsigned long)(pTimer->GetCurrTime()*1000) ); pTimer->MeasureTime("ScrTimerUp"); if(g_GC_Frequence->GetFVal()>0) { // Change Script Garbage collection frequency. m_pSystem->SetGCFrequency(g_GC_Frequence->GetFVal()); } ////////////////////////////////////////////////////////////////////////// // Special update function for developers mode. ////////////////////////////////////////////////////////////////////////// if (IsDevModeEnable()) DevModeUpdate(); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// pTimer->MeasureTime("EndGameUp"); ////////////////////////////////////////////////////////////////////////// // End Profiling Frame m_pSystem->GetIProfileSystem()->EndFrame(); ////////////////////////////////////////////////////////////////////////// return (m_bUpdateRet); } void CXGame::UpdateDuringLoading() { /* // to find areas where the function should be called more often { static DWORD dwTime=GetTickCount(); DWORD dwNewTime=GetTickCount(); DWORD dwRelative = dwNewTime-dwTime; if(dwRelative>1000) m_pSystem->GetILog()->Log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> UpdateDuringLoading %d",dwRelative); else m_pSystem->GetILog()->Log("UpdateDuringLoading %d",dwRelative); dwTime=dwNewTime; } */ if(m_pServer) m_pServer->UpdateXServerNetwork(); } ////////////////////////////////////////////////////////////////////////// bool CXGame::ParseLevelName(const char *szMsg,char *szLevelName,char *szMissionName) { const char *szPtr=szMsg; char *szDest; // get level & mission-name szPtr=szMsg+11; //skip "StartLevel " //find the level name memset(szLevelName,0,32); szDest=szLevelName; while ((*szPtr) && (*szPtr!=' ')) *szDest++=*szPtr++; //find the mission name memset(szMissionName,0,32); if (*szPtr) //if not eos { szPtr++; //skip space szDest=szMissionName; while (*szPtr) *szDest++=*szPtr++; } return (true); } ////////////////////////////////////////////////////////////////////// //Process the process messages //it is needed for example to perform actions that must be done //the next frame void CXGame::ProcessPMessages(const char *szMsg) { if (!szMsg) return; if ((stricmp(szMsg,"EndDemo") == 0) || (stricmp(szMsg,"EndDemoQuit") == 0)) // used for demos (e3, magazine demos) { ITexPic * pPic = m_pRenderer->EF_LoadTexture("Textures/end_screen.dds", FT_NORESIZE, 0, eTT_Base); int img = -1; if (pPic) { img = pPic->GetTextureID(); } GetSystem()->GetIRenderer()->BeginFrame(); //GetSystem()->GetIRenderer()->Draw2dImage(0,0,(float)(GetSystem()->GetIRenderer()->GetWidth()),(float)(GetSystem()->GetIRenderer()->GetHeight()),img,0,1.0f,1.0f,0); // hack! hardcoded to fix the incorrect d3d9 renderer matrix GetSystem()->GetIRenderer()->SetState(GS_NODEPTHTEST); GetSystem()->GetIRenderer()->Draw2dImage(0,0,(float)(800),(float)(600),img,0,1.0f,1.0f,0); GetSystem()->GetIRenderer()->Update(); float time = GetSystem()->GetITimer()->GetCurrTime(); // wait a bit and then quit the game while((GetSystem()->GetITimer()->GetCurrTime()-time) < 7) { GetSystem()->GetITimer()->Update(); } if (stricmp(szMsg,"EndDemoQuit") == 0) { m_bUpdateRet = false; } else { this->SendMessage("Switch"); } return; } else if (stricmp(szMsg,"Quit-Yes") == 0) // quit message { m_bUpdateRet = false; return; } else if (stricmp(szMsg,"Relaunch") == 0) // relaunch message { m_bRelaunch = true; m_bUpdateRet = false; return; } else if (stricmp(szMsg,"Switch")==0) // switch process (menu <> game) { //clear the current message // ::OutputDebugString("###############switch#############\n"); //m_pSystem->GetIProcess()->SetPMessage(""); if(m_bEditor) return; // we are probably in the editor? if (m_bMenuOverlay) // we're in menu-mode; switch to game { //check if a game is currently running before switching to //the 3d-engine CPlayer *pPlayer = 0; if (GetMyPlayer()) { GetMyPlayer()->GetContainer()->QueryContainerInterface(CIT_IPLAYER,(void **)&pPlayer); } // there must be a client for us to be able to go out of the menu // if this is a singleplayer game, and the player is alive, we can go back to game // otherwise, if this is not multiplayer game and the player is dead, it is locked in the menu // also, the client must not be loading, or waiting to connect if (m_pClient && m_pClient->IsConnected() && m_pUISystem->GetScriptObjectUI()->CanSwitch(0)) { if (IsMultiplayer() || (!pPlayer || pPlayer->m_stats.health > 0)) { MenuOff(); } } } else if (m_pUISystem->GetScriptObjectUI()->CanSwitch(1)) { // ::OutputDebugString("->menu\n"); // quit if menu disabled (usefull during development) ICVar * pCvarNoMenu = m_pSystem->GetIConsole()->CreateVariable("g_NoMenu","0",0); if(pCvarNoMenu && pCvarNoMenu->GetIVal()) { m_pSystem->Quit(); return; } MenuOn(); } } else if (stricmp(szMsg, "EndCutScene")==0) { if (m_bMenuOverlay) // we're in menu-mode; switch to game { if (m_pClient) { MenuOff(); } else if(!IsMultiplayer()) { // there's no game, so lets quit... // exit from game-must be prompted with "Are you Sure?" m_pSystem->Quit(); } } } else if (stricmp(szMsg,"LoadLastCheckPoint")==0) { // the loading funciotn calls game->update 20 times(??) // and the script menu system allows to click the reload // button again during game->update, so be sure that the game isn't // loading already if (!m_bIsLoadingLevelFromFile) { LoadLatest(); } } else if (strnicmp(szMsg,"StartLevelFade",14)==0) // start a level with fade out { if (!m_bEditor) { ICVar *g_LevelStated = GetISystem()->GetIConsole()->GetCVar("g_LevelStated"); if (g_LevelStated && g_LevelStated->GetIVal() && m_pClient && m_pClient->IsConnected()) { HSCRIPTFUNCTION pfnDisplayLevelStats = m_pScriptSystem->GetFunctionPtr("Game", "DisplayTimeZone"); if (pfnDisplayLevelStats) { m_pScriptSystem->BeginCall(pfnDisplayLevelStats); m_pScriptSystem->PushFuncParam(GetScriptObject()); m_pScriptSystem->EndCall(); m_pScriptSystem->ReleaseFunc(pfnDisplayLevelStats); } } else { m_p3DEngine->ResetScreenFx(); m_p3DEngine->SetScreenFx("ScreenFade",1); float fFadeTime=1.5f; m_p3DEngine->SetScreenFxParam("ScreenFade","ScreenFadeTime", &fFadeTime); m_fFadingStartTime=m_pSystem->GetITimer()->GetCurrTime(); AllowQuicksave(false); sprintf(m_szLoadMsg,"StartLevel%s",szMsg+14); // skip levelfade // disable input handling during fading to load m_pSystem->GetIInput()->EnableEventPosting(0); } } else m_pSystem->GetILog()->Log("Skipping Load Level in editor (%s)",szMsg); } else if (strnicmp(szMsg,"StartLevel",10)==0) // start a level { if (!m_bEditor) { ICVar *g_LevelStated = GetISystem()->GetIConsole()->GetCVar("g_LevelStated"); if (g_LevelStated && g_LevelStated->GetIVal() && m_pClient && m_pClient->IsConnected()) { HSCRIPTFUNCTION pfnDisplayLevelStats = m_pScriptSystem->GetFunctionPtr("Game", "DisplayTimeZone"); if (pfnDisplayLevelStats) { m_pScriptSystem->BeginCall(pfnDisplayLevelStats); m_pScriptSystem->PushFuncParam(GetScriptObject()); m_pScriptSystem->EndCall(); m_pScriptSystem->ReleaseFunc(pfnDisplayLevelStats); } } else { char szLevelName[32]; char szMissionName[32]; m_p3DEngine->ResetScreenFx(); // always disable cryvision at start m_p3DEngine->SetScreenFx("NightVision",0); // reset fading in case someone will load a level // while the current one is fading out m_fFadingStartTime=-1; m_p3DEngine->SetScreenFx("ScreenFade",0); ParseLevelName(szMsg,szLevelName,szMissionName); bool listen = false; if (strcmp(szMissionName, "listen")==0) { szMissionName[0] = 0; //strcpy( szMissionName,"" ); listen = true; }; // disable input handling during load m_pSystem->GetIInput()->EnableEventPosting(0); m_pSystem->GetIInput()->GetIKeyboard()->ClearKeyState(); LoadLevelCS(false, szLevelName, szMissionName, listen); // finished loading, reenable input handling m_pSystem->GetIInput()->EnableEventPosting(1); m_pSystem->GetIInput()->GetIKeyboard()->ClearKeyState(); } } else m_pSystem->GetILog()->Log("Skipping Load Level in editor (%s)",szMsg); } else if (strnicmp(szMsg,"SaveGame", 8)==0) // save current game { if(!m_bEditor) { //clear the current message // m_pSystem->GetIProcess()->SetPMessage(""); const char *sname="quicksave"; if(strlen(szMsg)>8) { sname=szMsg+9; } Save(sname, NULL, NULL); } } else if (strnicmp(szMsg,"LoadGame", 8)==0) // load game { if(!m_bEditor) { m_p3DEngine->ResetScreenFx(); //clear the current message // m_pSystem->GetIProcess()->SetPMessage(""); const char *sname="quicksave"; if(strlen(szMsg)>8) { sname=szMsg+9; } // disable input handling during load m_pSystem->GetIInput()->EnableEventPosting(0); //m_pSystem->GetIInput()->GetIKeyboard()->ClearKeyState(); // get out of all the areas localplayer is in - on load it will be retrigererd IEntity *pIMyPlayer = GetMyPlayer(); if( pIMyPlayer ) { IEntityContainer *pIContainer = pIMyPlayer->GetContainer(); if (pIContainer) { CPlayer *pPlayer = NULL; if (pIContainer->QueryContainerInterface(CIT_IPLAYER, (void**)&pPlayer)) m_XAreaMgr.ExitAllAreas( pPlayer->m_AreaUser ); } } if (Load(sname)) { //if loaded successfull, switch to 3d engine if(m_pClient) { m_pSystem->SetIProcess(m_p3DEngine); m_pSystem->GetIProcess()->SetFlags(PROC_3DENGINE); } } // finished loading, reenable input m_pSystem->GetIInput()->EnableEventPosting(1); //m_pSystem->GetIInput()->GetIKeyboard()->ClearKeyState(); } } // else // if (stricmp(szMsg,"ConnectTo")==0) // { // } } ////////////////////////////////////////////////////////////////////////// /*! Load a level on the local machine (connecting with a local client) @param dedicated if true the local client will not be created @param keepclient if true the current client server connection will be kept @param szMapName name of the level that has to be loaded @param szMissionName name of the mission that has to be loaded @param listen allow external clients to connect */ ////////////////////////////////////////////////////////////////////////// void CXGame::LoadLevelCS(bool keepclient, const char *szMapName, const char *szMissionName, bool listen) { // need to reset timers as well m_pScriptTimerMgr->Reset(); if (m_pUISystem) { m_pUISystem->GetScriptObjectUI()->OnSwitch(0); m_pUISystem->StopAllVideo(); m_p3DEngine->Enable(1); m_pSystem->GetILog()->Log("UISystem: Enabled 3D Engine!"); } #if !defined(LINUX) if (m_pSystem->GetIMovieSystem()) m_pSystem->GetIMovieSystem()->StopAllCutScenes(); //m_lstPlayedCutScenes.clear(); #endif bool bDedicated=GetSystem()->IsDedicated(); string strGameType = g_GameType->GetString(); AutoSuspendTimeQuota AutoSuspender(GetSystem()->GetStreamEngine()); assert( szMissionName != 0 ); string sLevelFolder = szMapName; if (sLevelFolder.find('\\') == string::npos && sLevelFolder.find('/') == string::npos) { // This is just a map name, not a folder. sLevelFolder = GetLevelsFolder() + "/" + sLevelFolder; } IConsole *pConsole=GetSystem()->GetIConsole(); IInput *pInput=GetSystem()->GetIInput(); // might be 0 (e.g. dedicated server) if(pInput) pInput->SetMouseExclusive(false); //if(!*szMissionName) szMissionName = "Multiplayer"; if (!IsMultiplayer()) { m_pSystem->GetIConsole()->Clear(); m_pSystem->GetIConsole()->SetScrollMax(600); m_pSystem->GetIConsole()->ShowConsole(true); string sLoadingScreenTexture = string("levels/") + string(szMapName) + string("/loadscreen_") + string(szMapName) + ".dds"; m_pSystem->GetIConsole()->SetLoadingImage(sLoadingScreenTexture.c_str()); m_pSystem->GetIConsole()->ResetProgressBar(0x7fffffff); m_pSystem->GetILog()->UpdateLoadingScreen(""); // just to draw the console } if (m_pClient && !keepclient) { ShutdownClient(); } // start server if((!m_pServer || !keepclient) && !StartupServer(listen)) { m_pLog->LogToConsole("Unable to load the level %s,%s [startup server failed]", sLevelFolder.c_str(),szMissionName); if(pInput) pInput->SetMouseExclusive(true); LoadingError("@LoadLevelError"); return; } bool bNeedClient = !bDedicated && ((keepclient && !m_pClient) || !keepclient); //create local client(must be before the level is loaded) if(bNeedClient) { if(!StartupLocalClient()) { m_pLog->LogToConsole("Unable to load the level %s,mission %s [startup client failed]", sLevelFolder.c_str(),szMissionName); if(pInput) pInput->SetMouseExclusive(true); LoadingError("@LoadLevelError"); return; } } const char *szMission = szMissionName; if (!*szMissionName) szMission=strGameType.c_str(); // KIRILL lets reset - they will be spawned anyway m_pSystem->GetAISystem()->Reset(); // refresh the current server info for incoming queries during loading m_pServer->GetServerInfo(); // load the level if(!m_pServer->m_pISystem->LoadLevel( sLevelFolder.c_str(),szMission,false)) { m_pLog->LogToConsole("Unable to load the level %s,mission %s \n", sLevelFolder.c_str(),szMissionName); if (pInput) pInput->SetMouseExclusive(true); LoadingError("@LoadLevelError"); return; } // start and connect a local client if(bNeedClient) { if(m_pClient) { if (IsMultiplayer() && m_pServer->m_pIServer->GetServerType()!=eMPST_LAN) m_pClient->XConnect("127.0.0.1",false,true); else m_pClient->XConnect("127.0.0.1"); } } if(m_pClient) m_pClient->OnMapChanged(); if(m_pServer) m_pServer->OnMapChanged(); if(pInput) pInput->SetMouseExclusive(true); AllowQuicksave(true); }; ////////////////////////////////////////////////////////////////////////// bool CXGame::GetLevelMissions( const char *szLevelDir,std::vector &missions ) { string sLevelPath = szLevelDir; if (!szLevelDir || sLevelPath.empty()) return false; string sEPath = sLevelPath+string("/levelinfo.xml"); string sPaks = sLevelPath + "/*.pak"; //GetSystem()->GetIPak()->OpenPacks(sPaks.c_str()); OpenPacks(sPaks.c_str()); XmlNodeRef root = GetSystem()->LoadXmlFile( sEPath.c_str() ); bool bResult = false; if (root) { XmlNodeRef missionsNode = root->findChild( "Missions" ); if (missionsNode) { // we found a mission node - the level is valid bResult = true; for (int i = 0; i < missionsNode->getChildCount(); i++) { XmlNodeRef missionNode = missionsNode->getChild(i); if (missionNode->isTag( "Mission" )) { const char *sMissionName = missionNode->getAttr( "Name" ); if (sMissionName) missions.push_back( sMissionName ); } } } } //GetSystem()->GetIPak()-> ClosePacks(sPaks.c_str()); return bResult; } ////////////////////////////////////////////////////////////////////////// bool CXGame::IsMultiplayer() { // cannot be in multiplayer when in editor if (m_bEditor) return false; bool bServer=IsServer(); bool bClient=IsClient(); if(!bServer && !bClient) return false; return !bServer || !bClient || m_pServer->m_bListen; }; ////////////////////////////////////////////////////////////////////////// void CXGame::ResetState(void) { // m_PlayersWithLighs.clear(); m_pSystem->GetIEntitySystem()->ResetEntities(); if (GetMyPlayer()) { m_XAreaMgr.ReTriggerArea(GetMyPlayer(), GetMyPlayer()->GetPos(),false); GetMyPlayer()->SetNeedUpdate(true); } m_pSystem->GetIInput()->Update(1); // flush the keyboard buffers m_pSystem->GetIInput()->Update(1); // flush the keyboard buffers m_pSystem->GetIInput()->GetIKeyboard()->ClearKeyState(); } ////////////////////////////////////////////////////////////////////////// bool CXGame::ConstrainToSandbox(IEntity *pEntity) { bool bPosChanged = false; if (IsMultiplayer()) { Vec3 vPos, vBounds[2]={Vec3(0,0,0),Vec3(0,0,0)}; IPhysicalEntity *pPhysEnt = pEntity->GetPhysics(); if (pPhysEnt) { pe_status_pos sp; pPhysEnt->GetStatus(&sp); vPos = sp.pos; } else vPos=pEntity->GetPos(); vBounds[1].x = vBounds[1].y = (float)m_p3DEngine->GetTerrainSize(); vBounds[0].z = -100; vBounds[1].z = 500; for(int i=0;i<3;i++) if (!inrange(vPos[i], vBounds[0][i],vBounds[1][i])) { vPos[i] = vBounds[isneg((vBounds[0][i]+vBounds[1][i])*0.5f-vPos[i])][i]; bPosChanged = true; } if (bPosChanged) { if (pPhysEnt) { pe_params_pos pp; pp.pos = vPos; pPhysEnt->SetParams(&pp); } else pEntity->SetPos(vPos); } } return bPosChanged; } ////////////////////////////////////////////////////////////////////////// void CXGame::GotoMenu(bool bTriggerOnSwitch) { if(m_bEditor) return; if(!m_pUISystem) // e.g. dedicated server return; if (!IsInMenu()) { DeleteMessage("Switch"); SendMessage("Switch"); } else if (bTriggerOnSwitch) { m_pUISystem->GetScriptObjectUI()->OnSwitch(1); } } ////////////////////////////////////////////////////////////////////////// void CXGame::GotoGame(bool bTriggerOnSwitch) { if (m_bEditor) { return; } if (IsInMenu()) { DeleteMessage("Switch"); SendMessage("Switch"); } else if (bTriggerOnSwitch) { m_pUISystem->GetScriptObjectUI()->OnSwitch(0); } } ////////////////////////////////////////////////////////////////////////// void CXGame::MenuOn() { // stop sounds and timers affected by game pause m_pSystem->GetISoundSystem()->Pause(true,true); m_pScriptTimerMgr->Pause(true); if (m_pSystem->GetIMusicSystem()) { m_pSystem->GetIMusicSystem()->Pause(true); //m_pSystem->GetIMusicSystem()->Silence(); } if (m_pUISystem && m_pUISystem->IsEnabled()) { m_pSystem->GetIInput()->AddEventListener(m_pUISystem); m_pSystem->GetIInput()->ClearKeyState(); m_pUISystem->GetScriptObjectUI()->OnSwitch(1); } m_bMenuOverlay = 1; if (!m_bEditor) { if (m_pUISystem->GetScriptObjectUI()->CanRenderGame()) { m_pSystem->GetILog()->Log("UISystem: Enabled 3D Engine!"); m_p3DEngine->Enable(1); } else { m_pSystem->GetILog()->Log("UISystem: Disabled 3D Engine!"); m_p3DEngine->Enable(0); } } _SmartScriptObject pClientStuff(m_pScriptSystem, true); if(m_pScriptSystem->GetGlobalValue("ClientStuff",pClientStuff)) { m_pScriptSystem->BeginCall("ClientStuff","OnPauseGame"); m_pScriptSystem->PushFuncParam(pClientStuff); m_pScriptSystem->EndCall(); } } ////////////////////////////////////////////////////////////////////////// void CXGame::MenuOff() { // resume sounds and timers affected by game pause m_pSystem->GetISoundSystem()->Pause(false); m_pSystem->GetIMusicSystem()->Pause(false); m_pScriptTimerMgr->Pause(false); if (m_pUISystem && m_pUISystem->IsEnabled()) { m_pSystem->GetIInput()->RemoveEventListener(m_pUISystem); m_pSystem->GetIInput()->ClearKeyState(); m_pUISystem->GetScriptObjectUI()->OnSwitch(0); if (GetMyPlayer()) m_XAreaMgr.ReTriggerArea(GetMyPlayer(), GetMyPlayer()->GetPos(),false); // m_XAreaMgr.ReTriggerArea(GetMyPlayer(), m_pSystem->GetISoundSystem()->GetListenerPos(),false); } m_bMenuOverlay = 0; m_pSystem->SetIProcess(m_p3DEngine); m_pSystem->GetIProcess()->SetFlags(PROC_3DENGINE); if (!m_bEditor) { m_pSystem->GetILog()->Log("UISystem: Enabled 3D Engine!"); m_p3DEngine->Enable(1); } _SmartScriptObject pClientStuff(m_pScriptSystem, true); if(m_pScriptSystem->GetGlobalValue("ClientStuff",pClientStuff)) { m_pScriptSystem->BeginCall("ClientStuff","OnResumeGame"); m_pScriptSystem->PushFuncParam(pClientStuff); m_pScriptSystem->EndCall(); } } ////////////////////////////////////////////////////////////////////////// void CXGame::DeleteMessage(const char *szMessage) { StringQueue NewQueue; while(!m_qMessages.empty()) { string qMessage = m_qMessages.front(); m_qMessages.pop(); if (qMessage != szMessage) { NewQueue.push(qMessage); } } m_qMessages = NewQueue; } ////////////////////////////////////////////////////////////////////////// IScriptObject *CXGame::GetScriptObject() { if (!m_pScriptObjectGame) { return 0; } return m_pScriptObjectGame->GetScriptObject(); } void CXGame::PlaySubtitle(ISound * pSound) { #if !defined(LINUX) if (m_pMovieUser) m_pMovieUser->PlaySubtitles(pSound); #endif } vector2f CXGame::GetSubtitleSize(const string &szMessage, float sizex, float sizey, const string &szFontName, const string &szFontEffect) { IFFont *pFont = m_pSystem->GetICryFont()->GetFont(szFontName.c_str()); pFont->Reset(); pFont->SetEffect(szFontEffect.c_str()); pFont->SetSize(vector2f(sizex, sizey)); wstring szwString; m_StringTableMgr.Localize(szMessage, szwString); return pFont->GetTextSizeW(szwString.c_str()); } void CXGame::WriteSubtitle(const string &szMessage, float x, float y, float sizex, float sizey, const color4f &cColor, const string &szFontName, const string &szFontEffect) { IFFont *pFont = m_pSystem->GetICryFont()->GetFont(szFontName.c_str()); pFont->Reset(); pFont->SetEffect(szFontEffect.c_str()); pFont->SetSize(vector2f(sizex, sizey)); pFont->SetColor(cColor); wstring szwString; m_StringTableMgr.Localize(szMessage, szwString); pFont->DrawStringW(x, y, szwString.c_str()); } ////////////////////////////////////////////////////////////////////////// IGameMods* CXGame::GetModsInterface() { return m_pGameMods; }; ////////////////////////////////////////////////////////////////////////// void CXGame::LoadingError(const char *szError) { m_pRenderer->ClearColorBuffer(Vec3(0,0,0)); GetSystem()->GetIConsole()->ResetProgressBar(0); m_pSystem->GetIConsole()->ShowConsole(false); m_pSystem->GetIConsole()->SetScrollMax(600/2); m_pScriptSystem->BeginCall("Game", "OnLoadingError"); m_pScriptSystem->PushFuncParam(GetScriptObject()); m_pScriptSystem->PushFuncParam(szError); m_pScriptSystem->EndCall(); } //------------------------------------------------------------------------------------------------- bool CXGame::GetCDPath(string &szCDPath) { bool bRet( false ); #ifdef WIN32 DWORD nBufferSize( GetLogicalDriveStrings( 0, 0 ) ); if( 0 < nBufferSize ) { // get list of all available logical drives tvector rawDriveLetters( nBufferSize + 1 ); GetLogicalDriveStrings( nBufferSize, &rawDriveLetters[ 0 ] ); // quickly scan all drives tvector::size_type i( 0 ); while( true ) { // check if current drive is cd/dvd drive if( DRIVE_CDROM == GetDriveType( &rawDriveLetters[ i ] ) ) { // get volume name tvector cdVolumeName( MAX_VOLUME_ID_SIZE + 1 ); if( FALSE != GetVolumeInformation( &rawDriveLetters[ i ], &cdVolumeName[ 0 ], (DWORD) cdVolumeName.size(), 0, 0, 0, 0, 0 ) ) { // check volume name to verify it's Far Cry's game cd/dvd tstring cdVolumeLabel( &cdVolumeName[ 0 ] ); tstring farCryDisk1Label( _T( "FARCRY_1" ) ); if( cdVolumeLabel == farCryDisk1Label ) { // found Far Cry's game cd/dvd, copy information and bail out szCDPath = &rawDriveLetters[ i ]; bRet = true; break; } } } // proceed to next drive while( 0 != rawDriveLetters[ i ] ) { ++i; } ++i; // skip null termination of current drive // check if we're out of drive letters if( 0 == rawDriveLetters[ i ] ) { // double null termination found, bail out break; } } } #endif return( bRet ); } ITagPointManager* CXGame::GetTagPointManager() { return m_pTagPointManager; }