158 lines
5.9 KiB
C++
158 lines
5.9 KiB
C++
|
// 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];
|
||
|
}
|