1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
19 #include "continent_manager_build.h"
20 #include "sheet_manager.h"
23 #include "nel/misc/types_nl.h"
31 #include "nel/ligo/primitive_utils.h"
33 // ***************************************************************************
35 extern NLLIGO::CLigoConfig LigoConfig
;
37 // ***************************************************************************
40 using namespace NLMISC
;
41 using namespace NLLIGO
;
43 // ***************************************************************************
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();
60 p
->getPropertyByName("name", primName
);
61 lm
.TitleTextID
= primName
;
62 CPrimVector
*pvVect
= p
->getPrimVector();
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");
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
;
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
;
124 // Check the date of region files with the packed file
125 uint32 nPackedDate
= CFile::getFileModificationDate(sPackedFileName
);
127 for (uint32 i
= 0; i
< vRegionFiles
.size(); ++i
)
129 nRegionDate
= CFile::getFileModificationDate(vRegionFiles
[i
]);
130 if (nRegionDate
> nPackedDate
)
134 string swmf
= CPath::lookup(WORLD_MAP_FILE
);
135 nRegionDate
= CFile::getFileModificationDate(swmf
);
136 if (nRegionDate
> nPackedDate
)
142 map
<uint32
, string
> aliasToRegionMap
;
144 nlinfo("Rebuilding landmarks for all continents");
145 for (uint32 nRegion
= 0; nRegion
< vRegionFiles
.size(); ++nRegion
)
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
;
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
)
166 vContRes
[nCont
]->getPropertyByName("id", contName
);
167 map
<string
,sTmpContinent
*>::iterator it
= AllContinents
.find(contName
);
168 if (it
!= AllContinents
.end())
171 sTmpContinent
*pCont
= it
->second
;
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
;
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
);
194 nlwarning("region %s do not contain any point", lm
.TitleTextID
.c_str());
197 // get alias and region name
199 string primName
, primAlias
;
200 vGenRes
[i
]->getPropertyByName("name", primName
);
202 TPrimitiveClassPredicate
pred("alias");
203 IPrimitive
*aliasNode
= getPrimitiveChild(const_cast<IPrimitive
*>(vGenRes
[i
]), pred
);
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");
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
);
238 nlwarning("place %s do not contain any point", lm
.TitleTextID
.c_str());
242 TPrimitiveClassPredicate
predStable("stable");
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
);
252 nlwarning("stable %s do not contain any point", lm
.TitleTextID
.c_str());
257 nlwarning("cannot find continent %s in %s", contName
.c_str(), worldSheet
.c_str());
261 // Load the world map file
262 vector
<CContLandMark
> WorldMap
;
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());
274 // Get all the regions
276 TPrimitiveClassPredicate
predReg("region");
277 CPrimitiveSet
<TPrimitiveClassPredicate
> setReg
;
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
);
287 nlwarning("region %s do not contain any point", lm
.TitleTextID
.c_str());
290 CPrimitiveContext::instance().CurrentPrimitive
= NULL
;
295 if (f
.open(sPackedFileName
))
298 map
<string
,sTmpContinent
*>::iterator it
= AllContinents
.begin();
299 while (it
!= AllContinents
.end())
304 sint ver
= f
.serialVersion(1);
306 it
= AllContinents
.begin();
307 while (it
!= AllContinents
.end())
309 sTmpContinent
*pCont
= it
->second
;
310 string sContName
= it
->first
;
312 // save the continent shapes
313 f
.serial(pCont
->Zone
);
314 f
.serial(pCont
->ZoneCenter
);
315 f
.serialCont(pCont
->ContLandMarks
);
318 f
.serialCont(WorldMap
);
320 f
.serialCont(aliasToRegionMap
);
324 map
<string
,sTmpContinent
*>::iterator it
= AllContinents
.begin();
325 while (it
!= AllContinents
.end())
327 sTmpContinent
*pCont
= it
->second
;