summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorryanbennitt <ryanbennitt@googlemail.com>2016-03-26 09:26:20 +1100
committermd_5 <git@md-5.net>2016-03-26 09:40:09 +1100
commit996146280e6e9fb4cc6f43235f22f4e568431597 (patch)
treeaa37967267234d24397b9451e109d07b00f385ce /src
parentccc245a7e6fd9406220d69d583b5e8eeeb0bfe3e (diff)
downloadbukkit-996146280e6e9fb4cc6f43235f22f4e568431597.tar
bukkit-996146280e6e9fb4cc6f43235f22f4e568431597.tar.gz
bukkit-996146280e6e9fb4cc6f43235f22f4e568431597.tar.lz
bukkit-996146280e6e9fb4cc6f43235f22f4e568431597.tar.xz
bukkit-996146280e6e9fb4cc6f43235f22f4e568431597.zip
SPIGOT-1682: Fixed block data for Beetroot
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/bukkit/Material.java4
-rw-r--r--src/main/java/org/bukkit/material/Crops.java84
-rw-r--r--src/test/java/org/bukkit/materials/MaterialDataTest.java62
3 files changed, 142 insertions, 8 deletions
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
index 295ffa85..6de16317 100644
--- a/src/main/java/org/bukkit/Material.java
+++ b/src/main/java/org/bukkit/Material.java
@@ -208,8 +208,8 @@ public enum Material {
BEACON(138),
COBBLE_WALL(139),
FLOWER_POT(140, FlowerPot.class),
- CARROT(141),
- POTATO(142),
+ CARROT(141, Crops.class),
+ POTATO(142, Crops.class),
WOOD_BUTTON(143, Button.class),
SKULL(144, Skull.class),
ANVIL(145),
diff --git a/src/main/java/org/bukkit/material/Crops.java b/src/main/java/org/bukkit/material/Crops.java
index 0a4f8f17..f48637d0 100644
--- a/src/main/java/org/bukkit/material/Crops.java
+++ b/src/main/java/org/bukkit/material/Crops.java
@@ -4,15 +4,43 @@ import org.bukkit.CropState;
import org.bukkit.Material;
/**
- * Represents the different types of crops.
+ * Represents the different types of crops in different states of growth.
+ *
+ * @see Material#CROPS
+ * @see Material#CARROT
+ * @see Material#POTATO
+ * @see Material#BEETROOT_BLOCK
+ * @see Material#NETHER_WARTS
*/
public class Crops extends MaterialData {
+ protected static final Material DEFAULT_TYPE = Material.CROPS;
+ protected static final CropState DEFAULT_STATE = CropState.SEEDED;
+
+ /**
+ * Constructs a wheat crop block in the seeded state.
+ */
public Crops() {
- super(Material.CROPS);
+ this(DEFAULT_TYPE, DEFAULT_STATE);
}
+ /**
+ * Constructs a wheat crop block in the given growth state
+ *
+ * @param state The growth state of the crops
+ */
public Crops(CropState state) {
- this();
+ this(DEFAULT_TYPE, state);
+ setState(state);
+ }
+
+ /**
+ * Constructs a crop block of the given type and in the given growth state
+ *
+ * @param type The type of crops
+ * @param state The growth state of the crops
+ */
+ public Crops(final Material type, final CropState state) {
+ super(type);
setState(state);
}
@@ -25,8 +53,13 @@ public class Crops extends MaterialData {
super(type);
}
+ /**
+ * Constructs a crop block of the given type and in the seeded state
+ *
+ * @param type The type of crops
+ */
public Crops(final Material type) {
- super(type);
+ this(type, DEFAULT_STATE);
}
/**
@@ -52,19 +85,58 @@ public class Crops extends MaterialData {
/**
* Gets the current growth state of this crop
*
+ * For crops with only four growth states such as beetroot, only the values SEEDED, SMALL, TALL and RIPE will be
+ * returned.
+ *
* @return CropState of this crop
*/
public CropState getState() {
- return CropState.getByData(getData());
+ switch (getItemType()) {
+ case CROPS:
+ case CARROT:
+ case POTATO:
+ // Mask the data just in case top bit set
+ return CropState.getByData((byte)(getData() & 0x7));
+ case BEETROOT_BLOCK:
+ case NETHER_WARTS:
+ // Mask the data just in case top bits are set
+ // Will return SEEDED, SMALL, TALL, RIPE for the three growth data values
+ return CropState.getByData((byte)(((getData() & 0x3)*7+2)/3)) ;
+ default:
+ throw new IllegalArgumentException("Block type is not a crop");
+ }
}
/**
* Sets the growth state of this crop
*
+ * For crops with only four growth states such as beetroot, the 8 CropStates are mapped into four states:
+ *
+ * SEEDED, SMALL, TALL and RIPE
+ *
+ * GERMINATED will change to SEEDED
+ * VERY_SMALL will change to SMALL
+ * MEDIUM will change to TALL
+ * VERY_TALL will change to RIPE
+ *
* @param state New growth state of this crop
*/
public void setState(CropState state) {
- setData(state.getData());
+ switch (getItemType()) {
+ case CROPS:
+ case CARROT:
+ case POTATO:
+ // Preserve the top bit in case it is set
+ setData((byte)((getData() & 0x8)|state.getData()));
+ break;
+ case NETHER_WARTS:
+ case BEETROOT_BLOCK:
+ // Preserve the top bits in case they are set
+ setData((byte)((getData() & 0xC)|(state.getData() >> 1)));
+ break;
+ default:
+ throw new IllegalArgumentException("Block type is not a crop");
+ }
}
@Override
diff --git a/src/test/java/org/bukkit/materials/MaterialDataTest.java b/src/test/java/org/bukkit/materials/MaterialDataTest.java
index 3eaede3c..2be3ddc9 100644
--- a/src/test/java/org/bukkit/materials/MaterialDataTest.java
+++ b/src/test/java/org/bukkit/materials/MaterialDataTest.java
@@ -3,12 +3,16 @@ package org.bukkit.materials;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
+import org.bukkit.CropState;
import org.bukkit.Material;
+import org.bukkit.NetherWartsState;
import org.bukkit.TreeSpecies;
import org.bukkit.block.BlockFace;
+import org.bukkit.material.Crops;
import org.bukkit.material.Door;
import org.bukkit.material.Leaves;
import org.bukkit.material.Mushroom;
+import org.bukkit.material.NetherWarts;
import org.bukkit.material.Sapling;
import org.bukkit.material.Tree;
import org.bukkit.material.Wood;
@@ -259,4 +263,62 @@ public class MaterialDataTest {
}
}
}
+
+ @Test
+ public void testCrops() {
+ Crops crops = new Crops();
+ assertThat("Constructed with default crops type", crops.getItemType(), equalTo(Material.CROPS));
+ assertThat("Constructed with default crop state", crops.getState(), equalTo(CropState.SEEDED));
+
+ CropState[] allStates = CropState.values();
+ for (CropState state : allStates) {
+ crops = new Crops(state);
+ assertThat("Constructed with default crops type", crops.getItemType(), equalTo(Material.CROPS));
+ assertThat("Constructed with correct crop state", crops.getState(), equalTo(state));
+ }
+
+ // The crops which fully implement all crop states
+ Material[] allCrops = new Material[] {Material.CROPS, Material.CARROT, Material.POTATO};
+ for (Material crop : allCrops) {
+ crops = new Crops(crop);
+ assertThat("Constructed with correct crops type", crops.getItemType(), equalTo(crop));
+ assertThat("Constructed with default crop state", crops.getState(), equalTo(CropState.SEEDED));
+
+ for (CropState state : allStates) {
+ crops = new Crops(crop, state);
+ assertThat("Constructed with correct crops type", crops.getItemType(), equalTo(crop));
+ assertThat("Constructed with correct crop state", crops.getState(), equalTo(state));
+ }
+ }
+
+ // Beetroot are crops too, but they only have four states
+ // Setting different crop states for beetroot will return the following when retrieved back
+ CropState[] beetrootStates = new CropState[] {CropState.SEEDED, CropState.SEEDED, CropState.SMALL, CropState.SMALL, CropState.TALL, CropState.TALL, CropState.RIPE, CropState.RIPE};
+ assertThat("Beetroot state translations match size", beetrootStates.length, equalTo(allStates.length));
+ crops = new Crops(Material.BEETROOT_BLOCK);
+ assertThat("Constructed with correct crops type", crops.getItemType(), equalTo(Material.BEETROOT_BLOCK));
+ assertThat("Constructed with default crop state", crops.getState(), equalTo(CropState.SEEDED));
+ for (int s = 0; s < beetrootStates.length; s++) {
+ crops = new Crops(Material.BEETROOT_BLOCK, allStates[s]);
+ assertThat("Constructed with correct crops type", crops.getItemType(), equalTo(Material.BEETROOT_BLOCK));
+ assertThat("Constructed with correct crop state", crops.getState(), equalTo(beetrootStates[s]));
+ }
+
+ // In case you want to treat NetherWarts as Crops, although they really aren't
+ crops = new Crops(Material.NETHER_WARTS);
+ NetherWarts warts = new NetherWarts();
+ assertThat("Constructed with correct crops type", crops.getItemType(), equalTo(warts.getItemType()));
+ assertThat("Constructed with default crop state", crops.getState(), equalTo(CropState.SEEDED));
+ assertThat("Constructed with default wart state", warts.getState(), equalTo(NetherWartsState.SEEDED));
+ allStates = new CropState[] {CropState.SEEDED, CropState.SMALL, CropState.TALL, CropState.RIPE};
+ NetherWartsState[] allWartStates = NetherWartsState.values();
+ assertThat("Nether Warts state translations match size", allWartStates.length, equalTo(allStates.length));
+ for (int s = 0; s < allStates.length; s++) {
+ crops = new Crops(Material.NETHER_WARTS, allStates[s]);
+ warts = new NetherWarts(allWartStates[s]);
+ assertThat("Constructed with correct crops type", crops.getItemType(), equalTo(warts.getItemType()));
+ assertThat("Constructed with correct crop state", crops.getState(), equalTo(allStates[s]));
+ assertThat("Constructed with correct wart state", warts.getState(), equalTo(allWartStates[s]));
+ }
+ }
}