2012-05-29 13:31:11 +00:00
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "stdpch.h"
# include "weather_everywhere.h"
# include "nel/misc/sheet_id.h"
# include "nel/georges/load_form.h"
# include "nel/georges/u_form_elm.h"
# include "zone_manager.h"
# include "egs_sheets/egs_sheets.h"
# include "game_share/time_weather_season/weather_manager.h"
# include "game_share/time_weather_season/weather_setup_sheet_base.h"
# include "game_share/time_weather_season/weather_function_params_sheet_base.h"
# include "game_share/time_weather_season/weather_predict.h"
# include "game_share/season.h"
using namespace NLMISC ;
using namespace NLGEORGES ;
using namespace std ;
/// Singleton instance
CWeatherEverywhere WeatherEverywhere ;
/// Number of possible weather setups
const uint NB_WEATHER_SETUPS = 6 ;
/// Mapping from weather setups to EWeather value
const CRyzomTime : : EWeather WeatherSetupsToValue [ NB_WEATHER_SETUPS ] =
{
CRyzomTime : : best ,
CRyzomTime : : good , CRyzomTime : : good ,
CRyzomTime : : bad , CRyzomTime : : bad ,
CRyzomTime : : worst
} ;
/*
* Initialization
*/
void CWeatherEverywhere : : init ( )
{
// Init weather manager (with weather setup sheets)
std : : vector < CSheetId > sheetVec ;
CSheetId : : buildIdVector ( sheetVec , " weather_setup " ) ; // list weather_setup sheets
std : : vector < const CWeatherSetupSheetBase * > weatherSheets ;
std : : vector < std : : string > weatherSheetNames ;
for ( uint k = 0 ; k ! = sheetVec . size ( ) ; + + k )
{
const CWeatherSetupSheetBase * sheet = CSheets : : getWeatherSetupSheet ( sheetVec [ k ] ) ; // get static sheet
if ( sheet )
{
weatherSheetNames . push_back ( sheetVec [ k ] . toString ( ) ) ;
weatherSheets . push_back ( sheet ) ;
}
}
CWeatherManager weatherManager ;
weatherManager . init ( weatherSheets , weatherSheetNames ) ;
// Load the continents (george forms). The sorted list is found in CStaticWorld.
sheetVec . clear ( ) ;
const CStaticWorld * staticWorld = CSheets : : getWorldForm ( CSheetId ( " ryzom.world " ) ) ;
nlassert ( staticWorld ) ;
nlassertex ( staticWorld - > Continents . size ( ) = = CONTINENT : : NB_CONTINENTS , ( " ryzom.world should contain exactly the same number of continents as the enum size CONTINENT::TContinent (=%u), not %u " , ( uint ) ( CONTINENT : : NB_CONTINENTS ) , staticWorld - > Continents . size ( ) ) ) ;
UFormLoader * formLoader = UFormLoader : : createLoader ( ) ;
_WeatherFunctionsBySeasonByContinent . resize ( staticWorld - > Continents . size ( ) ) ;
for ( uint iContinent = 0 ; iContinent ! = CONTINENT : : NB_CONTINENTS ; + + iContinent )
{
_WeatherFunctionsBySeasonByContinent [ iContinent ] = new CWeatherFunction [ EGSPD : : CSeason : : Invalid ] ;
CSmartPtr < UForm > continentForm = formLoader - > loadForm ( staticWorld - > Continents [ iContinent ] . toString ( ) . c_str ( ) ) ; // load continent form
if ( continentForm = = NULL )
{
nlwarning ( " Continent sheet '%s' not found " , staticWorld - > Continents [ iContinent ] . toString ( ) . c_str ( ) ) ;
}
else
{
for ( uint iSeason = 0 ; iSeason ! = EGSPD : : CSeason : : Invalid ; + + iSeason )
{
string seasonStr = EGSPD : : CSeason : : toString ( ( EGSPD : : CSeason : : TSeason ) iSeason ) ;
const UFormElm * seasonWFNode = NULL ;
if ( continentForm - > getRootNode ( ) . getNodeByName ( & seasonWFNode , ( seasonStr + string ( " WeatherFunction " ) ) . c_str ( ) ) & & seasonWFNode )
{
CWeatherFunctionSheet wfs ;
wfs . build ( * seasonWFNode ) ;
_WeatherFunctionsBySeasonByContinent [ iContinent ] [ iSeason ] . buildFromSheet ( wfs , weatherManager ) ;
}
else
{
// Not a warning because indoor continent does not have any weather function
nlinfo ( " %s has no node %s " , staticWorld - > Continents [ iContinent ] . toString ( ) . c_str ( ) , ( seasonStr + string ( " WeatherFunction " ) ) . c_str ( ) ) ;
}
}
}
}
UFormLoader : : releaseLoader ( formLoader ) ;
// Use always first weather function param sheet
if ( CSheets : : getWeatherFunctionParamsSheets ( ) . begin ( ) ! = CSheets : : getWeatherFunctionParamsSheets ( ) . end ( ) )
{
_WeatherFunctionParamsSheet = & ( * CSheets : : getWeatherFunctionParamsSheets ( ) . begin ( ) ) . second ;
}
}
/*
* Destructor
*/
CWeatherEverywhere : : ~ CWeatherEverywhere ( )
{
for ( uint i = 0 ; i ! = _WeatherFunctionsBySeasonByContinent . size ( ) ; + + i )
{
delete [ ] _WeatherFunctionsBySeasonByContinent [ i ] ;
}
}
/*
* Return the weather at the specified position & time .
* In case of failure ( such as a position outside a continent ) , return unknownWeather .
*/
CRyzomTime : : EWeather CWeatherEverywhere : : getWeather ( const NLMISC : : CVector & pos , const CRyzomTime & ryzomTime ) const
{
if ( ! _WeatherFunctionParamsSheet )
return CRyzomTime : : unknownWeather ;
// Get continent of which the position belongs
CContinent * continent = CZoneManager : : getInstance ( ) . getContinent ( pos ) ;
if ( ! continent )
return CRyzomTime : : unknownWeather ;
// Predict weather
float weatherFloatValue = CPredictWeather : : predictWeather (
ryzomTime . getRyzomDay ( ) ,
ryzomTime . getRyzomTime ( ) ,
* _WeatherFunctionParamsSheet ,
_WeatherFunctionsBySeasonByContinent [ continent - > getId ( ) ] ) ;
// Map from weather setup to EWeather value
uint weatherSetupIndex = min ( ( uint ) ( weatherFloatValue * ( ( float ) NB_WEATHER_SETUPS ) ) , NB_WEATHER_SETUPS - 1 ) ;
//nldebug( "Weather setup of position is %u", weatherSetupIndex );
return WeatherSetupsToValue [ weatherSetupIndex ] ;
}