diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 8141af712..ae1497a08 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -421,6 +421,8 @@ namespace MWBase const MWWorld::Ptr& actor, const std::string& sourceName) = 0; virtual void breakInvisibility (const MWWorld::Ptr& actor) = 0; + + virtual bool isNight() const = 0; }; } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index da3ed2523..4f7754951 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -707,17 +707,30 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun } } - - MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name()) + if (MWBase::Environment::get().getWorld()->isNight()) { + MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name()) + { + mAnimation->showLights(true); if(!mAnimation->isPlaying("torch")) - mAnimation->play("torch", Priority_Torch, - MWRender::Animation::Group_LeftArm, false, - 1.0f, "start", "stop", 0.0f, (~(size_t)0)); + mAnimation->play("torch", Priority_Torch, + MWRender::Animation::Group_LeftArm, false, + 1.0f, "start", "stop", 0.0f, (~(size_t)0)); + } + else if (mAnimation->isPlaying("torch")) + { + mAnimation->disable("torch"); + mAnimation->showLights(false); + mAnimation->showShield(true); + } } - else if(mAnimation->isPlaying("torch")) + else + { mAnimation->disable("torch"); + mAnimation->showLights(false); + mAnimation->showShield(true); + } return forcestateupdate; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index aa04e39e2..16af6d5a6 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -275,6 +275,7 @@ public: virtual void showWeapons(bool showWeapon); virtual void showShield(bool show) {} + virtual void showLights(bool show) {} void enableLights(bool enable); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index eb0c5dfbc..6e363ab88 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -118,6 +118,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v mViewMode(viewMode), mShowWeapons(false), mShowShield(true), + mShowLights(false), mFirstPersonOffset(0.f, 0.f, 0.f), mAlpha(1.f) { @@ -320,6 +321,7 @@ void NpcAnimation::updateParts() showWeapons(mShowWeapons); showShield(mShowShield); + showLights(mShowLights); // Remember body parts so we only have to search through the store once for each race/gender/viewmode combination static std::map< std::pair,std::vector > sRaceMapping; @@ -660,21 +662,12 @@ void NpcAnimation::showShield(bool show) MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (shield != inv.end() && shield->getTypeName() == typeid(ESM::Light).name()) - { - // ... Except for lights, which are still shown during spellcasting since they - // have their own (one-handed) casting animations - show = true; - } - if(show && shield != inv.end()) + if(show && shield != inv.end() && shield->getTypeName() != typeid(ESM::Light).name()) { Ogre::Vector3 glowColor = getEnchantmentColor(*shield); std::string mesh = MWWorld::Class::get(*shield).getModel(*shield); addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, mesh, !shield->getClass().getEnchantment(*shield).empty(), &glowColor); - - if (shield->getTypeName() == typeid(ESM::Light).name()) - addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], shield->get()->mBase); } else { @@ -682,6 +675,27 @@ void NpcAnimation::showShield(bool show) } } +void NpcAnimation::showLights(bool show) +{ + mShowLights = show; + MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); + MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + + if(show && shield != inv.end() && shield->getTypeName() == typeid(ESM::Light).name()) + { + Ogre::Vector3 glowColor = getEnchantmentColor(*shield); + std::string mesh = MWWorld::Class::get(*shield).getModel(*shield); + addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, + mesh, !shield->getClass().getEnchantment(*shield).empty(), &glowColor); + addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], shield->get()->mBase); + } + else + { + removeIndividualPart(ESM::PRT_Shield); + } +} + + void NpcAnimation::permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew, bool playSound) { // During first auto equip, we don't play any sounds. diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 04dde87c7..0500b46c6 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -54,6 +54,7 @@ private: ViewMode mViewMode; bool mShowWeapons; bool mShowShield; + bool mShowLights; int mVisibilityFlags; @@ -101,6 +102,7 @@ public: virtual void showWeapons(bool showWeapon); virtual void showShield(bool showShield); + virtual void showLights(bool showLights); void setViewMode(ViewMode viewMode); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 8b05d2256..c355d86a8 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -707,3 +707,8 @@ float WeatherManager::getWindSpeed() const { return mWindSpeed; } + +bool WeatherManager::isNight() const +{ + return (mHour < mSunriseTime || mHour > mNightStart - 1); +} diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 80cbe0418..4c412c449 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -152,6 +152,8 @@ namespace MWWorld void modRegion(const std::string ®ionid, const std::vector &chances); + bool isNight() const; + private: float mHour; int mDay, mMonth; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f64d22122..479feab3e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2244,4 +2244,9 @@ namespace MWWorld actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Invisibility); actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility); } + + bool World::isNight() const + { + return mWeatherManager->isNight(); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index c8133441d..2f8994c8e 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -506,6 +506,7 @@ namespace MWWorld const MWWorld::Ptr& actor, const std::string& sourceName); virtual void breakInvisibility (const MWWorld::Ptr& actor); + virtual bool isNight() const; }; }