Merge pull request #151 from OpenMW/master

Add OpenMW commits up to 16 Feb 2017
pull/163/head
David Cernat 8 years ago committed by GitHub
commit c32c004516

@ -131,6 +131,8 @@ namespace CSMWorld
Display_InfoCondComp,
Display_String32,
Display_LongString256,
Display_BookType,
Display_BloodType,
Display_EffectSkill, // must display at least one, unlike Display_Skill
Display_EffectAttribute, // must display at least one, unlike Display_Attribute

@ -98,7 +98,7 @@ namespace CSMWorld
{ ColumnId_ArmorType, "Armor Type" },
{ ColumnId_Health, "Health" },
{ ColumnId_ArmorValue, "Armor Value" },
{ ColumnId_Scroll, "Scroll" },
{ ColumnId_BookType, "Book Type" },
{ ColumnId_ClothingType, "Clothing Type" },
{ ColumnId_WeightCapacity, "Weight Capacity" },
{ ColumnId_OrganicContainer, "Organic Container" },
@ -112,8 +112,8 @@ namespace CSMWorld
{ ColumnId_Flies, "Flies" },
{ ColumnId_Walks, "Walks" },
{ ColumnId_Essential, "Essential" },
{ ColumnId_SkeletonBlood, "Skeleton Blood" },
{ ColumnId_MetalBlood, "Metal Blood" },
{ ColumnId_BloodType, "Blood Type" },
{ ColumnId_OpenSound, "Open Sound" },
{ ColumnId_CloseSound, "Close Sound" },
{ ColumnId_Duration, "Duration" },
@ -553,6 +553,16 @@ namespace
"AI Wander", "AI Travel", "AI Follow", "AI Escort", "AI Activate", 0
};
static const char *sBookType[] =
{
"Book", "Scroll", 0
};
static const char *sBloodType[] =
{
"Default (Red)", "Skeleton Blood (White)", "Metal Blood (Golden)", 0
};
const char **getEnumNames (CSMWorld::Columns::ColumnId column)
{
switch (column)
@ -582,6 +592,8 @@ namespace
case CSMWorld::Columns::ColumnId_AiPackageType: return sAiPackageType;
case CSMWorld::Columns::ColumnId_InfoCondFunc: return CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings;
case CSMWorld::Columns::ColumnId_InfoCondComp: return CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings;
case CSMWorld::Columns::ColumnId_BookType: return sBookType;
case CSMWorld::Columns::ColumnId_BloodType: return sBloodType;
default: return 0;
}

@ -92,7 +92,7 @@ namespace CSMWorld
ColumnId_ArmorType = 77,
ColumnId_Health = 78,
ColumnId_ArmorValue = 79,
ColumnId_Scroll = 80,
ColumnId_BookType = 80,
ColumnId_ClothingType = 81,
ColumnId_WeightCapacity = 82,
ColumnId_OrganicContainer = 83,
@ -107,8 +107,8 @@ namespace CSMWorld
ColumnId_Flies = 92,
ColumnId_Walks = 93,
ColumnId_Essential = 94,
ColumnId_SkeletonBlood = 95,
ColumnId_MetalBlood = 96,
ColumnId_BloodType = 95,
// unused
ColumnId_OpenSound = 97,
ColumnId_CloseSound = 98,
ColumnId_Duration = 99,

