mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-19 21:11:32 +00:00
commit
c02920bcd1
8 changed files with 43 additions and 56 deletions
|
@ -497,8 +497,8 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void breakInvisibility (const MWWorld::Ptr& actor) = 0;
|
virtual void breakInvisibility (const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
// Are we in an exterior or pseudo-exterior cell and it's night?
|
// Allow NPCs to use torches?
|
||||||
virtual bool isDark() const = 0;
|
virtual bool useTorches() const = 0;
|
||||||
|
|
||||||
virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
||||||
|
|
||||||
|
|
|
@ -233,24 +233,6 @@ namespace MWClass
|
||||||
if (!(ref->mBase->mData.mFlags & ESM::Light::Carry))
|
if (!(ref->mBase->mData.mFlags & ESM::Light::Carry))
|
||||||
return std::make_pair(0,"");
|
return std::make_pair(0,"");
|
||||||
|
|
||||||
const MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc);
|
|
||||||
MWWorld::ConstContainerStoreIterator weapon = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
|
||||||
|
|
||||||
if(weapon == invStore.end())
|
|
||||||
return std::make_pair(1,"");
|
|
||||||
|
|
||||||
/// \todo the 2h check is repeated many times; put it in a function
|
|
||||||
if(weapon->getTypeName() == typeid(ESM::Weapon).name() &&
|
|
||||||
(weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::LongBladeTwoHand ||
|
|
||||||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoClose ||
|
|
||||||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::BluntTwoWide ||
|
|
||||||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::SpearTwoWide ||
|
|
||||||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::AxeTwoHand ||
|
|
||||||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanBow ||
|
|
||||||
weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow))
|
|
||||||
{
|
|
||||||
return std::make_pair(3,"");
|
|
||||||
}
|
|
||||||
return std::make_pair(1,"");
|
return std::make_pair(1,"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -900,7 +900,7 @@ namespace MWMechanics
|
||||||
stats.setTimeToStartDrowning(fHoldBreathTime);
|
stats.setTimeToStartDrowning(fHoldBreathTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration)
|
void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration, bool mayEquip)
|
||||||
{
|
{
|
||||||
bool isPlayer = (ptr == getPlayer());
|
bool isPlayer = (ptr == getPlayer());
|
||||||
|
|
||||||
|
@ -922,7 +922,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWorld()->isDark())
|
if (mayEquip)
|
||||||
{
|
{
|
||||||
if (torch != inventoryStore.end())
|
if (torch != inventoryStore.end())
|
||||||
{
|
{
|
||||||
|
@ -931,16 +931,11 @@ namespace MWMechanics
|
||||||
// For non-hostile NPCs, unequip whatever is in the left slot in favor of a light.
|
// For non-hostile NPCs, unequip whatever is in the left slot in favor of a light.
|
||||||
if (heldIter != inventoryStore.end() && heldIter->getTypeName() != typeid(ESM::Light).name())
|
if (heldIter != inventoryStore.end() && heldIter->getTypeName() != typeid(ESM::Light).name())
|
||||||
inventoryStore.unequipItem(*heldIter, ptr);
|
inventoryStore.unequipItem(*heldIter, ptr);
|
||||||
|
|
||||||
// Also unequip twohanded weapons which conflict with anything in CarriedLeft
|
|
||||||
if (torch->getClass().canBeEquipped(*torch, ptr).first == 3)
|
|
||||||
inventoryStore.unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight, ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
heldIter = inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
heldIter = inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||||
|
|
||||||
// If we have a torch and can equip it (left slot free, no
|
// If we have a torch and can equip it, then equip it now.
|
||||||
// twohanded weapon in right slot), then equip it now.
|
|
||||||
if (heldIter == inventoryStore.end()
|
if (heldIter == inventoryStore.end()
|
||||||
&& torch->getClass().canBeEquipped(*torch, ptr).first == 1)
|
&& torch->getClass().canBeEquipped(*torch, ptr).first == 1)
|
||||||
{
|
{
|
||||||
|
@ -1204,6 +1199,9 @@ namespace MWMechanics
|
||||||
if (mTimerDisposeSummonsCorpses >= 0.2f) mTimerDisposeSummonsCorpses = 0;
|
if (mTimerDisposeSummonsCorpses >= 0.2f) mTimerDisposeSummonsCorpses = 0;
|
||||||
if (timerUpdateEquippedLight >= updateEquippedLightInterval) timerUpdateEquippedLight = 0;
|
if (timerUpdateEquippedLight >= updateEquippedLightInterval) timerUpdateEquippedLight = 0;
|
||||||
|
|
||||||
|
// show torches only when there are darkness and no precipitations
|
||||||
|
bool showTorches = MWBase::Environment::get().getWorld()->useTorches();
|
||||||
|
|
||||||
MWWorld::Ptr player = getPlayer();
|
MWWorld::Ptr player = getPlayer();
|
||||||
|
|
||||||
/// \todo move update logic to Actor class where appropriate
|
/// \todo move update logic to Actor class where appropriate
|
||||||
|
@ -1302,7 +1300,7 @@ namespace MWMechanics
|
||||||
updateNpc(iter->first, duration);
|
updateNpc(iter->first, duration);
|
||||||
|
|
||||||
if (timerUpdateEquippedLight == 0)
|
if (timerUpdateEquippedLight == 0)
|
||||||
updateEquippedLight(iter->first, updateEquippedLightInterval);
|
updateEquippedLight(iter->first, updateEquippedLightInterval, showTorches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
|
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
|
||||||
|
|
||||||
void updateEquippedLight (const MWWorld::Ptr& ptr, float duration);
|
void updateEquippedLight (const MWWorld::Ptr& ptr, float duration, bool mayEquip);
|
||||||
|
|
||||||
void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration);
|
void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <components/fallback/fallback.hpp>
|
#include <components/fallback/fallback.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/actorutil.hpp"
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
@ -520,6 +519,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const Fall
|
||||||
, mSecunda("Secunda", fallback)
|
, mSecunda("Secunda", fallback)
|
||||||
, mWindSpeed(0.f)
|
, mWindSpeed(0.f)
|
||||||
, mIsStorm(false)
|
, mIsStorm(false)
|
||||||
|
, mPrecipitation(false)
|
||||||
, mStormDirection(0,1,0)
|
, mStormDirection(0,1,0)
|
||||||
, mCurrentRegion()
|
, mCurrentRegion()
|
||||||
, mTimePassed(0)
|
, mTimePassed(0)
|
||||||
|
@ -608,14 +608,11 @@ void WeatherManager::modRegion(const std::string& regionID, const std::vector<ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeatherManager::playerTeleported()
|
void WeatherManager::playerTeleported(const std::string& playerRegion, bool isExterior)
|
||||||
{
|
{
|
||||||
// If the player teleports to an outdoors cell in a new region (for instance, by travelling), the weather needs to
|
// If the player teleports to an outdoors cell in a new region (for instance, by travelling), the weather needs to
|
||||||
// be changed immediately, and any transitions for the previous region discarded.
|
// be changed immediately, and any transitions for the previous region discarded.
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
||||||
if(world->isCellExterior() || world->isCellQuasiExterior())
|
|
||||||
{
|
{
|
||||||
std::string playerRegion = Misc::StringUtils::lowerCase(world->getPlayerPtr().getCell()->getCell()->mRegion);
|
|
||||||
std::map<std::string, RegionWeather>::iterator it = mRegions.find(playerRegion);
|
std::map<std::string, RegionWeather>::iterator it = mRegions.find(playerRegion);
|
||||||
if(it != mRegions.end() && playerRegion != mCurrentRegion)
|
if(it != mRegions.end() && playerRegion != mCurrentRegion)
|
||||||
{
|
{
|
||||||
|
@ -625,11 +622,9 @@ void WeatherManager::playerTeleported()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeatherManager::update(float duration, bool paused)
|
void WeatherManager::update(float duration, bool paused, const TimeStamp& time, bool isExterior)
|
||||||
{
|
{
|
||||||
MWWorld::ConstPtr player = MWMechanics::getPlayer();
|
MWWorld::ConstPtr player = MWMechanics::getPlayer();
|
||||||
MWBase::World& world = *MWBase::Environment::get().getWorld();
|
|
||||||
TimeStamp time = world.getTimeStamp();
|
|
||||||
|
|
||||||
if(!paused || mFastForward)
|
if(!paused || mFastForward)
|
||||||
{
|
{
|
||||||
|
@ -647,8 +642,7 @@ void WeatherManager::update(float duration, bool paused)
|
||||||
updateWeatherTransitions(duration);
|
updateWeatherTransitions(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool exterior = (world.isCellExterior() || world.isCellQuasiExterior());
|
if(!isExterior)
|
||||||
if(!exterior)
|
|
||||||
{
|
{
|
||||||
mRendering.setSkyEnabled(false);
|
mRendering.setSkyEnabled(false);
|
||||||
stopSounds();
|
stopSounds();
|
||||||
|
@ -660,6 +654,10 @@ void WeatherManager::update(float duration, bool paused)
|
||||||
mWindSpeed = mResult.mWindSpeed;
|
mWindSpeed = mResult.mWindSpeed;
|
||||||
mIsStorm = mResult.mIsStorm;
|
mIsStorm = mResult.mIsStorm;
|
||||||
|
|
||||||
|
// For some reason Ash Storm is not considered as a precipitation weather in game
|
||||||
|
mPrecipitation = !(mResult.mParticleEffect.empty() && mResult.mRainEffect.empty())
|
||||||
|
&& mResult.mParticleEffect != "meshes\\ashcloud.nif";
|
||||||
|
|
||||||
if (mIsStorm)
|
if (mIsStorm)
|
||||||
{
|
{
|
||||||
osg::Vec3f playerPos (player.getRefData().getPosition().asVec3());
|
osg::Vec3f playerPos (player.getRefData().getPosition().asVec3());
|
||||||
|
@ -777,12 +775,11 @@ unsigned int WeatherManager::getWeatherID() const
|
||||||
return mCurrentWeather;
|
return mCurrentWeather;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WeatherManager::isDark() const
|
bool WeatherManager::useTorches(float hour) const
|
||||||
{
|
{
|
||||||
TimeStamp time = MWBase::Environment::get().getWorld()->getTimeStamp();
|
bool isDark = hour < mSunriseTime || hour > mTimeSettings.mNightStart - 1;
|
||||||
bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior()
|
|
||||||
|| MWBase::Environment::get().getWorld()->isCellQuasiExterior());
|
return isDark && !mPrecipitation;
|
||||||
return exterior && (time.getHour() < mSunriseTime || time.getHour() > mTimeSettings.mNightStart - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeatherManager::write(ESM::ESMWriter& writer, Loading::Listener& progress)
|
void WeatherManager::write(ESM::ESMWriter& writer, Loading::Listener& progress)
|
||||||
|
|
|
@ -218,14 +218,14 @@ namespace MWWorld
|
||||||
*/
|
*/
|
||||||
void changeWeather(const std::string& regionID, const unsigned int weatherID);
|
void changeWeather(const std::string& regionID, const unsigned int weatherID);
|
||||||
void modRegion(const std::string& regionID, const std::vector<char>& chances);
|
void modRegion(const std::string& regionID, const std::vector<char>& chances);
|
||||||
void playerTeleported();
|
void playerTeleported(const std::string& playerRegion, bool isExterior);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per-frame update
|
* Per-frame update
|
||||||
* @param duration
|
* @param duration
|
||||||
* @param paused
|
* @param paused
|
||||||
*/
|
*/
|
||||||
void update(float duration, bool paused = false);
|
void update(float duration, bool paused, const TimeStamp& time, bool isExterior);
|
||||||
|
|
||||||
void stopSounds();
|
void stopSounds();
|
||||||
|
|
||||||
|
@ -240,8 +240,7 @@ namespace MWWorld
|
||||||
|
|
||||||
unsigned int getWeatherID() const;
|
unsigned int getWeatherID() const;
|
||||||
|
|
||||||
/// @see World::isDark
|
bool useTorches(float hour) const;
|
||||||
bool isDark() const;
|
|
||||||
|
|
||||||
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
||||||
|
|
||||||
|
@ -275,6 +274,7 @@ namespace MWWorld
|
||||||
|
|
||||||
float mWindSpeed;
|
float mWindSpeed;
|
||||||
bool mIsStorm;
|
bool mIsStorm;
|
||||||
|
bool mPrecipitation;
|
||||||
osg::Vec3f mStormDirection;
|
osg::Vec3f mStormDirection;
|
||||||
|
|
||||||
std::string mCurrentRegion;
|
std::string mCurrentRegion;
|
||||||
|
|
|
@ -2862,11 +2862,17 @@ namespace MWWorld
|
||||||
MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(actor);
|
MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::isDark() const
|
bool World::useTorches() const
|
||||||
{
|
{
|
||||||
|
// If we are in exterior, check the weather manager.
|
||||||
|
// In interiors there are no precipitations and sun, so check the ambient
|
||||||
|
// Looks like pseudo-exteriors considered as interiors in this case
|
||||||
MWWorld::CellStore* cell = mPlayer->getPlayer().getCell();
|
MWWorld::CellStore* cell = mPlayer->getPlayer().getCell();
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
return mWeatherManager->isDark();
|
{
|
||||||
|
float hour = getTimeStamp().getHour();
|
||||||
|
return mWeatherManager->useTorches(hour);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t ambient = cell->getCell()->mAmbi.mAmbient;
|
uint32_t ambient = cell->getCell()->mAmbi.mAmbient;
|
||||||
|
@ -3027,13 +3033,17 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::updateWeather(float duration, bool paused)
|
void World::updateWeather(float duration, bool paused)
|
||||||
{
|
{
|
||||||
|
bool isExterior = isCellExterior() || isCellQuasiExterior();
|
||||||
if (mPlayer->wasTeleported())
|
if (mPlayer->wasTeleported())
|
||||||
{
|
{
|
||||||
mPlayer->setTeleported(false);
|
mPlayer->setTeleported(false);
|
||||||
mWeatherManager->playerTeleported();
|
|
||||||
|
const std::string playerRegion = Misc::StringUtils::lowerCase(getPlayerPtr().getCell()->getCell()->mRegion);
|
||||||
|
mWeatherManager->playerTeleported(playerRegion, isExterior);
|
||||||
}
|
}
|
||||||
|
|
||||||
mWeatherManager->update(duration, paused);
|
const TimeStamp time = getTimeStamp();
|
||||||
|
mWeatherManager->update(duration, paused, time, isExterior);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AddDetectedReferenceVisitor
|
struct AddDetectedReferenceVisitor
|
||||||
|
|
|
@ -607,10 +607,10 @@ namespace MWWorld
|
||||||
void applyLoopingParticles(const MWWorld::Ptr& ptr);
|
void applyLoopingParticles(const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
const std::vector<std::string>& getContentFiles() const override;
|
const std::vector<std::string>& getContentFiles() const override;
|
||||||
|
|
||||||
void breakInvisibility (const MWWorld::Ptr& actor) override;
|
void breakInvisibility (const MWWorld::Ptr& actor) override;
|
||||||
// Are we in an exterior or pseudo-exterior cell and it's night?
|
|
||||||
bool isDark() const override;
|
// Allow NPCs to use torches?
|
||||||
|
bool useTorches() const override;
|
||||||
|
|
||||||
bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) override;
|
bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue