2012-02-21 19:22:46 +00:00
|
|
|
#ifndef GAME_MWWORLD_WEATHER_H
|
|
|
|
#define GAME_MWWORLD_WEATHER_H
|
|
|
|
|
2014-03-21 06:33:11 +00:00
|
|
|
#include <stdint.h>
|
2014-03-20 06:25:52 +00:00
|
|
|
#include <string>
|
2015-06-03 21:04:35 +00:00
|
|
|
#include <map>
|
2014-03-20 06:25:52 +00:00
|
|
|
|
2015-04-14 13:55:56 +00:00
|
|
|
#include <osg/Vec4f>
|
2013-03-15 09:26:04 +00:00
|
|
|
|
2018-04-10 03:06:44 +00:00
|
|
|
#include <components/fallback/fallback.hpp>
|
|
|
|
|
2014-12-01 19:31:33 +00:00
|
|
|
#include "../mwbase/soundmanager.hpp"
|
|
|
|
|
2015-08-05 02:07:42 +00:00
|
|
|
#include "../mwrender/sky.hpp"
|
|
|
|
|
2013-06-19 14:18:43 +00:00
|
|
|
namespace ESM
|
|
|
|
{
|
|
|
|
struct Region;
|
2015-08-27 03:59:21 +00:00
|
|
|
struct RegionWeatherState;
|
2014-03-20 06:25:52 +00:00
|
|
|
class ESMWriter;
|
|
|
|
class ESMReader;
|
2013-06-19 14:18:43 +00:00
|
|
|
}
|
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
namespace MWRender
|
|
|
|
{
|
|
|
|
class RenderingManager;
|
|
|
|
}
|
|
|
|
|
2014-04-28 09:29:57 +00:00
|
|
|
namespace Loading
|
|
|
|
{
|
|
|
|
class Listener;
|
|
|
|
}
|
|
|
|
|
2016-01-06 11:46:06 +00:00
|
|
|
namespace Fallback
|
|
|
|
{
|
|
|
|
class Map;
|
|
|
|
}
|
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
namespace MWWorld
|
|
|
|
{
|
2015-08-27 03:59:21 +00:00
|
|
|
class TimeStamp;
|
2013-03-15 09:26:04 +00:00
|
|
|
|
2019-01-27 12:55:36 +00:00
|
|
|
enum NightDayMode
|
|
|
|
{
|
|
|
|
Default = 0,
|
|
|
|
ExteriorNight = 1,
|
|
|
|
InteriorDay = 2
|
|
|
|
};
|
|
|
|
|
2018-04-10 03:06:44 +00:00
|
|
|
struct WeatherSetting
|
|
|
|
{
|
|
|
|
float mPreSunriseTime;
|
|
|
|
float mPostSunriseTime;
|
|
|
|
float mPreSunsetTime;
|
|
|
|
float mPostSunsetTime;
|
|
|
|
};
|
2015-11-01 21:47:40 +00:00
|
|
|
|
|
|
|
struct TimeOfDaySettings
|
|
|
|
{
|
|
|
|
float mNightStart;
|
|
|
|
float mNightEnd;
|
|
|
|
float mDayStart;
|
|
|
|
float mDayEnd;
|
2018-04-10 03:06:44 +00:00
|
|
|
|
|
|
|
std::map<std::string, WeatherSetting> mSunriseTransitions;
|
|
|
|
|
|
|
|
float mStarsPostSunsetStart;
|
|
|
|
float mStarsPreSunriseFinish;
|
|
|
|
float mStarsFadingDuration;
|
|
|
|
|
|
|
|
WeatherSetting getSetting(const std::string& type) const
|
|
|
|
{
|
|
|
|
std::map<std::string, WeatherSetting>::const_iterator it = mSunriseTransitions.find(type);
|
|
|
|
if (it != mSunriseTransitions.end())
|
|
|
|
{
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return { 1.f, 1.f, 1.f, 1.f };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-22 06:08:48 +00:00
|
|
|
void addSetting(const std::string& type)
|
2018-04-10 03:06:44 +00:00
|
|
|
{
|
|
|
|
WeatherSetting setting = {
|
2019-01-22 06:08:48 +00:00
|
|
|
Fallback::Map::getFloat("Weather_" + type + "_Pre-Sunrise_Time"),
|
|
|
|
Fallback::Map::getFloat("Weather_" + type + "_Post-Sunrise_Time"),
|
|
|
|
Fallback::Map::getFloat("Weather_" + type + "_Pre-Sunset_Time"),
|
|
|
|
Fallback::Map::getFloat("Weather_" + type + "_Post-Sunset_Time")
|
2018-04-10 03:06:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
mSunriseTransitions[type] = setting;
|
|
|
|
}
|
2015-11-01 21:47:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Interpolates between 4 data points (sunrise, day, sunset, night) based on the time of day.
|
|
|
|
/// The template value could be a floating point number, or a color.
|
|
|
|
template <typename T>
|
|
|
|
class TimeOfDayInterpolator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TimeOfDayInterpolator(const T& sunrise, const T& day, const T& sunset, const T& night)
|
|
|
|
: mSunriseValue(sunrise), mDayValue(day), mSunsetValue(sunset), mNightValue(night)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-04-10 03:06:44 +00:00
|
|
|
T getValue (const float gameHour, const TimeOfDaySettings& timeSettings, const std::string& prefix) const;
|
2015-11-01 21:47:40 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
T mSunriseValue, mDayValue, mSunsetValue, mNightValue;
|
|
|
|
};
|
|
|
|
|
2012-02-22 19:39:14 +00:00
|
|
|
/// Defines a single weather setting (according to INI)
|
2015-08-16 04:38:49 +00:00
|
|
|
class Weather
|
2012-02-21 19:22:46 +00:00
|
|
|
{
|
2015-08-16 04:38:49 +00:00
|
|
|
public:
|
|
|
|
Weather(const std::string& name,
|
|
|
|
float stormWindSpeed,
|
|
|
|
float rainSpeed,
|
2017-09-21 10:08:45 +00:00
|
|
|
float dlFactor,
|
|
|
|
float dlOffset,
|
2015-08-16 04:38:49 +00:00
|
|
|
const std::string& particleEffect);
|
|
|
|
|
2014-03-20 06:25:52 +00:00
|
|
|
std::string mCloudTexture;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2015-11-01 21:47:40 +00:00
|
|
|
// Sky (atmosphere) color
|
|
|
|
TimeOfDayInterpolator<osg::Vec4f> mSkyColor;
|
|
|
|
// Fog color
|
|
|
|
TimeOfDayInterpolator<osg::Vec4f> mFogColor;
|
|
|
|
// Ambient lighting color
|
|
|
|
TimeOfDayInterpolator<osg::Vec4f> mAmbientColor;
|
|
|
|
// Sun (directional) lighting color
|
|
|
|
TimeOfDayInterpolator<osg::Vec4f> mSunColor;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
// Fog depth/density
|
2015-11-01 22:03:16 +00:00
|
|
|
TimeOfDayInterpolator<float> mLandFogDepth;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2015-09-21 17:43:48 +00:00
|
|
|
// Color modulation for the sun itself during sunset
|
2015-04-14 13:55:56 +00:00
|
|
|
osg::Vec4f mSunDiscSunsetColor;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2014-06-24 16:37:38 +00:00
|
|
|
// Used by scripts to animate signs, etc based on the wind (GetWindSpeed)
|
2012-02-21 19:22:46 +00:00
|
|
|
float mWindSpeed;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
// Cloud animation speed multiplier
|
|
|
|
float mCloudSpeed;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2015-08-07 05:08:18 +00:00
|
|
|
// Value between 0 and 1, defines the strength of the sun glare effect.
|
|
|
|
// Also appears to modify how visible the sun, moons, and stars are for various weather effects.
|
2012-02-21 19:22:46 +00:00
|
|
|
float mGlareView;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2017-09-21 10:08:45 +00:00
|
|
|
// Fog factor and offset used with distant land rendering.
|
|
|
|
struct {
|
|
|
|
float FogFactor;
|
|
|
|
float FogOffset;
|
|
|
|
} mDL;
|
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
// Sound effect
|
|
|
|
// This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
|
2014-03-20 06:25:52 +00:00
|
|
|
std::string mAmbientLoopSoundID;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2014-06-26 18:26:46 +00:00
|
|
|
// Is this an ash storm / blight storm? If so, the following will happen:
|
|
|
|
// - The particles and clouds will be oriented so they appear to come from the Red Mountain.
|
2014-06-24 16:37:38 +00:00
|
|
|
// - Characters will animate their hand to protect eyes from the storm when looking in its direction (idlestorm animation)
|
2014-06-26 18:26:46 +00:00
|
|
|
// - Slower movement when walking against the storm (fStromWalkMult)
|
2014-06-24 16:37:38 +00:00
|
|
|
bool mIsStorm;
|
|
|
|
|
2014-06-25 16:20:21 +00:00
|
|
|
// How fast does rain travel down?
|
|
|
|
// In Morrowind.ini this is set globally, but we may want to change it per weather later.
|
|
|
|
float mRainSpeed;
|
|
|
|
|
|
|
|
// How often does a new rain mesh spawn?
|
2019-10-12 15:35:06 +00:00
|
|
|
float mRainEntranceSpeed;
|
|
|
|
|
|
|
|
// Maximum count of rain particles
|
|
|
|
int mRainMaxRaindrops;
|
|
|
|
|
|
|
|
// Radius of rain effect
|
|
|
|
float mRainDiameter;
|
|
|
|
|
|
|
|
// Transition threshold to spawn rain
|
|
|
|
float mRainThreshold;
|
|
|
|
|
|
|
|
// Height of rain particles spawn
|
|
|
|
float mRainMinHeight;
|
|
|
|
float mRainMaxHeight;
|
2014-06-25 16:20:21 +00:00
|
|
|
|
2014-06-24 13:00:15 +00:00
|
|
|
std::string mParticleEffect;
|
|
|
|
|
2014-06-25 16:20:21 +00:00
|
|
|
std::string mRainEffect;
|
|
|
|
|
2014-06-24 13:00:15 +00:00
|
|
|
// 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.
|
2015-08-16 04:38:49 +00:00
|
|
|
|
2015-08-27 03:59:21 +00:00
|
|
|
float transitionDelta() const;
|
2015-09-09 03:05:33 +00:00
|
|
|
float cloudBlendFactor(const float transitionRatio) const;
|
|
|
|
|
|
|
|
float calculateThunder(const float transitionRatio, const float elapsedSeconds, const bool isPaused);
|
2015-08-16 04:38:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
float mTransitionDelta;
|
|
|
|
float mCloudsMaximumPercent;
|
2015-09-09 03:05:33 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
// non-zero values.
|
|
|
|
float mThunderFrequency;
|
|
|
|
float mThunderThreshold;
|
|
|
|
std::string mThunderSoundID[4];
|
|
|
|
float mFlashDecrement;
|
|
|
|
|
|
|
|
float mFlashBrightness;
|
|
|
|
|
|
|
|
void flashDecrement(const float elapsedSeconds);
|
|
|
|
float thunderChance(const float transitionRatio, const float elapsedSeconds) const;
|
|
|
|
void lightningAndThunder(void);
|
2012-02-21 19:22:46 +00:00
|
|
|
};
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2015-08-27 03:59:21 +00:00
|
|
|
/// A class for storing a region's weather.
|
|
|
|
class RegionWeather
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit RegionWeather(const ESM::Region& region);
|
|
|
|
explicit RegionWeather(const ESM::RegionWeatherState& state);
|
|
|
|
|
2015-08-27 04:34:15 +00:00
|
|
|
operator ESM::RegionWeatherState() const;
|
2015-08-27 03:59:21 +00:00
|
|
|
|
|
|
|
void setChances(const std::vector<char>& chances);
|
|
|
|
|
|
|
|
void setWeather(int weatherID);
|
|
|
|
|
|
|
|
int getWeather();
|
|
|
|
|
|
|
|
private:
|
|
|
|
int mWeather;
|
|
|
|
std::vector<char> mChances;
|
|
|
|
|
|
|
|
void chooseNewWeather();
|
|
|
|
};
|
|
|
|
|
|
|
|
/// A class that acts as a model for the moons.
|
2015-07-30 04:57:45 +00:00
|
|
|
class MoonModel
|
|
|
|
{
|
|
|
|
public:
|
2019-01-22 06:08:48 +00:00
|
|
|
MoonModel(const std::string& name);
|
2015-07-30 04:57:45 +00:00
|
|
|
|
2015-08-27 03:59:21 +00:00
|
|
|
MWRender::MoonState calculateState(const TimeStamp& gameTime) const;
|
2015-07-30 04:57:45 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
float mFadeInStart;
|
|
|
|
float mFadeInFinish;
|
|
|
|
float mFadeOutStart;
|
|
|
|
float mFadeOutFinish;
|
|
|
|
float mAxisOffset;
|
|
|
|
float mSpeed;
|
|
|
|
float mDailyIncrement;
|
|
|
|
float mFadeStartAngle;
|
|
|
|
float mFadeEndAngle;
|
|
|
|
float mMoonShadowEarlyFadeAngle;
|
|
|
|
|
2015-08-27 03:59:21 +00:00
|
|
|
float angle(const TimeStamp& gameTime) const;
|
2015-07-30 19:00:08 +00:00
|
|
|
float moonRiseHour(unsigned int daysPassed) const;
|
|
|
|
float rotation(float hours) const;
|
2020-10-26 21:16:31 +00:00
|
|
|
MWRender::MoonState::Phase phase(const TimeStamp& gameTime) const;
|
2015-07-30 19:00:08 +00:00
|
|
|
float shadowBlend(float angle) const;
|
|
|
|
float hourlyAlpha(float gameHour) const;
|
|
|
|
float earlyMoonShadowAlpha(float angle) const;
|
2015-07-30 04:57:45 +00:00
|
|
|
};
|
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
/// Interface for weather settings
|
|
|
|
class WeatherManager
|
|
|
|
{
|
|
|
|
public:
|
2015-07-10 00:34:00 +00:00
|
|
|
// Have to pass fallback and Store, can't use singleton since World isn't fully constructed yet at the time
|
2019-01-22 06:08:48 +00:00
|
|
|
WeatherManager(MWRender::RenderingManager& rendering, MWWorld::ESMStore& store);
|
2013-08-29 13:15:40 +00:00
|
|
|
~WeatherManager();
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
/**
|
2012-02-26 10:51:02 +00:00
|
|
|
* Change the weather in the specified region
|
|
|
|
* @param region that should be changed
|
|
|
|
* @param ID of the weather setting to shift to
|
2012-02-21 19:22:46 +00:00
|
|
|
*/
|
2015-08-27 03:59:21 +00:00
|
|
|
void changeWeather(const std::string& regionID, const unsigned int weatherID);
|
|
|
|
void modRegion(const std::string& regionID, const std::vector<char>& chances);
|
2018-03-19 19:08:15 +00:00
|
|
|
void playerTeleported(const std::string& playerRegion, bool isExterior);
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
/**
|
|
|
|
* Per-frame update
|
|
|
|
* @param duration
|
2014-10-10 10:29:51 +00:00
|
|
|
* @param paused
|
2012-02-21 19:22:46 +00:00
|
|
|
*/
|
2018-03-19 19:08:15 +00:00
|
|
|
void update(float duration, bool paused, const TimeStamp& time, bool isExterior);
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2014-12-01 19:31:33 +00:00
|
|
|
void stopSounds();
|
2013-06-19 14:18:43 +00:00
|
|
|
|
2013-05-01 09:42:24 +00:00
|
|
|
float getWindSpeed() const;
|
2019-01-27 12:55:36 +00:00
|
|
|
NightDayMode getNightDayMode() const;
|
2013-05-01 09:42:24 +00:00
|
|
|
|
2014-06-24 16:37:38 +00:00
|
|
|
/// Are we in an ash or blight storm?
|
|
|
|
bool isInStorm() const;
|
|
|
|
|
2015-05-12 01:02:15 +00:00
|
|
|
osg::Vec3f getStormDirection() const;
|
2014-06-24 16:37:38 +00:00
|
|
|
|
2015-08-27 19:20:45 +00:00
|
|
|
void advanceTime(double hours, bool incremental);
|
2012-09-25 19:28:25 +00:00
|
|
|
|
2012-02-25 20:34:38 +00:00
|
|
|
unsigned int getWeatherID() const;
|
2012-04-23 13:27:03 +00:00
|
|
|
|
2018-03-19 19:08:15 +00:00
|
|
|
bool useTorches(float hour) const;
|
2013-12-10 22:48:49 +00:00
|
|
|
|
2014-04-28 09:29:57 +00:00
|
|
|
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
2014-03-20 06:25:52 +00:00
|
|
|
|
2015-01-22 18:04:59 +00:00
|
|
|
bool readRecord(ESM::ESMReader& reader, uint32_t type);
|
2014-03-20 06:25:52 +00:00
|
|
|
|
2015-01-24 15:26:43 +00:00
|
|
|
void clear();
|
|
|
|
|
2012-02-21 19:22:46 +00:00
|
|
|
private:
|
2015-08-27 03:59:21 +00:00
|
|
|
MWWorld::ESMStore& mStore;
|
|
|
|
MWRender::RenderingManager& mRendering;
|
2013-03-09 23:24:14 +00:00
|
|
|
float mSunriseTime;
|
|
|
|
float mSunsetTime;
|
|
|
|
float mSunriseDuration;
|
|
|
|
float mSunsetDuration;
|
2015-09-21 17:43:48 +00:00
|
|
|
float mSunPreSunsetTime;
|
2015-11-01 21:47:40 +00:00
|
|
|
|
|
|
|
TimeOfDaySettings mTimeSettings;
|
|
|
|
|
|
|
|
// fading of night skydome
|
|
|
|
TimeOfDayInterpolator<float> mNightFade;
|
|
|
|
|
2015-08-27 03:59:21 +00:00
|
|
|
float mHoursBetweenWeatherChanges;
|
|
|
|
float mRainSpeed;
|
2015-11-01 21:09:02 +00:00
|
|
|
|
|
|
|
// underwater fog not really related to weather, but we handle it here because it's convenient
|
2015-11-01 21:47:40 +00:00
|
|
|
TimeOfDayInterpolator<float> mUnderwaterFog;
|
2015-11-01 21:09:02 +00:00
|
|
|
|
2015-08-27 03:59:21 +00:00
|
|
|
std::vector<Weather> mWeatherSettings;
|
|
|
|
MoonModel mMasser;
|
|
|
|
MoonModel mSecunda;
|
|
|
|
|
|
|
|
float mWindSpeed;
|
2019-09-23 18:22:50 +00:00
|
|
|
float mCurrentWindSpeed;
|
|
|
|
float mNextWindSpeed;
|
2015-08-27 03:59:21 +00:00
|
|
|
bool mIsStorm;
|
2018-03-03 13:18:40 +00:00
|
|
|
bool mPrecipitation;
|
2015-08-27 03:59:21 +00:00
|
|
|
osg::Vec3f mStormDirection;
|
|
|
|
|
|
|
|
std::string mCurrentRegion;
|
|
|
|
float mTimePassed;
|
|
|
|
bool mFastForward;
|
|
|
|
float mWeatherUpdateTime;
|
|
|
|
float mTransitionFactor;
|
2019-01-27 12:55:36 +00:00
|
|
|
NightDayMode mNightDayMode;
|
2015-08-27 03:59:21 +00:00
|
|
|
int mCurrentWeather;
|
|
|
|
int mNextWeather;
|
|
|
|
int mQueuedWeather;
|
|
|
|
std::map<std::string, RegionWeather> mRegions;
|
|
|
|
MWRender::WeatherResult mResult;
|
|
|
|
|
2017-09-12 04:33:18 +00:00
|
|
|
MWBase::Sound *mAmbientSound;
|
2015-08-27 03:59:21 +00:00
|
|
|
std::string mPlayingSoundID;
|
2015-08-16 04:38:49 +00:00
|
|
|
|
|
|
|
void addWeather(const std::string& name,
|
2017-09-21 10:08:45 +00:00
|
|
|
float dlFactor, float dlOffset,
|
2015-08-16 04:38:49 +00:00
|
|
|
const std::string& particleEffect = "");
|
|
|
|
|
2015-08-27 03:59:21 +00:00
|
|
|
void importRegions();
|
|
|
|
|
|
|
|
void regionalWeatherChanged(const std::string& regionID, RegionWeather& region);
|
|
|
|
bool updateWeatherTime();
|
|
|
|
bool updateWeatherRegion(const std::string& playerRegion);
|
|
|
|
void updateWeatherTransitions(const float elapsedRealSeconds);
|
|
|
|
void forceWeather(const int weatherID);
|
|
|
|
|
|
|
|
bool inTransition();
|
|
|
|
void addWeatherTransition(const int weatherID);
|
|
|
|
|
2015-09-09 03:05:33 +00:00
|
|
|
void calculateWeatherResult(const float gameHour, const float elapsedSeconds, const bool isPaused);
|
2015-08-27 03:59:21 +00:00
|
|
|
void calculateResult(const int weatherID, const float gameHour);
|
|
|
|
void calculateTransitionResult(const float factor, const float gameHour);
|
2019-09-23 18:22:50 +00:00
|
|
|
float calculateWindSpeed(int weatherId, float currentSpeed);
|
2012-02-21 19:22:46 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // GAME_MWWORLD_WEATHER_H
|