@ -301,9 +301,9 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
}
CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns,
const RefIdColumn *scroll, const RefIdColumn *skill, const RefIdColumn *text)
const RefIdColumn *bookType, const RefIdColumn *skill, const RefIdColumn *text)
: EnchantableRefIdAdapter<ESM::Book> (UniversalId::Type_Book, columns),
mScroll (scroll), mSkill (skill), mText (text)
mBookType (bookType), mSkill (skill), mText (text)
{}
QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column,
@ -312,8 +312,8 @@ QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column,
const Record<ESM::Book>& record = static_cast<const Record<ESM::Book>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
if (column==mScroll)
return record.get().mData.mIsScroll!=0;
if (column==mBookType)
return record.get().mData.mIsScroll;
if (column==mSkill)
return record.get().mData.mSkillId;
@ -332,7 +332,7 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
ESM::Book book = record.get();
if (column==mScroll)
if (column==mBookType)
book.mData.mIsScroll = value.toInt();
else if (column==mSkill)
book.mData.mSkillId = value.toInt();
@ -458,7 +458,8 @@ CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns)
mOriginal(NULL),
mAttributes(NULL),
mAttacks(NULL),
mMisc(NULL)
mMisc(NULL),
mBloodType(NULL)
{}
CSMWorld::CreatureRefIdAdapter::CreatureRefIdAdapter (const CreatureColumns& columns)
@ -489,6 +490,19 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, con
if (column==mColumns.mMisc)
return QVariant::fromValue(ColumnBase::TableEdit_Full);
if (column == mColumns.mBloodType)
{
int mask = ESM::Creature::Skeleton | ESM::Creature::Metal;
if ((record.get().mFlags & mask) == ESM::Creature::Skeleton)
return 1;
if ((record.get().mFlags & mask) == ESM::Creature::Metal)
return 2;
return 0;
}
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
mColumns.mFlags.find (column);
@ -512,6 +526,17 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
creature.mScale = value.toFloat();
else if (column==mColumns.mOriginal)
creature.mOriginal = value.toString().toUtf8().constData();
else if (column == mColumns.mBloodType)
{
int mask = ~(ESM::Creature::Skeleton | ESM::Creature::Metal);
if (value.toInt() == 1)
creature.mFlags = (creature.mFlags & mask) | ESM::Creature::Skeleton;
else if (value.toInt() == 2)
creature.mFlags = (creature.mFlags & mask) | ESM::Creature::Metal;
else
creature.mFlags = creature.mFlags & mask;
}
else
{
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
@ -696,7 +721,8 @@ CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns)
mHead(NULL),
mAttributes(NULL),
mSkills(NULL),
mMisc(NULL)
mMisc(NULL),
mBloodType(NULL)
{}
CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns)
@ -735,6 +761,19 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re
if (column==mColumns.mMisc)
return QVariant::fromValue(ColumnBase::TableEdit_Full);
if (column == mColumns.mBloodType)
{
int mask = ESM::NPC::Skeleton | ESM::NPC::Metal;
if ((record.get().mFlags & mask) == ESM::NPC::Skeleton)
return 1;
if ((record.get().mFlags & mask) == ESM::NPC::Metal)
return 2;
return 0;
}
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
mColumns.mFlags.find (column);
@ -762,6 +801,17 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
npc.mHair = value.toString().toUtf8().constData();
else if (column==mColumns.mHead)
npc.mHead = value.toString().toUtf8().constData();
else if (column == mColumns.mBloodType)
{
int mask = ~(ESM::NPC::Skeleton | ESM::NPC::Metal);
if (value.toInt() == 1)
npc.mFlags = (npc.mFlags & mask) | ESM::NPC::Skeleton;
else if (value.toInt() == 2)
npc.mFlags = (npc.mFlags & mask) | ESM::NPC::Metal;
else
npc.mFlags = npc.mFlags & mask;
}
else
{
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =

@ -694,13 +694,13 @@ namespace CSMWorld
class BookRefIdAdapter : public EnchantableRefIdAdapter<ESM::Book>
{
const RefIdColumn *mScroll;
const RefIdColumn *mBookType;
const RefIdColumn *mSkill;
const RefIdColumn *mText;
public:
BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *scroll,
BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *bookType,
const RefIdColumn *skill, const RefIdColumn *text);
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
@ -757,6 +757,7 @@ namespace CSMWorld
const RefIdColumn *mAttributes;
const RefIdColumn *mAttacks;
const RefIdColumn *mMisc;
const RefIdColumn *mBloodType;
CreatureColumns (const ActorColumns& actorColumns);
};
@ -849,6 +850,7 @@ namespace CSMWorld
const RefIdColumn *mAttributes; // depends on npc type
const RefIdColumn *mSkills; // depends on npc type
const RefIdColumn *mMisc; // may depend on npc type, e.g. FactionID
const RefIdColumn *mBloodType;
NpcColumns (const ActorColumns& actorColumns);
};

