static void Main(string[] args) { var maps = new List <(string name, string mapNumber, bool isCave)> { ("Solsar", "01", false), ("Hossin", "02", false), ("Cyssor", "03", false), ("Ishundar", "04", false), ("Forseral", "05", false), ("Ceryshen", "06", false), ("Esamir", "07", false), ("Oshur Prime", "08", false), ("Searhus", "09", false), ("Amerish", "10", false), ("HOME1 (NEW CONGLOMORATE SANCTUARY)", "11", false), ("HOME2 (TERRAN REPUBLIC SANCTUARY)", "12", false), ("HOME3 (VANU SOVREIGNTY SANCTUARY)", "13", false), ("Nexus", "96", false), ("Desolation", "97", false), ("Ascension", "98", false), ("Extinction", "99", false), ("Supai", "01", true), ("Hunhau", "02", true), ("Adlivun", "03", true), ("Byblos", "04", true), ("Annwn", "05", true), ("Drugaskan", "06", true) }; // Load all *.ubr files Parallel.ForEach(Directory.GetFiles(_planetsideModReadyFolder, "*.ubr", SearchOption.AllDirectories), file => { _ubrData.TryAdd(file, UBRReader.GetUbrData(file)); }); foreach (var map in maps) { var identifiableObjects = new List <PlanetSideObject>(); var(mapName, mapNumber, isCave) = map; Console.WriteLine($"Processing map {mapNumber} - {mapName}"); int id = 0; if (!isCave) { // Read the contents_map mpo file, and the associated objects_map lst file var mpoData = MPOReader.ReadMPOFile(_planetsideModReadyFolder, mapNumber); foreach (var entry in mpoData) { ProcessObject(identifiableObjects, entry, ref id, mapId: mpoData.IndexOf(entry) + 1, isTopLevel: true); } } // Read groundcover data var groundCoverData = LSTReader.ReadGroundCoverLST(_planetsideModReadyFolder, mapNumber, isCave); foreach (var line in groundCoverData) { var mapObj = LstObjectToMapObject(line); ProcessObject( identifiableObjects, mapObj, ref id, mapId: line.Id, isTopLevel: !mapObj.HasBangPrefix ); } // Battle islands for some reason have an X/Y offset applied to all coordinates in game_objects.adb.lst. Thus, we need to account for that. //19318:add_property map99 mapOffsetX 1024.0 //19319:add_property map99 mapOffsetY 1024.0 if (new List <string>() { "96", "97", "98", "99" }.Contains(mapNumber)) { for (int i = 0; i < identifiableObjects.Count(); i++) { identifiableObjects[i].AbsX += 1024; identifiableObjects[i].AbsY += 1024; } } // bfr_building doesn't actually have a GUID itself - the door does which is a sub-object in the ubr file. // Remove it from the list before assigning GUIDs identifiableObjects.RemoveAll(x => x.ObjectType == "bfr_building"); // Assign GUIDs to loaded map objects GUIDAssigner.AssignGUIDs(identifiableObjects); // Sanity checking to make sure the amount of objects we've got matches a list of expected object counts SanityChecker.CheckObjectCounts(identifiableObjects, mapName, mapNumber); // Sanity checking that assigned GUIDs match expected GUID ranges SanityChecker.CheckGuidRanges(identifiableObjects, mapName, mapNumber); RemoveUnusedLluSockets(identifiableObjects, mapNumber); // Export to json file var json = JsonConvert.SerializeObject(identifiableObjects.OrderBy(x => x.GUID), Formatting.Indented); var filename = !isCave ? $"map{mapNumber}.json" : $"ugd{mapNumber}.json"; File.WriteAllText(filename, json); if (isCave) { // Read zipline data, reformat and export as json var zplData = ZplReader.ReadZplFile(_planetsideModReadyFolder, mapNumber); File.WriteAllText($"zpl_ugd{mapNumber}.json", JsonConvert.SerializeObject(zplData, Formatting.Indented)); } } Console.WriteLine("Done"); Console.ReadKey(); }