/// <summary>
 /// Removes a cube from the corridor, and yields any cubes that are
 /// uncovered as a consequence.
 /// </summary>
 /// <param name="c">Cube to be destroyed.</param>
 /// <returns>Cubes that have been uncovered by destroying c.</returns>
 public override IEnumerable<Cube> DestroyCube(Cube c)
 {
     if (c.Z < Depth / 2)
         foreach (Cube uncovered in UpWall.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   uncovered.X, uncovered.Y, uncovered.Z);
     else
     {
         c.Z = Depth - 1 - c.Z;
         foreach (Cube uncovered in DownWall.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   uncovered.X, uncovered.Y, Depth - 1 - uncovered.Z);
     }
 }
        /// <summary>
        /// Removes a cube from the corridor, and yields any cubes that are
        /// uncovered as a consequence.
        /// </summary>
        /// <param name="c">Cube to be destroyed.</param>
        /// <returns>Cubes that have been uncovered by destroying c.</returns>
        public override IEnumerable<Cube> DestroyCube(Cube c)
        {
            List<Cube> toRet = new List<Cube>();

            if (c.X > 0 && !IsVisible(c.X-1, c.Y, c.Z))
                toRet.Add(new Cube(this, Cubes[c.X-1, c.Y, c.Z], c.X-1, c.Y, c.Z));
            if (c.X < Width-1 && !IsVisible(c.X+1, c.Y, c.Z))
                toRet.Add(new Cube(this, Cubes[c.X+1, c.Y, c.Z], c.X+1, c.Y, c.Z));
            if (c.Y > 0 && !IsVisible(c.X, c.Y-1, c.Z))
                toRet.Add(new Cube(this, Cubes[c.X, c.Y-1, c.Z], c.X, c.Y-1, c.Z));
            if (c.Y < Depth-1 && !IsVisible(c.X, c.Y+1, c.Z))
                toRet.Add(new Cube(this, Cubes[c.X, c.Y+1, c.Z], c.X, c.Y+1, c.Z));
            if (c.Z > 0 && !IsVisible(c.X, c.Y, c.Z-1))
                toRet.Add(new Cube(this, Cubes[c.X, c.Y, c.Z-1], c.X, c.Y, c.Z-1));
            if (c.Z < Height-1 && !IsVisible(c.X, c.Y, c.Z+1))
                toRet.Add(new Cube(this, Cubes[c.X, c.Y, c.Z+1], c.X, c.Y, c.Z+1));

            Cubes[c.X, c.Y, c.Z] = ItemBase.tOreType.NOT_ORE;
            return toRet;
        }
 /// <summary>
 /// Removes a cube from the corridor, and yields any cubes that are
 /// uncovered as a consequence.
 /// </summary>
 /// <param name="c">Cube to be destroyed.</param>
 /// <returns>Cubes that have been uncovered by destroying c.</returns>
 public override IEnumerable<Cube> DestroyCube(Cube c)
 {
     if (c.X < Width / 2)
     {
         int tmp = c.Z;
         c.Z = c.X;
         c.X = tmp;
         foreach (Cube uncovered in LeftWall.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   uncovered.Z, uncovered.Y, uncovered.X);
     }
     else
     {
         int tmp = c.Z;
         c.Z = Width - 1 - c.X;
         c.X = tmp;
         foreach (Cube uncovered in RightWall.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   Width - 1 - uncovered.Z, uncovered.Y, uncovered.X);
     }
 }
 /// <summary>
 /// Removes a cube from the corridor, and yields any cubes that are
 /// uncovered as a consequence.
 /// </summary>
 /// <param name="c">Cube to be destroyed.</param>
 /// <returns>Cubes that have been uncovered by destroying c.</returns>
 public abstract IEnumerable<Cube> DestroyCube(Cube c);
        /// <summary>
        /// Spawns a cube in Unity given a Cube object (holding the type of cube, and (x,y,z)
        /// coordinate position of the cube in the room) and a vector denoting where (0,0,0)
        /// lies in Unity space.
        /// </summary>
        /// <param name="cube">Cube object you would like to spawn.</param>
        /// <param name="cubeStart">Offset of (0,0,0) in Unity space.</param>
        /// <param name="scalar">Value to scale 1 block to.</param>
        private void InstantiateCube(Cube cube, Vector3 cubeStart, float scalar)
        {
            if (cube.Type == ItemBase.tOreType.NOT_ORE)
                return;

            cube.Parent = this;
            MineableBlock ct = allocator.GetCube(cube);
            ct.transform.position = (new Vector3(cube.X, cube.Y, cube.Z) + cubeStart) * scalar;
            blocks.Add(ct);
        }
        /// <summary>
        /// Destroys a cube stored in this room's Cubes data set. Since this class
        /// doesn't directly hold the cube, we'll pass the cube on to Cubes to handle.
        /// 
        /// This class inherits this structure for consistency in convention for handling
        /// cube destruction. However, since this class will be the one instantiating the
        /// yielded cubes from lower DestroyCube calls, nothing is yielded from this call.
        /// </summary>
        /// <param name="c">Cube to be destroyed.</param>
        /// <returns>Nothing. This class will handle instantiation - don't worry your pretty
        /// little head over it.</returns>
        public IEnumerable<Cube> DestroyCube(Cube c)
        {
            foreach (Cube uncovered in Cubes.DestroyCube(c))
                if (uncovered.Type != ItemBase.tOreType.NOT_ORE)
                    InstantiateCube(uncovered, _cubeStart, _scalar);

            // We have no reason to return anything, so don't
            return new List<Cube>();
        }
 /// <summary>
 /// Removes a cube from the corridor, and yields any cubes that are
 /// uncovered as a consequence.
 /// </summary>
 /// <param name="c">Cube to be destroyed.</param>
 /// <returns>Cubes that have been uncovered by destroying c.</returns>
 public override IEnumerable<Cube> DestroyCube(Cube c)
 {
     // Left side:
     if (c.X < L_Wall.MaxDepth)
     {
         // Top:
         if (c.Z < TL_Corner.Depth)
         {
             int tmp = c.Z;
             c.Z = c.Y;
             c.Y = tmp;
             foreach (Cube uncovered in TL_Corner.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       uncovered.X, uncovered.Z, uncovered.Y);
         }
         // Center:
         else if (c.Z < TL_Corner.Depth + L_Wall.Width)
         {
             int tmp = c.Z;
             c.Z = c.X;
             c.X = Depth - BL_Corner.Width - 1 - tmp;
             foreach (Cube uncovered in L_Wall.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       uncovered.Z, uncovered.Y, Depth - BL_Corner.Width - 1 - uncovered.X);
         }
         // Bottom:
         else
         {
             int tmp = c.Z;
             c.Z = c.Y;
             c.Y = c.X;
             c.X = Depth - 1 - tmp;
             foreach (Cube uncovered in TR_Corner.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       uncovered.Y, uncovered.Z, Depth - 1 - uncovered.X);
         }
     }
     // Center:
     else if (c.X < L_Wall.MaxDepth + T_Wall.Width)
     {
         // Top:
         if (c.Z < TL_Corner.Depth)
         {
             c.X -= TL_Corner.Depth;
             foreach (Cube uncovered in T_Wall.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       uncovered.X + L_Wall.MaxDepth, uncovered.Y, uncovered.Z);
         }
         // Bottom:
         else
         {
             c.X = Width - BR_Corner.Width - 1 - c.X;
             c.Z = Depth - 1 - c.Z;
             foreach (Cube uncovered in B_Wall.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       Width - BR_Corner.Width - 1 - uncovered.X, uncovered.Y, Depth - 1 - uncovered.Z);
         }
     }
     // Right side:
     else
     {
         // Top:
         if (c.Z < TL_Corner.Depth)
         {
             int tmp = c.Z;
             c.Z = c.Y;
             c.Y = Width - 1 - c.X;
             c.X = tmp;
             foreach (Cube uncovered in TR_Corner.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       Width - uncovered.Y - 1, uncovered.Z, uncovered.X);
         }
         // Center:
         else if (c.Z < TL_Corner.Depth + L_Wall.Width)
         {
             int tmp = c.Z;
             c.Z = Width - 1 - c.X;
             c.X = tmp - TR_Corner.Width;
             foreach (Cube uncovered in R_Wall.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       Width - 1 - uncovered.Z, uncovered.Y, TR_Corner.Width + uncovered.X);
         }
         // Bottom:
         else
         {
             int tmp = c.Z;
             c.Z = c.Y;
             c.Y = Depth - 1 - tmp;
             c.X = Width - 1 - c.X;
             foreach (Cube uncovered in BR_Corner.DestroyCube(c))
                 yield return new Cube(this, uncovered.Type,
                                       Width - 1 - uncovered.X, uncovered.Z, Depth - 1 - uncovered.Y);
         }
     }
 }
 /// <summary>
 /// Removes a cube from the corridor, and yields any cubes that are
 /// uncovered as a consequence.
 /// </summary>
 /// <param name="c">Cube to be destroyed.</param>
 /// <returns>Cubes that have been uncovered by destroying c.</returns>
 public override IEnumerable<Cube> DestroyCube(Cube c)
 {
     // L Side
     if (c.X < L_Side.Width)
     {
         foreach (Cube uncovered in L_Side.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   uncovered.X, uncovered.Y, uncovered.Z);
     }
     // L Corner
     else if (c.X < L_Side.Width + L_Corner.Width)
     {
         int tmp = c.Z;
         c.Z = c.Y;
         c.Y = tmp;
         c.X -= L_Side.Width;
         foreach (Cube uncovered in L_Corner.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   uncovered.X + L_Side.Width, uncovered.Z, uncovered.Y);
     }
     // R Corner
     else if (c.X < L_Side.Width + L_Corner.Width + R_Corner.Depth)
     {
         int tmp = c.Z;
         c.Z = c.Y;
         c.Y = Width - 1 - R_Side.Width - c.X;
         c.X = tmp;
         foreach (Cube uncovered in R_Corner.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   Width - 1 - R_Side.Width - uncovered.Y, uncovered.Z, uncovered.X);
     }
     //c.X + L_Side.Width + RogueDungeon.CORRIDOR_WIDTH, c.Y, c.Z
     // R Side
     else
     {
         c.X -= L_Side.Width + RogueDungeon.CORRIDOR_WIDTH;
         foreach (Cube uncovered in R_Side.DestroyCube(c))
             yield return new Cube(this, uncovered.Type,
                                   uncovered.X + L_Side.Width + RogueDungeon.CORRIDOR_WIDTH, uncovered.Y, uncovered.Z);
     }
 }
        /// <summary>
        /// Removes a cube from the corridor, and yields any cubes that are
        /// uncovered as a consequence.
        /// </summary>
        /// <param name="c">Cube to be destroyed.</param>
        /// <returns>Cubes that have been uncovered by destroying c.</returns>
        public override IEnumerable<Cube> DestroyCube(Cube c)
        {
            List<Cube> toRet = new List<Cube>();
            // If we are on one of the edges, don't check neighbors in the plane:
            // we know that those are already displayed
            if (c.X == 0)
            {
                if (!IsUncovered(c.X+1, c.Y, c.Z))
                    toRet.Add(new Cube(this, Cubes[c.X+1, c.Y, c.Z], c.X+1, c.Y, c.Z));
            }
            else if (c.X == Width-1)
            {
                if (!IsUncovered(c.X-1, c.Y, c.Z))
                    toRet.Add(new Cube(this, Cubes[c.X-1, c.Y, c.Z], c.X-1, c.Y, c.Z));
            }
            else
            {
                if (!IsUncovered(c.X-1, c.Y, c.Z))
                    toRet.Add(new Cube(this, Cubes[c.X-1, c.Y, c.Z], c.X-1, c.Y, c.Z));
                if (!IsUncovered(c.X+1, c.Y, c.Z))
                    toRet.Add(new Cube(this, Cubes[c.X+1, c.Y, c.Z], c.X+1, c.Y, c.Z));

                if (c.Y > 0 && !IsUncovered(c.X, c.Y-1, c.Z))
                    toRet.Add(new Cube(this, Cubes[c.X, c.Y-1, c.Z], c.X, c.Y-1, c.Z));
                if (c.Y < Height-1 && !IsUncovered(c.X, c.Y+1, c.Z))
                    toRet.Add(new Cube(this, Cubes[c.X, c.Y+1, c.Z], c.X, c.Y+1, c.Z));

                if (c.Z > 0 && !IsUncovered(c.X, c.Y, c.Z-1))
                    toRet.Add(new Cube(this, Cubes[c.X, c.Y, c.Z-1], c.X, c.Y, c.Z-1));
                if (c.Z < MaxDepth-1 && !IsUncovered(c.X, c.Y, c.Z+1))
                    toRet.Add(new Cube(this, Cubes[c.X, c.Y, c.Z+1], c.X, c.Y, c.Z+1));
            }

            Cubes[c.X, c.Y, c.Z] = ItemBase.tOreType.NOT_ORE;
            return toRet;
        }