1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
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>
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/>.
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"
35 #include "nel/3d/u_landscape.h"
37 #include "nel/georges/u_form.h"
38 #include "nel/georges/u_form_elm.h"
39 #include "nel/georges/u_form_loader.h"
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"
49 #include "weather_manager_client.h"
50 #include "interface_v3/interface_manager.h"
51 #include "interface_v3/group_map.h"
55 #include "continent_manager_build.h"
59 using namespace NLPACS
;
60 using namespace NLMISC
;
63 using namespace NLGEORGES
;
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
;
85 H_AUTO_DECL ( RZ_Client_Continent_Mngr_Update_Streamable
)
90 //-----------------------------------------------
91 // CContinentManager :
93 //-----------------------------------------------
94 CContinentManager::CContinentManager()
98 }// CContinentManager //
102 void CContinentManager::reset()
104 // stop the background sound
106 SoundMngr
->stopBackgroundSound();
108 // Unselect continent
110 _Current
->unselect();
112 // Shared data must be NULL now
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
128 _Current
->unselect();
133 // NB: landscape zones are deleted in USCene::deleteLandscape()
135 // clear continents DB
136 for(TContinents::iterator it
= _Continents
.begin(); it
!= _Continents
.end(); ++it
)
146 //-----------------------------------------------
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()
175 CEntitySheet
*sheet
= SheetMngr
.get(CSheetId("ryzom.world"));
177 if (!sheet
|| sheet
->type() != CEntitySheet::WORLD
)
179 nlerror("World sheet not found or bad type");
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
);
200 if (sheet
->type() == CEntitySheet::CONTINENT
)
202 CContinent
*pCont
= new CContinent
;
203 pCont
->SheetName
= continentSheetName
;
204 _Continents
.insert(make_pair(clTmp
.SelectionName
, pCont
));
208 nlwarning("Bad type for continent form %s.", continentSheetName
.c_str());
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())
229 loadContinentLandMarks();
231 // \todo GUIGUI : Do it better when there will be "ecosystem"/Wind/etc.
232 // Initialize the Landscape Vegetable.
233 if(ClientCfg
.MicroVeget
)
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
);
250 //-----------------------------------------------
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());
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
306 nlassert (GR
== NULL
);
307 nlassert (RB
== NULL
);
308 nlassert (PACS
== NULL
);
309 nlassert (IGCallbacks
== NULL
);
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.
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
340 SoundMngr
->stopBackgroundSound();
345 // Teleport in the hibernated continent
346 _Current
->select(pos
, progress
, false, true, CurrSeason
);
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
)
363 SoundMngr
->loadContinent(name
, pos
);
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"));
377 pMap
->setMap(pWS
->Maps
[i
].Name
);
378 pMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:respawn_map:content:map_content:actual_map"));
380 pMap
->setMap(pWS
->Maps
[i
].Name
);
388 //-----------------------------------------------
390 // Select closest continent from a vector.
391 //-----------------------------------------------
392 void CContinentManager::select(const CVectorD
&pos
, NLMISC::IProgressCallback
&progress
)
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
);
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());
426 nlwarning("cannot select any continent at pos (%f, %f)", fPos
.x
, fPos
.y
);
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.
440 //nlassertex(0, ("can't select any continent"));
445 bool CContinentManager::isLoadingforced(const NLMISC::CVector
&playerPos
) const
450 return _Current
->isLoadingforced(playerPos
);
453 void CContinentManager::updateStreamable(const NLMISC::CVector
&playerPos
)
455 H_AUTO_USE ( RZ_Client_Continent_Mngr_Update_Streamable
)
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
)
466 _Current
->forceUpdateStreamable(playerPos
, progress
);
472 void CContinentManager::removeVillages()
474 for(TContinents::iterator it
= _Continents
.begin(); it
!= _Continents
.end(); ++it
)
477 it
->second
->removeVillages();
481 void CContinentManager::getFogState(TFogType fogType
, float dayNight
, float duskRatio
, CLightCycleManager::TLightState lightState
, const NLMISC::CVectorD
&pos
, CFogState
&result
)
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())
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"/>
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')
530 xmlSetProp(lmNode
, (const xmlChar
*)"title", (const xmlChar
*)title
.c_str());
536 void CContinentManager::readFrom(xmlNodePtr node
)
540 // <landmarks continent="bagne" type="user">
541 // <landmark type="0" x="0" y="0" title="landmark title" />
544 std::string continent
;
545 prop
= xmlGetProp(node
, (xmlChar
*)"continent");
548 nlwarning("Ignore landmarks group 'continent' attribute.");
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());
561 prop
= xmlGetProp(node
, (xmlChar
*)"type");
564 nlwarning("Ignore landmarks group without 'type' attribute.");
567 lmtype
= toLowerAscii((const char*)prop
);
568 if (lmtype
!= "user")
570 nlwarning("Ignore landmarks group with type '%s', expected 'user'.", lmtype
.c_str());
574 node
= node
->children
;
577 if (stricmp((char*)node
->name
, "landmark") != 0)
579 nlwarning("Ignore invalid node '%s' under landmarks group", (const char*)node
->name
);
588 prop
= xmlGetProp(node
, (xmlChar
*)"type");
590 fromString((const char*)prop
, lm
.Type
);
592 nlwarning("Using default value for landmark type");
594 prop
= xmlGetProp(node
, (xmlChar
*)"x");
597 fromString((const char*)prop
, lm
.Pos
.x
);
601 nlwarning("Landmark missing 'x' attribute");
605 prop
= xmlGetProp(node
, (xmlChar
*)"y");
608 fromString((const char*)prop
, lm
.Pos
.y
);
612 nlwarning("Landmark missing 'y' attribute");
616 prop
= xmlGetProp(node
, (xmlChar
*)"title");
619 lm
.Title
.fromUtf8((const char*)prop
);
623 nlwarning("Landmark missing 'title' attribute");
629 // before adding, check for duplicate
630 // duplicates might be read from .icfg before .xml is read
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)
646 itContinent
->second
->UserLandMarks
.push_back(lm
);
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());
655 nlwarning("Landmark not added");
662 uint32
CContinentManager::serialUserLandMarks(NLMISC::IStream
&f
)
664 uint32 totalLandmarks
= 0;
669 uint32 numCont
= (uint32
)_Continents
.size();
671 for(TContinents::iterator it
= _Continents
.begin(); it
!= _Continents
.end(); ++it
)
673 std::string name
= it
->first
;
677 f
.serialCont(it
->second
->UserLandMarks
);
678 totalLandmarks
+= it
->second
->UserLandMarks
.size();
682 std::vector
<CUserLandMark
> dummy
;
691 for(uint k
= 0; k
< numCont
; ++k
)
693 std::string 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();
703 std::vector
<CUserLandMark
> 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"));
720 pMap
->updateUserLandMarks();
724 //-----------------------------------------------
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
)
747 static const string emptyString
;
752 void CContinentManager::reloadWeather()
754 WeatherManager
.release();
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
));
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
);
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
);
837 else if(type
== CEntitySheet::SKY
)
839 // find matching sheet in new sheetManager
840 const CEntitySheet
*other
= sheetManager
.get(it
->first
);
843 // replace data in place
844 ((CSkySheet
&) *it
->second
.EntitySheet
) = ((const CSkySheet
&) *other
);
851 _Current
->releaseSky();
856 // ***************************************************************************
857 void CContinentManager::loadContinentLandMarks()
859 std::string dataPath
= "../../client/data";
861 if (ClientCfg
.UpdatePackedSheet
== false)
863 readLMConts(dataPath
);
867 buildLMConts("ryzom.world", "../../common/data_leveldesign/primitives", dataPath
);
868 readLMConts(dataPath
);
872 // ***************************************************************************
874 void CContinentManager::readLMConts(const std::string
&dataPath
)
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
))
885 sint ver
= f
.serialVersion(1);
887 for (uint32 i
= 0; i
< nNbCont
; ++i
)
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
);
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
);
911 f
.serialCont(aliasToRegionMap
);
915 nlwarning("cannot load " LM_PACKED_FILE
);
919 // ***************************************************************************
921 string
CContinentManager::getRegionNameByAlias(uint32 i
)
923 return aliasToRegionMap
[i
];