public Structure(Region tregion, Location startOfTrace, int maxrad) { // TODO: Optimize tracing! startOfTrace = startOfTrace.GetBlockLocation(); Queue <Location> locs = new Queue <Location>(); HashSet <Location> found = new HashSet <Location>(); List <Location> resultLocs = new List <Location>(); locs.Enqueue(startOfTrace); int maxradsq = maxrad * maxrad; AABB box = new AABB() { Max = startOfTrace, Min = startOfTrace }; while (locs.Count > 0) { Location loc = locs.Dequeue(); if (found.Contains(loc)) { continue; } if (loc.DistanceSquared(startOfTrace) > maxradsq) { throw new Exception("Escaped radius!"); } BlockInternal bi = tregion.GetBlockInternal(loc); if ((Material)bi.BlockMaterial == Material.AIR) { continue; } if (!((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.EDITED)) { throw new Exception("Found natural block!"); } if (((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.PROTECTED)) { throw new Exception("Found protected block!"); } found.Add(loc); resultLocs.Add(loc); box.Include(loc); foreach (Location dir in FloodDirs) { locs.Enqueue(loc + dir); } } Location ext = box.Max - box.Min; Size = new Vector3i((int)ext.X + 1, (int)ext.Y + 1, (int)ext.Z + 1); Origin = new Vector3i((int)Math.Floor(startOfTrace.X - box.Min.X), (int)Math.Floor(startOfTrace.Y - box.Min.Y), (int)Math.Floor(startOfTrace.Z - box.Min.Z)); Blocks = new BlockInternal[Size.X * Size.Y * Size.Z]; foreach (Location loc in resultLocs) { Blocks[BlockIndex((int)(loc.X - box.Min.X), (int)(loc.Y - box.Min.Y), (int)(loc.Z - box.Min.Z))] = tregion.GetBlockInternal(loc); } }
// TODO: Optimize tracing! public Structure(Region tregion, Location startOfTrace, int maxrad) { startOfTrace = startOfTrace.GetBlockLocation(); Queue<Location> locs = new Queue<Location>(); HashSet<Location> found = new HashSet<Location>(); List<Location> resultLocs = new List<Location>(); locs.Enqueue(startOfTrace); int maxradsq = maxrad * maxrad; AABB box = new AABB() { Max = startOfTrace, Min = startOfTrace }; while (locs.Count > 0) { Location loc = locs.Dequeue(); if (found.Contains(loc)) { continue; } if (loc.DistanceSquared(startOfTrace) > maxradsq) { throw new Exception("Escaped radius!"); } BlockInternal bi = tregion.GetBlockInternal(loc); if ((Material)bi.BlockMaterial == Material.AIR) { continue; } if (!((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.EDITED)) { throw new Exception("Found natural block!"); } if (((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.PROTECTED)) { throw new Exception("Found protected block!"); } found.Add(loc); resultLocs.Add(loc); box.Include(loc); foreach (Location dir in FloodDirs) { locs.Enqueue(loc + dir); } } Location ext = box.Max - box.Min; Size = new Vector3i((int)ext.X + 1, (int)ext.Y + 1, (int)ext.Z + 1); Origin = new Vector3i((int)Math.Floor(startOfTrace.X - box.Min.X), (int)Math.Floor(startOfTrace.Y - box.Min.Y), (int)Math.Floor(startOfTrace.Z - box.Min.Z)); Blocks = new BlockInternal[Size.X * Size.Y * Size.Z]; foreach (Location loc in resultLocs) { Blocks[BlockIndex((int)(loc.X - box.Min.X), (int)(loc.Y - box.Min.Y), (int)(loc.Z - box.Min.Z))] = tregion.GetBlockInternal(loc); } }
public Structure(Region tregion, Location min, Location max, Location origin) { Location ext = max - min; Size = new Vector3i((int)ext.X + 1, (int)ext.Y + 1, (int)ext.Z + 1); Origin = new Vector3i((int)Math.Floor(origin.X - min.X), (int)Math.Floor(origin.Y - min.Y), (int)Math.Floor(origin.Z - min.Z)); Blocks = new BlockInternal[Size.X * Size.Y * Size.Z]; for (int x = 0; x < Size.X; x++) { for (int y = 0; y < Size.Y; y++) { for (int z = 0; z < Size.Z; z++) { Blocks[BlockIndex(x, y, z)] = tregion.GetBlockInternal(new Location(min.X + x, min.Y + y, min.Z + z)); } } } }
public Structure(Region tregion, Location min, Location max, Location origin) { Location ext = max - min; Size = new Vector3i((int)ext.X + 1, (int)ext.Y + 1, (int)ext.Z + 1); Origin = new Vector3i((int)Math.Floor(origin.X - min.X), (int)Math.Floor(origin.Y - min.Y), (int)Math.Floor(origin.Z - min.Z)); Blocks = new BlockInternal[Size.X * Size.Y * Size.Z]; for (int x = 0; x < Size.X; x++) { for (int y = 0; y < Size.Y; y++) { for (int z = 0; z < Size.Z; z++) { Blocks[BlockIndex(x, y, z)] = tregion.GetBlockInternal(new Location(min.X + x, min.Y + y, min.Z + z)); } } } }
bool FloodFrom(Region tregion, Location start, List<KeyValuePair<Location, BlockInternal>> blocks, double maxRad, AABB extent) { Queue<Location> locsToGo = new Queue<Location>(); locsToGo.Enqueue(start); while (locsToGo.Count > 0) { Location c = locsToGo.Dequeue(); if ((c - start).LengthSquared() > maxRad * maxRad) { SysConsole.Output(OutputType.INFO, "Escaped radius!"); return false; } BlockInternal bi = tregion.GetBlockInternal(c); if ((Material)bi.BlockMaterial == Material.AIR) { continue; } if (!((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.EDITED)) { SysConsole.Output(OutputType.INFO, "Found natural block!"); return false; } if (((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.PROTECTED)) { continue; } blocks.Add(new KeyValuePair<Location, BlockInternal>(c, bi)); tregion.SetBlockMaterial(c, (Material)bi.BlockMaterial, bi.BlockData, bi.BlockPaint, (byte)(bi.BlockLocalData | (byte)BlockFlags.PROTECTED), bi.Damage, false, false); extent.Include(c); foreach (Location dir in FloodDirs) { locsToGo.Enqueue(c + dir); } } return true; }