From 7e02bb7348569ef30f0ea5514dfe1cff3932c760 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 20 Feb 2017 19:58:00 +0100 Subject: [PATCH] Preload summoned creature models before the spell is cast --- apps/openmw/mwmechanics/spellcasting.cpp | 36 ++++++++++++++++++++++++ apps/openmw/mwmechanics/spellcasting.hpp | 2 ++ apps/openmw/mwmechanics/summoning.cpp | 32 ++------------------- apps/openmw/mwworld/scene.cpp | 10 +++++-- apps/openmw/mwworld/scene.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 20 ++++++++++--- 6 files changed, 64 insertions(+), 38 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 230d01e78..ffb31d70d 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -1175,4 +1175,40 @@ namespace MWMechanics return true; } + std::string getSummonedCreature(int effectId) + { + static std::map summonMap; + if (summonMap.empty()) + { + summonMap[ESM::MagicEffect::SummonAncestralGhost] = "sMagicAncestralGhostID"; + summonMap[ESM::MagicEffect::SummonBonelord] = "sMagicBonelordID"; + summonMap[ESM::MagicEffect::SummonBonewalker] = "sMagicLeastBonewalkerID"; + summonMap[ESM::MagicEffect::SummonCenturionSphere] = "sMagicCenturionSphereID"; + summonMap[ESM::MagicEffect::SummonClannfear] = "sMagicClannfearID"; + summonMap[ESM::MagicEffect::SummonDaedroth] = "sMagicDaedrothID"; + summonMap[ESM::MagicEffect::SummonDremora] = "sMagicDremoraID"; + summonMap[ESM::MagicEffect::SummonFabricant] = "sMagicFabricantID"; + summonMap[ESM::MagicEffect::SummonFlameAtronach] = "sMagicFlameAtronachID"; + summonMap[ESM::MagicEffect::SummonFrostAtronach] = "sMagicFrostAtronachID"; + summonMap[ESM::MagicEffect::SummonGoldenSaint] = "sMagicGoldenSaintID"; + summonMap[ESM::MagicEffect::SummonGreaterBonewalker] = "sMagicGreaterBonewalkerID"; + summonMap[ESM::MagicEffect::SummonHunger] = "sMagicHungerID"; + summonMap[ESM::MagicEffect::SummonScamp] = "sMagicScampID"; + summonMap[ESM::MagicEffect::SummonSkeletalMinion] = "sMagicSkeletalMinionID"; + summonMap[ESM::MagicEffect::SummonStormAtronach] = "sMagicStormAtronachID"; + summonMap[ESM::MagicEffect::SummonWingedTwilight] = "sMagicWingedTwilightID"; + summonMap[ESM::MagicEffect::SummonWolf] = "sMagicCreature01ID"; + summonMap[ESM::MagicEffect::SummonBear] = "sMagicCreature02ID"; + summonMap[ESM::MagicEffect::SummonBonewolf] = "sMagicCreature03ID"; + summonMap[ESM::MagicEffect::SummonCreature04] = "sMagicCreature04ID"; + summonMap[ESM::MagicEffect::SummonCreature05] = "sMagicCreature05ID"; + } + + std::map::const_iterator it = summonMap.find(effectId); + if (it == summonMap.end()) + return std::string(); + else + return MWBase::Environment::get().getWorld()->getStore().get().find(it->second)->getString(); + } + } diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 91bb6821a..8e48681b6 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -67,6 +67,8 @@ namespace MWMechanics /// @return Was the effect a tickable effect with a magnitude? bool effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const MWMechanics::EffectKey& effectKey, float magnitude); + std::string getSummonedCreature(int effectId); + class CastSpell { private: diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index 3ff8cf667..e4a825efc 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -40,32 +40,7 @@ namespace MWMechanics void UpdateSummonedCreatures::process() { - static std::map summonMap; - if (summonMap.empty()) - { - summonMap[ESM::MagicEffect::SummonAncestralGhost] = "sMagicAncestralGhostID"; - summonMap[ESM::MagicEffect::SummonBonelord] = "sMagicBonelordID"; - summonMap[ESM::MagicEffect::SummonBonewalker] = "sMagicLeastBonewalkerID"; - summonMap[ESM::MagicEffect::SummonCenturionSphere] = "sMagicCenturionSphereID"; - summonMap[ESM::MagicEffect::SummonClannfear] = "sMagicClannfearID"; - summonMap[ESM::MagicEffect::SummonDaedroth] = "sMagicDaedrothID"; - summonMap[ESM::MagicEffect::SummonDremora] = "sMagicDremoraID"; - summonMap[ESM::MagicEffect::SummonFabricant] = "sMagicFabricantID"; - summonMap[ESM::MagicEffect::SummonFlameAtronach] = "sMagicFlameAtronachID"; - summonMap[ESM::MagicEffect::SummonFrostAtronach] = "sMagicFrostAtronachID"; - summonMap[ESM::MagicEffect::SummonGoldenSaint] = "sMagicGoldenSaintID"; - summonMap[ESM::MagicEffect::SummonGreaterBonewalker] = "sMagicGreaterBonewalkerID"; - summonMap[ESM::MagicEffect::SummonHunger] = "sMagicHungerID"; - summonMap[ESM::MagicEffect::SummonScamp] = "sMagicScampID"; - summonMap[ESM::MagicEffect::SummonSkeletalMinion] = "sMagicSkeletalMinionID"; - summonMap[ESM::MagicEffect::SummonStormAtronach] = "sMagicStormAtronachID"; - summonMap[ESM::MagicEffect::SummonWingedTwilight] = "sMagicWingedTwilightID"; - summonMap[ESM::MagicEffect::SummonWolf] = "sMagicCreature01ID"; - summonMap[ESM::MagicEffect::SummonBear] = "sMagicCreature02ID"; - summonMap[ESM::MagicEffect::SummonBonewolf] = "sMagicCreature03ID"; - summonMap[ESM::MagicEffect::SummonCreature04] = "sMagicCreature04ID"; - summonMap[ESM::MagicEffect::SummonCreature05] = "sMagicCreature05ID"; - } + MWMechanics::CreatureStats& creatureStats = mActor.getClass().getCreatureStats(mActor); @@ -89,10 +64,7 @@ namespace MWMechanics bool found = creatureMap.find(std::make_pair(it->first, it->second)) != creatureMap.end(); if (!found) { - const std::string& creatureGmst = summonMap[it->first]; - std::string creatureID = - MWBase::Environment::get().getWorld()->getStore().get().find(creatureGmst)->getString(); - + std::string creatureID = getSummonedCreature(it->first); if (!creatureID.empty()) { int creatureActorId = -1; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 8c3fc771d..ea8b7c539 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -684,10 +684,14 @@ namespace MWWorld Resource::SceneManager* mSceneManager; }; - void Scene::preload(const std::string &mesh) + void Scene::preload(const std::string &mesh, bool useAnim) { - if (!mRendering.getResourceSystem()->getSceneManager()->checkLoaded(mesh, mRendering.getReferenceTime())) - mRendering.getWorkQueue()->addWorkItem(new PreloadMeshItem(mesh, mRendering.getResourceSystem()->getSceneManager())); + std::string mesh_ = mesh; + if (useAnim) + mesh_ = Misc::ResourceHelpers::correctActorModelPath(mesh_, mRendering.getResourceSystem()->getVFS()); + + if (!mRendering.getResourceSystem()->getSceneManager()->checkLoaded(mesh_, mRendering.getReferenceTime())) + mRendering.getWorkQueue()->addWorkItem(new PreloadMeshItem(mesh_, mRendering.getResourceSystem()->getSceneManager())); } void Scene::preloadCells(float dt) diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index cbceb14f5..5f17f8d59 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -133,7 +133,7 @@ namespace MWWorld Ptr searchPtrViaActorId (int actorId); - void preload(const std::string& mesh); + void preload(const std::string& mesh, bool useAnim=false); }; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 83b2b4d54..91e10dca1 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3398,10 +3398,16 @@ namespace MWWorld { if (obj.empty()) return; - MWWorld::ManualRef ref(store, obj); - std::string model = ref.getPtr().getClass().getModel(ref.getPtr()); - if (!model.empty()) - scene->preload(model); + try + { + MWWorld::ManualRef ref(store, obj); + std::string model = ref.getPtr().getClass().getModel(ref.getPtr()); + if (!model.empty()) + scene->preload(model, ref.getPtr().getClass().useAnim()); + } + catch(std::exception& e) + { + } } void World::preloadEffects(const ESM::EffectList *effectList) @@ -3410,6 +3416,12 @@ namespace MWWorld { const ESM::MagicEffect *effect = mStore.get().find(it->mEffectID); + if (MWMechanics::isSummoningEffect(it->mEffectID)) + { + preload(mWorldScene, mStore, "VFX_Summon_Start"); + preload(mWorldScene, mStore, MWMechanics::getSummonedCreature(it->mEffectID)); + } + preload(mWorldScene, mStore, effect->mCasting); preload(mWorldScene, mStore, effect->mHit);