Merge remote-tracking branch 'slothlife/weather_save'

actorid
Marc Zinnschlag 11 years ago
commit 1b6b4e3442

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

@ -1,5 +1,7 @@
#include "weather.hpp"
#include <components/esm/weatherstate.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
@ -91,8 +93,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa
mHour(14), mCurrentWeather("clear"), mNextWeather(""), mFirstUpdate(true),
mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0),
mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0),
mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f),
mRendering(rendering)
mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering)
{
//Globals
mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0");
@ -530,7 +531,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;
@ -599,12 +600,6 @@ void WeatherManager::setHour(const float hour)
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
@ -691,6 +686,55 @@ bool WeatherManager::isDark() const
return exterior && (mHour < mSunriseTime || mHour > mNightStart - 1);
}
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);
state.save(writer);
writer.endRecord(ESM::REC_WTHR);
}
bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type)
{
if(ESM::REC_WTHR == type)
{
// 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();
mRegionMods.clear();
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;
}
return false;
}
void WeatherManager::switchToNextWeather(bool instantly)
{
MWBase::World* world = MWBase::Environment::get().getWorld();

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

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

@ -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

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

@ -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_WEATHERSTATE_H
#define OPENMW_ESM_WEATHERSTATE_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