@ -291,8 +291,8 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.push_back (RefIdColumn (Columns::ColumnId_ArmorValue, ColumnBase::Display_Integer));
const RefIdColumn *armor = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_Scroll, ColumnBase::Display_Boolean));
const RefIdColumn *scroll = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_BookType, ColumnBase::Display_BookType));
const RefIdColumn *bookType = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_Skill, ColumnBase::Display_SkillId));
const RefIdColumn *skill = &mColumns.back();
@ -346,15 +346,11 @@ CSMWorld::RefIdCollection::RefIdCollection()
{ Columns::ColumnId_Flies, ESM::Creature::Flies },
{ Columns::ColumnId_Walks, ESM::Creature::Walks },
{ Columns::ColumnId_Essential, ESM::Creature::Essential },
{ Columns::ColumnId_SkeletonBlood, ESM::Creature::Skeleton },
{ Columns::ColumnId_MetalBlood, ESM::Creature::Metal },
{ -1, 0 }
};
// for re-use in NPC records
const RefIdColumn *essential = 0;
const RefIdColumn *skeletonBlood = 0;
const RefIdColumn *metalBlood = 0;
for (int i=0; sCreatureFlagTable[i].mName!=-1; ++i)
{
@ -364,11 +360,14 @@ CSMWorld::RefIdCollection::RefIdCollection()
switch (sCreatureFlagTable[i].mFlag)
{
case ESM::Creature::Essential: essential = &mColumns.back(); break;
case ESM::Creature::Skeleton: skeletonBlood = &mColumns.back(); break;
case ESM::Creature::Metal: metalBlood = &mColumns.back(); break;
}
}
mColumns.push_back(RefIdColumn(Columns::ColumnId_BloodType, ColumnBase::Display_BloodType));
// For re-use in NPC records.
const RefIdColumn *bloodType = &mColumns.back();
creatureColumns.mBloodType = bloodType;
creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn));
// Nested table
@ -497,9 +496,8 @@ CSMWorld::RefIdCollection::RefIdCollection()
npcColumns.mFlags.insert (std::make_pair (autoCalc, ESM::NPC::Autocalc));
npcColumns.mFlags.insert (std::make_pair (skeletonBlood, ESM::NPC::Skeleton));
npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal));
// Re-used from Creature records.
npcColumns.mBloodType = bloodType;
// Need a way to add a table of stats and values (rather than adding a long list of
// entries in the dialogue subview) E.g. attributes+stats(health, mana, fatigue), skills
@ -659,7 +657,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
mAdapters.insert (std::make_pair (UniversalId::Type_Armor,
new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor, partRef)));
mAdapters.insert (std::make_pair (UniversalId::Type_Book,
new BookRefIdAdapter (enchantableColumns, scroll, skill, text)));
new BookRefIdAdapter (enchantableColumns, bookType, skill, text)));
mAdapters.insert (std::make_pair (UniversalId::Type_Clothing,
new ClothingRefIdAdapter (enchantableColumns, clothingType, partRef)));
mAdapters.insert (std::make_pair (UniversalId::Type_Container,

@ -107,6 +107,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
{ CSMWorld::ColumnBase::Display_IngredEffectId, CSMWorld::Columns::ColumnId_EffectId, true },
{ CSMWorld::ColumnBase::Display_EffectSkill, CSMWorld::Columns::ColumnId_Skill, false },
{ CSMWorld::ColumnBase::Display_EffectAttribute, CSMWorld::Columns::ColumnId_Attribute, false },
{ CSMWorld::ColumnBase::Display_BookType, CSMWorld::Columns::ColumnId_BookType, false},
{ CSMWorld::ColumnBase::Display_BloodType, CSMWorld::Columns::ColumnId_BloodType, false}
};
for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i)

