From f16cc648404ac87f5292ab67641395c818a477ab Mon Sep 17 00:00:00 2001 From: ryanbennitt Date: Tue, 1 Mar 2016 08:30:03 +1100 Subject: SPIGOT-1389: Fixed issues with setting tree species by expanding API --- src/main/java/org/bukkit/Material.java | 16 +- src/main/java/org/bukkit/material/Leaves.java | 107 +++++++++-- src/main/java/org/bukkit/material/Sapling.java | 121 +++++++++++++ src/main/java/org/bukkit/material/Tree.java | 105 +++++++---- src/main/java/org/bukkit/material/Wood.java | 196 +++++++++++++++++++++ src/main/java/org/bukkit/material/WoodenStep.java | 73 ++++---- .../org/bukkit/materials/MaterialDataTest.java | 173 ++++++++++++++++++ 7 files changed, 697 insertions(+), 94 deletions(-) create mode 100644 src/main/java/org/bukkit/material/Sapling.java create mode 100644 src/main/java/org/bukkit/material/Wood.java (limited to 'src') diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java index 41becbe3..fdb619e7 100644 --- a/src/main/java/org/bukkit/Material.java +++ b/src/main/java/org/bukkit/Material.java @@ -24,6 +24,7 @@ import org.bukkit.material.FlowerPot; import org.bukkit.material.Furnace; import org.bukkit.material.Gate; import org.bukkit.material.Ladder; +import org.bukkit.material.Leaves; import org.bukkit.material.Lever; import org.bukkit.material.LongGrass; import org.bukkit.material.MaterialData; @@ -39,6 +40,7 @@ import org.bukkit.material.Rails; import org.bukkit.material.RedstoneTorch; import org.bukkit.material.RedstoneWire; import org.bukkit.material.Sandstone; +import org.bukkit.material.Sapling; import org.bukkit.material.Sign; import org.bukkit.material.Skull; import org.bukkit.material.SmoothBrick; @@ -51,12 +53,14 @@ import org.bukkit.material.Tree; import org.bukkit.material.Tripwire; import org.bukkit.material.TripwireHook; import org.bukkit.material.Vine; +import org.bukkit.material.Wood; import org.bukkit.material.WoodenStep; import org.bukkit.material.Wool; import org.bukkit.potion.Potion; import org.bukkit.util.Java15Compat; import com.google.common.collect.Maps; + import org.bukkit.material.Banner; /** @@ -68,8 +72,8 @@ public enum Material { GRASS(2), DIRT(3), COBBLESTONE(4), - WOOD(5, Tree.class), - SAPLING(6, Tree.class), + WOOD(5, Wood.class), + SAPLING(6, Sapling.class), BEDROCK(7), WATER(8, MaterialData.class), STATIONARY_WATER(9, MaterialData.class), @@ -81,7 +85,7 @@ public enum Material { IRON_ORE(15), COAL_ORE(16), LOG(17, Tree.class), - LEAVES(18, Tree.class), + LEAVES(18, Leaves.class), SPONGE(19), GLASS(20), LAPIS_ORE(21), @@ -188,7 +192,7 @@ public enum Material { DRAGON_EGG(122), REDSTONE_LAMP_OFF(123), REDSTONE_LAMP_ON(124), - WOOD_DOUBLE_STEP(125, WoodenStep.class), + WOOD_DOUBLE_STEP(125, Wood.class), WOOD_STEP(126, WoodenStep.class), COCOA(127, CocoaPlant.class), SANDSTONE_STAIRS(128, Stairs.class), @@ -224,8 +228,8 @@ public enum Material { DROPPER(158, Dispenser.class), STAINED_CLAY(159), STAINED_GLASS_PANE(160), - LEAVES_2(161), - LOG_2(162), + LEAVES_2(161, Leaves.class), + LOG_2(162, Tree.class), ACACIA_STAIRS(163, Stairs.class), DARK_OAK_STAIRS(164, Stairs.class), SLIME_BLOCK(165), diff --git a/src/main/java/org/bukkit/material/Leaves.java b/src/main/java/org/bukkit/material/Leaves.java index 9f40a23d..1be14094 100644 --- a/src/main/java/org/bukkit/material/Leaves.java +++ b/src/main/java/org/bukkit/material/Leaves.java @@ -4,16 +4,41 @@ import org.bukkit.Material; import org.bukkit.TreeSpecies; /** - * Represents the different types of leaves. + * Represents the different types of leaf block that may be permanent or can + * decay when too far from a log. + * + * @see Material.LEAVES + * @see Material.LEAVES_2 */ -public class Leaves extends MaterialData { +public class Leaves extends Wood { + protected static final Material DEFAULT_TYPE = Material.LEAVES; + protected static final boolean DEFAULT_DECAYABLE = true; + + /** + * Constructs a leaf block. + */ public Leaves() { - super(Material.LEAVES); + this(DEFAULT_TYPE, DEFAULT_SPECIES, DEFAULT_DECAYABLE); } + /** + * Constructs a leaf block of the given tree species. + * + * @param species the species of the wood block + */ public Leaves(TreeSpecies species) { - this(); - setSpecies(species); + this(DEFAULT_TYPE, species, DEFAULT_DECAYABLE); + } + + /** + * Constructs a leaf block of the given tree species and flag for whether + * this leaf block will disappear when too far from a log. + * + * @param species the species of the wood block + * @param isDecayable whether the block is permanent or can disappear + */ + public Leaves(TreeSpecies species, boolean isDecayable) { + this(DEFAULT_TYPE, species, isDecayable); } /** @@ -25,8 +50,36 @@ public class Leaves extends MaterialData { super(type); } + /** + * Constructs a leaf block of the given type. + * + * @param type the type of leaf block + */ public Leaves(final Material type) { - super(type); + this(type, DEFAULT_SPECIES, DEFAULT_DECAYABLE); + } + + /** + * Constructs a leaf block of the given type and tree species. + * + * @param type the type of leaf block + * @param species the species of the wood block + */ + public Leaves(final Material type, TreeSpecies species) { + this(type, species, DEFAULT_DECAYABLE); + } + + /** + * Constructs a leaf block of the given type and tree species and flag for + * whether this leaf block will disappear when too far from a log. + * + * @param type the type of leaf block + * @param species the species of the wood block + * @param isDecayable whether the block is permanent or can disappear + */ + public Leaves(final Material type, TreeSpecies species, boolean isDecayable) { + super(type, species); + setDecayable(isDecayable); } /** @@ -50,26 +103,50 @@ public class Leaves extends MaterialData { } /** - * Gets the current species of this leave + * Checks if this leaf block is in the process of decaying + * + * @return true if the leaf block is in the process of decaying + */ + public boolean isDecaying() { + return (getData() & 0x8) != 0; + } + + /** + * Set whether this leaf block is in the process of decaying + * + * @param isDecaying whether the block is decaying or not + */ + public void setDecaying(boolean isDecaying) { + setData((byte) ((getData() & 0x3) | (isDecaying + ? 0x8 // Clear the permanent flag to make this a decayable flag and set the decaying flag + : (getData() & 0x4)))); // Only persist the decayable flag if this is not a decaying block + } + + /** + * Checks if this leaf block is permanent or can decay when too far from a + * log * - * @return TreeSpecies of this leave + * @return true if the leaf block is permanent or can decay when too far + * from a log */ - public TreeSpecies getSpecies() { - return TreeSpecies.getByData((byte) (getData() & 3)); + public boolean isDecayable() { + return (getData() & 0x4) == 0; } /** - * Sets the species of this leave + * Set whether this leaf block will disappear when too far from a log * - * @param species New species of this leave + * @param isDecayable whether the block is permanent or can disappear */ - public void setSpecies(TreeSpecies species) { - setData(species.getData()); + public void setDecayable(boolean isDecayable) { + setData((byte) ((getData() & 0x3) | (isDecayable + ? (getData() & 0x8) // Only persist the decaying flag if this is a decayable block + : 0x4))); } @Override public String toString() { - return getSpecies() + " " + super.toString(); + return getSpecies() + (isDecayable() ? " DECAYABLE " : " PERMANENT ") + (isDecaying() ? " DECAYING " : " ") + super.toString(); } @Override diff --git a/src/main/java/org/bukkit/material/Sapling.java b/src/main/java/org/bukkit/material/Sapling.java new file mode 100644 index 00000000..52dbaee8 --- /dev/null +++ b/src/main/java/org/bukkit/material/Sapling.java @@ -0,0 +1,121 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.TreeSpecies; + +/** + * Represents the different types of Tree block that face a direction. + * + * @see Material.SAPLING + */ +public class Sapling extends Wood { + + /** + * Constructs a sapling. + */ + public Sapling() { + this(DEFAULT_SPECIES); + } + + /** + * Constructs a sapling of the given tree species. + * + * @param species the species of the sapling + */ + public Sapling(TreeSpecies species) { + this(species, false); + } + + /** + * Constructs a sapling of the given tree species and if is it instant + * growable + * + * @param species the species of the tree block + * @param isInstantGrowable true if the Sapling should grow when next ticked with bonemeal + */ + public Sapling(TreeSpecies species, boolean isInstantGrowable) { + this(Material.SAPLING, species, isInstantGrowable); + } + + /** + * Constructs a sapling of the given type. + * + * @param type the type of tree block + */ + public Sapling(final Material type) { + this(type, DEFAULT_SPECIES, false); + } + + /** + * Constructs a sapling of the given type and tree species. + * + * @param type the type of sapling + * @param species the species of the sapling + */ + public Sapling(final Material type, TreeSpecies species) { + this(type, species, false); + } + + /** + * Constructs a sapling of the given type and tree species and if is it + * instant growable + * + * @param type the type of sapling + * @param species the species of the sapling + * @param isInstantGrowable true if the Sapling should grow when next ticked + * with bonemeal + */ + public Sapling(final Material type, TreeSpecies species, boolean isInstantGrowable) { + super(type, species); + setIsInstantGrowable(isInstantGrowable); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Sapling(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Sapling(final Material type, final byte data) { + super(type, data); + } + + /** + * Checks if the Sapling would grow when next ticked with bonemeal + * + * @return true if the Sapling would grow when next ticked with bonemeal + */ + public boolean isInstantGrowable() { + return (getData() & 0x8) == 0x8; + } + + /** + * Set whether this sapling will grow when next ticked with bonemeal + * + * @param isInstantGrowable true if the Sapling should grow when next ticked + * with bonemeal + */ + public void setIsInstantGrowable(boolean isInstantGrowable) { + setData(isInstantGrowable ? (byte) ((getData() & 0x7) | 0x8) : (byte) (getData() & 0x7)); + } + + @Override + public String toString() { + return getSpecies() + " " + (isInstantGrowable() ? " IS_INSTANT_GROWABLE " : "") + " " + super.toString(); + } + + @Override + public Sapling clone() { + return (Sapling) super.clone(); + } +} diff --git a/src/main/java/org/bukkit/material/Tree.java b/src/main/java/org/bukkit/material/Tree.java index d90126c1..8bc79af1 100644 --- a/src/main/java/org/bukkit/material/Tree.java +++ b/src/main/java/org/bukkit/material/Tree.java @@ -5,22 +5,40 @@ import org.bukkit.TreeSpecies; import org.bukkit.block.BlockFace; /** - * Represents the different types of Trees. + * Represents the different types of Tree block that face a direction. + * + * @see Material.LOG + * @see Material.LOG_2 */ -public class Tree extends MaterialData { +public class Tree extends Wood { + protected static final Material DEFAULT_TYPE = Material.LOG; + protected static final BlockFace DEFAULT_DIRECTION = BlockFace.UP; + + /** + * Constructs a tree block. + */ public Tree() { - super(Material.LOG); + this(DEFAULT_TYPE, DEFAULT_SPECIES, DEFAULT_DIRECTION); } + /** + * Constructs a tree block of the given tree species. + * + * @param species the species of the tree block + */ public Tree(TreeSpecies species) { - this(); - setSpecies(species); + this(DEFAULT_TYPE, species, DEFAULT_DIRECTION); } + /** + * Constructs a tree block of the given tree species, and facing the given + * direction. + * + * @param species the species of the tree block + * @param dir the direction the tree block is facing + */ public Tree(TreeSpecies species, BlockFace dir) { - this(); - setSpecies(species); - setDirection(dir); + this(DEFAULT_TYPE, species, dir); } /** @@ -32,8 +50,36 @@ public class Tree extends MaterialData { super(type); } + /** + * Constructs a tree block of the given type. + * + * @param type the type of tree block + */ public Tree(final Material type) { - super(type); + this(type, DEFAULT_SPECIES, DEFAULT_DIRECTION); + } + + /** + * Constructs a tree block of the given type and tree species. + * + * @param type the type of tree block + * @param species the species of the tree block + */ + public Tree(final Material type, TreeSpecies species) { + this(type, species, DEFAULT_DIRECTION); + } + + /** + * Constructs a tree block of the given type and tree species, and facing + * the given direction. + * + * @param type the type of tree block + * @param species the species of the tree block + * @param dir the direction the tree block is facing + */ + public Tree(final Material type, TreeSpecies species, BlockFace dir) { + super(type, species); + setDirection(dir); } /** @@ -56,35 +102,18 @@ public class Tree extends MaterialData { super(type, data); } - /** - * Gets the current species of this tree - * - * @return TreeSpecies of this tree - */ - public TreeSpecies getSpecies() { - return TreeSpecies.getByData((byte) (getData() & 0x3)); - } - - /** - * Sets the species of this tree - * - * @param species New species of this tree - */ - public void setSpecies(TreeSpecies species) { - setData((byte) ((getData() & 0xC) | species.getData())); - } - /** * Get direction of the log * * @return one of: - * + * */ + @SuppressWarnings("deprecation") public BlockFace getDirection() { switch ((getData() >> 2) & 0x3) { case 0: // Up-down @@ -98,11 +127,13 @@ public class Tree extends MaterialData { return BlockFace.SELF; } } + /** * Set direction of the log * * @param dir - direction of end of log (BlockFace.SELF for no direction) */ + @SuppressWarnings("deprecation") public void setDirection(BlockFace dir) { int dat; switch (dir) { @@ -113,17 +144,17 @@ public class Tree extends MaterialData { break; case WEST: case EAST: - dat = 1; + dat = 4; // 1<<2 break; case NORTH: case SOUTH: - dat = 2; + dat = 8; // 2<<2 break; case SELF: - dat = 3; + dat = 12; // 3<<2 break; } - setData((byte) ((getData() & 0x3) | (dat << 2))); + setData((byte) ((getData() & 0x3) | dat)); } @Override diff --git a/src/main/java/org/bukkit/material/Wood.java b/src/main/java/org/bukkit/material/Wood.java new file mode 100644 index 00000000..1c401621 --- /dev/null +++ b/src/main/java/org/bukkit/material/Wood.java @@ -0,0 +1,196 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.TreeSpecies; + +/** + * Represents wood blocks of different species. + * + * @see Material.WOOD + * @see Material.SAPLING + * @see Material.WOOD_DOUBLE_STEP + */ +public class Wood extends MaterialData { + protected static final Material DEFAULT_TYPE = Material.WOOD; + protected static final TreeSpecies DEFAULT_SPECIES = TreeSpecies.GENERIC; + + /** + * Constructs a wood block. + */ + public Wood() { + this(DEFAULT_TYPE, DEFAULT_SPECIES); + } + + /** + * Constructs a wood block of the given tree species. + * + * @param species the species of the wood block + */ + public Wood(TreeSpecies species) { + this(DEFAULT_TYPE, species); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Wood(final int type) { + super(type); + } + + /** + * Constructs a wood block of the given type. + * + * @param type the type of wood block + */ + public Wood(final Material type) { + this(type, DEFAULT_SPECIES); + } + + /** + * Constructs a wood block of the given type and tree species. + * + * @param type the type of wood block + * @param species the species of the wood block + */ + public Wood(final Material type, final TreeSpecies species) { + // Ensure only valid species-type combinations + super(getSpeciesType(type, species)); + setSpecies(species); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Wood(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Wood(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current species of this wood block + * + * @return TreeSpecies of this wood block + */ + public TreeSpecies getSpecies() { + switch (getItemType()) { + case WOOD: + case WOOD_DOUBLE_STEP: + return TreeSpecies.getByData((byte) getData()); + case LOG: + case LEAVES: + return TreeSpecies.getByData((byte) (getData() & 0x3)); + case LOG_2: + case LEAVES_2: + return TreeSpecies.getByData((byte) ((getData() & 0x3) | 0x4)); + case SAPLING: + case WOOD_STEP: + return TreeSpecies.getByData((byte) (getData() & 0x7)); + default: + throw new IllegalArgumentException("Invalid block type for tree species"); + } + } + + /** + * Correct the block type for certain species-type combinations. + * + * @param type The desired type + * @param species The required species + * @return The actual type for this species given the desired type + */ + private static Material getSpeciesType(Material type, TreeSpecies species) { + switch (species) { + case GENERIC: + case REDWOOD: + case BIRCH: + case JUNGLE: + switch (type) { + case LOG_2: + return Material.LOG; + case LEAVES_2: + return Material.LEAVES; + default: + } + break; + case ACACIA: + case DARK_OAK: + switch (type) { + case LOG: + return Material.LOG_2; + case LEAVES: + return Material.LEAVES_2; + default: + } + break; + } + return type; + } + + /** + * Sets the species of this wood block + * + * @param species New species of this wood block + */ + public void setSpecies(final TreeSpecies species) { + boolean firstType = false; + switch (getItemType()) { + case WOOD: + case WOOD_DOUBLE_STEP: + setData(species.getData()); + break; + case LOG: + case LEAVES: + firstType = true; + // fall through to next switch statement below + case LOG_2: + case LEAVES_2: + switch (species) { + case GENERIC: + case REDWOOD: + case BIRCH: + case JUNGLE: + if (!firstType) { + throw new IllegalArgumentException("Invalid tree species for block type, use block type 2 instead"); + } + break; + case ACACIA: + case DARK_OAK: + if (firstType) { + throw new IllegalArgumentException("Invalid tree species for block type 2, use block type instead"); + } + break; + } + setData((byte) ((getData() & 0xC) | (species.getData() & 0x3))); + break; + case SAPLING: + case WOOD_STEP: + setData((byte) ((getData() & 0x8) | species.getData())); + break; + default: + throw new IllegalArgumentException("Invalid block type for tree species"); + } + } + + @Override + public String toString() { + return getSpecies() + " " + super.toString(); + } + + @Override + public Wood clone() { + return (Wood) super.clone(); + } +} diff --git a/src/main/java/org/bukkit/material/WoodenStep.java b/src/main/java/org/bukkit/material/WoodenStep.java index b07ee89b..293c95b1 100644 --- a/src/main/java/org/bukkit/material/WoodenStep.java +++ b/src/main/java/org/bukkit/material/WoodenStep.java @@ -5,11 +5,39 @@ import org.bukkit.TreeSpecies; /** * Represents the different types of wooden steps. + * + * @see Material.WOOD_STEP */ -public class WoodenStep extends MaterialData { +public class WoodenStep extends Wood { + protected static final Material DEFAULT_TYPE = Material.WOOD_STEP; + protected static final boolean DEFAULT_INVERTED = false; + /** + * Constructs a wooden step. + */ public WoodenStep() { - super(Material.WOOD_STEP); + this(DEFAULT_SPECIES, DEFAULT_INVERTED); + } + + /** + * Constructs a wooden step of the given tree species. + * + * @param species the species of the wooden step + */ + public WoodenStep(TreeSpecies species) { + this(species, DEFAULT_INVERTED); + } + + /** + * Constructs a wooden step of the given type and tree species, either + * inverted or not. + * + * @param species the species of the wooden step + * @param inv true the step is at the top of the block + */ + public WoodenStep(final TreeSpecies species, boolean inv) { + super(DEFAULT_TYPE, species); + setInverted(inv); } /** @@ -21,17 +49,6 @@ public class WoodenStep extends MaterialData { super(type); } - public WoodenStep(TreeSpecies species) { - this(); - setSpecies(species); - } - - public WoodenStep(TreeSpecies species, boolean inv) { - this(); - setSpecies(species); - setInverted(inv); - } - /** * @param type the raw type id * @param data the raw data value @@ -52,39 +69,23 @@ public class WoodenStep extends MaterialData { super(type, data); } - /** - * Gets the current species of this tree - * - * @return TreeSpecies of this tree - */ - public TreeSpecies getSpecies() { - return TreeSpecies.getByData((byte) (getData() & 0x3)); - } - - /** - * Sets the species of this tree - * - * @param species New species of this tree - */ - public void setSpecies(TreeSpecies species) { - setData((byte) ((getData() & 0xC) | species.getData())); - } - /** * Test if step is inverted * * @return true if inverted (top half), false if normal (bottom half) */ + @SuppressWarnings("deprecation") public boolean isInverted() { return ((getData() & 0x8) != 0); } - + /** * Set step inverted state * - * @param inv - true if step is inverted (top half), false if step is - * normal (bottom half) + * @param inv - true if step is inverted (top half), false if step is normal + * (bottom half) */ + @SuppressWarnings("deprecation") public void setInverted(boolean inv) { int dat = getData() & 0x7; if (inv) { @@ -92,7 +93,7 @@ public class WoodenStep extends MaterialData { } setData((byte) dat); } - + @Override public WoodenStep clone() { return (WoodenStep) super.clone(); @@ -100,6 +101,6 @@ public class WoodenStep extends MaterialData { @Override public String toString() { - return super.toString() + " " + getSpecies() + (isInverted()?" inverted":""); + return super.toString() + " " + getSpecies() + (isInverted() ? " inverted" : ""); } } diff --git a/src/test/java/org/bukkit/materials/MaterialDataTest.java b/src/test/java/org/bukkit/materials/MaterialDataTest.java index e888381d..41dff993 100644 --- a/src/test/java/org/bukkit/materials/MaterialDataTest.java +++ b/src/test/java/org/bukkit/materials/MaterialDataTest.java @@ -4,8 +4,14 @@ import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import org.bukkit.Material; +import org.bukkit.TreeSpecies; import org.bukkit.block.BlockFace; import org.bukkit.material.Door; +import org.bukkit.material.Leaves; +import org.bukkit.material.Sapling; +import org.bukkit.material.Tree; +import org.bukkit.material.Wood; +import org.bukkit.material.WoodenStep; import org.junit.Test; public class MaterialDataTest { @@ -58,4 +64,171 @@ public class MaterialDataTest { } } } + + @Test + public void testWood() { + Wood wood = new Wood(); + assertThat("Constructed with default wood type", wood.getItemType(), equalTo(Material.WOOD)); + assertThat("Constructed with default tree species", wood.getSpecies(), equalTo(TreeSpecies.GENERIC)); + + TreeSpecies[] allSpecies = TreeSpecies.values(); + for (TreeSpecies species : allSpecies) { + wood = new Wood(species); + assertThat("Constructed with default wood type", wood.getItemType(), equalTo(Material.WOOD)); + assertThat("Constructed with correct tree species", wood.getSpecies(), equalTo(species)); + } + + Material[] types = new Material[]{Material.WOOD, Material.WOOD_DOUBLE_STEP}; + for (Material type : types) { + wood = new Wood(type); + assertThat("Constructed with correct wood type", wood.getItemType(), equalTo(type)); + assertThat("Constructed with default tree species", wood.getSpecies(), equalTo(TreeSpecies.GENERIC)); + + for (TreeSpecies species : allSpecies) { + wood = new Wood(type, species); + assertThat("Constructed with correct wood type", wood.getItemType(), equalTo(type)); + assertThat("Constructed with correct tree species", wood.getSpecies(), equalTo(species)); + } + } + } + + @Test + public void testTree() { + Tree tree = new Tree(); + assertThat("Constructed with default tree type", tree.getItemType(), equalTo(Material.LOG)); + assertThat("Constructed with default tree species", tree.getSpecies(), equalTo(TreeSpecies.GENERIC)); + assertThat("Constructed with default direction", tree.getDirection(), equalTo(BlockFace.UP)); + + tree = new Tree(Material.LOG); + assertThat("Constructed with correct tree type", tree.getItemType(), equalTo(Material.LOG)); + assertThat("Constructed with default tree species", tree.getSpecies(), equalTo(TreeSpecies.GENERIC)); + assertThat("Constructed with default direction", tree.getDirection(), equalTo(BlockFace.UP)); + + Material[] types = new Material[]{Material.LOG, Material.LOG_2}; + TreeSpecies[][] allSpecies = new TreeSpecies[][]{ + {TreeSpecies.GENERIC, TreeSpecies.REDWOOD, TreeSpecies.BIRCH, TreeSpecies.JUNGLE}, + {TreeSpecies.ACACIA, TreeSpecies.DARK_OAK} + }; + BlockFace[] allDirections = new BlockFace[]{BlockFace.UP, BlockFace.WEST, BlockFace.NORTH, BlockFace.SELF}; + for (int t = 0; t < types.length; t++) { + for (TreeSpecies species : allSpecies[t]) { + tree = new Tree(types[t], species); + assertThat("Constructed with correct tree type", tree.getItemType(), equalTo(types[t])); + assertThat("Constructed with correct tree species", tree.getSpecies(), equalTo(species)); + assertThat("Constructed with default direction", tree.getDirection(), equalTo(BlockFace.UP)); + + // check item type is fixed automatically for invalid type-species combo + tree = new Tree(types[types.length - 1 - t], species); + assertThat("Constructed with fixed tree type", tree.getItemType(), equalTo(types[t])); + assertThat("Constructed with correct tree species", tree.getSpecies(), equalTo(species)); + assertThat("Constructed with default direction", tree.getDirection(), equalTo(BlockFace.UP)); + for (BlockFace dir : allDirections) { + tree = new Tree(types[t], species, dir); + assertThat("Constructed with correct tree type", tree.getItemType(), equalTo(types[t])); + assertThat("Constructed with correct tree species", tree.getSpecies(), equalTo(species)); + assertThat("Constructed with correct direction", tree.getDirection(), equalTo(dir)); + } + } + } + } + + @Test + public void testLeaves() { + Leaves leaves = new Leaves(); + assertThat("Constructed with default leaf type", leaves.getItemType(), equalTo(Material.LEAVES)); + assertThat("Constructed with default tree species", leaves.getSpecies(), equalTo(TreeSpecies.GENERIC)); + assertThat("Constructed with default decayable", leaves.isDecayable(), equalTo(true)); + assertThat("Constructed with default decaying", leaves.isDecaying(), equalTo(false)); + + leaves = new Leaves(Material.LEAVES); + assertThat("Constructed with correct leaf type", leaves.getItemType(), equalTo(Material.LEAVES)); + assertThat("Constructed with default tree species", leaves.getSpecies(), equalTo(TreeSpecies.GENERIC)); + assertThat("Constructed with default decayable", leaves.isDecayable(), equalTo(true)); + assertThat("Constructed with default decaying", leaves.isDecaying(), equalTo(false)); + + Material[] types = new Material[]{Material.LEAVES, Material.LEAVES_2}; + TreeSpecies[][] allSpecies = new TreeSpecies[][]{ + {TreeSpecies.GENERIC, TreeSpecies.REDWOOD, TreeSpecies.BIRCH, TreeSpecies.JUNGLE}, + {TreeSpecies.ACACIA, TreeSpecies.DARK_OAK} + }; + boolean[] decayable = new boolean[]{true, false}; + boolean[] decaying = new boolean[]{true, false}; + for (int t = 0; t < types.length; t++) { + for (TreeSpecies species : allSpecies[t]) { + leaves = new Leaves(types[t], species); + assertThat("Constructed with correct leaf type", leaves.getItemType(), equalTo(types[t])); + assertThat("Constructed with correct tree species", leaves.getSpecies(), equalTo(species)); + assertThat("Constructed with default decayable", leaves.isDecayable(), equalTo(true)); + assertThat("Constructed with default decaying", leaves.isDecaying(), equalTo(false)); + + // check item type is fixed automatically for invalid type-species combo + leaves = new Leaves(types[types.length - 1 - t], species); + assertThat("Constructed with fixed leaf type", leaves.getItemType(), equalTo(types[t])); + assertThat("Constructed with correct tree species", leaves.getSpecies(), equalTo(species)); + assertThat("Constructed with default decayable", leaves.isDecayable(), equalTo(true)); + assertThat("Constructed with default decaying", leaves.isDecaying(), equalTo(false)); + for (boolean isDecayable : decayable) { + leaves = new Leaves(types[t], species, isDecayable); + assertThat("Constructed with correct wood type", leaves.getItemType(), equalTo(types[t])); + assertThat("Constructed with correct tree species", leaves.getSpecies(), equalTo(species)); + assertThat("Constructed with correct decayable", leaves.isDecayable(), equalTo(isDecayable)); + assertThat("Constructed with default decaying", leaves.isDecaying(), equalTo(false)); + for (boolean isDecaying : decaying) { + leaves = new Leaves(types[t], species, isDecayable); + leaves.setDecaying(isDecaying); + assertThat("Constructed with correct wood type", leaves.getItemType(), equalTo(types[t])); + assertThat("Constructed with correct tree species", leaves.getSpecies(), equalTo(species)); + assertThat("Constructed with correct decayable", leaves.isDecayable(), equalTo(isDecaying || isDecayable)); + assertThat("Constructed with correct decaying", leaves.isDecaying(), equalTo(isDecaying)); + } + } + } + } + } + + @Test + public void testWoodenStep() { + WoodenStep woodenStep = new WoodenStep(); + assertThat("Constructed with default step type", woodenStep.getItemType(), equalTo(Material.WOOD_STEP)); + assertThat("Constructed with default tree species", woodenStep.getSpecies(), equalTo(TreeSpecies.GENERIC)); + assertThat("Constructed with default inversion", woodenStep.isInverted(), equalTo(false)); + + TreeSpecies[] allSpecies = TreeSpecies.values(); + boolean[] inversion = new boolean[]{true, false}; + for (TreeSpecies species : allSpecies) { + woodenStep = new WoodenStep(species); + assertThat("Constructed with default step type", woodenStep.getItemType(), equalTo(Material.WOOD_STEP)); + assertThat("Constructed with correct tree species", woodenStep.getSpecies(), equalTo(species)); + assertThat("Constructed with default inversion", woodenStep.isInverted(), equalTo(false)); + for (boolean isInverted : inversion) { + woodenStep = new WoodenStep(species, isInverted); + assertThat("Constructed with default step type", woodenStep.getItemType(), equalTo(Material.WOOD_STEP)); + assertThat("Constructed with correct tree species", woodenStep.getSpecies(), equalTo(species)); + assertThat("Constructed with correct inversion", woodenStep.isInverted(), equalTo(isInverted)); + } + } + } + + @Test + public void testSapling() { + Sapling sapling = new Sapling(); + assertThat("Constructed with default sapling type", sapling.getItemType(), equalTo(Material.SAPLING)); + assertThat("Constructed with default tree species", sapling.getSpecies(), equalTo(TreeSpecies.GENERIC)); + assertThat("Constructed with default growable", sapling.isInstantGrowable(), equalTo(false)); + + TreeSpecies[] allSpecies = TreeSpecies.values(); + boolean[] growable = new boolean[]{true, false}; + for (TreeSpecies species : allSpecies) { + sapling = new Sapling(species); + assertThat("Constructed with default sapling type", sapling.getItemType(), equalTo(Material.SAPLING)); + assertThat("Constructed with correct tree species", sapling.getSpecies(), equalTo(species)); + assertThat("Constructed with default growable", sapling.isInstantGrowable(), equalTo(false)); + for (boolean isInstantGrowable : growable) { + sapling = new Sapling(species, isInstantGrowable); + assertThat("Constructed with default sapling type", sapling.getItemType(), equalTo(Material.SAPLING)); + assertThat("Constructed with correct tree species", sapling.getSpecies(), equalTo(species)); + assertThat("Constructed with correct growable", sapling.isInstantGrowable(), equalTo(isInstantGrowable)); + } + } + } } -- cgit v1.2.3