// Ryzom - MMORPG Framework // 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 . #include "stdpch.h" #include "continent_manager_build.h" #include "sheet_manager.h" // Misc #include "nel/misc/types_nl.h" // std. #include #include #include // Ligo #include "nel/ligo/primitive_utils.h" // *************************************************************************** extern NLLIGO::CLigoConfig LigoConfig; // *************************************************************************** using namespace std; using namespace NLLIGO; // *************************************************************************** struct sTmpContinent { vector ContLandMarks; NLLIGO::CPrimZone Zone; NLMISC::CVector2f ZoneCenter; sTmpContinent() { ZoneCenter.x = ZoneCenter.y = 0.0f; } }; // *************************************************************************** // Convert a primitive to a landmark void primitiveToLM(CContLandMark &lm, IPrimitive *p) { lm.Zone.VPoints.clear(); string primName; p->getPropertyByName("name", primName); lm.TitleTextID = primName; CPrimVector *pvVect = p->getPrimVector(); if (pvVect != NULL) for (uint32 j = 0; j < p->getNumVector(); ++j) lm.Zone.VPoints.push_back(CPrimVector(CVector2f(pvVect[j].x,pvVect[j].y))); lm.Pos = lm.getZoneCenter(); } // *************************************************************************** bool buildLMConts(const std::string &worldSheet, const std::string &primitivesPath, const std::string &dataPath) { bool bRebuild = false; // Load the name of all continents map AllContinents; // Map with all continents. { CEntitySheet *sheet = SheetMngr.get(CSheetId(worldSheet)); if (!sheet || sheet->type() != CEntitySheet::WORLD) { nlerror("World sheet not found or bad type"); return false; } CWorldSheet *ws = (CWorldSheet *) sheet; // Copy datas from the sheet for (uint32 i = 0; i < ws->ContLocs.size(); ++i) { const SContLoc &clTmp = ws->ContLocs[i]; sTmpContinent *pCont = new sTmpContinent; AllContinents.insert(make_pair(clTmp.SelectionName, pCont)); } } // Get all region_*.primitive files vector vRegionFiles; { vector vTmp; CPath::getPathContent(primitivesPath, true, false, true, vTmp); for (uint32 i = 0; i < vTmp.size(); ++i) { string filename = CFile::getFilename(vTmp[i]); string ext = CFile::getExtension(vTmp[i]); if (strnicmp(filename.c_str(), "region_", 7) == 0) if (stricmp(ext.c_str(), "primitive") == 0) vRegionFiles.push_back(vTmp[i]); } } // If the packed file do not exists string sPackedFileName = CPath::lookup(LM_PACKED_FILE, false); if (sPackedFileName.empty()) { sPackedFileName = NLMISC::CPath::standardizePath(dataPath) + LM_PACKED_FILE; bRebuild = true; } else { // Check the date of region files with the packed file uint32 nPackedDate = CFile::getFileModificationDate(sPackedFileName); uint32 nRegionDate; for (uint32 i = 0; i < vRegionFiles.size(); ++i) { nRegionDate = CFile::getFileModificationDate(vRegionFiles[i]); if (nRegionDate > nPackedDate) bRebuild = true; } string swmf = CPath::lookup(WORLD_MAP_FILE); nRegionDate = CFile::getFileModificationDate(swmf); if (nRegionDate > nPackedDate) bRebuild = true; } if (bRebuild) { map aliasToRegionMap; nlinfo("Rebuilding landmarks for all continents"); for (uint32 nRegion = 0; nRegion < vRegionFiles.size(); ++nRegion) { CPrimitives PrimDoc; CPrimitiveContext::instance().CurrentPrimitive = &PrimDoc; if (!loadXmlPrimitiveFile(PrimDoc, vRegionFiles[nRegion], LigoConfig)) { nlwarning("cannot open %s file", vRegionFiles[nRegion].c_str()); CPrimitiveContext::instance().CurrentPrimitive = NULL; continue; } CPrimitiveContext::instance().CurrentPrimitive = NULL; // Select all nodes continent TPrimitiveClassPredicate predCont("continent"); CPrimitiveSet setCont; TPrimitiveSet vContRes; setCont.buildSet(PrimDoc.RootNode, predCont, vContRes); for (uint32 nCont = 0; nCont < vContRes.size(); ++nCont) { string contName; vContRes[nCont]->getPropertyByName("id", contName); map::iterator it = AllContinents.find(contName); if (it != AllContinents.end()) { uint32 i; sTmpContinent *pCont = it->second; CContLandMark lm; CPrimitiveSet genSet; TPrimitiveSet vGenRes; // Load the surrounding zone of the continent primitiveToLM(lm, vContRes[nCont]); if (lm.Zone.VPoints.size() != 0) pCont->Zone = lm.Zone; else nlwarning("continent %s do not contain any Zone (used for select)", contName.c_str()); pCont->ZoneCenter = CContLandMark::getZoneCenter(pCont->Zone); // Get all the regions TPrimitiveClassPredicate predReg("region"); genSet.buildSet(vContRes[nCont], predReg, vGenRes); for (i = 0; i < vGenRes.size(); ++i) { lm.Type = CContLandMark::Region; primitiveToLM(lm, vGenRes[i]); if (lm.Zone.VPoints.size() != 0) pCont->ContLandMarks.push_back(lm); else nlwarning("region %s do not contain any point", lm.TitleTextID.c_str()); // get alias and region name uint32 alias = 0; string primName, primAlias; vGenRes[i]->getPropertyByName("name", primName); TPrimitiveClassPredicate pred("alias"); IPrimitive *aliasNode = getPrimitiveChild(const_cast(vGenRes[i]), pred); if (aliasNode) { CPrimAlias *pa = dynamic_cast(aliasNode); alias = pa->getFullAlias(); } // associate alias to region aliasToRegionMap[alias]= primName; //nlinfo("aliasToRegionMap -- name = %s : %u", primName.c_str(), alias); } // Get all cities and place (lieudit) and outpost TPrimitiveClassPredicate predPlace("place"); vGenRes.clear(); genSet.buildSet(vContRes[nCont], predPlace, vGenRes); for (i = 0; i < vGenRes.size(); ++i) { string placeType, disp; vGenRes[i]->getPropertyByName("displayed", disp); if (disp != "true") continue; // Does the place is displayed vGenRes[i]->getPropertyByName("place_type", placeType); lm.Type = CContLandMark::Place; if (placeType == "Capital") lm.Type = CContLandMark::Capital; else if (placeType == "Village") lm.Type = CContLandMark::Village; else if (placeType == "Outpost") lm.Type = CContLandMark::Outpost; else if (placeType == "Locality") lm.Type = CContLandMark::Place; else if (placeType == "Street") lm.Type = CContLandMark::Street; primitiveToLM(lm, vGenRes[i]); if (lm.Zone.VPoints.size() != 0) pCont->ContLandMarks.push_back(lm); else nlwarning("place %s do not contain any point", lm.TitleTextID.c_str()); } // Get all stables TPrimitiveClassPredicate predStable("stable"); vGenRes.clear(); genSet.buildSet(vContRes[nCont], predStable, vGenRes); for (i = 0; i < vGenRes.size(); ++i) { lm.Type = CContLandMark::Stable; primitiveToLM(lm, vGenRes[i]); if (lm.Zone.VPoints.size() != 0) pCont->ContLandMarks.push_back(lm); else nlwarning("stable %s do not contain any point", lm.TitleTextID.c_str()); } } else { nlwarning("cannot find continent %s in %s", contName.c_str(), worldSheet.c_str()); } } } // Load the world map file vector WorldMap; { CPrimitives PrimDoc; CPrimitiveContext::instance().CurrentPrimitive = &PrimDoc; string swmf = CPath::lookup(WORLD_MAP_FILE); if (!loadXmlPrimitiveFile(PrimDoc, swmf, LigoConfig)) { nlwarning("cannot open %s file (%s)", WORLD_MAP_FILE, swmf.c_str()); } else { // Get all the regions CContLandMark lm; TPrimitiveClassPredicate predReg("region"); CPrimitiveSet setReg; TPrimitiveSet vRes; setReg.buildSet(PrimDoc.RootNode, predReg, vRes); for (uint32 i = 0; i < vRes.size(); ++i) { lm.Type = CContLandMark::Region; primitiveToLM(lm, vRes[i]); if (lm.Zone.VPoints.size() != 0) WorldMap.push_back(lm); else nlwarning("region %s do not contain any point", lm.TitleTextID.c_str()); } } CPrimitiveContext::instance().CurrentPrimitive = NULL; } // Ok save the file COFile f; if (f.open(sPackedFileName)) { uint32 nNbCont = 0; map::iterator it = AllContinents.begin(); while (it != AllContinents.end()) { nNbCont++; it++; } sint ver= f.serialVersion(1); f.serial(nNbCont); it = AllContinents.begin(); while (it != AllContinents.end()) { sTmpContinent *pCont = it->second; string sContName = it->first; f.serial(sContName); // save the continent shapes f.serial(pCont->Zone); f.serial(pCont->ZoneCenter); f.serialCont(pCont->ContLandMarks); it++; } f.serialCont(WorldMap); if (ver >= 1) f.serialCont(aliasToRegionMap); } } map::iterator it = AllContinents.begin(); while (it != AllContinents.end()) { sTmpContinent *pCont = it->second; delete pCont; it++; } return true; }