public Anvil(string path) { NbtTag levelDat = new NbtFile(Path.Combine(path, "level.dat")).RootTag["Data"]; string levelName = levelDat["LevelName"].StringValue; string[] regionFiles = Directory.GetFiles(Path.Combine(path, "region"), "*.mca"); for (int idx = 0; idx < regionFiles.Length; idx++) ParseRegion(regionFiles[idx]); Bounds bounds = ScanForBounds(); boundaryWidth = bounds.Width; boundaryHeight = bounds.Height; boundaryLength = bounds.Length; offsetX = -bounds.minX; offsetY = -bounds.minY; offsetZ = -bounds.minZ; Console.WriteLine("Extracting blocks within boundary."); foreach (KeyValuePair<CoordinateInt, Block[]> pair in chunks) { CoordinateInt chunkCoord = pair.Key; if (bounds.ContainsChunk(chunkCoord)) for (int idx = 0; idx < pair.Value.Length; idx++) if (BlockTypeIsSupported(pair.Value[idx].id)) { int absoluteX = chunkCoord.X * 16 + idx % 16; int absoluteZ = chunkCoord.Z * 16 + (idx / 16) % 16; int absoluteY = chunkCoord.Y * 16 + idx / (16 * 16); if (bounds.Contains(absoluteX, absoluteY, absoluteZ)) { CoordinateInt blockCoord = new CoordinateInt(absoluteX + offsetX, absoluteZ + offsetZ, absoluteY + offsetY); blocks[blockCoord] = new Block(pair.Value[idx].id, 0);// pair.Value[idx].data); } } } }
private const int matchData = 14; //red private Bounds ScanForBounds() { Console.WriteLine("Scanning {0} chunks for bounds.", chunks.Count); Bounds bounds = new Bounds(); int matchesFound = 0; foreach (KeyValuePair <CoordinateInt, Block[]> pair in chunks) { CoordinateInt chunkCoord = pair.Key; Block[] blocks = pair.Value; for (int blockIdx = 0; blockIdx < blocks.Length; blockIdx++) { if (blocks[blockIdx].id == matchType && blocks[blockIdx].data == matchData) { matchesFound++; int relativeX = blockIdx % 16; int relativeZ = (blockIdx / 16) % 16; int relativeY = blockIdx / (16 * 16); bounds.AddPoint(chunkCoord.X * 16 + relativeX, chunkCoord.Y * 16 + relativeY, chunkCoord.Z * 16 + relativeZ); } } } bounds.Shrink(1); Console.WriteLine("Found {0} bounds markers.\nBoundary is {1}.", matchesFound, bounds); return(bounds); }
public bool ContainsChunk(CoordinateInt chunkCoord) { return !( chunkCoord.X * chunkSize + 16 < minX || chunkCoord.X * chunkSize > maxX || chunkCoord.Y * chunkSize + 16 < minY || chunkCoord.Y * chunkSize > maxY || chunkCoord.Z * chunkSize + 16 < minZ || chunkCoord.Z * chunkSize > maxZ); }
public void Save(CoordinateInt Start, CoordinateInt End) { FileStream fs = new FileStream("D:\\path.astar", FileMode.Create, FileAccess.Write); fs.WriteByte((byte)(Start.X >> 8)); fs.WriteByte((byte)(Start.X & 0x000000FF)); fs.WriteByte((byte)(Start.Y >> 8)); fs.WriteByte((byte)(Start.Y & 0x000000FF)); fs.WriteByte((byte)(End.X >> 8)); fs.WriteByte((byte)(End.X & 0x000000FF)); fs.WriteByte((byte)(End.Y >> 8)); fs.WriteByte((byte)(End.Y & 0x000000FF)); fs.WriteByte((byte)(1)); fs.WriteByte((byte)(0)); fs.WriteByte((byte)(0)); fs.WriteByte((byte)2); fs.WriteByte((byte)0); fs.WriteByte((byte)(0)); fs.WriteByte((byte)(((int)50000) >> 24)); fs.WriteByte((byte)(((int)50000) >> 16)); fs.WriteByte((byte)(((int)50000) >> 8)); fs.WriteByte((byte)(((int)50000) & 0x000000FF)); fs.WriteByte((byte)50); fs.WriteByte((byte)1); for (int y = 0; y < 1000; y++) { for (int x = 0; x < 1000; x++) { fs.WriteByte(MapArr[x, y]); } } fs.Close(); }
public CoordinateInt GetClosestIndex(Coordinate pos) { CoordinateInt minIndex = new CoordinateInt(); float minDistance = (float)9999.0; for (int i = 0; i < ArrSizeX; i++) { for (int j = 0; j < ArrSizeX; j++) { if (MapArr[i, j] == 0) { continue; } Coordinate arrPos = new Coordinate(i / ArrScale + Min.X, j / ArrScale + Min.Y, 0); float currDist = pos.Distance(arrPos); if (currDist < minDistance) { minDistance = currDist; minIndex.X = i; minIndex.Y = j; } } } return(minIndex); }
private static bool ObstructedScanXY(CoordinateInt coord, int width, int height, int offsetZ, HashSet<CoordinateInt> blockCheck) { for (int dX = 0; dX < width; dX++) for (int dY = 0; dY < height; dY++) if (!blockCheck.Contains(coord.Offset(dX, dY, offsetZ))) return false; totalHiddenFaces++; return true; }
private static bool ObstructedScanXZ(CoordinateInt coord, int width, int offsetY, int length, HashSet<CoordinateInt> blockCheck) { for (int dX = 0; dX < width; dX++) for (int dZ = 0; dZ < length; dZ++) if (!blockCheck.Contains(coord.Offset(dX, offsetY, dZ))) return false; totalHiddenFaces++; return true; }
private static bool ObstructedScanYZ(CoordinateInt coord, int offsetX, int height, int length, HashSet<CoordinateInt> blockCheck) { for (int dY = 0; dY < height; dY++) for (int dZ = 0; dZ < length; dZ++) if (!blockCheck.Contains(coord.Offset(offsetX, dY, dZ))) return false; totalHiddenFaces++; return true; }
private Volume LargestVolume_Iterate(CoordinateInt origin, bool allowInvisible) { Volume largestVolume = new Volume(); int maxX = 0; while (SearchAllBlocks(origin.Offset(maxX, 0, 0), allowInvisible)) { maxX++; } int maxY = 0; while (SearchAllBlocks(origin.Offset(0, maxY, 0), allowInvisible)) { maxY++; } int maxZ = 0; while (SearchAllBlocks(origin.Offset(0, 0, maxZ), allowInvisible)) { maxZ++; } for (int extentZ = maxZ; extentZ >= 0; extentZ--) { for (int extentY = maxY; extentY >= 0; extentY--) { for (int extentX = maxX; extentX >= 0; extentX--) { int lengthX = extentX + 1; int lengthY = extentY + 1; int lengthZ = extentZ + 1; /* Don't bother considering this volume if it won't get used. */ if (lengthX * lengthY * lengthZ <= largestVolume.TotalVolume) { continue; } if (LargestVolume_Valid(origin, lengthX, lengthY, lengthZ, allowInvisible)) { int totalVolume = lengthX * lengthY * lengthZ; if (totalVolume >= largestVolume.TotalVolume) { largestVolume = new Volume(origin, lengthX, lengthY, lengthZ); } } //else // break; } } } return(largestVolume); }
private static bool IsInvisible(CoordinateInt coord, Dictionary<CoordinateInt, Block> rawWorld) { bool isInvisible = OpaqueBrickAt(coord.Offset(-1, 0, 0), rawWorld) && OpaqueBrickAt(coord.Offset(1, 0, 0), rawWorld) && OpaqueBrickAt(coord.Offset(0, -1, 0), rawWorld) && OpaqueBrickAt(coord.Offset(0, 1, 0), rawWorld) && OpaqueBrickAt(coord.Offset(0, 0, -1), rawWorld) && OpaqueBrickAt(coord.Offset(0, 0, 1), rawWorld); return isInvisible; }
private static bool IsInvisible(CoordinateInt coord, Dictionary <CoordinateInt, Block> rawWorld) { bool isInvisible = OpaqueBrickAt(coord.Offset(-1, 0, 0), rawWorld) && OpaqueBrickAt(coord.Offset(1, 0, 0), rawWorld) && OpaqueBrickAt(coord.Offset(0, -1, 0), rawWorld) && OpaqueBrickAt(coord.Offset(0, 1, 0), rawWorld) && OpaqueBrickAt(coord.Offset(0, 0, -1), rawWorld) && OpaqueBrickAt(coord.Offset(0, 0, 1), rawWorld); return(isInvisible); }
private void ParseRegion(string regionPath) { string fileName = Path.GetFileName(regionPath); int chunkCount = 0; using (BinaryReader binaryReader = new BinaryReader(File.Open(regionPath, FileMode.Open))) { List <LocationData> locationList = new List <LocationData>(); for (int idx = 0; idx < 1024; idx++) { int row = Endian.ToBig(binaryReader.ReadInt32()); int offset = (row >> 8); byte sectorCount = (byte)(row & 0x000000FF); if (offset != 0 || sectorCount != 0) { locationList.Add(new LocationData(idx % 32, idx / 32, offset, sectorCount)); } } for (int locationIdx = 0; locationIdx < locationList.Count; locationIdx++) { binaryReader.BaseStream.Seek(sectorSize * locationList[locationIdx].offset, SeekOrigin.Begin); int length = Endian.ToBig(binaryReader.ReadInt32()); byte compressionType = binaryReader.ReadByte(); byte[] dataBuffer = binaryReader.ReadBytes(length - 1); NbtFile region = new NbtFile(); region.LoadFromBuffer(dataBuffer, 0, dataBuffer.Length, NbtCompression.ZLib); NbtTag levelTag = region.RootTag["Level"]; int chunkX = levelTag["xPos"].IntValue; int chunkZ = levelTag["zPos"].IntValue; NbtList sections = levelTag["Sections"] as NbtList; for (int sectionIdx = 0; sectionIdx < sections.Count; sectionIdx++) { Block[] blocks = new Block[16 * 16 * 16]; NbtTag sectionTag = sections[sectionIdx]; int offsetY = sectionTag["Y"].ByteValue; byte[] blockIDs = sectionTag["Blocks"].ByteArrayValue; byte[] blockData = sectionTag["Data"].ByteArrayValue; for (int blockIdx = 0; blockIdx < blockIDs.Length; blockIdx++) { blocks[blockIdx] = new Block((BlockIdentifier)blockIDs[blockIdx], MaskTo4Bit(blockData, blockIdx)); } CoordinateInt coord = new CoordinateInt(chunkX, offsetY, chunkZ); chunks.Add(coord, blocks); chunkCount++; } } Console.WriteLine("Parsed {0} ({1} chunks)", fileName, chunkCount); } }
private static bool ObstructedScanXY(CoordinateInt coord, int width, int height, int offsetZ, HashSet <CoordinateInt> blockCheck) { for (int dX = 0; dX < width; dX++) { for (int dY = 0; dY < height; dY++) { if (!blockCheck.Contains(coord.Offset(dX, dY, offsetZ))) { return(false); } } } totalHiddenFaces++; return(true); }
private static bool ObstructedScanYZ(CoordinateInt coord, int offsetX, int height, int length, HashSet <CoordinateInt> blockCheck) { for (int dY = 0; dY < height; dY++) { for (int dZ = 0; dZ < length; dZ++) { if (!blockCheck.Contains(coord.Offset(offsetX, dY, dZ))) { return(false); } } } totalHiddenFaces++; return(true); }
private static bool ObstructedScanXZ(CoordinateInt coord, int width, int offsetY, int length, HashSet <CoordinateInt> blockCheck) { for (int dX = 0; dX < width; dX++) { for (int dZ = 0; dZ < length; dZ++) { if (!blockCheck.Contains(coord.Offset(dX, offsetY, dZ))) { return(false); } } } totalHiddenFaces++; return(true); }
private bool LargestVolume_Valid(CoordinateInt coord, int lengthX, int lengthY, int lengthZ, bool allowInvisible) { for (int gZ = lengthZ - 1; gZ >= 0; gZ--) { for (int gY = lengthY - 1; gY >= 0; gY--) { for (int gX = lengthX - 1; gX >= 0; gX--) { if (!SearchAllBlocks(coord.Offset(gX, gY, gZ), allowInvisible)) { return(false); } } } } return(true); }
public Anvil(string path) { NbtTag levelDat = new NbtFile(Path.Combine(path, "level.dat")).RootTag["Data"]; string levelName = levelDat["LevelName"].StringValue; string[] regionFiles = Directory.GetFiles(Path.Combine(path, "region"), "*.mca"); for (int idx = 0; idx < regionFiles.Length; idx++) { ParseRegion(regionFiles[idx]); } Bounds bounds = ScanForBounds(); boundaryWidth = bounds.Width; boundaryHeight = bounds.Height; boundaryLength = bounds.Length; offsetX = -bounds.minX; offsetY = -bounds.minY; offsetZ = -bounds.minZ; Console.WriteLine("Extracting blocks within boundary."); foreach (KeyValuePair <CoordinateInt, Block[]> pair in chunks) { CoordinateInt chunkCoord = pair.Key; if (bounds.ContainsChunk(chunkCoord)) { for (int idx = 0; idx < pair.Value.Length; idx++) { if (BlockTypeIsSupported(pair.Value[idx].id)) { int absoluteX = chunkCoord.X * 16 + idx % 16; int absoluteZ = chunkCoord.Z * 16 + (idx / 16) % 16; int absoluteY = chunkCoord.Y * 16 + idx / (16 * 16); if (bounds.Contains(absoluteX, absoluteY, absoluteZ)) { CoordinateInt blockCoord = new CoordinateInt(absoluteX + offsetX, absoluteZ + offsetZ, absoluteY + offsetY); blocks[blockCoord] = new Block(pair.Value[idx].id, 0);// pair.Value[idx].data); } } } } } }
private void map_LeftMouseUp(object sender, MouseButtonEventArgs e) { if (_navigationEnabled == false || _mapinfo.HasNavCoordinates == false) { return; } Point p = e.GetPosition(this); Coordinate clickCoordinate = MapToWorld(new Coordinate((float)p.X, (float)p.Y, 0)); System.Diagnostics.Debug.Print(clickCoordinate.X + "," + clickCoordinate.Y); GC.Collect(); if (_mapArr != null) { CoordinateInt startIndex = _mapArr.GetClosestIndex(_user.Coordinate); CoordinateInt endIndex = _mapArr.GetClosestIndex(clickCoordinate); _pathFinder = new PathFinderFast(_mapArr.MapArr) { Formula = HeuristicFormula.Manhattan, Diagonals = true, HeavyDiagonals = false, HeuristicEstimate = (int)2, PunishChangeDirection = false, TieBreaker = true, SearchLimit = (int)9000000, DebugProgress = false, DebugFoundPath = false }; _selectedPath = _pathFinder.FindPath(new System.Drawing.Point(startIndex.X, startIndex.Y), new System.Drawing.Point(endIndex.X, endIndex.Y)); _mapArr.Save(startIndex, endIndex); _selectedPathCoords = new List <Coordinate>(); if (_selectedPath == null) { MessageBox.Show("No Path Found"); return; } _selectedPath.Reverse(); for (int i = 0; i < _selectedPath.Count; i += 1) { Coordinate pnt1 = WorldToMap(new Coordinate(_selectedPath[i].X / _mapArr.ArrScale + _mapArr.Min.X, _selectedPath[i].Y / _mapArr.ArrScale + _mapArr.Min.Y, 0)); _selectedPathCoords.Add(pnt1); } GC.Collect(); } }
private static bool OpaqueBrickAt(CoordinateInt coord, Dictionary<CoordinateInt, Block> rawWorld) { Block blockType; return (rawWorld.TryGetValue(coord, out blockType)) && Array.IndexOf(TransparentBlocks, blockType.id) == -1; }
private static bool OpaqueBrickAt(CoordinateInt coord, Dictionary <CoordinateInt, Block> rawWorld) { Block blockType; return((rawWorld.TryGetValue(coord, out blockType)) && Array.IndexOf(TransparentBlocks, blockType.id) == -1); }
private void ParseRegion(string regionPath) { string fileName = Path.GetFileName(regionPath); int chunkCount = 0; using (BinaryReader binaryReader = new BinaryReader(File.Open(regionPath, FileMode.Open))) { List<LocationData> locationList = new List<LocationData>(); for (int idx = 0; idx < 1024; idx++) { int row = Endian.ToBig(binaryReader.ReadInt32()); int offset = (row >> 8); byte sectorCount = (byte)(row & 0x000000FF); if (offset != 0 || sectorCount != 0) locationList.Add(new LocationData(idx % 32, idx / 32, offset, sectorCount)); } for (int locationIdx = 0; locationIdx < locationList.Count; locationIdx++) { binaryReader.BaseStream.Seek(sectorSize * locationList[locationIdx].offset, SeekOrigin.Begin); int length = Endian.ToBig(binaryReader.ReadInt32()); byte compressionType = binaryReader.ReadByte(); byte[] dataBuffer = binaryReader.ReadBytes(length - 1); NbtFile region = new NbtFile(); region.LoadFromBuffer(dataBuffer, 0, dataBuffer.Length, NbtCompression.ZLib); NbtTag levelTag = region.RootTag["Level"]; int chunkX = levelTag["xPos"].IntValue; int chunkZ = levelTag["zPos"].IntValue; NbtList sections = levelTag["Sections"] as NbtList; for (int sectionIdx = 0; sectionIdx < sections.Count; sectionIdx++) { Block[] blocks = new Block[16 * 16 * 16]; NbtTag sectionTag = sections[sectionIdx]; int offsetY = sectionTag["Y"].ByteValue; byte[] blockIDs = sectionTag["Blocks"].ByteArrayValue; byte[] blockData = sectionTag["Data"].ByteArrayValue; for (int blockIdx = 0; blockIdx < blockIDs.Length; blockIdx++) blocks[blockIdx] = new Block((BlockIdentifier)blockIDs[blockIdx], MaskTo4Bit(blockData, blockIdx)); CoordinateInt coord = new CoordinateInt(chunkX, offsetY, chunkZ); chunks.Add(coord, blocks); chunkCount++; } } Console.WriteLine("Parsed {0} ({1} chunks)", fileName, chunkCount); } }
private bool SearchAllBlocks(CoordinateInt coord, bool allowInvisible) { return(visibleBlocks.Contains(coord) || (allowInvisible && invisibleBlocks.Contains(coord))); }
private bool CoordinateIsVisible(CoordinateInt coord) { return(visibleBlocks.Contains(coord)); }