// Ryzom - MMORPG Framework // 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 . #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 sheetVec; CSheetId::buildIdVector( sheetVec, "weather_setup" ); // list weather_setup sheets std::vector weatherSheets; std::vector 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 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]; }