Merge remote-tracking branch 'lgro/issue417_apply_weather_instantly_when_teleporting'

Conflicts:
	apps/openmw/mwworld/weather.cpp
	apps/openmw/mwworld/worldimp.cpp
This commit is contained in:
Marc Zinnschlag 2014-01-01 14:57:14 +01:00
commit 5fa9aa5d1e
10 changed files with 108 additions and 48 deletions

View file

@ -7,6 +7,7 @@
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwrender/animation.hpp" #include "../mwrender/animation.hpp"
@ -240,11 +241,15 @@ namespace MWMechanics
else if (effectId == ESM::MagicEffect::DivineIntervention) 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 // 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. // or alternatively, the last known exterior location of the player, which is how vanilla does it.
} }
else if (effectId == ESM::MagicEffect::AlmsiviIntervention) else if (effectId == ESM::MagicEffect::AlmsiviIntervention)
{ {
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
// Same as above // Same as above
} }
@ -254,6 +259,8 @@ namespace MWMechanics
} }
else if (effectId == ESM::MagicEffect::Recall) else if (effectId == ESM::MagicEffect::Recall)
{ {
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
// TODO // TODO
} }
} }

View file

@ -43,10 +43,13 @@ namespace MWScript
ESM::Position pos; ESM::Position pos;
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
if (world->findExteriorPosition(cell, pos)) { world->getPlayer().setTeleported(true);
if (world->findExteriorPosition(cell, pos))
{
world->changeToExteriorCell(pos); world->changeToExteriorCell(pos);
} }
else { else
{
// Change to interior even if findInteriorPosition() // Change to interior even if findInteriorPosition()
// yields false. In this case position will be zero-point. // yields false. In this case position will be zero-point.
world->findInteriorPosition(cell, pos); world->findInteriorPosition(cell, pos);
@ -68,13 +71,14 @@ namespace MWScript
runtime.pop(); runtime.pop();
ESM::Position pos; ESM::Position pos;
MWBase::World *world = MWBase::Environment::get().getWorld();
MWBase::Environment::get().getWorld()->indexToPosition (x, y, pos.pos[0], pos.pos[1], true); world->getPlayer().setTeleported(true);
world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true);
pos.pos[2] = 0; pos.pos[2] = 0;
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); world->changeToExteriorCell (pos);
} }
}; };

View file

@ -207,6 +207,10 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(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); std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop(); runtime.pop();
@ -271,6 +275,10 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(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; Interpreter::Type_Float x = runtime[0].mFloat;
runtime.pop(); runtime.pop();
@ -328,6 +336,10 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(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; Interpreter::Type_Float x = runtime[0].mFloat;
runtime.pop(); runtime.pop();

View file

@ -3,6 +3,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "player.hpp"
namespace MWWorld namespace MWWorld
{ {
@ -14,9 +15,12 @@ namespace MWWorld
void ActionTeleport::executeImp (const Ptr& actor) void ActionTeleport::executeImp (const Ptr& actor)
{ {
MWBase::World* world = MWBase::Environment::get().getWorld();
world->getPlayer().setTeleported(true);
if (mCellName.empty()) if (mCellName.empty())
MWBase::Environment::get().getWorld()->changeToExteriorCell (mPosition); world->changeToExteriorCell (mPosition);
else else
MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, mPosition); world->changeToInteriorCell (mCellName, mPosition);
} }
} }

View file

@ -19,7 +19,8 @@ namespace MWWorld
Player::Player (const ESM::NPC *player, const MWBase::World& world) Player::Player (const ESM::NPC *player, const MWBase::World& world)
: mCellStore(0), : mCellStore(0),
mAutoMove(false), mAutoMove(false),
mForwardBackward (0) mForwardBackward (0),
mTeleported(false)
{ {
mPlayer.mBase = player; mPlayer.mBase = player;
mPlayer.mRef.mRefID = "player"; mPlayer.mRef.mRefID = "player";
@ -145,4 +146,14 @@ namespace MWWorld
MWWorld::Ptr ptr = getPlayer(); MWWorld::Ptr ptr = getPlayer();
return MWWorld::Class::get(ptr).getNpcStats(ptr).getDrawState(); return MWWorld::Class::get(ptr).getNpcStats(ptr).getDrawState();
} }
bool Player::wasTeleported() const
{
return mTeleported;
}
void Player::setTeleported(bool teleported)
{
mTeleported = teleported;
}
} }

