/*
* Copyright (C) 2006-2010 - Frictional Games
*
* This file is part of Penumbra Overture.
*
* Penumbra Overture 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.
*
* Penumbra Overture 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 Penumbra Overture. If not, see .
*/
#include "SaveHandler.h"
#include "Init.h"
#include "MapHandler.h"
#include "Player.h"
#include "Inventory.h"
#include "Notebook.h"
#include "GraphicsHelper.h"
#include "GameEntity.h"
#include "GameMusicHandler.h"
#include "RadioHandler.h"
//////////////////////////////////////////////////////////////////////////
// SAVED WORLD
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSavedWorld::~cSavedWorld()
{
Reset();
}
void cSavedWorld::Reset()
{
////////////////////////////////
//Clear and deleter entities
cContainerListIterator it = mlstEntities.GetIterator();
while(it.HasNext())
{
iGameEntity_SaveData *pSaveEntity = it.Next();
//Log(" delete %d\n", pSaveEntity);
hplDelete( pSaveEntity );
}
mlstEntities.Clear();
mlstVars.Clear();
//Inventory variables
mlstUseCallbacks.Clear();
mlstPickupCallbacks.Clear();
mlstCombineCallbacks.Clear();
//Player collider callbacks
mlstCollideCallbacks.Clear();
mlstLights.Clear();
mlstPS.Clear();
mlstSounds.Clear();
mlstJoints.Clear();
mlstBeams.Clear();
mlstTimers.Clear();
}
//-----------------------------------------------------------------------
bool cSavedWorld::PSExists(cParticleSystem3D *apPS)
{
cContainerListIterator it = mlstPS.GetIterator();
while(it.HasNext())
{
cEnginePS_SaveData &savePS = it.Next();
if(savePS.msName == apPS->GetName()) return true;
}
return false;
}
//-----------------------------------------------------------------------
bool cSavedWorld::BeamExists(cBeam *apBeam)
{
cContainerListIterator it = mlstBeams.GetIterator();
while(it.HasNext())
{
cEngineBeam_SaveData &saveBeam = it.Next();
if(saveBeam.msName == apBeam->GetName()) return true;
}
return false;
}
//-----------------------------------------------------------------------
bool cSavedWorld::SoundExists(cSoundEntity *apSound)
{
cContainerListIterator it = mlstSounds.GetIterator();
while(it.HasNext())
{
cEngineSound_SaveData &saveSound = it.Next();
if(saveSound.msName == apSound->GetName()) return true;
}
return false;
}
//-----------------------------------------------------------------------
bool cSavedWorld::JointExists(iPhysicsJoint *apJoint)
{
cContainerListIterator it = mlstJoints.GetIterator();
while(it.HasNext())
{
cEngineJoint_SaveData &saveJoint = it.Next();
if(saveJoint.msName == apJoint->GetName()) return true;
}
return false;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SAVED GAME
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSavedGame::~cSavedGame()
{
Reset();
}
//-----------------------------------------------------------------------
void cSavedGame::Reset()
{
ResetWorlds();
ResetGlobalData();
}
void cSavedGame::ResetWorlds()
{
cContainerListIterator it = mlstWorlds.GetIterator();
while(it.HasNext())
{
cSavedWorld* pWorld =it.Next();
//Log("delete world %d, '%s'\n", pWorld, pWorld->msName.c_str());
hplDelete( pWorld );
}
mlstWorlds.Clear();
}
void cSavedGame::ResetGlobalData()
{
mMapHandler.mvLoadedMaps.Clear();
mMapHandler.mlstTimers.Clear();
mInventory.mlstItems.Clear();
mInventory.mlstSlots.Clear();
mInventory.mvEquipSlots.Clear();
mNotebook.mlstNotes.Clear();
mNotebook.mlstTasks.Clear();
mlstScriptVars.Clear();
mvSceneLoadedMap.Clear();
}
cSavedWorld* cSavedGame::GetSavedWorld(const tString &asName)
{
tString sLowName = cString::ToLowerCase(asName);
//See if world allready exists
cContainerListIterator it = mlstWorlds.GetIterator();
while(it.HasNext())
{
cSavedWorld* pWorld = it.Next();
if(cString::ToLowerCase(pWorld->msName) == sLowName)
{
return pWorld;
}
}
//Create newer world
cSavedWorld *pWorld = hplNew( cSavedWorld, () );
pWorld->msName = asName;
mlstWorlds.Add(pWorld);
//Log("Creating saved world %d, %s\n",pWorld,asName.c_str());
return pWorld;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
cSaveHandler::cSaveHandler(cInit *apInit) : iUpdateable("SaveHandler")
{
mpInit = apInit;
mpSavedGame = hplNew( cSavedGame, () );
Reset();
//////////////////////////////////////////////
// Create directories
msSaveDir = _W("");
iLowLevelSystem *pLowLevelSystem = mpInit->mpGame->GetSystem()->GetLowLevel();
tWString sPeronalDir = GetSystemSpecialPath(eSystemPath_Personal);
if(sPeronalDir == _W(""))
{
Warning("Couldn't find a personal folder! Using the local folder instead!\n");
return;
}
//Put an "/" at end of needed
if( cString::GetLastCharW(sPeronalDir) != _W("/") &&
cString::GetLastCharW(sPeronalDir) != _W("\\"))
{
sPeronalDir += _W("/");
}
//Set to the name of directory
msSaveDir = sPeronalDir + PERSONAL_RELATIVEROOT PERSONAL_RELATIVEGAME;
//The directories that should be created
tWString vDirs[] = { PERSONAL_RELATIVEPIECES
PERSONAL_RELATIVEROOT PERSONAL_RELATIVEGAME_PARENT,
PERSONAL_RELATIVEROOT PERSONAL_RELATIVEGAME,
PERSONAL_RELATIVEROOT PERSONAL_RELATIVEGAME _W("save"),
PERSONAL_RELATIVEROOT PERSONAL_RELATIVEGAME _W("save/auto"),
PERSONAL_RELATIVEROOT PERSONAL_RELATIVEGAME _W("save/spot"),
PERSONAL_RELATIVEROOT PERSONAL_RELATIVEGAME _W("save/favorite")};
int lDirNum = PERSONAL_RELATIVEPIECES_COUNT + 6;
//Check if directories exist and if not create
for(int i=0; iGetSavedWorld(asName);
pSavedWorld->Reset();
///////////////////////
//Map properties
cRenderer3D *pRenderer = mpInit->mpGame->GetGraphics()->GetRenderer3D();
pSavedWorld->mAmbientColor = pRenderer->GetAmbientColor();
pSavedWorld->mbFogActive = pRenderer->GetFogActive();
pSavedWorld->mfFogStartDist = pRenderer->GetFogStart();
pSavedWorld->mfFogEndDist = pRenderer->GetFogEnd();
pSavedWorld->mFogColor = pRenderer->GetFogColor();
pSavedWorld->mbFogCulling = pRenderer->GetFogCulling();
pSavedWorld->mbSkyboxActive = pRenderer->GetSkyBoxActive();
pSavedWorld->mSkyboxColor = pRenderer->GetSkyBoxColor();
if(pRenderer->GetSkyBox())
pSavedWorld->msSkyboxFile = pRenderer->GetSkyBox()->GetName();
else
pSavedWorld->msSkyboxFile = "";
///////////////////////
//Inventory callbacks
cInventory *pInventory = mpInit->mpInventory;
//////////////////////
//Use callbacks
{
pSavedWorld->mlstUseCallbacks.Clear();
tInventoryUseCallbackMapIt it = pInventory->m_mapUseCallbacks.begin();
for(; it != pInventory->m_mapUseCallbacks.end(); ++it)
{
pSavedWorld->mlstUseCallbacks.Add(*(it->second));
}
}
//////////////////////
//Pickup callbacks
{
pSavedWorld->mlstPickupCallbacks.Clear();
tInventoryPickupCallbackMapIt it = pInventory->m_mapPickupCallbacks.begin();
for(; it != pInventory->m_mapPickupCallbacks.end(); ++it)
{
pSavedWorld->mlstPickupCallbacks.Add(*(it->second));
}
}
//////////////////////
//Combine callbacks
{
pSavedWorld->mlstCombineCallbacks.Clear();
tInventoryCombineCallbackListIt it = pInventory->mlstCombineCallbacks.begin();
for(; it != pInventory->mlstCombineCallbacks.end(); ++it)
{
pSavedWorld->mlstCombineCallbacks.Add(*(*it));
}
}
//////////////////////
//Player world data
mpInit->mpPlayer->AddSaveData(pSavedWorld);
/////////////////////////
//Entities on map
mpInit->mpMapHandler->AddSaveData(pSavedWorld);
//cSerializeClass::SetLog(true);
//cSerializeClass::SaveToFile(pSavedWorld,"TestSave.txt","SaveGame");
}
//-----------------------------------------------------------------------
void cSaveHandler::LoadData(const tString &asName)
{
cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D();
cSavedWorld *pSavedWorld = mpSavedGame->GetSavedWorld(asName);
///////////////////////
//Map properties
cRenderer3D *pRenderer = mpInit->mpGame->GetGraphics()->GetRenderer3D();
cResources *pResources = mpInit->mpGame->GetResources();
pRenderer->SetAmbientColor(pSavedWorld->mAmbientColor);
pRenderer->SetFogActive(pSavedWorld->mbFogActive);
pRenderer->SetFogStart(pSavedWorld->mfFogStartDist);
pRenderer->SetFogEnd(pSavedWorld->mfFogEndDist);
pRenderer->SetFogColor(pSavedWorld->mFogColor);
pRenderer->SetFogCulling(pSavedWorld->mbFogCulling);
pRenderer->SetSkyBoxActive(pSavedWorld->mbSkyboxActive);
pRenderer->SetSkyBoxColor(pSavedWorld->mSkyboxColor);
if(pSavedWorld->msSkyboxFile != "") {
iTexture *pTex = pResources->GetTextureManager()->CreateCubeMap(pSavedWorld->msSkyboxFile,false);
pRenderer->SetSkyBox(pTex,true);
}
else {
pRenderer->SetSkyBox(NULL,false);
}
///////////////////////
//Inventory callbacks
cInventory *pInventory = mpInit->mpInventory;
///////////////////////
//Use callbacks
{
cContainerListIterator it =pSavedWorld->mlstUseCallbacks.GetIterator();
while(it.HasNext())
{
cInventoryUseCallback &temp = it.Next();
mpInit->mpInventory->AddUseCallback(temp.msItem,temp.msObject,temp.msFunction);
}
}
///////////////////////
//Pickup callbacks
{
cContainerListIterator it = pSavedWorld->mlstPickupCallbacks.GetIterator();
while(it.HasNext())
{
cInventoryPickupCallback &temp = it.Next();
mpInit->mpInventory->AddPickupCallback(temp.msItem,temp.msFunction);
}
}
///////////////////////
//Combine callbacks
{
cContainerListIterator it = pSavedWorld->mlstCombineCallbacks.GetIterator();
while(it.HasNext())
{
cInventoryCombineCallback &temp = it.Next();
mpInit->mpInventory->AddCombineCallback(temp.msItem1, temp.msItem2, temp.msFunction);
}
}
/////////////////////////
//Entities on map
mpInit->mpMapHandler->LoadSaveData(pSavedWorld);
//////////////////////
//Player world data (do after entities are created)
mpInit->mpPlayer->LoadSaveData(pSavedWorld);
}
//-----------------------------------------------------------------------
void cSaveHandler::SaveGameToFile(const tWString& asFile)
{
//Reset all global data
mpSavedGame->ResetGlobalData();
//////////////////////////////
//Save the current map:
SaveData(mpInit->mpMapHandler->GetCurrentMapName());
//////////////////////////////
// Save Global variables
mpSavedGame->mlstScriptVars.Clear();
tScriptVarMap* pGlobalVarMap = mpInit->mpGame->GetScene()->GetGlobalVarMap();
tScriptVarMapIt VarIt = pGlobalVarMap->begin();
for(; VarIt != pGlobalVarMap->end(); ++VarIt)
{
mpSavedGame->mlstScriptVars.Add(VarIt->second);
}
//////////////////////////////
//Save global properties
mpSavedGame->mDifficulty = mpInit->mDifficulty;
mpSavedGame->msOnRadioEndCallback = mpInit->mpRadioHandler->GetOnEndCallback();
//////////////////////////////
//Save player
mpInit->mpPlayer->SaveToGlobal(&mpSavedGame->mPlayer);
//////////////////////////////
//Save map handler
mpInit->mpMapHandler->SaveToGlobal(&mpSavedGame->mMapHandler);
//////////////////////////////
//Save loaded maps in Scene
mpSavedGame->mvSceneLoadedMap.Clear();
tStringSet* pStringSet = mpInit->mpGame->GetScene()->GetLoadedMapsSet();
tStringSetIt it = pStringSet->begin();
for(; it != pStringSet->end(); ++it)
{
cSceneLoadedMap_GlobalSave loadedMap;
loadedMap.msName = *it;
mpSavedGame->mvSceneLoadedMap.Add(loadedMap);
}
//////////////////////////////
//Save inventory
mpInit->mpInventory->SaveToGlobal(&mpSavedGame->mInventory);
/////////////////////////////////
//Save notebook
mpInit->mpNotebook->SaveToGlobal(&mpSavedGame->mNotebook);
//////////////////////////////
//Load game music
mpInit->mpMusicHandler->SaveToGlobal(&mpSavedGame->mGameMusicHandler);
//////////////////////////////
//Save current music
cMusicEntry *pMusic = mpInit->mpGame->GetSound()->GetMusicHandler()->GetCurrentSong();
if(pMusic)
{
mpSavedGame->mMusic.msName = pMusic->msFileName;
mpSavedGame->mMusic.mfVolume = pMusic->mfMaxVolume;
mpSavedGame->mMusic.mbLoop = pMusic->mbLoop;
}
else
{
mpSavedGame->mMusic.msName = "";
}
//////////////////////////////
//Write to file:
//tWString sSavePath = mpInit->mpGame->GetSystem()->GetLowLevel()->GetSystemSpecialPath(eSystemPath_Personal);
//if(cString::GetLastCharW(sSavePath) != _W("/") && cString::GetLastCharW(sSavePath) != _W("\\"))
//sSavePath += _W("/");
tWString sSavePath = msSaveDir + asFile;
//tString sSaveFile = cString::To8Char(sSavePath);
//Log("Saving to %s\n",sSaveFile.c_str());
//cSerializeClass::SetLog(true);
cSerializeClass::SaveToFile(mpSavedGame,sSavePath, "SaveGame");
}
//-----------------------------------------------------------------------
void cSaveHandler::LoadGameFromFile(const tWString& asFile)
{
///////////////////////////////
//Draw loading screen.
mpInit->mpGraphicsHelper->DrawLoadingScreen("");
//1. Reset everything
//2. Load all data from file
//3. Load data to player, map handler, inventory,etc
//4. Load current map in mpSaveGame. Do NOT call any scripts.
//5. Load save data to map
//6. Play some music
mpInit->mpMapHandler->GetWorldCache()->DecResources();
mpInit->mpMapHandler->GetWorldCache()->AddResources();
mpInit->mbResetCache = false;
mpInit->ResetGame(false);
mpInit->mbResetCache = true;
mpInit->mpGame->GetSound()->GetMusicHandler()->Stop(0);
mpInit->mpGame->GetSound()->Update(1/60.0f);
cSerializeClass::SetLog(false);
tWString sSavePath = msSaveDir + asFile;
//tString sSaveFile = cString::To8Char(sSavePath);
cSerializeClass::LoadFromFile(mpSavedGame,sSavePath);
//////////////////////////////
//Load global properties
mpInit->mDifficulty = mpSavedGame->mDifficulty;
mpInit->mpRadioHandler->SetOnEndCallback(mpSavedGame->msOnRadioEndCallback);
//////////////////////////////////////////
//Load the save map handler data
mpInit->mpMapHandler->LoadFromGlobal(&mpSavedGame->mMapHandler);
//////////////////////////////
// Load Global variables
cContainerListIterator VarIt = mpSavedGame->mlstScriptVars.GetIterator();
while(VarIt.HasNext())
{
cScriptVar &tempVar = VarIt.Next();
cScriptVar *pVar = mpInit->mpGame->GetScene()->CreateGlobalVar(tempVar.msName);
pVar->mlVal = tempVar.mlVal;
//Log("Created global var: '%s' %d\n",pVar->msName.c_str(),pVar->mlVal);
}
////////////////////////////////
//Load loaded maps in Scene
tStringSet* pStringSet = mpInit->mpGame->GetScene()->GetLoadedMapsSet();
cContainerListIterator it = mpSavedGame->mvSceneLoadedMap.GetIterator();
while(it.HasNext())
{
pStringSet->insert(it.Next().msName);
}
/////////////////////////////////
//Load inventory
mpInit->mpInventory->LoadFromGlobal(&mpSavedGame->mInventory);
/////////////////////////////////
//Load notebook
mpInit->mpNotebook->LoadFromGlobal(&mpSavedGame->mNotebook);
///////////////////////////////
//Load the map
//TOOD: Use the correct file!
mpInit->mpMapHandler->LoadSimple(mpSavedGame->mMapHandler.msCurrentMap+".dae",false);
//LoadData(mpSavedGame->mMapHandler.msCurrentMap);
//mpInit->mpMapHandler->Load(mpSavedGame->mMapHandler.msCurrentMap+".dae","link01");
//////////////////////////////
//Load player properties.
mpInit->mpPlayer->LoadFromGlobal(&mpSavedGame->mPlayer);
//////////////////////////////
//Load game music
mpInit->mpMusicHandler->LoadFromGlobal(&mpSavedGame->mGameMusicHandler);
/////////////////////////////
//Start Music
if(mpSavedGame->mMusic.msName!="" && mpSavedGame->mMusic.mbLoop)
{
mpInit->mpGame->GetSound()->GetMusicHandler()->Play(mpSavedGame->mMusic.msName,
mpSavedGame->mMusic.mfVolume,0.5f,true);
}
//Reset logic timer.
mpInit->mpGame->ResetLogicTimer();
//Quick fix, make sure player is always active:
mpInit->mpPlayer->SetActive(true);
}
//-----------------------------------------------------------------------
void cSaveHandler::AutoSave(const tWString &asDir, int alMaxSaves)
{
//////////////////////
//Check the available autosaves
DeleteOldestIfMax(_W("save/")+asDir,_W("*.sav"),alMaxSaves);
//////////////////////
//Save the autosave
tWString sMapName = mpInit->mpMapHandler->GetMapGameName();
sMapName = cString::ReplaceCharToW(sMapName,_W("\n"),_W(" "));
sMapName = cString::ReplaceCharToW(sMapName,_W(":"),_W(" "));
cDate date = mpInit->mpGame->GetSystem()->GetLowLevel()->GetDate();
wchar_t sTemp[512];
swprintf(sTemp,512,_W("save/%ls/%ls %d-%02d-%02d_%02d.%02d.%02d_%02d.sav"),
asDir.c_str(),
sMapName.c_str(),
date.year,
date.month+1,
date.month_day,
date.hours,
date.minutes,
date.seconds,
cMath::RandRectl(0,99));
tWString sFile = sTemp;
SaveGameToFile(sFile);
mpInit->mpGame->ResetLogicTimer();
}
//-----------------------------------------------------------------------
void cSaveHandler::AutoLoad(const tWString &asDir)
{
tWString sFile = GetLatest(_W("save/")+asDir,_W("*.sav"));
LoadGameFromFile(_W("save/")+asDir+_W("/") + sFile);
mpInit->mpGame->ResetLogicTimer();
}
//-----------------------------------------------------------------------
void cSaveHandler::ClearSavedMaps()
{
Log("Clearing all previously saved maps...\n");
mpSavedGame->ResetWorlds();
}
//-----------------------------------------------------------------------
void cSaveHandler::OnWorldLoad()
{
}
//-----------------------------------------------------------------------
void cSaveHandler::OnStart()
{
}
//-----------------------------------------------------------------------
void cSaveHandler::Reset()
{
mpSavedGame->Reset();
}
void cSaveHandler::OnExit()
{
//Log(" doing nothing...\n");
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
void cSaveHandler::DeleteOldestIfMax(const tWString &asDir,const tWString &asMask, int alMaxFiles)
{
iLowLevelResources *pLowLevelResources = mpInit->mpGame->GetResources()->GetLowLevel();
iLowLevelSystem *pLowLevelSystem = mpInit->mpGame->GetSystem()->GetLowLevel();
tWString sPath = msSaveDir + asDir;
tWStringList lstFiles;
pLowLevelResources->FindFilesInDir(lstFiles,sPath,asMask);
//If there are too many files, remove oldest.
if((int)lstFiles.size() >= alMaxFiles)
{
tWString sOldest = _W("");
cDate oldestDate;
tWStringListIt it = lstFiles.begin();
for(; it != lstFiles.end(); ++it)
{
cDate date = FileModifiedDate(sPath + _W("/") +*it);
if(sOldest == _W("") || oldestDate > date)
{
sOldest = *it;
oldestDate = date;
}
}
RemoveFile(sPath + _W("/") +sOldest);
}
}
//-----------------------------------------------------------------------
tWString cSaveHandler::GetLatest(const tWString &asDir,const tWString &asMask)
{
iLowLevelResources *pLowLevelResources = mpInit->mpGame->GetResources()->GetLowLevel();
iLowLevelSystem *pLowLevelSystem = mpInit->mpGame->GetSystem()->GetLowLevel();
tWString sPath = msSaveDir + asDir;
tWStringList lstFiles;
pLowLevelResources->FindFilesInDir(lstFiles,sPath,asMask);
tWString sNewest = _W("");
cDate newestDate;
tWStringListIt it = lstFiles.begin();
for(; it != lstFiles.end(); ++it)
{
tWString sFile = *it;
cDate date = FileModifiedDate(sPath + _W("/") +*it);
if(sNewest == _W("") || newestDate < date)
{
sNewest = *it;
newestDate = date;
}
}
return sNewest;
}
//-----------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// SERIALIZABLE
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
kBeginSerializeBase(cMusic_GlobalSave)
kSerializeVar(msName,eSerializeType_String)
kSerializeVar(mfVolume,eSerializeType_Float32)
kSerializeVar(mbLoop,eSerializeType_Bool)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cGameMusic_GlobalSave)
kSerializeVar(msFile,eSerializeType_String)
kSerializeVar(mbLoop,eSerializeType_Bool)
kSerializeVar(mfVolume,eSerializeType_Float32)
kEndSerialize()
kBeginSerializeBase(cGameMusicHandler_GlobalSave)
kSerializeVar(mlCurrentMaxPrio,eSerializeType_Int32)
kSerializeVar(mbAttackPlaying,eSerializeType_Bool)
kSerializeVar(mbEnemyClosePlaying,eSerializeType_Bool)
kSerializeClassContainer(mvGameMusic,cGameMusic_GlobalSave,eSerializeType_Class)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cNotebookTask_GlobalSave)
kSerializeVar(msName,eSerializeType_String)
kSerializeVar(msText,eSerializeType_WString)
kEndSerialize()
kBeginSerializeBase(cNotebookNote_GlobalSave)
kSerializeVar(msName,eSerializeType_WString)
kSerializeVar(mbRead,eSerializeType_Bool)
kSerializeVar(msTextCat,eSerializeType_String)
kSerializeVar(msTextEntry,eSerializeType_String)
kEndSerialize()
kBeginSerializeBase(cNotebook_GlobalSave)
kSerializeClassContainer(mlstNotes,cNotebookNote_GlobalSave,eSerializeType_Class)
kSerializeClassContainer(mlstTasks,cNotebookTask_GlobalSave,eSerializeType_Class)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cInventorySlot_GlobalSave)
kSerializeVar(msItemName,eSerializeType_String)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cInventoryItem_GlobalSave)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(msGameName, eSerializeType_WString)
kSerializeVar(msDescription, eSerializeType_WString)
kSerializeVar(mItemType, eSerializeType_Int32)
kSerializeVar(msSubType, eSerializeType_String)
kSerializeVar(msEntityFile, eSerializeType_String)
kSerializeVar(msGfxObjectFile, eSerializeType_String)
kSerializeVar(msHudModelFile, eSerializeType_String)
kSerializeVar(msHudModelName, eSerializeType_String)
kSerializeVar(mbCanBeDropped, eSerializeType_Bool)
kSerializeVar(mbHasCount, eSerializeType_Bool)
kSerializeVar(mlCount, eSerializeType_Int32)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cInventory_GlobalSave)
kSerializeVar(mbNoteBookActive, eSerializeType_Bool)
kSerializeClassContainer(mlstSlots,cInventorySlot_GlobalSave,eSerializeType_Class)
kSerializeClassContainer(mvEquipSlots,cInventorySlot_GlobalSave,eSerializeType_Class)
kSerializeClassContainer(mlstItems,cInventoryItem_GlobalSave,eSerializeType_Class)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cSceneLoadedMap_GlobalSave)
kSerializeVar(msName, eSerializeType_String)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cMapHandlerLoadedMap_GlobalSave)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(mfTime, eSerializeType_Float32)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cMapHandlerTimer_GlobalSave)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(msCallback, eSerializeType_String)
kSerializeVar(mbGlobal, eSerializeType_Bool)
kSerializeVar(mfTime, eSerializeType_Float32)
kSerializeVar(mbDeleteMe, eSerializeType_Bool)
kSerializeVar(mbPaused, eSerializeType_Bool)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cMapHandler_GlobalSave)
kSerializeVar(mfGameTime, eSerializeType_Float32)
kSerializeVar(msCurrentMap, eSerializeType_String)
kSerializeClassContainer(mvLoadedMaps,cMapHandlerLoadedMap_GlobalSave,eSerializeType_Class)
kSerializeClassContainer(mlstTimers,cMapHandlerTimer_GlobalSave,eSerializeType_Class)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cPlayer_GlobalSave_CameraPS)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(msFile, eSerializeType_String)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cPlayer_GlobalSave)
/////////////////
//Stats
kSerializeVar(mlStat_NumOfSaves, eSerializeType_Int32)
/////////////////
//Global
kSerializeVar(mfForwardUpMul, eSerializeType_Float32)
kSerializeVar(mfForwardRightMul, eSerializeType_Float32)
kSerializeVar(mfUpMul, eSerializeType_Float32)
kSerializeVar(mfRightMul, eSerializeType_Float32)
kSerializeVar(mbPickAtPoint, eSerializeType_Bool)
kSerializeVar(mbRotateWithPlayer, eSerializeType_Bool)
kSerializeVar(mbUseNormalMass, eSerializeType_Bool)
kSerializeVar(mfGrabMassMul, eSerializeType_Float32)
//////////////////////////////
//Private
kSerializeVar(mbActive, eSerializeType_Bool)
kSerializeVar(mfHeightAdd, eSerializeType_Float32)
kSerializeVar(mfSpeedMul, eSerializeType_Float32)
kSerializeVar(mfHealthSpeedMul, eSerializeType_Float32)
kSerializeVar(mfHeadMoveSizeMul, eSerializeType_Float32)
kSerializeVar(mfHeadMoveSpeedMul, eSerializeType_Float32)
kSerializeVar(mState, eSerializeType_Int32)
kSerializeVar(mMoveState, eSerializeType_Int32)
kSerializeVar(mCrossHairState, eSerializeType_Int32)
kSerializeVar(mbItemFlash, eSerializeType_Bool)
kSerializeVar(mfHealth, eSerializeType_Float32)
kSerializeVar(mfPower, eSerializeType_Float32)
kSerializeVar(mfMass, eSerializeType_Float32)
kSerializeClassContainer(mvOnCameraPS,cPlayer_GlobalSave_CameraPS, eSerializeType_Class)
//////////////////////////////
// Lights
kSerializeVar(mbFlashlightActive, eSerializeType_Bool)
kSerializeVar(mbFlashlightDisabled, eSerializeType_Bool)
kSerializeVar(mbGlowstickActive, eSerializeType_Bool)
kSerializeVar(mbFlareActive, eSerializeType_Bool)
kSerializeVar(mfFlareTime, eSerializeType_Float32)
//////////////////////////////
//Body and Camera Specific
kSerializeVar(mvPosition, eSerializeType_Vector3f)
kSerializeVar(mfYaw, eSerializeType_Float32)
kSerializeVar(mfPitch, eSerializeType_Float32)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cSavedWorld)
kSerializeVar(msName, eSerializeType_String)
kSerializeVar(msGameName, eSerializeType_WString)
kSerializeVar(mAmbientColor,eSerializeType_Color)
kSerializeVar(mbFogActive,eSerializeType_Bool)
kSerializeVar(mfFogStartDist,eSerializeType_Float32)
kSerializeVar(mfFogEndDist,eSerializeType_Float32)
kSerializeVar(mFogColor,eSerializeType_Color)
kSerializeVar(mbFogCulling,eSerializeType_Bool)
kSerializeVar(mbSkyboxActive,eSerializeType_Bool)
kSerializeVar(mSkyboxColor,eSerializeType_Color)
kSerializeVar(msSkyboxFile,eSerializeType_String)
kSerializeClassContainer(mlstVars,cScriptVar,eSerializeType_Class)
kSerializeClassContainer(mlstUseCallbacks,cInventoryUseCallback, eSerializeType_Class)
kSerializeClassContainer(mlstPickupCallbacks,cInventoryPickupCallback, eSerializeType_Class)
kSerializeClassContainer(mlstCombineCallbacks, cInventoryCombineCallback, eSerializeType_Class)
kSerializeClassContainer(mlstCollideCallbacks,cSaveGame_cGameCollideScript,eSerializeType_Class)
kSerializeClassContainer(mlstTimers,cGameTimer,eSerializeType_Class)
kSerializeClassContainer(mlstEntities,iGameEntity_SaveData, eSerializeType_ClassPointer)
kSerializeClassContainer(mlstLights,cEngineLight_SaveData,eSerializeType_Class)
kSerializeClassContainer(mlstPS,cEnginePS_SaveData,eSerializeType_Class)
kSerializeClassContainer(mlstBeams,cEngineBeam_SaveData,eSerializeType_Class)
kSerializeClassContainer(mlstSounds,cEngineSound_SaveData,eSerializeType_Class)
kSerializeClassContainer(mlstJoints,cEngineJoint_SaveData,eSerializeType_Class)
kEndSerialize()
//-----------------------------------------------------------------------
kBeginSerializeBase(cSavedGame)
kSerializeVar(mDifficulty,eSerializeType_Int32)
kSerializeVar(msOnRadioEndCallback, eSerializeType_String)
kSerializeVar(mPlayer,eSerializeType_Class)
kSerializeVar(mMapHandler,eSerializeType_Class)
kSerializeVar(mInventory,eSerializeType_Class)
kSerializeVar(mNotebook,eSerializeType_Class)
kSerializeVar(mMusic,eSerializeType_Class)
kSerializeVar(mGameMusicHandler,eSerializeType_Class)
kSerializeClassContainer(mvSceneLoadedMap,cSceneLoadedMap_GlobalSave,eSerializeType_Class)
kSerializeClassContainer(mlstScriptVars, cScriptVar, eSerializeType_Class)
kSerializeClassContainer(mlstWorlds,cSavedWorld,eSerializeType_ClassPointer)
kEndSerialize()
//-----------------------------------------------------------------------