From 100edda8c086f72599884bafd591d1bb260de76f Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sat, 28 Dec 2013 16:15:34 +0100 Subject: [PATCH 1/5] Fixes #417: Apply weather instantly when teleporting Change speed of weather transition from blight to other (twice fast as normal) and from other to blight (four times faster than normal). Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwworld/weather.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 8b05d2256a..5641d34930 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -195,7 +195,22 @@ void WeatherManager::setWeather(const String& weather, bool instant) } mNextWeather = weather; - mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600; + + /** + * Issue #417: + * + * Change speed of weather transition from blight to other (twice fast as normal) + * and from other to blight (four times faster than normal) + */ + mRemainingTransitionTime = (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600.f); + if (mCurrentWeather == "blight" && mNextWeather != "") + { + mRemainingTransitionTime *= 0.25f; + } + else if (mNextWeather == "blight") + { + mRemainingTransitionTime *= 0.5f; + } } mFirstUpdate = false; } From faf8011c48d0e5bf553ef3de08c2a474e95941e3 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 29 Dec 2013 12:47:44 +0100 Subject: [PATCH 2/5] Fixes #417: Apply weather instantly when teleporting Removed changing speed of weather transition introduced in previous commit. Instead try to detect player "teleporting" (ie. coc), and then switch instantly to the next weather type. Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwworld/weather.cpp | 59 +++++++++++++++++++++++--------- apps/openmw/mwworld/weather.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 20 ++++++++++- apps/openmw/mwworld/worldimp.hpp | 2 +- 4 files changed, 64 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 5641d34930..4a8def1847 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -195,22 +195,7 @@ void WeatherManager::setWeather(const String& weather, bool instant) } mNextWeather = weather; - - /** - * Issue #417: - * - * Change speed of weather transition from blight to other (twice fast as normal) - * and from other to blight (four times faster than normal) - */ - mRemainingTransitionTime = (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600.f); - if (mCurrentWeather == "blight" && mNextWeather != "") - { - mRemainingTransitionTime *= 0.25f; - } - else if (mNextWeather == "blight") - { - mRemainingTransitionTime *= 0.5f; - } + mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600.f; } mFirstUpdate = false; } @@ -722,3 +707,45 @@ float WeatherManager::getWindSpeed() const { return mWindSpeed; } + +void WeatherManager::switchToNextWeather(bool instantly) +{ + const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); + if (!exterior) + { + mRendering->sunDisable(false); + mRendering->skyDisable(); + mRendering->getSkyManager()->setLightningStrength(0.f); + stopSounds(true); + return; + } + + // Exterior + std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); + + if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) + { + mCurrentRegion = regionstr; + mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; + + std::string weatherType = "clear"; + + if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) + { + weatherType = mRegionOverrides[regionstr]; + } + else + { + // get weather probabilities for the current region + const ESM::Region *region = + MWBase::Environment::get().getWorld()->getStore().get().search (regionstr); + + if (region != 0) + { + weatherType = nextWeather(region); + } + } + + setWeather(weatherType, instantly); + } +} diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 80cbe0418e..2111cac39a 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -128,6 +128,7 @@ namespace MWWorld * @param ID of the weather setting to shift to */ void changeWeather(const std::string& region, const unsigned int id); + void switchToNextWeather(bool instantly = true); /** * Per-frame update diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 448211bc2e..9ce4f47d28 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1287,7 +1287,7 @@ namespace MWWorld mRendering->playVideo(mFallback.getFallbackString("Movies_New_Game"), true); } - mWeatherManager->update (duration); + updateWeather(duration); mWorldScene->update (duration, paused); @@ -2244,4 +2244,22 @@ namespace MWWorld actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Invisibility); actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility); } + + void World::updateWeather(float duration) + { + static const float TELEPORTATION_STEP_THRESHOLD = 256.f; + static ESM::Position lastPlayerPos; + ESM::Position currentPos = mPlayer->getPlayer().getRefData().getPosition(); + + if (fabs(fabs(lastPlayerPos.pos[0]) - fabs(currentPos.pos[0])) >= TELEPORTATION_STEP_THRESHOLD + || fabs(fabs(lastPlayerPos.pos[1]) - fabs(currentPos.pos[1])) >= TELEPORTATION_STEP_THRESHOLD) + { + lastPlayerPos = currentPos; + mWeatherManager->switchToNextWeather(true); + } + else + { + mWeatherManager->update (duration); + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 5a51cb773c..346c64d82d 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -106,7 +106,7 @@ namespace MWWorld }; std::map mProjectiles; - + void updateWeather(float duration); int getDaysPerMonth (int month) const; void rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust); From c65f018760539e9a990782ad10fbf6c9f81908f3 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 29 Dec 2013 15:09:49 +0100 Subject: [PATCH 3/5] Fixes #417: Apply weather instantly when teleporting Corrected constant name. Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwworld/worldimp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9ce4f47d28..18dc77d3aa 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2247,12 +2247,12 @@ namespace MWWorld void World::updateWeather(float duration) { - static const float TELEPORTATION_STEP_THRESHOLD = 256.f; + static const float teleportationStepTreshold = 256.f; static ESM::Position lastPlayerPos; ESM::Position currentPos = mPlayer->getPlayer().getRefData().getPosition(); - if (fabs(fabs(lastPlayerPos.pos[0]) - fabs(currentPos.pos[0])) >= TELEPORTATION_STEP_THRESHOLD - || fabs(fabs(lastPlayerPos.pos[1]) - fabs(currentPos.pos[1])) >= TELEPORTATION_STEP_THRESHOLD) + if (fabs(fabs(lastPlayerPos.pos[0]) - fabs(currentPos.pos[0])) >= teleportationStepTreshold + || fabs(fabs(lastPlayerPos.pos[1]) - fabs(currentPos.pos[1])) >= teleportationStepTreshold) { lastPlayerPos = currentPos; mWeatherManager->switchToNextWeather(true); From e9844e1b3724c8cecdf89631023cc3d7e716a352 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Tue, 31 Dec 2013 20:40:23 +0100 Subject: [PATCH 4/5] Fixes #417: Apply weather instantly when teleporting Changed teleporting detection from "position tracking" to manually setting "teleportation" flag ( player->setTeleported(true) ). Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwmechanics/spellcasting.cpp | 7 ++ apps/openmw/mwscript/cellextensions.cpp | 14 ++- .../mwscript/transformationextensions.cpp | 12 +++ apps/openmw/mwworld/actionteleport.cpp | 8 +- apps/openmw/mwworld/player.cpp | 13 ++- apps/openmw/mwworld/player.hpp | 5 +- apps/openmw/mwworld/weather.cpp | 101 ++++++------------ apps/openmw/mwworld/worldimp.cpp | 23 ++-- 8 files changed, 92 insertions(+), 91 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 74816d12e2..411fa6bdfb 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -7,6 +7,7 @@ #include "../mwworld/containerstore.hpp" +#include "../mwworld/player.hpp" #include "../mwrender/animation.hpp" @@ -240,11 +241,15 @@ namespace MWMechanics else if (effectId == ESM::MagicEffect::DivineIntervention) { + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + // We need to be able to get the world location of an interior cell before implementing this // or alternatively, the last known exterior location of the player, which is how vanilla does it. } else if (effectId == ESM::MagicEffect::AlmsiviIntervention) { + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + // Same as above } @@ -254,6 +259,8 @@ namespace MWMechanics } else if (effectId == ESM::MagicEffect::Recall) { + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + // TODO } } diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 316f912dad..f26602f7a7 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -43,10 +43,13 @@ namespace MWScript ESM::Position pos; MWBase::World *world = MWBase::Environment::get().getWorld(); - if (world->findExteriorPosition(cell, pos)) { + world->getPlayer().setTeleported(true); + if (world->findExteriorPosition(cell, pos)) + { world->changeToExteriorCell(pos); } - else { + else + { // Change to interior even if findInteriorPosition() // yields false. In this case position will be zero-point. world->findInteriorPosition(cell, pos); @@ -68,13 +71,14 @@ namespace MWScript runtime.pop(); ESM::Position pos; - - MWBase::Environment::get().getWorld()->indexToPosition (x, y, pos.pos[0], pos.pos[1], true); + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->getPlayer().setTeleported(true); + world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true); pos.pos[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; - MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); + world->changeToExteriorCell (pos); } }; diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index ae9ac041e1..47a632ae98 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -207,6 +207,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); + if (ptr.getRefData().getHandle() == "player") + { + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + } std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -271,6 +275,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); + if (ptr.getRefData().getHandle() == "player") + { + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + } Interpreter::Type_Float x = runtime[0].mFloat; runtime.pop(); @@ -328,6 +336,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); + if (ptr.getRefData().getHandle() == "player") + { + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + } Interpreter::Type_Float x = runtime[0].mFloat; runtime.pop(); diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index ae5ffc3b90..773fde81e3 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -3,6 +3,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "player.hpp" namespace MWWorld { @@ -14,9 +15,12 @@ namespace MWWorld void ActionTeleport::executeImp (const Ptr& actor) { + MWBase::World* world = MWBase::Environment::get().getWorld(); + world->getPlayer().setTeleported(true); + if (mCellName.empty()) - MWBase::Environment::get().getWorld()->changeToExteriorCell (mPosition); + world->changeToExteriorCell (mPosition); else - MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, mPosition); + world->changeToInteriorCell (mCellName, mPosition); } } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index e26c2e2a52..291490ae04 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -19,7 +19,8 @@ namespace MWWorld Player::Player (const ESM::NPC *player, const MWBase::World& world) : mCellStore(0), mAutoMove(false), - mForwardBackward (0) + mForwardBackward (0), + mTeleported(false) { mPlayer.mBase = player; mPlayer.mRef.mRefID = "player"; @@ -145,4 +146,14 @@ namespace MWWorld MWWorld::Ptr ptr = getPlayer(); return MWWorld::Class::get(ptr).getNpcStats(ptr).getDrawState(); } + + bool Player::wasTeleported() const + { + return mTeleported; + } + + void Player::setTeleported(bool teleported) + { + mTeleported = teleported; + } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index d78b1901c4..55d8ff2c88 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -30,7 +30,7 @@ namespace MWWorld bool mAutoMove; int mForwardBackward; - + bool mTeleported; public: Player(const ESM::NPC *player, const MWBase::World& world); @@ -64,6 +64,9 @@ namespace MWWorld void yaw(float yaw); void pitch(float pitch); void roll(float roll); + + bool wasTeleported() const; + void setTeleported(bool teleported); }; } #endif diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 4a8def1847..124fc14ab2 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -324,42 +324,7 @@ void WeatherManager::update(float duration) mWeatherUpdateTime -= timePassed; - const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); - if (!exterior) - { - mRendering->sunDisable(false); - mRendering->skyDisable(); - mRendering->getSkyManager()->setLightningStrength(0.f); - stopSounds(true); - return; - } - - // Exterior - std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); - - if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) - { - mCurrentRegion = regionstr; - mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; - - std::string weatherType = "clear"; - - if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) - weatherType = mRegionOverrides[regionstr]; - else - { - // get weather probabilities for the current region - const ESM::Region *region = - MWBase::Environment::get().getWorld()->getStore().get().search (regionstr); - - if (region != 0) - { - weatherType = nextWeather(region); - } - } - - setWeather(weatherType, false); - } + switchToNextWeather(false); if (mNextWeather != "") { @@ -710,42 +675,42 @@ float WeatherManager::getWindSpeed() const void WeatherManager::switchToNextWeather(bool instantly) { - const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); - if (!exterior) - { - mRendering->sunDisable(false); - mRendering->skyDisable(); - mRendering->getSkyManager()->setLightningStrength(0.f); - stopSounds(true); - return; - } + MWBase::World* world = MWBase::Environment::get().getWorld(); + const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior()); + if (!exterior) + { + mRendering->sunDisable(false); + mRendering->skyDisable(); + mRendering->getSkyManager()->setLightningStrength(0.f); + stopSounds(true); + return; + } - // Exterior - std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); + // Exterior + std::string regionstr = Misc::StringUtils::lowerCase(world->getPlayer().getPlayer().getCell()->mCell->mRegion); - if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) - { - mCurrentRegion = regionstr; - mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; + if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) + { + mCurrentRegion = regionstr; + mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; - std::string weatherType = "clear"; + std::string weatherType = "clear"; - if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) - { - weatherType = mRegionOverrides[regionstr]; - } - else - { - // get weather probabilities for the current region - const ESM::Region *region = - MWBase::Environment::get().getWorld()->getStore().get().search (regionstr); + if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) + { + weatherType = mRegionOverrides[regionstr]; + } + else + { + // get weather probabilities for the current region + const ESM::Region *region = world->getStore().get().search (regionstr); - if (region != 0) - { - weatherType = nextWeather(region); - } - } + if (region != 0) + { + weatherType = nextWeather(region); + } + } - setWeather(weatherType, instantly); - } + setWeather(weatherType, instantly); + } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 18dc77d3aa..86dc38a8e9 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2247,19 +2247,14 @@ namespace MWWorld void World::updateWeather(float duration) { - static const float teleportationStepTreshold = 256.f; - static ESM::Position lastPlayerPos; - ESM::Position currentPos = mPlayer->getPlayer().getRefData().getPosition(); - - if (fabs(fabs(lastPlayerPos.pos[0]) - fabs(currentPos.pos[0])) >= teleportationStepTreshold - || fabs(fabs(lastPlayerPos.pos[1]) - fabs(currentPos.pos[1])) >= teleportationStepTreshold) - { - lastPlayerPos = currentPos; - mWeatherManager->switchToNextWeather(true); - } - else - { - mWeatherManager->update (duration); - } + if (mPlayer->wasTeleported()) + { + mPlayer->setTeleported(false); + mWeatherManager->switchToNextWeather(true); + } + else + { + mWeatherManager->update (duration); + } } } From 101813fd0dc353f4732f5cd2508fdd144349e150 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Tue, 31 Dec 2013 21:18:10 +0100 Subject: [PATCH 5/5] Fixes #417: Apply weather instantly when teleporting Correction to previous commit - WeatherManager->update() will always be called. Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwworld/worldimp.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 86dc38a8e9..b4b1bd1f65 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2252,9 +2252,7 @@ namespace MWWorld mPlayer->setTeleported(false); mWeatherManager->switchToNextWeather(true); } - else - { - mWeatherManager->update (duration); - } + + mWeatherManager->update(duration); } }