summaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/bukkit/Material.java36
-rw-r--r--src/main/java/org/bukkit/material/Cauldron.java51
-rw-r--r--src/main/java/org/bukkit/material/Door.java12
-rw-r--r--src/main/java/org/bukkit/material/Gate.java91
-rw-r--r--src/main/java/org/bukkit/material/Mushroom.java182
-rw-r--r--src/main/java/org/bukkit/material/Openable.java17
-rw-r--r--src/main/java/org/bukkit/material/SpawnEgg.java52
-rw-r--r--src/main/java/org/bukkit/material/TrapDoor.java53
-rw-r--r--src/main/java/org/bukkit/material/Vine.java185
9 files changed, 631 insertions, 48 deletions
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
index 69963a1c..942957c7 100644
--- a/src/main/java/org/bukkit/Material.java
+++ b/src/main/java/org/bukkit/Material.java
@@ -7,7 +7,9 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.Validate;
+import org.bukkit.map.MapView;
import org.bukkit.material.*;
+import org.bukkit.potion.Potion;
import org.bukkit.util.Java15Compat;
import com.google.common.collect.Maps;
@@ -115,26 +117,26 @@ public enum Material {
TRAP_DOOR(96, TrapDoor.class),
MONSTER_EGGS(97, MonsterEggs.class),
SMOOTH_BRICK(98, SmoothBrick.class),
- HUGE_MUSHROOM_1(99),
- HUGE_MUSHROOM_2(100),
+ HUGE_MUSHROOM_1(99, Mushroom.class),
+ HUGE_MUSHROOM_2(100, Mushroom.class),
IRON_FENCE(101),
THIN_GLASS(102),
MELON_BLOCK(103),
- PUMPKIN_STEM(104),
- MELON_STEM(105),
- VINE(106),
- FENCE_GATE(107),
- BRICK_STAIRS(108),
- SMOOTH_STAIRS(109),
+ PUMPKIN_STEM(104, MaterialData.class),
+ MELON_STEM(105, MaterialData.class),
+ VINE(106, Vine.class),
+ FENCE_GATE(107, Gate.class),
+ BRICK_STAIRS(108, Stairs.class),
+ SMOOTH_STAIRS(109, Stairs.class),
MYCEL(110),
WATER_LILY(111),
NETHER_BRICK(112),
NETHER_FENCE(113),
- NETHER_BRICK_STAIRS(114),
- NETHER_WARTS(115),
+ NETHER_BRICK_STAIRS(114, Stairs.class),
+ NETHER_WARTS(115, MaterialData.class),
ENCHANTMENT_TABLE(116),
- BREWING_STAND(117),
- CAULDRON(118),
+ BREWING_STAND(117, MaterialData.class),
+ CAULDRON(118, Cauldron.class),
ENDER_PORTAL(119),
ENDER_PORTAL_FRAME(120),
ENDER_STONE(121),
@@ -242,6 +244,9 @@ public enum Material {
BED(355, 1),
DIODE(356),
COOKIE(357),
+ /**
+ * @see MapView
+ */
MAP(358, 1, MaterialData.class),
SHEARS(359, 1, 238),
MELON(360),
@@ -257,7 +262,10 @@ public enum Material {
GHAST_TEAR(370),
GOLD_NUGGET(371),
NETHER_STALK(372),
- POTION(373, 1),
+ /**
+ * @see Potion
+ */
+ POTION(373, 1, MaterialData.class),
GLASS_BOTTLE(374),
SPIDER_EYE(375),
FERMENTED_SPIDER_EYE(376),
@@ -267,7 +275,7 @@ public enum Material {
CAULDRON_ITEM(380),
EYE_OF_ENDER(381),
SPECKLED_MELON(382),
- MONSTER_EGG(383, 1),
+ MONSTER_EGG(383, 1, SpawnEgg.class),
GOLD_RECORD(2256, 1),
GREEN_RECORD(2257, 1),
RECORD_3(2258, 1),
diff --git a/src/main/java/org/bukkit/material/Cauldron.java b/src/main/java/org/bukkit/material/Cauldron.java
new file mode 100644
index 00000000..3a923cba
--- /dev/null
+++ b/src/main/java/org/bukkit/material/Cauldron.java
@@ -0,0 +1,51 @@
+package org.bukkit.material;
+
+import org.bukkit.Material;
+
+/**
+ * Represents a cauldron
+ */
+public class Cauldron extends MaterialData {
+ private static final int CAULDRON_FULL = 3;
+ private static final int CAULDRON_EMPTY = 0;
+
+ public Cauldron() {
+ super(Material.CAULDRON);
+ }
+
+ public Cauldron(int type, byte data){
+ super(type, data);
+ }
+
+ public Cauldron(byte data) {
+ super(Material.CAULDRON, data);
+ }
+
+ /**
+ * Check if the cauldron is full.
+ *
+ * @return True if it is full.
+ */
+ public boolean isFull() {
+ return getData() >= CAULDRON_FULL;
+ }
+
+ /**
+ * Check if the cauldron is empty.
+ *
+ * @return True if it is empty.
+ */
+ public boolean isEmpty() {
+ return getData() <= CAULDRON_EMPTY;
+ }
+
+ @Override
+ public String toString() {
+ return (isEmpty() ? "EMPTY" : (isFull() ? "FULL" : getData() + "/3 FULL")) + " CAULDRON";
+ }
+
+ @Override
+ public Cauldron clone() {
+ return (Cauldron) super.clone();
+ }
+}
diff --git a/src/main/java/org/bukkit/material/Door.java b/src/main/java/org/bukkit/material/Door.java
index 14226790..e992c28e 100644
--- a/src/main/java/org/bukkit/material/Door.java
+++ b/src/main/java/org/bukkit/material/Door.java
@@ -6,7 +6,7 @@ import org.bukkit.block.BlockFace;
/**
* Represents a door.
*/
-public class Door extends MaterialData implements Directional {
+public class Door extends MaterialData implements Directional, Openable {
public Door() {
super(Material.WOODEN_DOOR);
}
@@ -27,20 +27,10 @@ public class Door extends MaterialData implements Directional {
super(type, data);
}
- /**
- * Check to see if the door is open.
- *
- * @return true if the door has swung counterclockwise around its hinge.
- */
public boolean isOpen() {
return ((getData() & 0x4) == 0x4);
}
- /**
- * Configure this door to be either open or closed;
- *
- * @param isOpen True to open the door.
- */
public void setOpen(boolean isOpen) {
setData((byte) (isOpen ? (getData() | 0x4) : (getData() & ~0x4)));
}
diff --git a/src/main/java/org/bukkit/material/Gate.java b/src/main/java/org/bukkit/material/Gate.java
new file mode 100644
index 00000000..e80abe7a
--- /dev/null
+++ b/src/main/java/org/bukkit/material/Gate.java
@@ -0,0 +1,91 @@
+package org.bukkit.material;
+
+import org.bukkit.Material;
+import org.bukkit.block.BlockFace;
+
+/**
+ * Represents a fence gate
+ */
+public class Gate extends MaterialData implements Directional, Openable {
+ private static final byte OPEN_BIT = 0x4;
+ private static final byte DIR_BIT = 0x3;
+ private static final byte GATE_SOUTH = 0x0;
+ private static final byte GATE_WEST = 0x1;
+ private static final byte GATE_NORTH = 0x2;
+ private static final byte GATE_EAST = 0x3;
+
+ public Gate() {
+ super(Material.FENCE_GATE);
+ }
+
+ public Gate(int type, byte data){
+ super(type, data);
+ }
+
+ public Gate(byte data) {
+ super(Material.FENCE_GATE, data);
+ }
+
+ public void setFacingDirection(BlockFace face) {
+ byte data = (byte) (getData() &~ DIR_BIT);
+
+ switch (face) {
+ default:
+ case SOUTH:
+ data |= GATE_SOUTH;
+ break;
+ case WEST:
+ data |= GATE_WEST;
+ break;
+ case NORTH:
+ data |= GATE_NORTH;
+ break;
+ case EAST:
+ data |= GATE_EAST;
+ break;
+ }
+
+ setData(data);
+ }
+
+ public BlockFace getFacing() {
+ switch (getData() & DIR_BIT) {
+ case GATE_SOUTH:
+ return BlockFace.SOUTH;
+ case GATE_WEST:
+ return BlockFace.WEST;
+ case GATE_NORTH:
+ return BlockFace.NORTH;
+ case GATE_EAST:
+ return BlockFace.EAST;
+ }
+
+ return BlockFace.SOUTH;
+ }
+
+ public boolean isOpen() {
+ return (getData() & OPEN_BIT) > 0;
+ }
+
+ public void setOpen(boolean isOpen) {
+ byte data = getData();
+
+ if (isOpen) {
+ data |= OPEN_BIT;
+ } else {
+ data &= ~OPEN_BIT;
+ }
+
+ setData(data);
+ }
+
+ @Override
+ public String toString() {
+ return (isOpen() ? "OPEN " : "CLOSED ") + " facing and opening " + getFacing();
+ }
+
+ @Override
+ public Gate clone() {
+ return (Gate) super.clone();
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/bukkit/material/Mushroom.java b/src/main/java/org/bukkit/material/Mushroom.java
new file mode 100644
index 00000000..237a17a5
--- /dev/null
+++ b/src/main/java/org/bukkit/material/Mushroom.java
@@ -0,0 +1,182 @@
+package org.bukkit.material;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.apache.commons.lang.Validate;
+import org.bukkit.Material;
+import org.bukkit.block.BlockFace;
+
+/**
+ * Represents a huge mushroom block
+ */
+public class Mushroom extends MaterialData {
+ private static final byte SHROOM_NONE = 0;
+ private static final byte SHROOM_STEM = 10;
+ private static final byte NORTH_LIMIT = 4;
+ private static final byte SOUTH_LIMIT = 6;
+ private static final byte EAST_WEST_LIMIT = 3;
+ private static final byte EAST_REMAINDER = 0;
+ private static final byte WEST_REMAINDER = 1;
+ private static final byte NORTH_SOUTH_MOD = 3;
+ private static final byte EAST_WEST_MOD = 1;
+
+ public Mushroom(Material shroom) {
+ super(shroom);
+ Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!");
+ }
+
+ public Mushroom(Material shroom, byte data) {
+ super(shroom, data);
+ Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!");
+ }
+
+ public Mushroom(int type, byte data){
+ super(type, data);
+ Validate.isTrue(type == Material.HUGE_MUSHROOM_1.getId() || type == Material.HUGE_MUSHROOM_2.getId(), "Not a mushroom!");
+ }
+
+ /**
+ * @return Whether this is a mushroom stem.
+ */
+ public boolean isStem() {
+ return getData() == SHROOM_STEM;
+ }
+
+ /**
+ * Sets this to be a mushroom stem.
+ */
+ public void setStem() {
+ setData((byte) 10);
+ }
+
+ /**
+ * Checks whether a face of the block is painted.
+ * @param face The face to check.
+ * @return True if it is painted.
+ */
+ public boolean isFacePainted(BlockFace face) {
+ byte data = getData();
+
+ if (data == SHROOM_NONE || data == SHROOM_STEM) {
+ return false;
+ }
+
+ switch (face) {
+ case NORTH:
+ return data < NORTH_LIMIT;
+ case SOUTH:
+ return data > SOUTH_LIMIT;
+ case EAST:
+ return data % EAST_WEST_LIMIT == EAST_REMAINDER;
+ case WEST:
+ return data % EAST_WEST_LIMIT == WEST_REMAINDER;
+ case UP:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Set a face of the block to be painted or not. Note that due to the nature of how the data is stored,
+ * setting a face painted or not is not guaranteed to leave the other faces unchanged.
+ * @param face The face to paint or unpaint.
+ * @param painted True if you want to paint it, false if you want the pores to show.
+ */
+ public void setFacePainted(BlockFace face, boolean painted) {
+ if (painted == isFacePainted(face)) {
+ return;
+ }
+
+ byte data = getData();
+
+ if (data == SHROOM_STEM) {
+ data = 5;
+ }
+
+ switch (face) {
+ case NORTH:
+ if (painted) {
+ data -= NORTH_SOUTH_MOD;
+ } else {
+ data += NORTH_SOUTH_MOD;
+ }
+
+ break;
+ case SOUTH:
+ if (painted) {
+ data += NORTH_SOUTH_MOD;
+ } else {
+ data -= NORTH_SOUTH_MOD;
+ }
+
+ break;
+ case EAST:
+ if (painted) {
+ data += EAST_WEST_MOD;
+ } else {
+ data -= EAST_WEST_MOD;
+ }
+
+ break;
+ case WEST:
+ if (painted) {
+ data -= EAST_WEST_MOD;
+ } else {
+ data += EAST_WEST_MOD;
+ }
+
+ break;
+ case UP:
+ if (!painted) {
+ data = 0;
+ }
+
+ break;
+ default:
+ throw new IllegalArgumentException("Can't paint that face of a mushroom!");
+ }
+
+ setData(data);
+ }
+
+ /**
+ * @return A set of all faces that are currently painted (an empty set if it is a stem)
+ */
+ public Set<BlockFace> getPaintedFaces() {
+ EnumSet<BlockFace> faces = EnumSet.noneOf(BlockFace.class);
+
+ if (isFacePainted(BlockFace.NORTH)) {
+ faces.add(BlockFace.NORTH);
+ }
+
+ if (isFacePainted(BlockFace.EAST)) {
+ faces.add(BlockFace.EAST);
+ }
+
+ if (isFacePainted(BlockFace.WEST)) {
+ faces.add(BlockFace.WEST);
+ }
+
+ if (isFacePainted(BlockFace.SOUTH)) {
+ faces.add(BlockFace.SOUTH);
+ }
+
+ if (isFacePainted(BlockFace.UP)) {
+ faces.add(BlockFace.UP);
+ }
+
+ return faces;
+ }
+
+ @Override
+ public String toString() {
+ return Material.getMaterial(getItemTypeId()).toString() + (isStem() ? "{STEM}" : getPaintedFaces());
+ }
+
+ @Override
+ public Mushroom clone() {
+ return (Mushroom) super.clone();
+ }
+}
diff --git a/src/main/java/org/bukkit/material/Openable.java b/src/main/java/org/bukkit/material/Openable.java
new file mode 100644
index 00000000..17e5f022
--- /dev/null
+++ b/src/main/java/org/bukkit/material/Openable.java
@@ -0,0 +1,17 @@
+package org.bukkit.material;
+
+public interface Openable {
+ /**
+ * Check to see if the door is open.
+ *
+ * @return true if the door has swung counterclockwise around its hinge.
+ */
+ boolean isOpen();
+
+ /**
+ * Configure this door to be either open or closed;
+ *
+ * @param isOpen True to open the door.
+ */
+ void setOpen(boolean isOpen);
+}
diff --git a/src/main/java/org/bukkit/material/SpawnEgg.java b/src/main/java/org/bukkit/material/SpawnEgg.java
new file mode 100644
index 00000000..7ee0f1bd
--- /dev/null
+++ b/src/main/java/org/bukkit/material/SpawnEgg.java
@@ -0,0 +1,52 @@
+package org.bukkit.material;
+
+import org.bukkit.Material;
+import org.bukkit.entity.EntityType;
+
+/**
+ * Represents a spawn egg that can be used to spawn mobs
+ */
+public class SpawnEgg extends MaterialData {
+ public SpawnEgg() {
+ super(Material.MONSTER_EGG);
+ }
+
+ public SpawnEgg(int type, byte data){
+ super(type, data);
+ }
+
+ public SpawnEgg(byte data) {
+ super(Material.MONSTER_EGG, data);
+ }
+
+ public SpawnEgg(EntityType type) {
+ this();
+ setSpawnedType(type);
+ }
+
+ /**
+ * Get the type of entity this egg will spawn.
+ * @return The entity type.
+ */
+ public EntityType getSpawnedType() {
+ return EntityType.fromId(getData());
+ }
+
+ /**
+ * Set the type of entity this egg will spawn.
+ * @param type The entity type.
+ */
+ public void setSpawnedType(EntityType type) {
+ setData((byte) type.getTypeId());
+ }
+
+ @Override
+ public String toString() {
+ return "SPAWN EGG{" + getSpawnedType() + "}";
+ }
+
+ @Override
+ public SpawnEgg clone() {
+ return (SpawnEgg) super.clone();
+ }
+}
diff --git a/src/main/java/org/bukkit/material/TrapDoor.java b/src/main/java/org/bukkit/material/TrapDoor.java
index f709fcf9..c280c78f 100644
--- a/src/main/java/org/bukkit/material/TrapDoor.java
+++ b/src/main/java/org/bukkit/material/TrapDoor.java
@@ -6,7 +6,7 @@ import org.bukkit.block.BlockFace;
/**
* Represents a trap door
*/
-public class TrapDoor extends SimpleAttachableMaterialData {
+public class TrapDoor extends SimpleAttachableMaterialData implements Openable {
public TrapDoor() {
super(Material.TRAP_DOOR);
}
@@ -27,30 +27,37 @@ public class TrapDoor extends SimpleAttachableMaterialData {
super(type, data);
}
- /**
- * Check to see if the trap door is open.
- *
- * @return true if the trap door is open.
- */
public boolean isOpen() {
return ((getData() & 0x4) == 0x4);
}
+ public void setOpen(boolean isOpen) {
+ byte data = getData();
+
+ if (isOpen) {
+ data |= 0x4;
+ } else {
+ data &= ~0x4;
+ }
+
+ setData(data);
+ }
+
public BlockFace getAttachedFace() {
byte data = (byte) (getData() & 0x3);
switch (data) {
- case 0x0:
- return BlockFace.WEST;
+ case 0x0:
+ return BlockFace.WEST;
- case 0x1:
- return BlockFace.EAST;
+ case 0x1:
+ return BlockFace.EAST;
- case 0x2:
- return BlockFace.SOUTH;
+ case 0x2:
+ return BlockFace.SOUTH;
- case 0x3:
- return BlockFace.NORTH;
+ case 0x3:
+ return BlockFace.NORTH;
}
return null;
@@ -61,15 +68,15 @@ public class TrapDoor extends SimpleAttachableMaterialData {
byte data = (byte) (getData() & 0x4);
switch (face) {
- case WEST:
- data |= 0x1;
- break;
- case NORTH:
- data |= 0x2;
- break;
- case SOUTH:
- data |= 0x3;
- break;
+ case WEST:
+ data |= 0x1;
+ break;
+ case NORTH:
+ data |= 0x2;
+ break;
+ case SOUTH:
+ data |= 0x3;
+ break;
}
setData(data);
diff --git a/src/main/java/org/bukkit/material/Vine.java b/src/main/java/org/bukkit/material/Vine.java
new file mode 100644
index 00000000..beb92480
--- /dev/null
+++ b/src/main/java/org/bukkit/material/Vine.java
@@ -0,0 +1,185 @@
+package org.bukkit.material;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+
+import org.bukkit.Material;
+import org.bukkit.block.BlockFace;
+
+/**
+ * Represents a vine
+ */
+public class Vine extends MaterialData {
+ private static final int VINE_NORTH = 0x4;
+ private static final int VINE_EAST = 0x8;
+ private static final int VINE_WEST = 0x2;
+ private static final int VINE_SOUTH = 0x1;
+ EnumSet<BlockFace> possibleFaces = EnumSet.of(BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH);
+
+ public Vine() {
+ super(Material.VINE);
+ }
+
+ public Vine(int type, byte data){
+ super(type, data);
+ }
+
+ public Vine(byte data) {
+ super(Material.VINE, data);
+ }
+
+ public Vine(BlockFace... faces) {
+ this(EnumSet.copyOf(Arrays.asList(faces)));
+ }
+
+ public Vine(EnumSet<BlockFace> faces) {
+ this((byte) 0);
+ faces.retainAll(possibleFaces);
+
+ byte data = 0;
+
+ if (faces.contains(BlockFace.NORTH)) {
+ data |= VINE_NORTH;
+ }
+
+ if (faces.contains(BlockFace.EAST)) {
+ data |= VINE_EAST;
+ }
+
+ if (faces.contains(BlockFace.WEST)) {
+ data |= VINE_WEST;
+ }
+
+ if (faces.contains(BlockFace.SOUTH)) {
+ data |= VINE_SOUTH;
+ }
+
+ setData(data);
+ }
+
+ /**
+ * Check if the vine is attached to the specified face of an adjacent block. You can
+ * check two faces at once by passing eg {@link BlockFace#NORTH_EAST}.
+ *
+ * @param face The face to check.
+ * @return Whether it is attached to that face.
+ */
+ public boolean isOnFace(BlockFace face) {
+ switch (face) {
+ case NORTH:
+ return (getData() & VINE_NORTH) > 0;
+ case EAST:
+ return (getData() & VINE_EAST) > 0;
+ case WEST:
+ return (getData() & VINE_WEST) > 0;
+ case SOUTH:
+ return (getData() & VINE_SOUTH) > 0;
+ case NORTH_EAST:
+ return isOnFace(BlockFace.NORTH) && isOnFace(BlockFace.EAST);
+ case NORTH_WEST:
+ return isOnFace(BlockFace.NORTH) && isOnFace(BlockFace.WEST);
+ case SOUTH_EAST:
+ return isOnFace(BlockFace.SOUTH) && isOnFace(BlockFace.EAST);
+ case SOUTH_WEST:
+ return isOnFace(BlockFace.SOUTH) && isOnFace(BlockFace.WEST);
+ case UP: // It's impossible to be accurate with this since it's contextual
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Attach the vine to the specified face of an adjacent block.
+ *
+ * @param face The face to attach.
+ */
+ public void putOnFace(BlockFace face) {
+ switch(face) {
+ case NORTH:
+ setData((byte) (getData() | VINE_NORTH));
+ break;
+ case EAST:
+ setData((byte) (getData() | VINE_EAST));
+ break;
+ case WEST:
+ setData((byte) (getData() | VINE_WEST));
+ break;
+ case SOUTH:
+ setData((byte) (getData() | VINE_SOUTH));
+ break;
+ case NORTH_EAST:
+ putOnFace(BlockFace.NORTH);
+ putOnFace(BlockFace.EAST);
+ break;
+ case NORTH_WEST:
+ putOnFace(BlockFace.NORTH);
+ putOnFace(BlockFace.WEST);
+ break;
+ case SOUTH_EAST:
+ putOnFace(BlockFace.SOUTH);
+ putOnFace(BlockFace.EAST);
+ break;
+ case SOUTH_WEST:
+ putOnFace(BlockFace.SOUTH);
+ putOnFace(BlockFace.WEST);
+ break;
+ case UP:
+ break;
+ default:
+ throw new IllegalArgumentException("Vines can't go on face " + face.toString());
+ }
+ }
+
+ /**
+ * Detach the vine from the specified face of an adjacent block.
+ *
+ * @param face The face to detach.
+ */
+ public void removeFromFace(BlockFace face) {
+ switch(face) {
+ case NORTH:
+ setData((byte) (getData() &~ VINE_NORTH));
+ break;
+ case EAST:
+ setData((byte) (getData() &~ VINE_EAST));
+ break;
+ case WEST:
+ setData((byte) (getData() &~ VINE_WEST));
+ break;
+ case SOUTH:
+ setData((byte) (getData() &~ VINE_SOUTH));
+ break;
+ case NORTH_EAST:
+ removeFromFace(BlockFace.NORTH);
+ removeFromFace(BlockFace.EAST);
+ break;
+ case NORTH_WEST:
+ removeFromFace(BlockFace.NORTH);
+ removeFromFace(BlockFace.WEST);
+ break;
+ case SOUTH_EAST:
+ removeFromFace(BlockFace.SOUTH);
+ removeFromFace(BlockFace.EAST);
+ break;
+ case SOUTH_WEST:
+ removeFromFace(BlockFace.SOUTH);
+ removeFromFace(BlockFace.WEST);
+ break;
+ case UP:
+ break;
+ default:
+ throw new IllegalArgumentException("Vines can't go on face " + face.toString());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "VINE";
+ }
+
+ @Override
+ public Vine clone() {
+ return (Vine) super.clone();
+ }
+}