1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 04:19:55 +00:00
openmw-tes3mp/apps/openmw/mwworld/weather.cpp
Lukasz Gromanowski 91a4d9a2eb Fixes #845: NPCs hold torches during the day
Added method in WeatherManger and World which returns true if it is night.
This method is used later in character controller to show torches
(or other sources of light) at night and hide them at day.

Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
2013-12-10 23:48:49 +01:00

714 lines
25 KiB
C++

#include "weather.hpp"
#include <boost/algorithm/string.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "player.hpp"
#include "esmstore.hpp"
#include "fallback.hpp"
using namespace Ogre;
using namespace MWWorld;
using namespace MWSound;
namespace
{
float lerp (float x, float y, float factor)
{
return x * (1-factor) + y * factor;
}
Ogre::ColourValue lerp (const Ogre::ColourValue& x, const Ogre::ColourValue& y, float factor)
{
return x * (1-factor) + y * factor;
}
}
void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name)
{
std::string upper=name;
upper[0]=toupper(name[0]);
weather.mCloudsMaximumPercent = mFallback->getFallbackFloat("Weather_"+upper+"_Clouds_Maximum_Percent");
weather.mTransitionDelta = mFallback->getFallbackFloat("Weather_"+upper+"_Transition_Delta");
weather.mSkySunriseColor=mFallback->getFallbackColour("Weather_"+upper+"_Sky_Sunrise_Color");
weather.mSkyDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Day_Color");
weather.mSkySunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Sunset_Color");
weather.mSkyNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Night_Color");
weather.mFogSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Sunrise_Color");
weather.mFogDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Day_Color");
weather.mFogSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Sunset_Color");
weather.mFogNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Night_Color");
weather.mAmbientSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Sunrise_Color");
weather.mAmbientDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Day_Color");
weather.mAmbientSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Sunset_Color");
weather.mAmbientNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Night_Color");
weather.mSunSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Sunrise_Color");
weather.mSunDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Day_Color");
weather.mSunSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Sunset_Color");
weather.mSunNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Night_Color");
weather.mSunDiscSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Disc_Sunset_Color");
weather.mLandFogDayDepth = mFallback->getFallbackFloat("Weather_"+upper+"_Land_Fog_Day_Depth");
weather.mLandFogNightDepth = mFallback->getFallbackFloat("Weather_"+upper+"_Land_Fog_Night_Depth");
weather.mWindSpeed = mFallback->getFallbackFloat("Weather_"+upper+"_Wind_Speed");
weather.mCloudSpeed = mFallback->getFallbackFloat("Weather_"+upper+"_Cloud_Speed");
weather.mGlareView = mFallback->getFallbackFloat("Weather_"+upper+"_Glare_View");
mWeatherSettings[name] = weather;
}
float WeatherManager::calculateHourFade (const std::string& moonName) const
{
float fadeOutStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Out_Start");
float fadeOutFinish=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Out_Finish");
float fadeInStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_In_Start");
float fadeInFinish=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_In_Finish");
if (mHour >= fadeOutStart && mHour <= fadeOutFinish)
return (1 - ((mHour - fadeOutStart) / (fadeOutFinish - fadeOutStart)));
if (mHour >= fadeInStart && mHour <= fadeInFinish)
return (1 - ((mHour - fadeInStart) / (fadeInFinish - fadeInStart)));
else
return 1;
}
float WeatherManager::calculateAngleFade (const std::string& moonName, float angle) const
{
float endAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_End_Angle");
float startAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Start_Angle");
if (angle <= startAngle && angle >= endAngle)
return (1 - ((angle - endAngle)/(startAngle-endAngle)));
else if (angle > startAngle)
return 0.f;
else
return 1.f;
}
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) :
mHour(14), mCurrentWeather("clear"), mNextWeather(""), mFirstUpdate(true),
mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0),
mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0),
mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f),
mRendering(rendering)
{
//Globals
mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0");
mThunderSoundID1 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_1");
mThunderSoundID2 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_2");
mThunderSoundID3 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_3");
mSunriseTime = mFallback->getFallbackFloat("Weather_Sunrise_Time");
mSunsetTime = mFallback->getFallbackFloat("Weather_Sunset_Time");
mSunriseDuration = mFallback->getFallbackFloat("Weather_Sunrise_Duration");
mSunsetDuration = mFallback->getFallbackFloat("Weather_Sunset_Duration");
mHoursBetweenWeatherChanges = mFallback->getFallbackFloat("Weather_Hours_Between_Weather_Changes");
mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600;
mThunderFrequency = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Frequency");
mThunderThreshold = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Threshold");
mThunderSoundDelay = 0.25;
//Some useful values
/* TODO: Use pre-sunrise_time, pre-sunset_time,
* post-sunrise_time, and post-sunset_time to better
* describe sunrise/sunset time.
* These values are fallbacks attached to weather.
*/
mNightStart = mSunsetTime + mSunsetDuration;
mNightEnd = mSunriseTime - 0.5;
mDayStart = mSunriseTime + mSunriseDuration;
mDayEnd = mSunsetTime;
//Weather
Weather clear;
clear.mCloudTexture = "tx_sky_clear.dds";
setFallbackWeather(clear,"clear");
Weather cloudy;
cloudy.mCloudTexture = "tx_sky_cloudy.dds";
setFallbackWeather(cloudy,"cloudy");
Weather foggy;
foggy.mCloudTexture = "tx_sky_foggy.dds";
setFallbackWeather(foggy,"foggy");
Weather thunderstorm;
thunderstorm.mCloudTexture = "tx_sky_thunder.dds";
thunderstorm.mRainLoopSoundID = "rain heavy";
setFallbackWeather(thunderstorm,"thunderstorm");
Weather rain;
rain.mCloudTexture = "tx_sky_rainy.dds";
rain.mRainLoopSoundID = "rain";
setFallbackWeather(rain,"rain");
Weather overcast;
overcast.mCloudTexture = "tx_sky_overcast.dds";
setFallbackWeather(overcast,"overcast");
Weather ashstorm;
ashstorm.mCloudTexture = "tx_sky_ashstorm.dds";
ashstorm.mAmbientLoopSoundID = "ashstorm";
setFallbackWeather(ashstorm,"ashstorm");
Weather blight;
blight.mCloudTexture = "tx_sky_blight.dds";
blight.mAmbientLoopSoundID = "blight";
setFallbackWeather(blight,"blight");
Weather snow;
snow.mCloudTexture = "tx_bm_sky_snow.dds";
setFallbackWeather(snow, "snow");
Weather blizzard;
blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds";
blizzard.mAmbientLoopSoundID = "BM Blizzard";
setFallbackWeather(blizzard,"blizzard");
}
WeatherManager::~WeatherManager()
{
stopSounds(true);
}
void WeatherManager::setWeather(const String& weather, bool instant)
{
if (weather == mCurrentWeather && mNextWeather == "")
{
mFirstUpdate = false;
return;
}
if (instant || mFirstUpdate)
{
mNextWeather = "";
mCurrentWeather = weather;
}
else
{
if (mNextWeather != "")
{
// transition more than 50% finished?
if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600) <= 0.5)
mCurrentWeather = mNextWeather;
}
mNextWeather = weather;
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600;
}
mFirstUpdate = false;
}
void WeatherManager::setResult(const String& weatherType)
{
const Weather& current = mWeatherSettings[weatherType];
mResult.mCloudTexture = current.mCloudTexture;
mResult.mCloudBlendFactor = 0;
mResult.mCloudOpacity = current.mCloudsMaximumPercent;
mResult.mWindSpeed = current.mWindSpeed;
mResult.mCloudSpeed = current.mCloudSpeed;
mResult.mGlareView = current.mGlareView;
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
mResult.mSunColor = current.mSunDiscSunsetColor;
mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
mResult.mFogDepth = mResult.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
// night
if (mHour <= mNightEnd || mHour >= mNightStart + 1)
{
mResult.mFogColor = current.mFogNightColor;
mResult.mAmbientColor = current.mAmbientNightColor;
mResult.mSunColor = current.mSunNightColor;
mResult.mSkyColor = current.mSkyNightColor;
mResult.mNightFade = 1.f;
}
// sunrise
else if (mHour >= mNightEnd && mHour <= mDayStart + 1)
{
if (mHour <= mSunriseTime)
{
// fade in
float advance = mSunriseTime - mHour;
float factor = advance / 0.5f;
mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor);
mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor);
mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor, factor);
mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor, factor);
mResult.mNightFade = factor;
}
else //if (mHour >= 6)
{
// fade out
float advance = mHour - mSunriseTime;
float factor = advance / 3.f;
mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor);
mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor);
mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor, factor);
mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor, factor);
}
}
// day
else if (mHour >= mDayStart + 1 && mHour <= mDayEnd - 1)
{
mResult.mFogColor = current.mFogDayColor;
mResult.mAmbientColor = current.mAmbientDayColor;
mResult.mSunColor = current.mSunDayColor;
mResult.mSkyColor = current.mSkyDayColor;
}
// sunset
else if (mHour >= mDayEnd - 1 && mHour <= mNightStart + 1)
{
if (mHour <= mDayEnd + 1)
{
// fade in
float advance = (mDayEnd + 1) - mHour;
float factor = (advance / 2);
mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor);
mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor);
mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor, factor);
mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor, factor);
}
else //if (mHour >= 19)
{
// fade out
float advance = mHour - (mDayEnd + 1);
float factor = advance / 2.f;
mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor);
mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor);
mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor, factor);
mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor, factor);
mResult.mNightFade = factor;
}
}
}
void WeatherManager::transition(float factor)
{
setResult(mCurrentWeather);
const WeatherResult current = mResult;
setResult(mNextWeather);
const WeatherResult other = mResult;
mResult.mCloudTexture = current.mCloudTexture;
mResult.mNextCloudTexture = other.mCloudTexture;
mResult.mCloudBlendFactor = factor;
mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
mResult.mFogColor = lerp(current.mFogColor, other.mFogColor, factor);
mResult.mSunColor = lerp(current.mSunColor, other.mSunColor, factor);
mResult.mSkyColor = lerp(current.mSkyColor, other.mSkyColor, factor);
mResult.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor, factor);
mResult.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor, factor);
mResult.mFogDepth = lerp(current.mFogDepth, other.mFogDepth, factor);
mResult.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed, factor);
mResult.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed, factor);
mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
mResult.mGlareView = lerp(current.mGlareView, other.mGlareView, factor);
mResult.mNightFade = lerp(current.mNightFade, other.mNightFade, factor);
mResult.mNight = current.mNight;
}
void WeatherManager::update(float duration)
{
float timePassed = mTimePassed;
mTimePassed = 0;
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<ESM::Region>().search (regionstr);
if (region != 0)
{
weatherType = nextWeather(region);
}
}
setWeather(weatherType, false);
}
if (mNextWeather != "")
{
mRemainingTransitionTime -= timePassed;
if (mRemainingTransitionTime < 0)
{
mCurrentWeather = mNextWeather;
mNextWeather = "";
}
}
if (mNextWeather != "")
transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600)));
else
setResult(mCurrentWeather);
mWindSpeed = mResult.mWindSpeed;
mRendering->configureFog(mResult.mFogDepth, mResult.mFogColor);
// disable sun during night
if (mHour >= mNightStart || mHour <= mSunriseTime)
mRendering->getSkyManager()->sunDisable();
else
mRendering->getSkyManager()->sunEnable();
// sun angle
float height;
//Day duration
float dayDuration = (mNightStart - 1) - mSunriseTime;
// rise at 6, set at 20
if (mHour >= mSunriseTime && mHour <= mNightStart)
height = 1 - std::abs(((mHour - dayDuration) / 7.f));
else if (mHour > mNightStart)
height = (mHour - mNightStart) / 4.f;
else //if (mHour > 0 && mHour < 6)
height = 1 - (mHour / mSunriseTime);
int facing = (mHour > 13.f) ? 1 : -1;
Vector3 final(
(height - 1) * facing,
(height - 1) * facing,
height);
mRendering->setSunDirection(final);
/*
* TODO: import separated fadeInStart/Finish, fadeOutStart/Finish
* for masser and secunda
*/
float fadeOutFinish=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Finish");
float fadeInStart=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start");
//moon calculations
float moonHeight;
if (mHour >= fadeInStart)
moonHeight = mHour - fadeInStart;
else if (mHour <= fadeOutFinish)
moonHeight = mHour + fadeOutFinish;
else
moonHeight = 0;
moonHeight /= (24.f - (fadeInStart - fadeOutFinish));
if (moonHeight != 0)
{
int facing = (moonHeight <= 1) ? 1 : -1;
Vector3 masser(
(moonHeight - 1) * facing,
(1 - moonHeight) * facing,
moonHeight);
Vector3 secunda(
(moonHeight - 1) * facing * 1.25,
(1 - moonHeight) * facing * 0.8,
moonHeight);
mRendering->getSkyManager()->setMasserDirection(masser);
mRendering->getSkyManager()->setSecundaDirection(secunda);
mRendering->getSkyManager()->masserEnable();
mRendering->getSkyManager()->secundaEnable();
float angle = (1-moonHeight) * 90.f * facing;
float masserHourFade = calculateHourFade("Masser");
float secundaHourFade = calculateHourFade("Secunda");
float masserAngleFade = calculateAngleFade("Masser", angle);
float secundaAngleFade = calculateAngleFade("Secunda", angle);
masserAngleFade *= masserHourFade;
secundaAngleFade *= secundaHourFade;
mRendering->getSkyManager()->setMasserFade(masserAngleFade);
mRendering->getSkyManager()->setSecundaFade(secundaAngleFade);
}
else
{
mRendering->getSkyManager()->masserDisable();
mRendering->getSkyManager()->secundaDisable();
}
if (mCurrentWeather == "thunderstorm" && mNextWeather == "")
{
if (mThunderFlash > 0)
{
// play the sound after a delay
mThunderSoundDelay -= duration;
if (mThunderSoundDelay <= 0)
{
// pick a random sound
int sound = rand() % 4;
std::string* soundName = NULL;
if (sound == 0) soundName = &mThunderSoundID0;
else if (sound == 1) soundName = &mThunderSoundID1;
else if (sound == 2) soundName = &mThunderSoundID2;
else if (sound == 3) soundName = &mThunderSoundID3;
MWBase::Environment::get().getSoundManager()->playSound(*soundName, 1.0, 1.0);
mThunderSoundDelay = 1000;
}
mThunderFlash -= duration;
if (mThunderFlash > 0)
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
else
{
mThunderChanceNeeded = rand() % 100;
mThunderChance = 0;
mRendering->getSkyManager()->setLightningStrength( 0.f );
}
}
else
{
// no thunder active
mThunderChance += duration*4; // chance increases by 4 percent every second
if (mThunderChance >= mThunderChanceNeeded)
{
mThunderFlash = mThunderThreshold;
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
mThunderSoundDelay = 0.25;
}
}
}
else
mRendering->getSkyManager()->setLightningStrength(0.f);
mRendering->setAmbientColour(mResult.mAmbientColor);
mRendering->sunEnable(false);
mRendering->setSunColour(mResult.mSunColor);
mRendering->getSkyManager()->setWeather(mResult);
// Play sounds
if (mNextWeather == "")
{
std::string ambientSnd = mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID;
if (!ambientSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end())
{
mSoundsPlaying.push_back(ambientSnd);
MWBase::Environment::get().getSoundManager()->playSound(ambientSnd, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
}
std::string rainSnd = mWeatherSettings[mCurrentWeather].mRainLoopSoundID;
if (!rainSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end())
{
mSoundsPlaying.push_back(rainSnd);
MWBase::Environment::get().getSoundManager()->playSound(rainSnd, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
}
}
stopSounds(false);
}
void WeatherManager::stopSounds(bool stopAll)
{
std::vector<std::string>::iterator it = mSoundsPlaying.begin();
while (it!=mSoundsPlaying.end())
{
if (stopAll ||
!((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) ||
(*it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)))
{
MWBase::Environment::get().getSoundManager()->stopSound(*it);
it = mSoundsPlaying.erase(it);
}
else
++it;
}
}
Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const
{
std::vector<char> probability;
RegionModMap::const_iterator iter = mRegionMods.find(Misc::StringUtils::lowerCase(region->mId));
if(iter != mRegionMods.end())
probability = iter->second;
else
{
probability.reserve(10);
probability.push_back(region->mData.mClear);
probability.push_back(region->mData.mCloudy);
probability.push_back(region->mData.mFoggy);
probability.push_back(region->mData.mOvercast);
probability.push_back(region->mData.mRain);
probability.push_back(region->mData.mThunder);
probability.push_back(region->mData.mAsh);
probability.push_back(region->mData.mBlight);
probability.push_back(region->mData.mA);
probability.push_back(region->mData.mB);
}
/*
* All probabilities must add to 100 (responsibility of the user).
* If chances A and B has values 30 and 70 then by generating
* 100 numbers 1..100, 30% will be lesser or equal 30 and
* 70% will be greater than 30 (in theory).
*/
int chance = (rand() % 100) + 1; // 1..100
int sum = 0;
unsigned int i = 0;
for (; i < probability.size(); ++i)
{
sum += probability[i];
if (chance < sum)
break;
}
switch (i)
{
case 1:
return "cloudy";
case 2:
return "foggy";
case 3:
return "overcast";
case 4:
return "rain";
case 5:
return "thunderstorm";
case 6:
return "ashstorm";
case 7:
return "blight";
case 8:
return "snow";
case 9:
return "blizzard";
default: // case 0
return "clear";
}
}
void WeatherManager::setHour(const float hour)
{
mHour = hour;
}
void WeatherManager::setDate(const int day, const int month)
{
mDay = day;
mMonth = month;
}
unsigned int WeatherManager::getWeatherID() const
{
// Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather
if (mCurrentWeather == "clear")
return 0;
else if (mCurrentWeather == "cloudy")
return 1;
else if (mCurrentWeather == "foggy")
return 2;
else if (mCurrentWeather == "overcast")
return 3;
else if (mCurrentWeather == "rain")
return 4;
else if (mCurrentWeather == "thunderstorm")
return 5;
else if (mCurrentWeather == "ashstorm")
return 6;
else if (mCurrentWeather == "blight")
return 7;
else if (mCurrentWeather == "snow")
return 8;
else if (mCurrentWeather == "blizzard")
return 9;
else
return 0;
}
void WeatherManager::changeWeather(const std::string& region, const unsigned int id)
{
// make sure this region exists
MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().find(region);
std::string weather;
if (id==0)
weather = "clear";
else if (id==1)
weather = "cloudy";
else if (id==2)
weather = "foggy";
else if (id==3)
weather = "overcast";
else if (id==4)
weather = "rain";
else if (id==5)
weather = "thunderstorm";
else if (id==6)
weather = "ashstorm";
else if (id==7)
weather = "blight";
else if (id==8)
weather = "snow";
else if (id==9)
weather = "blizzard";
else
weather = "clear";
mRegionOverrides[Misc::StringUtils::lowerCase(region)] = weather;
std::string playerRegion = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion;
if (Misc::StringUtils::ciEqual(region, playerRegion))
setWeather(weather);
}
void WeatherManager::modRegion(const std::string &regionid, const std::vector<char> &chances)
{
mRegionMods[Misc::StringUtils::lowerCase(regionid)] = chances;
// Start transitioning right away if the region no longer supports the current weather type
unsigned int current = getWeatherID();
if(current >= chances.size() || chances[current] == 0)
mWeatherUpdateTime = 0.0f;
}
float WeatherManager::getWindSpeed() const
{
return mWindSpeed;
}
bool WeatherManager::isNight() const
{
return (mHour < mSunriseTime || mHour > mNightStart - 1);
}