1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 19:49:41 +00:00

Feature #1173: Saved Game: include weather state

Removed some unused state in and changed Ogre::String to std::string in
WeatherManager.
This commit is contained in:
slothlife 2014-03-20 01:25:52 -05:00
parent 8b36de6c67
commit 1acd1bd913
5 changed files with 93 additions and 27 deletions

View file

@ -266,6 +266,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
case ESM::REC_GLOB: case ESM::REC_GLOB:
case ESM::REC_PLAY: case ESM::REC_PLAY:
case ESM::REC_CSTA: case ESM::REC_CSTA:
case ESM::REC_WTHR:
MWBase::Environment::get().getWorld()->readRecord (reader, n.val, contentFileMap); MWBase::Environment::get().getWorld()->readRecord (reader, n.val, contentFileMap);
break; break;

View file

@ -1,5 +1,8 @@
#include "weather.hpp" #include "weather.hpp"
#include <components/esm/esmreader.hpp>
#include <components/esm/esmwriter.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
@ -15,6 +18,15 @@ using namespace Ogre;
using namespace MWWorld; using namespace MWWorld;
using namespace MWSound; using namespace MWSound;
#define HOUR "HOUR"
#define WINDSPEED "WNSP"
#define CURRENTWEATHER "CWTH"
#define NEXTWEATHER "NWTH"
#define CURRENTREGION "CREG"
#define FIRSTUPDATE "FUPD"
#define REMAININGTRANSITIONTIME "RTTM"
#define TIMEPASSED "TMPS"
namespace namespace
{ {
float lerp (float x, float y, float factor) float lerp (float x, float y, float factor)
@ -91,8 +103,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa
mHour(14), mCurrentWeather("clear"), mNextWeather(""), mFirstUpdate(true), mHour(14), mCurrentWeather("clear"), mNextWeather(""), mFirstUpdate(true),
mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0),
mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0),
mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering)
mRendering(rendering)
{ {
//Globals //Globals
mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0"); mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0");
@ -530,7 +541,7 @@ void WeatherManager::stopSounds(bool stopAll)
} }
} }
Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const std::string WeatherManager::nextWeather(const ESM::Region* region) const
{ {
std::vector<char> probability; std::vector<char> probability;
@ -599,12 +610,6 @@ void WeatherManager::setHour(const float hour)
mHour = hour; mHour = hour;
} }
void WeatherManager::setDate(const int day, const int month)
{
mDay = day;
mMonth = month;
}
unsigned int WeatherManager::getWeatherID() const unsigned int WeatherManager::getWeatherID() const
{ {
// Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather
@ -691,6 +696,60 @@ bool WeatherManager::isDark() const
return exterior && (mHour < mSunriseTime || mHour > mNightStart - 1); return exterior && (mHour < mSunriseTime || mHour > mNightStart - 1);
} }
void WeatherManager::write(ESM::ESMWriter& writer)
{
writer.startRecord(ESM::REC_WTHR);
writer.writeHNT(HOUR, mHour);
writer.writeHNT(WINDSPEED, mWindSpeed);
writer.writeHNCString(CURRENTWEATHER, mCurrentWeather.c_str());
writer.writeHNCString(NEXTWEATHER, mNextWeather.c_str());
writer.writeHNCString(CURRENTREGION, mCurrentRegion.c_str());
writer.writeHNT(FIRSTUPDATE, mFirstUpdate);
writer.writeHNT(REMAININGTRANSITIONTIME, mRemainingTransitionTime);
writer.writeHNT(TIMEPASSED, mTimePassed);
writer.endRecord(ESM::REC_WTHR);
}
bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type)
{
if(ESM::REC_WTHR == type)
{
// store state in locals so that if we fail to load, we don't leave the manager in a half-way state
float newHour = 0.0;
reader.getHNT(newHour, HOUR);
float newWindSpeed = 0.0;
reader.getHNT(newWindSpeed, WINDSPEED);
std::string newCurrentWeather = reader.getHNString(CURRENTWEATHER);
std::string newNextWeather = reader.getHNString(NEXTWEATHER);
std::string newCurrentRegion = reader.getHNString(CURRENTREGION);
bool newFirstUpdate = false;
reader.getHNT(newFirstUpdate, FIRSTUPDATE);
float newRemainingTransitionTime = 0.0;
reader.getHNT(newRemainingTransitionTime, REMAININGTRANSITIONTIME);
double newTimePassed = 0.0;
reader.getHNT(newTimePassed, TIMEPASSED);
// reset other temporary state
mRegionOverrides.clear();
stopSounds(true); // TODO: inconsistent state if this throws...
mRegionMods.clear();
// swap in new values, now that we can't fail
mHour = newHour;
mWindSpeed = newWindSpeed;
mCurrentWeather.swap(newCurrentWeather);
mNextWeather.swap(newNextWeather);
mCurrentRegion.swap(newCurrentRegion);
mFirstUpdate = newFirstUpdate;
mRemainingTransitionTime = newRemainingTransitionTime;
mTimePassed = newTimePassed;
return true;
}
return false;
}
void WeatherManager::switchToNextWeather(bool instantly) void WeatherManager::switchToNextWeather(bool instantly)
{ {
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* world = MWBase::Environment::get().getWorld();

View file

@ -1,12 +1,16 @@
#ifndef GAME_MWWORLD_WEATHER_H #ifndef GAME_MWWORLD_WEATHER_H
#define GAME_MWWORLD_WEATHER_H #define GAME_MWWORLD_WEATHER_H
#include <OgreString.h> #include <cstdint>
#include <string>
#include <OgreColourValue.h> #include <OgreColourValue.h>
namespace ESM namespace ESM
{ {
struct Region; struct Region;
class ESMWriter;
class ESMReader;
} }
namespace MWRender namespace MWRender
@ -21,8 +25,8 @@ namespace MWWorld
/// Defines the actual weather that results from weather setting (see below), time of day and weather transition /// Defines the actual weather that results from weather setting (see below), time of day and weather transition
struct WeatherResult struct WeatherResult
{ {
Ogre::String mCloudTexture; std::string mCloudTexture;
Ogre::String mNextCloudTexture; std::string mNextCloudTexture;
float mCloudBlendFactor; float mCloudBlendFactor;
Ogre::ColourValue mFogColor; Ogre::ColourValue mFogColor;
@ -48,14 +52,14 @@ namespace MWWorld
bool mNight; // use night skybox bool mNight; // use night skybox
float mNightFade; // fading factor for night skybox float mNightFade; // fading factor for night skybox
Ogre::String mAmbientLoopSoundID; std::string mAmbientLoopSoundID;
}; };
/// Defines a single weather setting (according to INI) /// Defines a single weather setting (according to INI)
struct Weather struct Weather
{ {
Ogre::String mCloudTexture; std::string mCloudTexture;
// Sky (atmosphere) colors // Sky (atmosphere) colors
Ogre::ColourValue mSkySunriseColor, Ogre::ColourValue mSkySunriseColor,
@ -105,10 +109,10 @@ namespace MWWorld
// Sound effect // Sound effect
// This is used for Blight, Ashstorm and Blizzard (Bloodmoon) // This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
Ogre::String mAmbientLoopSoundID; std::string mAmbientLoopSoundID;
// Rain sound effect // Rain sound effect
Ogre::String mRainLoopSoundID; std::string mRainLoopSoundID;
/// \todo disease chance /// \todo disease chance
}; };
@ -142,8 +146,6 @@ namespace MWWorld
float getWindSpeed() const; float getWindSpeed() const;
void setDate(const int day, const int month);
void advanceTime(double hours) void advanceTime(double hours)
{ {
mTimePassed += hours*3600; mTimePassed += hours*3600;
@ -156,22 +158,25 @@ namespace MWWorld
/// @see World::isDark /// @see World::isDark
bool isDark() const; bool isDark() const;
void write(ESM::ESMWriter& writer);
bool readRecord(ESM::ESMReader& reader, int32_t type);
private: private:
float mHour; float mHour;
int mDay, mMonth;
float mWindSpeed; float mWindSpeed;
MWWorld::Fallback* mFallback; MWWorld::Fallback* mFallback;
void setFallbackWeather(Weather& weather,const std::string& name); void setFallbackWeather(Weather& weather,const std::string& name);
MWRender::RenderingManager* mRendering; MWRender::RenderingManager* mRendering;
std::map<Ogre::String, Weather> mWeatherSettings; std::map<std::string, Weather> mWeatherSettings;
std::map<std::string, std::string> mRegionOverrides; std::map<std::string, std::string> mRegionOverrides;
std::vector<std::string> mSoundsPlaying; std::vector<std::string> mSoundsPlaying;
Ogre::String mCurrentWeather; std::string mCurrentWeather;
Ogre::String mNextWeather; std::string mNextWeather;
std::string mCurrentRegion; std::string mCurrentRegion;
@ -186,13 +191,13 @@ namespace MWWorld
double mTimePassed; // time passed since last update double mTimePassed; // time passed since last update
void transition(const float factor); void transition(const float factor);
void setResult(const Ogre::String& weatherType); void setResult(const std::string& weatherType);
float calculateHourFade (const std::string& moonName) const; float calculateHourFade (const std::string& moonName) const;
float calculateAngleFade (const std::string& moonName, float angle) const; float calculateAngleFade (const std::string& moonName, float angle) const;
void setWeather(const Ogre::String& weatherType, bool instant=false); void setWeather(const std::string& weatherType, bool instant=false);
Ogre::String nextWeather(const ESM::Region* region) const; std::string nextWeather(const ESM::Region* region) const;
WeatherResult mResult; WeatherResult mResult;
typedef std::map<std::string,std::vector<char> > RegionModMap; typedef std::map<std::string,std::vector<char> > RegionModMap;

View file

@ -279,6 +279,7 @@ namespace MWWorld
mGlobalVariables.write (writer); mGlobalVariables.write (writer);
mCells.write (writer); mCells.write (writer);
mPlayer->write (writer); mPlayer->write (writer);
mWeatherManager->write (writer);
} }
void World::readRecord (ESM::ESMReader& reader, int32_t type, void World::readRecord (ESM::ESMReader& reader, int32_t type,
@ -287,6 +288,7 @@ namespace MWWorld
if (!mStore.readRecord (reader, type) && if (!mStore.readRecord (reader, type) &&
!mGlobalVariables.readRecord (reader, type) && !mGlobalVariables.readRecord (reader, type) &&
!mPlayer->readRecord (reader, type) && !mPlayer->readRecord (reader, type) &&
!mWeatherManager->readRecord (reader, type) &&
!mCells.readRecord (reader, type, contentFileMap)) !mCells.readRecord (reader, type, contentFileMap))
{ {
throw std::runtime_error ("unknown record in saved game"); throw std::runtime_error ("unknown record in saved game");
@ -680,8 +682,6 @@ namespace MWWorld
mGlobalVariables["month"].setInteger (month); mGlobalVariables["month"].setInteger (month);
mRendering->skySetDate (day, month); mRendering->skySetDate (day, month);
mWeatherManager->setDate (day, month);
} }
void World::setMonth (int month) void World::setMonth (int month)

View file

@ -92,6 +92,7 @@ enum RecNameInts
REC_CSTA = 0x41545343, REC_CSTA = 0x41545343,
REC_GMAP = 0x50414d47, REC_GMAP = 0x50414d47,
REC_DIAS = 0x53414944, REC_DIAS = 0x53414944,
REC_WTHR = 0x52485457,
// format 1 // format 1
REC_FILT = 0x544C4946 REC_FILT = 0x544C4946