|
|
|
// 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 //
|
|
|
|
/////////////
|
|
|
|
// misc
|
|
|
|
#include "nel/misc/path.h"
|
|
|
|
#include "nel/misc/vectord.h"
|
|
|
|
#include "nel/misc/i18n.h"
|
|
|
|
#include "nel/misc/progress_callback.h"
|
|
|
|
// 3D Interface.
|
|
|
|
#include "nel/3d/u_landscape.h"
|
|
|
|
// Georges
|
|
|
|
#include "nel/georges/u_form.h"
|
|
|
|
#include "nel/georges/u_form_elm.h"
|
|
|
|
#include "nel/georges/u_form_loader.h"
|
|
|
|
|
|
|
|
// Client
|
|
|
|
#include "continent_manager.h"
|
|
|
|
#include "client_cfg.h"
|
|
|
|
#include "sheet_manager.h"
|
|
|
|
#include "sound_manager.h"
|
|
|
|
#include "entities.h" // \todo Hld : a enlever lorsque unselect aura son bool bien pris en compte
|
|
|
|
#include "init_main_loop.h"
|
|
|
|
#include "weather.h"
|
|
|
|
#include "weather_manager_client.h"
|
|
|
|
#include "interface_v3/interface_manager.h"
|
|
|
|
#include "interface_v3/group_map.h"
|
|
|
|
//
|
|
|
|
#include "input.h"
|
|
|
|
|
|
|
|
#include "continent_manager_build.h"
|
|
|
|
///////////
|
|
|
|
// USING //
|
|
|
|
///////////
|
|
|
|
using namespace NLPACS;
|
|
|
|
using namespace NLMISC;
|
|
|
|
using namespace NL3D;
|
|
|
|
using namespace std;
|
|
|
|
using namespace NLGEORGES;
|
|
|
|
|
|
|
|
////////////
|
|
|
|
// EXTERN //
|
|
|
|
////////////
|
|
|
|
extern ULandscape *Landscape;
|
|
|
|
extern UMoveContainer *PACS;
|
|
|
|
extern UGlobalRetriever *GR;
|
|
|
|
extern URetrieverBank *RB;
|
|
|
|
extern class CIGCallback *IGCallbacks;
|
|
|
|
extern NLLIGO::CLigoConfig LigoConfig;
|
|
|
|
|
|
|
|
UMoveContainer *PACSHibernated = NULL;
|
|
|
|
UGlobalRetriever *GRHibernated = NULL;
|
|
|
|
URetrieverBank *RBHibernated = NULL;
|
|
|
|
CIGCallback *IGCallbacksHibernated = NULL;
|
|
|
|
|
|
|
|
////////////
|
|
|
|
// GLOBAL //
|
|
|
|
////////////
|
|
|
|
|
|
|
|
// Hierarchical timer
|
|
|
|
H_AUTO_DECL ( RZ_Client_Continent_Mngr_Update_Streamable )
|
|
|
|
|
|
|
|
/////////////
|
|
|
|
// METHODS //
|
|
|
|
/////////////
|
|
|
|
//-----------------------------------------------
|
|
|
|
// CContinentManager :
|
|
|
|
// Constructor.
|
|
|
|
//-----------------------------------------------
|
|
|
|
CContinentManager::CContinentManager()
|
|
|
|
{
|
|
|
|
_Current = 0;
|
|
|
|
_Hibernated = NULL;
|
|
|
|
}// CContinentManager //
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CContinentManager::reset()
|
|
|
|
{
|
|
|
|
// stop the background sound
|
|
|
|
if (SoundMngr)
|
|
|
|
SoundMngr->stopBackgroundSound();
|
|
|
|
|
|
|
|
// Unselect continent
|
|
|
|
if (_Current)
|
|
|
|
_Current->unselect();
|
|
|
|
|
|
|
|
// Shared data must be NULL now
|
|
|
|
_Current = NULL;
|
|
|
|
nlassert (GR == NULL);
|
|
|
|
nlassert (RB == NULL);
|
|
|
|
nlassert (PACS == NULL);
|
|
|
|
nlassert (IGCallbacks == NULL);
|
|
|
|
|
|
|
|
// Swap the hibernated data
|
|
|
|
std::swap(GR, GRHibernated);
|
|
|
|
std::swap(RB, RBHibernated);
|
|
|
|
std::swap(PACS, PACSHibernated);
|
|
|
|
std::swap(_Current, _Hibernated);
|
|
|
|
std::swap(IGCallbacks, IGCallbacksHibernated);
|
|
|
|
|
|
|
|
// Unselect continent
|
|
|
|
if (_Current)
|
|
|
|
_Current->unselect();
|
|
|
|
|
|
|
|
// remove villages
|
|
|
|
removeVillages();
|
|
|
|
|
|
|
|
// NB: landscape zones are deleted in USCene::deleteLandscape()
|
|
|
|
|
|
|
|
// clear continents DB
|
|
|
|
for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
|
|
|
|
{
|
|
|
|
delete it->second;
|
|
|
|
}
|
|
|
|
_Continents.clear();
|
|
|
|
_Current = NULL;
|
|
|
|
_Hibernated = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
// load :
|
|
|
|
// Load all continent.
|
|
|
|
//-----------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
// Oldies now all these data are stored in the ryzom.world
|
|
|
|
const uint32 NBCONTINENT = 8;
|
|
|
|
SContInit vAllContinents[NBCONTINENT] = {
|
|
|
|
{ "fyros", "fyros", 15767, 20385, -27098, -23769 },
|
|
|
|
{ "tryker", "tryker", 15285, 18638, -34485, -30641 },
|
|
|
|
{ "matis", "lesfalaises", 235, 6316, -7920, -256 },
|
|
|
|
{ "zorai", "lepaysmalade", 6805, 12225, -5680, -1235 },
|
|
|
|
{ "bagne", "lebagne", 434, 1632, -11230, -9715 },
|
|
|
|
{ "route", "laroutedesombres", 5415, 7400, -17000, -9575 },
|
|
|
|
{ "sources", "sources", 2520, 3875, -11400, -9720 },
|
|
|
|
{ "terres", "lesterres", 100, 3075, -15900, -13000 }
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Read the ryzom.world which give the names and bboxes
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
void CContinentManager::preloadSheets()
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
|
|
|
|
CEntitySheet *sheet = SheetMngr.get(CSheetId("ryzom.world"));
|
|
|
|
|
|
|
|
if (!sheet || sheet->type() != CEntitySheet::WORLD)
|
|
|
|
{
|
|
|
|
nlerror("World sheet not found or bad type");
|
|
|
|
}
|
|
|
|
uint32 i;
|
|
|
|
|
|
|
|
CWorldSheet *ws = (CWorldSheet *) sheet;
|
|
|
|
|
|
|
|
// Copy datas from the sheet
|
|
|
|
|
|
|
|
for (i = 0; i < ws->ContLocs.size(); ++i)
|
|
|
|
{
|
|
|
|
const SContLoc &clTmp = ws->ContLocs[i];
|
|
|
|
std::string continentSheetName = NLMISC::strlwr(clTmp.ContinentName);
|
|
|
|
if (continentSheetName.find(".continent") == std::string::npos)
|
|
|
|
{
|
|
|
|
continentSheetName += ".continent";
|
|
|
|
}
|
|
|
|
// Get the continent form
|
|
|
|
CSheetId continentId(continentSheetName);
|
|
|
|
sheet = SheetMngr.get(continentId);
|
|
|
|
if (sheet)
|
|
|
|
{
|
|
|
|
if (sheet->type() == CEntitySheet::CONTINENT)
|
|
|
|
{
|
|
|
|
CContinent *pCont = new CContinent;
|
|
|
|
pCont->SheetName = continentSheetName;
|
|
|
|
_Continents.insert(make_pair(clTmp.SelectionName, pCont));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("Bad type for continent form %s.", continentSheetName.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("cant find continent sheet : %s.", continentSheetName.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
void CContinentManager::load ()
|
|
|
|
{
|
|
|
|
// Continents are preloaded so setup them
|
|
|
|
TContinents::iterator it = _Continents.begin();
|
|
|
|
while (it != _Continents.end())
|
|
|
|
{
|
|
|
|
it->second->setup();
|
|
|
|
it++;
|
|
|
|
}
|
|
|
|
|
|
|
|
loadContinentLandMarks();
|
|
|
|
|
|
|
|
// \todo GUIGUI : Do it better when there will be "ecosystem"/Wind/etc.
|
|
|
|
// Initialize the Landscape Vegetable.
|
|
|
|
if(ClientCfg.MicroVeget)
|
|
|
|
{
|
|
|
|
if (Landscape)
|
|
|
|
{
|
|
|
|
// if configured, enable the vegetable and load the texture.
|
|
|
|
Landscape->enableVegetable(true);
|
|
|
|
// Default setup. TODO later by gameDev.
|
|
|
|
Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0);
|
|
|
|
// Default setup. should work well for night/day transition in 30 minutes.
|
|
|
|
// Because all vegetables will be updated every 20 seconds => 90 steps.
|
|
|
|
Landscape->setVegetableUpdateLightingFrequency(1/20.f);
|
|
|
|
// Density (percentage to ratio)
|
|
|
|
Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}// load //
|
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
// select :
|
|
|
|
// Select continent from a name.
|
|
|
|
// \param const string &name : name of the contient to select.
|
|
|
|
//-----------------------------------------------
|
|
|
|
void CContinentManager::select(const string &name, const CVectorD &pos, NLMISC::IProgressCallback &progress)
|
|
|
|
{
|
|
|
|
CNiceInputAuto niceInputs;
|
|
|
|
// Find the continent.
|
|
|
|
TContinents::iterator itCont = _Continents.find(name);
|
|
|
|
if(itCont == _Continents.end())
|
|
|
|
{
|
|
|
|
nlwarning("CContinentManager::select: Continent '%s' is Unknown. Cannot Select it.", name.c_str());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dirt weather
|
|
|
|
|
|
|
|
{
|
|
|
|
H_AUTO(InitRZWorldSetLoadingContinent)
|
|
|
|
// Set the loading continent
|
|
|
|
setLoadingContinent (itCont->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ** Update the weather manager for loading information
|
|
|
|
|
|
|
|
// Update the weather manager
|
|
|
|
{
|
|
|
|
H_AUTO(InitRZWorldUpdateWeatherManager )
|
|
|
|
updateWeatherManager (itCont->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// startup season can be changed now the player is safe
|
|
|
|
StartupSeason = RT.getRyzomSeason();
|
|
|
|
// Modify this season according to the continent reached. eg: newbieland continent force the winter to be autumn
|
|
|
|
if(StartupSeason<EGSPD::CSeason::Invalid)
|
|
|
|
StartupSeason= (*itCont).second->ForceDisplayedSeason[StartupSeason];
|
|
|
|
|
|
|
|
// Compute the current season according to StartupSeason, Server driver season, R2 Editor season or manual debug season
|
|
|
|
CurrSeason = computeCurrSeason();
|
|
|
|
|
|
|
|
|
|
|
|
// Is it the same continent than the old one.
|
|
|
|
{
|
|
|
|
H_AUTO(InitRZWorldSelectCont)
|
|
|
|
if(((*itCont).second != _Current) || ((*itCont).second->Season != CurrSeason))
|
|
|
|
{
|
|
|
|
// New continent is not an indoor ?
|
|
|
|
if (!(*itCont).second->Indoor && _Current)
|
|
|
|
{
|
|
|
|
// Unselect the current continent
|
|
|
|
_Current->unselect();
|
|
|
|
|
|
|
|
// Shared data must be NULL now
|
|
|
|
_Current = NULL;
|
|
|
|
nlassert (GR == NULL);
|
|
|
|
nlassert (RB == NULL);
|
|
|
|
nlassert (PACS == NULL);
|
|
|
|
nlassert (IGCallbacks == NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Remove the primitive for all entitites (new PACS coming soon and need new primitives).
|
|
|
|
EntitiesMngr.removeCollision();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Swap the hibernated data
|
|
|
|
std::swap(GR, GRHibernated);
|
|
|
|
std::swap(RB, RBHibernated);
|
|
|
|
std::swap(PACS, PACSHibernated);
|
|
|
|
std::swap(_Current, _Hibernated);
|
|
|
|
std::swap(IGCallbacks, IGCallbacksHibernated);
|
|
|
|
|
|
|
|
// Is it the same continent than the old one.
|
|
|
|
if(((*itCont).second != _Current) || ((*itCont).second->Season != CurrSeason))
|
|
|
|
{
|
|
|
|
// Unselect the old continent.
|
|
|
|
if(_Current)
|
|
|
|
_Current->unselect();
|
|
|
|
_Current = (*itCont).second;
|
|
|
|
|
|
|
|
// Teleport in a new continent, complete load
|
|
|
|
_Current->select(pos, progress, true, false, CurrSeason);
|
|
|
|
|
|
|
|
// New continent is not an indoor ?
|
|
|
|
if (!_Current->Indoor)
|
|
|
|
{
|
|
|
|
// Stop the background sound
|
|
|
|
if (SoundMngr)
|
|
|
|
SoundMngr->stopBackgroundSound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Teleport in the hibernated continent
|
|
|
|
_Current->select(pos, progress, false, true, CurrSeason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Teleport in the same continent
|
|
|
|
_Current->select(pos, progress, false, false, CurrSeason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
H_AUTO(InitRZWorldSound)
|
|
|
|
|
|
|
|
// New continent is not an indoor ?
|
|
|
|
if (!_Current->Indoor)
|
|
|
|
{
|
|
|
|
if(SoundMngr)
|
|
|
|
SoundMngr->loadContinent(name, pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Map handling
|
|
|
|
{
|
|
|
|
H_AUTO(InitRZWorldMapHandling)
|
|
|
|
CWorldSheet *pWS = dynamic_cast<CWorldSheet*>(SheetMngr.get(CSheetId("ryzom.world")));
|
|
|
|
for (uint32 i = 0; i < pWS->Maps.size(); ++i)
|
|
|
|
if (pWS->Maps[i].ContinentName == name)
|
|
|
|
{
|
|
|
|
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
|
|
|
CGroupMap *pMap = dynamic_cast<CGroupMap*>(pIM->getElementFromId("ui:interface:map:content:map_content:actual_map"));
|
|
|
|
if (pMap != NULL)
|
|
|
|
pMap->setMap(pWS->Maps[i].Name);
|
|
|
|
pMap = dynamic_cast<CGroupMap*>(pIM->getElementFromId("ui:interface:respawn_map:content:map_content:actual_map"));
|
|
|
|
if (pMap != NULL)
|
|
|
|
pMap->setMap(pWS->Maps[i].Name);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}// select //
|
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
// select :
|
|
|
|
// Select closest continent from a vector.
|
|
|
|
//-----------------------------------------------
|
|
|
|
void CContinentManager::select(const CVectorD &pos, NLMISC::IProgressCallback &progress)
|
|
|
|
{
|
|
|
|
|
|
|
|
CVector2f fPos;
|
|
|
|
fPos.x = (float)pos.x;
|
|
|
|
fPos.y = (float)pos.y;
|
|
|
|
TContinents::iterator it = _Continents.begin();
|
|
|
|
while (it != _Continents.end())
|
|
|
|
{
|
|
|
|
CContinent *pCont = it->second;
|
|
|
|
nlinfo("Looking into %s", pCont->SheetName.c_str());
|
|
|
|
if (pCont->Zone.VPoints.size() > 0) // Patch because some continent have not been done yet
|
|
|
|
{
|
|
|
|
if (pCont->Zone.contains(fPos))
|
|
|
|
{
|
|
|
|
// load the continent selected.
|
|
|
|
select (it->first, pos, progress);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
nlwarning("**********************************************");
|
|
|
|
nlwarning("Start position (%s) not found in continent %s", NLMISC::toString(pos.asVector()).c_str(), it->first.c_str());
|
|
|
|
for(uint k = 0; k < pCont->Zone.VPoints.size(); ++k)
|
|
|
|
{
|
|
|
|
nlwarning("zone point %d = %s", (int)k, NLMISC::toString(pCont->Zone.VPoints[k]).c_str());
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
it++;
|
|
|
|
}
|
|
|
|
|
|
|
|
nlwarning("cannot select any continent at pos (%f, %f)", fPos.x, fPos.y);
|
|
|
|
|
|
|
|
/* *****************
|
|
|
|
PLEASE DO *****NOT***** PUT AN ASSERT HERE
|
|
|
|
While this is a bug, it is a data bug. Crashing is not a good solution in this case.
|
|
|
|
If you put an assert, it can happens this scenario for example:
|
|
|
|
- A levelDesigner put a bad Teleporter which teleport to an invalid position
|
|
|
|
- The player teleport, but its position is invalid => crash
|
|
|
|
- the next time he logs, it crashes at start, AND HENCE CANNOT ASK A GM TO TELEPORT HIM AWAY
|
|
|
|
|
|
|
|
Other scenarios can happens like Data change, Continent change => Player no more at valid position etc...
|
|
|
|
HENCE MUST NOT CRASH, but display a "Lost In Space screen" leaving the player the possibility to ask HELP.
|
|
|
|
*****************
|
|
|
|
*/
|
|
|
|
//nlassertex(0, ("can't select any continent"));
|
|
|
|
|
|
|
|
}// select //
|
|
|
|
|
|
|
|
|
|
|
|
bool CContinentManager::isLoadingforced(const NLMISC::CVector &playerPos) const
|
|
|
|
{
|
|
|
|
if(_Current == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return _Current->isLoadingforced(playerPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CContinentManager::updateStreamable(const NLMISC::CVector &playerPos)
|
|
|
|
{
|
|
|
|
H_AUTO_USE ( RZ_Client_Continent_Mngr_Update_Streamable )
|
|
|
|
if(_Current)
|
|
|
|
_Current->updateStreamable(playerPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CContinentManager::forceUpdateStreamable(const NLMISC::CVector &playerPos, NLMISC::IProgressCallback &progress)
|
|
|
|
{
|
|
|
|
H_AUTO_USE ( RZ_Client_Continent_Mngr_Update_Streamable )
|
|
|
|
if (ClientCfg.VillagesEnabled)
|
|
|
|
{
|
|
|
|
if(_Current)
|
|
|
|
_Current->forceUpdateStreamable(playerPos, progress);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CContinentManager::removeVillages()
|
|
|
|
{
|
|
|
|
for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
|
|
|
|
{
|
|
|
|
if (it->second)
|
|
|
|
it->second->removeVillages();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CContinentManager::getFogState(TFogType fogType, float dayNight, float duskRatio, CLightCycleManager::TLightState lightState, const NLMISC::CVectorD &pos, CFogState &result)
|
|
|
|
{
|
|
|
|
if(_Current)
|
|
|
|
_Current->getFogState(fogType, dayNight, duskRatio, lightState, pos, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
CContinent *CContinentManager::get(const std::string &contName)
|
|
|
|
{
|
|
|
|
TContinents::iterator it = _Continents.find(contName);
|
|
|
|
if (it != _Continents.end())
|
|
|
|
return it->second;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CContinentManager::serialUserLandMarks(NLMISC::IStream &f)
|
|
|
|
{
|
|
|
|
f.serialVersion(1);
|
|
|
|
if (!f.isReading())
|
|
|
|
{
|
|
|
|
uint32 numCont = (uint32)_Continents.size();
|
|
|
|
f.serial(numCont);
|
|
|
|
for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
|
|
|
|
{
|
|
|
|
std::string name = it->first;
|
|
|
|
f.serial(name);
|
|
|
|
if (it->second)
|
|
|
|
{
|
|
|
|
f.serialCont(it->second->UserLandMarks);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::vector<CUserLandMark> dummy;
|
|
|
|
f.serialCont(dummy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint32 numCont;
|
|
|
|
f.serial(numCont);
|
|
|
|
for(uint k = 0; k < numCont; ++k)
|
|
|
|
{
|
|
|
|
std::string contName;
|
|
|
|
f.serial(contName);
|
|
|
|
TContinents::iterator it = _Continents.find(contName);
|
|
|
|
if (it != _Continents.end() && it->second)
|
|
|
|
{
|
|
|
|
f.serialCont(it->second->UserLandMarks);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::vector<CUserLandMark> dummy;
|
|
|
|
f.serialCont(dummy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The number of stored landmarks is not checked at this time, but if we receive a
|
|
|
|
// lower value in the server database, we will cut down using checkNumberOfUserLandmarks()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
// checkNumberOfLandmarks
|
|
|
|
//-----------------------------------------------
|
|
|
|
void CContinentManager::checkNumberOfUserLandmarks( uint maxNumber )
|
|
|
|
{
|
|
|
|
for ( TContinents::iterator it=_Continents.begin(); it!=_Continents.end(); ++it )
|
|
|
|
{
|
|
|
|
CContinent *cont = (*it).second;
|
|
|
|
if ( cont->UserLandMarks.size() > maxNumber )
|
|
|
|
{
|
|
|
|
// Just cut down the last landmarks (in case of hacked file)
|
|
|
|
if ( cont == _Current )
|
|
|
|
{
|
|
|
|
CGroupMap *pMap = dynamic_cast<CGroupMap*>(CInterfaceManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
|
|
|
|
if ( pMap )
|
|
|
|
pMap->removeExceedingUserLandMarks( maxNumber );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cont->UserLandMarks.resize( maxNumber );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
// serialFOWMaps
|
|
|
|
//-----------------------------------------------
|
|
|
|
void CContinentManager::serialFOWMaps()
|
|
|
|
{
|
|
|
|
for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
|
|
|
|
{
|
|
|
|
CContinent *pCont = it->second;
|
|
|
|
//nlinfo("Saving fow continent %s of name %s", it->first.c_str(), pCont->Name.c_str());
|
|
|
|
it->second->FoW.save(pCont->Name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string &CContinentManager::getCurrentContinentSelectName()
|
|
|
|
{
|
|
|
|
TContinents::iterator it;
|
|
|
|
|
|
|
|
for (it = _Continents.begin(); it != _Continents.end(); ++it)
|
|
|
|
{
|
|
|
|
if (it->second == _Current)
|
|
|
|
return it->first;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const string emptyString;
|
|
|
|
return emptyString;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CContinentManager::reloadWeather()
|
|
|
|
{
|
|
|
|
WeatherManager.release();
|
|
|
|
// reload the sheet
|
|
|
|
std::vector<std::string> extensions;
|
|
|
|
extensions.push_back("weather_setup");
|
|
|
|
extensions.push_back("weather_function_params");
|
|
|
|
extensions.push_back("continent");
|
|
|
|
extensions.push_back("light_cycle");
|
|
|
|
|
|
|
|
NLMISC::IProgressCallback pc;
|
|
|
|
SheetMngr.loadAllSheet(pc, true, false, true, true, &extensions);
|
|
|
|
|
|
|
|
WeatherManager.init();
|
|
|
|
// Load description of light cycles for each season.
|
|
|
|
loadWorldLightCycle();
|
|
|
|
// Load global weather function parameters
|
|
|
|
loadWeatherFunctionParams();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
|
|
|
|
{
|
|
|
|
NLMISC::CSheetId contSI(it->second->SheetName);
|
|
|
|
CContinentSheet *cs = dynamic_cast<CContinentSheet *>(SheetMngr.get(contSI));
|
|
|
|
if (cs)
|
|
|
|
{
|
|
|
|
// update continent weather part
|
|
|
|
for(uint l = 0; l < EGSPD::CSeason::Invalid; ++l)
|
|
|
|
{
|
|
|
|
it->second->WeatherFunction[l].buildFromSheet(cs->WeatherFunction[l], WeatherManager);
|
|
|
|
}
|
|
|
|
// update misc params
|
|
|
|
it->second->FogStart = cs->Continent.FogStart;
|
|
|
|
it->second->FogEnd = cs->Continent.FogEnd;
|
|
|
|
it->second->RootFogStart = cs->Continent.RootFogStart;
|
|
|
|
it->second->RootFogEnd = cs->Continent.RootFogEnd;
|
|
|
|
it->second->LandscapeLightDay = cs->Continent.LandscapeLightDay;
|
|
|
|
it->second->LandscapeLightDusk = cs->Continent.LandscapeLightDusk;
|
|
|
|
it->second->LandscapeLightNight = cs->Continent.LandscapeLightNight;
|
|
|
|
it->second->EntityLightDay = cs->Continent.EntityLightDay;
|
|
|
|
it->second->EntityLightDusk = cs->Continent.EntityLightDusk;
|
|
|
|
it->second->EntityLightNight = cs->Continent.EntityLightNight;
|
|
|
|
it->second->RootLightDay = cs->Continent.RootLightDay;
|
|
|
|
it->second->RootLightDusk = cs->Continent.RootLightDusk;
|
|
|
|
it->second->RootLightNight = cs->Continent.RootLightNight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CContinentManager::reloadSky()
|
|
|
|
{
|
|
|
|
// reload new style sky
|
|
|
|
std::vector<std::string> exts;
|
|
|
|
CSheetManager sheetManager;
|
|
|
|
exts.push_back("sky");
|
|
|
|
exts.push_back("continent");
|
|
|
|
NLMISC::IProgressCallback progress;
|
|
|
|
sheetManager.loadAllSheet(progress, true, false, false, true, &exts);
|
|
|
|
//
|
|
|
|
const CSheetManager::TEntitySheetMap &sm = SheetMngr.getSheets();
|
|
|
|
for(CSheetManager::TEntitySheetMap::const_iterator it = sm.begin(); it != sm.end(); ++it)
|
|
|
|
{
|
|
|
|
if (it->second.EntitySheet)
|
|
|
|
{
|
|
|
|
CEntitySheet::TType type = it->second.EntitySheet->Type;
|
|
|
|
if (type == CEntitySheet::CONTINENT)
|
|
|
|
{
|
|
|
|
// find matching sheet in new sheetManager
|
|
|
|
const CEntitySheet *other = sheetManager.get(it->first);
|
|
|
|
if (other)
|
|
|
|
{
|
|
|
|
const CContinentParameters &cp = static_cast<const CContinentSheet *>(other)->Continent;
|
|
|
|
// find matching continent in manager
|
|
|
|
for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
|
|
|
|
{
|
|
|
|
if (it->second && nlstricmp(it->second->Name, cp.Name) == 0)
|
|
|
|
{
|
|
|
|
std::copy(cp.SkySheet, cp.SkySheet + EGSPD::CSeason::Invalid, it->second->SkySheet);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(type == CEntitySheet::SKY)
|
|
|
|
{
|
|
|
|
// find matching sheet in new sheetManager
|
|
|
|
const CEntitySheet *other = sheetManager.get(it->first);
|
|
|
|
if (other)
|
|
|
|
{
|
|
|
|
// replace data in place
|
|
|
|
((CSkySheet &) *it->second.EntitySheet) = ((const CSkySheet &) *other);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_Current)
|
|
|
|
{
|
|
|
|
_Current->releaseSky();
|
|
|
|
_Current->initSky();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
void CContinentManager::loadContinentLandMarks()
|
|
|
|
{
|
|
|
|
if (ClientCfg.UpdatePackedSheet == false)
|
|
|
|
{
|
|
|
|
readLMConts();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
buildLMConts();
|
|
|
|
readLMConts();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
|
|
|
void CContinentManager::readLMConts()
|
|
|
|
{
|
|
|
|
CIFile f;
|
|
|
|
|
|
|
|
string sPackedFileName = CPath::lookup(LM_PACKED_FILE, false);
|
|
|
|
if (sPackedFileName.empty())
|
|
|
|
sPackedFileName = LM_PACKED_FILE_SAVE;
|
|
|
|
|
|
|
|
if (f.open(sPackedFileName))
|
|
|
|
{
|
|
|
|
uint32 nNbCont = 0;
|
|
|
|
sint ver= f.serialVersion(1);
|
|
|
|
f.serial(nNbCont);
|
|
|
|
for (uint32 i = 0; i < nNbCont; ++i)
|
|
|
|
{
|
|
|
|
string sContName;
|
|
|
|
f.serial(sContName);
|
|
|
|
TContinents::iterator itCont = _Continents.find(sContName);
|
|
|
|
if(itCont != _Continents.end())
|
|
|
|
{
|
|
|
|
CContinent *pCont = itCont->second;
|
|
|
|
f.serial(pCont->Zone);
|
|
|
|
f.serial(pCont->ZoneCenter);
|
|
|
|
f.serialCont(pCont->ContLandMarks);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CContinent dummy;
|
|
|
|
f.serial(dummy.Zone);
|
|
|
|
f.serial(dummy.ZoneCenter);
|
|
|
|
f.serialCont(dummy.ContLandMarks);
|
|
|
|
nlwarning("continent not found : %s", sContName.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.serialCont(WorldMap);
|
|
|
|
|
|
|
|
if (ver >= 1)
|
|
|
|
f.serialCont(aliasToRegionMap);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("cannot load " LM_PACKED_FILE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
|
|
|
string CContinentManager::getRegionNameByAlias(uint32 i)
|
|
|
|
{
|
|
|
|
return aliasToRegionMap[i];
|
|
|
|
}
|