You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw-tes3mp/apps/openmw/mwworld/weather.cpp

759 lines
30 KiB
C++

#include "weather.hpp"
#include "world.hpp"
#include "player.hpp"
#include "../mwrender/renderingmanager.hpp"
13 years ago
#include "../mwsound/soundmanager.hpp"
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace Ogre;
using namespace MWWorld;
13 years ago
using namespace MWSound;
#define lerp(x, y) (x * (1-factor) + y * factor)
13 years ago
const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0";
const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1";
const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2";
const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3";
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) :
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
{
mRendering = rendering;
13 years ago
mEnvironment = env;
#define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f)
/// \todo read these from Morrowind.ini
Weather clear;
clear.mCloudTexture = "tx_sky_clear.dds";
clear.mCloudsMaximumPercent = 1.0;
13 years ago
clear.mTransitionDelta = 0.015;
clear.mSkySunriseColor = clr(118, 141, 164);
clear.mSkyDayColor = clr(95, 135, 203);
clear.mSkySunsetColor = clr(56, 89, 129);
clear.mSkyNightColor = clr(9, 10, 11);
clear.mFogSunriseColor = clr(255, 189, 157);
clear.mFogDayColor = clr(206, 227, 255);
clear.mFogSunsetColor = clr(255, 189, 157);
clear.mFogNightColor = clr(9, 10, 11);
clear.mAmbientSunriseColor = clr(47, 66, 96);
clear.mAmbientDayColor = clr(137, 140, 160);
clear.mAmbientSunsetColor = clr(68, 75, 96);
clear.mAmbientNightColor = clr(32, 35, 42);
clear.mSunSunriseColor = clr(242, 159, 99);
clear.mSunDayColor = clr(255, 252, 238);
clear.mSunSunsetColor = clr(255, 115, 79);
clear.mSunNightColor = clr(59, 97, 176);
13 years ago
clear.mSunDiscSunsetColor = clr(255, 189, 157);
clear.mLandFogDayDepth = 0.69;
clear.mLandFogNightDepth = 0.69;
clear.mWindSpeed = 0.1;
clear.mCloudSpeed = 1.25;
clear.mGlareView = 1.0;
mWeatherSettings["clear"] = clear;
Weather cloudy;
cloudy.mCloudTexture = "tx_sky_cloudy.dds";
cloudy.mCloudsMaximumPercent = 1.0;
13 years ago
cloudy.mTransitionDelta = 0.015;
cloudy.mSkySunriseColor = clr(126, 158, 173);
cloudy.mSkyDayColor = clr(117, 160, 215);
cloudy.mSkySunsetColor = clr(111, 114, 159);
cloudy.mSkyNightColor = clr(9, 10, 11);
cloudy.mFogSunriseColor = clr(255, 207, 149);
cloudy.mFogDayColor = clr(245, 235, 224);
cloudy.mFogSunsetColor = clr(255, 155, 106);
cloudy.mFogNightColor = clr(9, 10, 11);
cloudy.mAmbientSunriseColor = clr(66, 74, 87);
cloudy.mAmbientDayColor = clr(137, 145, 160);
cloudy.mAmbientSunsetColor = clr(71, 80, 92);
cloudy.mAmbientNightColor = clr(32, 39, 54);
cloudy.mSunSunriseColor = clr(241, 177, 99);
cloudy.mSunDayColor = clr(255, 236, 221);
cloudy.mSunSunsetColor = clr(255, 89, 00);
cloudy.mSunNightColor = clr(77, 91, 124);
13 years ago
cloudy.mSunDiscSunsetColor = clr(255, 202, 179);
cloudy.mLandFogDayDepth = 0.72;
cloudy.mLandFogNightDepth = 0.72;
cloudy.mWindSpeed = 0.2;
cloudy.mCloudSpeed = 2;
cloudy.mGlareView = 1.0;
mWeatherSettings["cloudy"] = cloudy;
Weather foggy;
foggy.mCloudTexture = "tx_sky_foggy.dds";
foggy.mCloudsMaximumPercent = 1.0;
foggy.mTransitionDelta = 0.015;
foggy.mSkySunriseColor = clr(197, 190, 180);
foggy.mSkyDayColor = clr(184, 211, 228);
foggy.mSkySunsetColor = clr(142, 159, 176);
foggy.mSkyNightColor = clr(18, 23, 28);
foggy.mFogSunriseColor = clr(173, 164, 148);
foggy.mFogDayColor = clr(150, 187, 209);
foggy.mFogSunsetColor = clr(113, 135, 157);
foggy.mFogNightColor = clr(19, 24, 29);
foggy.mAmbientSunriseColor = clr(48, 43, 37);
foggy.mAmbientDayColor = clr(92, 109, 120);
foggy.mAmbientSunsetColor = clr(28, 33, 39);
foggy.mAmbientNightColor = clr(28, 33, 39);
foggy.mSunSunriseColor = clr(177, 162, 137);
foggy.mSunDayColor = clr(111, 131, 151);
foggy.mSunSunsetColor = clr(125, 157, 189);
foggy.mSunNightColor = clr(81, 100, 119);
foggy.mSunDiscSunsetColor = clr(223, 223, 223);
foggy.mLandFogDayDepth = 1.0;
foggy.mLandFogNightDepth = 1.9;
foggy.mWindSpeed = 0;
foggy.mCloudSpeed = 1.25;
foggy.mGlareView = 0.25;
mWeatherSettings["foggy"] = foggy;
13 years ago
Weather thunderstorm;
thunderstorm.mCloudTexture = "tx_sky_thunder.dds";
thunderstorm.mCloudsMaximumPercent = 0.66;
thunderstorm.mTransitionDelta = 0.03;
thunderstorm.mSkySunriseColor = clr(35, 36, 39);
thunderstorm.mSkyDayColor = clr(97, 104, 115);
thunderstorm.mSkySunsetColor = clr(35, 36, 39);
thunderstorm.mSkyNightColor = clr(19, 20, 22);
thunderstorm.mFogSunriseColor = clr(70, 74, 85);
thunderstorm.mFogDayColor = clr(97, 104, 115);
thunderstorm.mFogSunsetColor = clr(70, 74, 85);
thunderstorm.mFogNightColor = clr(19, 20, 22);
thunderstorm.mAmbientSunriseColor = clr(54, 54, 54);
thunderstorm.mAmbientDayColor = clr(90, 90, 90);
thunderstorm.mAmbientSunsetColor = clr(54, 54, 54);
thunderstorm.mAmbientNightColor = clr(49, 51, 54);
thunderstorm.mSunSunriseColor = clr(91, 99, 122);
thunderstorm.mSunDayColor = clr(138, 144, 155);
thunderstorm.mSunSunsetColor = clr(96, 101, 117);
thunderstorm.mSunNightColor = clr(55, 76, 110);
thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128);
thunderstorm.mLandFogDayDepth = 1;
thunderstorm.mLandFogNightDepth = 1.15;
thunderstorm.mWindSpeed = 0.5;
thunderstorm.mCloudSpeed = 3;
thunderstorm.mGlareView = 0;
thunderstorm.mRainLoopSoundID = "rain heavy";
13 years ago
mWeatherSettings["thunderstorm"] = thunderstorm;
Weather rain;
rain.mCloudTexture = "tx_sky_rainy.dds";
rain.mCloudsMaximumPercent = 0.66;
rain.mTransitionDelta = 0.015;
rain.mSkySunriseColor = clr(71, 74, 75);
rain.mSkyDayColor = clr(116, 120, 122);
rain.mSkySunsetColor = clr(73, 73, 73);
rain.mSkyNightColor = clr(24, 25, 26);
rain.mFogSunriseColor = clr(71, 74, 75);
rain.mFogDayColor = clr(116, 120, 122);
rain.mFogSunsetColor = clr(73, 73, 73);
rain.mFogNightColor = clr(24, 25, 26);
rain.mAmbientSunriseColor = clr(97, 90, 88);
rain.mAmbientDayColor = clr(105, 110, 113);
rain.mAmbientSunsetColor = clr(88, 97, 97);
rain.mAmbientNightColor = clr(50, 55, 67);
rain.mSunSunriseColor = clr(131, 122, 120);
rain.mSunDayColor = clr(149, 157, 170);
rain.mSunSunsetColor = clr(120, 126, 131);
rain.mSunNightColor = clr(50, 62, 101);
rain.mSunDiscSunsetColor = clr(128, 128, 128);
rain.mLandFogDayDepth = 0.8;
rain.mLandFogNightDepth = 0.8;
rain.mWindSpeed = 0.3;
rain.mCloudSpeed = 2;
rain.mGlareView = 0;
rain.mRainLoopSoundID = "rain";
mWeatherSettings["rain"] = rain;
Weather overcast;
overcast.mCloudTexture = "tx_sky_overcast.dds";
overcast.mCloudsMaximumPercent = 1.0;
overcast.mTransitionDelta = 0.015;
overcast.mSkySunriseColor = clr(91, 99, 106);
overcast.mSkyDayColor = clr(143, 146, 149);
overcast.mSkySunsetColor = clr(108, 115, 121);
overcast.mSkyNightColor = clr(19, 22, 25);
overcast.mFogSunriseColor = clr(91, 99, 106);
overcast.mFogDayColor = clr(143, 146, 149);
overcast.mFogSunsetColor = clr(108, 115, 121);
overcast.mFogNightColor = clr(19, 22, 25);
overcast.mAmbientSunriseColor = clr(84, 88, 92);
overcast.mAmbientDayColor = clr(93, 96, 105);
overcast.mAmbientSunsetColor = clr(83, 77, 75);
overcast.mAmbientNightColor = clr(57, 60, 66);
overcast.mSunSunriseColor = clr(87, 125, 163);
overcast.mSunDayColor = clr(163, 169, 183);
overcast.mSunSunsetColor = clr(85, 103, 157);
overcast.mSunNightColor = clr(32, 54, 100);
overcast.mSunDiscSunsetColor = clr(128, 128, 128);
overcast.mLandFogDayDepth = 0.7;
overcast.mLandFogNightDepth = 0.7;
overcast.mWindSpeed = 0.2;
overcast.mCloudSpeed = 1.5;
overcast.mGlareView = 0;
mWeatherSettings["overcast"] = overcast;
Weather ashstorm;
ashstorm.mCloudTexture = "tx_sky_ashstorm.dds";
ashstorm.mCloudsMaximumPercent = 1.0;
ashstorm.mTransitionDelta = 0.035;
ashstorm.mSkySunriseColor = clr(91, 56, 51);
ashstorm.mSkyDayColor = clr(124, 73, 58);
ashstorm.mSkySunsetColor = clr(106, 55, 40);
ashstorm.mSkyNightColor = clr(20, 21, 22);
ashstorm.mFogSunriseColor = clr(91, 56, 51);
ashstorm.mFogDayColor = clr(124, 73, 58);
ashstorm.mFogSunsetColor = clr(106, 55, 40);
ashstorm.mFogNightColor = clr(20, 21, 22);
ashstorm.mAmbientSunriseColor = clr(52, 42, 37);
ashstorm.mAmbientDayColor = clr(75, 49, 41);
ashstorm.mAmbientSunsetColor = clr(48, 39, 35);
ashstorm.mAmbientNightColor = clr(36, 42, 49);
ashstorm.mSunSunriseColor = clr(184, 91, 71);
ashstorm.mSunDayColor = clr(228, 139, 114);
ashstorm.mSunSunsetColor = clr(185, 86, 57);
ashstorm.mSunNightColor = clr(54, 66, 74);
ashstorm.mSunDiscSunsetColor = clr(128, 128, 128);
ashstorm.mLandFogDayDepth = 1.1;
ashstorm.mLandFogNightDepth = 1.2;
ashstorm.mWindSpeed = 0.8;
ashstorm.mCloudSpeed = 7;
ashstorm.mGlareView = 0;
ashstorm.mAmbientLoopSoundID = "ashstorm";
mWeatherSettings["ashstorm"] = ashstorm;
Weather blight;
blight.mCloudTexture = "tx_sky_blight.dds";
blight.mCloudsMaximumPercent = 1.0;
blight.mTransitionDelta = 0.04;
blight.mSkySunriseColor = clr(90, 35, 35);
blight.mSkyDayColor = clr(90, 35, 35);
blight.mSkySunsetColor = clr(92, 33, 33);
blight.mSkyNightColor = clr(44, 14, 14);
blight.mFogSunriseColor = clr(90, 35, 35);
blight.mFogDayColor = clr(128, 19, 19);
blight.mFogSunsetColor = clr(92, 33, 33);
blight.mFogNightColor = clr(44, 14, 14);
blight.mAmbientSunriseColor = clr(61, 40, 40);
blight.mAmbientDayColor = clr(79, 54, 54);
blight.mAmbientSunsetColor = clr(61, 40, 40);
blight.mAmbientNightColor = clr(56, 58, 62);
blight.mSunSunriseColor = clr(180, 78, 78);
blight.mSunDayColor = clr(224, 84, 84);
blight.mSunSunsetColor = clr(180, 78, 78);
blight.mSunNightColor = clr(61, 91, 143);
blight.mSunDiscSunsetColor = clr(128, 128, 128);
blight.mLandFogDayDepth = 1.1;
blight.mLandFogNightDepth = 1.2;
blight.mWindSpeed = 0.9;
blight.mCloudSpeed = 9;
blight.mGlareView = 0;
blight.mAmbientLoopSoundID = "blight";
mWeatherSettings["blight"] = blight;
Weather snow;
snow.mCloudTexture = "tx_bm_sky_snow.dds";
snow.mCloudsMaximumPercent = 1.0;
snow.mTransitionDelta = 0.014;
snow.mSkySunriseColor = clr(196, 91, 91);
snow.mSkyDayColor = clr(153, 158, 166);
snow.mSkySunsetColor = clr(96, 115, 134);
snow.mSkyNightColor = clr(31, 35, 39);
snow.mFogSunriseColor = clr(106, 91, 91);
snow.mFogDayColor = clr(153, 158, 166);
snow.mFogSunsetColor = clr(96, 115, 134);
snow.mFogNightColor = clr(31, 35, 39);
snow.mAmbientSunriseColor = clr(92, 84, 84);
snow.mAmbientDayColor = clr(93, 96, 105);
snow.mAmbientSunsetColor = clr(70, 79, 87);
snow.mAmbientNightColor = clr(49, 58, 68);
snow.mSunSunriseColor = clr(141, 109, 109);
snow.mSunDayColor = clr(163, 169, 183);
snow.mSunSunsetColor = clr(101, 121, 141);
snow.mSunNightColor = clr(55, 66, 77);
snow.mSunDiscSunsetColor = clr(128, 128, 128);
snow.mLandFogDayDepth = 1.0;
snow.mLandFogNightDepth = 1.2;
snow.mWindSpeed = 0;
snow.mCloudSpeed = 1.5;
snow.mGlareView = 0;
mWeatherSettings["snow"] = snow;
Weather blizzard;
blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds";
blizzard.mCloudsMaximumPercent = 1.0;
blizzard.mTransitionDelta = 0.030;
blizzard.mSkySunriseColor = clr(91, 99, 106);
blizzard.mSkyDayColor = clr(121, 133, 145);
blizzard.mSkySunsetColor = clr(108, 115, 121);
blizzard.mSkyNightColor = clr(27, 29, 31);
blizzard.mFogSunriseColor = clr(91, 99, 106);
blizzard.mFogDayColor = clr(121, 133, 145);
blizzard.mFogSunsetColor = clr(108, 115, 121);
blizzard.mFogNightColor = clr(21, 24, 28);
blizzard.mAmbientSunriseColor = clr(84, 88, 92);
blizzard.mAmbientDayColor = clr(93, 96, 105);
blizzard.mAmbientSunsetColor = clr(83, 77, 75);
blizzard.mAmbientNightColor = clr(53, 62, 70);
blizzard.mSunSunriseColor = clr(114, 128, 146);
blizzard.mSunDayColor = clr(163, 169, 183);
blizzard.mSunSunsetColor = clr(106, 114, 136);
blizzard.mSunNightColor = clr(57, 66, 74);
blizzard.mSunDiscSunsetColor = clr(128, 128, 128);
blizzard.mLandFogDayDepth = 2.8;
blizzard.mLandFogNightDepth = 3.0;
blizzard.mWindSpeed = 0.9;
blizzard.mCloudSpeed = 7.5;
blizzard.mGlareView = 0;
blizzard.mAmbientLoopSoundID = "BM Blizzard";
mWeatherSettings["blizzard"] = blizzard;
}
void WeatherManager::setWeather(const String& weather, bool instant)
{
if (instant || mFirstUpdate)
{
mNextWeather = "";
mCurrentWeather = weather;
mFirstUpdate = false;
}
else
{
// if there's another transition that hasn't finished yet, just apply it immediately
if (mNextWeather != "")
mCurrentWeather = mNextWeather;
mNextWeather = weather;
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60;
}
}
WeatherResult WeatherManager::getResult(const String& weather)
{
const Weather& current = mWeatherSettings[weather];
WeatherResult result;
result.mCloudTexture = current.mCloudTexture;
result.mCloudBlendFactor = 0;
result.mCloudOpacity = current.mCloudsMaximumPercent;
result.mWindSpeed = current.mWindSpeed;
result.mCloudSpeed = current.mCloudSpeed;
result.mGlareView = current.mGlareView;
result.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
const float fade_duration = current.mTransitionDelta * 24.f;
result.mNight = (mHour < 6.f+fade_duration || mHour > 20.f-fade_duration);
// night
if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
|| mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
{
result.mFogColor = current.mFogNightColor;
result.mAmbientColor = current.mAmbientNightColor;
result.mSunColor = current.mSunNightColor;
result.mSkyColor = current.mSkyNightColor;
result.mNightFade = 1.f;
}
// sunrise
else if (mHour >= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) && mHour <= WeatherGlobals::mSunriseTime)
{
if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration))
{
// fade in
float advance = (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)-mHour;
float factor = (advance / fade_duration);
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor);
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor);
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor);
result.mNightFade = factor;
}
else if (mHour >= (WeatherGlobals::mSunriseTime-fade_duration))
{
// fade out
float advance = mHour-(WeatherGlobals::mSunriseTime-fade_duration);
float factor = advance / fade_duration;
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor);
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor);
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor);
}
else
{
result.mFogColor = current.mFogSunriseColor;
result.mAmbientColor = current.mAmbientSunriseColor;
result.mSunColor = current.mSunSunriseColor;
result.mSkyColor = current.mSkySunriseColor;
}
}
// day
else if (mHour >= (WeatherGlobals::mSunriseTime) && mHour <= (WeatherGlobals::mSunsetTime))
{
result.mFogColor = current.mFogDayColor;
result.mAmbientColor = current.mAmbientDayColor;
result.mSunColor = current.mSunDayColor;
result.mSkyColor = current.mSkyDayColor;
}
// sunset
else if (mHour >= (WeatherGlobals::mSunsetTime) && mHour <= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
{
if (mHour <= (WeatherGlobals::mSunsetTime+fade_duration))
{
// fade in
float advance = (WeatherGlobals::mSunsetTime+fade_duration)-mHour;
float factor = (advance / fade_duration);
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor);
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor);
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor);
}
else if (mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration))
{
// fade out
float advance = mHour-(WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration);
float factor = advance / fade_duration;
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor);
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor);
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor);
result.mNightFade = factor;
}
else
{
result.mFogColor = current.mFogSunsetColor;
result.mAmbientColor = current.mAmbientSunsetColor;
result.mSunColor = current.mSunSunsetColor;
result.mSkyColor = current.mSkySunsetColor;
}
}
return result;
}
WeatherResult WeatherManager::transition(float factor)
{
const WeatherResult& current = getResult(mCurrentWeather);
const WeatherResult& other = getResult(mNextWeather);
WeatherResult result;
result.mCloudTexture = current.mCloudTexture;
result.mNextCloudTexture = other.mCloudTexture;
result.mCloudBlendFactor = factor;
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
result.mFogColor = lerp(current.mFogColor, other.mFogColor);
result.mSunColor = lerp(current.mSunColor, other.mSunColor);
result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor);
result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor);
result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor);
result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth);
result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed);
result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed);
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
result.mGlareView = lerp(current.mGlareView, other.mGlareView);
result.mNight = current.mNight;
// sound change behaviour:
// if 'other' has a new sound, switch to it after 1/2 of the transition length
if (other.mAmbientLoopSoundID != "")
result.mAmbientLoopSoundID = factor>0.5 ? other.mAmbientLoopSoundID : current.mAmbientLoopSoundID;
// if 'current' has a sound and 'other' does not have a sound, turn off the sound immediately
else if (current.mAmbientLoopSoundID != "")
result.mAmbientLoopSoundID = "";
return result;
}
void WeatherManager::update(float duration)
{
mWeatherUpdateTime -= duration;
13 years ago
if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior())
{
std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region;
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
{
mCurrentRegion = regionstr;
mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f;
// get weather probabilities for the current region
const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr);
float clear = region->data.clear/255.f;
float cloudy = region->data.cloudy/255.f;
float foggy = region->data.foggy/255.f;
float overcast = region->data.overcast/255.f;
float rain = region->data.rain/255.f;
float thunder = region->data.thunder/255.f;
float ash = region->data.ash/255.f;
float blight = region->data.blight/255.f;
float snow = region->data.a/255.f;
float blizzard = region->data.b/255.f;
// re-scale to 100 percent
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
srand(time(NULL));
float random = ((rand()%100)/100.f) * total;
std::string weather;
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blizzard";
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "snow";
else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blight";
else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
weather = "ashstorm";
else if (random >= rain+overcast+foggy+cloudy+clear)
weather = "thunderstorm";
else if (random >= overcast+foggy+cloudy+clear)
weather = "rain";
else if (random >= foggy+cloudy+clear)
weather = "overcast";
else if (random >= cloudy+clear)
weather = "foggy";
else if (random >= clear)
weather = "cloudy";
else
weather = "clear";
setWeather(weather, false);
/*
std::cout << "roll result: " << random << std::endl;
std::cout << regionstr << " weather probabilities: " << clear << " " << cloudy << " " << foggy << " "
<< overcast << " " << rain << " " << thunder << " " << ash << " " << blight << " " << snow << " "
<< blizzard << std::endl;
std::cout << "New weather : " << weather << std::endl;
*/
}
13 years ago
WeatherResult result;
if (mNextWeather != "")
{
13 years ago
mRemainingTransitionTime -= duration;
if (mRemainingTransitionTime < 0)
{
mCurrentWeather = mNextWeather;
mNextWeather = "";
}
}
13 years ago
if (mNextWeather != "")
result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60)));
13 years ago
else
result = getResult(mCurrentWeather);
// disable sun during night
if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration
|| mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
mRendering->getSkyManager()->sunDisable();
else
{
// during day, calculate sun angle
float height = 1-std::abs(((mHour-13)/7.f));
int facing = mHour > 13.f ? 1 : -1;
Vector3 final(
(1-height)*facing,
(1-height)*facing,
height);
mRendering->setSunDirection(final);
mRendering->getSkyManager()->sunEnable();
}
// moon calculations
float night;
if (mHour >= 14)
night = mHour-14;
else if (mHour <= 10)
night = mHour+10;
else
night = 0;
night /= 20.f;
if (night != 0)
{
float moonHeight = 1-std::abs((night-0.5)*2);
int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1;
Vector3 masser(
(1-moonHeight)*facing,
(1-moonHeight)*facing,
moonHeight);
Vector3 secunda(
(1-moonHeight)*facing*0.8,
(1-moonHeight)*facing*1.25,
moonHeight);
mRendering->getSkyManager()->setMasserDirection(masser);
mRendering->getSkyManager()->setSecundaDirection(secunda);
mRendering->getSkyManager()->masserEnable();
mRendering->getSkyManager()->secundaEnable();
float hour_fade;
if (mHour >= 7.f && mHour <= 14.f)
hour_fade = 1-(mHour-7)/3.f;
else if (mHour >= 14 && mHour <= 15.f)
hour_fade = mHour-14;
else
hour_fade = 1;
float secunda_angle_fade;
float masser_angle_fade;
float angle = moonHeight*90.f;
if (angle >= 30 && angle <= 50)
secunda_angle_fade = (angle-30)/20.f;
else if (angle <30)
secunda_angle_fade = 0.f;
else
secunda_angle_fade = 1.f;
if (angle >= 40 && angle <= 50)
masser_angle_fade = (angle-40)/10.f;
else if (angle <40)
masser_angle_fade = 0.f;
else
masser_angle_fade = 1.f;
masser_angle_fade *= hour_fade;
secunda_angle_fade *= hour_fade;
mRendering->getSkyManager()->setMasserFade(masser_angle_fade);
mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade);
}
else
{
mRendering->getSkyManager()->masserDisable();
mRendering->getSkyManager()->secundaDisable();
}
13 years ago
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;
if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0;
else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1;
else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2;
else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3;
mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0);
mThunderSoundDelay = 1000;
}
mThunderFlash -= duration;
if (mThunderFlash > 0)
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
else
{
srand(time(NULL));
mThunderChanceNeeded = rand() % 100;
mThunderChance = 0;
mRendering->getSkyManager()->setThunder( 0.f );
}
}
else
{
// no thunder active
mThunderChance += duration*4; // chance increases by 4 percent every second
if (mThunderChance >= mThunderChanceNeeded)
{
mThunderFlash = WeatherGlobals::mThunderThreshold;
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
}
}
}
mRendering->setAmbientColour(result.mAmbientColor);
mRendering->sunEnable();
mRendering->setSunColour(result.mSunColor);
mRendering->skyEnable();
mRendering->getSkyManager()->setWeather(result);
}
else
{
mRendering->sunDisable();
mRendering->skyDisable();
13 years ago
mRendering->getSkyManager()->setThunder(0.f);
}
}
void WeatherManager::setHour(const float hour)
{
// accelerate a bit for testing
/*
mHour += 0.005;
if (mHour >= 24.f) mHour = 0.f;
std::cout << "hour " << mHour << std::endl;
*/
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 == "thunder")
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;
}