/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /* * Copyright (C) 2006-2010 - Frictional Games * * This file is part of Penumbra Overture. */ #include "hpl1/penumbra-overture/SaveHandler.h" #include "common/savefile.h" #include "hpl1/debug.h" #include "hpl1/hpl1.h" #include "hpl1/penumbra-overture/GameEntity.h" #include "hpl1/penumbra-overture/GameMusicHandler.h" #include "hpl1/penumbra-overture/GraphicsHelper.h" #include "hpl1/penumbra-overture/Init.h" #include "hpl1/penumbra-overture/Inventory.h" #include "hpl1/penumbra-overture/MapHandler.h" #include "hpl1/penumbra-overture/Notebook.h" #include "hpl1/penumbra-overture/Player.h" #include "hpl1/penumbra-overture/RadioHandler.h" #include "hpl1/string.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 already 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(); } //----------------------------------------------------------------------- cSaveHandler::~cSaveHandler(void) { hplDelete(mpSavedGame); } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- void cSaveHandler::SaveData(const tString &asName) { cSavedWorld *pSavedWorld = mpSavedGame->GetSavedWorld(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, bool drawLoadingScreen) { /////////////////////////////// // Draw loading screen. if (drawLoadingScreen) // if the loading screen has already been drawn, drawing it twice causes bugs 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(asDir, _W(":*"), 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(); Common::String dateString = Common::String::format("%02d-%02d-%02d %02d:%02d:%02d", date.year, date.month + 1, date.month_day, date.hours, date.minutes, date.seconds); tWString sFile = Common::U32String::format("%S: %S %s", asDir.c_str(), sMapName.c_str(), dateString.c_str()); SaveGameToFile(sFile); mpInit->mpGame->ResetLogicTimer(); } //----------------------------------------------------------------------- void cSaveHandler::AutoLoad(const tWString &asDir) { tWString latestSave = GetLatest(asDir + _W(":*")); if (!latestSave.empty()) { LoadGameFromFile(latestSave); 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 ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cDate cSaveHandler::parseDate(const Common::String &saveFile) { cDate date; Common::String strDate = saveFile.substr(saveFile.size() - 17); sscanf(strDate.c_str(), "%d-%d-%d %d:%d:%d", &date.year, &date.month, &date.month_day, &date.hours, &date.minutes, &date.seconds); return date; } template Common::String firstSave(const Common::StringArray &saves, DateCmp cmp) { if (saves.empty()) return ""; cDate latestDate = cSaveHandler::parseDate(saves.front()); const Common::String *latestSave = &saves.front(); for (auto it = saves.begin() + 1; it != saves.end(); ++it) { cDate d = cSaveHandler::parseDate(*it); if (cmp(d, latestDate)) { latestDate = d; latestSave = it; } } return *latestSave; } void cSaveHandler::DeleteOldestIfMax(const tWString &asDir, const tWString &asMask, int alMaxFiles) { const Common::StringArray saves = Hpl1::g_engine->listInternalSaves(asDir + asMask); if (static_cast(saves.size()) > alMaxFiles) { const Common::String oldest = firstSave(saves, [](const cDate &a, const cDate &b) { return a < b; }); Hpl1::logInfo(Hpl1::kDebugSaves, "removing save %s\n", oldest.c_str()); Hpl1::g_engine->removeSaveFile(oldest); } } //----------------------------------------------------------------------- tWString cSaveHandler::GetLatest(const tWString &asMask) { Common::StringArray saves = Hpl1::g_engine->listInternalSaves(asMask); return firstSave(saves, [](const cDate &a, const cDate &b) { return a > b; }); } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // 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() //-----------------------------------------------------------------------