Move weather state save/load to a new class

actorid
slothlife 11 years ago
parent 1acd1bd913
commit 6eab9c5179

@ -1,7 +1,6 @@
#include "weather.hpp" #include "weather.hpp"
#include <components/esm/esmreader.hpp> #include <components/esm/weatherstate.hpp>
#include <components/esm/esmwriter.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -18,15 +17,6 @@ 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)
@ -698,15 +688,18 @@ bool WeatherManager::isDark() const
void WeatherManager::write(ESM::ESMWriter& writer) 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.startRecord(ESM::REC_WTHR);
writer.writeHNT(HOUR, mHour); state.save(writer);
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); writer.endRecord(ESM::REC_WTHR);
} }
@ -714,35 +707,27 @@ bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type)
{ {
if(ESM::REC_WTHR == 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 // load first so that if it fails, we haven't accidentally reset the state below
float newHour = 0.0; ESM::WeatherState state;
reader.getHNT(newHour, HOUR); state.load(reader);
float newWindSpeed = 0.0;
reader.getHNT(newWindSpeed, WINDSPEED); // reset other temporary state, now that we loaded successfully
std::string newCurrentWeather = reader.getHNString(CURRENTWEATHER); stopSounds(true); // let's hope this never throws
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(); mRegionOverrides.clear();
stopSounds(true); // TODO: inconsistent state if this throws...
mRegionMods.clear(); mRegionMods.clear();
mThunderFlash = 0.0;
// swap in new values, now that we can't fail mThunderChance = 0.0;
mHour = newHour; mThunderChanceNeeded = 50.0;
mWindSpeed = newWindSpeed;
mCurrentWeather.swap(newCurrentWeather); // swap in the loaded values now that we can't fail
mNextWeather.swap(newNextWeather); mHour = state.mHour;
mCurrentRegion.swap(newCurrentRegion); mWindSpeed = state.mWindSpeed;
mFirstUpdate = newFirstUpdate; mCurrentWeather.swap(state.mCurrentWeather);
mRemainingTransitionTime = newRemainingTransitionTime; mNextWeather.swap(state.mNextWeather);
mTimePassed = newTimePassed; mCurrentRegion.swap(state.mCurrentRegion);
mFirstUpdate = state.mFirstUpdate;
mRemainingTransitionTime = state.mRemainingTransitionTime;
mTimePassed = state.mTimePassed;
return true; return true;
} }

@ -45,7 +45,7 @@ add_component_dir (esm
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter 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 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 add_component_dir (misc

@ -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);
}
}

@ -0,0 +1,27 @@
#ifndef OPENMW_ESM_WEATHER_H
#define OPENMW_ESM_WEATHER_H
#include <string>
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
Loading…
Cancel
Save