Files
FC1/Editor/GameEngine.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

936 lines
26 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: gameengine.cpp
// Version: v1.00
// Created: 13/5/2002 by Timur.
// Compilers: Visual Studio.NET
// Description:
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "gameengine.h"
#include "CryEditDoc.h"
#include "Objects\ObjectManager.h"
#include "Objects\EntityScript.h"
#include "Mission.h"
#include "GameExporter.h"
#include "SurfaceType.h"
#include "VegetationMap.h"
#include "Heightmap.h"
#include "TerrainGrid.h"
#include "EdMesh.h"
#include "AI\AIManager.h"
#include "Material\MaterialManager.h"
#include "Particles\ParticleManager.h"
#include <IAgent.h>
#include <I3DEngine.h>
#include <IAISystem.h>
#include <IEntitySystem.h>
#include <EntityDesc.h>
#include <IMovieSystem.h>
#include <IGame.h>
#include <IInput.h>
#include <IScriptSystem.h>
#include <ICryPak.h>
#include <IDataProbe.h>
//////////////////////////////////////////////////////////////////////////
// Implementation of System Callback structure.
//////////////////////////////////////////////////////////////////////////
struct SSystemUserCallback : public ISystemUserCallback
{
bool OnError( const char *szErrorString )
{
if (szErrorString)
Log( szErrorString );
if (GetIEditor()->IsInTestMode())
{
abort();
}
char str[4096];
if (szErrorString)
sprintf( str,"%s\r\nSave Level Before Exiting the Editor?",szErrorString );
else
sprintf( str,"Unknown Error\r\nSave Level Before Exiting the Editor?" );
int res = MessageBox( NULL,str,"Engine Error",MB_YESNOCANCEL|MB_ICONERROR|MB_TOPMOST|MB_APPLMODAL|MB_DEFAULT_DESKTOP_ONLY);
if (res == IDYES || res == IDNO)
{
if (res == IDYES)
{
if (GetIEditor()->SaveDocument())
MessageBox( NULL,"Level has been sucessfully saved!\r\nPress Ok to terminate Editor.","Save",MB_OK );
}
}
return true;
}
void OnSaveDocument()
{
GetIEditor()->SaveDocument();
}
void OnProcessSwitch()
{
if (GetIEditor()->IsInGameMode())
GetIEditor()->SetInGameMode(false);
}
};
//////////////////////////////////////////////////////////////////////////
// Implments EntitySystemSink for InGame mode.
//////////////////////////////////////////////////////////////////////////
struct SInGameEntitySystemListener : public IEntitySystemSink
{
SInGameEntitySystemListener() {}
~SInGameEntitySystemListener()
{
// Remove all remaining entities from entity system.
IEntitySystem *pEntitySystem = GetIEditor()->GetSystem()->GetIEntitySystem();
for (std::set<int>::iterator it = m_entities.begin(); it != m_entities.end(); ++it)
{
pEntitySystem->RemoveEntity(*it, true);
}
}
virtual void OnSpawnContainer( CEntityDesc &ed,IEntity *pEntity) {};
virtual void OnSpawn( IEntity *e, CEntityDesc &ed )
{
if(ed.ClassId!=0 && ed.ClassId!=PLAYER_CLASS_ID) // Ignore MainPlayer
{
m_entities.insert(e->GetId());
}
}
virtual void OnRemove( IEntity *e )
{
m_entities.erase(e->GetId());
}
virtual void OnBind(EntityId id,EntityId child,unsigned char param){}
virtual void OnUnbind(EntityId id,EntityId child,unsigned char param){}
// Ids of all spawned entities.
std::set<int> m_entities;
};
namespace
{
SInGameEntitySystemListener* s_InGameEntityListener = 0;
};
//////////////////////////////////////////////////////////////////////////
// Timur.
// This is FarCry.exe authentication function, this code is not for public release!!
//////////////////////////////////////////////////////////////////////////
static void GameSystemAuthCheckFunction( void *data )
{
// src and trg can be the same pointer (in place encryption)
// len must be in bytes and must be multiple of 8 byts (64bits).
// key is 128bit: int key[4] = {n1,n2,n3,n4};
// void encipher(unsigned int *const v,unsigned int *const w,const unsigned int *const k )
#define TEA_ENCODE( src,trg,len,key ) {\
register unsigned int *v = (src), *w = (trg), *k = (key), nlen = (len) >> 3; \
register unsigned int delta=0x9E3779B9,a=k[0],b=k[1],c=k[2],d=k[3]; \
while (nlen--) {\
register unsigned int y=v[0],z=v[1],n=32,sum=0; \
while(n-->0) { sum += delta; y += (z << 4)+a ^ z+sum ^ (z >> 5)+b; z += (y << 4)+c ^ y+sum ^ (y >> 5)+d; } \
w[0]=y; w[1]=z; v+=2,w+=2; }}
// src and trg can be the same pointer (in place decryption)
// len must be in bytes and must be multiple of 8 byts (64bits).
// key is 128bit: int key[4] = {n1,n2,n3,n4};
// void decipher(unsigned int *const v,unsigned int *const w,const unsigned int *const k)
#define TEA_DECODE( src,trg,len,key ) {\
register unsigned int *v = (src), *w = (trg), *k = (key), nlen = (len) >> 3; \
register unsigned int delta=0x9E3779B9,a=k[0],b=k[1],c=k[2],d=k[3]; \
while (nlen--) { \
register unsigned int y=v[0],z=v[1],sum=0xC6EF3720,n=32; \
while(n-->0) { z -= (y << 4)+c ^ y+sum ^ (y >> 5)+d; y -= (z << 4)+a ^ z+sum ^ (z >> 5)+b; sum -= delta; } \
w[0]=y; w[1]=z; v+=2,w+=2; }}
// Data assumed to be 32 bytes.
int key1[4] = {1178362782,223786232,371615531,90884141};
TEA_DECODE( (unsigned int*)data,(unsigned int*)data,32,(unsigned int*)key1 );
int key2[4] = {89158165, 1389745433,971685123,785741042};
TEA_ENCODE( (unsigned int*)data,(unsigned int*)data,32,(unsigned int*)key2 );
}
//////////////////////////////////////////////////////////////////////////
CGameEngine::CGameEngine()
{
m_ISystem = NULL;
m_IGame = NULL;
m_I3DEngine = 0;
m_IAISystem = 0;
m_IEntitySystem = 0;
m_bLevelLoaded = false;
m_inGameMode = false;
m_simulationMode = false;
m_syncPlayerPosition = true;
m_bGameInitialized = false;
m_hSystemHandle = 0;
m_pSystemUserCallback = new SSystemUserCallback;
m_levelName = "Untitled";
}
//////////////////////////////////////////////////////////////////////////
CGameEngine::~CGameEngine()
{
// Release all EdMEshes.
CEdMesh::ReleaseAll();
delete m_pSystemUserCallback;
// Disable callback to editor.
m_ISystem->GetIMovieSystem()->SetCallback( NULL );
if (m_ISystem)
m_ISystem->Release();
if (m_hSystemHandle)
FreeLibrary(m_hSystemHandle);
//////////////////////////////////////////////////////////////////////////
// Delete entity registry.
//////////////////////////////////////////////////////////////////////////
CEntityScriptRegistry::Instance()->Release();;
}
//////////////////////////////////////////////////////////////////////////
bool CGameEngine::Init( bool bPreviewMode,bool bTestMode, const char *sInCmdLine )
{
m_hSystemHandle = LoadLibrary( "CrySystem.dll" );
if (!m_hSystemHandle)
{
Error( "CrySystem.DLL Loading Failed" );
return false;
}
PFNCREATESYSTEMINTERFACE pfnCreateSystemInterface =
(PFNCREATESYSTEMINTERFACE)::GetProcAddress( m_hSystemHandle,"CreateSystemInterface" );
SSystemInitParams sip;
sip.bEditor = true;
sip.bPreview = bPreviewMode;
sip.bTestMode = bTestMode;
sip.hInstance = AfxGetInstanceHandle();
if (AfxGetMainWnd())
sip.hWnd = AfxGetMainWnd()->GetSafeHwnd();
sip.pLog = new CLogFile;
sip.pUserCallback = m_pSystemUserCallback;
sip.pValidator = GetIEditor()->GetErrorReport(); // Assign validator from Editor.
if (sInCmdLine)
strcpy( sip.szSystemCmdLine,sInCmdLine );
sip.pCheckFunc = &GameSystemAuthCheckFunction;
m_ISystem = pfnCreateSystemInterface( sip );
if (!m_ISystem)
{
Error( "CreateSystemInterface Failed" );
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CGameEngine::InitGame( const char *sGameDLL )
{
m_I3DEngine = m_ISystem->GetI3DEngine();
m_IAISystem = m_ISystem->GetAISystem();
m_IEntitySystem = m_ISystem->GetIEntitySystem();
SGameInitParams ip;
ip.sGameDLL = sGameDLL;
if (!m_ISystem->CreateGame( ip ))
{
Error( "CreateGame Failed %s",sGameDLL );
return false;
}
m_IGame = m_ISystem->GetIGame();
/*
m_IGame->LoadLevel( "Editor" );
m_ISystem->IgnoreUpdates( true );
//@HACK: Update game several times to insure client connection.
for (int i = 0; i < 10; i++)
{
m_IGame->Update();
}
m_ISystem->IgnoreUpdates( false );
*/
/*
// Make main console font use realpixels.
IFFont *pFont = GetIEditor()->GetSystem()->GetICryFont()->GetFont("Default");
if (pFont)
{
pFont->UseRealPixels(true);
}
*/
// Enable displaying of labels.
//@HACK!: @FIXME
ICVar* pCvar = m_ISystem->GetIConsole()->GetCVar("r_DisplayInfo");
if (pCvar) pCvar->Set("1");
// Now initialize our AI.
GetIEditor()->GetAI()->Init( m_ISystem );
//! Remove indoor nodes from loaded graph.
// GetAISystem()->GetNodeGraph()->RemoveIndoorNodes();
//////////////////////////////////////////////////////////////////////////
// Execute Editor.lua ovrride file.
IScriptSystem *pScriptSystem = m_ISystem->GetIScriptSystem();
pScriptSystem->ExecuteFile("Editor.Lua",false);
//////////////////////////////////////////////////////////////////////////
CEntityScriptRegistry::Instance()->LoadScripts();
return true;
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetLevelPath( const CString &path )
{
CString relPath = GetIEditor()->GetRelativePath(path);
if (relPath.IsEmpty())
relPath = path;
m_levelPath = Path::RemoveBackslash(relPath);
m_levelName = Path::RemoveBackslash(relPath);
if (m_I3DEngine)
m_I3DEngine->SetLevelPath( m_levelPath );
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetMissionName( const CString &mission )
{
m_missionName = mission;
}
//////////////////////////////////////////////////////////////////////////
bool CGameEngine::LoadLevel( const CString &levelPath,const CString &mission,bool bDeleteAIGraph,bool bReleaseResources )
{
// In case 3d engine was not been initialized before.
m_I3DEngine = m_ISystem->GetI3DEngine();
////////////////////////////////////////////////////////////////////////
// Load a map inside the engine
////////////////////////////////////////////////////////////////////////
SetLevelPath( levelPath );
m_missionName = mission;
CLogFile::FormatLine("Loading map '%s' into engine...", (const char*)m_levelPath );
if (bReleaseResources)
ResetResources();
// Switch the current directory back to the Master CD folder first.
// The engine might have trouble to find some files when the current
// directory is wrong
SetCurrentDirectory( GetIEditor()->GetMasterCDFolder() );
CString pakFile = m_levelPath + "/*.pak";
// Open Pak file for this level.
if (!m_ISystem->GetIPak()->OpenPacks( pakFile ))
{
// Pak1 not found.
//CryWarning( VALIDATOR_MODULE_GAME,VALIDATOR_WARNING,"Level Pack File %s Not Found",sPak1.c_str() );
}
// Initialize physics grid.
if (bReleaseResources)
{
if (m_ISystem->GetIPhysicalWorld())
{
float fCellSize = 4.0f;
SSectorInfo si;
GetIEditor()->GetHeightmap()->GetSectorsInfo( si );
float terrainSize = si.sectorSize * si.numSectors;
m_ISystem->GetIPhysicalWorld()->SetupEntityGrid( 2,Vec3(0,0,0),terrainSize/fCellSize,terrainSize/fCellSize,fCellSize,fCellSize );
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Load level in 3d engine.
//////////////////////////////////////////////////////////////////////////
if (!m_I3DEngine->LoadLevel( m_levelPath,m_missionName,true))
{
CLogFile::WriteLine("ERROR: Can't load level !");
AfxMessageBox( "ERROR: Can't load level !" );
return false;
}
m_bLevelLoaded = true;
CHeightmap *pHeightmap = GetIEditor()->GetHeightmap();
if (pHeightmap)
{
// Set to heightmap size of currently loaded texture.
/*
int texSize = m_I3DEngine->GetTerrainTextureDim();
if (texSize > 0)
pHeightmap->SetSurfaceTextureSize(texSize,texSize);
*/
// Initialize terrain grid.
SSectorInfo si;
pHeightmap->GetSectorsInfo(si);
pHeightmap->GetTerrainGrid()->InitSectorGrid( si.numSectors );
}
HEAP_CHECK
GetIEditor()->GetObjectManager()->SendEvent( EVENT_REFRESH );
HEAP_CHECK
//GetIEditor()->GetSystem()->GetI3DEngine()->RemoveAllStaticObjects();
CVegetationMap *vegMap = GetIEditor()->GetVegetationMap();
if (vegMap)
vegMap->PlaceObjectsOnTerrain();
//GetIEditor()->GetStatObjMap()->PlaceObjectsOnTerrain();
if (bDeleteAIGraph)
{
m_IAISystem->FlushSystem();
m_IAISystem->LoadTriangulation( 0,0 );
//if (!LoadAI( m_levelName,m_missionName ))
//return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CGameEngine::ReloadLevel()
{
if (!IsLevelLoaded())
return false;
if (!LoadLevel( GetLevelPath(),GetMissionName(),false,false ))
return false;
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CGameEngine::LoadAI( const CString &levelName,const CString &missionName )
{
if (!m_IAISystem)
return false;
if (!IsLevelLoaded())
return false;
CLogFile::FormatLine( "Loading AI Triangulation %s, %s",(const char*)levelName,(const char*)missionName );
m_IAISystem->FlushSystem();
GetIEditor()->GetObjectManager()->SendEvent( EVENT_CLEAR_AIGRAPH );
m_IAISystem->LoadTriangulation( levelName,missionName );
m_IAISystem->GetNodeGraph()->RemoveIndoorNodes();
/*
// Call OnReset for all entities.
IEntityIt *entityIt = m_IEntitySystem->GetEntityIterator();
if (entityIt)
{
for (IEntity *entity = entityIt->Next(); entity != 0; entity = entityIt->Next())
{
CLogFile::FormatLine( "Reseting: %s, Class: %s",entity->GetName(),entity->GetEntityClassName() );
entity->Reset();
}
}
*/
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CGameEngine::LoadMission( const CString &mission )
{
if (!IsLevelLoaded())
return false;
if (mission != m_missionName)
{
m_missionName = mission;
m_I3DEngine->LoadEnvironmentSettingsFromXML( m_missionName, true );
}
/*
CLogFile::WriteLine( "Initializing AI system" );
char szLevel[1024];
_splitpath( GetIEditor()->GetDocument()->GetPathName(),0,0,szLevel,0 );
CString missionName = mission->GetName();
GetIEditor()->GetSystem()->GetAISystem()->Init( GetIEditor()->GetSystem(),szLevel,missionName );
*/
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CGameEngine::ReloadEnvironment()
{
if (!m_I3DEngine)
return false;
if (!IsLevelLoaded())
return false;
//char szLevelPath[_MAX_PATH];
//strcpy( szLevelPath,GetLevelPath() );
//PathAddBackslash( szLevelPath );
//CGameExporter gameExporter( GetIEditor()->GetSystem() );
//gameExporter.ExportLevelData( szLevelPath,false );
XmlNodeRef env = new CXmlNode("Environment");
CXmlTemplate::SetValues( GetIEditor()->GetDocument()->GetEnvironmentTemplate(),env );
// Notify mission that environment may be changed.
GetIEditor()->GetDocument()->GetCurrentMission()->OnEnvironmentChange();
//! Add lighting node to environment settings.
GetIEditor()->GetDocument()->GetCurrentMission()->GetLighting()->Serialize( env,false );
CString xmlStr = env->getXML();
// Reload level data in engine.
m_I3DEngine->LoadEnvironmentSettingsFromXML( GetMissionName(),true,xmlStr );
return true;
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetGameMode( bool inGame )
{
if (m_inGameMode == inGame)
return;
IGame *pGame = GetIEditor()->GetGame();
//////////////////////////////////////////////////////////////////////////
if (m_I3DEngine)
{
// Reset some 3d engine effects.
m_I3DEngine->ResetScreenFx();
m_I3DEngine->ResetParticlesAndDecals();
}
m_inGameMode = inGame;
if (inGame)
{
// m_IGame->HideLocalPlayer(false);
// Go to game mode.
IEntity *myPlayer;
#ifndef _ISNOTFARCRY
myPlayer = GetIXGame( pGame )->GetMyPlayer();
#endif
if (myPlayer)
{
pe_player_dimensions dim;
dim.heightEye = 0;
if (myPlayer->GetPhysics())
myPlayer->GetPhysics()->GetParams( &dim );
myPlayer->SetPos( GetIEditor()->GetViewerPos() - Vec3(0,0,dim.heightEye) );
myPlayer->SetAngles( GetIEditor()->GetViewerAngles() );
}
#ifndef _ISNOTFARCRY
GetIXGame( GetIEditor()->GetGame() )->SetViewAngles( GetIEditor()->GetViewerAngles() );
#endif
// Disable accelerators.
GetIEditor()->EnableAcceleratos( false );
// Reset physics state before switching to game.
m_ISystem->GetIPhysicalWorld()->ResetDynamicEntities();
// Reset Equipment
#ifndef _ISNOTFARCRY
GetIXGame( GetIEditor()->GetGame() )->RestoreWeaponPacks();
#endif
// Reset mission script.
GetIEditor()->GetDocument()->GetCurrentMission()->ResetScript();
// reset all agents in aisystem
m_ISystem->GetAISystem()->Reset();
// [Anton] - order changed, see comments for CGameEngine::SetSimulationMode
if (m_IGame)
m_IGame->ResetState();
//! Send event to switch into game.
GetIEditor()->GetObjectManager()->SendEvent( EVENT_INGAME );
// Reset movie system.
GetIEditor()->GetAnimation()->ResetAnimations(true);
// Switch to first person mode.
//GetIEditor()->GetGame()->SetViewMode(false);
// drawing of character.
#ifndef _ISNOTFARCRY
GetIXGame( m_IGame )->HideLocalPlayer( false, true );
#endif
SetPlayerPos( m_playerPos );
SetPlayerAngles( m_playerAngles );
// Register in game entitysystem listener.
s_InGameEntityListener = new SInGameEntitySystemListener;
m_IEntitySystem->SetSink(s_InGameEntityListener);
}
else
{
// reset all agents in aisystem
m_ISystem->GetAISystem()->Reset();
// Out of game in Editor mode.
GetIEditor()->SetViewerPos( m_ISystem->GetViewCamera().GetPos() );
GetIEditor()->SetViewerAngles( m_ISystem->GetViewCamera().GetAngles() );
// Unregister ingame entitysystem listener, and kill all remaining entities.
m_IEntitySystem->RemoveSink(s_InGameEntityListener);
delete s_InGameEntityListener;
s_InGameEntityListener = 0;
// Enable accelerators.
GetIEditor()->EnableAcceleratos( true );
// Reset mission script.
GetIEditor()->GetDocument()->GetCurrentMission()->ResetScript();
if (GetIEditor()->Get3DEngine()->IsTerainHightMapModifiedByGame())
GetIEditor()->GetHeightmap()->UpdateEngineTerrain();
// reset movie-system
GetIEditor()->GetAnimation()->ResetAnimations(false);
m_ISystem->GetIPhysicalWorld()->ResetDynamicEntities();
if (m_IGame)
m_IGame->ResetState();
// [Anton] - order changed, see comments for CGameEngine::SetSimulationMode
//! Send event to switch out of game.
GetIEditor()->GetObjectManager()->SendEvent( EVENT_OUTOFGAME );
// Switch to third person mode.
//GetIEditor()->GetGame()->SetViewMode(true);
// Hide all drawing of character.
#ifndef _ISNOTFARCRY
GetIXGame( m_IGame )->HideLocalPlayer( true, true );
#endif
}
if (AfxGetMainWnd())
{
HWND hWnd = AfxGetMainWnd()->GetSafeHwnd();
m_ISystem->GetIInput()->SetMouseExclusive( false,hWnd );
m_ISystem->GetIInput()->SetKeyboardExclusive( false,hWnd );
AfxGetMainWnd()->SetFocus();
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetSimulationMode( bool enabled )
{
if (m_simulationMode == enabled)
return;
m_simulationMode = enabled;
if (m_simulationMode)
{
// When turning physics on, emulate out of game event.
m_ISystem->GetAISystem()->Reset();
// [Anton] the order of the next 3 calls changed, since, EVENT_INGAME loads physics state (if any),
// and Reset should be called before it
m_ISystem->GetIPhysicalWorld()->ResetDynamicEntities();
if (m_IGame)
m_IGame->ResetState();
GetIEditor()->GetObjectManager()->SendEvent( EVENT_INGAME );
GetIEditor()->SetConsoleVar( "ai_ignoreplayer",1 );
GetIEditor()->SetConsoleVar( "ai_soundperception",0 );
}
else
{
// When turning physics off, emulate out of game event.
m_ISystem->GetAISystem()->Reset();
m_ISystem->GetIPhysicalWorld()->ResetDynamicEntities();
if (m_IGame)
m_IGame->ResetState();
GetIEditor()->GetObjectManager()->SendEvent( EVENT_OUTOFGAME );
GetIEditor()->SetConsoleVar( "ai_ignoreplayer",0 );
GetIEditor()->SetConsoleVar( "ai_soundperception",1 );
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::GenerateAiTriangulation()
{
CWaitProgress wait( "Generating AI Triangulation" );
CWaitCursor waitcrs;
GetIEditor()->SetConsoleVar( "ai_triangulate",1 );
//GetIEditor()->GetObjectManager()->SendEvent( EVENT_UNLOAD_ENTITY );
GetIEditor()->GetObjectManager()->SendEvent( EVENT_CLEAR_AIGRAPH );
CLogFile::FormatLine( "Generating Triangulation for Level:%s Mission:%s",(const char*)m_levelPath,(const char*)m_missionName );
m_IAISystem->FlushSystem();
m_IAISystem->LoadTriangulation( m_levelPath,m_missionName );
//GetIEditor()->GetObjectManager()->SendEvent( EVENT_RELOAD_ENTITY );
GetIEditor()->GetObjectManager()->SendEvent( EVENT_MISSION_CHANGE );
GetIEditor()->SetConsoleVar( "ai_triangulate",0 );
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::ForceRegisterEntitiesInSectors()
{
// Reset state of all entities.
IEntityIt *entityIt = m_IEntitySystem->GetEntityIterator();
if (entityIt)
{
entityIt->MoveFirst();
for (IEntity *entity = entityIt->Next(); entity != 0; entity = entityIt->Next())
{
//if (entity->Re
//entity->SetRegisterInSectors(false);
//entity->SetRegisterInSectors(true);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::ResetResources()
{
//////////////////////////////////////////////////////////////////////////
// Before clearing game and engine resources,
// make sure we dont keep some things in editor.
//////////////////////////////////////////////////////////////////////////
GetIEditor()->GetMaterialManager()->ClearAll();
GetIEditor()->GetParticleManager()->ClearAll();
// /*
m_I3DEngine = m_ISystem->GetI3DEngine();
IGame *pGame = GetIEditor()->GetGame();
if (!pGame)
return;
GetIEditor()->GetIconManager()->Reset();
GetIEditor()->GetVegetationMap()->UnloadObjectsGeometry();
CEdMesh::ReleaseAll();
// Clear everything.
//m_I3DEngine->ClearRenderResources(); //this function is called by the game already
m_ISystem->IgnoreUpdates( true );
pGame->LoadLevelForEditor( m_levelPath,m_missionName );
/*
//@HACK: Update game several times to insure client connection.
for (int i = 0; i < 10; i++)
{
pGame->Update();
}
m_ISystem->IgnoreUpdates( false );
m_IGame->HideLocalPlayer(true,true);
*/
m_ISystem->IgnoreUpdates( false );
m_bGameInitialized = true;
CEntityScriptRegistry::Instance()->LoadScripts();
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::PutSurfaceTypesToGame( bool bExportToEngine )
{
CCryEditDoc *doc = GetIEditor()->GetDocument();
IGame *pGame = GetIEditor()->GetGame();
if (!doc || !pGame)
return;
for (int i = 0; i < doc->GetSurfaceTypeCount(); i++)
{
CString physMaterial = doc->GetSurfaceType(i)->GetMaterial();
if (!physMaterial.IsEmpty())
{
#ifndef _ISNOTFARCRY
GetIXGame( pGame )->SetTerrainSurface( physMaterial, i );
#endif
}
}
if (bExportToEngine)
{
if (!IsLevelLoaded())
return;
char szLevelPath[_MAX_PATH];
strcpy( szLevelPath,GetLevelPath() );
PathAddBackslash( szLevelPath );
CGameExporter gameExporter( GetIEditor()->GetSystem() );
gameExporter.ExportLevelData( szLevelPath,false );
// Reload level data in engine.
m_I3DEngine->LoadTerrainSurfacesFromXML();
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetPlayerEquipPack( const char *sEqipPackName )
{
if (m_IGame && m_bGameInitialized)
{
#ifndef _ISNOTFARCRY
GetIXGame( m_IGame )->SetPlayerEquipPackName( sEqipPackName );
#endif
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::ReloadResourceFile( const CString &filename )
{
GetIEditor()->GetRenderer()->EF_ReloadFile( filename );
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetPlayerPos( const Vec3 &pos,bool bEyePos )
{
m_playerPos = pos;
if (!m_IGame)
return;
IEntity *myPlayer = NULL;
#ifndef _ISNOTFARCRY
myPlayer = GetIXGame( m_IGame )->GetMyPlayer();
#endif
if (!myPlayer)
return;
//if (m_inGameMode || m_simulationMode)
if (m_syncPlayerPosition)
{
Vec3 p = pos;
if (bEyePos)
{
pe_player_dimensions dim;
dim.heightEye = 0;
if (myPlayer->GetPhysics())
{
myPlayer->GetPhysics()->GetParams( &dim );
p.z = p.z - dim.heightEye;
}
}
myPlayer->SetPos( p );
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetPlayerAngles( const Vec3 &angles )
{
m_playerAngles = angles;
if (m_syncPlayerPosition)
{
//if (m_inGameMode || m_simulationMode)
{
if (m_IGame)
{
#ifndef _ISNOTFARCRY
GetIXGame( m_IGame )->SetViewAngles( angles );
#endif
}
}
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SyncPlayerPosition( bool bEnable )
{
m_syncPlayerPosition = bEnable;
if (m_syncPlayerPosition)
{
SetPlayerPos( m_playerPos );
SetPlayerAngles( m_playerAngles );
}
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::SetCurrentMOD( const char *sMod )
{
m_MOD = sMod;
}
//////////////////////////////////////////////////////////////////////////
const char* CGameEngine::GetCurrentMOD() const
{
return m_MOD;
}
//////////////////////////////////////////////////////////////////////////
void CGameEngine::Update()
{
if (m_inGameMode)
return;
if (m_IGame)
{
#ifndef _ISNOTFARCRY
IXGame* pXGame = GetIXGame( m_IGame );
if (!pXGame->GetMyPlayer())
{
m_ISystem->IgnoreUpdates( true );
//@HACK: Update game several times to insure client connection.
for (int i = 0; i < 20; i++)
{
pXGame->Update();
if (pXGame->GetMyPlayer())
break;
}
m_ISystem->IgnoreUpdates( false );
}
#endif
}
// Only in Editor mode.
// Update system.
int updateFlags = ESYSUPDATE_EDITOR;
if (!GetSimulationMode())
{
updateFlags += ESYSUPDATE_IGNORE_PHYSICS|ESYSUPDATE_IGNORE_AI;
}
// [marco] check current sound and vis areas for music etc.
// but if in game mode, 'cos is already done in the above call to game->update()
#ifndef _ISNOTFARCRY
if (m_IGame) GetIXGame( m_IGame )->CheckSoundVisAreas();
#endif
GetIEditor()->GetSystem()->Update( updateFlags );
// [marco] after system update, retrigger areas if necessary
if (m_IGame)
{
#ifndef _ISNOTFARCRY
if (m_IGame) GetIXGame( m_IGame )->RetriggerAreas();
if (m_IGame) GetIXGame( m_IGame )->HideLocalPlayer( true, true );
#endif
}
}