Exemplo n.º 1
0
        public static bool Go(Voxel voxel, Voxel.Coord center, int radius, Action <List <DynamicVoxel> > callback = null)
        {
            if (!voxel[center].Permanent)
            {
                // Break off a chunk of this voxel into a new DynamicMap.

                List <Voxel.Coord> edges = new List <Voxel.Coord>();

                Voxel.Coord ripStart = center.Move(-radius, -radius, -radius);
                Voxel.Coord ripEnd   = center.Move(radius, radius, radius);

                Dictionary <Voxel.Box, bool> permanentBoxes = new Dictionary <Voxel.Box, bool>();
                foreach (Voxel.Coord c in ripStart.CoordinatesBetween(ripEnd))
                {
                    Voxel.Box box = voxel.GetBox(c);
                    if (box != null && box.Type.Permanent)
                    {
                        permanentBoxes[box] = true;
                    }
                }

                foreach (Voxel.Box b in permanentBoxes.Keys)
                {
                    // Top and bottom
                    for (int x = b.X - 1; x <= b.X + b.Width; x++)
                    {
                        for (int z = b.Z - 1; z <= b.Z + b.Depth; z++)
                        {
                            Voxel.Coord coord = new Voxel.Coord {
                                X = x, Y = b.Y + b.Height, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }

                            coord = new Voxel.Coord {
                                X = x, Y = b.Y - 1, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }
                        }
                    }

                    // Outer shell
                    for (int y = b.Y; y < b.Y + b.Height; y++)
                    {
                        // Left and right
                        for (int z = b.Z - 1; z <= b.Z + b.Depth; z++)
                        {
                            Voxel.Coord coord = new Voxel.Coord {
                                X = b.X - 1, Y = y, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }

                            coord = new Voxel.Coord {
                                X = b.X + b.Width, Y = y, Z = z
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }
                        }

                        // Backward and forward
                        for (int x = b.X; x < b.X + b.Width; x++)
                        {
                            Voxel.Coord coord = new Voxel.Coord {
                                X = x, Y = y, Z = b.Z - 1
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }

                            coord = new Voxel.Coord {
                                X = x, Y = y, Z = b.Z + b.Depth
                            };
                            if (coord.Between(ripStart, ripEnd))
                            {
                                edges.Add(coord);
                            }
                        }
                    }
                }

                if (edges.Contains(center))
                {
                    return(false);
                }

                // Top and bottom
                for (int x = ripStart.X; x <= ripEnd.X; x++)
                {
                    for (int z = ripStart.Z; z <= ripEnd.Z; z++)
                    {
                        Voxel.Coord c = new Voxel.Coord {
                            X = x, Y = ripStart.Y, Z = z
                        };
                        Voxel.State s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                        c = new Voxel.Coord {
                            X = x, Y = ripEnd.Y, Z = z
                        };
                        s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                    }
                }

                // Sides
                for (int y = ripStart.Y + 1; y <= ripEnd.Y - 1; y++)
                {
                    // Left and right
                    for (int z = ripStart.Z; z <= ripEnd.Z; z++)
                    {
                        Voxel.Coord c = new Voxel.Coord {
                            X = ripStart.X, Y = y, Z = z
                        };
                        Voxel.State s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                        c = new Voxel.Coord {
                            X = ripEnd.X, Y = y, Z = z
                        };
                        s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                    }

                    // Backward and forward
                    for (int x = ripStart.X; x <= ripEnd.X; x++)
                    {
                        Voxel.Coord c = new Voxel.Coord {
                            X = x, Y = y, Z = ripStart.Z
                        };
                        Voxel.State s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                        c = new Voxel.Coord {
                            X = x, Y = y, Z = ripEnd.Z
                        };
                        s = voxel[c];
                        if (s != Voxel.States.Empty && !s.Permanent)
                        {
                            edges.Add(c);
                        }
                    }
                }

                Propagator p = WorldFactory.Instance.Get <Propagator>();
                foreach (Voxel.Coord c in edges)
                {
                    p.SparksLowPriority(voxel.GetAbsolutePosition(c), Propagator.Spark.Dangerous);
                }

                voxel.Empty(edges);

                voxel.Regenerate(callback);
                return(true);
            }
            return(false);
        }