forked from mirror/openmw-tes3mp
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 <lgromanowski@gmail.com>
This commit is contained in:
parent
c65f018760
commit
e9844e1b37
8 changed files with 92 additions and 91 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 != "")
|
||||||
{
|
{
|
||||||
|
@ -710,7 +675,8 @@ float WeatherManager::getWindSpeed() const
|
||||||
|
|
||||||
void WeatherManager::switchToNextWeather(bool instantly)
|
void WeatherManager::switchToNextWeather(bool instantly)
|
||||||
{
|
{
|
||||||
const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior());
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior());
|
||||||
if (!exterior)
|
if (!exterior)
|
||||||
{
|
{
|
||||||
mRendering->sunDisable(false);
|
mRendering->sunDisable(false);
|
||||||
|
@ -721,7 +687,7 @@ void WeatherManager::switchToNextWeather(bool instantly)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exterior
|
// Exterior
|
||||||
std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion);
|
std::string regionstr = Misc::StringUtils::lowerCase(world->getPlayer().getPlayer().getCell()->mCell->mRegion);
|
||||||
|
|
||||||
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
|
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
|
||||||
{
|
{
|
||||||
|
@ -737,8 +703,7 @@ void WeatherManager::switchToNextWeather(bool instantly)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// get weather probabilities for the current region
|
// get weather probabilities for the current region
|
||||||
const ESM::Region *region =
|
const ESM::Region *region = world->getStore().get<ESM::Region>().search (regionstr);
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().search (regionstr);
|
|
||||||
|
|
||||||
if (region != 0)
|
if (region != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2247,14 +2247,9 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::updateWeather(float duration)
|
void World::updateWeather(float duration)
|
||||||
{
|
{
|
||||||
static const float teleportationStepTreshold = 256.f;
|
if (mPlayer->wasTeleported())
|
||||||
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;
|
mPlayer->setTeleported(false);
|
||||||
mWeatherManager->switchToNextWeather(true);
|
mWeatherManager->switchToNextWeather(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue