public void LoadMap01() { using (var wad = new Wad(WadPath.Doom2)) { var flats = new FlatLookup(wad, true); var textures = new TextureLookup(wad, true); var map = wad.GetLumpNumber("MAP01"); var vertices = Vertex.FromWad(wad, map + 4); var sectors = Sector.FromWad(wad, map + 8, flats); var sides = SideDef.FromWad(wad, map + 3, textures, sectors); var lines = LineDef.FromWad(wad, map + 2, vertices, sides); var segs = Seg.FromWad(wad, map + 5, vertices, lines); var subsectors = Subsector.FromWad(wad, map + 6, segs); Assert.AreEqual(194, subsectors.Length); Assert.AreEqual(4, subsectors[0].SegCount); for (var i = 0; i < 4; i++) { Assert.IsTrue(segs[subsectors[0].FirstSeg + i] == segs[i]); } Assert.AreEqual(4, subsectors[57].SegCount); for (var i = 0; i < 4; i++) { Assert.IsTrue(segs[subsectors[57].FirstSeg + i] == segs[179 + i]); } Assert.AreEqual(4, subsectors[193].SegCount); for (var i = 0; i < 4; i++) { Assert.IsTrue(segs[subsectors[193].FirstSeg + i] == segs[597 + i]); } } }
public void CreateSubsectorAramis() { TravellerMap map = new TravellerMap("Aramis Subsector"); SpinwardMarchesMap spinwardmarches = new SpinwardMarchesMap(map); Subsector aramis = spinwardmarches.CreateAramisSubsector(); }
public void LoadE1M1() { using (var wad = new Wad(WadPath.Doom1)) { var flats = new FlatLookup(wad, true); var textures = new TextureLookup(wad, true); var map = wad.GetLumpNumber("E1M1"); var vertices = Vertex.FromWad(wad, map + 4); var sectors = Sector.FromWad(wad, map + 8, flats); var sides = SideDef.FromWad(wad, map + 3, textures, sectors); var lines = LineDef.FromWad(wad, map + 2, vertices, sides); var segs = Seg.FromWad(wad, map + 5, vertices, lines); var subsectors = Subsector.FromWad(wad, map + 6, segs); Assert.AreEqual(239, subsectors.Length); Assert.AreEqual(8, subsectors[0].SegCount); for (var i = 0; i < 8; i++) { Assert.IsTrue(segs[subsectors[0].FirstSeg + i] == segs[0 + i]); } Assert.AreEqual(1, subsectors[54].SegCount); for (var i = 0; i < 1; i++) { Assert.IsTrue(segs[subsectors[54].FirstSeg + i] == segs[181 + i]); } Assert.AreEqual(2, subsectors[238].SegCount); for (var i = 0; i < 2; i++) { Assert.IsTrue(segs[subsectors[238].FirstSeg + i] == segs[745 + i]); } } }
public Subsector ParseSubsector(TravellerMap map, string name, TextReader reader) { Subsector subsector = new Subsector(name); map.Add <Subsector>(subsector); WorldSECParser worldParser = new WorldSECParser(); string line = null; //int linecount = 0; bool startWorlds = false; while ((line = reader.ReadLine()) != null) { //linecount++; //if (linecount < 13) //continue; if (string.IsNullOrEmpty(line)) { continue; } else if (!startWorlds && line.StartsWith("....+")) { startWorlds = true; continue; } World world = worldParser.ParseWorld(map, line); subsector.Add(world); } return(subsector); }
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if (e.Property == SubsectorProperty) { this.Modelo.Subsector = this.Subsector; } base.OnPropertyChanged(e); }
public Sector CreateSector() { Sector sector = new Sector("Spinward Marches"); Map.Add <Sector>(sector); Subsector sub = CreateSubsector("Cronor"); sector.Add("A", sub); sub = CreateSubsector("Jewell"); sector.Add("B", sub); sub = CreateSubsector("Regina"); sector.Add("C", sub); sub = CreateSubsector("Aramis"); sector.Add("D", sub); sub = CreateSubsector("Querion"); sector.Add("E", sub); sub = CreateSubsector("Vilis"); sector.Add("F", sub); sub = CreateSubsector("Lanth"); sector.Add("G", sub); sub = CreateSubsector("Rhylanor"); sector.Add("H", sub); sub = CreateSubsector("Darrian"); sector.Add("I", sub); sub = CreateSubsector("Sword Worlds"); sector.Add("J", sub); sub = CreateSubsector("Lunion"); sector.Add("K", sub); sub = CreateSubsector("Mora"); sector.Add("L", sub); sub = CreateSubsector("Five Sisters"); sector.Add("M", sub); sub = CreateSubsector("District 268"); sector.Add("N", sub); sub = CreateSubsector("Glisten"); sector.Add("O", sub); sub = CreateSubsector("Trin's Veil"); sector.Add("P", sub); return(sector); }
public Subsector CreateCronorSubsector() { string text = TestingUtilities.ReadResource("Files", "Cronor.sec"); StringReader reader = new StringReader(text); SubsectorSECFileParser parser = new SubsectorSECFileParser(); Subsector aramis = parser.ParseSubsector(Map, "Cronor", reader); return(aramis); }
public Subsector CreateSubsector(string name) { string text = TestingUtilities.ReadResource("Files", $"{name}.sec"); StringReader reader = new StringReader(text); SubsectorSECFileParser parser = new SubsectorSECFileParser(); Subsector subsector = parser.ParseSubsector(Map, name, reader); return(subsector); }
public SubsectorResult(Sector sector, Subsector subsector) { if (sector == null) { throw new ArgumentNullException(nameof(sector)); } if (subsector == null) { throw new ArgumentNullException(nameof(subsector)); } SectorLocation = sector.Location; Index = subsector.Index[0]; }
public void Resolve(SectorMap.Milieu sectorMap, out Sector sector, out Subsector subsector) { if (sectorMap == null) { throw new ArgumentNullException(nameof(sectorMap)); } sector = null; subsector = null; sector = sectorMap.FromLocation(SectorLocation.X, SectorLocation.Y); if (sector != null) { subsector = sector.Subsector(Index); } }
public VMFamilia(Fixius.Servicios.DTO.Articulos.Familia DTO) : base(DTO) { this.PresentadorJerarquia = (IPresentadorBusquedaArticulo)FabricaPresentadores.Instancia.Resolver(typeof(IPresentadorBusquedaArticulo)); this.PresentadorJerarquia.SetServicios(); this.CargaFamilia(); if (DTO.Id == 0) { this.CodigoVisible = Visibility.Collapsed; this.ArbolVisible = Visibility.Collapsed; } else { this.Subsector = this.Modelo.Subsector; this.Sector = this.Modelo.Subsector.Sector; this.Area = this.Modelo.Subsector.Sector.Area; } }
public override void Process(ResourceManager resourceManager) { // NOTE: This (re)initializes a static data structure used for // resolving names into sector locations, so needs to be run // before any other objects (e.g. Worlds) are loaded. SectorMap.Milieu map = SectorMap.ForMilieu(resourceManager, GetStringOption("milieu")); Location loc = Location.Empty; if (HasOption("sector")) { string sectorName = GetStringOption("sector"); Sector sec = map.FromName(sectorName) ?? throw new HttpError(404, "Not Found", $"The specified sector '{sectorName}' was not found."); int hex = GetIntOption("hex", Astrometrics.SectorCentralHex); loc = new Location(sec.Location, hex); } else if (HasLocation()) { loc = GetLocation(); } if (loc.Hex.IsEmpty) { loc.Hex = Astrometrics.SectorCenter; } Sector sector = map.FromLocation(loc.Sector.X, loc.Sector.Y); var data = new Results.CreditsResult(); if (sector != null) { data.SectorX = sector.X; data.SectorY = sector.Y; // TODO: Multiple names foreach (var name in sector.Names.Take(1)) { data.SectorName = name.Text; } // Raw HTML credits data.Credits = sector.Credits?.Trim(); // Product info if (sector.Products.Count > 0) { data.ProductPublisher = sector.Products[0].Publisher; data.ProductTitle = sector.Products[0].Title; data.ProductAuthor = sector.Products[0].Author; data.ProductRef = sector.Products[0].Ref; } // Tags data.SectorTags = sector.TagString; // // Sector Credits // data.SectorAuthor = sector.Author; data.SectorSource = sector.Source; data.SectorPublisher = sector.Publisher; data.SectorCopyright = sector.Copyright; data.SectorRef = sector.Ref; data.SectorMilieu = sector.CanonicalMilieu; if (sector.DataFile != null) { data.SectorAuthor = sector.DataFile.Author ?? data.SectorAuthor; data.SectorSource = sector.DataFile.Source ?? data.SectorSource; data.SectorPublisher = sector.DataFile.Publisher ?? data.SectorPublisher; data.SectorCopyright = sector.DataFile.Copyright ?? data.SectorCopyright; data.SectorRef = sector.DataFile.Ref ?? data.SectorRef; data.SectorMilieu = sector.CanonicalMilieu; } // // Subsector Credits // int ssx = (loc.Hex.X - 1) / Astrometrics.SubsectorWidth; int ssy = (loc.Hex.Y - 1) / Astrometrics.SubsectorHeight; int ssi = ssx + ssy * 4; Subsector ss = sector.Subsector(ssi); if (ss != null) { data.SubsectorIndex = ss.Index; data.SubsectorName = ss.Name; } // // Routes Credits // // // World Data // WorldCollection worlds = sector.GetWorlds(resourceManager); if (worlds != null) { World world = worlds[loc.Hex]; if (world != null) { data.WorldName = world.Name; data.WorldHex = world.Hex; data.WorldUwp = world.UWP; data.WorldRemarks = world.Remarks; data.WorldIx = world.Importance; data.WorldEx = world.Economic; data.WorldCx = world.Cultural; data.WorldPbg = world.PBG; data.WorldAllegiance = sector.GetAllegianceFromCode(world.Allegiance)?.T5Code ?? ""; } } } SendResult(data); }
private void Apply(string line, Sector sector) { string[] kv = line.Split(null, 2); string key = kv[0].Trim().ToUpperInvariant(); string value = kv[1].Trim(); if (Regex.IsMatch(key, @"^\d{4}$")) { // Value is full name for world in hex return; } if (Regex.IsMatch(key, @"^[A-P]$")) { Subsector ss = new Subsector(); ss.Index = key; ss.Name = value; sector.Subsectors.Add(ss); return; } switch (key) { case "DOMAIN": sector.Domain = value; return; case "SECTOR": { // TODO: Add sector name sector.Names.Add(new Name(value)); return; } case "ALPHA": sector.AlphaQuadrant = value; return; case "BETA": sector.BetaQuadrant = value; return; case "GAMMA": sector.GammaQuadrant = value; return; case "DELTA": sector.DeltaQuadrant = value; return; case "ALLY": { Match match = Regex.Match(value, @"^(..)\s+(.*)$"); if (match.Success) { var code = match.Groups[1].Value; var name = match.Groups[2].Value; sector.Allegiances.Add(new Allegiance(code, name)); return; } break; } case "BASE": { Match match = Regex.Match(value, @"^(.)\s+(..)$/"); // Base decodes to two bases if (match.Success) { var code = match.Groups[1].Value; var bases = match.Groups[2].Value; // TODO: Base decodes return; } match = Regex.Match(value, @"^(.)\s+(\S+)\s(\S+)\s+(.*)$"); if (match.Success) { var code = match.Groups[1].Value; var zapf = match.Groups[2].Value; var color = match.Groups[3].Value; var name = match.Groups[4].Value; // TODO: Base symbols return; } break; } case "REGION": { // TODO: Support regions - like borders, but filled rather than stroked return; } case "BORDER": { string[] tokens = value.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); if (!Regex.IsMatch(tokens.Last(), @"^\d{4}$")) sector.Borders.Add(new Border(String.Join(" ", tokens.Take(tokens.Count() - 1)), tokens.Last())); else sector.Borders.Add(new Border(String.Join(" ", tokens))); return; } case "ROUTE": { var tokens = value.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); int cur = 0; Route route = new Route(); if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) route.StartOffsetX = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) route.StartOffsetY = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); route.Start = Astrometrics.HexToInt(tokens[cur++]); if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) route.EndOffsetX = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) route.EndOffsetY = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); route.End = Astrometrics.HexToInt(tokens[cur++]); if (cur < tokens.Length) route.ColorHtml = tokens[cur++]; sector.Routes.Add(route); return; } case "LABEL": { Match match = Regex.Match(value, @"^(..)(..)[,\/]?([\S]+)?\s+(.*)$"); if (match.Success) { var c = match.Groups[1].Value; var r = match.Groups[2].Value; var options = match.Groups[3].Value; var text = match.Groups[4].Value; Label label = new Label(Int32.Parse(c + r), text); foreach (var option in options.ToLowerInvariant().Split(',')) { if (option == "low") { label.OffsetY = 0.85f; continue; } if (Regex.IsMatch(option, @"[-+](\d+)$")) { int offset = 0; Int32.TryParse(option, out offset); label.OffsetY = offset / 100f; continue; } if (option == "right" || option == "left") { // TODO: Implement continue; } if (option == "large" || option == "small") { label.Size = option; continue; } if (option.StartsWith("subsec")) { label.RenderType = "Subsector"; continue; } if (option.StartsWith("quad")) { label.RenderType = "Quadrant"; continue; } if (option.StartsWith("sect")) { label.RenderType = "Sector"; continue; } if (option.StartsWith("custom")) { label.RenderType = "Custom"; continue; } if (option.Length > 0) { label.ColorHtml = option; } } sector.Labels.Add(label); return; } break; } } }
private void Page_Load(object sender, System.EventArgs e) { if (!ServiceConfiguration.CheckEnabled("credits", Response)) { return; } ResourceManager resourceManager = new ResourceManager(Server, Cache); // NOTE: This (re)initializes a static data structure used for // resolving names into sector locations, so needs to be run // before any other objects (e.g. Worlds) are loaded. SectorMap map = SectorMap.FromName(SectorMap.DefaultSetting, resourceManager); Location loc = new Location(map.FromName("Spinward Marches").Location, 1910); if (HasOption("sector")) { string sectorName = GetStringOption("sector"); Sector sec = map.FromName(sectorName); if (sec == null) { SendError(404, "Not Found", "Sector not found."); return; } int hex = GetIntOption("hex", Astrometrics.SectorCentralHex); loc = new Location(sec.Location, hex); } else if (HasOption("sx") && HasOption("sy")) { int sx = GetIntOption("sx", 0); int sy = GetIntOption("sy", 0); int hx = GetIntOption("hx", 0); int hy = GetIntOption("hy", 0); loc = new Location(map.FromLocation(sx, sy).Location, hx * 100 + hy); } else if (HasOption("x") && HasOption("y")) { loc = Astrometrics.CoordinatesToLocation(GetIntOption("x", 0), GetIntOption("y", 0)); } if (loc.HexLocation.IsEmpty) { loc.HexLocation = new Point(Astrometrics.SectorWidth / 2, Astrometrics.SectorHeight / 2); } Sector sector = map.FromLocation(loc.SectorLocation.X, loc.SectorLocation.Y); Result data = new Result(); if (sector != null) { // TODO: Multiple names foreach (var name in sector.Names.Take(1)) { data.SectorName = name.Text; } // Raw HTML credits data.Credits = sector.Credits == null ? null : sector.Credits.Trim(); // Product info if (sector.Products.Count > 0) { data.ProductPublisher = sector.Products[0].Publisher; data.ProductTitle = sector.Products[0].Title; data.ProductAuthor = sector.Products[0].Author; data.ProductRef = sector.Products[0].Ref; } // // Sector Credits // if (sector.DataFile != null) { data.SectorAuthor = sector.DataFile.Author; data.SectorSource = sector.DataFile.Source; data.SectorPublisher = sector.DataFile.Publisher; data.SectorCopyright = sector.DataFile.Copyright; data.SectorRef = sector.DataFile.Ref; data.SectorEra = sector.DataFile.Era; } // // Subsector Credits // int ssx = (loc.HexLocation.X - 1) / Astrometrics.SubsectorWidth; int ssy = (loc.HexLocation.Y - 1) / Astrometrics.SubsectorHeight; int ssi = ssx + ssy * 4; Subsector ss = sector[ssi]; if (ss != null) { data.SubsectorIndex = ss.Index; data.SubsectorName = ss.Name; } // // Routes Credits // // // World Data // WorldCollection worlds = sector.GetWorlds(resourceManager); if (worlds != null) { World world = worlds[loc.HexLocation.X, loc.HexLocation.Y]; if (world != null) { data.WorldName = world.Name; data.WorldHex = world.Hex.ToString("0000", CultureInfo.InvariantCulture); data.WorldUwp = world.UWP; data.WorldRemarks = world.Remarks; data.WorldIx = world.Importance; data.WorldEx = world.Economic; data.WorldCx = world.Cultural; data.WorldPbg = world.PBG; data.WorldAllegiance = world.Allegiance; } } } SendResult(data); }
public void Serialize() { // Header // writer.WriteLine("# Generated by https://travellermap.com"); writer.WriteLine("# " + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz", DateTimeFormatInfo.InvariantInfo)); writer.WriteLine(); // Sector name // writer.WriteLine("sector " + sector.Names[0].Text); if (!string.IsNullOrEmpty(sector.Domain)) { writer.WriteLine("domain " + sector.Domain); } if (!string.IsNullOrEmpty(sector.AlphaQuadrant)) { writer.WriteLine("alpha " + sector.AlphaQuadrant); } if (!string.IsNullOrEmpty(sector.BetaQuadrant)) { writer.WriteLine("beta " + sector.BetaQuadrant); } if (!string.IsNullOrEmpty(sector.GammaQuadrant)) { writer.WriteLine("gamma " + sector.GammaQuadrant); } if (!string.IsNullOrEmpty(sector.DeltaQuadrant)) { writer.WriteLine("delta " + sector.DeltaQuadrant); } writer.WriteLine(); // Subsectors // if (sector.Subsectors.Count > 0) { writer.WriteLine("# Subsectors"); writer.WriteLine("#"); for (int i = 0; i < 16; i++) { Subsector ss = sector.Subsector(i); if (ss != null) { writer.WriteLine("" + (char)('a' + i) + " " + ss.Name); } else { writer.WriteLine("" + (char)('a' + i)); } } writer.WriteLine(); } // Borders, Routes and Labels - group by allegiance // List <IAllegiance> list = new List <IAllegiance>(); list.AddRange(sector.Allegiances); // TODO: Output stock allegiances list.AddRange(sector.Borders); list.AddRange(sector.Routes); list.AddRange(sector.Labels); // Output grouped by allegiance // list.Sort(CompareAllegiances); bool isFirst = true; string code = null; Allegiance alleg = null; foreach (IAllegiance item in list) { // Determine allegiance if (isFirst || item.Allegiance != code) { isFirst = false; code = item.Allegiance; alleg = null; if (code != null) { alleg = sector.GetAllegianceFromCode(code); } if (alleg != null) { writer.WriteLine(); writer.Write("# "); writer.WriteLine(alleg.Name); writer.WriteLine("#"); } else { writer.WriteLine(); writer.WriteLine("# Other"); writer.WriteLine("#"); } } // Output the item if (item is Allegiance) { WriteAllegiance(item as Allegiance); } else if (item is Border) { WriteBorder(item as Border, alleg); } else if (item is Label) { WriteLabel(item as Label); } else if (item is Route) { WriteRoute(item as Route); } } }
public void LoadMap01() { using (var wad = new Wad(WadPath.Doom2)) { var flats = new FlatLookup(wad, true); var textures = new TextureLookup(wad, true); var map = wad.GetLumpNumber("MAP01"); var vertices = Vertex.FromWad(wad, map + 4); var sectors = Sector.FromWad(wad, map + 8, flats); var sides = SideDef.FromWad(wad, map + 3, textures, sectors); var lines = LineDef.FromWad(wad, map + 2, vertices, sides); var segs = Seg.FromWad(wad, map + 5, vertices, lines); var subsectors = Subsector.FromWad(wad, map + 6, segs); var nodes = Node.FromWad(wad, map + 7, subsectors); Assert.AreEqual(193, nodes.Length); Assert.AreEqual(64, nodes[0].X.ToDouble(), delta); Assert.AreEqual(1024, nodes[0].Y.ToDouble(), delta); Assert.AreEqual(0, nodes[0].Dx.ToDouble(), delta); Assert.AreEqual(-64, nodes[0].Dy.ToDouble(), delta); Assert.AreEqual(1173, nodes[0].Bbox[0][Box.Top].ToDouble(), delta); Assert.AreEqual(960, nodes[0].Bbox[0][Box.Bottom].ToDouble(), delta); Assert.AreEqual(-64, nodes[0].Bbox[0][Box.Left].ToDouble(), delta); Assert.AreEqual(64, nodes[0].Bbox[0][Box.Right].ToDouble(), delta); Assert.AreEqual(1280, nodes[0].Bbox[1][Box.Top].ToDouble(), delta); Assert.AreEqual(1024, nodes[0].Bbox[1][Box.Bottom].ToDouble(), delta); Assert.AreEqual(64, nodes[0].Bbox[1][Box.Left].ToDouble(), delta); Assert.AreEqual(128, nodes[0].Bbox[1][Box.Right].ToDouble(), delta); Assert.AreEqual(32770, nodes[0].Children[0] + 0x10000); Assert.AreEqual(32771, nodes[0].Children[1] + 0x10000); Assert.AreEqual(640, nodes[57].X.ToDouble(), delta); Assert.AreEqual(856, nodes[57].Y.ToDouble(), delta); Assert.AreEqual(-88, nodes[57].Dx.ToDouble(), delta); Assert.AreEqual(-16, nodes[57].Dy.ToDouble(), delta); Assert.AreEqual(856, nodes[57].Bbox[0][Box.Top].ToDouble(), delta); Assert.AreEqual(840, nodes[57].Bbox[0][Box.Bottom].ToDouble(), delta); Assert.AreEqual(552, nodes[57].Bbox[0][Box.Left].ToDouble(), delta); Assert.AreEqual(640, nodes[57].Bbox[0][Box.Right].ToDouble(), delta); Assert.AreEqual(856, nodes[57].Bbox[1][Box.Top].ToDouble(), delta); Assert.AreEqual(760, nodes[57].Bbox[1][Box.Bottom].ToDouble(), delta); Assert.AreEqual(536, nodes[57].Bbox[1][Box.Left].ToDouble(), delta); Assert.AreEqual(704, nodes[57].Bbox[1][Box.Right].ToDouble(), delta); Assert.AreEqual(32829, nodes[57].Children[0] + 0x10000); Assert.AreEqual(56, nodes[57].Children[1]); Assert.AreEqual(96, nodes[192].X.ToDouble(), delta); Assert.AreEqual(1280, nodes[192].Y.ToDouble(), delta); Assert.AreEqual(32, nodes[192].Dx.ToDouble(), delta); Assert.AreEqual(0, nodes[192].Dy.ToDouble(), delta); Assert.AreEqual(1280, nodes[192].Bbox[0][Box.Top].ToDouble(), delta); Assert.AreEqual(-960, nodes[192].Bbox[0][Box.Bottom].ToDouble(), delta); Assert.AreEqual(-1304, nodes[192].Bbox[0][Box.Left].ToDouble(), delta); Assert.AreEqual(2072, nodes[192].Bbox[0][Box.Right].ToDouble(), delta); Assert.AreEqual(2688, nodes[192].Bbox[1][Box.Top].ToDouble(), delta); Assert.AreEqual(1280, nodes[192].Bbox[1][Box.Bottom].ToDouble(), delta); Assert.AreEqual(-1304, nodes[192].Bbox[1][Box.Left].ToDouble(), delta); Assert.AreEqual(2072, nodes[192].Bbox[1][Box.Right].ToDouble(), delta); Assert.AreEqual(147, nodes[192].Children[0]); Assert.AreEqual(191, nodes[192].Children[1]); } }
public void LoadE1M1() { using (var wad = new Wad(WadPath.Doom1)) { var flats = new FlatLookup(wad, true); var textures = new TextureLookup(wad, true); var map = wad.GetLumpNumber("E1M1"); var vertices = Vertex.FromWad(wad, map + 4); var sectors = Sector.FromWad(wad, map + 8, flats); var sides = SideDef.FromWad(wad, map + 3, textures, sectors); var lines = LineDef.FromWad(wad, map + 2, vertices, sides); var segs = Seg.FromWad(wad, map + 5, vertices, lines); var subsectors = Subsector.FromWad(wad, map + 6, segs); var nodes = Node.FromWad(wad, map + 7, subsectors); Assert.AreEqual(238, nodes.Length); Assert.AreEqual(1784, nodes[0].X.ToDouble(), delta); Assert.AreEqual(-3448, nodes[0].Y.ToDouble(), delta); Assert.AreEqual(-240, nodes[0].Dx.ToDouble(), delta); Assert.AreEqual(64, nodes[0].Dy.ToDouble(), delta); Assert.AreEqual(-3104, nodes[0].Bbox[0][Box.Top].ToDouble(), delta); Assert.AreEqual(-3448, nodes[0].Bbox[0][Box.Bottom].ToDouble(), delta); Assert.AreEqual(1520, nodes[0].Bbox[0][Box.Left].ToDouble(), delta); Assert.AreEqual(2128, nodes[0].Bbox[0][Box.Right].ToDouble(), delta); Assert.AreEqual(-3384, nodes[0].Bbox[1][Box.Top].ToDouble(), delta); Assert.AreEqual(-3448, nodes[0].Bbox[1][Box.Bottom].ToDouble(), delta); Assert.AreEqual(1544, nodes[0].Bbox[1][Box.Left].ToDouble(), delta); Assert.AreEqual(1784, nodes[0].Bbox[1][Box.Right].ToDouble(), delta); Assert.AreEqual(32768, nodes[0].Children[0] + 0x10000); Assert.AreEqual(32769, nodes[0].Children[1] + 0x10000); Assert.AreEqual(928, nodes[57].X.ToDouble(), delta); Assert.AreEqual(-3360, nodes[57].Y.ToDouble(), delta); Assert.AreEqual(0, nodes[57].Dx.ToDouble(), delta); Assert.AreEqual(256, nodes[57].Dy.ToDouble(), delta); Assert.AreEqual(-3104, nodes[57].Bbox[0][Box.Top].ToDouble(), delta); Assert.AreEqual(-3360, nodes[57].Bbox[0][Box.Bottom].ToDouble(), delta); Assert.AreEqual(928, nodes[57].Bbox[0][Box.Left].ToDouble(), delta); Assert.AreEqual(1344, nodes[57].Bbox[0][Box.Right].ToDouble(), delta); Assert.AreEqual(-3104, nodes[57].Bbox[1][Box.Top].ToDouble(), delta); Assert.AreEqual(-3360, nodes[57].Bbox[1][Box.Bottom].ToDouble(), delta); Assert.AreEqual(704, nodes[57].Bbox[1][Box.Left].ToDouble(), delta); Assert.AreEqual(928, nodes[57].Bbox[1][Box.Right].ToDouble(), delta); Assert.AreEqual(32825, nodes[57].Children[0] + 0x10000); Assert.AreEqual(56, nodes[57].Children[1]); Assert.AreEqual(2176, nodes[237].X.ToDouble(), delta); Assert.AreEqual(-2304, nodes[237].Y.ToDouble(), delta); Assert.AreEqual(0, nodes[237].Dx.ToDouble(), delta); Assert.AreEqual(-256, nodes[237].Dy.ToDouble(), delta); Assert.AreEqual(-2048, nodes[237].Bbox[0][Box.Top].ToDouble(), delta); Assert.AreEqual(-4064, nodes[237].Bbox[0][Box.Bottom].ToDouble(), delta); Assert.AreEqual(-768, nodes[237].Bbox[0][Box.Left].ToDouble(), delta); Assert.AreEqual(2176, nodes[237].Bbox[0][Box.Right].ToDouble(), delta); Assert.AreEqual(-2048, nodes[237].Bbox[1][Box.Top].ToDouble(), delta); Assert.AreEqual(-4864, nodes[237].Bbox[1][Box.Bottom].ToDouble(), delta); Assert.AreEqual(2176, nodes[237].Bbox[1][Box.Left].ToDouble(), delta); Assert.AreEqual(3808, nodes[237].Bbox[1][Box.Right].ToDouble(), delta); Assert.AreEqual(131, nodes[237].Children[0]); Assert.AreEqual(236, nodes[237].Children[1]); } }
private void Apply(string line, Sector sector) { string[] kv = line.Split(null, 2); string key = kv[0].Trim().ToUpperInvariant(); string value = kv[1].Trim(); if (Regex.IsMatch(key, @"^\d{4}$")) { // Value is full name for world in hex return; } if (Regex.IsMatch(key, @"^[A-P]$")) { Subsector ss = new Subsector(); ss.Index = key; ss.Name = value; sector.Subsectors.Add(ss); return; } switch (key) { case "DOMAIN": sector.Domain = value; return; case "SECTOR": { // TODO: Add sector name sector.Names.Add(new Name(value)); return; } case "ALPHA": sector.AlphaQuadrant = value; return; case "BETA": sector.BetaQuadrant = value; return; case "GAMMA": sector.GammaQuadrant = value; return; case "DELTA": sector.DeltaQuadrant = value; return; case "ALLY": { Match match = Regex.Match(value, @"^(..)\s+(.*)$"); if (match.Success) { var code = match.Groups[1].Value; var name = match.Groups[2].Value; sector.Allegiances.Add(new Allegiance(code, name)); return; } break; } case "BASE": { Match match = Regex.Match(value, @"^(.)\s+(..)$/"); // Base decodes to two bases if (match.Success) { var code = match.Groups[1].Value; var bases = match.Groups[2].Value; // TODO: Base decodes return; } match = Regex.Match(value, @"^(.)\s+(\S+)\s(\S+)\s+(.*)$"); if (match.Success) { var code = match.Groups[1].Value; var zapf = match.Groups[2].Value; var color = match.Groups[3].Value; var name = match.Groups[4].Value; // TODO: Base symbols return; } break; } case "REGION": { // TODO: Support regions - like borders, but filled rather than stroked return; } case "BORDER": { string[] tokens = value.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); if (!Regex.IsMatch(tokens.Last(), @"^\d{4}$")) { sector.Borders.Add(new Border(String.Join(" ", tokens.Take(tokens.Count() - 1)), tokens.Last())); } else { sector.Borders.Add(new Border(String.Join(" ", tokens))); } return; } case "ROUTE": { var tokens = value.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); int cur = 0; Route route = new Route(); if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) { route.StartOffsetX = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); } if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) { route.StartOffsetY = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); } route.Start = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) { route.EndOffsetX = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); } if (Regex.IsMatch(tokens[cur], @"^[-+]?[01]$")) { route.EndOffsetY = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); } route.End = Int32.Parse(tokens[cur++], NumberStyles.Integer, CultureInfo.InvariantCulture); if (cur < tokens.Length) { route.ColorHtml = tokens[cur++]; } sector.Routes.Add(route); return; } case "LABEL": { Match match = Regex.Match(value, @"^(..)(..)[,\/]?([\S]+)?\s+(.*)$"); if (match.Success) { var c = match.Groups[1].Value; var r = match.Groups[2].Value; var options = match.Groups[3].Value; var text = match.Groups[4].Value; Label label = new Label(Int32.Parse(c + r), text); foreach (var option in options.ToLowerInvariant().Split(',')) { if (option == "low") { // TODO: Implement continue; } if (Regex.IsMatch(option, @"[-+](\d+)$")) { // TODO: Implement continue; } if (option == "right" || option == "left") { // TODO: Implement continue; } if (option == "large" || option == "small") { label.Size = option; continue; } if (option.StartsWith("subsec")) { label.RenderType = "Subsector"; continue; } if (option.StartsWith("quad")) { label.RenderType = "Quadrant"; continue; } if (option.StartsWith("sect")) { label.RenderType = "Sector"; continue; } if (option.StartsWith("custom")) { label.RenderType = "Custom"; continue; } if (option.Length > 0) { label.ColorHtml = option; } } sector.Labels.Add(label); return; } break; } } }