@ -215,7 +215,9 @@ namespace MWBase
virtual std::string getSelectedSpell() = 0;
virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0;
virtual void setSelectedEnchantItem(const MWWorld::Ptr& item) = 0;
virtual const MWWorld::Ptr& getSelectedEnchantItem() const = 0;
virtual void setSelectedWeapon(const MWWorld::Ptr& item) = 0;
virtual const MWWorld::Ptr& getSelectedWeapon() const = 0;
virtual void unsetSelectedSpell() = 0;
virtual void unsetSelectedWeapon() = 0;

@ -572,6 +572,9 @@ namespace MWBase
/// Export scene graph to a file and return the filename.
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
virtual std::string exportSceneGraph(const MWWorld::Ptr& ptr) = 0;
/// Preload VFX associated with this effect list
virtual void preloadEffects(const ESM::EffectList* effectList) = 0;
};
}

@ -39,6 +39,7 @@ namespace MWGui
void setSelectedSpell(const std::string& spellId, int successChancePercent);
void setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent);
const MWWorld::Ptr& getSelectedEnchantItem();
void setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent);
void unsetSelectedSpell();
void unsetSelectedWeapon();

@ -1286,6 +1286,7 @@ namespace MWGui
void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
mSelectedSpell = spellId;
mSelectedEnchantItem = MWWorld::Ptr();
mHud->setSelectedSpell(spellId, successChancePercent);
const ESM::Spell* spell = mStore->get<ESM::Spell>().find(spellId);
@ -1295,6 +1296,7 @@ namespace MWGui
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item)
{
mSelectedEnchantItem = item;
mSelectedSpell = "";
const ESM::Enchantment* ench = mStore->get<ESM::Enchantment>()
.find(item.getClass().getEnchantment(item));
@ -1305,17 +1307,29 @@ namespace MWGui
mSpellWindow->setTitle(item.getClass().getName(item));
}
const MWWorld::Ptr &WindowManager::getSelectedEnchantItem() const
{
return mSelectedEnchantItem;
}
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item)
{
mSelectedWeapon = item;
int durabilityPercent =
static_cast<int>(item.getClass().getItemHealth(item) / static_cast<float>(item.getClass().getItemMaxHealth(item)) * 100);
mHud->setSelectedWeapon(item, durabilityPercent);
mInventoryWindow->setTitle(item.getClass().getName(item));
}
const MWWorld::Ptr &WindowManager::getSelectedWeapon() const
{
return mSelectedWeapon;
}
void WindowManager::unsetSelectedSpell()
{
mSelectedSpell = "";
mSelectedEnchantItem = MWWorld::Ptr();
mHud->unsetSelectedSpell();
MWWorld::Player* player = &MWBase::Environment::get().getWorld()->getPlayer();
@ -1327,6 +1341,7 @@ namespace MWGui
void WindowManager::unsetSelectedWeapon()
{
mSelectedWeapon = MWWorld::Ptr();
mHud->unsetSelectedWeapon();
mInventoryWindow->setTitle("#{sSkillHandtohand}");
}

@ -13,6 +13,8 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/ptr.hpp"
#include <components/settings/settings.hpp>
#include <components/to_utf8/to_utf8.hpp>
@ -244,7 +246,9 @@ namespace MWGui
virtual std::string getSelectedSpell() { return mSelectedSpell; }
virtual void setSelectedSpell(const std::string& spellId, int successChancePercent);
virtual void setSelectedEnchantItem(const MWWorld::Ptr& item);
virtual const MWWorld::Ptr& getSelectedEnchantItem() const;
virtual void setSelectedWeapon(const MWWorld::Ptr& item);
virtual const MWWorld::Ptr& getSelectedWeapon() const;
virtual void unsetSelectedSpell();
virtual void unsetSelectedWeapon();
@ -403,6 +407,8 @@ namespace MWGui
void onWindowChangeCoord(MyGUI::Window* _sender);
std::string mSelectedSpell;
MWWorld::Ptr mSelectedEnchantItem;
MWWorld::Ptr mSelectedWeapon;
std::stack<WindowModal*> mCurrentModals;

@ -426,6 +426,9 @@ namespace MWMechanics
MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor);
inv.setSelectedEnchantItem(inv.end());
}
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(mSpellId);
MWBase::Environment::get().getWorld()->preloadEffects(&spell->mEffects);
}
float ActionSpell::getCombatRange (bool& isRanged) const

