From 6eab9c5179725ae234a504ba10c67ab35de9ed48 Mon Sep 17 00:00:00 2001 From: slothlife Date: Fri, 21 Mar 2014 01:19:40 -0500 Subject: [PATCH] Move weather state save/load to a new class --- apps/openmw/mwworld/weather.cpp | 77 +++++++++++++-------------------- components/CMakeLists.txt | 2 +- components/esm/weatherstate.cpp | 59 +++++++++++++++++++++++++ components/esm/weatherstate.hpp | 27 ++++++++++++ 4 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 components/esm/weatherstate.cpp create mode 100644 components/esm/weatherstate.hpp diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index b74ca6393..335702c66 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -1,7 +1,6 @@ #include "weather.hpp" -#include -#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -18,15 +17,6 @@ using namespace Ogre; using namespace MWWorld; 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 { float lerp (float x, float y, float factor) @@ -698,15 +688,18 @@ bool WeatherManager::isDark() const void WeatherManager::write(ESM::ESMWriter& writer) { + ESM::WeatherState state; + state.mHour = mHour; + state.mWindSpeed = mWindSpeed; + state.mCurrentWeather = mCurrentWeather; + state.mNextWeather = mNextWeather; + state.mCurrentRegion = mCurrentRegion; + state.mFirstUpdate = mFirstUpdate; + state.mRemainingTransitionTime = mRemainingTransitionTime; + state.mTimePassed = mTimePassed; + 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); + state.save(writer); writer.endRecord(ESM::REC_WTHR); } @@ -714,35 +707,27 @@ 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 + // load first so that if it fails, we haven't accidentally reset the state below + ESM::WeatherState state; + state.load(reader); + + // reset other temporary state, now that we loaded successfully + stopSounds(true); // let's hope this never throws 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; + mThunderFlash = 0.0; + mThunderChance = 0.0; + mThunderChanceNeeded = 50.0; + + // swap in the loaded values now that we can't fail + mHour = state.mHour; + mWindSpeed = state.mWindSpeed; + mCurrentWeather.swap(state.mCurrentWeather); + mNextWeather.swap(state.mNextWeather); + mCurrentRegion.swap(state.mCurrentRegion); + mFirstUpdate = state.mFirstUpdate; + mRemainingTransitionTime = state.mRemainingTransitionTime; + mTimePassed = state.mTimePassed; return true; } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index db4ecad0b..c4d13170d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -45,7 +45,7 @@ add_component_dir (esm loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate - npcstats creaturestats + npcstats creaturestats weatherstate ) add_component_dir (misc diff --git a/components/esm/weatherstate.cpp b/components/esm/weatherstate.cpp new file mode 100644 index 000000000..48cf55a60 --- /dev/null +++ b/components/esm/weatherstate.cpp @@ -0,0 +1,59 @@ +#include "weatherstate.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" + +namespace +{ + const char* hourRecord = "HOUR"; + const char* windSpeedRecord = "WNSP"; + const char* currentWeatherRecord = "CWTH"; + const char* nextWeatherRecord = "NWTH"; + const char* currentRegionRecord = "CREG"; + const char* firstUpdateRecord = "FUPD"; + const char* remainingTransitionTimeRecord = "RTTM"; + const char* timePassedRecord = "TMPS"; +} + +namespace ESM +{ + void WeatherState::load(ESMReader& esm) + { + // store values locally so that a failed load can't leave the state half set + float newHour = 0.0; + esm.getHNT(newHour, hourRecord); + float newWindSpeed = 0.0; + esm.getHNT(newWindSpeed, windSpeedRecord); + std::string newCurrentWeather = esm.getHNString(currentWeatherRecord); + std::string newNextWeather = esm.getHNString(nextWeatherRecord); + std::string newCurrentRegion = esm.getHNString(currentRegionRecord); + bool newFirstUpdate = false; + esm.getHNT(newFirstUpdate, firstUpdateRecord); + float newRemainingTransitionTime = 0.0; + esm.getHNT(newRemainingTransitionTime, remainingTransitionTimeRecord); + double newTimePassed = 0.0; + esm.getHNT(newTimePassed, timePassedRecord); + + // swap values now that it is safe to do so + mHour = newHour; + mWindSpeed = newWindSpeed; + mCurrentWeather.swap(newCurrentWeather); + mNextWeather.swap(newNextWeather); + mCurrentRegion.swap(newCurrentRegion); + mFirstUpdate = newFirstUpdate; + mRemainingTransitionTime = newRemainingTransitionTime; + mTimePassed = newTimePassed; + } + + void WeatherState::save(ESMWriter& esm) const + { + esm.writeHNT(hourRecord, mHour); + esm.writeHNT(windSpeedRecord, mWindSpeed); + esm.writeHNCString(currentWeatherRecord, mCurrentWeather.c_str()); + esm.writeHNCString(nextWeatherRecord, mNextWeather.c_str()); + esm.writeHNCString(currentRegionRecord, mCurrentRegion.c_str()); + esm.writeHNT(firstUpdateRecord, mFirstUpdate); + esm.writeHNT(remainingTransitionTimeRecord, mRemainingTransitionTime); + esm.writeHNT(timePassedRecord, mTimePassed); + } +} diff --git a/components/esm/weatherstate.hpp b/components/esm/weatherstate.hpp new file mode 100644 index 000000000..545751225 --- /dev/null +++ b/components/esm/weatherstate.hpp @@ -0,0 +1,27 @@ +#ifndef OPENMW_ESM_WEATHER_H +#define OPENMW_ESM_WEATHER_H + +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + struct WeatherState + { + float mHour; + float mWindSpeed; + std::string mCurrentWeather; + std::string mNextWeather; + std::string mCurrentRegion; + bool mFirstUpdate; + float mRemainingTransitionTime; + double mTimePassed; + + void load(ESMReader& esm); + void save(ESMWriter& esm) const; + }; +} + +#endif