public static Map Parse(int id, MapName name, PackageCollection collection, List <int> attemptedIds = null) { if (attemptedIds == null) { attemptedIds = new List <int>(); } Stopwatch watch = Stopwatch.StartNew(); Map result = new Map(); result.Id = id; if (name != null) { result.Id = name.Id; result.Name = name.Name; result.StreetName = name.StreetName; } WZProperty mapEntry = collection.Resolve($"Map/Map/Map{id.ToString("D8")[0]}/{id.ToString("D8")}.img"); mapEntry = mapEntry ?? collection.Resolve($"Map/Map/Map{id.ToString("D9")[0]}/{id.ToString("D9")}.img"); mapEntry = mapEntry ?? collection.Resolve($"Map/Map/Map{result.Id.ToString("D8")[0]}/{result.Id.ToString("D8")}.img"); mapEntry = mapEntry ?? collection.Resolve($"Map/Map/Map{result.Id.ToString("D9")[0]}/{result.Id.ToString("D9")}.img"); result.mapEntry = mapEntry; int?linkedTo = mapEntry.ResolveFor <int>("info/link"); if (linkedTo.HasValue && !attemptedIds.Contains(linkedTo.Value)) { watch.Stop(); attemptedIds.Add(id); attemptedIds.Add(result.Id); return(Parse(linkedTo.Value, name, collection, attemptedIds)); } Parse(mapEntry, result); watch.Stop(); Package.Logging($"Map Parse took {watch.ElapsedMilliseconds}"); return(result); }
public static ILookup <int, MapName> GetMapNameLookup(WZProperty anyWz) { ILookup <int, MapName> lookup = null; if (anyWz.FileContainer.Collection.VersionCache.TryGetValue("mapNames", out object mapNamesCached)) { lookup = (ILookup <int, MapName>)mapNamesCached; } else { lookup = anyWz.ResolveOutlink("String/Map").Children.SelectMany(c => c.Children).ToLookup(c => int.Parse(c.NameWithoutExtension), c => MapName.Parse(c)); anyWz.FileContainer.Collection.VersionCache.AddOrUpdate("mapNameLookup", lookup, (a, b) => b); } return(lookup); }
public static IEnumerable <MapName> GetMapNames(WZProperty stringWz) { IEnumerable <MapName> names = null; if (stringWz.FileContainer.Collection.VersionCache.TryGetValue("mapNames", out object mapNamesCached)) { names = (IEnumerable <MapName>)mapNamesCached; } else { names = stringWz.Resolve("Map").Children.SelectMany(c => c.Children).Select(c => MapName.Parse(c)); stringWz.FileContainer.Collection.VersionCache.AddOrUpdate("mapNames", names, (a, b) => b); } return(names); }
private static void ParseInfo(Map result, WZProperty mapEntry, WZProperty mapInfo) { Stopwatch watch = Stopwatch.StartNew(); float top = 0; float right = 0; float bottom = 0; float left = 0; Task minimapTask = Task.Run(() => result.MiniMap = MiniMap.Parse(mapEntry.Resolve("miniMap"))); WZProperty portalProperty = mapEntry.Resolve("portal"); WZProperty[] portals = portalProperty.Children.ToArray(); result.portals = new Portal[portals.Length]; Parallel.For(0, portals.Length, i => { Portal portal = new Portal(); portal.collection = mapEntry.FileContainer.Collection; WZProperty portalData = portals[i]; foreach (WZProperty portalChildNode in portalData.Children) { if (portalChildNode.Name == "pn") { portal.PortalName = portalChildNode.ResolveForOrNull <string>(); } if (portalChildNode.Name == "tm") { portal.ToMap = portalChildNode.ResolveFor <int>() ?? int.MinValue; portal.ToMapName = MapName.GetMapNameLookup(portalChildNode)[portal.ToMap].FirstOrDefault(); } if (portalChildNode.Name == "tn") { portal.ToName = portalChildNode.ResolveForOrNull <string>(); } if (portalChildNode.Name == "pt") { portal.Type = (PortalType)(portalChildNode.ResolveFor <int>() ?? 0); } if (portalChildNode.Name == "x") { portal.x = portalChildNode.ResolveFor <int>() ?? int.MinValue; } if (portalChildNode.Name == "y") { portal.y = portalChildNode.ResolveFor <int>() ?? int.MinValue; } if (portalChildNode.Name == "image") { portal.PortalName = portalChildNode.ResolveForOrNull <string>(); } if (portalChildNode.Name == "onlyOnce") { portal.onlyOnce = portalChildNode.ResolveFor <bool>(); } } if (!portal.UnknownExit) { portal.IsStarForcePortal = (portalData.ResolveOutlinkFor <int>($"Map/Map/Map{portal.ToMap.ToString("D8")[0]}/{portal.ToMap.ToString("D8")}.img/info/barrier") ?? 0) > 0; } result.portals[i] = portal; }); Parallel.ForEach(mapInfo.Children, (child) => { if (child.Name == "link") { result.LinksTo = child.ResolveFor <int>(); } if (child.Name == "bgm") { result.BackgroundMusic = child.ResolveForOrNull <string>(); } if (child.Name == "returnMap") { result.ReturnMap = child.ResolveFor <int>(); result.IsReturnMap = result.ReturnMap == 999999999; if ((!result.IsReturnMap) ?? false && result.ReturnMap.HasValue) { result.ReturnMapName = MapName.GetMapNameLookup(mapInfo)[result.ReturnMap ?? -1].FirstOrDefault() ?? new MapName() { Id = result.ReturnMap ?? -1, Name = "Unknown", StreetName = "Unknown" } } ; } if (child.Name == "town") { result.IsTown = child.ResolveFor <bool>(); } if (child.Name == "swim") { result.IsSwim = child.ResolveFor <bool>(); } if (child.Name == "mobRate") { result.MobRate = child.ResolveFor <double>(); } if (child.Name == "mapMark") { result.MapMark = child.ResolveForOrNull <string>(); } if (child.Name == "barrier") { result.MinimumStarForce = child.ResolveFor <int>(); } if (child.Name == "barrierArc") { result.MinimumArcaneForce = child.ResolveFor <int>(); } if (child.Name == "lvLimit") { result.MinimumLevel = child.ResolveFor <int>(); } if (child.Name == "VRTop") { top = child.ResolveFor <float>() ?? 0; } if (child.Name == "VRRight") { right = child.ResolveFor <float>() ?? 0; } if (child.Name == "VRBottom") { bottom = child.ResolveFor <float>() ?? 0; } if (child.Name == "VRLeft") { left = child.ResolveFor <float>() ?? 0; } }); result.VRBounds = new RectangleF(left, top, right - left, bottom - top); minimapTask.Wait(); watch.Stop(); Package.Logging($"Map ParseInfo took {watch.ElapsedMilliseconds}"); }