@ -2,6 +2,7 @@
#include <stdexcept>
#include <limits>
#include <cstdlib>
#include <osg/Light>
#include <osg/LightModel>
@ -202,6 +203,7 @@ namespace MWRender
mObjects.reset(new Objects(mResourceSystem, sceneRoot, mUnrefQueue.get()));
if (getenv("OPENMW_DONT_PRECOMPILE") == NULL)
mViewer->setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation);
mResourceSystem->getSceneManager()->setIncrementalCompileOperation(mViewer->getIncrementalCompileOperation());

@ -10,6 +10,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/settings/settings.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -679,6 +680,35 @@ namespace MWWorld
return Ptr();
}
class PreloadMeshItem : public SceneUtil::WorkItem
{
public:
PreloadMeshItem(const std::string& mesh, Resource::SceneManager* sceneManager)
: mMesh(mesh), mSceneManager(sceneManager)
{
}
virtual void doWork()
{
try
{
mSceneManager->getTemplate(mMesh);
}
catch (std::exception& e)
{
}
}
private:
std::string mMesh;
Resource::SceneManager* mSceneManager;
};
void Scene::preload(const std::string &mesh)
{
if (!mRendering.getResourceSystem()->getSceneManager()->checkLoaded(mesh, mRendering.getReferenceTime()))
mRendering.getWorkQueue()->addWorkItem(new PreloadMeshItem(mesh, mRendering.getResourceSystem()->getSceneManager()));
}
void Scene::preloadCells(float dt)
{
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();

@ -132,6 +132,8 @@ namespace MWWorld
bool isCellActive(const CellStore &cell);
Ptr searchPtrViaActorId (int actorId);
void preload(const std::string& mesh);
};
}

@ -159,7 +159,7 @@ namespace MWWorld
mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mUserDataPath(userDataPath),
mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript),
mStartCell (startCell), mDistanceToFacedObject(-1), mTeleportEnabled(true),
mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0)
mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0), mSpellPreloadTimer(0.f)
{
mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode);
mRendering = new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath);
@ -1653,6 +1653,13 @@ namespace MWWorld
updateSoundListener();
updatePlayer(paused);
mSpellPreloadTimer -= duration;
if (mSpellPreloadTimer <= 0.f)
{
mSpellPreloadTimer = 0.1f;
preloadSpells();
}
}
void World::updatePlayer(bool paused)
@ -1709,7 +1716,39 @@ namespace MWWorld
if (result.mHit)
mRendering->getCamera()->setCameraDistance((result.mHitPos - focal).length() - radius, false, false);
}
}
void World::preloadSpells()
{
std::string selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell();
if (!selectedSpell.empty())
{
const ESM::Spell* spell = mStore.get<ESM::Spell>().search(selectedSpell);
if (spell)
preloadEffects(&spell->mEffects);
}
const MWWorld::Ptr& selectedEnchantItem = MWBase::Environment::get().getWindowManager()->getSelectedEnchantItem();
if (!selectedEnchantItem.isEmpty())
{
std::string enchantId = selectedEnchantItem.getClass().getEnchantment(selectedEnchantItem);
if (!enchantId.empty())
{
const ESM::Enchantment* ench = mStore.get<ESM::Enchantment>().search(selectedEnchantItem.getClass().getEnchantment(selectedEnchantItem));
if (ench)
preloadEffects(&ench->mEffects);
}
}
const MWWorld::Ptr& selectedWeapon = MWBase::Environment::get().getWindowManager()->getSelectedWeapon();
if (!selectedWeapon.isEmpty())
{
std::string enchantId = selectedWeapon.getClass().getEnchantment(selectedWeapon);
if (!enchantId.empty())
{
const ESM::Enchantment* ench = mStore.get<ESM::Enchantment>().search(enchantId);
if (ench && ench->mData.mType == ESM::Enchantment::WhenStrikes)
preloadEffects(&ench->mEffects);
}
}
}
void World::updateSoundListener()
@ -2803,7 +2842,6 @@ namespace MWWorld
if (!selectedSpell.empty())
{
const ESM::Spell* spell = getStore().get<ESM::Spell>().find(selectedSpell);
cast.cast(spell);
}
else if (actor.getClass().hasInventoryStore(actor))
@ -3439,4 +3477,30 @@ namespace MWWorld
return mPhysics->getHitDistance(weaponPos, target) - halfExtents.y();
}
void preload(MWWorld::Scene* scene, const ESMStore& store, const std::string& obj)
{
if (obj.empty())
return;
MWWorld::ManualRef ref(store, obj);
std::string model = ref.getPtr().getClass().getModel(ref.getPtr());
if (!model.empty())
scene->preload(model);
}
void World::preloadEffects(const ESM::EffectList *effectList)
{
for (std::vector<ESM::ENAMstruct>::const_iterator it = effectList->mList.begin(); it != effectList->mList.end(); ++it)
{
const ESM::MagicEffect *effect = mStore.get<ESM::MagicEffect>().find(it->mEffectID);
preload(mWorldScene, mStore, effect->mCasting);
preload(mWorldScene, mStore, effect->mHit);
if (it->mArea > 0)
preload(mWorldScene, mStore, effect->mArea);
if (it->mRange == ESM::RT_Target)
preload(mWorldScene, mStore, effect->mBolt);
}
}
}

