Advertisement
Guest User

Cuboid Class

a guest
Aug 20th, 2014
460
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 26.89 KB | None | 0 0
  1. import java.util.ArrayList;
  2. import java.util.HashMap;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import java.util.Map;
  6.  
  7.  
  8. import org.bukkit.Bukkit;
  9. import org.bukkit.Chunk;
  10. import org.bukkit.Location;
  11. import org.bukkit.World;
  12. import org.bukkit.block.Block;
  13. import org.bukkit.configuration.serialization.ConfigurationSerializable;
  14. /**
  15.  * This class is a region/cuboid from one location to another. It can be used for blocks protection and things like WorldEdit.
  16.  * @author desht (Original code), KingFaris10 (Editor of code)
  17.  */
  18. public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializable {
  19.         protected final String worldName;
  20.         protected final int x1, y1, z1;
  21.         protected final int x2, y2, z2;
  22.  
  23.         /**
  24.          * Construct a Cuboid given two Location objects which represent any two corners of the Cuboid.
  25.          * Note: The 2 locations must be on the same world.
  26.          *
  27.          * @param l1 - One of the corners
  28.          * @param l2 - The other corner
  29.          */
  30.         public Cuboid(Location l1, Location l2) {
  31.                 if (!l1.getWorld().equals(l2.getWorld())) throw new IllegalArgumentException("Locations must be on the same world");
  32.                 this.worldName = l1.getWorld().getName();
  33.                 this.x1 = Math.min(l1.getBlockX(), l2.getBlockX());
  34.                 this.y1 = Math.min(l1.getBlockY(), l2.getBlockY());
  35.                 this.z1 = Math.min(l1.getBlockZ(), l2.getBlockZ());
  36.                 this.x2 = Math.max(l1.getBlockX(), l2.getBlockX());
  37.                 this.y2 = Math.max(l1.getBlockY(), l2.getBlockY());
  38.                 this.z2 = Math.max(l1.getBlockZ(), l2.getBlockZ());
  39.         }
  40.  
  41.         /**
  42.          * Construct a one-block Cuboid at the given Location of the Cuboid.
  43.          *
  44.          * @param l1 location of the Cuboid
  45.          */
  46.         public Cuboid(Location l1) {
  47.                 this(l1, l1);
  48.         }
  49.  
  50.         /**
  51.          * Copy constructor.
  52.          *
  53.          * @param other - The Cuboid to copy
  54.          */
  55.         public Cuboid(Cuboid other) {
  56.                 this(other.getWorld().getName(), other.x1, other.y1, other.z1, other.x2, other.y2, other.z2);
  57.         }
  58.  
  59.         /**
  60.          * Construct a Cuboid in the given World and xyz co-ordinates
  61.          *
  62.          * @param world - The Cuboid's world
  63.          * @param x1 - X co-ordinate of corner 1
  64.          * @param y1 - Y co-ordinate of corner 1
  65.          * @param z1 - Z co-ordinate of corner 1
  66.          * @param x2 - X co-ordinate of corner 2
  67.          * @param y2 - Y co-ordinate of corner 2
  68.          * @param z2 - Z co-ordinate of corner 2
  69.          */
  70.         public Cuboid(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
  71.                 this.worldName = world.getName();
  72.                 this.x1 = Math.min(x1, x2);
  73.                 this.x2 = Math.max(x1, x2);
  74.                 this.y1 = Math.min(y1, y2);
  75.                 this.y2 = Math.max(y1, y2);
  76.                 this.z1 = Math.min(z1, z2);
  77.                 this.z2 = Math.max(z1, z2);
  78.         }
  79.  
  80.         /**
  81.          * Construct a Cuboid in the given world name and xyz co-ordinates.
  82.          *
  83.          * @param worldName - The Cuboid's world name
  84.          * @param x1 - X co-ordinate of corner 1
  85.          * @param y1 - Y co-ordinate of corner 1
  86.          * @param z1 - Z co-ordinate of corner 1
  87.          * @param x2 - X co-ordinate of corner 2
  88.          * @param y2 - Y co-ordinate of corner 2
  89.          * @param z2 - Z co-ordinate of corner 2
  90.          */
  91.         private Cuboid(String worldName, int x1, int y1, int z1, int x2, int y2, int z2) {
  92.                 this.worldName = worldName;
  93.                 this.x1 = Math.min(x1, x2);
  94.                 this.x2 = Math.max(x1, x2);
  95.                 this.y1 = Math.min(y1, y2);
  96.                 this.y2 = Math.max(y1, y2);
  97.                 this.z1 = Math.min(z1, z2);
  98.                 this.z2 = Math.max(z1, z2);
  99.         }
  100.  
  101.         /**
  102.          * Construct a Cuboid using a map with the following keys: worldName, x1, x2, y1, y2, z1, z2
  103.          * @param map - The map of keys.
  104.          */
  105.         public Cuboid(Map<String, Object> map) {
  106.                 this.worldName = (String) map.get("worldName");
  107.                 this.x1 = (Integer) map.get("x1");
  108.                 this.x2 = (Integer) map.get("x2");
  109.                 this.y1 = (Integer) map.get("y1");
  110.                 this.y2 = (Integer) map.get("y2");
  111.                 this.z1 = (Integer) map.get("z1");
  112.                 this.z2 = (Integer) map.get("z2");
  113.         }
  114.  
  115.         @Override
  116.         public Map<String, Object> serialize() {
  117.                 Map<String, Object> map = new HashMap<String, Object>();
  118.                 map.put("worldName", this.worldName);
  119.                 map.put("x1", this.x1);
  120.                 map.put("y1", this.y1);
  121.                 map.put("z1", this.z1);
  122.                 map.put("x2", this.x2);
  123.                 map.put("y2", this.y2);
  124.                 map.put("z2", this.z2);
  125.                 return map;
  126.         }
  127.  
  128.         /**
  129.          * Get the Location of the lower northeast corner of the Cuboid (minimum XYZ co-ordinates).
  130.          *
  131.          * @return Location of the lower northeast corner
  132.          */
  133.         public Location getLowerNE() {
  134.                 return new Location(this.getWorld(), this.x1, this.y1, this.z1);
  135.         }
  136.  
  137.         /**
  138.          * Get the Location of the upper southwest corner of the Cuboid (maximum XYZ co-ordinates).
  139.          *
  140.          * @return Location of the upper southwest corner
  141.          */
  142.         public Location getUpperSW() {
  143.                 return new Location(this.getWorld(), this.x2, this.y2, this.z2);
  144.         }
  145.  
  146.         /**
  147.          * Get the blocks in the Cuboid.
  148.          *
  149.          * @return The blocks in the Cuboid
  150.          */
  151.         public List<Block> getBlocks() {
  152.                 Iterator<Block> blockI = this.iterator();
  153.                 List<Block> copy = new ArrayList<Block>();
  154.                 while (blockI.hasNext())
  155.                         copy.add(blockI.next());
  156.                 return copy;
  157.         }
  158.  
  159.         /**
  160.          * Get the the centre of the Cuboid.
  161.          *
  162.          * @return Location at the centre of the Cuboid
  163.          */
  164.         public Location getCenter() {
  165.                 int x1 = this.getUpperX() + 1;
  166.                 int y1 = this.getUpperY() + 1;
  167.                 int z1 = this.getUpperZ() + 1;
  168.                 return new Location(this.getWorld(), this.getLowerX() + (x1 - this.getLowerX()) / 2.0, this.getLowerY() + (y1 - this.getLowerY()) / 2.0, this.getLowerZ() + (z1 - this.getLowerZ()) / 2.0);
  169.         }
  170.  
  171.         /**
  172.          * Get the Cuboid's world.
  173.          *
  174.          * @return The World object representing this Cuboid's world
  175.          * @throws IllegalStateException if the world is not loaded
  176.          */
  177.         public World getWorld() {
  178.                 World world = Bukkit.getWorld(this.worldName);
  179.                 if (world == null) throw new IllegalStateException("World '" + this.worldName + "' is not loaded");
  180.                 return world;
  181.         }
  182.  
  183.         /**
  184.          * Get the size of this Cuboid along the X axis
  185.          *
  186.          * @return      Size of Cuboid along the X axis
  187.          */
  188.         public int getSizeX() {
  189.                 return (this.x2 - this.x1) + 1;
  190.         }
  191.  
  192.         /**
  193.          * Get the size of this Cuboid along the Y axis
  194.          *
  195.          * @return      Size of Cuboid along the Y axis
  196.          */
  197.         public int getSizeY() {
  198.                 return (this.y2 - this.y1) + 1;
  199.         }
  200.  
  201.         /**
  202.          * Get the size of this Cuboid along the Z axis
  203.          *
  204.          * @return      Size of Cuboid along the Z axis
  205.          */
  206.         public int getSizeZ() {
  207.                 return (this.z2 - this.z1) + 1;
  208.         }
  209.  
  210.         /**
  211.          * Get the minimum X co-ordinate of this Cuboid
  212.          *
  213.          * @return      the minimum X co-ordinate
  214.          */
  215.         public int getLowerX() {
  216.                 return this.x1;
  217.         }
  218.  
  219.         /**
  220.          * Get the minimum Y co-ordinate of this Cuboid
  221.          *
  222.          * @return      the minimum Y co-ordinate
  223.          */
  224.         public int getLowerY() {
  225.                 return this.y1;
  226.         }
  227.  
  228.         /**
  229.          * Get the minimum Z co-ordinate of this Cuboid
  230.          *
  231.          * @return      the minimum Z co-ordinate
  232.          */
  233.         public int getLowerZ() {
  234.                 return this.z1;
  235.         }
  236.  
  237.         /**
  238.          * Get the maximum X co-ordinate of this Cuboid
  239.          *
  240.          * @return      the maximum X co-ordinate
  241.          */
  242.         public int getUpperX() {
  243.                 return this.x2;
  244.         }
  245.  
  246.         /**
  247.          * Get the maximum Y co-ordinate of this Cuboid
  248.          *
  249.          * @return      the maximum Y co-ordinate
  250.          */
  251.         public int getUpperY() {
  252.                 return this.y2;
  253.         }
  254.  
  255.         /**
  256.          * Get the maximum Z co-ordinate of this Cuboid
  257.          *
  258.          * @return      the maximum Z co-ordinate
  259.          */
  260.         public int getUpperZ() {
  261.                 return this.z2;
  262.         }
  263.  
  264.         /**
  265.          * Get the Blocks at the eight corners of the Cuboid.
  266.          *
  267.          * @return array of Block objects representing the Cuboid corners
  268.          */
  269.         public Block[] corners() {
  270.                 Block[] res = new Block[8];
  271.                 World w = this.getWorld();
  272.                 res[0] = w.getBlockAt(this.x1, this.y1, this.z1);
  273.                 res[1] = w.getBlockAt(this.x1, this.y1, this.z2);
  274.                 res[2] = w.getBlockAt(this.x1, this.y2, this.z1);
  275.                 res[3] = w.getBlockAt(this.x1, this.y2, this.z2);
  276.                 res[4] = w.getBlockAt(this.x2, this.y1, this.z1);
  277.                 res[5] = w.getBlockAt(this.x2, this.y1, this.z2);
  278.                 res[6] = w.getBlockAt(this.x2, this.y2, this.z1);
  279.                 res[7] = w.getBlockAt(this.x2, this.y2, this.z2);
  280.                 return res;
  281.         }
  282.  
  283.         /**
  284.          * Expand the Cuboid in the given direction by the given amount.  Negative amounts will shrink the Cuboid in the given direction.  Shrinking a cuboid's face past the opposite face is not an error and will return a valid Cuboid.
  285.          *
  286.          * @param dir - The direction in which to expand
  287.          * @param amount - The number of blocks by which to expand
  288.          * @return A new Cuboid expanded by the given direction and amount
  289.          */
  290.         public Cuboid expand(CuboidDirection dir, int amount) {
  291.                 switch (dir) {
  292.                 case North:
  293.                         return new Cuboid(this.worldName, this.x1 - amount, this.y1, this.z1, this.x2, this.y2, this.z2);
  294.                 case South:
  295.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2 + amount, this.y2, this.z2);
  296.                 case East:
  297.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1 - amount, this.x2, this.y2, this.z2);
  298.                 case West:
  299.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z2 + amount);
  300.                 case Down:
  301.                         return new Cuboid(this.worldName, this.x1, this.y1 - amount, this.z1, this.x2, this.y2, this.z2);
  302.                 case Up:
  303.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2 + amount, this.z2);
  304.                 default:
  305.                         throw new IllegalArgumentException("Invalid direction " + dir);
  306.                 }
  307.         }
  308.  
  309.         /**
  310.          * Shift the Cuboid in the given direction by the given amount.
  311.          *
  312.          * @param dir - The direction in which to shift
  313.          * @param amount - The number of blocks by which to shift
  314.          * @return A new Cuboid shifted by the given direction and amount
  315.          */
  316.         public Cuboid shift(CuboidDirection dir, int amount) {
  317.                 return expand(dir, amount).expand(dir.opposite(), -amount);
  318.         }
  319.  
  320.         /**
  321.          * Outset (grow) the Cuboid in the given direction by the given amount.
  322.          *
  323.          * @param dir - The direction in which to outset (must be Horizontal, Vertical, or Both)
  324.          * @param amount - The number of blocks by which to outset
  325.          * @return A new Cuboid outset by the given direction and amount
  326.          */
  327.         public Cuboid outset(CuboidDirection dir, int amount) {
  328.                 Cuboid c;
  329.                 switch (dir) {
  330.                 case Horizontal:
  331.                         c = expand(CuboidDirection.North, amount).expand(CuboidDirection.South, amount).expand(CuboidDirection.East, amount).expand(CuboidDirection.West, amount);
  332.                         break;
  333.                 case Vertical:
  334.                         c = expand(CuboidDirection.Down, amount).expand(CuboidDirection.Up, amount);
  335.                         break;
  336.                 case Both:
  337.                         c = outset(CuboidDirection.Horizontal, amount).outset(CuboidDirection.Vertical, amount);
  338.                         break;
  339.                 default:
  340.                         throw new IllegalArgumentException("Invalid direction " + dir);
  341.                 }
  342.                 return c;
  343.         }
  344.  
  345.         /**
  346.          * Inset (shrink) the Cuboid in the given direction by the given amount.  Equivalent
  347.          * to calling outset() with a negative amount.
  348.          *
  349.          * @param dir - The direction in which to inset (must be Horizontal, Vertical, or Both)
  350.          * @param amount - The number of blocks by which to inset
  351.          * @return A new Cuboid inset by the given direction and amount
  352.          */
  353.         public Cuboid inset(CuboidDirection dir, int amount) {
  354.                 return this.outset(dir, -amount);
  355.         }
  356.  
  357.         /**
  358.          * Return true if the point at (x,y,z) is contained within this Cuboid.
  359.          *
  360.          * @param x     - The X co-ordinate
  361.          * @param y     - The Y co-ordinate
  362.          * @param z     - The Z co-ordinate
  363.          * @return true if the given point is within this Cuboid, false otherwise
  364.          */
  365.         public boolean contains(int x, int y, int z) {
  366.                 return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2 && z >= this.z1 && z <= this.z2;
  367.         }
  368.  
  369.         /**
  370.          * Check if the given Block is contained within this Cuboid.
  371.          *
  372.          * @param b     - The Block to check for
  373.          * @return true if the Block is within this Cuboid, false otherwise
  374.          */
  375.         public boolean contains(Block b) {
  376.                 return this.contains(b.getLocation());
  377.         }
  378.  
  379.         /**
  380.          * Check if the given Location is contained within this Cuboid.
  381.          *
  382.          * @param l     - The Location to check for
  383.          * @return true if the Location is within this Cuboid, false otherwise
  384.          */
  385.         public boolean contains(Location l) {
  386.                 if (!this.worldName.equals(l.getWorld().getName())) return false;
  387.                 return this.contains(l.getBlockX(), l.getBlockY(), l.getBlockZ());
  388.         }
  389.  
  390.         /**
  391.          * Get the volume of this Cuboid.
  392.          *
  393.          * @return The Cuboid volume, in blocks
  394.          */
  395.         public int getVolume() {
  396.                 return this.getSizeX() * this.getSizeY() * this.getSizeZ();
  397.         }
  398.  
  399.         /**
  400.          * Get the average light level of all empty (air) blocks in the Cuboid.  Returns 0 if there are no empty blocks.
  401.          *
  402.          * @return The average light level of this Cuboid
  403.          */
  404.         public byte getAverageLightLevel() {
  405.                 long total = 0;
  406.                 int n = 0;
  407.                 for (Block b : this) {
  408.                         if (b.isEmpty()) {
  409.                                 total += b.getLightLevel();
  410.                                 ++n;
  411.                         }
  412.                 }
  413.                 return n > 0 ? (byte) (total / n) : 0;
  414.         }
  415.  
  416.         /**
  417.          * Contract the Cuboid, returning a Cuboid with any air around the edges removed, just large enough to include all non-air blocks.
  418.          *
  419.          * @return A new Cuboid with no external air blocks
  420.          */
  421.         public Cuboid contract() {
  422.                 return this.contract(CuboidDirection.Down).contract(CuboidDirection.South).contract(CuboidDirection.East).contract(CuboidDirection.Up).contract(CuboidDirection.North).contract(CuboidDirection.West);
  423.         }
  424.  
  425.         /**
  426.          * Contract the Cuboid in the given direction, returning a new Cuboid which has no exterior empty space.
  427.          * E.g. A direction of Down will push the top face downwards as much as possible.
  428.          *
  429.          * @param dir - The direction in which to contract
  430.          * @return A new Cuboid contracted in the given direction
  431.          */
  432.         public Cuboid contract(CuboidDirection dir) {
  433.                 Cuboid face = getFace(dir.opposite());
  434.                 switch (dir) {
  435.                 case Down:
  436.                         while (face.containsOnly(0) && face.getLowerY() > this.getLowerY()) {
  437.                                 face = face.shift(CuboidDirection.Down, 1);
  438.                         }
  439.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, face.getUpperY(), this.z2);
  440.                 case Up:
  441.                         while (face.containsOnly(0) && face.getUpperY() < this.getUpperY()) {
  442.                                 face = face.shift(CuboidDirection.Up, 1);
  443.                         }
  444.                         return new Cuboid(this.worldName, this.x1, face.getLowerY(), this.z1, this.x2, this.y2, this.z2);
  445.                 case North:
  446.                         while (face.containsOnly(0) && face.getLowerX() > this.getLowerX()) {
  447.                                 face = face.shift(CuboidDirection.North, 1);
  448.                         }
  449.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, face.getUpperX(), this.y2, this.z2);
  450.                 case South:
  451.                         while (face.containsOnly(0) && face.getUpperX() < this.getUpperX()) {
  452.                                 face = face.shift(CuboidDirection.South, 1);
  453.                         }
  454.                         return new Cuboid(this.worldName, face.getLowerX(), this.y1, this.z1, this.x2, this.y2, this.z2);
  455.                 case East:
  456.                         while (face.containsOnly(0) && face.getLowerZ() > this.getLowerZ()) {
  457.                                 face = face.shift(CuboidDirection.East, 1);
  458.                         }
  459.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, face.getUpperZ());
  460.                 case West:
  461.                         while (face.containsOnly(0) && face.getUpperZ() < this.getUpperZ()) {
  462.                                 face = face.shift(CuboidDirection.West, 1);
  463.                         }
  464.                         return new Cuboid(this.worldName, this.x1, this.y1, face.getLowerZ(), this.x2, this.y2, this.z2);
  465.                 default:
  466.                         throw new IllegalArgumentException("Invalid direction " + dir);
  467.                 }
  468.         }
  469.  
  470.         /**
  471.          * Get the Cuboid representing the face of this Cuboid.  The resulting Cuboid will be one block thick in the axis perpendicular to the requested face.
  472.          *
  473.          * @param dir - which face of the Cuboid to get
  474.          * @return The Cuboid representing this Cuboid's requested face
  475.          */
  476.         public Cuboid getFace(CuboidDirection dir) {
  477.                 switch (dir) {
  478.                 case Down:
  479.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y1, this.z2);
  480.                 case Up:
  481.                         return new Cuboid(this.worldName, this.x1, this.y2, this.z1, this.x2, this.y2, this.z2);
  482.                 case North:
  483.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x1, this.y2, this.z2);
  484.                 case South:
  485.                         return new Cuboid(this.worldName, this.x2, this.y1, this.z1, this.x2, this.y2, this.z2);
  486.                 case East:
  487.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z1);
  488.                 case West:
  489.                         return new Cuboid(this.worldName, this.x1, this.y1, this.z2, this.x2, this.y2, this.z2);
  490.                 default:
  491.                         throw new IllegalArgumentException("Invalid direction " + dir);
  492.                 }
  493.         }
  494.  
  495.         /**
  496.          * Check if the Cuboid contains only blocks of the given type
  497.          *
  498.          * @param blockId - The block ID to check for
  499.          * @return true if this Cuboid contains only blocks of the given type
  500.          */
  501.         @SuppressWarnings("deprecation")
  502.         public boolean containsOnly(int blockId) {
  503.                 for (Block b : this) {
  504.                         if (b.getTypeId() != blockId) return false;
  505.                 }
  506.                 return true;
  507.         }
  508.  
  509.         /**
  510.          * Get the Cuboid big enough to hold both this Cuboid and the given one.
  511.          *
  512.          * @param other - The other cuboid.
  513.          * @return A new Cuboid large enough to hold this Cuboid and the given Cuboid
  514.          */
  515.         public Cuboid getBoundingCuboid(Cuboid other) {
  516.                 if (other == null) return this;
  517.  
  518.                 int xMin = Math.min(this.getLowerX(), other.getLowerX());
  519.                 int yMin = Math.min(this.getLowerY(), other.getLowerY());
  520.                 int zMin = Math.min(this.getLowerZ(), other.getLowerZ());
  521.                 int xMax = Math.max(this.getUpperX(), other.getUpperX());
  522.                 int yMax = Math.max(this.getUpperY(), other.getUpperY());
  523.                 int zMax = Math.max(this.getUpperZ(), other.getUpperZ());
  524.  
  525.                 return new Cuboid(this.worldName, xMin, yMin, zMin, xMax, yMax, zMax);
  526.         }
  527.  
  528.         /**
  529.          * Get a block relative to the lower NE point of the Cuboid.
  530.          *
  531.          * @param x     - The X co-ordinate
  532.          * @param y     - The Y co-ordinate
  533.          * @param z     - The Z co-ordinate
  534.          * @return The block at the given position
  535.          */
  536.         public Block getRelativeBlock(int x, int y, int z) {
  537.                 return this.getWorld().getBlockAt(this.x1 + x, this.y1 + y, this.z1 + z);
  538.         }
  539.  
  540.         /**
  541.          * Get a block relative to the lower NE point of the Cuboid in the given World.  This
  542.          * version of getRelativeBlock() should be used if being called many times, to avoid
  543.          * excessive calls to getWorld().
  544.          *
  545.          * @param w     - The world
  546.          * @param x     - The X co-ordinate    
  547.          * @param y     - The Y co-ordinate    
  548.          * @param z     - The Z co-ordinate    
  549.          * @return The block at the given position
  550.          */
  551.         public Block getRelativeBlock(World w, int x, int y, int z) {
  552.                 return w.getBlockAt(this.x1 + x, y1 + y, this.z1 + z);
  553.         }
  554.  
  555.         /**
  556.          * Get a list of the chunks which are fully or partially contained in this cuboid.
  557.          *
  558.          * @return A list of Chunk objects
  559.          */
  560.         public List<Chunk> getChunks() {
  561.                 List<Chunk> res = new ArrayList<Chunk>();
  562.  
  563.                 World w = this.getWorld();
  564.                 int x1 = this.getLowerX() & ~0xf;
  565.                 int x2 = this.getUpperX() & ~0xf;
  566.                 int z1 = this.getLowerZ() & ~0xf;
  567.                 int z2 = this.getUpperZ() & ~0xf;
  568.                 for (int x = x1; x <= x2; x += 16) {
  569.                         for (int z = z1; z <= z2; z += 16) {
  570.                                 res.add(w.getChunkAt(x >> 4, z >> 4));
  571.                         }
  572.                 }
  573.                 return res;
  574.         }
  575.  
  576.         public Iterator<Block> iterator() {
  577.                 return new CuboidIterator(this.getWorld(), this.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
  578.         }
  579.  
  580.         @Override
  581.         public Cuboid clone() {
  582.                 return new Cuboid(this);
  583.         }
  584.  
  585.         @Override
  586.         public String toString() {
  587.                 return new String("Cuboid: " + this.worldName + "," + this.x1 + "," + this.y1 + "," + this.z1 + "=>" + this.x2 + "," + this.y2 + "," + this.z2);
  588.         }
  589.  
  590.         public class CuboidIterator implements Iterator<Block> {
  591.                 private World w;
  592.                 private int baseX, baseY, baseZ;
  593.                 private int x, y, z;
  594.                 private int sizeX, sizeY, sizeZ;
  595.  
  596.                 public CuboidIterator(World w, int x1, int y1, int z1, int x2, int y2, int z2) {
  597.                         this.w = w;
  598.                         this.baseX = x1;
  599.                         this.baseY = y1;
  600.                         this.baseZ = z1;
  601.                         this.sizeX = Math.abs(x2 - x1) + 1;
  602.                         this.sizeY = Math.abs(y2 - y1) + 1;
  603.                         this.sizeZ = Math.abs(z2 - z1) + 1;
  604.                         this.x = this.y = this.z = 0;
  605.                 }
  606.  
  607.                 public boolean hasNext() {
  608.                         return this.x < this.sizeX && this.y < this.sizeY && this.z < this.sizeZ;
  609.                 }
  610.  
  611.                 public Block next() {
  612.                         Block b = this.w.getBlockAt(this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z);
  613.                         if (++x >= this.sizeX) {
  614.                                 this.x = 0;
  615.                                 if (++this.y >= this.sizeY) {
  616.                                         this.y = 0;
  617.                                         ++this.z;
  618.                                 }
  619.                         }
  620.                         return b;
  621.                 }
  622.  
  623.                 public void remove() {
  624.                 }
  625.         }
  626.  
  627.         public enum CuboidDirection {
  628.                 North, East, South, West, Up, Down, Horizontal, Vertical, Both, Unknown;
  629.  
  630.                 public CuboidDirection opposite() {
  631.                         switch (this) {
  632.                         case North:
  633.                                 return South;
  634.                         case East:
  635.                                 return West;
  636.                         case South:
  637.                                 return North;
  638.                         case West:
  639.                                 return East;
  640.                         case Horizontal:
  641.                                 return Vertical;
  642.                         case Vertical:
  643.                                 return Horizontal;
  644.                         case Up:
  645.                                 return Down;
  646.                         case Down:
  647.                                 return Up;
  648.                         case Both:
  649.                                 return Both;
  650.                         default:
  651.                                 return Unknown;
  652.                         }
  653.                 }
  654.  
  655.         }
  656.  
  657. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement