public static PGStarMatch[] GetStarMatchByName(string sysname) { if (SystemsByName.ContainsKey(sysname)) { return(SystemsByName[sysname].Select(i => SystemsById[i]).ToArray()); } else { int index = 0; int starclass = 0; ByteXYZ blkcoords = new ByteXYZ(); int[] coords = null; HandAuthoredSector sector = null; string regionname = GetProcGenRegionNameFromSystemName(sysname, out index, out starclass, ref blkcoords); if (regionname != null) { sector = HandAuthoredSectors.Sectors.FindSector(regionname)?.First(); if (sector != null) { int[] basecoords = sector.GetBaseBlockCoords(starclass); coords = new int[] { basecoords[0] + blkcoords.X, basecoords[1] + blkcoords.Y, basecoords[2] + blkcoords.Z }; } else { ByteXYZ regioncoords = PGSectors.GetSectorPos(regionname); if (regioncoords != ByteXYZ.Invalid) { string _regionname = PGSectors.GetSectorName(regioncoords); coords = new int[] { (regioncoords.X << starclass) + blkcoords.X, (regioncoords.Y << starclass) + blkcoords.Y, (regioncoords.Z << starclass) + blkcoords.Z }; } } if (coords != null) { long id = GetProcGenId(coords, starclass, index); if (SystemsById.ContainsKey(id)) { return(new PGStarMatch[] { SystemsById[id] }); } } } } return(new PGStarMatch[0]); }
public static long GetProcGenId(ByteXYZ regionCoords, UShortXYZ relCoords, int starclass, int starseq) { int blocksize = 40960 >> starclass; int[] coords = new int[] { (int)(regionCoords.X * 40960 + relCoords.X) / blocksize, (int)(regionCoords.Y * 40960 + relCoords.Y) / blocksize, (int)(regionCoords.Z * 40960 + relCoords.Z) / blocksize }; return(GetProcGenId(coords, starclass, starseq)); }
private static uint Interleave3(ByteXYZ val) { unchecked { ulong x = (((ulong)val.X & 0x7F)) | (((ulong)val.Y & 0x7F) << 7) | (((ulong)val.Z & 0x7F) << 14); x = (x | (x << 32)) & 0x001F00000000FFFFUL; x = (x | (x << 16)) & 0x001F0000FF0000FFUL; x = (x | (x << 8)) & 0x100F00F00F00F00FUL; x = (x | (x << 4)) & 0x10C30C30C30C30C3UL; x = (x | (x << 2)) & 0x1249249249249249UL; return((uint)((x | (x >> 20) | (x >> 40)) & 0x1FFFFF)); } }
public static string GetPgSuffix(ByteXYZ blockcoords, int starclass) { int blocknr = blockcoords.X + ((int)blockcoords.Y << 7) + ((int)blockcoords.Z << 14); char v1 = (char)((blocknr % 26) + 'A'); blocknr /= 26; char v2 = (char)((blocknr % 26) + 'A'); blocknr /= 26; char v3 = (char)((blocknr % 26) + 'A'); blocknr /= 26; char sc = (char)('h' - starclass); string v4 = blocknr == 0 ? "" : $"{blocknr}-"; return($"{v1}{v2}-{v3} {sc}{v4}"); }
public ByteXYZ GetBlockCoords(PGStarMatch m) { int starclass = m.StarClass; int[] v0 = GetBaseBlockCoords(starclass); int[] v = m.BlockCoords; int[] bc = new int[] { v[0] - v0[0], v[1] - v0[1], v[2] - v0[2] }; if (bc[0] < 0 || bc[0] >= 128 || bc[1] < 0 || bc[1] >= 128 || bc[2] < 0 || bc[2] >= 128) { return(ByteXYZ.Invalid); } else { ByteXYZ blockcoords = new ByteXYZ { X = (sbyte)bc[0], Y = (sbyte)bc[1], Z = (sbyte)bc[2] }; string suffix = PGStarMatch.GetPgSuffix(blockcoords, m.StarClass, m.StarSeq); return(blockcoords); } }
// Region coords to sector name - based on https://bitbucket.org/Esvandiary/edts/src/master/pgnames.py public static string GetSectorName(ByteXYZ pos) { if (CachedSectorsByCoords.ContainsKey(pos)) { return(CachedSectorsByCoords[pos]); } else { int offset = (pos.Z << 14) + (pos.Y << 7) + pos.X; string sectorname; if (IsC1Sector(offset)) { sectorname = GetC1Name(offset); } else { sectorname = GetC2Name(offset); } CachedSectorsByCoords[pos] = sectorname; return(sectorname); } }
public static string GetC2SectorName(ByteXYZ pos) { return(GetC2Name((pos.Z << 14) + (pos.Y << 7) + pos.X)); }
public static long GetProcGenId(string sysname, Vector3 starpos, out HandAuthoredSector sector) { int index = 0; int starclass = 0; ByteXYZ blkcoords = new ByteXYZ(); int[] coords = null; sector = null; string regionname = GetProcGenRegionNameFromSystemName(sysname, out index, out starclass, ref blkcoords); if (regionname == null) { if (SystemsByName.ContainsKey(sysname)) { List <PGStarMatch> matches = SystemsByName[sysname].Select(s => SystemsById[s]).ToList(); foreach (PGStarMatch sm in matches) { Vector3 smcoords = sm.Coords; Vector3 diff = new Vector3 { X = smcoords.X - starpos.X, Y = smcoords.Y - starpos.Y, Z = smcoords.Z - starpos.Z }; double sqdist = diff.X * diff.X + diff.Y * diff.Y + diff.Z * diff.Z; if (sqdist < 0.015625) { sector = sm.HASector; return(sm.Id); } } } else { return(0); } } else { sector = HandAuthoredSectors.Sectors.FindSector(regionname).FirstOrDefault(); if (sector != null) { int[] basecoords = sector.GetBaseBlockCoords(starclass); coords = new int[] { basecoords[0] + blkcoords.X, basecoords[1] + blkcoords.Y, basecoords[2] + blkcoords.Z }; } else { ByteXYZ regioncoords = PGSectors.GetSectorPos(regionname); if (regioncoords != ByteXYZ.Invalid) { coords = new int[] { (regioncoords.X << starclass) + blkcoords.X, (regioncoords.Y << starclass) + blkcoords.Y, (regioncoords.Z << starclass) + blkcoords.Z }; } } } if (coords != null) { long id = GetProcGenId(coords, starclass, index); if (id < 0) { Console.WriteLine($"Error: {sysname} => {id} ([{coords[0]},{coords[1]},{coords[2]}]:{starclass}:{index})"); } return(id); } else { return(0); } }
public static PGStarMatch GetStarMatch(string sysname, Vector3 starpos, uint edsmid = 0, uint eddbid = 0) { int index = 0; int starclass = 0; ByteXYZ blkcoords = new ByteXYZ(); int[] coords = null; HandAuthoredSector sector = null; if (SystemsByName.ContainsKey(sysname)) { List <PGStarMatch> matches = SystemsByName[sysname].Select(i => SystemsById[i]).ToList(); if (matches.Count == 1) { return(matches[0]); } foreach (PGStarMatch sm in matches) { Vector3 smcoords = sm.Coords; Vector3 diff = new Vector3 { X = smcoords.X - starpos.X, Y = smcoords.Y - starpos.Y, Z = smcoords.Z - starpos.Z }; double sqdist = diff.X * diff.X + diff.Y * diff.Y + diff.Z * diff.Z; if (sqdist < 0.015625) { sector = sm.HASector; return(sm); } } } string regionname = GetProcGenRegionNameFromSystemName(sysname, out index, out starclass, ref blkcoords); int blocksize = 40960 >> starclass; double vx = starpos.X + 49985; double vy = starpos.Y + 40985; double vz = starpos.Z + 24105; if (vx < 0 || vx >= 163840 || vy < 0 || vy > 163840 || vz < 0 || vz > 163840) { return(PGStarMatch.Invalid); } int x = (int)(vx * 32 + 0.5); int y = (int)(vy * 32 + 0.5); int z = (int)(vz * 32 + 0.5); int cx = x / blocksize; int cy = y / blocksize; int cz = z / blocksize; if (regionname != null && starpos != null && !Double.IsNaN(starpos.X) && !Double.IsNaN(starpos.Y) && !Double.IsNaN(starpos.Z)) { sector = HandAuthoredSectors.Sectors.FindSector(regionname)?.First(); if (sector != null) { int[] basecoords = sector.GetBaseBlockCoords(starclass); coords = new int[] { basecoords[0] + blkcoords.X, basecoords[1] + blkcoords.Y, basecoords[2] + blkcoords.Z }; } else { int bx = (x % 40960) / blocksize; int by = (y % 40960) / blocksize; int bz = (z % 40960) / blocksize; ByteXYZ regioncoords = new ByteXYZ { X = (sbyte)(x / 40960), Y = (sbyte)(y / 40960), Z = (sbyte)(z / 40960) }; string pgregion = PGSectors.GetSectorName(regioncoords); ByteXYZ nregcoords = pgregion == regionname ? regioncoords : PGSectors.GetSectorPos(regionname); if (bx == blkcoords.X && by == blkcoords.Y && bz == blkcoords.Z && nregcoords == regioncoords) { coords = new int[] { cx, cy, cz }; } else { ByteXYZ relcoords = new ByteXYZ { X = (sbyte)bx, Y = (sbyte)by, Z = (sbyte)bz }; if (nregcoords == ByteXYZ.Invalid) { Console.WriteLine($"System {sysname}: Unknown sector {regionname} @ {regioncoords} - coordname={pgregion} {GetPgSuffix(relcoords, starclass, index)}"); } else { Vector3 namecoords = new Vector3 { X = (nregcoords.X * 40960 + blkcoords.X * blocksize) / 32.0 - 49985, Y = (nregcoords.Y * 40960 + blkcoords.Y * blocksize) / 32.0 - 40985, Z = (nregcoords.Z * 40960 + blkcoords.Z * blocksize) / 32.0 - 24105 }; Console.WriteLine($"System {sysname}: Bad coordinates for sector {regionname} @ {regioncoords} - coordname={pgregion} {GetPgSuffix(relcoords, starclass, index)} | namecoords={namecoords}"); } return(PGStarMatch.Invalid); } } int ix = coords[0]; int iy = coords[1]; int iz = coords[2]; long id = GetProcGenId(coords, starclass, index); if (SystemsById.ContainsKey(id)) { PGStarMatch sm = SystemsById[id]; if (cx != ix || cy != iy || cz != iz) { Vector3 error = new Vector3 { X = coords[0] * blocksize / 32.0 - 49985, Y = coords[1] * blocksize / 32.0 - 40985, Z = coords[2] * blocksize / 32.0 - 24105 }; Console.WriteLine($"Warning: System {sysname} Coord mismatch - starpos={starpos} | match={sm.Coords} | namepos={error}"); } if ((eddbid == 0 && edsmid != 0 && sm._EdsmId == 0) || (sm._EdsmId == edsmid && eddbid != 0 && sm._EddbId == 0)) { if (eddbid == 0 && edsmid != 0 && sm._EdsmId == 0) { sm._EdsmId = edsmid; } if (sm._EdsmId == edsmid && eddbid != 0 && sm._EddbId == 0) { sm._EddbId = eddbid; } SystemsById[id] = sm; } return(sm); } else { PGStarMatch sm = new PGStarMatch { _RegionCoordsX = (sbyte)(x / 40960), _RegionCoordsY = (sbyte)(y / 40960), _RegionCoordsZ = (sbyte)(z / 40960), _RelCoordsX = (ushort)(x % 40960), _RelCoordsY = (ushort)(y % 40960), _RelCoordsZ = (ushort)(z % 40960), _StarSeq = (ushort)index, _StarClass = (byte)starclass, _HandAuthoredSectorIndex = (ushort)(HandAuthoredSectors.Sectors.IndexOf(sector) + 1), _EdsmId = edsmid, _EddbId = eddbid }; if (cx != ix || cy != iy || cz != iz) { Vector3 error = new Vector3 { X = coords[0] * blocksize / 32.0 - 49985, Y = coords[1] * blocksize / 32.0 - 40985, Z = coords[2] * blocksize / 32.0 - 24105 }; int[] bc = sm.BlockCoords; Console.WriteLine($"Warning: System {sysname} Coord mismatch - pgname={sm.HPGName} | starpos={starpos} | namepos={error} | nc=({coords[0]}, {coords[1]}, {coords[2]}) | pc=({bc[0]}, {bc[1]}, {bc[2]})"); } SystemsById[id] = sm; return(sm); } } else { return(PGStarMatch.Invalid); } }
public static string GetProcGenRegionNameFromSystemName(string s, out int index, out int starclass, ref ByteXYZ blkcoords) { int i = s.Length - 1; int blknum = 0; index = 0; starclass = 0; string _s = s.ToLowerInvariant(); if (i < 9) { return(null); // a bc-d e0 } if (_s[i] < '0' || _s[i] > '9') { return(null); // cepheus dark region a sector xy-z a1-[0] } while (i > 8 && _s[i] >= '0' && _s[i] <= '9') { i--; } if (i < _s.Length - 6) { return(null); } index = Int32.Parse(_s.Substring(i + 1)); if (_s[i] == '-') // cepheus dark region a sector xy-z a1[-]0 { i--; int vend = i; while (i > 8 && _s[i] >= '0' && _s[i] <= '9') { i--; // cepheus dark region a sector xy-z a[1]-0 } if (i < vend - 4) { return(null); } blknum = Int32.Parse(_s.Substring(i + 1, vend - i)); } if (_s[i] < 'a' || _s[i] > 'h') { return(null); // cepheus dark region a sector xy-z [a]1-0 } starclass = 'h' - _s[i]; i--; if (_s[i] != ' ') { return(null); // cepheus dark region a sector xy-z[ ]a1-0 } i--; if (_s[i] < 'a' || _s[i] > 'z') { return(null); // cepheus dark region a sector xy-[z] a1-0 } blknum = blknum * 26 + _s[i] - 'a'; i--; if (_s[i] != '-') { return(null); // cepheus dark region a sector xy[-]z a1-0 } i--; if (_s[i] < 'a' || _s[i] > 'z') { return(null); // cepheus dark region a sector x[y]-z a1-0 } blknum = blknum * 26 + _s[i] - 'a'; i--; if (_s[i] < 'a' || _s[i] > 'z') { return(null); // cepheus dark region a sector [x]y-z a1-0 } blknum = blknum * 26 + _s[i] - 'a'; i--; if (_s[i] != ' ') { return(null); // cepheus dark region a sector[ ]xy-z a1-0 } i--; blkcoords = new ByteXYZ( (sbyte)(blknum & 127), (sbyte)((blknum >> 7) & 127), (sbyte)((blknum >> 14) & 127) ); return(s.Substring(0, i + 1)); // [cepheus dark region a sector] xy-z a1-0 }
public static string GetPgSuffix(ByteXYZ blockcoords, int starclass, int starseq) { string pgbsuffix = GetPgSuffix(blockcoords, starclass); return($"{pgbsuffix}{starseq}"); }