@ -135,6 +135,8 @@ namespace MWWorld
void updateWindowManager ();
void updatePlayer(bool paused);
void preloadSpells();
MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true);
public: // FIXME
@ -174,6 +176,8 @@ namespace MWWorld
bool mGoToJail;
int mDaysInPrison;
float mSpellPreloadTimer;
float feetToGameUnits(float feet);
float getActivationDistancePlusTelekinesis();
@ -680,6 +684,9 @@ namespace MWWorld
/// Export scene graph to a file and return the filename.
/// \param ptr object to export scene graph for (if empty, export entire scene graph)
virtual std::string exportSceneGraph(const MWWorld::Ptr& ptr);
/// Preload VFX associated with this effect list
virtual void preloadEffects(const ESM::EffectList* effectList);
};
}

@ -49,6 +49,18 @@ osg::ref_ptr<osg::Object> ObjectCache::getRefFromObjectCache(const std::string&
else return 0;
}
bool ObjectCache::checkInObjectCache(const std::string &fileName, double timeStamp)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
ObjectCacheMap::iterator itr = _objectCache.find(fileName);
if (itr!=_objectCache.end())
{
itr->second.second = timeStamp;
return true;
}
else return false;
}
void ObjectCache::updateTimeStampOfObjectsInCacheWithExternalReferences(double referenceTime)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);

@ -64,6 +64,9 @@ class ObjectCache : public osg::Referenced
/** Get an ref_ptr<Object> from the object cache*/
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName);
/** Check if an object is in the cache, and if it is, update its usage time stamp. */
bool checkInObjectCache(const std::string& fileName, double timeStamp);
/** call releaseGLObjects on all objects attached to the object cache.*/
void releaseGLObjects(osg::State* state);

@ -272,6 +272,14 @@ namespace Resource
mShaderManager->setShaderPath(path);
}
bool SceneManager::checkLoaded(const std::string &name, double timeStamp)
{
std::string normalized = name;
mVFS->normalizeFilename(normalized);
return mCache->checkInObjectCache(normalized, timeStamp);
}
/// @brief Callback to read image files from the VFS.
class ImageReadCallback : public osgDB::ReadFileCallback
{

@ -77,6 +77,9 @@ namespace Resource
void setShaderPath(const std::string& path);
/// Check if a given scene is loaded and if so, update its usage timestamp to prevent it from being unloaded
bool checkLoaded(const std::string& name, double referenceTime);
/// Get a read-only copy of this scene "template"
/// @note If the given filename does not exist or fails to load, an error marker mesh will be used instead.
/// If even the error marker mesh can not be found, an exception is thrown.

Loading…
Cancel
Save