/* 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/MapHandler.h" #include "hpl1/penumbra-overture/FadeHandler.h" #include "hpl1/penumbra-overture/GameArea.h" #include "hpl1/penumbra-overture/GameDamageArea.h" #include "hpl1/penumbra-overture/GameEnemy.h" #include "hpl1/penumbra-overture/GameEntity.h" #include "hpl1/penumbra-overture/GameForceArea.h" #include "hpl1/penumbra-overture/GameItem.h" #include "hpl1/penumbra-overture/GameLadder.h" #include "hpl1/penumbra-overture/GameLink.h" #include "hpl1/penumbra-overture/GameLiquidArea.h" #include "hpl1/penumbra-overture/GameMessageHandler.h" #include "hpl1/penumbra-overture/GameMusicHandler.h" #include "hpl1/penumbra-overture/GameStickArea.h" #include "hpl1/penumbra-overture/GraphicsHelper.h" #include "hpl1/penumbra-overture/Init.h" #include "hpl1/penumbra-overture/Inventory.h" #include "hpl1/penumbra-overture/MapLoadText.h" #include "hpl1/penumbra-overture/Player.h" #include "hpl1/penumbra-overture/PlayerHands.h" #include "hpl1/penumbra-overture/SaveHandler.h" #include "hpl1/penumbra-overture/SaveTypes.h" #include "hpl1/penumbra-overture/TriggerHandler.h" #include "hpl1/penumbra-overture/Triggers.h" ////////////////////////////////////////////////////////////////////////// // WORLD CACHE ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cWorldCache::cWorldCache(cInit *apInit) { mpInit = apInit; mpResources = mpInit->mpGame->GetResources(); mlCount = 0; } cWorldCache::~cWorldCache() { DecResources(); } //----------------------------------------------------------------------- void cWorldCache::AddResources() { //////////////////////////// // Materials { cResourceBaseIterator it = mpResources->GetMaterialManager()->GetResourceBaseIterator(); while (it.HasNext()) { iResourceBase *pResource = it.Next(); pResource->IncUserCount(); mlstMaterials.push_back(pResource); } } //////////////////////////// // Meshes { cResourceBaseIterator it = mpResources->GetMeshManager()->GetResourceBaseIterator(); while (it.HasNext()) { iResourceBase *pResource = it.Next(); pResource->IncUserCount(); mlstMeshes.push_back(pResource); } } //////////////////////////// // Animations { cResourceBaseIterator it = mpResources->GetAnimationManager()->GetResourceBaseIterator(); while (it.HasNext()) { iResourceBase *pResource = it.Next(); pResource->IncUserCount(); mlstAnimations.push_back(pResource); } } // mlCount++; } //----------------------------------------------------------------------- void cWorldCache::DecResources() { //////////////////////////// // Materials { tResourceBaseListIt it = mlstMaterials.begin(); for (; it != mlstMaterials.end(); ++it) { iResourceBase *pResource = *it; mpResources->GetMaterialManager()->Destroy(pResource); } mlstMaterials.clear(); } //////////////////////////// // Meshes { tResourceBaseListIt it = mlstMeshes.begin(); for (; it != mlstMeshes.end(); ++it) { iResourceBase *pResource = *it; mpResources->GetMeshManager()->Destroy(pResource); } mlstMeshes.clear(); } //////////////////////////// // Animations { tResourceBaseListIt it = mlstAnimations.begin(); for (; it != mlstAnimations.end(); ++it) { iResourceBase *pResource = *it; mpResources->GetAnimationManager()->Destroy(pResource); } mlstAnimations.clear(); } // mlCount--; } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // SOUND CALLBACK ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cMapHandlerSoundCallback::cMapHandlerSoundCallback(cInit *apInit) { mpInit = apInit; /////////////////////////////////////////// // Load all sounds that can heard by enemies tString sFile = "sounds/EnemySounds.dat"; TiXmlDocument *pXmlDoc = hplNew(TiXmlDocument, (sFile.c_str())); if (pXmlDoc->LoadFile() == false) { Error("Couldn't load XML file '%s'!\n", sFile.c_str()); hplDelete(pXmlDoc); return; } // Get the root. TiXmlElement *pRootElem = pXmlDoc->RootElement(); TiXmlElement *pChildElem = pRootElem->FirstChildElement(); for (; pChildElem != NULL; pChildElem = pChildElem->NextSiblingElement()) { tString sName = cString::ToString(pChildElem->Attribute("name"), ""); mvEnemyHearableSounds.push_back(sName); } hplDelete(pXmlDoc); } //----------------------------------------------------------------------- void cMapHandlerSoundCallback::OnStart(cSoundEntity *apSoundEntity) { /////////////////////////// // Check if the sound is something to worry bout tString sTypeName = apSoundEntity->GetData()->GetName(); bool bUsed = false; for (size_t i = 0; i < mvEnemyHearableSounds.size(); ++i) { tString &sName = mvEnemyHearableSounds[i]; if (sTypeName.size() >= sName.size() && sName == sTypeName.substr(0, sName.size())) { bUsed = true; } } if (bUsed == false) return; // Add a sound trigger cGameTrigger_Sound *pSound = hplNew(cGameTrigger_Sound, ()); pSound->mpSound = apSoundEntity->GetData(); mpInit->mpTriggerHandler->Add(pSound, eGameTriggerType_Sound, apSoundEntity->GetWorldPosition(), 10, 1.0f / 60.0f, apSoundEntity->GetData()->GetMaxDistance()); } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // LIGHT FLASH ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cEffectLightFlash::cEffectLightFlash(cInit *apInit, const cVector3f &avPos, float afRadius, const cColor &aColor, float afAddTime, float afNegTime) { mpInit = apInit; cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D(); mpLight = pWorld->CreateLightPoint("Flash"); mpLight->SetFarAttenuation(afRadius); mpLight->SetDiffuseColor(cColor(0, 0)); mpLight->SetCastShadows(true); mpLight->SetIsSaved(false); mpLight->SetPosition(avPos); mfRadius = afRadius; mfNegTime = afNegTime; // Log("Fade to %s : %f in time %f\n",aColor.ToString().c_str(),mfRadius,afAddTime); mpLight->FadeTo(aColor, mfRadius, afAddTime); mbIsDying = false; mbDead = false; } cEffectLightFlash::~cEffectLightFlash() { cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D(); pWorld->DestroyLight(mpLight); } //----------------------------------------------------------------------- void cEffectLightFlash::Update(float afTimeStep) { /*cColor Col = */ mpLight->GetDiffuseColor(); // Log("Update...\n"); if (mbIsDying == false) { if (mpLight->IsFading() == false) { // Log("Fade to black\n"); mpLight->FadeTo(cColor(0, 0), mfRadius, mfNegTime); mbIsDying = true; } } else { if (mpLight->IsFading() == false) { // Log("Kill\n"); mbDead = true; } } } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cMapHandler::cMapHandler(cInit *apInit) : iUpdateable("MapHandler") { mpInit = apInit; mbPreUpdating = false; mpScene = apInit->mpGame->GetScene(); mpResources = apInit->mpGame->GetResources(); mpWorldCache = hplNew(cWorldCache, (apInit)); mfGameTime = 0; mbDestroyingAll = false; Reset(); mpSoundCallback = hplNew(cMapHandlerSoundCallback, (apInit)); cSoundEntity::AddGlobalCallback(mpSoundCallback); mpMapChangeTexture = mpInit->mpGame->GetResources()->GetTextureManager()->Create2D("other_mapchange.jpg", false); } //----------------------------------------------------------------------- cMapHandler::~cMapHandler(void) { if (mpMapChangeTexture) mpInit->mpGame->GetResources()->GetTextureManager()->Destroy(mpMapChangeTexture); hplDelete(mpSoundCallback); hplDelete(mpWorldCache); } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- #ifdef DEMO_VERSION static int glNumOfLoads = 0; #endif bool cMapHandler::Load(const tString &asFile, const tString &asStartPos) { tString sMapName = cString::ToLowerCase(cString::SetFileExt(asFile, "")); cWorld3D *pWorld = NULL; cWorld3D *pLastMap = NULL; bool bFirstTime = false; double fTimeSinceVisit = 0; #ifdef DEMO_VERSION glNumOfLoads++; if (glNumOfLoads > 5) { CreateMessageBoxW(_W("Demo not playable any more!\n"), _W("The limits of the demo have been exceeded!\n")); exit(0); } #endif unsigned long lStartTime = mpInit->mpGame->GetSystem()->GetLowLevel()->getTime(); if (sMapName != msCurrentMap) { //////////////////////////////////////// // DESTRUCTION OF STUFF NOT SAVED ////// // remove all local timer // RemoveLocalTimers(); // Exit script if (mpScene->GetWorld3D()) { // OnMapLoad for all entities tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { iGameEntity *pEntity = GIt->second; pEntity->OnWorldExit(); } mpScene->GetWorld3D()->GetScript()->Run("OnExit()"); pLastMap = mpScene->GetWorld3D(); } mpInit->mpMusicHandler->OnWorldExit(); // Destroy the player objects so they are no saved. mpInit->mpPlayer->OnWorldExit(); mpInit->mpPlayerHands->OnWorldExit(); mpInit->mpGameMessageHandler->OnWorldExit(); //////////////////////////////////////// // SAVING ///////////////////////////// // Save the map if (msCurrentMap != "" && mpScene->GetWorld3D() != NULL) { mpInit->mpSaveHandler->SaveData(msCurrentMap); } msCurrentMap = sMapName; //////////////////////////////////////// // DESTRUCTION OF SAVED STUFF ////////// mpInit->mpInventory->ClearCallbacks(); // Reset the rendering. mpInit->mpGame->GetGraphics()->GetRenderer3D()->SetAmbientColor(cColor(0, 1)); mpInit->mpGame->GetGraphics()->GetRenderer3D()->SetSkyBoxActive(false); mpInit->mpGame->GetGraphics()->GetRenderer3D()->SetFogActive(false); // Remove all current objects mpInit->mbDestroyGraphics = false; DestroyAll(); mpInit->mbDestroyGraphics = true; // Destroy all sound entities on previous map. if (mpScene->GetWorld3D()) { mpScene->GetWorld3D()->DestroyAllSoundEntities(); } mpInit->mpPlayer->ClearCollideScripts(); // Stop all sound mpInit->mpGame->GetSound()->GetSoundHandler()->StopAll(eSoundDest_World); mpInit->mpGame->GetSound()->Update(1.0f / 60.0f); //////////////////////////////////////// // LOAD THE MAP //////////////////////// // Load if (mpScene->HasLoadedWorld(asFile)) { // Log("-------- Loaded NOT first time! ----------------\n"); pWorld = mpScene->LoadWorld3D(asFile, true, eWorldLoadFlag_NoGameEntities); // eWorldLoadFlag_NoLights | // eWorldLoadFlag_NoEntities | // eWorldLoadFlag_NoGameEntities); if (pWorld) mpScene->SetWorld3D(pWorld); else { Error("Couldn't load map '%s'\n", asFile.c_str()); return false; } mpInit->mpSaveHandler->LoadData(msCurrentMap); mpInit->mpGame->GetResources()->GetSoundManager()->DestroyUnused(mpInit->mlMaxSoundDataNum); mpInit->mpGame->GetResources()->GetParticleManager()->DestroyUnused(mpInit->mlMaxPSDataNum); } else { // Log("-------- FIRST TIME first time! ----------------\n"); pWorld = mpScene->LoadWorld3D(asFile, true, 0); mpInit->mpGame->GetResources()->GetSoundManager()->DestroyUnused(mpInit->mlMaxSoundDataNum); mpInit->mpGame->GetResources()->GetParticleManager()->DestroyUnused(mpInit->mlMaxPSDataNum); if (pWorld) mpScene->SetWorld3D(pWorld); else { Error("Couldn't load map '%s'\n", asFile.c_str()); return false; } bFirstTime = true; } /////////////////////////// // Add to cache mpWorldCache->DecResources(); mpWorldCache->AddResources(); /////////////////////////// // Destroy old map if (pLastMap) { mpScene->DestroyWorld3D(pLastMap); } fTimeSinceVisit = AddLoadedMap(pWorld); pWorld->GetPhysicsWorld()->SetMaxTimeStep(mpInit->mfMaxPhysicsTimeStep); // OnMapLoad for all entities tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { iGameEntity *pEntity = GIt->second; pEntity->OnWorldLoad(); } // OnMapLoad for player mpInit->mpPlayer->OnWorldLoad(); mpInit->mpPlayerHands->OnWorldLoad(); mpInit->mpMusicHandler->OnWorldLoad(); if (bFirstTime) { // Set a default name msMapGameName = cString::To16Char(cString::SetFileExt(asFile, "")); // Init script if (pWorld->GetScript()) pWorld->GetScript()->Run("OnStart()"); } } else { if (mpScene->GetWorld3D() != NULL) { pWorld = mpScene->GetWorld3D(); } else { Error("No world has been loaded!\n"); return false; } } mpInit->mpPlayer->SetStartPos(asStartPos); // Run global script if (mpInit->mpGlobalScript) { if (bFirstTime) mpInit->mpGlobalScript->Run("OnMapStart()"); mpInit->mpGlobalScript->Run("OnMapLoad()"); } if (pWorld->GetScript()) { pWorld->GetScript()->Run("OnLoad()"); } // After script has been run callback tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { iGameEntity *pEntity = GIt->second; pEntity->OnPostLoadScripts(); } // Log("After load and before preupdate:\n"); unsigned long lTime = mpInit->mpGame->GetSystem()->GetLowLevel()->getTime() - lStartTime; Log("Loading map '%s' took: %d ms\n", pWorld->GetFileName().c_str(), lTime); PreUpdate(fTimeSinceVisit); mpInit->mpGame->ResetLogicTimer(); // mpInit->mpGame->GetSound()->GetSoundHandler()->ResumeAll(eSoundDest_World | eSoundDest_Gui); // Log("After load and preupdate:\n"); // Set physics accuracy pWorld->GetPhysicsWorld()->SetAccuracyLevel(mpInit->mPhysicsAccuracy); return true; } //----------------------------------------------------------------------- bool cMapHandler::LoadSimple(const tString &asFile, bool abLoadEntities) { tString sMapName = cString::ToLowerCase(cString::SetFileExt(asFile, "")); cWorld3D *pWorld = NULL; DestroyAll(); mpInit->mpGame->GetSound()->GetSoundHandler()->StopAll(eSoundDest_World); mpInit->mpGame->GetSound()->Update(1.0f / 60.0f); mpInit->mpGame->GetGraphics()->GetRenderer3D()->SetAmbientColor(cColor(0, 1)); cWorld3D *pOldWorld = mpScene->GetWorld3D(); // Delete all sound entities if (pOldWorld) { pOldWorld->DestroyAllSoundEntities(); } // Set the current map. msCurrentMap = sMapName; if (abLoadEntities == false) { pWorld = mpScene->LoadWorld3D(asFile, true, eWorldLoadFlag_NoGameEntities); // eWorldLoadFlag_NoLights | // eWorldLoadFlag_NoEntities | // eWorldLoadFlag_NoGameEntities); if (pWorld == NULL) { Error("Couldn't load map '%s'\n", asFile.c_str()); return false; } mpInit->mpSaveHandler->LoadData(msCurrentMap); mpInit->mpGame->GetResources()->GetSoundManager()->DestroyUnused(mpInit->mlMaxSoundDataNum); mpInit->mpGame->GetResources()->GetParticleManager()->DestroyUnused(mpInit->mlMaxPSDataNum); } else { pWorld = mpScene->LoadWorld3D(asFile, true, 0); mpInit->mpGame->GetResources()->GetSoundManager()->DestroyUnused(mpInit->mlMaxSoundDataNum); mpInit->mpGame->GetResources()->GetParticleManager()->DestroyUnused(mpInit->mlMaxPSDataNum); if (pWorld == NULL) { Error("Couldn't load map '%s'\n", asFile.c_str()); return false; } } // Destroy old world, if there is any. if (pOldWorld) { mpScene->DestroyWorld3D(pOldWorld); } // Set physics update if (pWorld->GetPhysicsWorld()) pWorld->GetPhysicsWorld()->SetMaxTimeStep(mpInit->mfMaxPhysicsTimeStep); // OnMapLoad for all entities tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { iGameEntity *pEntity = GIt->second; pEntity->OnWorldLoad(); } // OnMapLoad for player mpInit->mpPlayer->OnWorldLoad(); mpInit->mpGame->ResetLogicTimer(); // Physics set up pWorld->GetPhysicsWorld()->SetAccuracyLevel(mpInit->mPhysicsAccuracy); return true; } //----------------------------------------------------------------------- void cMapHandler::ChangeMap(const tString &asMap, const tString &asPos, const tString &asStartSound, const tString &asStopSound, float afFadeOutTime, float afFadeInTime, tString asLoadTextCat, tString asLoadTextEntry) { mMapChanger.msNewMap = asMap; mMapChanger.msPosName = asPos; mMapChanger.msDoneSound = asStopSound; mMapChanger.mfFadeInTime = afFadeInTime; mMapChanger.mbActive = true; mMapChanger.msLoadTextCat = asLoadTextCat; mMapChanger.msLoadTextEntry = asLoadTextEntry; mpInit->mpFadeHandler->FadeOut(afFadeOutTime); if (asStartSound != "") mpInit->mpGame->GetSound()->GetSoundHandler()->PlayGui(asStartSound, false, 1); mpInit->mpPlayer->SetActive(false); } //----------------------------------------------------------------------- void cMapHandler::AddSaveData(cSavedWorld *apSavedWorld) { cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D(); ///////////////////////// // Properties apSavedWorld->msGameName = msMapGameName; ///////////////////////// // Local timers for (tGameTimerListIt it = mlstTimers.begin(); it != mlstTimers.end(); ++it) { cGameTimer *pTimer = *it; if (pTimer->mbGlobal == false) { apSavedWorld->mlstTimers.Add(*pTimer); } } ///////////////////////// // Map script vars tScriptVarMap *pVarMap = mpScene->GetLocalVarMap(); tScriptVarMapIt varIt = pVarMap->begin(); for (; varIt != pVarMap->end(); ++varIt) { cScriptVar &scriptVar = varIt->second; scriptVar.mlVal = scriptVar.mlVal; scriptVar.msName = scriptVar.msName; apSavedWorld->mlstVars.Add(scriptVar); } ////////////////// // Engine data // Lights { cLight3DListIterator it = pWorld->GetLightIterator(); while (it.HasNext()) { iLight3D *pLight = it.Next(); cEngineLight_SaveData saveLight; if (pLight->IsSaved() && pLight->GetParent() == NULL && pLight->GetEntityParent() == NULL) { saveLight.FromLight(pLight); apSavedWorld->mlstLights.Add(saveLight); } } } // Particle systems { cParticleSystem3DIterator it = pWorld->GetParticleSystemIterator(); while (it.HasNext()) { cParticleSystem3D *pPS = it.Next(); cEnginePS_SaveData savePS; if (pPS->IsSaved() && pPS->GetParent() == NULL && pPS->GetEntityParent() == NULL && pPS->IsDying() == false) { savePS.FromPS(pPS); apSavedWorld->mlstPS.Add(savePS); } } } // Beams { cBeamIterator it = pWorld->GetBeamIterator(); while (it.HasNext()) { cBeam *pBeam = it.Next(); cEngineBeam_SaveData saveBeam; if (pBeam->IsSaved() && pBeam->GetParent() == NULL && pBeam->GetEntityParent() == NULL) { saveBeam.FromBeam(pBeam); apSavedWorld->mlstBeams.Add(saveBeam); } } } // Sounds { cSoundEntityIterator it = pWorld->GetSoundEntityIterator(); while (it.HasNext()) { cSoundEntity *pSound = it.Next(); cEngineSound_SaveData saveSound; if (pSound->IsSaved() && pSound->GetParent() == NULL && pSound->GetEntityParent() == NULL) { // Check if the sound should be saved. if (pSound->GetRemoveWhenOver() && pSound->GetData()->GetLoop() == false) continue; saveSound.FromSound(pSound); apSavedWorld->mlstSounds.Add(saveSound); } } } // Joints { cPhysicsJointIterator it = pWorld->GetPhysicsWorld()->GetJointIterator(); while (it.HasNext()) { iPhysicsJoint *pJoint = it.Next(); cEngineJoint_SaveData saveJoint; if (pJoint->IsSaved()) { // Check if the joint should be saved. if (pJoint->IsBroken()) continue; saveJoint.FromJoint(pJoint); apSavedWorld->mlstJoints.Add(saveJoint); } } } ////////////////// // Map handler tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { iGameEntity *pEntity = GIt->second; if (pEntity->IsSaved()) { // Log("Saving entity: '%s'\n",pEntity->GetName().c_str()); iGameEntity_SaveData *pSaveData = pEntity->CreateSaveData(); pEntity->SaveToSaveData(pSaveData); apSavedWorld->mlstEntities.Add(pSaveData); // Log("Adding save data: %d\n", pSaveData); } else { // Log("Skipping entity: '%s'\n",pEntity->GetName().c_str()); } } } //----------------------------------------------------------------------- void cMapHandler::LoadSaveData(cSavedWorld *apSavedWorld) { cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D(); iPhysicsWorld *pPhysicsWorld = pWorld->GetPhysicsWorld(); Common::List lstEntities; ///////////////////////// // Properties msMapGameName = apSavedWorld->msGameName; //////////////////////////////// // Script variables cContainerListIterator scriptVar = apSavedWorld->mlstVars.GetIterator(); while (scriptVar.HasNext()) { cScriptVar &var = scriptVar.Next(); cScriptVar *pVar = mpScene->CreateLocalVar(var.msName); pVar->mlVal = var.mlVal; } ///////////////////////// // Local timers cContainerListIterator timerIt = apSavedWorld->mlstTimers.GetIterator(); while (timerIt.HasNext()) { cGameTimer &savedTimer = timerIt.Next(); cGameTimer *pTimer = hplNew(cGameTimer, ()); *pTimer = savedTimer; mlstTimers.push_back(pTimer); } //////////////////////////////// // Engine data { /////////////////////// // Lights cContainerListIterator it = apSavedWorld->mlstLights.GetIterator(); while (it.HasNext()) { cEngineLight_SaveData &saveLight = it.Next(); iLight3D *pLight = pWorld->GetLight(saveLight.msName); if (pLight) { saveLight.ToLight(pLight); } else { // Create light // This is most probably a temp light so skip it. } } } { ////////////////////////// // Particle systems // Go through particle systems and throw away those not present. cParticleSystem3DIterator psIt = pWorld->GetParticleSystemIterator(); while (psIt.HasNext()) { cParticleSystem3D *pPS = psIt.Next(); if (apSavedWorld->PSExists(pPS) == false) { pPS->KillInstantly(); } } // Set data to map particle systems or create if no system exist. cContainerListIterator it = apSavedWorld->mlstPS.GetIterator(); while (it.HasNext()) { cEnginePS_SaveData &savePS = it.Next(); cParticleSystem3D *pPS = pWorld->GetParticleSystem(savePS.msName); if (pPS) { savePS.ToPS(pPS); } else { pPS = pWorld->CreateParticleSystem(savePS.msName, savePS.msType, savePS.mvSize, savePS.m_mtxTransform); savePS.ToPS(pPS); } } } ////////////////////////// // Beams { // Go through beams and throw away those not present. cBeamIterator beamIt = pWorld->GetBeamIterator(); while (beamIt.HasNext()) { cBeam *pBeam = beamIt.Next(); if (apSavedWorld->BeamExists(pBeam) == false) { mpScene->GetWorld3D()->DestroyBeam(pBeam); } } // Set data to map particle systems or create if no system exist. cContainerListIterator it = apSavedWorld->mlstBeams.GetIterator(); while (it.HasNext()) { cEngineBeam_SaveData &saveBeam = it.Next(); cBeam *pBeam = pWorld->GetBeam(saveBeam.msName); if (pBeam) { saveBeam.ToBeam(pBeam); } else { pBeam = pWorld->CreateBeam(saveBeam.msName); saveBeam.ToBeam(pBeam); } } } { ////////////////////////// // Sounds // Go through sound entities and throw away those not present. cSoundEntityIterator soundIt = pWorld->GetSoundEntityIterator(); while (soundIt.HasNext()) { cSoundEntity *pSound = soundIt.Next(); if (apSavedWorld->SoundExists(pSound) == false) { mpScene->GetWorld3D()->DestroySoundEntity(pSound); } } // Set data to map sound entities cContainerListIterator it = apSavedWorld->mlstSounds.GetIterator(); while (it.HasNext()) { cEngineSound_SaveData &saveSound = it.Next(); cSoundEntity *pSound = pWorld->GetSoundEntity(saveSound.msName); if (pSound) { saveSound.ToSound(pSound); } } } //////////////////////////////// // Create Entities cContainerListIterator it = apSavedWorld->mlstEntities.GetIterator(); while (it.HasNext()) { iGameEntity_SaveData *pSaveEntity = it.Next(); ////////////////////////////////// // The entity is loaded from file if (pSaveEntity->msFileName != "") { if (pWorld->CreateEntity(pSaveEntity->msName, pSaveEntity->m_mtxTransform, pSaveEntity->msFileName, true)) { iGameEntity *pGameEntity = mpInit->mpMapHandler->GetLatestEntity(); pGameEntity->LoadFromSaveData(pSaveEntity); pGameEntity->SetSaveData(pSaveEntity); lstEntities.push_back(pGameEntity); } } ////////////////////////////////// // The entity is an area. else { cVector3f vSize = 0; tString sType = ""; // Get type and size switch (pSaveEntity->mType) { case eGameEntityType_Area: vSize = static_cast(pSaveEntity)->mvSize; sType = "script"; break; case eGameEntityType_Link: vSize = static_cast(pSaveEntity)->mvSize; sType = "link"; break; case eGameEntityType_StickArea: vSize = static_cast(pSaveEntity)->mvSize; sType = "stick"; break; case eGameEntityType_SaveArea: vSize = static_cast(pSaveEntity)->mvSize; sType = "save"; break; case eGameEntityType_Ladder: vSize = static_cast(pSaveEntity)->mvSize; sType = "ladder"; break; case eGameEntityType_DamageArea: vSize = static_cast(pSaveEntity)->mvSize; sType = "damage"; break; case eGameEntityType_ForceArea: vSize = static_cast(pSaveEntity)->mvSize; sType = "force"; break; case eGameEntityType_LiquidArea: vSize = static_cast(pSaveEntity)->mvSize; sType = "liquid"; break; default: break; } // Load entity if (sType != "") { iArea3DLoader *pLoader = pWorld->GetResources()->GetArea3DLoader(sType); if (pLoader) { pLoader->Load(pSaveEntity->msName, vSize, pSaveEntity->m_mtxTransform, pWorld); iGameEntity *pGameEntity = mpInit->mpMapHandler->GetLatestEntity(); pGameEntity->LoadFromSaveData(pSaveEntity); pGameEntity->SetSaveData(pSaveEntity); lstEntities.push_back(pGameEntity); } } } } //////////////////////////////// // Setup Entities Common::List::iterator entIt = lstEntities.begin(); for (; entIt != lstEntities.end(); ++entIt) { iGameEntity *pEntity = *entIt; pEntity->SetupSaveData(pEntity->GetSaveData()); } { ////////////////////////// // Joints // this need to be done after entity creation so all joints are created. // Go through joints and throw away those not present. cPhysicsJointIterator jointIt = pPhysicsWorld->GetJointIterator(); while (jointIt.HasNext()) { iPhysicsJoint *pJoint = jointIt.Next(); if (apSavedWorld->JointExists(pJoint) == false) { pPhysicsWorld->DestroyJoint(pJoint); } } // Set data to map Joint entities cContainerListIterator it2 = apSavedWorld->mlstJoints.GetIterator(); while (it2.HasNext()) { cEngineJoint_SaveData &saveJoint = it2.Next(); iPhysicsJoint *pJoint = pPhysicsWorld->GetJoint(saveJoint.msName); if (pJoint) { saveJoint.ToJoint(pJoint); } } } } //----------------------------------------------------------------------- void cMapHandler::OnStart() { } //----------------------------------------------------------------------- void cMapHandler::OnWorldLoad() { } //----------------------------------------------------------------------- void cMapHandler::OnDraw() { tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { iGameEntity *pEntity = GIt->second; pEntity->OnDraw(); } } void cMapHandler::RenderItemEffect() { if (mpInit->mbFlashItems == false) return; // Check if any item needs the effect. bool bFound = false; tGameItemListIt it = mlstGameItems.begin(); for (; it != mlstGameItems.end(); ++it) { cGameItem *pItem = *it; if (pItem->IsActive() && pItem->GetFlashAlpha() > 0) { bFound = true; break; } } if (bFound == false) return; cCamera3D *pCam = static_cast(mpScene->GetCamera()); iLowLevelGraphics *pLowGfx = mpInit->mpGame->GetGraphics()->GetLowLevel(); pLowGfx->SetDepthTestActive(true); pLowGfx->SetDepthWriteActive(false); pLowGfx->SetBlendActive(true); pLowGfx->SetBlendFunc(eBlendFunc_One, eBlendFunc_One); pLowGfx->SetActiveTextureUnit(0); pLowGfx->SetTextureEnv(eTextureParam_ColorSource1, eTextureSource_Constant); pLowGfx->SetTextureEnv(eTextureParam_ColorSource0, eTextureSource_Texture); pLowGfx->SetTextureEnv(eTextureParam_ColorFunc, eTextureFunc_Modulate); it = mlstGameItems.begin(); for (; it != mlstGameItems.end(); ++it) { cGameItem *pItem = *it; if (pItem->IsActive() == false) continue; if (pItem->GetFlashAlpha() <= 0) continue; cMeshEntity *pMeshEntity = pItem->GetMeshEntity(); pLowGfx->SetTextureConstantColor(cColor(pItem->GetFlashAlpha(), 0)); pLowGfx->SetMatrix(eMatrix_ModelView, cMath::MatrixMul(pCam->GetViewMatrix(), pMeshEntity->GetWorldMatrix())); for (int i = 0; i < pMeshEntity->GetMesh()->GetSubMeshNum(); i++) { cSubMeshEntity *pSubEntity = pMeshEntity->GetSubMeshEntity(i); iVertexBuffer *pVtxBuffer = pSubEntity->GetVertexBuffer(); iMaterial *pMaterial = pSubEntity->GetMaterial(); iGpuProgram *gpuProgram = pMaterial->getGpuProgram(eMaterialRenderType_Z, 0, NULL); if (gpuProgram) { gpuProgram->Bind(); gpuProgram->SetMatrixf("worldViewProj", eGpuProgramMatrix_ViewProjection, eGpuProgramMatrixOp_Identity); gpuProgram->SetColor3f("ambientColor", pItem->GetFlashAlpha()); } pLowGfx->SetTexture(0, pMaterial->GetTexture(eMaterialTexture_Diffuse)); pVtxBuffer->Bind(); pVtxBuffer->Draw(); pVtxBuffer->UnBind(); if (gpuProgram) gpuProgram->UnBind(); } } pLowGfx->SetTexture(0, NULL); pLowGfx->SetActiveTextureUnit(0); pLowGfx->SetTextureEnv(eTextureParam_ColorSource1, eTextureSource_Previous); pLowGfx->SetTextureEnv(eTextureParam_ColorSource0, eTextureSource_Texture); pLowGfx->SetBlendActive(false); pLowGfx->SetDepthTestActive(true); pLowGfx->SetDepthWriteActive(true); } //----------------------------------------------------------------------- void cMapHandler::OnPostSceneDraw() { //////////////////////////////////// // Draw effect on items RenderItemEffect(); cCamera3D *pCam = static_cast(mpScene->GetCamera()); mpInit->mpGame->GetGraphics()->GetLowLevel()->SetMatrix(eMatrix_ModelView, pCam->GetViewMatrix()); // mpScene->GetWorld3D()->GetPhysicsWorld()->RenderDebugGeometry( // mpInit->mpGame->GetGraphics()->GetLowLevel(),cColor(1,0.5f,1)); /*mpInit->mpGame->GetGraphics()->GetLowLevel()->SetDepthTestActive(false); cParticleSystem3DIterator PIt = mpScene->GetWorld3D()->GetParticleSystemIterator(); while(PIt.HasNext()) { cParticleSystem3D*pPS = PIt.Next(); //if(pPS->GetName() == "tripod01_tripodflame") //{ // static bool bStatic = true; // if(bStatic){//pPS->SetTransformUpdated(true); // Log("Once!!!\n"); // } // bStatic =false; //pPS->SetPosition(pPS->GetLocalPosition()); mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawSphere(pPS->GetWorldPosition(), 0.3f,cColor(1,0,1)); mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin( pPS->GetEmitter(0)->GetBoundingVolume()->GetMax(), pPS->GetEmitter(0)->GetBoundingVolume()->GetMin(), cColor(0,1,1)); } mpInit->mpGame->GetGraphics()->GetLowLevel()->SetDepthTestActive(true);*/ //////////////////////////////////// // Let Entities post draw tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { iGameEntity *pEntity = GIt->second; pEntity->OnPostSceneDraw(); } return; mpInit->mpGame->GetGraphics()->GetLowLevel()->SetTexture(0, NULL); mpInit->mpGame->GetGraphics()->GetLowLevel()->SetBlendActive(false); mpInit->mpGame->GetGraphics()->GetLowLevel()->SetDepthTestActive(false); /*cVector3f vMin = */ mpScene->GetWorld3D()->GetPhysicsWorld()->GetWorldSizeMin(); /*cVector3f vMax = */ mpScene->GetWorld3D()->GetPhysicsWorld()->GetWorldSizeMax(); // mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin(vMax,vMin,cColor(1,0,1)); // mpScene->GetWorld3D()->DrawMeshBoundingBoxes(cColor(1,0.5f,1),false); // mpScene->GetWorld3D()->GetPhysicsWorld()->RenderDebugGeometry( // mpInit->mpGame->GetGraphics()->GetLowLevel(),cColor(1,0.5f,1)); // mpScene->GetWorld3D()->GetPhysicsWorld()->SetSaveContactPoints(true); // mpScene->GetWorld3D()->GetPhysicsWorld()->RenderContactPoints(mpInit->mpGame->GetGraphics()->GetLowLevel(),cColor(1,0.5f,1), // cColor(1,1,0.5f)); cLight3DListIterator lightIt = mpScene->GetWorld3D()->GetLightIterator(); while (lightIt.HasNext()) { iLight3D *pLight = lightIt.Next(); if (pLight->IsVisible() && pLight->IsActive() && pLight->GetLightType() == eLight3DType_Spot) { cBoundingVolume *pBV = pLight->GetBoundingVolume(); mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin( pBV->GetMax(), pBV->GetMin(), cColor(1, 0, 1)); } } /*mpInit->mpGame->GetGraphics()->GetLowLevel()->SetDepthTestActive(false); cBillboardIterator billIt = mpScene->GetWorld3D()->GetBillboardIterator(); while(billIt.HasNext()) { cBillboard *pBillboard = billIt.Next(); mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin( pBillboard->GetBoundingVolume()->GetMax(), pBillboard->GetBoundingVolume()->GetMin(),cColor(1,0,1)); }*/ GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end(); ++GIt) { // iGameEntity *pEntity = GIt->second; // if(pEntity->GetBodyNum()<=0) continue; // mpInit->mpGame->GetGraphics()->GetLowLevel()->SetDepthTestActive(false); // mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin( // pEntity->GetMeshEntity()->GetBoundingVolume()->GetMax(), // pEntity->GetMeshEntity()->GetBoundingVolume()->GetMin(),cColor(1,0,1)); /*for(int i=0; i < pEntity->GetBodyNum(); ++i) { iPhysicsBody* pBody = pEntity->GetBody(i); if(pBody){ cBoundingVolume *pBV = pBody->GetBV(); mpInit->mpGame->GetGraphics()->GetLowLevel()->DrawBoxMaxMin(pBV->GetMax(),pBV->GetMin(), cColor(1,0.5f,1)); //pBody->RenderDebugGeometry(mpInit->mpGame->GetGraphics()->GetLowLevel(),cColor(1,0.5f,1)); } }*/ } mpInit->mpGame->GetGraphics()->GetLowLevel()->SetDepthTestActive(true); } //----------------------------------------------------------------------- void cMapHandler::Update(float afTimeStep) { mfGameTime += (double)afTimeStep; // iLowLevelSystem *pLowLevelSystem =mpInit->mpGame->GetSystem()->GetLowLevel(); // LogUpdate(" Flashes!\n"); //////////////////////////// // Update light flashes tEffectLightFlashListIt FlashIt = mlstLightFlashes.begin(); for (; FlashIt != mlstLightFlashes.end();) { cEffectLightFlash *pFlash = *FlashIt; pFlash->Update(afTimeStep); if (pFlash->IsDead()) { hplDelete(pFlash); FlashIt = mlstLightFlashes.erase(FlashIt); } else { ++FlashIt; } } // LogUpdate(" Timers\n"); //////////////////////////// // Update timers UpdateTimers(afTimeStep); // LogUpdate(" Entities!\n"); //////////////////////////// // Update entities. tGameEntityMapIt GIt = m_mapGameEntities.begin(); for (; GIt != m_mapGameEntities.end();) { iGameEntity *pEntity = GIt->second; // unsigned int lTime = pLowLevelSystem->GetTime(); // LogUpdate(" %s\n",pEntity->GetName().c_str()); if (pEntity->IsActive()) { pEntity->OnUpdate(afTimeStep); } if (pEntity->GetDestroyMe() || pEntity->GetBreakMe()) { // LogUpdate(" destroying\n"); if (pEntity->GetBreakMe()) pEntity->BreakAction(); m_mapGameEntities.erase(GIt++); hplDelete(pEntity); // LogUpdate(" done destroying\n"); } else { ////LogUpdate(" updating %s took %d ms\n", pEntity->GetName().c_str(), // pLowLevelSystem->GetTime() - lTime); ++GIt; } } //////////////////////////// // Check for map change // LogUpdate(" Map change\n"); if (mMapChanger.mbActive && mpInit->mpFadeHandler->IsActive() == false) { mMapChanger.mbActive = false; // Log("---------- CHANGING TO MAP: '%s' ------------------\n",mMapChanger.msNewMap.c_str()); // Make sure that the graphics are not destroyed at the end of the map so // That the next map doesn't have to reload em. mpInit->mbDestroyGraphics = false; // Draw Loading image if (mMapChanger.msLoadTextCat != "") { mpInit->mpMapLoadText->SetText(mMapChanger.msLoadTextCat, mMapChanger.msLoadTextEntry); mpInit->mpMapLoadText->SetActive(true); } else { mpInit->mpGraphicsHelper->DrawLoadingScreen("other_loading.jpg"); } // Fade in here so that script will over ride it. mpInit->mpFadeHandler->FadeIn(mMapChanger.mfFadeInTime); Load(mMapChanger.msNewMap, mMapChanger.msPosName); mpInit->mbDestroyGraphics = true; if (mMapChanger.msDoneSound != "") mpInit->mpGame->GetSound()->GetSoundHandler()->PlayGui(mMapChanger.msDoneSound, false, 1); mpInit->mpPlayer->SetActive(true); // Log("Map change over...\n"); } } //----------------------------------------------------------------------- void cMapHandler::Reset() { #ifdef DEMO_VERSION glNumOfLoads = 0; #endif mMapChanger.mbActive = false; msCurrentMap = ""; if (mpInit->mbResetCache) mpWorldCache->DecResources(); mvLoadedMaps.clear(); // Timers STLDeleteAll(mlstTimers); DestroyAll(); // World3D if (mpScene->GetWorld3D()) mpScene->DestroyWorld3D(mpScene->GetWorld3D()); mpScene->SetWorld3D(NULL); // Make sure no occulssion queries are left. mpInit->mpGame->GetGraphics()->GetRenderer3D()->GetRenderList()->Clear(); } //----------------------------------------------------------------------- void cMapHandler::DestroyAll() { mbDestroyingAll = true; RemoveLocalTimers(); // Game entities STLMapDeleteAll(m_mapGameEntities); m_mapGameEntities.clear(); mlstGameEnemies.clear(); mlstGameItems.clear(); // Light flashes STLDeleteAll(mlstLightFlashes); mlstLightFlashes.clear(); mbDestroyingAll = false; } //----------------------------------------------------------------------- cGameTimer *cMapHandler::CreateTimer(const tString &asName, float afTime, const tString &asCallback, bool abGlobal) { cGameTimer *pTimer = hplNew(cGameTimer, ()); pTimer->msName = asName; pTimer->msCallback = asCallback; pTimer->mfTime = afTime; pTimer->mbGlobal = abGlobal; mlstTimers.push_back(pTimer); return pTimer; } cGameTimer *cMapHandler::GetTimer(const tString &asName) { return (cGameTimer *)STLFindByName(mlstTimers, asName); } //----------------------------------------------------------------------- void cMapHandler::AddLightFlash(const cVector3f &avPos, float afRadius, const cColor &aColor, float afAddTime, float afNegTime) { cEffectLightFlash *pFlash = hplNew(cEffectLightFlash, (mpInit, avPos, afRadius, aColor, afAddTime, afNegTime)); mlstLightFlashes.push_back(pFlash); } //----------------------------------------------------------------------- void cMapHandler::AddStickArea(cGameStickArea *apArea) { mlstGameStickAreas.push_back(apArea); } //----------------------------------------------------------------------- void cMapHandler::RemoveStickArea(cGameStickArea *apArea) { tGameStickAreaListIt it = mlstGameStickAreas.begin(); for (; it != mlstGameStickAreas.end(); ++it) { if (*it == apArea) { mlstGameStickAreas.erase(it); break; } } } //----------------------------------------------------------------------- cGameStickArea *cMapHandler::GetBodyStickArea(iPhysicsBody *apBody) { tGameStickAreaListIt it = mlstGameStickAreas.begin(); for (; it != mlstGameStickAreas.end(); ++it) { cGameStickArea *pArea = *it; if (pArea->GetAttachedBody() == apBody) { return pArea; } } return NULL; } //----------------------------------------------------------------------- void cMapHandler::AddGameEnemy(iGameEnemy *apEnemy) { mlstGameEnemies.push_back(apEnemy); } tGameEnemyIterator cMapHandler::GetGameEnemyIterator() { return tGameEnemyIterator(&mlstGameEnemies); } //----------------------------------------------------------------------- void cMapHandler::AddGameItem(cGameItem *apItem) { mlstGameItems.push_back(apItem); } void cMapHandler::RemoveGameItem(cGameItem *apItem) { tGameItemListIt it = mlstGameItems.begin(); for (; it != mlstGameItems.end(); ++it) { cGameItem *pItem = *it; if (pItem == apItem) { mlstGameItems.erase(it); break; } } } //----------------------------------------------------------------------- void cMapHandler::AddGameEntity(iGameEntity *apEntity) { iGameEntity *pSameNameEntity = GetGameEntity(apEntity->GetName(), false); if (pSameNameEntity) { Warning("Entity '%s' with file '%s' has name already taken by '%s'!\n", apEntity->GetName().c_str(), apEntity->GetFileName().c_str(), pSameNameEntity->GetFileName().c_str()); } mpLatestEntity = apEntity; m_mapGameEntities.insert(tGameEntityMap::value_type(apEntity->GetName(), apEntity)); } void cMapHandler::RemoveGameEntity(iGameEntity *apEntity) { m_mapGameEntities.erase(apEntity->GetName()); // If the entity is an enemy remove that aswel { tGameEnemyListIt it = mlstGameEnemies.begin(); for (; it != mlstGameEnemies.end(); ++it) { iGameEntity *pEnemy = *it; if (pEnemy == apEntity) { mlstGameEnemies.erase(it); break; } } } hplDelete(apEntity); } iGameEntity *cMapHandler::GetGameEntity(const tString &asName, bool abErrorMessage) { tGameEntityMapIt it = m_mapGameEntities.find(asName); if (it == m_mapGameEntities.end()) { if (abErrorMessage) Error("Couldn't find game entity '%s'\n", asName.c_str()); return NULL; } return it->second; } //----------------------------------------------------------------------- tGameEntityIterator cMapHandler::GetGameEntityIterator() { return tGameEntityIterator(&m_mapGameEntities); } //----------------------------------------------------------------------- iGameEntity *cMapHandler::GetLatestEntity() { return mpLatestEntity; } //----------------------------------------------------------------------- void cMapHandler::SaveToGlobal(cMapHandler_GlobalSave *apSave) { cMapHandler_GlobalSave *pData = apSave; ///////////////// // Variables kSaveData_SaveTo(mfGameTime); kSaveData_SaveTo(msCurrentMap); ///////////////// // Containers // Loaded maps pData->mvLoadedMaps.Resize(mvLoadedMaps.size()); for (size_t i = 0; i < mvLoadedMaps.size(); ++i) { pData->mvLoadedMaps[i].mfTime = mvLoadedMaps[i].mfTime; pData->mvLoadedMaps[i].msName = mvLoadedMaps[i].msName; } // Timers tGameTimerListIt it = mlstTimers.begin(); for (; it != mlstTimers.end(); ++it) { cGameTimer *pTimer = *it; cMapHandlerTimer_GlobalSave timerSave; if (pTimer->mbGlobal) { timerSave.mfTime = pTimer->mfTime; timerSave.msName = pTimer->msName; timerSave.msCallback = pTimer->msCallback; timerSave.mbGlobal = pTimer->mbGlobal; timerSave.mbDeleteMe = pTimer->mbDeleteMe; timerSave.mbPaused = pTimer->mbPaused; pData->mlstTimers.Add(timerSave); } } } void cMapHandler::LoadFromGlobal(cMapHandler_GlobalSave *apSave) { cMapHandler_GlobalSave *pData = apSave; ///////////////// // Variables kSaveData_LoadFrom(mfGameTime); // Should not be loadead so that current map is "" // kSaveData_LoadFrom(msCurrentMap); ///////////////// // Containers // Loaded maps mvLoadedMaps.resize(pData->mvLoadedMaps.Size()); for (size_t i = 0; i < mvLoadedMaps.size(); ++i) { mvLoadedMaps[i].mfTime = pData->mvLoadedMaps[i].mfTime; mvLoadedMaps[i].msName = pData->mvLoadedMaps[i].msName; } // Timers cContainerListIterator it = pData->mlstTimers.GetIterator(); while (it.HasNext()) { cGameTimer *pTimer = hplNew(cGameTimer, ()); cMapHandlerTimer_GlobalSave &timerSave = it.Next(); pTimer->mfTime = timerSave.mfTime; pTimer->msName = timerSave.msName; pTimer->msCallback = timerSave.msCallback; pTimer->mbGlobal = timerSave.mbGlobal; pTimer->mbDeleteMe = timerSave.mbDeleteMe; pTimer->mbPaused = timerSave.mbPaused; mlstTimers.push_back(pTimer); } } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS ////////////////////////////////////////////////////////////////////////// void cMapHandler::PrintSoundsPlaying() { Log("Sounds: "); tSoundEntryList *pEntryList = mpInit->mpGame->GetSound()->GetSoundHandler()->GetWorldEntryList(); for (tSoundEntryListIt it = pEntryList->begin(); it != pEntryList->end(); ++it) { iSoundChannel *pSound = it->mpSound; Log("'%s', ", pSound->GetData()->GetName().c_str()); } Log("\n"); } //----------------------------------------------------------------------- void cMapHandler::UpdateTimers(float afTimeStep) { for (tGameTimerListIt it = mlstTimers.begin(); it != mlstTimers.end();) { cGameTimer *pTimer = *it; if (pTimer->mbDeleteMe) { it = mlstTimers.erase(it); hplDelete(pTimer); } else { if (pTimer->mbPaused == false) pTimer->mfTime -= afTimeStep; if (pTimer->mfTime <= 0) { tString sCommand = pTimer->msCallback + "(\"" + pTimer->msName + "\")"; mpInit->RunScriptCommand(sCommand); it = mlstTimers.erase(it); hplDelete(pTimer); } else { ++it; } } } } void cMapHandler::RemoveLocalTimers() { for (tGameTimerListIt it = mlstTimers.begin(); it != mlstTimers.end();) { cGameTimer *pTimer = *it; if (pTimer->mbGlobal == false) { it = mlstTimers.erase(it); hplDelete(pTimer); } else { ++it; } } } //----------------------------------------------------------------------- void cMapHandler::PreUpdate(double afTimeSinceVisit) { cWorld3D *pWorld = mpScene->GetWorld3D(); iPhysicsWorld *pPhysicsWorld = pWorld->GetPhysicsWorld(); mbPreUpdating = true; // unsigned long lStart = mpInit->mpGame->GetSystem()->GetLowLevel()->getTime(); // Enable all physic bodies cPhysicsBodyIterator bodyIt = pPhysicsWorld->GetBodyIterator(); while (bodyIt.HasNext()) { iPhysicsBody *pBody = bodyIt.Next(); pBody->SetEnabled(true); } ////////////////////////////////////// // Pre update game stuff if (afTimeSinceVisit == 0) { pWorld->PreUpdate(2.0f, mpInit->mpGame->GetStepSize()); } else { float fTime = (float)afTimeSinceVisit; if (fTime > 3) fTime = 3; float fStepSize = mpInit->mpGame->GetStepSize(); mpInit->mpGame->GetSound()->GetSoundHandler()->SetSilent(true); while (fTime > 0) { // if(pWorld->GetPhysicsWorld()) pWorld->GetPhysicsWorld()->Update(fStepSize); // pWorld->UpdateParticles(fStepSize); pWorld->Update(fStepSize); tGameEnemyListIt it = mlstGameEnemies.begin(); for (; it != mlstGameEnemies.end(); ++it) { iGameEnemy *pEnemy = *it; pEnemy->Update(fStepSize); } fTime -= fStepSize; } mpInit->mpGame->GetSound()->GetSoundHandler()->SetSilent(false); } // unsigned long lTime = mpInit->mpGame->GetSystem()->GetLowLevel()->getTime() - lStart; // Log("PREUPDATE time: %d\n",lTime); mbPreUpdating = false; } //----------------------------------------------------------------------- double cMapHandler::AddLoadedMap(cWorld3D *apWorld) { // Check if map is loaded for (size_t i = 0; i < mvLoadedMaps.size(); ++i) { if (mvLoadedMaps[i].msName == apWorld->GetName()) { double fTime = mvLoadedMaps[i].mfTime; mvLoadedMaps[i].mfTime = GetGameTime(); return GetGameTime() - fTime; } } cLoadedMap LoadedMap; LoadedMap.msName = apWorld->GetName(); LoadedMap.mfTime = GetGameTime(); mvLoadedMaps.push_back(LoadedMap); return 0; } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // SAVE DATA ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- //-----------------------------------------------------------------------