@ -7,6 +7,19 @@
# include <components/esm/savedgame.hpp>
# include <components/esm/savedgame.hpp>
# include <components/esm/weatherstate.hpp>
# include <components/esm/weatherstate.hpp>
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
# include <components/openmw-mp/Log.hpp>
# include "../mwmp/Main.hpp"
# include "../mwmp/Networking.hpp"
# include "../mwmp/Worldstate.hpp"
/*
End of tes3mp addition
*/
# include "../mwbase/environment.hpp"
# include "../mwbase/environment.hpp"
# include "../mwbase/soundmanager.hpp"
# include "../mwbase/soundmanager.hpp"
@ -657,12 +670,72 @@ void WeatherManager::playerTeleported(const std::string& playerRegion, bool isEx
std : : map < std : : string , RegionWeather > : : iterator it = mRegions . find ( playerRegion ) ;
std : : map < std : : string , RegionWeather > : : iterator it = mRegions . find ( playerRegion ) ;
if ( it ! = mRegions . end ( ) & & playerRegion ! = mCurrentRegion )
if ( it ! = mRegions . end ( ) & & playerRegion ! = mCurrentRegion )
{
{
/*
Start of tes3mp addition
If we ' ve moved to another region , set our weather creation ability to false ;
the server will set it to true if it wants us creating weather here
*/
setWeatherCreationState ( false ) ;
/*
End of tes3mp addition
*/
mCurrentRegion = playerRegion ;
mCurrentRegion = playerRegion ;
forceWeather ( it - > second . getWeather ( ) ) ;
forceWeather ( it - > second . getWeather ( ) ) ;
}
}
}
}
}
}
/*
Start of tes3mp addition
Make it possible to set a specific weather state for a region from elsewhere
in the code
*/
void WeatherManager : : setRegionWeather ( const std : : string & region , const unsigned int currentWeather , const unsigned int nextWeather ,
const unsigned int queuedWeather , const float transitionFactor , bool force )
{
bool isSameRegion = Misc : : StringUtils : : ciEqual ( region , mCurrentRegion ) ;
// Only ever force weather if we are in the correct region for it
if ( isSameRegion )
{
if ( force )
{
mCurrentWeather = currentWeather ;
mNextWeather = nextWeather ;
mQueuedWeather = queuedWeather ;
mTransitionFactor = transitionFactor ;
}
else
{
// Keep the queued weather in sync if everything else already is
if ( mCurrentWeather = = currentWeather & & mNextWeather = = nextWeather )
{
mQueuedWeather = queuedWeather ;
}
// Start moving towards the next weather immediately if it's different from the one we have
else if ( mNextWeather ! = nextWeather & & nextWeather ! = - 1 )
{
changeWeather ( region , nextWeather ) ;
}
// Otherwise, if the current weather is different from the one we should have, move towards it
else if ( mCurrentWeather ! = currentWeather )
{
changeWeather ( region , currentWeather ) ;
}
}
}
else
{
changeWeather ( region , currentWeather ) ;
}
}
/*
End of tes3mp addition
*/
void WeatherManager : : update ( float duration , bool paused , const TimeStamp & time , bool isExterior )
void WeatherManager : : update ( float duration , bool paused , const TimeStamp & time , bool isExterior )
{
{
MWWorld : : ConstPtr player = MWMechanics : : getPlayer ( ) ;
MWWorld : : ConstPtr player = MWMechanics : : getPlayer ( ) ;
@ -906,6 +979,50 @@ void WeatherManager::clear()
importRegions ( ) ;
importRegions ( ) ;
}
}
/*
Start of tes3mp addition
Make it possible to check whether the local WeatherManager has the
ability to create weather changes
*/
bool WeatherManager : : getWeatherCreationState ( )
{
return mWeatherCreationState ;
}
/*
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to enable and disable the local WeatherManager ' s ability
to create weather changes
*/
void WeatherManager : : setWeatherCreationState ( bool state )
{
mWeatherCreationState = state ;
}
/*
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to send the current weather in a WorldWeather packet
when requested from elsewhere in the code
*/
void WeatherManager : : sendWeather ( )
{
mwmp : : Worldstate * worldstate = mwmp : : Main : : get ( ) . getNetworking ( ) - > getWorldstate ( ) ;
worldstate - > sendWeather ( mCurrentRegion , mCurrentWeather , mNextWeather , mQueuedWeather , mTransitionFactor ) ;
}
/*
End of tes3mp addition
*/
inline void WeatherManager : : addWeather ( const std : : string & name ,
inline void WeatherManager : : addWeather ( const std : : string & name ,
const Fallback : : Map & fallback ,
const Fallback : : Map & fallback ,
float dlFactor , float dlOffset ,
float dlFactor , float dlOffset ,
@ -943,7 +1060,19 @@ inline void WeatherManager::regionalWeatherChanged(const std::string& regionID,
inline bool WeatherManager : : updateWeatherTime ( )
inline bool WeatherManager : : updateWeatherTime ( )
{
{
/*
Start of tes3mp change ( major )
Avoid creating any weather changes on this client unless approved by the server
*/
if ( ! mWeatherCreationState )
return false ;
/*
End of tes3mp change ( major )
*/
mWeatherUpdateTime - = mTimePassed ;
mWeatherUpdateTime - = mTimePassed ;
mTimePassed = 0.0f ;
mTimePassed = 0.0f ;
if ( mWeatherUpdateTime < = 0.0f )
if ( mWeatherUpdateTime < = 0.0f )
{
{
@ -968,6 +1097,17 @@ inline bool WeatherManager::updateWeatherRegion(const std::string& playerRegion)
{
{
mCurrentRegion = playerRegion ;
mCurrentRegion = playerRegion ;
/*
Start of tes3mp addition
If we ' ve moved to another region , set our weather creation ability to false ;
the server will set it to true if it wants us creating weather here
*/
setWeatherCreationState ( false ) ;
/*
End of tes3mp addition
*/
return true ;
return true ;
}
}
@ -976,6 +1116,16 @@ inline bool WeatherManager::updateWeatherRegion(const std::string& playerRegion)
inline void WeatherManager : : updateWeatherTransitions ( const float elapsedRealSeconds )
inline void WeatherManager : : updateWeatherTransitions ( const float elapsedRealSeconds )
{
{
/*
Start of tes3mp addition
Track whether an ID_WORLD_WEATHER packet should be sent or not
*/
bool shouldSendPacket = false ;
/*
End of tes3mp addition
*/
// When a player chooses to train, wait, or serves jail time, any transitions will be fast forwarded to the last
// When a player chooses to train, wait, or serves jail time, any transitions will be fast forwarded to the last
// weather type set, regardless of the remaining transition time.
// weather type set, regardless of the remaining transition time.
if ( ! mFastForward & & inTransition ( ) )
if ( ! mFastForward & & inTransition ( ) )
@ -999,10 +1149,31 @@ inline void WeatherManager::updateWeatherTransitions(const float elapsedRealSeco
{
{
mTransitionFactor = 0.0f ;
mTransitionFactor = 0.0f ;
}
}
/*
Start of tes3mp addition
The weather is changing , so decide to send an ID_WORLD_WEATHER packet
*/
shouldSendPacket = true ;
/*
End of tes3mp addition
*/
}
}
}
}
else
else
{
{
/*
Start of tes3mp addition
If the weather is changing , decide to send an ID_WORLD_WEATHER packet
*/
if ( mQueuedWeather ! = invalidWeatherID | | mNextWeather ! = invalidWeatherID )
shouldSendPacket = true ;
/*
End of tes3mp addition
*/
if ( mQueuedWeather ! = invalidWeatherID )
if ( mQueuedWeather ! = invalidWeatherID )
{
{
mCurrentWeather = mQueuedWeather ;
mCurrentWeather = mQueuedWeather ;
@ -1016,6 +1187,20 @@ inline void WeatherManager::updateWeatherTransitions(const float elapsedRealSeco
mQueuedWeather = invalidWeatherID ;
mQueuedWeather = invalidWeatherID ;
mFastForward = false ;
mFastForward = false ;
}
}
/*
Start of tes3mp addition
Send an ID_WORLD_WEATHER packet every time the weather changes here , but only
if we are allowed to create weather changes on this client
*/
if ( shouldSendPacket & & mWeatherCreationState & & ! mCurrentRegion . empty ( ) )
{
sendWeather ( ) ;
}
/*
End of tes3mp addition
*/
}
}
inline void WeatherManager : : forceWeather ( const int weatherID )
inline void WeatherManager : : forceWeather ( const int weatherID )
@ -1024,6 +1209,20 @@ inline void WeatherManager::forceWeather(const int weatherID)
mCurrentWeather = weatherID ;
mCurrentWeather = weatherID ;
mNextWeather = invalidWeatherID ;
mNextWeather = invalidWeatherID ;
mQueuedWeather = invalidWeatherID ;
mQueuedWeather = invalidWeatherID ;
/*
Start of tes3mp addition
Send an ID_WORLD_WEATHER packet every time the weather changes here , but only
if we are allowed to create weather changes on this client
*/
if ( ! mCurrentRegion . empty ( ) & & mWeatherCreationState )
{
sendWeather ( ) ;
}
/*
End of tes3mp addition
*/
}
}
inline bool WeatherManager : : inTransition ( )
inline bool WeatherManager : : inTransition ( )
@ -1047,6 +1246,20 @@ inline void WeatherManager::addWeatherTransition(const int weatherID)
{
{
mQueuedWeather = weatherID ;
mQueuedWeather = weatherID ;
}
}
/*
Start of tes3mp addition
Send an ID_WORLD_WEATHER packet every time the weather changes here , but only
if we are allowed to create weather changes on this client
*/
if ( mWeatherCreationState )
{
sendWeather ( ) ;
}
/*
End of tes3mp addition
*/
}
}
inline void WeatherManager : : calculateWeatherResult ( const float gameHour ,
inline void WeatherManager : : calculateWeatherResult ( const float gameHour ,