View file

@ -30,7 +30,7 @@ namespace MWWorld
bool mAutoMove; bool mAutoMove;
int mForwardBackward; int mForwardBackward;
bool mTeleported;
public: public:
Player(const ESM::NPC *player, const MWBase::World& world); Player(const ESM::NPC *player, const MWBase::World& world);
@ -64,6 +64,9 @@ namespace MWWorld
void yaw(float yaw); void yaw(float yaw);
void pitch(float pitch); void pitch(float pitch);
void roll(float roll); void roll(float roll);
bool wasTeleported() const;
void setTeleported(bool teleported);
}; };
} }
#endif #endif

View file

@ -195,7 +195,7 @@ void WeatherManager::setWeather(const String& weather, bool instant)
} }
mNextWeather = weather; mNextWeather = weather;
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600; mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600.f;
} }
mFirstUpdate = false; mFirstUpdate = false;
} }
@ -324,42 +324,7 @@ void WeatherManager::update(float duration)
mWeatherUpdateTime -= timePassed; mWeatherUpdateTime -= timePassed;
const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); switchToNextWeather(false);
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<ESM::Region>().search (regionstr);
if (region != 0)
{
weatherType = nextWeather(region);
}
}
setWeather(weatherType, false);
}
if (mNextWeather != "") if (mNextWeather != "")
{ {
@ -714,3 +679,45 @@ bool WeatherManager::isDark() const
|| MWBase::Environment::get().getWorld()->isCellQuasiExterior()); || MWBase::Environment::get().getWorld()->isCellQuasiExterior());
return exterior && (mHour < mSunriseTime || mHour > mNightStart - 1); return exterior && (mHour < mSunriseTime || mHour > mNightStart - 1);
} }
void WeatherManager::switchToNextWeather(bool instantly)
{
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(world->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 = world->getStore().get<ESM::Region>().search (regionstr);
if (region != 0)
{
weatherType = nextWeather(region);
}
}
setWeather(weatherType, instantly);
}
}

View file

@ -128,6 +128,7 @@ namespace MWWorld
* @param ID of the weather setting to shift to * @param ID of the weather setting to shift to
*/ */
void changeWeather(const std::string& region, const unsigned int id); void changeWeather(const std::string& region, const unsigned int id);
void switchToNextWeather(bool instantly = true);
/** /**
* Per-frame update * Per-frame update

View file

@ -1287,7 +1287,7 @@ namespace MWWorld
mRendering->playVideo(mFallback.getFallbackString("Movies_New_Game"), true); mRendering->playVideo(mFallback.getFallbackString("Movies_New_Game"), true);
} }
mWeatherManager->update (duration); updateWeather(duration);
mWorldScene->update (duration, paused); mWorldScene->update (duration, paused);
@ -2290,4 +2290,15 @@ namespace MWWorld
{ {
return mWeatherManager->isDark(); return mWeatherManager->isDark();
} }
void World::updateWeather(float duration)
{
if (mPlayer->wasTeleported())
{
mPlayer->setTeleported(false);
mWeatherManager->switchToNextWeather(true);
}
mWeatherManager->update(duration);
}
} }

View file

@ -106,7 +106,7 @@ namespace MWWorld
}; };
std::map<MWWorld::Ptr, ProjectileState> mProjectiles; std::map<MWWorld::Ptr, ProjectileState> mProjectiles;
void updateWeather(float duration);
int getDaysPerMonth (int month) const; int getDaysPerMonth (int month) const;
void rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust); void rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust);