/// <summary> /// Loads a Track definition file and constructs a Track object. /// </summary> /// <param name="path"></param> /// <returns></returns> public static async Task <Track> LoadAsync(string defpath, string assetpath, IGraphicsFactory f) { FileIniDataParser file = new FileIniDataParser(); file.Parser.Configuration.CommentString = "//"; IniData inidata = file.ReadFile(defpath); if (inidata == null) { return(null); } IniGetter ini = new IniGetter(inidata); string bkgpath = ini.GetString("track", "background"); string maskpath = ini.GetString("track", "mask"); Dictionary <Color, int> regionColors = new Dictionary <Color, int>(); int regions = ini.GetInt("track", "regions"); for (int i = 0; i < regions; ++i) { string secname = string.Format("region{0}", i); if (!inidata.Sections.ContainsSection(secname)) { continue; } Color col = Color.FromArgb(255, (byte)ini.GetInt(secname, "color_r"), (byte)ini.GetInt(secname, "color_g"), (byte)ini.GetInt(secname, "color_b")); regionColors[col] = i; } IImage background = await f.LoadImageAsync(assetpath + bkgpath); IBitmap mask = await f.LoadBitmapAsync(assetpath + maskpath); /* * // TODO: find out whether engine provides faster solution * int[,] regionMap = new int[mask.Width, mask.Height]; * for (int x = 0; x < mask.Width; ++x) * { * // NOTE: since MonoAGS has Y axis pointing up, we need to invert the lookup array's Y index * for (int y = 0, mapy = mask.Height - 1; y < mask.Height; ++y, --mapy) * { * Color col = mask.GetPixel(x, y); * int index = 0; * regionColors.TryGetValue(col, out index); * regionMap[x, mapy] = index; * } * } * * return new Track(background, regionColors.Count, regionMap); */ Size trackSize = mask != null ? new Size(mask.Width, mask.Height) : new Size(); List <RaceNode> checkpoints = loadCheckpoints(assetpath, trackSize); TrackAIData aiData = await loadAIData(assetpath, trackSize, f); return(new Track(background, regionColors.Count, mask, regionColors, checkpoints, aiData)); }
private static async Task <TrackAIData> loadAIData(string assetpath, Size trackSize, IGraphicsFactory f) { TrackAIData data = new TrackAIData(); await loadAIRegionsData(data, assetpath, f); loadAIPathsData(data, assetpath, trackSize); return(data); }
// TODO: separate loading for data edited by MonoAGS version private static void loadAIPathsData(TrackAIData data, string assetpath, Size trackSize) { Stream s = File.OpenRead(assetpath + "aipaths.dat"); if (s == null) { return; } List <AIPathNode> paths = new List <AIPathNode>(); AGSFileReader f = new AGSFileReader(s); int firstNodeIndex = f.ReadInt(); int lastNodeIndex = f.ReadInt(); int n = firstNodeIndex; AIPathNode last = null; do { int x = f.ReadInt(); int y = f.ReadInt(); // NOTE: since MonoAGS has Y axis pointing up, we need to invert one read from AGS file y = trackSize.Height - y; AIPathNode node = new AIPathNode(); node.pt = new Vector2(x, y); node.radius = f.ReadInt(); node.threshold = f.ReadInt(); node.speed = f.ReadInt(); int p = f.ReadInt(); n = f.ReadInt(); if (last != null) { node.prev = last; last.next = node; } last = node; paths.Add(node); }while (n != firstNodeIndex); // Bind last node to the first one if (last != null) { last.next = paths[0]; paths[0].prev = last; } data.AIPathNodes = paths; }
private static async Task loadAIRegionsData(TrackAIData data, string assetpath, IGraphicsFactory f) { IBitmap regionMask = await f.LoadBitmapAsync(assetpath + "airegions.bmp"); if (regionMask == null) { return; } FileIniDataParser file = new FileIniDataParser(); file.Parser.Configuration.CommentString = "//"; IniData inidata = file.ReadFile(assetpath + "airegions.ini"); if (inidata == null) { return; } IniGetter ini = new IniGetter(inidata); Dictionary <Color, float> regionAngles = new Dictionary <Color, float>(); int regions = ini.GetInt("ai", "regions"); for (int i = 0; i < regions; ++i) { string secname = string.Format("region{0}", i); if (!inidata.Sections.ContainsSection(secname)) { continue; } Color col = Color.FromArgb(255, (byte)ini.GetInt(secname, "color_r"), (byte)ini.GetInt(secname, "color_g"), (byte)ini.GetInt(secname, "color_b")); regionAngles[col] = MathUtils.DegreesToRadians(ini.GetFloat(secname, "angle")); } data.AIRegionMask = regionMask; data.AIRegionAngles = regionAngles; return; }