mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 07:23:54 +00:00
Merge remote-tracking branch 'slothlife/weather_save'
This commit is contained in:
commit
1b6b4e3442
8 changed files with 165 additions and 28 deletions
|
@ -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
|
||||
|
|
59
components/esm/weatherstate.cpp
Normal file
59
components/esm/weatherstate.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
27
components/esm/weatherstate.hpp
Normal file
27
components/esm/weatherstate.hpp
Normal file
|
@ -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…
Reference in a new issue