Merge branch '164-crash-on-patching-and-possibly-right-after-login' into main/gingo...
[ryzomcore.git] / ryzom / client / src / continent_manager.cpp
blob3001eac34e115be08a45e4ed170cbf6d60f112e0
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "stdpch.h"
26 /////////////
27 // INCLUDE //
28 /////////////
29 // misc
30 #include "nel/misc/path.h"
31 #include "nel/misc/vectord.h"
32 #include "nel/misc/i18n.h"
33 #include "nel/misc/progress_callback.h"
34 // 3D Interface.
35 #include "nel/3d/u_landscape.h"
36 // Georges
37 #include "nel/georges/u_form.h"
38 #include "nel/georges/u_form_elm.h"
39 #include "nel/georges/u_form_loader.h"
41 // Client
42 #include "continent_manager.h"
43 #include "client_cfg.h"
44 #include "sheet_manager.h"
45 #include "sound_manager.h"
46 #include "entities.h" // \todo Hld : a enlever lorsque unselect aura son bool bien pris en compte
47 #include "init_main_loop.h"
48 #include "weather.h"
49 #include "weather_manager_client.h"
50 #include "interface_v3/interface_manager.h"
51 #include "interface_v3/group_map.h"
53 #include "input.h"
55 #include "continent_manager_build.h"
56 ///////////
57 // USING //
58 ///////////
59 using namespace NLPACS;
60 using namespace NLMISC;
61 using namespace NL3D;
62 using namespace std;
63 using namespace NLGEORGES;
65 ////////////
66 // EXTERN //
67 ////////////
68 extern ULandscape *Landscape;
69 extern UMoveContainer *PACS;
70 extern UGlobalRetriever *GR;
71 extern URetrieverBank *RB;
72 extern class CIGCallback *IGCallbacks;
73 extern NLLIGO::CLigoConfig LigoConfig;
75 UMoveContainer *PACSHibernated = NULL;
76 UGlobalRetriever *GRHibernated = NULL;
77 URetrieverBank *RBHibernated = NULL;
78 CIGCallback *IGCallbacksHibernated = NULL;
80 ////////////
81 // GLOBAL //
82 ////////////
84 // Hierarchical timer
85 H_AUTO_DECL ( RZ_Client_Continent_Mngr_Update_Streamable )
87 /////////////
88 // METHODS //
89 /////////////
90 //-----------------------------------------------
91 // CContinentManager :
92 // Constructor.
93 //-----------------------------------------------
94 CContinentManager::CContinentManager()
96 _Current = 0;
97 _Hibernated = NULL;
98 }// CContinentManager //
102 void CContinentManager::reset()
104 // stop the background sound
105 if (SoundMngr)
106 SoundMngr->stopBackgroundSound();
108 // Unselect continent
109 if (_Current)
110 _Current->unselect();
112 // Shared data must be NULL now
113 _Current = NULL;
114 nlassert (GR == NULL);
115 nlassert (RB == NULL);
116 nlassert (PACS == NULL);
117 nlassert (IGCallbacks == NULL);
119 // Swap the hibernated data
120 std::swap(GR, GRHibernated);
121 std::swap(RB, RBHibernated);
122 std::swap(PACS, PACSHibernated);
123 std::swap(_Current, _Hibernated);
124 std::swap(IGCallbacks, IGCallbacksHibernated);
126 // Unselect continent
127 if (_Current)
128 _Current->unselect();
130 // remove villages
131 removeVillages();
133 // NB: landscape zones are deleted in USCene::deleteLandscape()
135 // clear continents DB
136 for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
138 delete it->second;
140 _Continents.clear();
141 _Current = NULL;
142 _Hibernated = NULL;
146 //-----------------------------------------------
147 // load :
148 // Load all continent.
149 //-----------------------------------------------
153 // Oldies now all these data are stored in the ryzom.world
154 const uint32 NBCONTINENT = 8;
155 SContInit vAllContinents[NBCONTINENT] = {
156 { "fyros", "fyros", 15767, 20385, -27098, -23769 },
157 { "tryker", "tryker", 15285, 18638, -34485, -30641 },
158 { "matis", "lesfalaises", 235, 6316, -7920, -256 },
159 { "zorai", "lepaysmalade", 6805, 12225, -5680, -1235 },
160 { "bagne", "lebagne", 434, 1632, -11230, -9715 },
161 { "route", "laroutedesombres", 5415, 7400, -17000, -9575 },
162 { "sources", "sources", 2520, 3875, -11400, -9720 },
163 { "terres", "lesterres", 100, 3075, -15900, -13000 }
167 // Read the ryzom.world which give the names and bboxes
170 //-----------------------------------------------
171 void CContinentManager::preloadSheets()
173 reset();
175 CEntitySheet *sheet = SheetMngr.get(CSheetId("ryzom.world"));
177 if (!sheet || sheet->type() != CEntitySheet::WORLD)
179 nlerror("World sheet not found or bad type");
181 uint32 i;
183 CWorldSheet *ws = (CWorldSheet *) sheet;
185 // Copy datas from the sheet
187 for (i = 0; i < ws->ContLocs.size(); ++i)
189 const SContLoc &clTmp = ws->ContLocs[i];
190 std::string continentSheetName = NLMISC::toLowerAscii(clTmp.ContinentName);
191 if (continentSheetName.find(".continent") == std::string::npos)
193 continentSheetName += ".continent";
195 // Get the continent form
196 CSheetId continentId(continentSheetName);
197 sheet = SheetMngr.get(continentId);
198 if (sheet)
200 if (sheet->type() == CEntitySheet::CONTINENT)
202 CContinent *pCont = new CContinent;
203 pCont->SheetName = continentSheetName;
204 _Continents.insert(make_pair(clTmp.SelectionName, pCont));
206 else
208 nlwarning("Bad type for continent form %s.", continentSheetName.c_str());
211 else
213 nlwarning("cant find continent sheet : %s.", continentSheetName.c_str());
218 //-----------------------------------------------
219 void CContinentManager::load ()
221 // Continents are preloaded so setup them
222 TContinents::iterator it = _Continents.begin();
223 while (it != _Continents.end())
225 it->second->setup();
226 it++;
229 loadContinentLandMarks();
231 // \todo GUIGUI : Do it better when there will be "ecosystem"/Wind/etc.
232 // Initialize the Landscape Vegetable.
233 if(ClientCfg.MicroVeget)
235 if (Landscape)
237 // if configured, enable the vegetable and load the texture.
238 Landscape->enableVegetable(true);
239 // Default setup. TODO later by gameDev.
240 Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0);
241 // Default setup. should work well for night/day transition in 30 minutes.
242 // Because all vegetables will be updated every 20 seconds => 90 steps.
243 Landscape->setVegetableUpdateLightingFrequency(1/20.f);
244 // Density (percentage to ratio)
245 Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f);
248 }// load //
250 //-----------------------------------------------
251 // select :
252 // Select continent from a name.
253 // \param const string &name : name of the continent to select.
254 //-----------------------------------------------
255 void CContinentManager::select(const string &name, const CVectorD &pos, NLMISC::IProgressCallback &progress)
257 CNiceInputAuto niceInputs;
258 // Find the continent.
259 TContinents::iterator itCont = _Continents.find(name);
260 if(itCont == _Continents.end())
262 nlwarning("CContinentManager::select: Continent '%s' is Unknown. Cannot Select it.", name.c_str());
263 return;
266 // Dirt weather
269 H_AUTO(InitRZWorldSetLoadingContinent)
270 // Set the loading continent
271 setLoadingContinent (itCont->second);
274 // ** Update the weather manager for loading information
276 // Update the weather manager
278 H_AUTO(InitRZWorldUpdateWeatherManager )
279 updateWeatherManager (itCont->second);
283 // startup season can be changed now the player is safe
284 StartupSeason = RT.getRyzomSeason();
285 // Modify this season according to the continent reached. eg: newbieland continent force the winter to be autumn
286 if(StartupSeason<EGSPD::CSeason::Invalid)
287 StartupSeason= (*itCont).second->ForceDisplayedSeason[StartupSeason];
289 // Compute the current season according to StartupSeason, Server driver season, R2 Editor season or manual debug season
290 CurrSeason = computeCurrSeason();
293 // Is it the same continent than the old one.
295 H_AUTO(InitRZWorldSelectCont)
296 if(((*itCont).second != _Current) || ((*itCont).second->Season != CurrSeason))
298 // New continent is not an indoor ?
299 if (!(*itCont).second->Indoor && _Current)
301 // Unselect the current continent
302 _Current->unselect();
304 // Shared data must be NULL now
305 _Current = NULL;
306 nlassert (GR == NULL);
307 nlassert (RB == NULL);
308 nlassert (PACS == NULL);
309 nlassert (IGCallbacks == NULL);
311 else
313 // Remove the primitive for all entitites (new PACS coming soon and need new primitives).
314 EntitiesMngr.removeCollision();
317 // Swap the hibernated data
318 std::swap(GR, GRHibernated);
319 std::swap(RB, RBHibernated);
320 std::swap(PACS, PACSHibernated);
321 std::swap(_Current, _Hibernated);
322 std::swap(IGCallbacks, IGCallbacksHibernated);
324 // Is it the same continent than the old one.
325 if(((*itCont).second != _Current) || ((*itCont).second->Season != CurrSeason))
327 // Unselect the old continent.
328 if(_Current)
329 _Current->unselect();
330 _Current = (*itCont).second;
332 // Teleport in a new continent, complete load
333 _Current->select(pos, progress, true, false, CurrSeason);
335 // New continent is not an indoor ?
336 if (!_Current->Indoor)
338 // Stop the background sound
339 if (SoundMngr)
340 SoundMngr->stopBackgroundSound();
343 else
345 // Teleport in the hibernated continent
346 _Current->select(pos, progress, false, true, CurrSeason);
349 else
351 // Teleport in the same continent
352 _Current->select(pos, progress, false, false, CurrSeason);
357 H_AUTO(InitRZWorldSound)
359 // New continent is not an indoor ?
360 if (!_Current->Indoor)
362 if(SoundMngr)
363 SoundMngr->loadContinent(name, pos);
367 // Map handling
369 H_AUTO(InitRZWorldMapHandling)
370 CWorldSheet *pWS = dynamic_cast<CWorldSheet*>(SheetMngr.get(CSheetId("ryzom.world")));
371 for (uint32 i = 0; i < pWS->Maps.size(); ++i)
372 if (pWS->Maps[i].ContinentName == name)
374 CInterfaceManager *pIM = CInterfaceManager::getInstance();
375 CGroupMap *pMap = dynamic_cast<CGroupMap*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
376 if (pMap != NULL)
377 pMap->setMap(pWS->Maps[i].Name);
378 pMap = dynamic_cast<CGroupMap*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:respawn_map:content:map_content:actual_map"));
379 if (pMap != NULL)
380 pMap->setMap(pWS->Maps[i].Name);
381 break;
386 }// select //
388 //-----------------------------------------------
389 // select :
390 // Select closest continent from a vector.
391 //-----------------------------------------------
392 void CContinentManager::select(const CVectorD &pos, NLMISC::IProgressCallback &progress)
395 CVector2f fPos;
396 fPos.x = (float)pos.x;
397 fPos.y = (float)pos.y;
398 TContinents::iterator it = _Continents.begin();
399 while (it != _Continents.end())
401 CContinent *pCont = it->second;
402 nlinfo("Looking into %s", pCont->SheetName.c_str());
403 if (!pCont->Zone.VPoints.empty()) // Patch because some continent have not been done yet
405 if (pCont->Zone.contains(fPos))
407 // load the continent selected.
408 select (it->first, pos, progress);
409 return;
411 else
414 nlwarning("**********************************************");
415 nlwarning("Start position (%s) not found in continent %s", NLMISC::toString(pos.asVector()).c_str(), it->first.c_str());
416 for(uint k = 0; k < pCont->Zone.VPoints.size(); ++k)
418 nlwarning("zone point %d = %s", (int)k, NLMISC::toString(pCont->Zone.VPoints[k]).c_str());
423 it++;
426 nlwarning("cannot select any continent at pos (%f, %f)", fPos.x, fPos.y);
428 /* *****************
429 PLEASE DO *****NOT***** PUT AN ASSERT HERE
430 While this is a bug, it is a data bug. Crashing is not a good solution in this case.
431 If you put an assert, it can happens this scenario for example:
432 - A levelDesigner put a bad Teleporter which teleport to an invalid position
433 - The player teleport, but its position is invalid => crash
434 - the next time he logs, it crashes at start, AND HENCE CANNOT ASK A GM TO TELEPORT HIM AWAY
436 Other scenarios can happens like Data change, Continent change => Player no more at valid position etc...
437 HENCE MUST NOT CRASH, but display a "Lost In Space screen" leaving the player the possibility to ask HELP.
438 *****************
440 //nlassertex(0, ("can't select any continent"));
442 }// select //
445 bool CContinentManager::isLoadingforced(const NLMISC::CVector &playerPos) const
447 if(_Current == 0)
448 return false;
450 return _Current->isLoadingforced(playerPos);
453 void CContinentManager::updateStreamable(const NLMISC::CVector &playerPos)
455 H_AUTO_USE ( RZ_Client_Continent_Mngr_Update_Streamable )
456 if(_Current)
457 _Current->updateStreamable(playerPos);
460 void CContinentManager::forceUpdateStreamable(const NLMISC::CVector &playerPos, NLMISC::IProgressCallback &progress)
462 H_AUTO_USE ( RZ_Client_Continent_Mngr_Update_Streamable )
463 if (ClientCfg.VillagesEnabled)
465 if(_Current)
466 _Current->forceUpdateStreamable(playerPos, progress);
472 void CContinentManager::removeVillages()
474 for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
476 if (it->second)
477 it->second->removeVillages();
481 void CContinentManager::getFogState(TFogType fogType, float dayNight, float duskRatio, CLightCycleManager::TLightState lightState, const NLMISC::CVectorD &pos, CFogState &result)
483 if(_Current)
484 _Current->getFogState(fogType, dayNight, duskRatio, lightState, pos, result);
487 CContinent *CContinentManager::get(const std::string &contName)
489 TContinents::iterator it = _Continents.find(contName);
490 if (it != _Continents.end())
491 return it->second;
492 return NULL;
495 void CContinentManager::writeTo(xmlNodePtr node) const
497 // <landmarks continent="bagne" type="user" />
498 // <landmarks continent="tryker" type="user">
499 // <landmark type="0" x="0" y="0" title="landmark title"/>
500 // ...
501 // </landmarks>
502 for(TContinents::const_iterator it = _Continents.begin(); it != _Continents.end(); ++it)
504 std::string name = it->first;
505 xmlNodePtr contNode = xmlNewChild(node, NULL, (const xmlChar*)"landmarks", NULL);
506 xmlSetProp(contNode, (const xmlChar*)"continent", (const xmlChar*)name.c_str());
507 xmlSetProp(contNode, (const xmlChar*)"type", (const xmlChar*)"user");
509 if (it->second && it->second->UserLandMarks.size() > 0)
511 for(uint i = 0; i< it->second->UserLandMarks.size(); ++i)
513 const CUserLandMark& lm = it->second->UserLandMarks[i];
515 xmlNodePtr lmNode = xmlNewChild(contNode, NULL, (const xmlChar*)"landmark", NULL);
516 xmlSetProp(lmNode, (const xmlChar*)"type", (const xmlChar*)toString("%d", (uint32)lm.Type).c_str());
517 xmlSetProp(lmNode, (const xmlChar*)"x", (const xmlChar*)toString("%.2f", lm.Pos.x).c_str());
518 xmlSetProp(lmNode, (const xmlChar*)"y", (const xmlChar*)toString("%.2f", lm.Pos.y).c_str());
520 // sanitize ascii control chars
521 // libxml will encode other special chars itself
522 std::string title = lm.Title.toUtf8();
523 for(uint i = 0; i< title.size(); i++)
525 if (title[i] >= '\0' && title[i] < ' ' && title[i] != '\n' && title[i] != '\t')
527 title[i] = '?';
530 xmlSetProp(lmNode, (const xmlChar*)"title", (const xmlChar*)title.c_str());
536 void CContinentManager::readFrom(xmlNodePtr node)
538 CXMLAutoPtr prop;
540 // <landmarks continent="bagne" type="user">
541 // <landmark type="0" x="0" y="0" title="landmark title" />
542 // ...
543 // </landmarks>
544 std::string continent;
545 prop = xmlGetProp(node, (xmlChar*)"continent");
546 if (!prop)
548 nlwarning("Ignore landmarks group 'continent' attribute.");
549 return;
551 continent = (const char*)prop;
553 TContinents::iterator itContinent = _Continents.find(continent);
554 if (itContinent == _Continents.end() || !itContinent->second)
556 nlwarning("Ignore landmarks group with unknown 'continent' '%s'", continent.c_str());
557 return;
560 std::string lmtype;
561 prop = xmlGetProp(node, (xmlChar*)"type");
562 if (!prop)
564 nlwarning("Ignore landmarks group without 'type' attribute.");
565 return;
567 lmtype = toLowerAscii((const char*)prop);
568 if (lmtype != "user")
570 nlwarning("Ignore landmarks group with type '%s', expected 'user'.", lmtype.c_str());
571 return;
574 node = node->children;
575 while(node)
577 if (stricmp((char*)node->name, "landmark") != 0)
579 nlwarning("Ignore invalid node '%s' under landmarks group", (const char*)node->name);
581 node = node->next;
582 continue;
585 bool add = true;
586 CUserLandMark lm;
588 prop = xmlGetProp(node, (xmlChar*)"type");
589 if (prop)
590 fromString((const char*)prop, lm.Type);
591 else
592 nlwarning("Using default value for landmark type");
594 prop = xmlGetProp(node, (xmlChar*)"x");
595 if (prop)
597 fromString((const char*)prop, lm.Pos.x);
599 else
601 nlwarning("Landmark missing 'x' attribute");
602 add = false;
605 prop = xmlGetProp(node, (xmlChar*)"y");
606 if (prop)
608 fromString((const char*)prop, lm.Pos.y);
610 else
612 nlwarning("Landmark missing 'y' attribute");
613 add = false;
616 prop = xmlGetProp(node, (xmlChar*)"title");
617 if (prop)
619 lm.Title.fromUtf8((const char*)prop);
621 else
623 nlwarning("Landmark missing 'title' attribute");
624 add = false;
627 if (add)
629 // before adding, check for duplicate
630 // duplicates might be read from .icfg before .xml is read
631 add = true;
632 for(uint i = 0; i< itContinent->second->UserLandMarks.size(); ++i)
634 const CUserLandMark& test = itContinent->second->UserLandMarks[i];
635 uint xdiff = fabs(test.Pos.x - lm.Pos.x) * 100.f;
636 uint ydiff = fabs(test.Pos.y - lm.Pos.y) * 100.f;
637 if (xdiff == 0 && ydiff == 0)
639 add = false;
640 break;
644 if (add)
646 itContinent->second->UserLandMarks.push_back(lm);
648 else
650 nlwarning("Ignore landmark with duplicate pos (continent:'%s', x:%.2f, y:%.2f, type:%d, title:'%s')", continent.c_str(), lm.Pos.x, lm.Pos.y, (uint8)lm.Type, lm.Title.toUtf8().c_str());
653 else
655 nlwarning("Landmark not added");
658 node = node->next;
662 uint32 CContinentManager::serialUserLandMarks(NLMISC::IStream &f)
664 uint32 totalLandmarks = 0;
666 f.serialVersion(1);
667 if (!f.isReading())
669 uint32 numCont = (uint32)_Continents.size();
670 f.serial(numCont);
671 for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
673 std::string name = it->first;
674 f.serial(name);
675 if (it->second)
677 f.serialCont(it->second->UserLandMarks);
678 totalLandmarks += it->second->UserLandMarks.size();
680 else
682 std::vector<CUserLandMark> dummy;
683 f.serialCont(dummy);
687 else
689 uint32 numCont;
690 f.serial(numCont);
691 for(uint k = 0; k < numCont; ++k)
693 std::string contName;
694 f.serial(contName);
695 TContinents::iterator it = _Continents.find(contName);
696 if (it != _Continents.end() && it->second)
698 f.serialCont(it->second->UserLandMarks);
699 totalLandmarks += it->second->UserLandMarks.size();
701 else
703 std::vector<CUserLandMark> dummy;
704 f.serialCont(dummy);
709 return totalLandmarks;
713 //-----------------------------------------------
714 // updateUserLandMarks
715 //-----------------------------------------------
716 void CContinentManager::updateUserLandMarks()
718 CGroupMap *pMap = dynamic_cast<CGroupMap*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
719 if ( pMap )
720 pMap->updateUserLandMarks();
724 //-----------------------------------------------
725 // serialFOWMaps
726 //-----------------------------------------------
727 void CContinentManager::serialFOWMaps()
729 for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
731 CContinent *pCont = it->second;
732 //nlinfo("Saving fow continent %s of name %s", it->first.c_str(), pCont->Name.c_str());
733 it->second->FoW.save(pCont->Name);
737 const std::string &CContinentManager::getCurrentContinentSelectName()
739 TContinents::iterator it;
741 for (it = _Continents.begin(); it != _Continents.end(); ++it)
743 if (it->second == _Current)
744 return it->first;
747 static const string emptyString;
748 return emptyString;
752 void CContinentManager::reloadWeather()
754 WeatherManager.release();
755 // reload the sheet
756 std::vector<std::string> extensions;
757 extensions.push_back("weather_setup");
758 extensions.push_back("weather_function_params");
759 extensions.push_back("continent");
760 extensions.push_back("light_cycle");
762 NLMISC::IProgressCallback pc;
763 SheetMngr.loadAllSheet(pc, true, false, true, true, &extensions);
765 WeatherManager.init();
766 // Load description of light cycles for each season.
767 loadWorldLightCycle();
768 // Load global weather function parameters
769 loadWeatherFunctionParams();
774 for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
776 NLMISC::CSheetId contSI(it->second->SheetName);
777 CContinentSheet *cs = dynamic_cast<CContinentSheet *>(SheetMngr.get(contSI));
778 if (cs)
780 // update continent weather part
781 for(uint l = 0; l < EGSPD::CSeason::Invalid; ++l)
783 it->second->WeatherFunction[l].buildFromSheet(cs->WeatherFunction[l], WeatherManager);
785 // update misc params
786 it->second->FogStart = cs->Continent.FogStart;
787 it->second->FogEnd = cs->Continent.FogEnd;
788 it->second->RootFogStart = cs->Continent.RootFogStart;
789 it->second->RootFogEnd = cs->Continent.RootFogEnd;
790 it->second->LandscapeLightDay = cs->Continent.LandscapeLightDay;
791 it->second->LandscapeLightDusk = cs->Continent.LandscapeLightDusk;
792 it->second->LandscapeLightNight = cs->Continent.LandscapeLightNight;
793 it->second->EntityLightDay = cs->Continent.EntityLightDay;
794 it->second->EntityLightDusk = cs->Continent.EntityLightDusk;
795 it->second->EntityLightNight = cs->Continent.EntityLightNight;
796 it->second->RootLightDay = cs->Continent.RootLightDay;
797 it->second->RootLightDusk = cs->Continent.RootLightDusk;
798 it->second->RootLightNight = cs->Continent.RootLightNight;
803 void CContinentManager::reloadSky()
805 // reload new style sky
806 std::vector<std::string> exts;
807 CSheetManager sheetManager;
808 exts.push_back("sky");
809 exts.push_back("continent");
810 NLMISC::IProgressCallback progress;
811 sheetManager.loadAllSheet(progress, true, false, false, true, &exts);
813 const CSheetManager::TEntitySheetMap &sm = SheetMngr.getSheets();
814 for(CSheetManager::TEntitySheetMap::const_iterator it = sm.begin(); it != sm.end(); ++it)
816 if (it->second.EntitySheet)
818 CEntitySheet::TType type = it->second.EntitySheet->Type;
819 if (type == CEntitySheet::CONTINENT)
821 // find matching sheet in new sheetManager
822 const CEntitySheet *other = sheetManager.get(it->first);
823 if (other)
825 const CContinentParameters &cp = static_cast<const CContinentSheet *>(other)->Continent;
826 // find matching continent in manager
827 for(TContinents::iterator it = _Continents.begin(); it != _Continents.end(); ++it)
829 if (it->second && nlstricmp(it->second->Name, cp.Name) == 0)
831 std::copy(cp.SkySheet, cp.SkySheet + EGSPD::CSeason::Invalid, it->second->SkySheet);
832 break;
837 else if(type == CEntitySheet::SKY)
839 // find matching sheet in new sheetManager
840 const CEntitySheet *other = sheetManager.get(it->first);
841 if (other)
843 // replace data in place
844 ((CSkySheet &) *it->second.EntitySheet) = ((const CSkySheet &) *other);
849 if (_Current)
851 _Current->releaseSky();
852 _Current->initSky();
856 // ***************************************************************************
857 void CContinentManager::loadContinentLandMarks()
859 std::string dataPath = "../../client/data";
861 if (ClientCfg.UpdatePackedSheet == false)
863 readLMConts(dataPath);
865 else
867 buildLMConts("ryzom.world", "../../common/data_leveldesign/primitives", dataPath);
868 readLMConts(dataPath);
872 // ***************************************************************************
874 void CContinentManager::readLMConts(const std::string &dataPath)
876 CIFile f;
878 string sPackedFileName = CPath::lookup(LM_PACKED_FILE, false);
879 if (sPackedFileName.empty())
880 sPackedFileName = CPath::standardizePath(dataPath) + LM_PACKED_FILE;
882 if (f.open(sPackedFileName))
884 uint32 nNbCont = 0;
885 sint ver= f.serialVersion(1);
886 f.serial(nNbCont);
887 for (uint32 i = 0; i < nNbCont; ++i)
889 string sContName;
890 f.serial(sContName);
891 TContinents::iterator itCont = _Continents.find(sContName);
892 if(itCont != _Continents.end())
894 CContinent *pCont = itCont->second;
895 f.serial(pCont->Zone);
896 f.serial(pCont->ZoneCenter);
897 f.serialCont(pCont->ContLandMarks);
899 else
901 CContinent dummy;
902 f.serial(dummy.Zone);
903 f.serial(dummy.ZoneCenter);
904 f.serialCont(dummy.ContLandMarks);
905 nlwarning("continent not found : %s", sContName.c_str());
908 f.serialCont(WorldMap);
910 if (ver >= 1)
911 f.serialCont(aliasToRegionMap);
913 else
915 nlwarning("cannot load " LM_PACKED_FILE);
919 // ***************************************************************************
921 string CContinentManager::getRegionNameByAlias(uint32 i)
923 return aliasToRegionMap[i];