diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 3c4714d55..4a3c418f6 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -410,13 +410,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mVerboseScripts, *mScriptContext)); // Create game mechanics system - mEnvironment.setMechanicsManager (new MWMechanics::MechanicsManager); + MWMechanics::MechanicsManager* mechanics = new MWMechanics::MechanicsManager; + mEnvironment.setMechanicsManager (mechanics); // Create dialog system mEnvironment.setJournal (new MWDialogue::Journal); mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions, mVerboseScripts, mTranslationDataStorage)); mEnvironment.getWorld()->renderPlayer(); + mechanics->buildPlayer(); + window->updatePlayer(); if (!mNewGame) { diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 786299580..35a6d17a3 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -254,7 +254,7 @@ namespace MWClass void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { - renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr)); + renderingInterface.getActors().insertNPC(ptr); } void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 1e203dcd0..09f692e4f 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -47,8 +47,6 @@ namespace MWGui , mIngredients (4) , mSortModel(NULL) { - mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); - getWidget(mCreateButton, "CreateButton"); getWidget(mCancelButton, "CancelButton"); getWidget(mIngredients[0], "Ingredient1"); @@ -145,6 +143,8 @@ namespace MWGui void AlchemyWindow::open() { + mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); mSortModel = new SortFilterItemModel(model); mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients); diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index da7ce6557..8f8744917 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -63,8 +63,6 @@ namespace MWGui mItemView->eventItemClicked += MyGUI::newDelegate(this, &InventoryWindow::onItemSelected); mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &InventoryWindow::onBackgroundSelected); - updatePlayer(); - mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); @@ -75,8 +73,6 @@ namespace MWGui setCoord(mPositionInventory.left, mPositionInventory.top, mPositionInventory.width, mPositionInventory.height); onWindowResize(static_cast(mMainWidget)); - - mPreview.setup(); } void InventoryWindow::updatePlayer() diff --git a/apps/openmw/mwgui/itemview.cpp b/apps/openmw/mwgui/itemview.cpp index f9a900eba..3be133a3c 100644 --- a/apps/openmw/mwgui/itemview.cpp +++ b/apps/openmw/mwgui/itemview.cpp @@ -45,7 +45,6 @@ void ItemView::setModel(ItemModel *model) { delete mModel; mModel = model; - update(); } void ItemView::initialiseOverride() diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index e9b2c0fa8..61ac2c7b2 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -51,8 +51,6 @@ namespace MWGui setCoord(498, 300, 302, 300); - updateSpells(); - mMainWidget->castType()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize); } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 76ae65eb9..83325de23 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -246,9 +246,6 @@ namespace MWGui mPlayerSkillValues.insert(std::make_pair(ESM::Skill::sSkillIds[i], MWMechanics::Stat())); } - unsetSelectedSpell(); - unsetSelectedWeapon(); - // Set up visibility updateVisible(); @@ -1333,6 +1330,9 @@ namespace MWGui void WindowManager::updatePlayer() { + unsetSelectedSpell(); + unsetSelectedWeapon(); + mInventoryWindow->updatePlayer(); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 54b02fb52..bbebcd693 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -167,7 +167,7 @@ namespace MWMechanics : mUpdatePlayer (true), mClassSelected (false), mRaceSelected (false) { - buildPlayer(); + //buildPlayer no longer here, needs to be done explicitely after all subsystems are up and running } void MechanicsManager::add(const MWWorld::Ptr& ptr) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index ad07562c7..aedb84b29 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -33,12 +33,12 @@ namespace MWMechanics Objects mObjects; Actors mActors; + public: + void buildPlayer(); ///< build player according to stored class/race/birthsign information. Will /// default to the values of the ESM::NPC object, if no explicit information is given. - public: - MechanicsManager(); virtual void add (const MWWorld::Ptr& ptr); diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index 566b6fa81..1bdec6e19 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -68,13 +68,16 @@ void Actors::insertBegin(const MWWorld::Ptr &ptr) ptr.getRefData().setBaseNode(insert); } -void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv) +void Actors::insertNPC(const MWWorld::Ptr& ptr) { insertBegin(ptr); - NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), inv, RV_Actors); + NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), RV_Actors); delete mAllActors[ptr]; mAllActors[ptr] = anim; mRendering->addWaterRippleEmitter (ptr); + + // Create CustomData, will do autoEquip and trigger animation parts update + ptr.getClass().getInventoryStore(ptr); } void Actors::insertCreature (const MWWorld::Ptr& ptr) { diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp index 4547db9ad..61a0808f5 100644 --- a/apps/openmw/mwrender/actors.hpp +++ b/apps/openmw/mwrender/actors.hpp @@ -39,7 +39,7 @@ namespace MWRender void setRootNode(Ogre::SceneNode* root); - void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv); + void insertNPC(const MWWorld::Ptr& ptr); void insertCreature (const MWWorld::Ptr& ptr); void insertActivator (const MWWorld::Ptr& ptr); bool deleteObject (const MWWorld::Ptr& ptr); diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index e42218bc2..17fca8df3 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -70,8 +70,9 @@ namespace MWRender mNode = renderRoot->createChildSceneNode(); - mAnimation = new NpcAnimation(mCharacter, mNode, MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter), + mAnimation = new NpcAnimation(mCharacter, mNode, 0, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal)); + mAnimation->updateParts(); Ogre::Vector3 scale = mNode->getScale(); mCamera->setPosition(mPosition * scale); @@ -112,10 +113,9 @@ namespace MWRender { assert(mAnimation); delete mAnimation; - mAnimation = 0; - - mAnimation = new NpcAnimation(mCharacter, mNode, MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter), + mAnimation = new NpcAnimation(mCharacter, mNode, 0, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal)); + mAnimation->updateParts(); float scale=1.f; MWWorld::Class::get(mCharacter).adjustScale(mCharacter, scale); @@ -193,7 +193,7 @@ namespace MWRender else if(mAnimation->getInfo("torch")) mAnimation->disable("torch"); - mAnimation->updateParts(true); + mAnimation->updateParts(); mAnimation->runAnimation(0.0f); mViewport->setDimensions (0, 0, std::min(1.f, float(sizeX) / float(512)), std::min(1.f, float(sizeY) / float(1024))); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 9ffe53eab..2cbc76711 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -64,25 +64,11 @@ NpcAnimation::~NpcAnimation() } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags, ViewMode viewMode) +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int visibilityFlags, ViewMode viewMode) : Animation(ptr, node), mStateID(-1), - mTimeToChange(0), mVisibilityFlags(visibilityFlags), - mRobe(inv.end()), - mHelmet(inv.end()), - mShirt(inv.end()), - mCuirass(inv.end()), - mGreaves(inv.end()), - mPauldronL(inv.end()), - mPauldronR(inv.end()), - mBoots(inv.end()), - mPants(inv.end()), - mGloveL(inv.end()), - mGloveR(inv.end()), - mSkirtIter(inv.end()), - mWeapon(inv.end()), - mShield(inv.end()), + mViewMode(viewMode), mShowWeapons(false), mFirstPersonOffset(0.f, 0.f, 0.f) @@ -94,8 +80,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor mPartslots[i] = -1; //each slot is empty mPartPriorities[i] = 0; } - - updateNpcBase(); } void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) @@ -173,56 +157,50 @@ void NpcAnimation::updateNpcBase() for(size_t i = 0;i < ESM::PRT_Count;i++) removeIndividualPart((ESM::PartReferenceType)i); - updateParts(true); + updateParts(); } -void NpcAnimation::updateParts(bool forceupdate) +void NpcAnimation::updateParts() { + if (!mSkelBase) + { + // First update? + updateNpcBase(); + return; + } + + const MWWorld::Class &cls = MWWorld::Class::get(mPtr); + MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); + static const struct { - MWWorld::ContainerStoreIterator NpcAnimation::*mPart; int mSlot; int mBasePriority; } slotlist[] = { // FIXME: Priority is based on the number of reserved slots. There should be a better way. - { &NpcAnimation::mRobe, MWWorld::InventoryStore::Slot_Robe, 12 }, - { &NpcAnimation::mSkirtIter, MWWorld::InventoryStore::Slot_Skirt, 3 }, - { &NpcAnimation::mHelmet, MWWorld::InventoryStore::Slot_Helmet, 0 }, - { &NpcAnimation::mCuirass, MWWorld::InventoryStore::Slot_Cuirass, 0 }, - { &NpcAnimation::mGreaves, MWWorld::InventoryStore::Slot_Greaves, 0 }, - { &NpcAnimation::mPauldronL, MWWorld::InventoryStore::Slot_LeftPauldron, 0 }, - { &NpcAnimation::mPauldronR, MWWorld::InventoryStore::Slot_RightPauldron, 0 }, - { &NpcAnimation::mBoots, MWWorld::InventoryStore::Slot_Boots, 0 }, - { &NpcAnimation::mGloveL, MWWorld::InventoryStore::Slot_LeftGauntlet, 0 }, - { &NpcAnimation::mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet, 0 }, - { &NpcAnimation::mShirt, MWWorld::InventoryStore::Slot_Shirt, 0 }, - { &NpcAnimation::mPants, MWWorld::InventoryStore::Slot_Pants, 0 }, - { &NpcAnimation::mShield, MWWorld::InventoryStore::Slot_CarriedLeft, 0 }, - { &NpcAnimation::mWeapon, MWWorld::InventoryStore::Slot_CarriedRight, 0 } + { MWWorld::InventoryStore::Slot_Robe, 12 }, + { MWWorld::InventoryStore::Slot_Skirt, 3 }, + { MWWorld::InventoryStore::Slot_Helmet, 0 }, + { MWWorld::InventoryStore::Slot_Cuirass, 0 }, + { MWWorld::InventoryStore::Slot_Greaves, 0 }, + { MWWorld::InventoryStore::Slot_LeftPauldron, 0 }, + { MWWorld::InventoryStore::Slot_RightPauldron, 0 }, + { MWWorld::InventoryStore::Slot_Boots, 0 }, + { MWWorld::InventoryStore::Slot_LeftGauntlet, 0 }, + { MWWorld::InventoryStore::Slot_RightGauntlet, 0 }, + { MWWorld::InventoryStore::Slot_Shirt, 0 }, + { MWWorld::InventoryStore::Slot_Pants, 0 }, + { MWWorld::InventoryStore::Slot_CarriedLeft, 0 }, + { MWWorld::InventoryStore::Slot_CarriedRight, 0 } }; static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]); - const MWWorld::Class &cls = MWWorld::Class::get(mPtr); - MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); - for(size_t i = 0;!forceupdate && i < slotlistsize;i++) - { - MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].mSlot); - if(this->*slotlist[i].mPart != iter) - { - forceupdate = true; - break; - } - } - if(!forceupdate) - return; - for(size_t i = 0;i < slotlistsize && mViewMode != VM_HeadOnly;i++) { MWWorld::ContainerStoreIterator store = inv.getSlot(slotlist[i].mSlot); - this->*slotlist[i].mPart = store; removePartGroup(slotlist[i].mSlot); - if(this->*slotlist[i].mPart == inv.end()) + if(store == inv.end()) continue; if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Helmet) @@ -439,13 +417,6 @@ NifOgre::ObjectList NpcAnimation::insertBoundedPart(const std::string &model, in Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) { - if(mTimeToChange <= 0.0f) - { - mTimeToChange = 0.2f; - updateParts(); - } - mTimeToChange -= timepassed; - Ogre::Vector3 ret = Animation::runAnimation(timepassed); Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); @@ -599,11 +570,10 @@ void NpcAnimation::showWeapons(bool showWeapon) if(showWeapon) { MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); - mWeapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(mWeapon != inv.end()) // special case for weapons + MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if(weapon != inv.end()) // special case for weapons { - MWWorld::Ptr weapon = *mWeapon; - std::string mesh = MWWorld::Class::get(weapon).getModel(weapon); + std::string mesh = MWWorld::Class::get(*weapon).getModel(*weapon); addOrReplaceIndividualPart(ESM::PRT_Weapon, MWWorld::InventoryStore::Slot_CarriedRight, 1, mesh); } } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index b1abf97af..5bd29cff6 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -43,22 +43,6 @@ private: ViewMode mViewMode; bool mShowWeapons; - float mTimeToChange; - MWWorld::ContainerStoreIterator mRobe; - MWWorld::ContainerStoreIterator mHelmet; - MWWorld::ContainerStoreIterator mShirt; - MWWorld::ContainerStoreIterator mCuirass; - MWWorld::ContainerStoreIterator mGreaves; - MWWorld::ContainerStoreIterator mPauldronL; - MWWorld::ContainerStoreIterator mPauldronR; - MWWorld::ContainerStoreIterator mBoots; - MWWorld::ContainerStoreIterator mPants; - MWWorld::ContainerStoreIterator mGloveL; - MWWorld::ContainerStoreIterator mGloveR; - MWWorld::ContainerStoreIterator mSkirtIter; - MWWorld::ContainerStoreIterator mWeapon; - MWWorld::ContainerStoreIterator mShield; - int mVisibilityFlags; int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty @@ -78,8 +62,7 @@ private: void addPartGroup(int group, int priority, const std::vector &parts); public: - NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, - MWWorld::InventoryStore& inv, int visibilityFlags, + NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int visibilityFlags, ViewMode viewMode=VM_Normal); virtual ~NpcAnimation(); @@ -89,7 +72,7 @@ public: void setViewMode(ViewMode viewMode); - void updateParts(bool forceupdate = false); + void updateParts(); /// \brief Applies a translation to the arms and hands. /// This may be called multiple times before the animation diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 817a2d236..531e64629 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -336,6 +336,7 @@ void RenderingManager::updateAnimParts(const MWWorld::Ptr& ptr) else if(MWWorld::Class::get(ptr).isActor()) anim = dynamic_cast(mActors.getAnimation(ptr)); + assert(anim); if(anim) anim->updateParts(); } @@ -926,18 +927,17 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) { if(!mPlayerAnimation) { - mPlayerAnimation = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), - MWWorld::Class::get(ptr).getInventoryStore(ptr), - RV_Actors); + mPlayerAnimation = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), RV_Actors); } else { // Reconstruct the NpcAnimation in-place mPlayerAnimation->~NpcAnimation(); - new(mPlayerAnimation) NpcAnimation(ptr, ptr.getRefData().getBaseNode(), - MWWorld::Class::get(ptr).getInventoryStore(ptr), - RV_Actors); + new(mPlayerAnimation) NpcAnimation(ptr, ptr.getRefData().getBaseNode(), RV_Actors); } + // Ensure CustomData -> autoEquip -> animation update + ptr.getClass().getInventoryStore(ptr); + mCamera->setAnimation(mPlayerAnimation); mWater->removeEmitter(ptr); mWater->addEmitter(ptr); diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index d032b2613..456c07202 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -45,6 +45,7 @@ void MWWorld::InventoryStore::initSlots (TSlots& slots_) MWWorld::InventoryStore::InventoryStore() : mSelectedEnchantItem(end()) , mUpdatesEnabled (true) + , mFirstAutoEquip(true) { initSlots (mSlots); } @@ -54,6 +55,7 @@ MWWorld::InventoryStore::InventoryStore (const InventoryStore& store) , mSelectedEnchantItem(end()) { mMagicEffects = store.mMagicEffects; + mFirstAutoEquip = store.mFirstAutoEquip; mSelectedEnchantItem = store.mSelectedEnchantItem; mPermanentMagicEffectMagnitudes = store.mPermanentMagicEffectMagnitudes; copySlots (store); @@ -62,6 +64,7 @@ MWWorld::InventoryStore::InventoryStore (const InventoryStore& store) MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStore& store) { mMagicEffects = store.mMagicEffects; + mFirstAutoEquip = store.mFirstAutoEquip; mPermanentMagicEffectMagnitudes = store.mPermanentMagicEffectMagnitudes; ContainerStore::operator= (store); mSlots.clear(); @@ -256,6 +259,7 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& npc) updateMagicEffects(npc); flagAsModified(); } + mFirstAutoEquip = false; } const MWMechanics::MagicEffects& MWWorld::InventoryStore::getMagicEffects() const @@ -308,8 +312,10 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor) // so it doesn't really matter if both items will get the same magnitude. *Extreme* edge case. mPermanentMagicEffectMagnitudes[(**iter).getCellRef().mRefID] = random; - // TODO: What do we do if no animation yet? - if (MWBase::Environment::get().getWorld()->getAnimation(actor)) + // During first auto equip, we don't play any sounds. + // Basically we don't want sounds when the actor is first loaded, + // the items should appear as if they'd always been equipped. + if (!mFirstAutoEquip) { // Only the sound of the first effect plays if (effectIt == enchantment.mEffects.mList.begin()) @@ -324,13 +330,15 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor) else sndMgr->playSound3D(actor, schools[magicEffect->mData.mSchool]+" hit", 1.0f, 1.0f); } + } - if (!magicEffect->mHit.empty()) - { - const ESM::Static* castStatic = MWBase::Environment::get().getWorld()->getStore().get().find (magicEffect->mHit); - bool loop = magicEffect->mData.mFlags & ESM::MagicEffect::ContinuousVfx; + if (!magicEffect->mHit.empty()) + { + const ESM::Static* castStatic = MWBase::Environment::get().getWorld()->getStore().get().find (magicEffect->mHit); + bool loop = magicEffect->mData.mFlags & ESM::MagicEffect::ContinuousVfx; + // Similar as above, we don't want particles during first autoequip either, unless they're continuous. + if (!mFirstAutoEquip || loop) MWBase::Environment::get().getWorld()->getAnimation(actor)->addEffect("meshes\\" + castStatic->mModel, magicEffect->mIndex, loop, ""); - } } } diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index bccdcb991..f38e340ca 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -49,6 +49,8 @@ namespace MWWorld // This is disabled during autoequip to avoid excessive updates bool mUpdatesEnabled; + bool mFirstAutoEquip; + // Vanilla allows permanent effects with a random magnitude, so it needs to be stored here. // We also need this to only play sounds and particle effects when the item is equipped, rather than on every update. typedef std::map > TEffectMagnitudes; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 0c98ca504..254ad98cf 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -118,8 +118,6 @@ namespace MWWorld void Scene::loadCell (Ptr::CellStore *cell, Loading::Listener* loadingListener) { - // register local scripts - MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell); std::pair result = mActiveCells.insert(cell); if(result.second) @@ -157,6 +155,10 @@ namespace MWWorld mRendering.requestMap(cell); mRendering.configureAmbient(*cell); } + + // register local scripts + // ??? Should this go into the above if block ??? + MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell); } void Scene::playerCellChange(MWWorld::CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index bdd5d58c8..dd29c33a9 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2239,7 +2239,6 @@ namespace MWWorld void World::updateAnimParts(const Ptr& actor) { - if (actor.mCell && actor.mCell == mWorldScene->getCurrentCell()) - mRendering->updateAnimParts(actor); + mRendering->updateAnimParts(actor); } }