mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-21 09:39:56 +00:00
Merge branch 'weather_the_sun' into 'master'
Implement sun damage based on the research on the wiki Closes #6977 See merge request OpenMW/openmw!2422
This commit is contained in:
commit
fb90d35805
@ -13,6 +13,7 @@
|
||||
Bug #6949: Sun Damage effect doesn't work in quasi exteriors
|
||||
Bug #6964: Nerasa Dralor Won't Follow
|
||||
Bug #6974: Only harmful effects are reflected
|
||||
Bug #6977: Sun damage implementation does not match research
|
||||
Bug #6986: Sound magic effect does not make noise
|
||||
Bug #6987: Set/Mod Blindness should not darken the screen
|
||||
Bug #6992: Crossbow reloading doesn't look the same as in Morrowind
|
||||
|
@ -564,6 +564,9 @@ namespace MWBase
|
||||
// Allow NPCs to use torches?
|
||||
virtual bool useTorches() const = 0;
|
||||
|
||||
virtual float getSunVisibility() const = 0;
|
||||
virtual float getSunPercentage() const = 0;
|
||||
|
||||
virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
||||
|
||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||
|
@ -664,15 +664,9 @@ void applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, co
|
||||
// isInCell shouldn't be needed, but updateActor called during game start
|
||||
if (!target.isInCell() || !(target.getCell()->isExterior() || target.getCell()->isQuasiExterior()) || godmode)
|
||||
break;
|
||||
float time = world->getTimeStamp().getHour();
|
||||
float timeDiff = std::clamp(std::abs(time - 13.f), 0.f, 7.f);
|
||||
float damageScale = 1.f - timeDiff / 7.f;
|
||||
// When cloudy, the sun damage effect is halved
|
||||
const float sunRisen = world->getSunPercentage();
|
||||
static float fMagicSunBlockedMult = world->getStore().get<ESM::GameSetting>().find("fMagicSunBlockedMult")->mValue.getFloat();
|
||||
|
||||
int weather = world->getCurrentWeather();
|
||||
if (weather > 1)
|
||||
damageScale *= fMagicSunBlockedMult;
|
||||
const float damageScale = std::clamp(std::max(world->getSunVisibility() * sunRisen, fMagicSunBlockedMult * sunRisen), 0.f, 1.f);
|
||||
float damage = effect.mMagnitude * damageScale;
|
||||
adjustDynamicStat(target, 0, -damage);
|
||||
if (damage > 0.f)
|
||||
|
@ -176,8 +176,8 @@ namespace
|
||||
, mParticleEffect(particleEffect)
|
||||
, mRainEffect(Fallback::Map::getBool("Weather_" + name + "_Using_Precip") ? "meshes\\raindrop.nif" : "")
|
||||
, mStormDirection(Weather::defaultDirection())
|
||||
, mTransitionDelta(Fallback::Map::getFloat("Weather_" + name + "_Transition_Delta"))
|
||||
, mCloudsMaximumPercent(Fallback::Map::getFloat("Weather_" + name + "_Clouds_Maximum_Percent"))
|
||||
, mTransitionDelta(Fallback::Map::getFloat("Weather_" + name + "_Transition_Delta"))
|
||||
, mThunderFrequency(Fallback::Map::getFloat("Weather_" + name + "_Thunder_Frequency"))
|
||||
, mThunderThreshold(Fallback::Map::getFloat("Weather_" + name + "_Thunder_Threshold"))
|
||||
, mThunderSoundID()
|
||||
@ -875,6 +875,27 @@ namespace
|
||||
return isDark && !mPrecipitation;
|
||||
}
|
||||
|
||||
float WeatherManager::getSunPercentage(float hour) const
|
||||
{
|
||||
if (hour <= mTimeSettings.mNightEnd || hour >= mTimeSettings.mNightStart)
|
||||
return 0.f;
|
||||
else if (hour <= mTimeSettings.mDayStart)
|
||||
return (hour - mTimeSettings.mNightEnd) / mSunriseDuration;
|
||||
else if (hour > mTimeSettings.mDayEnd)
|
||||
return 1.f - ((hour - mTimeSettings.mDayEnd) / mSunsetDuration);
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
float WeatherManager::getSunVisibility() const
|
||||
{
|
||||
if (inTransition() && mTransitionFactor < mWeatherSettings[mNextWeather].mCloudsMaximumPercent)
|
||||
{
|
||||
float t = mTransitionFactor / mWeatherSettings[mNextWeather].mCloudsMaximumPercent;
|
||||
return (1.f - t) * mWeatherSettings[mCurrentWeather].mGlareView + t * mWeatherSettings[mNextWeather].mGlareView;
|
||||
}
|
||||
return mWeatherSettings[mCurrentWeather].mGlareView;
|
||||
}
|
||||
|
||||
void WeatherManager::write(ESM::ESMWriter& writer, Loading::Listener& progress)
|
||||
{
|
||||
ESM::WeatherState state;
|
||||
@ -1072,7 +1093,7 @@ namespace
|
||||
mQueuedWeather = invalidWeatherID;
|
||||
}
|
||||
|
||||
inline bool WeatherManager::inTransition()
|
||||
inline bool WeatherManager::inTransition() const
|
||||
{
|
||||
return mNextWeather != invalidWeatherID;
|
||||
}
|
||||
|
@ -193,6 +193,8 @@ namespace MWWorld
|
||||
|
||||
osg::Vec3f mStormDirection;
|
||||
|
||||
float mCloudsMaximumPercent;
|
||||
|
||||
// Note: For Weather Blight, there is a "Disease Chance" (=0.1) setting. But according to MWSFD this feature
|
||||
// is broken in the vanilla game and was disabled.
|
||||
|
||||
@ -203,7 +205,6 @@ namespace MWWorld
|
||||
|
||||
private:
|
||||
float mTransitionDelta;
|
||||
float mCloudsMaximumPercent;
|
||||
|
||||
// Note: In MW, only thunderstorms support these attributes, but in the interest of making weather more
|
||||
// flexible, these settings are imported for all weather types. Only thunderstorms will normally have any
|
||||
@ -315,6 +316,10 @@ namespace MWWorld
|
||||
|
||||
bool useTorches(float hour) const;
|
||||
|
||||
float getSunPercentage(float hour) const;
|
||||
|
||||
float getSunVisibility() const;
|
||||
|
||||
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
||||
|
||||
bool readRecord(ESM::ESMReader& reader, uint32_t type);
|
||||
@ -379,7 +384,7 @@ namespace MWWorld
|
||||
void updateWeatherTransitions(const float elapsedRealSeconds);
|
||||
void forceWeather(const int weatherID);
|
||||
|
||||
bool inTransition();
|
||||
bool inTransition() const;
|
||||
void addWeatherTransition(const int weatherID);
|
||||
|
||||
void calculateWeatherResult(const float gameHour, const float elapsedSeconds, const bool isPaused);
|
||||
|
@ -3260,6 +3260,16 @@ namespace MWWorld
|
||||
}
|
||||
}
|
||||
|
||||
float World::getSunVisibility() const
|
||||
{
|
||||
return mWeatherManager->getSunVisibility();
|
||||
}
|
||||
|
||||
float World::getSunPercentage() const
|
||||
{
|
||||
return mWeatherManager->getSunPercentage(getTimeStamp().getHour());
|
||||
}
|
||||
|
||||
bool World::findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result)
|
||||
{
|
||||
if (cell->isExterior())
|
||||
|
@ -668,6 +668,9 @@ namespace MWWorld
|
||||
// Allow NPCs to use torches?
|
||||
bool useTorches() const override;
|
||||
|
||||
float getSunVisibility() const override;
|
||||
float getSunPercentage() const override;
|
||||
|
||||
bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) override;
|
||||
|
||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||
|
Loading…
x
Reference in New Issue
Block a user