diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c771fd5..825b18d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,21 +11,22 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Set up JDK 17 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: 'adopt' java-version: 17 - name: Cache SonarCloud packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Cache Maven packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/README.md b/README.md index 3dd4bd7..a679ad8 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Greenhouses are made out of glass and must contain the blocks found in the Biome * Craft your own self-contained biome greenhouse on an island (or elsewhere if you like) * Greenhouses can grow plants that cannot normally be grown, like sunflowers -* Friendly mobs can spawn if your greenhouse is well designed - need slimes? Build a swamp greenhouse! +* Friendly mobs can spawn if your greenhouse is well-designed - need slimes? Build a swamp greenhouse! * Blocks change in biomes over time - dirt becomes sand in a desert, dirt becomes clay in a river, for example. * Greenhouses can run in multiple worlds. * Easy to use GUI shows greenhouse recipes (e.g. **/is greenhouses**) @@ -27,7 +27,7 @@ This example is for when you are in the BSkyBlock world. For AcidIsland, just us 1. Make glass blocks and build a rectangular set of walls with a flat roof. 2. Put a hopper in the wall or roof. -3. Put a door in the wall so you can get in and out. +3. Put a door in the wall, so you can get in and out. 4. Type **/island greenhouses** and read the rules for the greenhouse you want. 5. Exit the GUI and place blocks, water, lava, and ice so that you make your desired biome. 6. Type **/island greenhouses** again and click on the biome to make it. @@ -42,7 +42,7 @@ This example is for when you are in the BSkyBlock world. For AcidIsland, just us ## FAQ -* Can I use stained glass? Yes, you can. It's pretty. +* Can I use stained-glass? Yes, you can. It's pretty. * Can I fill my greenhouse full of water? Yes. That's an ocean. * Will a squid spawn there? Maybe... okay, yes it will if it's a big enough ocean. * How do I place a door high up in the wall if the wall is all glass? Place it on a hopper. diff --git a/pom.xml b/pom.xml index c940abd..7eb7b4b 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ ${build.version}-SNAPSHOT - 1.7.3 + 1.7.4 -LOCAL BentoBoxWorld_Greenhouses bentobox-world @@ -191,7 +191,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M5 + 3.1.0 ${argLine} @@ -252,7 +252,7 @@ org.jacoco jacoco-maven-plugin - 0.8.7 + 0.8.10 true diff --git a/src/main/java/world/bentobox/greenhouses/Greenhouses.java b/src/main/java/world/bentobox/greenhouses/Greenhouses.java index d3ed568..995bddb 100644 --- a/src/main/java/world/bentobox/greenhouses/Greenhouses.java +++ b/src/main/java/world/bentobox/greenhouses/Greenhouses.java @@ -11,6 +11,7 @@ import world.bentobox.bentobox.api.configuration.Config; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.Flag.Mode; import world.bentobox.bentobox.api.flags.Flag.Type; +import world.bentobox.greenhouses.greenhouse.Walls; import world.bentobox.greenhouses.managers.GreenhouseManager; import world.bentobox.greenhouses.managers.RecipeManager; import world.bentobox.greenhouses.ui.user.UserCommand; @@ -28,19 +29,13 @@ public class Greenhouses extends Addon { public static final Flag GREENHOUSES = new Flag.Builder("GREENHOUSE", Material.GREEN_STAINED_GLASS) .mode(Mode.BASIC) .type(Type.PROTECTION).build(); - private static Greenhouses instance; private final Config config; - public static Greenhouses getInstance() { - return instance; - } - /** * Constructor */ public Greenhouses() { super(); - instance = this; config = new Config<>(this, Settings.class); } @@ -122,4 +117,15 @@ public class Greenhouses extends Addon { return activeWorlds; } + /** + * Check if material is a wall material + * @param m - material + * @return true if wall material + */ + public boolean wallBlocks(Material m) { + return Walls.WALL_BLOCKS.contains(m) + || (m.equals(Material.GLOWSTONE) && getSettings().isAllowGlowstone()) + || (m.name().endsWith("GLASS_PANE") && getSettings().isAllowPanes()); + } + } diff --git a/src/main/java/world/bentobox/greenhouses/greenhouse/BiomeRecipe.java b/src/main/java/world/bentobox/greenhouses/greenhouse/BiomeRecipe.java index a589f77..700d5c0 100644 --- a/src/main/java/world/bentobox/greenhouses/greenhouse/BiomeRecipe.java +++ b/src/main/java/world/bentobox/greenhouses/greenhouse/BiomeRecipe.java @@ -209,24 +209,30 @@ public class BiomeRecipe implements Comparable { * @return set of results from the check */ private Set checkRecipeAsync(CompletableFuture> r, Greenhouse gh) { - AsyncWorldCache cache = new AsyncWorldCache(gh.getWorld()); - Set result = new HashSet<>(); + AsyncWorldCache cache = new AsyncWorldCache(addon, gh.getWorld()); long area = gh.getArea(); - Map blockCount = new EnumMap<>(Material.class); // Look through the greenhouse and count what is in there - for (int y = gh.getFloorHeight(); y< gh.getCeilingHeight();y++) { - for (int x = (int) (gh.getBoundingBox().getMinX()+1); x < gh.getBoundingBox().getMaxX(); x++) { - for (int z = (int) (gh.getBoundingBox().getMinZ()+1); z < gh.getBoundingBox().getMaxZ(); z++) { - Material t = cache.getBlockType(x, y, z); - if (!t.equals(Material.AIR)) { - blockCount.putIfAbsent(t, 0); - blockCount.merge(t, 1, Integer::sum); - } - } - } + Map blockCount = countBlocks(gh, cache); + + // Calculate % water, ice and lava ratios and check them + Set result = checkRatios(blockCount, area); + + // Compare to the required blocks + Map missingBlocks = requiredBlocks.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - blockCount.getOrDefault(e.getKey(), 0))); + // Remove any entries that are 0 or less + missingBlocks.values().removeIf(v -> v <= 0); + if (!missingBlocks.isEmpty()) { + result.add(GreenhouseResult.FAIL_INSUFFICIENT_BLOCKS); + gh.setMissingBlocks(missingBlocks); } - // Calculate % water, ice and lava ratios + // Return to main thread to complete + Bukkit.getScheduler().runTask(addon.getPlugin(), () -> r.complete(result)); + return result; + } + + private Set checkRatios(Map blockCount, long area) { + Set result = new HashSet<>(); double waterRatio = (double)blockCount.getOrDefault(Material.WATER, 0)/area * 100; double lavaRatio = (double)blockCount.getOrDefault(Material.LAVA, 0)/area * 100; int ice = blockCount.entrySet().stream().filter(en -> en.getKey().equals(Material.ICE) @@ -254,47 +260,57 @@ public class BiomeRecipe implements Comparable { if (iceCoverage > 0 && iceRatio < iceCoverage) { result.add(GreenhouseResult.FAIL_INSUFFICIENT_ICE); } - // Compare to the required blocks - Map missingBlocks = requiredBlocks.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - blockCount.getOrDefault(e.getKey(), 0))); - // Remove any entries that are 0 or less - missingBlocks.values().removeIf(v -> v <= 0); - if (!missingBlocks.isEmpty()) { - result.add(GreenhouseResult.FAIL_INSUFFICIENT_BLOCKS); - gh.setMissingBlocks(missingBlocks); - } - // Return to main thread to complete - Bukkit.getScheduler().runTask(addon.getPlugin(), () -> r.complete(result)); return result; } + private Map countBlocks(Greenhouse gh, AsyncWorldCache cache) { + Map blockCount = new EnumMap<>(Material.class); + for (int y = gh.getFloorHeight(); y< gh.getCeilingHeight();y++) { + for (int x = (int) (gh.getBoundingBox().getMinX()+1); x < gh.getBoundingBox().getMaxX(); x++) { + for (int z = (int) (gh.getBoundingBox().getMinZ()+1); z < gh.getBoundingBox().getMaxZ(); z++) { + Material t = cache.getBlockType(x, y, z); + if (!t.equals(Material.AIR)) { + blockCount.putIfAbsent(t, 0); + blockCount.merge(t, 1, Integer::sum); + } + } + } + } + return blockCount; + } + /** * Check if block should be converted * @param b - block to check */ public void convertBlock(Block b) { Material bType = b.getType(); - // Check if there is a block conversion for this block, as while the rest of the method wont do anything if .get() returns nothing anyway it still seems to be quite expensive + // Check if there is a block conversion for this block, as while the rest of the method won't do anything if .get() returns nothing anyway it still seems to be quite expensive if(conversionBlocks.keySet().contains(bType)) { - for(GreenhouseBlockConversions conversion_option : conversionBlocks.get(bType)) { - - // Roll the dice before bothering with checking the surrounding block as I think it's more common for greenhouses to be filled with convertable blocks and thus this dice roll wont be "wasted" - if(ThreadLocalRandom.current().nextDouble() < conversion_option.probability()) { - // Check if any of the adjacent blocks matches the required LocalMaterial, if there are any required LocalMaterials - if(conversion_option.localMaterial() != null) { - for(BlockFace adjacent_block : ADJ_BLOCKS) { - if(b.getRelative(adjacent_block).getType() == conversion_option.localMaterial()) { - b.setType(conversion_option.newMaterial()); - break; - } - } - } else { - b.setType(conversion_option.newMaterial()); - } - } + for(GreenhouseBlockConversions conversionOption : conversionBlocks.get(bType)) { + rollTheDice(b, conversionOption); } } } + private void rollTheDice(Block b, GreenhouseBlockConversions conversion_option) { + // Roll the dice before bothering with checking the surrounding block as I think it's more common for greenhouses to be filled with convertable blocks and thus this dice roll wont be "wasted" + if(ThreadLocalRandom.current().nextDouble() < conversion_option.probability()) { + // Check if any of the adjacent blocks matches the required LocalMaterial, if there are any required LocalMaterials + if(conversion_option.localMaterial() != null) { + for(BlockFace adjacent_block : ADJ_BLOCKS) { + if(b.getRelative(adjacent_block).getType() == conversion_option.localMaterial()) { + b.setType(conversion_option.newMaterial()); + break; + } + } + } else { + b.setType(conversion_option.newMaterial()); + } + } + + } + /** * @return the type */ @@ -376,7 +392,7 @@ public class BiomeRecipe implements Comparable { } // Center spawned mob Location spawnLoc = b.getLocation().clone().add(new Vector(0.5, 0, 0.5)); - boolean result = getRandomMob() + return getRandomMob() // Check if the spawn on block matches, if it exists .filter(m -> Optional.of(m.mobSpawnOn()) .map(b.getRelative(BlockFace.DOWN).getType()::equals) @@ -396,7 +412,6 @@ public class BiomeRecipe implements Comparable { return true; }).orElse(false); }).orElse(false); - return result; } /** @@ -435,7 +450,10 @@ public class BiomeRecipe implements Comparable { // Grow a random plant that can grow double r = random.nextDouble(); Double key = underwater ? underwaterPlants.ceilingKey(r) : plantTree.ceilingKey(r); - return key == null ? Optional.empty() : Optional.ofNullable(underwater ? underwaterPlants.get(key) : plantTree.get(key)); + if (key == null) { + return Optional.empty(); + } + return Optional.ofNullable(underwater ? underwaterPlants.get(key) : plantTree.get(key)); } /** @@ -461,11 +479,9 @@ public class BiomeRecipe implements Comparable { public boolean growPlant(GrowthBlock block, boolean underwater) { Block bl = block.block(); return getRandomPlant(underwater).map(p -> { - if (bl.getY() != 0 && canGrowOn(block, p)) { - if (plantIt(bl, p)) { - bl.getWorld().spawnParticle(Particle.SNOWBALL, bl.getLocation(), 10, 2, 2, 2); - return true; - } + if (bl.getY() != 0 && canGrowOn(block, p) && plantIt(bl, p)) { + bl.getWorld().spawnParticle(Particle.SNOWBALL, bl.getLocation(), 10, 2, 2, 2); + return true; } return false; }).orElse(false); @@ -554,14 +570,12 @@ public class BiomeRecipe implements Comparable { BlockFace d = null; boolean waterLogged = false; for (BlockFace adj : ADJ_BLOCKS) { - if (b.getRelative(adj).getType().equals(Material.AIR)) { + Material type = b.getRelative(adj).getType(); + if (type.equals(Material.AIR) || type.equals(Material.WATER)) { d = adj; - break; - } - // Lichen can grow under water too - if (b.getRelative(adj).getType().equals(Material.WATER)) { - d = adj; - waterLogged = true; + if (type.equals(Material.WATER)) { + waterLogged = true; + } break; } } diff --git a/src/main/java/world/bentobox/greenhouses/greenhouse/Roof.java b/src/main/java/world/bentobox/greenhouses/greenhouse/Roof.java index 1a62454..6720ba5 100644 --- a/src/main/java/world/bentobox/greenhouses/greenhouse/Roof.java +++ b/src/main/java/world/bentobox/greenhouses/greenhouse/Roof.java @@ -23,33 +23,17 @@ import world.bentobox.greenhouses.world.AsyncWorldCache; * @author tastybento * */ -@SuppressWarnings("deprecation") public class Roof extends MinMaxXZ { - private static final List ROOF_BLOCKS; - static { - // Roof blocks - ROOF_BLOCKS = Arrays.stream(Material.values()) - .filter(m -> !m.isLegacy()) - .filter(Material::isBlock) // Blocks only, no items - .filter(m -> Tag.TRAPDOORS.isTagged(m) // All trapdoors - || (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks - || m.equals(Material.HOPPER)).toList(); - } - /** - * Check if material is a roof material - * @param m - material - * @return true if roof material - */ - public static boolean roofBlocks(@NonNull Material m) { - return ROOF_BLOCKS.contains(Objects.requireNonNull(m)) - || (m.equals(Material.GLOWSTONE) && Greenhouses.getInstance().getSettings().isAllowGlowstone()) - || (m.name().endsWith("GLASS_PANE") && Greenhouses.getInstance().getSettings().isAllowPanes()); - } + private static final List ROOF_BLOCKS = Arrays.stream(Material.values()) + .filter(Material::isBlock) // Blocks only, no items + .filter(m -> Tag.TRAPDOORS.isTagged(m) // All trapdoors + || (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks + || m.equals(Material.HOPPER)).toList(); private final AsyncWorldCache cache; private int height; private final Location location; private boolean roofFound; - + private final Greenhouses addon; private final World world; @@ -58,13 +42,23 @@ public class Roof extends MinMaxXZ { * @param cache async world cache * @param loc - starting location */ - public Roof(AsyncWorldCache cache, Location loc) { + public Roof(AsyncWorldCache cache, Location loc, Greenhouses addon) { this.cache = cache; this.location = loc; + this.addon = addon; this.world = loc.getWorld(); } - + /** + * Check if material is a roof material + * @param m - material + * @return true if roof material + */ + public boolean roofBlocks(@NonNull Material m) { + return ROOF_BLOCKS.contains(Objects.requireNonNull(m)) + || (m.equals(Material.GLOWSTONE) && addon.getSettings().isAllowGlowstone()) + || (m.name().endsWith("GLASS_PANE") && addon.getSettings().isAllowPanes()); + } /** * This takes any location and tries to go as far as possible in NWSE directions finding contiguous roof blocks @@ -124,7 +118,7 @@ public class Roof extends MinMaxXZ { } boolean findRoof(Vector loc) { - // This does a ever-growing check around the player to find a wall block. It is possible for the player + // This does an ever-growing check around the player to find a wall block. It is possible for the player // to be outside the greenhouse in this situation, so a check is done later to make sure the player is inside int startY = loc.getBlockY(); for (int y = startY; y < world.getMaxHeight(); y++) { @@ -136,7 +130,7 @@ public class Roof extends MinMaxXZ { } } // If the roof was not found start going around in circles until something is found - // Expand in ever increasing squares around location until a wall block is found + // Expand in ever-increasing squares around location until a wall block is found if (!roofFound) { loc = spiralSearch(loc, startY); if (!roofFound) { @@ -205,13 +199,13 @@ public class Roof extends MinMaxXZ { } /** - * Get highest roof block + * Get the highest roof block * @param x - x coord of current search * @param startY - starting y coord * @param z - z coord of current search */ private Optional checkVertically(final int x, final int startY, final int z) { - if (!Walls.wallBlocks(cache.getBlockType(x, startY, z))) { + if (!addon.wallBlocks(cache.getBlockType(x, startY, z))) { // Look up for (int y = startY; y < world.getMaxHeight() && !roofFound; y++) { if (roofBlocks(cache.getBlockType(x,y,z))) { diff --git a/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java b/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java index d4a0890..1f34937 100644 --- a/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java +++ b/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java @@ -9,25 +9,17 @@ import org.bukkit.Location; import org.bukkit.Material; import world.bentobox.bentobox.BentoBox; -import world.bentobox.greenhouses.Greenhouses; import world.bentobox.greenhouses.world.AsyncWorldCache; -@SuppressWarnings("deprecation") public class Walls extends MinMaxXZ { - private static final List WALL_BLOCKS; - static { - // Hoppers - WALL_BLOCKS = Arrays.stream(Material.values()) - .filter(Material::isBlock) // Blocks only, no items - .filter(m -> !m.isLegacy()) - .filter(m -> !m.name().contains("TRAPDOOR")) // No trap doors - .filter(m -> m.name().contains("DOOR") // All doors - || (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks - || m.equals(Material.HOPPER)).toList(); - } + public static final List WALL_BLOCKS = Arrays.stream(Material.values()) + .filter(Material::isBlock) // Blocks only, no items + .filter(m -> !m.name().contains("TRAPDOOR")) // No trap doors + .filter(m -> m.name().contains("DOOR") // All doors + || (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks + || m.equals(Material.HOPPER)).toList(); private int floor; - private final AsyncWorldCache cache; static class WallFinder { @@ -177,17 +169,6 @@ public class Walls extends MinMaxXZ { } - /** - * Check if material is a wall material - * @param m - material - * @return true if wall material - */ - public static boolean wallBlocks(Material m) { - return WALL_BLOCKS.contains(m) - || (m.equals(Material.GLOWSTONE) && Greenhouses.getInstance().getSettings().isAllowGlowstone()) - || (m.name().endsWith("GLASS_PANE") && Greenhouses.getInstance().getSettings().isAllowPanes()); - } - /** * @return the floor */ diff --git a/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java b/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java index 377f593..428b139 100644 --- a/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java +++ b/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java @@ -53,7 +53,7 @@ public class GreenhouseGuard implements Listener { if (from.isPresent() && addon.getSettings().isAllowFlowOut()) { return; } - // Otherwise cancel - the flow is not allowed + // Otherwise, cancel - the flow is not allowed e.setCancelled(true); } diff --git a/src/main/java/world/bentobox/greenhouses/managers/EcoSystemManager.java b/src/main/java/world/bentobox/greenhouses/managers/EcoSystemManager.java index 0e17a42..8ca43e2 100644 --- a/src/main/java/world/bentobox/greenhouses/managers/EcoSystemManager.java +++ b/src/main/java/world/bentobox/greenhouses/managers/EcoSystemManager.java @@ -95,17 +95,17 @@ public class EcoSystemManager { return; } final BoundingBox ibb = gh.getInternalBoundingBox(); - int gh_min_x = NumberConversions.floor(ibb.getMinX()); - int gh_max_x = NumberConversions.floor(ibb.getMaxX()); - int gh_min_y = NumberConversions.floor(gh.getBoundingBox().getMinY()); // Note: this gets the floor - int gh_max_y = NumberConversions.floor(ibb.getMaxY()); - int gh_min_z = NumberConversions.floor(ibb.getMinZ()); - int gh_max_z = NumberConversions.floor(ibb.getMaxZ()); + int ghMinX = NumberConversions.floor(ibb.getMinX()); + int ghMaxX = NumberConversions.floor(ibb.getMaxX()); + int ghMinY = NumberConversions.floor(gh.getBoundingBox().getMinY()); // Note: this gets the floor + int ghMaxY = NumberConversions.floor(ibb.getMaxY()); + int ghMinZ = NumberConversions.floor(ibb.getMinZ()); + int ghMaxZ = NumberConversions.floor(ibb.getMaxZ()); BiomeRecipe biomeRecipe = gh.getBiomeRecipe(); - for (int x = gh_min_x; x < gh_max_x; x++) { - for (int z = gh_min_z; z < gh_max_z; z++) { - for (int y = gh_min_y; y < gh_max_y; y++) { + for (int x = ghMinX; x < ghMaxX; x++) { + for (int z = ghMinZ; z < ghMaxZ; z++) { + for (int y = ghMinY; y < ghMaxY; y++) { Block b = world.getBlockAt(x, y, z); if(!b.isEmpty()) { @@ -167,7 +167,7 @@ public class EcoSystemManager { Collections.shuffle(list, new Random(System.currentTimeMillis())); Iterator it = list.iterator(); // Check if the greenhouse is full - if (sum >= gh.getBiomeRecipe().getMaxMob()) { + if (gh.getBiomeRecipe().getMaxMob() > -1 && sum >= gh.getBiomeRecipe().getMaxMob()) { return false; } while (it.hasNext() && (sum == 0 || gh.getArea() / sum >= gh.getBiomeRecipe().getMobLimit())) { @@ -241,36 +241,39 @@ public class EcoSystemManager { for (double z = ibb.getMinZ(); z < ibb.getMaxZ(); z++) { for (double y = ibb.getMaxY() - 1; y >= bb.getMinY(); y--) { Block b = gh.getWorld().getBlockAt(NumberConversions.floor(x), NumberConversions.floor(y), NumberConversions.floor(z)); - - // Check floor blocks - if (!ignoreLiquid) { - // Check ceiling blocks - if (b.isEmpty() && !b.getRelative(BlockFace.UP).isEmpty()) { - result.add(new GrowthBlock(b, false)); - } - if (!b.isEmpty() && !Tag.LEAVES.isTagged(b.getType()) - && (b.getRelative(BlockFace.UP).isEmpty() - || b.getRelative(BlockFace.UP).isPassable() - || Tag.LEAVES.isTagged(b.getRelative(BlockFace.UP).getType()) - ) - ) { - result.add(new GrowthBlock(b.getRelative(BlockFace.UP), true)); - break; - } - } else { - if (!b.isEmpty() && !b.isLiquid() && b.getRelative(BlockFace.UP).isLiquid()) { - result.add(new GrowthBlock(b.getRelative(BlockFace.UP), true)); - break; - } + if (checkBlock(result, b, ignoreLiquid)) { + break; } - } } } return result; } - + private boolean checkBlock(List result, Block b, boolean ignoreLiquid) { + // Check floor blocks + if (!ignoreLiquid) { + // Check ceiling blocks + if (b.isEmpty() && !b.getRelative(BlockFace.UP).isEmpty()) { + result.add(new GrowthBlock(b, false)); + } + if (!b.isEmpty() && !Tag.LEAVES.isTagged(b.getType()) + && (b.getRelative(BlockFace.UP).isEmpty() + || b.getRelative(BlockFace.UP).isPassable() + || Tag.LEAVES.isTagged(b.getRelative(BlockFace.UP).getType()) + ) + ) { + result.add(new GrowthBlock(b.getRelative(BlockFace.UP), true)); + return true; + } + } else { + if (!b.isEmpty() && !b.isLiquid() && b.getRelative(BlockFace.UP).isLiquid()) { + result.add(new GrowthBlock(b.getRelative(BlockFace.UP), true)); + return true; + } + } + return false; + } private int getBoneMeal(Greenhouse gh) { Hopper hopper = getHopper(gh); diff --git a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java index e7b29f5..3ff6331 100644 --- a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java +++ b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java @@ -12,6 +12,7 @@ import org.bukkit.Tag; import org.bukkit.util.Vector; import world.bentobox.bentobox.BentoBox; +import world.bentobox.greenhouses.Greenhouses; import world.bentobox.greenhouses.data.Greenhouse; import world.bentobox.greenhouses.greenhouse.Roof; import world.bentobox.greenhouses.greenhouse.Walls; @@ -28,10 +29,11 @@ public class GreenhouseFinder { // If this is the bottom layer, the player has most likely uneven walls private int otherBlockLayer = -1; private int wallBlockCount; + private final Greenhouses addon; /** * This is the count of the various items */ - private CounterCheck cc = new CounterCheck(); + private CounterCheck counterCheck = new CounterCheck(); static class CounterCheck { int doorCount; @@ -40,6 +42,13 @@ public class GreenhouseFinder { boolean otherBlock; } + /** + * @param addon Addon + */ + public GreenhouseFinder(Greenhouses addon) { + this.addon = addon; + } + /** * Find out if there is a greenhouse here * @param location - start location @@ -51,9 +60,9 @@ public class GreenhouseFinder { redGlass.clear(); // Get a world cache - AsyncWorldCache cache = new AsyncWorldCache(location.getWorld()); + AsyncWorldCache cache = new AsyncWorldCache(addon, location.getWorld()); // Find the roof - Roof roof = new Roof(cache, location); + Roof roof = new Roof(cache, location, addon); roof.findRoof().thenAccept(found -> { if (Boolean.FALSE.equals(found)) { result.add(GreenhouseResult.FAIL_NO_ROOF); @@ -87,30 +96,26 @@ public class GreenhouseFinder { */ CompletableFuture> checkGreenhouse(AsyncWorldCache cache, Roof roof, Walls walls) { CompletableFuture> r = new CompletableFuture<>(); - Bukkit.getScheduler().runTaskAsynchronously(BentoBox.getInstance(), () -> checkGHAsync(r, cache, roof, walls)); + Bukkit.getScheduler().runTaskAsynchronously(BentoBox.getInstance(), () -> checkGreenhouseAsync(r, cache, roof, walls)); return r; } - private Set checkGHAsync(CompletableFuture> r, AsyncWorldCache cache, + private Set checkGreenhouseAsync(CompletableFuture> r, AsyncWorldCache cache, Roof roof, Walls walls) { - cc = new CounterCheck(); + counterCheck = new CounterCheck(); int y; for (y = roof.getHeight(); y > walls.getFloor(); y--) { wallBlockCount = 0; for (int x = walls.getMinX(); x <= walls.getMaxX(); x++) { for (int z = walls.getMinZ(); z <= walls.getMaxZ(); z++) { - checkBlock(cc, cache.getBlockType(x,y,z), roof, walls, new Vector(x, y, z)); + checkBlock(counterCheck, cache.getBlockType(x,y,z), roof, walls, new Vector(x, y, z)); } } if (wallBlockCount == 0 && y < roof.getHeight()) { // This is the floor break; - } else { - if (cc.otherBlock) { - if (otherBlockLayer < 0) { - otherBlockLayer = y; - } - } + } else if (counterCheck.otherBlock && otherBlockLayer < 0) { + otherBlockLayer = y; } } @@ -138,7 +143,7 @@ public class GreenhouseFinder { // Roof blocks must be glass, glowstone, doors or a hopper. result.add(GreenhouseResult.FAIL_BAD_ROOF_BLOCKS); } else if (isOtherBlocks()) { - // "Wall blocks must be glass, glowstone, doors or a hopper. + // Wall blocks must be glass, glowstone, doors or a hopper. result.add(GreenhouseResult.FAIL_BAD_WALL_BLOCKS); } if (this.getWallDoors() > 8) { @@ -166,7 +171,8 @@ public class GreenhouseFinder { // Check wall blocks only if (y == roof.getHeight() || x == walls.getMinX() || x == walls.getMaxX() || z == walls.getMinZ() || z== walls.getMaxZ()) { // Check for non-wall blocks or non-roof blocks at the top of walls - if ((y != roof.getHeight() && !Walls.wallBlocks(m)) || (y == roof.getHeight() && !Roof.roofBlocks(m))) { + if ((y != roof.getHeight() && !addon.wallBlocks(m)) + || (y == roof.getHeight() && !roof.roofBlocks(m))) { if (m.equals(Material.AIR)) { // Air hole found cc.airHole = true; @@ -241,28 +247,28 @@ public class GreenhouseFinder { * @return the wallDoors */ int getWallDoors() { - return cc.doorCount; + return counterCheck.doorCount; } /** * @return the ghHopper */ int getGhHopper() { - return cc.hopperCount; + return counterCheck.hopperCount; } /** * @return the airHoles */ boolean isAirHoles() { - return cc.airHole; + return counterCheck.airHole; } /** * @return the otherBlocks */ boolean isOtherBlocks() { - return cc.otherBlock; + return counterCheck.otherBlock; } /** @@ -315,21 +321,21 @@ public class GreenhouseFinder { } public void setGhHopper(int i) { - cc.hopperCount = i; + counterCheck.hopperCount = i; } public void setWallDoors(int i) { - cc.doorCount = i; + counterCheck.doorCount = i; } public void setAirHoles(boolean b) { - cc.airHole = b; + counterCheck.airHole = b; } public void setOtherBlocks(boolean b) { - cc.otherBlock = b; + counterCheck.otherBlock = b; } diff --git a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseManager.java b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseManager.java index a18e569..13f1e70 100644 --- a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseManager.java +++ b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseManager.java @@ -96,19 +96,19 @@ public class GreenhouseManager implements Listener { handler.loadObjects().forEach(g -> { GreenhouseResult result = map.addGreenhouse(g); switch (result) { - case FAIL_NO_ISLAND -> - // Delete the failed greenhouse - toBeRemoved.add(g); - case FAIL_OVERLAPPING -> addon.logError("Greenhouse overlaps with another greenhouse. Skipping..."); - case NULL -> addon.logError("Null location of greenhouse. Cannot load. Skipping..."); - case SUCCESS -> activateGreenhouse(g); - case FAIL_NO_WORLD -> addon.logError("Database contains greenhouse for a non-loaded world. Skipping..."); - case FAIL_UNKNOWN_RECIPE -> { - addon.logError("Greenhouse uses a recipe that does not exist in the biomes.yml. Skipping..."); - addon.logError("Greenhouse Id " + g.getUniqueId()); - } - default -> { - } + case FAIL_NO_ISLAND -> + // Delete the failed greenhouse + toBeRemoved.add(g); + case FAIL_OVERLAPPING -> addon.logError("Greenhouse overlaps with another greenhouse. Skipping..."); + case NULL -> addon.logError("Null location of greenhouse. Cannot load. Skipping..."); + case SUCCESS -> activateGreenhouse(g); + case FAIL_NO_WORLD -> addon.logError("Database contains greenhouse for a non-loaded world. Skipping..."); + case FAIL_UNKNOWN_RECIPE -> { + addon.logError("Greenhouse uses a recipe that does not exist in the biomes.yml. Skipping..."); + addon.logError("Greenhouse Id " + g.getUniqueId()); + } + default -> { + } } }); addon.log("Loaded " + map.getSize() + " greenhouses."); @@ -153,7 +153,7 @@ public class GreenhouseManager implements Listener { */ public CompletableFuture tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) { CompletableFuture r = new CompletableFuture<>(); - GreenhouseFinder finder = new GreenhouseFinder(); + GreenhouseFinder finder = new GreenhouseFinder(addon); finder.find(location).thenAccept(resultSet -> { if (!resultSet.isEmpty()) { // Failure! diff --git a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseMap.java b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseMap.java index 91d2af4..b42f829 100644 --- a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseMap.java +++ b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseMap.java @@ -6,7 +6,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import org.bukkit.Location; @@ -138,7 +137,7 @@ public class GreenhouseMap { * @return a list of all the Greenhouses */ public List getGreenhouses() { - return greenhouses.values().stream().flatMap(List::stream).collect(Collectors.toList()); + return greenhouses.values().stream().flatMap(List::stream).toList(); } /** diff --git a/src/main/java/world/bentobox/greenhouses/managers/RecipeManager.java b/src/main/java/world/bentobox/greenhouses/managers/RecipeManager.java index 9b5750a..76700d5 100644 --- a/src/main/java/world/bentobox/greenhouses/managers/RecipeManager.java +++ b/src/main/java/world/bentobox/greenhouses/managers/RecipeManager.java @@ -30,6 +30,7 @@ public class RecipeManager { private static final int MAXIMUM_INVENTORY_SIZE = 49; private final Greenhouses addon; private static final List biomeRecipes = new ArrayList<>(); + private static final String COULD_NOT_PARSE = "Could not parse "; public RecipeManager(Greenhouses addon) { this.addon = addon; @@ -179,45 +180,54 @@ public class RecipeManager { ConfigurationSection conversionSec = biomeRecipeConfig.getConfigurationSection("conversions"); if (conversionSec != null) { for (String oldMat : conversionSec.getKeys(false)) { - try { - Material oldMaterial = Material.valueOf(oldMat.toUpperCase(Locale.ENGLISH)); - String conversions = conversionSec.getString(oldMat); - if (!Objects.requireNonNull(conversions).isEmpty()) { - String[] split = conversions.split(":"); - double convChance = Double.parseDouble(split[0]); - Material newMaterial = Material.valueOf(split[1]); - Material localMaterial = null; - if(split.length > 2) { - localMaterial = Material.valueOf(split[2]); - } - b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial); - } - } catch (Exception e) { - addon.logError("Could not parse " + oldMat); - } - + parseConversions(oldMat, conversionSec, b); } } // Get the list of conversions for (String oldMat : biomeRecipeConfig.getStringList("conversion-list")) { - try { - // Split the string - String[] split = oldMat.split(":"); - Material oldMaterial = Material.valueOf(split[0].toUpperCase()); - double convChance = Double.parseDouble(split[1]); - Material newMaterial = Material.valueOf(split[2]); - Material localMaterial = null; - if(split.length > 3) { - localMaterial = Material.valueOf(split[3]); - } - b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial); - } catch (Exception e) { - addon.logError("Could not parse " + oldMat); - } + parseConversionList(oldMat, b); } } + private void parseConversionList(String oldMat, BiomeRecipe b) { + try { + // Split the string + String[] split = oldMat.split(":"); + Material oldMaterial = Material.valueOf(split[0].toUpperCase()); + double convChance = Double.parseDouble(split[1]); + Material newMaterial = Material.valueOf(split[2]); + Material localMaterial = null; + if(split.length > 3) { + localMaterial = Material.valueOf(split[3]); + } + b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial); + } catch (Exception e) { + addon.logError(COULD_NOT_PARSE + oldMat); + } + + } + + private void parseConversions(String oldMat, ConfigurationSection conversionSec, BiomeRecipe b) { + try { + Material oldMaterial = Material.valueOf(oldMat.toUpperCase(Locale.ENGLISH)); + String conversions = conversionSec.getString(oldMat); + if (!Objects.requireNonNull(conversions).isEmpty()) { + String[] split = conversions.split(":"); + double convChance = Double.parseDouble(split[0]); + Material newMaterial = Material.valueOf(split[1]); + Material localMaterial = null; + if(split.length > 2) { + localMaterial = Material.valueOf(split[2]); + } + b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial); + } + } catch (Exception e) { + addon.logError(COULD_NOT_PARSE + oldMat); + } + + } + private void loadMobs(ConfigurationSection biomeRecipeConfig, BiomeRecipe b) { ConfigurationSection temp = biomeRecipeConfig.getConfigurationSection("mobs"); // Mob EntityType: Probability:Spawn on Material @@ -235,7 +245,7 @@ public class RecipeManager { Material mobSpawnOn = Material.valueOf(split[1]); b.addMobs(mobType, mobProbability, mobSpawnOn); } catch (Exception e) { - addon.logError("Could not parse " + s.getKey()); + addon.logError(COULD_NOT_PARSE + s.getKey()); } } diff --git a/src/main/java/world/bentobox/greenhouses/world/AsyncWorldCache.java b/src/main/java/world/bentobox/greenhouses/world/AsyncWorldCache.java index 05c5ce0..4313fbc 100644 --- a/src/main/java/world/bentobox/greenhouses/world/AsyncWorldCache.java +++ b/src/main/java/world/bentobox/greenhouses/world/AsyncWorldCache.java @@ -27,14 +27,16 @@ public class AsyncWorldCache { private final World world; private final Map, ChunkSnapshot> cache; + private final Greenhouses addon; /** * Chunk cache. This class is designed to be run async and blocks futures * @param world - world to cache */ - public AsyncWorldCache(World world) { + public AsyncWorldCache(Greenhouses addon, World world) { this.world = world; cache = new HashMap<>(); + this.addon = addon; } /** @@ -59,7 +61,7 @@ public class AsyncWorldCache { */ private CompletableFuture getAChunk(int x, int z) { CompletableFuture r = new CompletableFuture<>(); - Bukkit.getScheduler().runTask(Greenhouses.getInstance().getPlugin(), () -> + Bukkit.getScheduler().runTask(addon.getPlugin(), () -> Util.getChunkAtAsync(world, x, z).thenAccept(chunk -> r.complete(chunk.getChunkSnapshot()))); return r; } @@ -104,7 +106,7 @@ public class AsyncWorldCache { try { return Objects.requireNonNull(getSnap(x, z)).getBlockType(xx, y, zz); } catch (InterruptedException | ExecutionException e) { - Greenhouses.getInstance().logError("Chunk could not be obtained async! " + e); + addon.logError("Chunk could not be obtained async! " + e); // Restore interrupted state... Thread.currentThread().interrupt(); return Material.AIR; diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 894ab48..73c9816 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -59,9 +59,9 @@ greenhouses: FAIL_TOO_MANY_DOORS: "&c You cannot have more than 4 doors in the greenhouse!" FAIL_TOO_MANY_HOPPERS: "&c Only one hopper is allowed in the walls or roof." FAIL_UNEVEN_WALLS: "&c The walls are uneven. Red glass blocks should show the problem blocks." - FAIL_INSUFFICIENT_ICE: "&c Insufficent ice to make this recipe" - FAIL_INSUFFICIENT_LAVA: "&c Insufficent lava to make this recipe" - FAIL_INSUFFICIENT_WATER: "&c Insufficent water to make this recipe" + FAIL_INSUFFICIENT_ICE: "&c Insufficient ice to make this recipe" + FAIL_INSUFFICIENT_LAVA: "&c Insufficient lava to make this recipe" + FAIL_INSUFFICIENT_WATER: "&c Insufficient water to make this recipe" FAIL_NO_ICE: "&c Ice is required to make this recipe" FAIL_NO_LAVA: "&c Lava is required to make this recipe" FAIL_NO_WATER: "&c Water is required to make this recipe" diff --git a/src/test/java/world/bentobox/greenhouses/data/GreenhouseTest.java b/src/test/java/world/bentobox/greenhouses/data/GreenhouseTest.java index 6665f0d..e352169 100644 --- a/src/test/java/world/bentobox/greenhouses/data/GreenhouseTest.java +++ b/src/test/java/world/bentobox/greenhouses/data/GreenhouseTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -61,7 +60,7 @@ public class GreenhouseTest { // RecipeManager PowerMockito.mockStatic(RecipeManager.class); when(br.getName()).thenReturn("test"); - when(RecipeManager.getBiomeRecipies(eq("test"))).thenReturn(Optional.of(br)); + when(RecipeManager.getBiomeRecipies("test")).thenReturn(Optional.of(br)); // Walls when(walls.getMinX()).thenReturn(MINX); when(walls.getMinZ()).thenReturn(MINZ); diff --git a/src/test/java/world/bentobox/greenhouses/greenhouse/BiomeRecipeTest.java b/src/test/java/world/bentobox/greenhouses/greenhouse/BiomeRecipeTest.java index db64690..407c869 100644 --- a/src/test/java/world/bentobox/greenhouses/greenhouse/BiomeRecipeTest.java +++ b/src/test/java/world/bentobox/greenhouses/greenhouse/BiomeRecipeTest.java @@ -151,7 +151,7 @@ public class BiomeRecipeTest { double convChance = 100D; Material localMaterial = Material.WATER; br.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial); - verify(addon).log(eq(" 100.0% chance for Sand to convert to Clay")); + verify(addon).log(" 100.0% chance for Sand to convert to Clay"); } /** @@ -163,7 +163,7 @@ public class BiomeRecipeTest { int mobProbability = 50; Material mobSpawnOn = Material.GRASS_BLOCK; br.addMobs(mobType, mobProbability, mobSpawnOn); - verify(addon).log(eq(" 50.0% chance for Cat to spawn on Grass Block.")); + verify(addon).log(" 50.0% chance for Cat to spawn on Grass Block."); } /** @@ -177,7 +177,7 @@ public class BiomeRecipeTest { br.addMobs(mobType, mobProbability, mobSpawnOn); br.addMobs(mobType, mobProbability, mobSpawnOn); br.addMobs(mobType, mobProbability, mobSpawnOn); - verify(addon).logError(eq("Mob chances add up to > 100% in BADLANDS biome recipe! Skipping CAT")); + verify(addon).logError("Mob chances add up to > 100% in BADLANDS biome recipe! Skipping CAT"); } /** @@ -190,7 +190,7 @@ public class BiomeRecipeTest { Material mobSpawnOn = Material.GRASS_BLOCK; br.addMobs(mobType, mobProbability, mobSpawnOn); br.addMobs(mobType, mobProbability, mobSpawnOn); - verify(addon).logError(eq("Mob chances add up to > 100% in BADLANDS biome recipe! Skipping CAT")); + verify(addon).logError("Mob chances add up to > 100% in BADLANDS biome recipe! Skipping CAT"); } /** @@ -202,7 +202,7 @@ public class BiomeRecipeTest { int plantProbability = 20; Material plantGrowOn = Material.DIRT; br.addPlants(plantMaterial, plantProbability, plantGrowOn); - verify(addon).log(eq(" 20.0% chance for Jungle Sapling to grow on Dirt")); + verify(addon).log(" 20.0% chance for Jungle Sapling to grow on Dirt"); } /** @@ -215,7 +215,7 @@ public class BiomeRecipeTest { Material plantGrowOn = Material.DIRT; br.addPlants(plantMaterial, plantProbability, plantGrowOn); br.addPlants(plantMaterial, plantProbability, plantGrowOn); - verify(addon).logError(eq("Plant chances add up to > 100% in BADLANDS biome recipe! Skipping JUNGLE_SAPLING")); + verify(addon).logError("Plant chances add up to > 100% in BADLANDS biome recipe! Skipping JUNGLE_SAPLING"); } /** @@ -226,7 +226,7 @@ public class BiomeRecipeTest { Material blockMaterial = Material.BLACK_CONCRETE; int blockQty = 30; br.addReqBlocks(blockMaterial, blockQty); - verify(addon).log(eq(" BLACK_CONCRETE x 30")); + verify(addon).log(" BLACK_CONCRETE x 30"); } /** @@ -451,7 +451,7 @@ public class BiomeRecipeTest { br.addMobs(mobType, mobProbability, mobSpawnOn); assertFalse(br.spawnMob(block)); - verify(world).spawnEntity(eq(location), eq(EntityType.CAT)); + verify(world).spawnEntity(location, EntityType.CAT); verify(location).add(any(Vector.class)); } @@ -477,7 +477,7 @@ public class BiomeRecipeTest { br.addMobs(mobType, mobProbability, mobSpawnOn); assertTrue(br.spawnMob(block)); - verify(world).spawnEntity(eq(location), eq(EntityType.CAT)); + verify(world).spawnEntity(location, EntityType.CAT); verify(location).add(any(Vector.class)); } @@ -504,7 +504,7 @@ public class BiomeRecipeTest { br.addMobs(mobType, mobProbability, mobSpawnOn); assertTrue(br.spawnMob(block)); - verify(world).spawnEntity(eq(location), eq(EntityType.HOGLIN)); + verify(world).spawnEntity(location, EntityType.HOGLIN); verify(location).add(any(Vector.class)); verify(hoglin).setImmuneToZombification(true); } @@ -532,7 +532,7 @@ public class BiomeRecipeTest { br.addMobs(mobType, mobProbability, mobSpawnOn); assertTrue(br.spawnMob(block)); - verify(world).spawnEntity(eq(location), eq(EntityType.PIGLIN)); + verify(world).spawnEntity(location, EntityType.PIGLIN); verify(location).add(any(Vector.class)); verify(piglin).setImmuneToZombification(true); } @@ -562,7 +562,7 @@ public class BiomeRecipeTest { br.addMobs(mobType, mobProbability, mobSpawnOn); assertTrue(br.spawnMob(block)); - verify(world).spawnEntity(eq(location), eq(EntityType.PIGLIN)); + verify(world).spawnEntity(location, EntityType.PIGLIN); verify(location).add(any(Vector.class)); verify(piglin, never()).setImmuneToZombification(true); } @@ -586,7 +586,7 @@ public class BiomeRecipeTest { br.addMobs(mobType, mobProbability, mobSpawnOn); assertFalse(br.spawnMob(block)); - verify(world, never()).spawnEntity(eq(location), eq(EntityType.CAT)); + verify(world, never()).spawnEntity(location, EntityType.CAT); } /** @@ -706,8 +706,8 @@ public class BiomeRecipeTest { assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK)); assertTrue(br.growPlant(new GrowthBlock(block, true), false)); verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble()); - verify(bisected).setHalf(eq(Half.BOTTOM)); - verify(bisected).setHalf(eq(Half.TOP)); + verify(bisected).setHalf(Half.BOTTOM); + verify(bisected).setHalf(Half.TOP); } /** @@ -722,8 +722,8 @@ public class BiomeRecipeTest { when(block.isEmpty()).thenReturn(true); Block ob = mock(Block.class); when(ob.getType()).thenReturn(Material.GRASS_BLOCK); - when(block.getRelative(eq(BlockFace.DOWN))).thenReturn(ob); - when(block.getRelative(eq(BlockFace.UP))).thenReturn(ob); + when(block.getRelative(BlockFace.DOWN)).thenReturn(ob); + when(block.getRelative(BlockFace.UP)).thenReturn(ob); assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK)); assertFalse(br.growPlant(new GrowthBlock(block, true), false)); } diff --git a/src/test/java/world/bentobox/greenhouses/greenhouse/RoofTest.java b/src/test/java/world/bentobox/greenhouses/greenhouse/RoofTest.java index 8b23894..b21e5e8 100644 --- a/src/test/java/world/bentobox/greenhouses/greenhouse/RoofTest.java +++ b/src/test/java/world/bentobox/greenhouses/greenhouse/RoofTest.java @@ -50,8 +50,6 @@ public class RoofTest { public void setUp() { PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true); - PowerMockito.mockStatic(Greenhouses.class, Mockito.RETURNS_MOCKS); - when(Greenhouses.getInstance()).thenReturn(addon); s = new Settings(); when(addon.getSettings()).thenReturn(s); @@ -89,14 +87,14 @@ public class RoofTest { when(location.clone()).thenReturn(location); // Test - roof = new Roof(cache, location); + roof = new Roof(cache, location, addon); assertTrue(roof.findRoof(new Vector(10,10,10))); } @Test public void testNoGlass() { when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.AIR); - roof = new Roof(cache, location); + roof = new Roof(cache, location, addon); assertFalse(roof.findRoof(new Vector(10,10,10))); } @@ -169,13 +167,13 @@ public class RoofTest { */ @Test public void testWallBlocks() { - assertFalse(Roof.roofBlocks(Material.ACACIA_BOAT)); - assertTrue(Roof.roofBlocks(Material.GLASS)); - assertTrue(Roof.roofBlocks(Material.GLOWSTONE)); - assertFalse(Roof.roofBlocks(Material.ACACIA_DOOR)); - assertTrue(Roof.roofBlocks(Material.HOPPER)); - assertTrue(Roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE)); - assertTrue(Roof.roofBlocks(Material.BIRCH_TRAPDOOR)); + assertFalse(roof.roofBlocks(Material.ACACIA_BOAT)); + assertTrue(roof.roofBlocks(Material.GLASS)); + assertTrue(roof.roofBlocks(Material.GLOWSTONE)); + assertFalse(roof.roofBlocks(Material.ACACIA_DOOR)); + assertTrue(roof.roofBlocks(Material.HOPPER)); + assertTrue(roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE)); + assertTrue(roof.roofBlocks(Material.BIRCH_TRAPDOOR)); } /** @@ -185,12 +183,12 @@ public class RoofTest { public void testWallBlocksNoGlowStoneNoPanes() { s.setAllowGlowstone(false); s.setAllowPanes(false); - assertFalse(Roof.roofBlocks(Material.ACACIA_BOAT)); - assertTrue(Roof.roofBlocks(Material.GLASS)); - assertFalse(Roof.roofBlocks(Material.GLOWSTONE)); - assertFalse(Roof.roofBlocks(Material.ACACIA_DOOR)); - assertTrue(Roof.roofBlocks(Material.HOPPER)); - assertFalse(Roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE)); - assertTrue(Roof.roofBlocks(Material.BIRCH_TRAPDOOR)); + assertFalse(roof.roofBlocks(Material.ACACIA_BOAT)); + assertTrue(roof.roofBlocks(Material.GLASS)); + assertFalse(roof.roofBlocks(Material.GLOWSTONE)); + assertFalse(roof.roofBlocks(Material.ACACIA_DOOR)); + assertTrue(roof.roofBlocks(Material.HOPPER)); + assertFalse(roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE)); + assertTrue(roof.roofBlocks(Material.BIRCH_TRAPDOOR)); } } diff --git a/src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java b/src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java index 7231f34..5e4d279 100644 --- a/src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java +++ b/src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java @@ -64,12 +64,10 @@ public class WallsTest { when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true); // Declare mock after mocking Bukkit roof = mock(Roof.class); - PowerMockito.mockStatic(Greenhouses.class, Mockito.RETURNS_MOCKS); - when(Greenhouses.getInstance()).thenReturn(addon); s = new Settings(); when(addon.getSettings()).thenReturn(s); when(addon.getPlugin()).thenReturn(plugin); - + when(addon.wallBlocks(any())).thenCallRealMethod(); walls = new Walls(cache); when(world.getMaxHeight()).thenReturn(255); when(location.getWorld()).thenReturn(world); @@ -201,13 +199,13 @@ public class WallsTest { */ @Test public void testWallBlocks() { - assertFalse(Walls.wallBlocks(Material.ACACIA_BOAT)); - assertTrue(Walls.wallBlocks(Material.GLASS)); - assertTrue(Walls.wallBlocks(Material.GLOWSTONE)); - assertTrue(Walls.wallBlocks(Material.ACACIA_DOOR)); - assertTrue(Walls.wallBlocks(Material.HOPPER)); - assertTrue(Walls.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE)); - assertFalse(Walls.wallBlocks(Material.BIRCH_TRAPDOOR)); + assertFalse(addon.wallBlocks(Material.ACACIA_BOAT)); + assertTrue(addon.wallBlocks(Material.GLASS)); + assertTrue(addon.wallBlocks(Material.GLOWSTONE)); + assertTrue(addon.wallBlocks(Material.ACACIA_DOOR)); + assertTrue(addon.wallBlocks(Material.HOPPER)); + assertTrue(addon.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE)); + assertFalse(addon.wallBlocks(Material.BIRCH_TRAPDOOR)); } /** @@ -217,13 +215,13 @@ public class WallsTest { public void testWallBlocksNoGlowStoneNoPanes() { s.setAllowGlowstone(false); s.setAllowPanes(false); - assertFalse(Walls.wallBlocks(Material.ACACIA_BOAT)); - assertTrue(Walls.wallBlocks(Material.GLASS)); - assertFalse(Walls.wallBlocks(Material.GLOWSTONE)); - assertTrue(Walls.wallBlocks(Material.ACACIA_DOOR)); - assertTrue(Walls.wallBlocks(Material.HOPPER)); - assertFalse(Walls.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE)); - assertFalse(Walls.wallBlocks(Material.BIRCH_TRAPDOOR)); + assertFalse(addon.wallBlocks(Material.ACACIA_BOAT)); + assertTrue(addon.wallBlocks(Material.GLASS)); + assertFalse(addon.wallBlocks(Material.GLOWSTONE)); + assertTrue(addon.wallBlocks(Material.ACACIA_DOOR)); + assertTrue(addon.wallBlocks(Material.HOPPER)); + assertFalse(addon.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE)); + assertFalse(addon.wallBlocks(Material.BIRCH_TRAPDOOR)); } /** diff --git a/src/test/java/world/bentobox/greenhouses/managers/EcoSystemManagerTest.java b/src/test/java/world/bentobox/greenhouses/managers/EcoSystemManagerTest.java index a81c9f8..bce299d 100644 --- a/src/test/java/world/bentobox/greenhouses/managers/EcoSystemManagerTest.java +++ b/src/test/java/world/bentobox/greenhouses/managers/EcoSystemManagerTest.java @@ -83,22 +83,22 @@ public class EcoSystemManagerTest { // Liquid false when(air.isEmpty()).thenReturn(true); when(air.isPassable()).thenReturn(true); - when(air.getRelative(eq(BlockFace.UP))).thenReturn(air); + when(air.getRelative(BlockFace.UP)).thenReturn(air); // Plant // Empty false // Liquid false when(plant.isPassable()).thenReturn(true); - when(plant.getRelative(eq(BlockFace.UP))).thenReturn(air); + when(plant.getRelative(BlockFace.UP)).thenReturn(air); // Liquid // Empty false when(liquid.isLiquid()).thenReturn(true); when(liquid.isPassable()).thenReturn(true); - when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(air); + when(liquid.getRelative(BlockFace.UP)).thenReturn(air); // Default for block // Empty false // Passable false // Liquid false - when(block.getRelative(eq(BlockFace.UP))).thenReturn(air); + when(block.getRelative(BlockFace.UP)).thenReturn(air); // Recipe when(recipe.noMobs()).thenReturn(true); diff --git a/src/test/java/world/bentobox/greenhouses/managers/GreenhouseFinderTest.java b/src/test/java/world/bentobox/greenhouses/managers/GreenhouseFinderTest.java index ca8139f..d081a12 100644 --- a/src/test/java/world/bentobox/greenhouses/managers/GreenhouseFinderTest.java +++ b/src/test/java/world/bentobox/greenhouses/managers/GreenhouseFinderTest.java @@ -71,12 +71,14 @@ public class GreenhouseFinderTest { when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true); // Declare mock after mocking Bukkit roof = mock(Roof.class); + when(roof.roofBlocks(any())).thenCallRealMethod(); // Location when(location.getBlockX()).thenReturn(5); when(location.getBlockY()).thenReturn(14); when(location.getBlockZ()).thenReturn(25); when(location.getWorld()).thenReturn(world); - + // Addon + when(addon.wallBlocks(any())).thenCallRealMethod(); // Block when(cache.getBlockType(any())).thenReturn(Material.GLASS); when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.GLASS); @@ -94,7 +96,7 @@ public class GreenhouseFinderTest { when(cache.getMaxHeight()).thenReturn(30); - gf = new GreenhouseFinder(); + gf = new GreenhouseFinder(addon); cc = new CounterCheck(); }