Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / continent_manager_build.cpp
blobba212400943cac3a8c82c40759d082704ec1180e
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "stdpch.h"
19 #include "continent_manager_build.h"
20 #include "sheet_manager.h"
22 // Misc
23 #include "nel/misc/types_nl.h"
25 // std.
26 #include <vector>
27 #include <map>
28 #include <string>
30 // Ligo
31 #include "nel/ligo/primitive_utils.h"
33 // ***************************************************************************
35 extern NLLIGO::CLigoConfig LigoConfig;
37 // ***************************************************************************
39 using namespace std;
40 using namespace NLMISC;
41 using namespace NLLIGO;
43 // ***************************************************************************
45 struct sTmpContinent
47 vector<CContLandMark> ContLandMarks;
48 NLLIGO::CPrimZone Zone;
49 NLMISC::CVector2f ZoneCenter;
51 sTmpContinent() { ZoneCenter.x = ZoneCenter.y = 0.0f; }
54 // ***************************************************************************
55 // Convert a primitive to a landmark
56 void primitiveToLM(CContLandMark &lm, IPrimitive *p)
58 lm.Zone.VPoints.clear();
59 string primName;
60 p->getPropertyByName("name", primName);
61 lm.TitleTextID = primName;
62 CPrimVector *pvVect = p->getPrimVector();
63 if (pvVect != NULL)
64 for (uint32 j = 0; j < p->getNumVector(); ++j)
65 lm.Zone.VPoints.push_back(CPrimVector(CVector2f(pvVect[j].x,pvVect[j].y)));
67 lm.Pos = lm.getZoneCenter();
70 // ***************************************************************************
71 bool buildLMConts(const std::string &worldSheet, const std::string &primitivesPath, const std::string &dataPath)
73 bool bRebuild = false;
75 // Load the name of all continents
77 map<string, sTmpContinent*> AllContinents; // Map with all continents.
79 CEntitySheet *sheet = SheetMngr.get(CSheetId(worldSheet));
81 if (!sheet || sheet->type() != CEntitySheet::WORLD)
83 nlerror("World sheet not found or bad type");
84 return false;
87 CWorldSheet *ws = (CWorldSheet *) sheet;
89 // Copy datas from the sheet
90 for (uint32 i = 0; i < ws->ContLocs.size(); ++i)
92 const SContLoc &clTmp = ws->ContLocs[i];
93 sTmpContinent *pCont = new sTmpContinent;
94 AllContinents.insert(make_pair(clTmp.SelectionName, pCont));
99 // Get all region_*.primitive files
101 vector<string> vRegionFiles;
103 vector<string> vTmp;
104 CPath::getPathContent(primitivesPath, true, false, true, vTmp);
105 for (uint32 i = 0; i < vTmp.size(); ++i)
107 string filename = CFile::getFilename(vTmp[i]);
108 string ext = CFile::getExtension(vTmp[i]);
109 if (strnicmp(filename.c_str(), "region_", 7) == 0)
110 if (stricmp(ext.c_str(), "primitive") == 0)
111 vRegionFiles.push_back(vTmp[i]);
115 // If the packed file do not exists
116 string sPackedFileName = CPath::lookup(LM_PACKED_FILE, false);
117 if (sPackedFileName.empty())
119 sPackedFileName = NLMISC::CPath::standardizePath(dataPath) + LM_PACKED_FILE;
120 bRebuild = true;
122 else
124 // Check the date of region files with the packed file
125 uint32 nPackedDate = CFile::getFileModificationDate(sPackedFileName);
126 uint32 nRegionDate;
127 for (uint32 i = 0; i < vRegionFiles.size(); ++i)
129 nRegionDate = CFile::getFileModificationDate(vRegionFiles[i]);
130 if (nRegionDate > nPackedDate)
131 bRebuild = true;
134 string swmf = CPath::lookup(WORLD_MAP_FILE);
135 nRegionDate = CFile::getFileModificationDate(swmf);
136 if (nRegionDate > nPackedDate)
137 bRebuild = true;
140 if (bRebuild)
142 map<uint32, string> aliasToRegionMap;
144 nlinfo("Rebuilding landmarks for all continents");
145 for (uint32 nRegion = 0; nRegion < vRegionFiles.size(); ++nRegion)
147 CPrimitives PrimDoc;
148 CPrimitiveContext::instance().CurrentPrimitive = &PrimDoc;
149 if (!loadXmlPrimitiveFile(PrimDoc, vRegionFiles[nRegion], LigoConfig))
151 nlwarning("cannot open %s file", vRegionFiles[nRegion].c_str());
152 CPrimitiveContext::instance().CurrentPrimitive = NULL;
153 continue;
156 CPrimitiveContext::instance().CurrentPrimitive = NULL;
158 // Select all nodes continent
159 TPrimitiveClassPredicate predCont("continent");
160 CPrimitiveSet<TPrimitiveClassPredicate> setCont;
161 TPrimitiveSet vContRes;
162 setCont.buildSet(PrimDoc.RootNode, predCont, vContRes);
163 for (uint32 nCont = 0; nCont < vContRes.size(); ++nCont)
165 string contName;
166 vContRes[nCont]->getPropertyByName("id", contName);
167 map<string,sTmpContinent*>::iterator it = AllContinents.find(contName);
168 if (it != AllContinents.end())
170 uint32 i;
171 sTmpContinent *pCont = it->second;
172 CContLandMark lm;
173 CPrimitiveSet<TPrimitiveClassPredicate> genSet;
174 TPrimitiveSet vGenRes;
176 // Load the surrounding zone of the continent
177 primitiveToLM(lm, vContRes[nCont]);
178 if (lm.Zone.VPoints.size() != 0)
179 pCont->Zone = lm.Zone;
180 else
181 nlwarning("continent %s do not contain any Zone (used for select)", contName.c_str());
182 pCont->ZoneCenter = CContLandMark::getZoneCenter(pCont->Zone);
184 // Get all the regions
185 TPrimitiveClassPredicate predReg("region");
186 genSet.buildSet(vContRes[nCont], predReg, vGenRes);
187 for (i = 0; i < vGenRes.size(); ++i)
189 lm.Type = CContLandMark::Region;
190 primitiveToLM(lm, vGenRes[i]);
191 if (lm.Zone.VPoints.size() != 0)
192 pCont->ContLandMarks.push_back(lm);
193 else
194 nlwarning("region %s do not contain any point", lm.TitleTextID.c_str());
197 // get alias and region name
198 uint32 alias = 0;
199 string primName, primAlias;
200 vGenRes[i]->getPropertyByName("name", primName);
202 TPrimitiveClassPredicate pred("alias");
203 IPrimitive *aliasNode = getPrimitiveChild(const_cast<IPrimitive*>(vGenRes[i]), pred);
204 if (aliasNode)
206 CPrimAlias *pa = dynamic_cast<CPrimAlias*>(aliasNode);
207 alias = pa->getFullAlias();
210 // associate alias to region
211 aliasToRegionMap[alias]= primName;
212 //nlinfo("aliasToRegionMap -- name = %s : %u", primName.c_str(), alias);
215 // Get all cities and place (lieudit) and outpost
216 TPrimitiveClassPredicate predPlace("place");
217 vGenRes.clear();
218 genSet.buildSet(vContRes[nCont], predPlace, vGenRes);
219 for (i = 0; i < vGenRes.size(); ++i)
221 string placeType, disp;
222 vGenRes[i]->getPropertyByName("displayed", disp);
223 if (disp != "true") continue; // Does the place is displayed
225 vGenRes[i]->getPropertyByName("place_type", placeType);
227 lm.Type = CContLandMark::Place;
228 if (placeType == "Capital") lm.Type = CContLandMark::Capital;
229 else if (placeType == "Village") lm.Type = CContLandMark::Village;
230 else if (placeType == "Outpost") lm.Type = CContLandMark::Outpost;
231 else if (placeType == "Locality") lm.Type = CContLandMark::Place;
232 else if (placeType == "Street") lm.Type = CContLandMark::Street;
234 primitiveToLM(lm, vGenRes[i]);
235 if (lm.Zone.VPoints.size() != 0)
236 pCont->ContLandMarks.push_back(lm);
237 else
238 nlwarning("place %s do not contain any point", lm.TitleTextID.c_str());
241 // Get all stables
242 TPrimitiveClassPredicate predStable("stable");
243 vGenRes.clear();
244 genSet.buildSet(vContRes[nCont], predStable, vGenRes);
245 for (i = 0; i < vGenRes.size(); ++i)
247 lm.Type = CContLandMark::Stable;
248 primitiveToLM(lm, vGenRes[i]);
249 if (lm.Zone.VPoints.size() != 0)
250 pCont->ContLandMarks.push_back(lm);
251 else
252 nlwarning("stable %s do not contain any point", lm.TitleTextID.c_str());
255 else
257 nlwarning("cannot find continent %s in %s", contName.c_str(), worldSheet.c_str());
261 // Load the world map file
262 vector<CContLandMark> WorldMap;
264 CPrimitives PrimDoc;
265 CPrimitiveContext::instance().CurrentPrimitive = &PrimDoc;
267 string swmf = CPath::lookup(WORLD_MAP_FILE);
268 if (!loadXmlPrimitiveFile(PrimDoc, swmf, LigoConfig))
270 nlwarning("cannot open %s file (%s)", WORLD_MAP_FILE, swmf.c_str());
272 else
274 // Get all the regions
275 CContLandMark lm;
276 TPrimitiveClassPredicate predReg("region");
277 CPrimitiveSet<TPrimitiveClassPredicate> setReg;
278 TPrimitiveSet vRes;
279 setReg.buildSet(PrimDoc.RootNode, predReg, vRes);
280 for (uint32 i = 0; i < vRes.size(); ++i)
282 lm.Type = CContLandMark::Region;
283 primitiveToLM(lm, vRes[i]);
284 if (lm.Zone.VPoints.size() != 0)
285 WorldMap.push_back(lm);
286 else
287 nlwarning("region %s do not contain any point", lm.TitleTextID.c_str());
290 CPrimitiveContext::instance().CurrentPrimitive = NULL;
293 // Ok save the file
294 COFile f;
295 if (f.open(sPackedFileName))
297 uint32 nNbCont = 0;
298 map<string,sTmpContinent*>::iterator it = AllContinents.begin();
299 while (it != AllContinents.end())
301 nNbCont++;
302 it++;
304 sint ver= f.serialVersion(1);
305 f.serial(nNbCont);
306 it = AllContinents.begin();
307 while (it != AllContinents.end())
309 sTmpContinent *pCont = it->second;
310 string sContName = it->first;
311 f.serial(sContName);
312 // save the continent shapes
313 f.serial(pCont->Zone);
314 f.serial(pCont->ZoneCenter);
315 f.serialCont(pCont->ContLandMarks);
316 it++;
318 f.serialCont(WorldMap);
319 if (ver >= 1)
320 f.serialCont(aliasToRegionMap);
324 map<string,sTmpContinent*>::iterator it = AllContinents.begin();
325 while (it != AllContinents.end())
327 sTmpContinent *pCont = it->second;
328 delete pCont;
329 it++;
332 return true;