mirror of
https://github.com/BentoBoxWorld/Greenhouses.git
synced 2024-11-22 02:25:50 +01:00
Version 1.7.4 (#109)
* Version 1.7.3 * Add ${argLine} to get jacoco coverage * Updated Jacoco POM entry * Address bugs reported by SonarCloud * Updated ReadMe * Add max mobs option #99 * Use updated Bucket event * Added tests to cover #99 * Fixes help text for user command. Fixes #105 * Fixed maxmobs typo instead of maxmob * Remove unused imports * Update to new Bukkit Loader * Remove debug * Create plugin.yml (#106) * Create plugin.yml * Update pom.xml * Update GreenhousesPladdon.java * Removed static getInstance usage * Version 1.7.4 * Refactored to reduce complexity * Update surefire plugin * Refactored to reduce complexity * Minor typos and grammar fixes * Reduced complexity * Refactor to reduce complexity * Refactor to reduce complexity * Update Github Action build script * Added distribution required for Github Action * Update pom.xml * Fixes mob spawning when no maxmob value given. Found while doing #108 * Code clean up. --------- Co-authored-by: BONNe <bonne@bonne.id.lv>
This commit is contained in:
parent
5fd9cbfd36
commit
4084876c4b
9
.github/workflows/build.yml
vendored
9
.github/workflows/build.yml
vendored
@ -11,21 +11,22 @@ jobs:
|
|||||||
name: Build
|
name: Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
java-version: 17
|
java-version: 17
|
||||||
- name: Cache SonarCloud packages
|
- name: Cache SonarCloud packages
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.sonar/cache
|
path: ~/.sonar/cache
|
||||||
key: ${{ runner.os }}-sonar
|
key: ${{ runner.os }}-sonar
|
||||||
restore-keys: ${{ runner.os }}-sonar
|
restore-keys: ${{ runner.os }}-sonar
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.m2
|
path: ~/.m2
|
||||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||||
|
@ -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)
|
* 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
|
* 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.
|
* 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.
|
* Greenhouses can run in multiple worlds.
|
||||||
* Easy to use GUI shows greenhouse recipes (e.g. **/is greenhouses**)
|
* 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.
|
1. Make glass blocks and build a rectangular set of walls with a flat roof.
|
||||||
2. Put a hopper in the wall or 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.
|
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.
|
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.
|
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
|
## 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.
|
* 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.
|
* 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.
|
* How do I place a door high up in the wall if the wall is all glass? Place it on a hopper.
|
||||||
|
6
pom.xml
6
pom.xml
@ -51,7 +51,7 @@
|
|||||||
<!-- Revision variable removes warning about dynamic version -->
|
<!-- Revision variable removes warning about dynamic version -->
|
||||||
<revision>${build.version}-SNAPSHOT</revision>
|
<revision>${build.version}-SNAPSHOT</revision>
|
||||||
<!-- This allows to change between versions and snapshots. -->
|
<!-- This allows to change between versions and snapshots. -->
|
||||||
<build.version>1.7.3</build.version>
|
<build.version>1.7.4</build.version>
|
||||||
<build.number>-LOCAL</build.number>
|
<build.number>-LOCAL</build.number>
|
||||||
<sonar.projectKey>BentoBoxWorld_Greenhouses</sonar.projectKey>
|
<sonar.projectKey>BentoBoxWorld_Greenhouses</sonar.projectKey>
|
||||||
<sonar.organization>bentobox-world</sonar.organization>
|
<sonar.organization>bentobox-world</sonar.organization>
|
||||||
@ -191,7 +191,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.0.0-M5</version>
|
<version>3.1.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<argLine>
|
<argLine>
|
||||||
${argLine}
|
${argLine}
|
||||||
@ -252,7 +252,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>0.8.7</version>
|
<version>0.8.10</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<append>true</append>
|
<append>true</append>
|
||||||
<excludes>
|
<excludes>
|
||||||
|
@ -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;
|
||||||
import world.bentobox.bentobox.api.flags.Flag.Mode;
|
import world.bentobox.bentobox.api.flags.Flag.Mode;
|
||||||
import world.bentobox.bentobox.api.flags.Flag.Type;
|
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.GreenhouseManager;
|
||||||
import world.bentobox.greenhouses.managers.RecipeManager;
|
import world.bentobox.greenhouses.managers.RecipeManager;
|
||||||
import world.bentobox.greenhouses.ui.user.UserCommand;
|
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)
|
public static final Flag GREENHOUSES = new Flag.Builder("GREENHOUSE", Material.GREEN_STAINED_GLASS)
|
||||||
.mode(Mode.BASIC)
|
.mode(Mode.BASIC)
|
||||||
.type(Type.PROTECTION).build();
|
.type(Type.PROTECTION).build();
|
||||||
private static Greenhouses instance;
|
|
||||||
private final Config<Settings> config;
|
private final Config<Settings> config;
|
||||||
|
|
||||||
public static Greenhouses getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public Greenhouses() {
|
public Greenhouses() {
|
||||||
super();
|
super();
|
||||||
instance = this;
|
|
||||||
config = new Config<>(this, Settings.class);
|
config = new Config<>(this, Settings.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,4 +117,15 @@ public class Greenhouses extends Addon {
|
|||||||
return activeWorlds;
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -209,24 +209,30 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
* @return set of results from the check
|
* @return set of results from the check
|
||||||
*/
|
*/
|
||||||
private Set<GreenhouseResult> checkRecipeAsync(CompletableFuture<Set<GreenhouseResult>> r, Greenhouse gh) {
|
private Set<GreenhouseResult> checkRecipeAsync(CompletableFuture<Set<GreenhouseResult>> r, Greenhouse gh) {
|
||||||
AsyncWorldCache cache = new AsyncWorldCache(gh.getWorld());
|
AsyncWorldCache cache = new AsyncWorldCache(addon, gh.getWorld());
|
||||||
Set<GreenhouseResult> result = new HashSet<>();
|
|
||||||
long area = gh.getArea();
|
long area = gh.getArea();
|
||||||
Map<Material, Integer> blockCount = new EnumMap<>(Material.class);
|
|
||||||
|
|
||||||
// Look through the greenhouse and count what is in there
|
// Look through the greenhouse and count what is in there
|
||||||
for (int y = gh.getFloorHeight(); y< gh.getCeilingHeight();y++) {
|
Map<Material, Integer> blockCount = countBlocks(gh, cache);
|
||||||
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++) {
|
// Calculate % water, ice and lava ratios and check them
|
||||||
Material t = cache.getBlockType(x, y, z);
|
Set<GreenhouseResult> result = checkRatios(blockCount, area);
|
||||||
if (!t.equals(Material.AIR)) {
|
|
||||||
blockCount.putIfAbsent(t, 0);
|
// Compare to the required blocks
|
||||||
blockCount.merge(t, 1, Integer::sum);
|
Map<Material, Integer> 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<GreenhouseResult> checkRatios(Map<Material, Integer> blockCount, long area) {
|
||||||
|
Set<GreenhouseResult> result = new HashSet<>();
|
||||||
double waterRatio = (double)blockCount.getOrDefault(Material.WATER, 0)/area * 100;
|
double waterRatio = (double)blockCount.getOrDefault(Material.WATER, 0)/area * 100;
|
||||||
double lavaRatio = (double)blockCount.getOrDefault(Material.LAVA, 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)
|
int ice = blockCount.entrySet().stream().filter(en -> en.getKey().equals(Material.ICE)
|
||||||
@ -254,47 +260,57 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
if (iceCoverage > 0 && iceRatio < iceCoverage) {
|
if (iceCoverage > 0 && iceRatio < iceCoverage) {
|
||||||
result.add(GreenhouseResult.FAIL_INSUFFICIENT_ICE);
|
result.add(GreenhouseResult.FAIL_INSUFFICIENT_ICE);
|
||||||
}
|
}
|
||||||
// Compare to the required blocks
|
|
||||||
Map<Material, Integer> 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<Material, Integer> countBlocks(Greenhouse gh, AsyncWorldCache cache) {
|
||||||
|
Map<Material, Integer> 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
|
* Check if block should be converted
|
||||||
* @param b - block to check
|
* @param b - block to check
|
||||||
*/
|
*/
|
||||||
public void convertBlock(Block b) {
|
public void convertBlock(Block b) {
|
||||||
Material bType = b.getType();
|
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)) {
|
if(conversionBlocks.keySet().contains(bType)) {
|
||||||
for(GreenhouseBlockConversions conversion_option : conversionBlocks.get(bType)) {
|
for(GreenhouseBlockConversions conversionOption : conversionBlocks.get(bType)) {
|
||||||
|
rollTheDice(b, conversionOption);
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
* @return the type
|
||||||
*/
|
*/
|
||||||
@ -376,7 +392,7 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
}
|
}
|
||||||
// Center spawned mob
|
// Center spawned mob
|
||||||
Location spawnLoc = b.getLocation().clone().add(new Vector(0.5, 0, 0.5));
|
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
|
// Check if the spawn on block matches, if it exists
|
||||||
.filter(m -> Optional.of(m.mobSpawnOn())
|
.filter(m -> Optional.of(m.mobSpawnOn())
|
||||||
.map(b.getRelative(BlockFace.DOWN).getType()::equals)
|
.map(b.getRelative(BlockFace.DOWN).getType()::equals)
|
||||||
@ -396,7 +412,6 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
return true;
|
return true;
|
||||||
}).orElse(false);
|
}).orElse(false);
|
||||||
}).orElse(false);
|
}).orElse(false);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -435,7 +450,10 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
// Grow a random plant that can grow
|
// Grow a random plant that can grow
|
||||||
double r = random.nextDouble();
|
double r = random.nextDouble();
|
||||||
Double key = underwater ? underwaterPlants.ceilingKey(r) : plantTree.ceilingKey(r);
|
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<BiomeRecipe> {
|
|||||||
public boolean growPlant(GrowthBlock block, boolean underwater) {
|
public boolean growPlant(GrowthBlock block, boolean underwater) {
|
||||||
Block bl = block.block();
|
Block bl = block.block();
|
||||||
return getRandomPlant(underwater).map(p -> {
|
return getRandomPlant(underwater).map(p -> {
|
||||||
if (bl.getY() != 0 && canGrowOn(block, p)) {
|
if (bl.getY() != 0 && canGrowOn(block, p) && plantIt(bl, p)) {
|
||||||
if (plantIt(bl, p)) {
|
bl.getWorld().spawnParticle(Particle.SNOWBALL, bl.getLocation(), 10, 2, 2, 2);
|
||||||
bl.getWorld().spawnParticle(Particle.SNOWBALL, bl.getLocation(), 10, 2, 2, 2);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}).orElse(false);
|
}).orElse(false);
|
||||||
@ -554,14 +570,12 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
BlockFace d = null;
|
BlockFace d = null;
|
||||||
boolean waterLogged = false;
|
boolean waterLogged = false;
|
||||||
for (BlockFace adj : ADJ_BLOCKS) {
|
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;
|
d = adj;
|
||||||
break;
|
if (type.equals(Material.WATER)) {
|
||||||
}
|
waterLogged = true;
|
||||||
// Lichen can grow under water too
|
}
|
||||||
if (b.getRelative(adj).getType().equals(Material.WATER)) {
|
|
||||||
d = adj;
|
|
||||||
waterLogged = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,33 +23,17 @@ import world.bentobox.greenhouses.world.AsyncWorldCache;
|
|||||||
* @author tastybento
|
* @author tastybento
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class Roof extends MinMaxXZ {
|
public class Roof extends MinMaxXZ {
|
||||||
private static final List<Material> ROOF_BLOCKS;
|
private static final List<Material> ROOF_BLOCKS = Arrays.stream(Material.values())
|
||||||
static {
|
.filter(Material::isBlock) // Blocks only, no items
|
||||||
// Roof blocks
|
.filter(m -> Tag.TRAPDOORS.isTagged(m) // All trapdoors
|
||||||
ROOF_BLOCKS = Arrays.stream(Material.values())
|
|| (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks
|
||||||
.filter(m -> !m.isLegacy())
|
|| m.equals(Material.HOPPER)).toList();
|
||||||
.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 final AsyncWorldCache cache;
|
private final AsyncWorldCache cache;
|
||||||
private int height;
|
private int height;
|
||||||
private final Location location;
|
private final Location location;
|
||||||
private boolean roofFound;
|
private boolean roofFound;
|
||||||
|
private final Greenhouses addon;
|
||||||
private final World world;
|
private final World world;
|
||||||
|
|
||||||
|
|
||||||
@ -58,13 +42,23 @@ public class Roof extends MinMaxXZ {
|
|||||||
* @param cache async world cache
|
* @param cache async world cache
|
||||||
* @param loc - starting location
|
* @param loc - starting location
|
||||||
*/
|
*/
|
||||||
public Roof(AsyncWorldCache cache, Location loc) {
|
public Roof(AsyncWorldCache cache, Location loc, Greenhouses addon) {
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.location = loc;
|
this.location = loc;
|
||||||
|
this.addon = addon;
|
||||||
this.world = loc.getWorld();
|
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
|
* 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) {
|
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
|
// 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();
|
int startY = loc.getBlockY();
|
||||||
for (int y = startY; y < world.getMaxHeight(); y++) {
|
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
|
// 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) {
|
if (!roofFound) {
|
||||||
loc = spiralSearch(loc, startY);
|
loc = spiralSearch(loc, startY);
|
||||||
if (!roofFound) {
|
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 x - x coord of current search
|
||||||
* @param startY - starting y coord
|
* @param startY - starting y coord
|
||||||
* @param z - z coord of current search
|
* @param z - z coord of current search
|
||||||
*/
|
*/
|
||||||
private Optional<Vector> checkVertically(final int x, final int startY, final int z) {
|
private Optional<Vector> 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
|
// Look up
|
||||||
for (int y = startY; y < world.getMaxHeight() && !roofFound; y++) {
|
for (int y = startY; y < world.getMaxHeight() && !roofFound; y++) {
|
||||||
if (roofBlocks(cache.getBlockType(x,y,z))) {
|
if (roofBlocks(cache.getBlockType(x,y,z))) {
|
||||||
|
@ -9,25 +9,17 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.greenhouses.Greenhouses;
|
|
||||||
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class Walls extends MinMaxXZ {
|
public class Walls extends MinMaxXZ {
|
||||||
private static final List<Material> WALL_BLOCKS;
|
public static final List<Material> WALL_BLOCKS = Arrays.stream(Material.values())
|
||||||
static {
|
.filter(Material::isBlock) // Blocks only, no items
|
||||||
// Hoppers
|
.filter(m -> !m.name().contains("TRAPDOOR")) // No trap doors
|
||||||
WALL_BLOCKS = Arrays.stream(Material.values())
|
.filter(m -> m.name().contains("DOOR") // All doors
|
||||||
.filter(Material::isBlock) // Blocks only, no items
|
|| (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks
|
||||||
.filter(m -> !m.isLegacy())
|
|| m.equals(Material.HOPPER)).toList();
|
||||||
.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 int floor;
|
||||||
|
|
||||||
private final AsyncWorldCache cache;
|
private final AsyncWorldCache cache;
|
||||||
|
|
||||||
static class WallFinder {
|
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
|
* @return the floor
|
||||||
*/
|
*/
|
||||||
|
@ -53,7 +53,7 @@ public class GreenhouseGuard implements Listener {
|
|||||||
if (from.isPresent() && addon.getSettings().isAllowFlowOut()) {
|
if (from.isPresent() && addon.getSettings().isAllowFlowOut()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Otherwise cancel - the flow is not allowed
|
// Otherwise, cancel - the flow is not allowed
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,17 +95,17 @@ public class EcoSystemManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final BoundingBox ibb = gh.getInternalBoundingBox();
|
final BoundingBox ibb = gh.getInternalBoundingBox();
|
||||||
int gh_min_x = NumberConversions.floor(ibb.getMinX());
|
int ghMinX = NumberConversions.floor(ibb.getMinX());
|
||||||
int gh_max_x = NumberConversions.floor(ibb.getMaxX());
|
int ghMaxX = NumberConversions.floor(ibb.getMaxX());
|
||||||
int gh_min_y = NumberConversions.floor(gh.getBoundingBox().getMinY()); // Note: this gets the floor
|
int ghMinY = NumberConversions.floor(gh.getBoundingBox().getMinY()); // Note: this gets the floor
|
||||||
int gh_max_y = NumberConversions.floor(ibb.getMaxY());
|
int ghMaxY = NumberConversions.floor(ibb.getMaxY());
|
||||||
int gh_min_z = NumberConversions.floor(ibb.getMinZ());
|
int ghMinZ = NumberConversions.floor(ibb.getMinZ());
|
||||||
int gh_max_z = NumberConversions.floor(ibb.getMaxZ());
|
int ghMaxZ = NumberConversions.floor(ibb.getMaxZ());
|
||||||
BiomeRecipe biomeRecipe = gh.getBiomeRecipe();
|
BiomeRecipe biomeRecipe = gh.getBiomeRecipe();
|
||||||
|
|
||||||
for (int x = gh_min_x; x < gh_max_x; x++) {
|
for (int x = ghMinX; x < ghMaxX; x++) {
|
||||||
for (int z = gh_min_z; z < gh_max_z; z++) {
|
for (int z = ghMinZ; z < ghMaxZ; z++) {
|
||||||
for (int y = gh_min_y; y < gh_max_y; y++) {
|
for (int y = ghMinY; y < ghMaxY; y++) {
|
||||||
Block b = world.getBlockAt(x, y, z);
|
Block b = world.getBlockAt(x, y, z);
|
||||||
|
|
||||||
if(!b.isEmpty()) {
|
if(!b.isEmpty()) {
|
||||||
@ -167,7 +167,7 @@ public class EcoSystemManager {
|
|||||||
Collections.shuffle(list, new Random(System.currentTimeMillis()));
|
Collections.shuffle(list, new Random(System.currentTimeMillis()));
|
||||||
Iterator<GrowthBlock> it = list.iterator();
|
Iterator<GrowthBlock> it = list.iterator();
|
||||||
// Check if the greenhouse is full
|
// Check if the greenhouse is full
|
||||||
if (sum >= gh.getBiomeRecipe().getMaxMob()) {
|
if (gh.getBiomeRecipe().getMaxMob() > -1 && sum >= gh.getBiomeRecipe().getMaxMob()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (it.hasNext() && (sum == 0 || gh.getArea() / sum >= gh.getBiomeRecipe().getMobLimit())) {
|
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 z = ibb.getMinZ(); z < ibb.getMaxZ(); z++) {
|
||||||
for (double y = ibb.getMaxY() - 1; y >= bb.getMinY(); y--) {
|
for (double y = ibb.getMaxY() - 1; y >= bb.getMinY(); y--) {
|
||||||
Block b = gh.getWorld().getBlockAt(NumberConversions.floor(x), NumberConversions.floor(y), NumberConversions.floor(z));
|
Block b = gh.getWorld().getBlockAt(NumberConversions.floor(x), NumberConversions.floor(y), NumberConversions.floor(z));
|
||||||
|
if (checkBlock(result, b, ignoreLiquid)) {
|
||||||
// Check floor blocks
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkBlock(List<GrowthBlock> 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) {
|
private int getBoneMeal(Greenhouse gh) {
|
||||||
Hopper hopper = getHopper(gh);
|
Hopper hopper = getHopper(gh);
|
||||||
|
@ -12,6 +12,7 @@ import org.bukkit.Tag;
|
|||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
import world.bentobox.greenhouses.data.Greenhouse;
|
import world.bentobox.greenhouses.data.Greenhouse;
|
||||||
import world.bentobox.greenhouses.greenhouse.Roof;
|
import world.bentobox.greenhouses.greenhouse.Roof;
|
||||||
import world.bentobox.greenhouses.greenhouse.Walls;
|
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
|
// If this is the bottom layer, the player has most likely uneven walls
|
||||||
private int otherBlockLayer = -1;
|
private int otherBlockLayer = -1;
|
||||||
private int wallBlockCount;
|
private int wallBlockCount;
|
||||||
|
private final Greenhouses addon;
|
||||||
/**
|
/**
|
||||||
* This is the count of the various items
|
* This is the count of the various items
|
||||||
*/
|
*/
|
||||||
private CounterCheck cc = new CounterCheck();
|
private CounterCheck counterCheck = new CounterCheck();
|
||||||
|
|
||||||
static class CounterCheck {
|
static class CounterCheck {
|
||||||
int doorCount;
|
int doorCount;
|
||||||
@ -40,6 +42,13 @@ public class GreenhouseFinder {
|
|||||||
boolean otherBlock;
|
boolean otherBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param addon Addon
|
||||||
|
*/
|
||||||
|
public GreenhouseFinder(Greenhouses addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find out if there is a greenhouse here
|
* Find out if there is a greenhouse here
|
||||||
* @param location - start location
|
* @param location - start location
|
||||||
@ -51,9 +60,9 @@ public class GreenhouseFinder {
|
|||||||
redGlass.clear();
|
redGlass.clear();
|
||||||
|
|
||||||
// Get a world cache
|
// Get a world cache
|
||||||
AsyncWorldCache cache = new AsyncWorldCache(location.getWorld());
|
AsyncWorldCache cache = new AsyncWorldCache(addon, location.getWorld());
|
||||||
// Find the roof
|
// Find the roof
|
||||||
Roof roof = new Roof(cache, location);
|
Roof roof = new Roof(cache, location, addon);
|
||||||
roof.findRoof().thenAccept(found -> {
|
roof.findRoof().thenAccept(found -> {
|
||||||
if (Boolean.FALSE.equals(found)) {
|
if (Boolean.FALSE.equals(found)) {
|
||||||
result.add(GreenhouseResult.FAIL_NO_ROOF);
|
result.add(GreenhouseResult.FAIL_NO_ROOF);
|
||||||
@ -87,30 +96,26 @@ public class GreenhouseFinder {
|
|||||||
*/
|
*/
|
||||||
CompletableFuture<Set<GreenhouseResult>> checkGreenhouse(AsyncWorldCache cache, Roof roof, Walls walls) {
|
CompletableFuture<Set<GreenhouseResult>> checkGreenhouse(AsyncWorldCache cache, Roof roof, Walls walls) {
|
||||||
CompletableFuture<Set<GreenhouseResult>> r = new CompletableFuture<>();
|
CompletableFuture<Set<GreenhouseResult>> 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;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<GreenhouseResult> checkGHAsync(CompletableFuture<Set<GreenhouseResult>> r, AsyncWorldCache cache,
|
private Set<GreenhouseResult> checkGreenhouseAsync(CompletableFuture<Set<GreenhouseResult>> r, AsyncWorldCache cache,
|
||||||
Roof roof, Walls walls) {
|
Roof roof, Walls walls) {
|
||||||
cc = new CounterCheck();
|
counterCheck = new CounterCheck();
|
||||||
int y;
|
int y;
|
||||||
for (y = roof.getHeight(); y > walls.getFloor(); y--) {
|
for (y = roof.getHeight(); y > walls.getFloor(); y--) {
|
||||||
wallBlockCount = 0;
|
wallBlockCount = 0;
|
||||||
for (int x = walls.getMinX(); x <= walls.getMaxX(); x++) {
|
for (int x = walls.getMinX(); x <= walls.getMaxX(); x++) {
|
||||||
for (int z = walls.getMinZ(); z <= walls.getMaxZ(); z++) {
|
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()) {
|
if (wallBlockCount == 0 && y < roof.getHeight()) {
|
||||||
// This is the floor
|
// This is the floor
|
||||||
break;
|
break;
|
||||||
} else {
|
} else if (counterCheck.otherBlock && otherBlockLayer < 0) {
|
||||||
if (cc.otherBlock) {
|
otherBlockLayer = y;
|
||||||
if (otherBlockLayer < 0) {
|
|
||||||
otherBlockLayer = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +143,7 @@ public class GreenhouseFinder {
|
|||||||
// Roof blocks must be glass, glowstone, doors or a hopper.
|
// Roof blocks must be glass, glowstone, doors or a hopper.
|
||||||
result.add(GreenhouseResult.FAIL_BAD_ROOF_BLOCKS);
|
result.add(GreenhouseResult.FAIL_BAD_ROOF_BLOCKS);
|
||||||
} else if (isOtherBlocks()) {
|
} 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);
|
result.add(GreenhouseResult.FAIL_BAD_WALL_BLOCKS);
|
||||||
}
|
}
|
||||||
if (this.getWallDoors() > 8) {
|
if (this.getWallDoors() > 8) {
|
||||||
@ -166,7 +171,8 @@ public class GreenhouseFinder {
|
|||||||
// Check wall blocks only
|
// Check wall blocks only
|
||||||
if (y == roof.getHeight() || x == walls.getMinX() || x == walls.getMaxX() || z == walls.getMinZ() || z== walls.getMaxZ()) {
|
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
|
// 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)) {
|
if (m.equals(Material.AIR)) {
|
||||||
// Air hole found
|
// Air hole found
|
||||||
cc.airHole = true;
|
cc.airHole = true;
|
||||||
@ -241,28 +247,28 @@ public class GreenhouseFinder {
|
|||||||
* @return the wallDoors
|
* @return the wallDoors
|
||||||
*/
|
*/
|
||||||
int getWallDoors() {
|
int getWallDoors() {
|
||||||
return cc.doorCount;
|
return counterCheck.doorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the ghHopper
|
* @return the ghHopper
|
||||||
*/
|
*/
|
||||||
int getGhHopper() {
|
int getGhHopper() {
|
||||||
return cc.hopperCount;
|
return counterCheck.hopperCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the airHoles
|
* @return the airHoles
|
||||||
*/
|
*/
|
||||||
boolean isAirHoles() {
|
boolean isAirHoles() {
|
||||||
return cc.airHole;
|
return counterCheck.airHole;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the otherBlocks
|
* @return the otherBlocks
|
||||||
*/
|
*/
|
||||||
boolean isOtherBlocks() {
|
boolean isOtherBlocks() {
|
||||||
return cc.otherBlock;
|
return counterCheck.otherBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -315,21 +321,21 @@ public class GreenhouseFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setGhHopper(int i) {
|
public void setGhHopper(int i) {
|
||||||
cc.hopperCount = i;
|
counterCheck.hopperCount = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWallDoors(int i) {
|
public void setWallDoors(int i) {
|
||||||
cc.doorCount = i;
|
counterCheck.doorCount = i;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAirHoles(boolean b) {
|
public void setAirHoles(boolean b) {
|
||||||
cc.airHole = b;
|
counterCheck.airHole = b;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOtherBlocks(boolean b) {
|
public void setOtherBlocks(boolean b) {
|
||||||
cc.otherBlock = b;
|
counterCheck.otherBlock = b;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,19 +96,19 @@ public class GreenhouseManager implements Listener {
|
|||||||
handler.loadObjects().forEach(g -> {
|
handler.loadObjects().forEach(g -> {
|
||||||
GreenhouseResult result = map.addGreenhouse(g);
|
GreenhouseResult result = map.addGreenhouse(g);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case FAIL_NO_ISLAND ->
|
case FAIL_NO_ISLAND ->
|
||||||
// Delete the failed greenhouse
|
// Delete the failed greenhouse
|
||||||
toBeRemoved.add(g);
|
toBeRemoved.add(g);
|
||||||
case FAIL_OVERLAPPING -> addon.logError("Greenhouse overlaps with another greenhouse. Skipping...");
|
case FAIL_OVERLAPPING -> addon.logError("Greenhouse overlaps with another greenhouse. Skipping...");
|
||||||
case NULL -> addon.logError("Null location of greenhouse. Cannot load. Skipping...");
|
case NULL -> addon.logError("Null location of greenhouse. Cannot load. Skipping...");
|
||||||
case SUCCESS -> activateGreenhouse(g);
|
case SUCCESS -> activateGreenhouse(g);
|
||||||
case FAIL_NO_WORLD -> addon.logError("Database contains greenhouse for a non-loaded world. Skipping...");
|
case FAIL_NO_WORLD -> addon.logError("Database contains greenhouse for a non-loaded world. Skipping...");
|
||||||
case FAIL_UNKNOWN_RECIPE -> {
|
case FAIL_UNKNOWN_RECIPE -> {
|
||||||
addon.logError("Greenhouse uses a recipe that does not exist in the biomes.yml. Skipping...");
|
addon.logError("Greenhouse uses a recipe that does not exist in the biomes.yml. Skipping...");
|
||||||
addon.logError("Greenhouse Id " + g.getUniqueId());
|
addon.logError("Greenhouse Id " + g.getUniqueId());
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addon.log("Loaded " + map.getSize() + " greenhouses.");
|
addon.log("Loaded " + map.getSize() + " greenhouses.");
|
||||||
@ -153,7 +153,7 @@ public class GreenhouseManager implements Listener {
|
|||||||
*/
|
*/
|
||||||
public CompletableFuture<GhResult> tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) {
|
public CompletableFuture<GhResult> tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) {
|
||||||
CompletableFuture<GhResult> r = new CompletableFuture<>();
|
CompletableFuture<GhResult> r = new CompletableFuture<>();
|
||||||
GreenhouseFinder finder = new GreenhouseFinder();
|
GreenhouseFinder finder = new GreenhouseFinder(addon);
|
||||||
finder.find(location).thenAccept(resultSet -> {
|
finder.find(location).thenAccept(resultSet -> {
|
||||||
if (!resultSet.isEmpty()) {
|
if (!resultSet.isEmpty()) {
|
||||||
// Failure!
|
// Failure!
|
||||||
|
@ -6,7 +6,6 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
|
||||||
@ -138,7 +137,7 @@ public class GreenhouseMap {
|
|||||||
* @return a list of all the Greenhouses
|
* @return a list of all the Greenhouses
|
||||||
*/
|
*/
|
||||||
public List<Greenhouse> getGreenhouses() {
|
public List<Greenhouse> getGreenhouses() {
|
||||||
return greenhouses.values().stream().flatMap(List::stream).collect(Collectors.toList());
|
return greenhouses.values().stream().flatMap(List::stream).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,6 +30,7 @@ public class RecipeManager {
|
|||||||
private static final int MAXIMUM_INVENTORY_SIZE = 49;
|
private static final int MAXIMUM_INVENTORY_SIZE = 49;
|
||||||
private final Greenhouses addon;
|
private final Greenhouses addon;
|
||||||
private static final List<BiomeRecipe> biomeRecipes = new ArrayList<>();
|
private static final List<BiomeRecipe> biomeRecipes = new ArrayList<>();
|
||||||
|
private static final String COULD_NOT_PARSE = "Could not parse ";
|
||||||
|
|
||||||
public RecipeManager(Greenhouses addon) {
|
public RecipeManager(Greenhouses addon) {
|
||||||
this.addon = addon;
|
this.addon = addon;
|
||||||
@ -179,45 +180,54 @@ public class RecipeManager {
|
|||||||
ConfigurationSection conversionSec = biomeRecipeConfig.getConfigurationSection("conversions");
|
ConfigurationSection conversionSec = biomeRecipeConfig.getConfigurationSection("conversions");
|
||||||
if (conversionSec != null) {
|
if (conversionSec != null) {
|
||||||
for (String oldMat : conversionSec.getKeys(false)) {
|
for (String oldMat : conversionSec.getKeys(false)) {
|
||||||
try {
|
parseConversions(oldMat, conversionSec, b);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get the list of conversions
|
// Get the list of conversions
|
||||||
for (String oldMat : biomeRecipeConfig.getStringList("conversion-list")) {
|
for (String oldMat : biomeRecipeConfig.getStringList("conversion-list")) {
|
||||||
try {
|
parseConversionList(oldMat, b);
|
||||||
// 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 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) {
|
private void loadMobs(ConfigurationSection biomeRecipeConfig, BiomeRecipe b) {
|
||||||
ConfigurationSection temp = biomeRecipeConfig.getConfigurationSection("mobs");
|
ConfigurationSection temp = biomeRecipeConfig.getConfigurationSection("mobs");
|
||||||
// Mob EntityType: Probability:Spawn on Material
|
// Mob EntityType: Probability:Spawn on Material
|
||||||
@ -235,7 +245,7 @@ public class RecipeManager {
|
|||||||
Material mobSpawnOn = Material.valueOf(split[1]);
|
Material mobSpawnOn = Material.valueOf(split[1]);
|
||||||
b.addMobs(mobType, mobProbability, mobSpawnOn);
|
b.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
addon.logError("Could not parse " + s.getKey());
|
addon.logError(COULD_NOT_PARSE + s.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,14 +27,16 @@ public class AsyncWorldCache {
|
|||||||
|
|
||||||
private final World world;
|
private final World world;
|
||||||
private final Map<Pair<Integer, Integer>, ChunkSnapshot> cache;
|
private final Map<Pair<Integer, Integer>, ChunkSnapshot> cache;
|
||||||
|
private final Greenhouses addon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chunk cache. This class is designed to be run async and blocks futures
|
* Chunk cache. This class is designed to be run async and blocks futures
|
||||||
* @param world - world to cache
|
* @param world - world to cache
|
||||||
*/
|
*/
|
||||||
public AsyncWorldCache(World world) {
|
public AsyncWorldCache(Greenhouses addon, World world) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
cache = new HashMap<>();
|
cache = new HashMap<>();
|
||||||
|
this.addon = addon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +61,7 @@ public class AsyncWorldCache {
|
|||||||
*/
|
*/
|
||||||
private CompletableFuture<ChunkSnapshot> getAChunk(int x, int z) {
|
private CompletableFuture<ChunkSnapshot> getAChunk(int x, int z) {
|
||||||
CompletableFuture<ChunkSnapshot> r = new CompletableFuture<>();
|
CompletableFuture<ChunkSnapshot> 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())));
|
Util.getChunkAtAsync(world, x, z).thenAccept(chunk -> r.complete(chunk.getChunkSnapshot())));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -104,7 +106,7 @@ public class AsyncWorldCache {
|
|||||||
try {
|
try {
|
||||||
return Objects.requireNonNull(getSnap(x, z)).getBlockType(xx, y, zz);
|
return Objects.requireNonNull(getSnap(x, z)).getBlockType(xx, y, zz);
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} 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...
|
// Restore interrupted state...
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return Material.AIR;
|
return Material.AIR;
|
||||||
|
@ -59,9 +59,9 @@ greenhouses:
|
|||||||
FAIL_TOO_MANY_DOORS: "&c You cannot have more than 4 doors in the greenhouse!"
|
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_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_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_ICE: "&c Insufficient ice to make this recipe"
|
||||||
FAIL_INSUFFICIENT_LAVA: "&c Insufficent lava to make this recipe"
|
FAIL_INSUFFICIENT_LAVA: "&c Insufficient lava to make this recipe"
|
||||||
FAIL_INSUFFICIENT_WATER: "&c Insufficent water 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_ICE: "&c Ice is required to make this recipe"
|
||||||
FAIL_NO_LAVA: "&c Lava 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"
|
FAIL_NO_WATER: "&c Water is required to make this recipe"
|
||||||
|
@ -5,7 +5,6 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ public class GreenhouseTest {
|
|||||||
// RecipeManager
|
// RecipeManager
|
||||||
PowerMockito.mockStatic(RecipeManager.class);
|
PowerMockito.mockStatic(RecipeManager.class);
|
||||||
when(br.getName()).thenReturn("test");
|
when(br.getName()).thenReturn("test");
|
||||||
when(RecipeManager.getBiomeRecipies(eq("test"))).thenReturn(Optional.of(br));
|
when(RecipeManager.getBiomeRecipies("test")).thenReturn(Optional.of(br));
|
||||||
// Walls
|
// Walls
|
||||||
when(walls.getMinX()).thenReturn(MINX);
|
when(walls.getMinX()).thenReturn(MINX);
|
||||||
when(walls.getMinZ()).thenReturn(MINZ);
|
when(walls.getMinZ()).thenReturn(MINZ);
|
||||||
|
@ -151,7 +151,7 @@ public class BiomeRecipeTest {
|
|||||||
double convChance = 100D;
|
double convChance = 100D;
|
||||||
Material localMaterial = Material.WATER;
|
Material localMaterial = Material.WATER;
|
||||||
br.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
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;
|
int mobProbability = 50;
|
||||||
Material mobSpawnOn = Material.GRASS_BLOCK;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
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);
|
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;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,7 +202,7 @@ public class BiomeRecipeTest {
|
|||||||
int plantProbability = 20;
|
int plantProbability = 20;
|
||||||
Material plantGrowOn = Material.DIRT;
|
Material plantGrowOn = Material.DIRT;
|
||||||
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
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;
|
Material plantGrowOn = Material.DIRT;
|
||||||
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
||||||
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;
|
Material blockMaterial = Material.BLACK_CONCRETE;
|
||||||
int blockQty = 30;
|
int blockQty = 30;
|
||||||
br.addReqBlocks(blockMaterial, blockQty);
|
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);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertFalse(br.spawnMob(block));
|
assertFalse(br.spawnMob(block));
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.CAT));
|
verify(world).spawnEntity(location, EntityType.CAT);
|
||||||
verify(location).add(any(Vector.class));
|
verify(location).add(any(Vector.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +477,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
assertTrue(br.spawnMob(block));
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.CAT));
|
verify(world).spawnEntity(location, EntityType.CAT);
|
||||||
verify(location).add(any(Vector.class));
|
verify(location).add(any(Vector.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,7 +504,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
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(location).add(any(Vector.class));
|
||||||
verify(hoglin).setImmuneToZombification(true);
|
verify(hoglin).setImmuneToZombification(true);
|
||||||
}
|
}
|
||||||
@ -532,7 +532,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
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(location).add(any(Vector.class));
|
||||||
verify(piglin).setImmuneToZombification(true);
|
verify(piglin).setImmuneToZombification(true);
|
||||||
}
|
}
|
||||||
@ -562,7 +562,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
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(location).add(any(Vector.class));
|
||||||
verify(piglin, never()).setImmuneToZombification(true);
|
verify(piglin, never()).setImmuneToZombification(true);
|
||||||
}
|
}
|
||||||
@ -586,7 +586,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertFalse(br.spawnMob(block));
|
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.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
||||||
assertTrue(br.growPlant(new GrowthBlock(block, true), false));
|
assertTrue(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
||||||
verify(bisected).setHalf(eq(Half.BOTTOM));
|
verify(bisected).setHalf(Half.BOTTOM);
|
||||||
verify(bisected).setHalf(eq(Half.TOP));
|
verify(bisected).setHalf(Half.TOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -722,8 +722,8 @@ public class BiomeRecipeTest {
|
|||||||
when(block.isEmpty()).thenReturn(true);
|
when(block.isEmpty()).thenReturn(true);
|
||||||
Block ob = mock(Block.class);
|
Block ob = mock(Block.class);
|
||||||
when(ob.getType()).thenReturn(Material.GRASS_BLOCK);
|
when(ob.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(eq(BlockFace.DOWN))).thenReturn(ob);
|
when(block.getRelative(BlockFace.DOWN)).thenReturn(ob);
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(ob);
|
when(block.getRelative(BlockFace.UP)).thenReturn(ob);
|
||||||
assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
||||||
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,6 @@ public class RoofTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
||||||
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
||||||
PowerMockito.mockStatic(Greenhouses.class, Mockito.RETURNS_MOCKS);
|
|
||||||
when(Greenhouses.getInstance()).thenReturn(addon);
|
|
||||||
s = new Settings();
|
s = new Settings();
|
||||||
when(addon.getSettings()).thenReturn(s);
|
when(addon.getSettings()).thenReturn(s);
|
||||||
|
|
||||||
@ -89,14 +87,14 @@ public class RoofTest {
|
|||||||
when(location.clone()).thenReturn(location);
|
when(location.clone()).thenReturn(location);
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
roof = new Roof(cache, location);
|
roof = new Roof(cache, location, addon);
|
||||||
assertTrue(roof.findRoof(new Vector(10,10,10)));
|
assertTrue(roof.findRoof(new Vector(10,10,10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoGlass() {
|
public void testNoGlass() {
|
||||||
when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.AIR);
|
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)));
|
assertFalse(roof.findRoof(new Vector(10,10,10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,13 +167,13 @@ public class RoofTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWallBlocks() {
|
public void testWallBlocks() {
|
||||||
assertFalse(Roof.roofBlocks(Material.ACACIA_BOAT));
|
assertFalse(roof.roofBlocks(Material.ACACIA_BOAT));
|
||||||
assertTrue(Roof.roofBlocks(Material.GLASS));
|
assertTrue(roof.roofBlocks(Material.GLASS));
|
||||||
assertTrue(Roof.roofBlocks(Material.GLOWSTONE));
|
assertTrue(roof.roofBlocks(Material.GLOWSTONE));
|
||||||
assertFalse(Roof.roofBlocks(Material.ACACIA_DOOR));
|
assertFalse(roof.roofBlocks(Material.ACACIA_DOOR));
|
||||||
assertTrue(Roof.roofBlocks(Material.HOPPER));
|
assertTrue(roof.roofBlocks(Material.HOPPER));
|
||||||
assertTrue(Roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
assertTrue(roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
||||||
assertTrue(Roof.roofBlocks(Material.BIRCH_TRAPDOOR));
|
assertTrue(roof.roofBlocks(Material.BIRCH_TRAPDOOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,12 +183,12 @@ public class RoofTest {
|
|||||||
public void testWallBlocksNoGlowStoneNoPanes() {
|
public void testWallBlocksNoGlowStoneNoPanes() {
|
||||||
s.setAllowGlowstone(false);
|
s.setAllowGlowstone(false);
|
||||||
s.setAllowPanes(false);
|
s.setAllowPanes(false);
|
||||||
assertFalse(Roof.roofBlocks(Material.ACACIA_BOAT));
|
assertFalse(roof.roofBlocks(Material.ACACIA_BOAT));
|
||||||
assertTrue(Roof.roofBlocks(Material.GLASS));
|
assertTrue(roof.roofBlocks(Material.GLASS));
|
||||||
assertFalse(Roof.roofBlocks(Material.GLOWSTONE));
|
assertFalse(roof.roofBlocks(Material.GLOWSTONE));
|
||||||
assertFalse(Roof.roofBlocks(Material.ACACIA_DOOR));
|
assertFalse(roof.roofBlocks(Material.ACACIA_DOOR));
|
||||||
assertTrue(Roof.roofBlocks(Material.HOPPER));
|
assertTrue(roof.roofBlocks(Material.HOPPER));
|
||||||
assertFalse(Roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
assertFalse(roof.roofBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
||||||
assertTrue(Roof.roofBlocks(Material.BIRCH_TRAPDOOR));
|
assertTrue(roof.roofBlocks(Material.BIRCH_TRAPDOOR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,12 +64,10 @@ public class WallsTest {
|
|||||||
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
||||||
// Declare mock after mocking Bukkit
|
// Declare mock after mocking Bukkit
|
||||||
roof = mock(Roof.class);
|
roof = mock(Roof.class);
|
||||||
PowerMockito.mockStatic(Greenhouses.class, Mockito.RETURNS_MOCKS);
|
|
||||||
when(Greenhouses.getInstance()).thenReturn(addon);
|
|
||||||
s = new Settings();
|
s = new Settings();
|
||||||
when(addon.getSettings()).thenReturn(s);
|
when(addon.getSettings()).thenReturn(s);
|
||||||
when(addon.getPlugin()).thenReturn(plugin);
|
when(addon.getPlugin()).thenReturn(plugin);
|
||||||
|
when(addon.wallBlocks(any())).thenCallRealMethod();
|
||||||
walls = new Walls(cache);
|
walls = new Walls(cache);
|
||||||
when(world.getMaxHeight()).thenReturn(255);
|
when(world.getMaxHeight()).thenReturn(255);
|
||||||
when(location.getWorld()).thenReturn(world);
|
when(location.getWorld()).thenReturn(world);
|
||||||
@ -201,13 +199,13 @@ public class WallsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWallBlocks() {
|
public void testWallBlocks() {
|
||||||
assertFalse(Walls.wallBlocks(Material.ACACIA_BOAT));
|
assertFalse(addon.wallBlocks(Material.ACACIA_BOAT));
|
||||||
assertTrue(Walls.wallBlocks(Material.GLASS));
|
assertTrue(addon.wallBlocks(Material.GLASS));
|
||||||
assertTrue(Walls.wallBlocks(Material.GLOWSTONE));
|
assertTrue(addon.wallBlocks(Material.GLOWSTONE));
|
||||||
assertTrue(Walls.wallBlocks(Material.ACACIA_DOOR));
|
assertTrue(addon.wallBlocks(Material.ACACIA_DOOR));
|
||||||
assertTrue(Walls.wallBlocks(Material.HOPPER));
|
assertTrue(addon.wallBlocks(Material.HOPPER));
|
||||||
assertTrue(Walls.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
assertTrue(addon.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
||||||
assertFalse(Walls.wallBlocks(Material.BIRCH_TRAPDOOR));
|
assertFalse(addon.wallBlocks(Material.BIRCH_TRAPDOOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,13 +215,13 @@ public class WallsTest {
|
|||||||
public void testWallBlocksNoGlowStoneNoPanes() {
|
public void testWallBlocksNoGlowStoneNoPanes() {
|
||||||
s.setAllowGlowstone(false);
|
s.setAllowGlowstone(false);
|
||||||
s.setAllowPanes(false);
|
s.setAllowPanes(false);
|
||||||
assertFalse(Walls.wallBlocks(Material.ACACIA_BOAT));
|
assertFalse(addon.wallBlocks(Material.ACACIA_BOAT));
|
||||||
assertTrue(Walls.wallBlocks(Material.GLASS));
|
assertTrue(addon.wallBlocks(Material.GLASS));
|
||||||
assertFalse(Walls.wallBlocks(Material.GLOWSTONE));
|
assertFalse(addon.wallBlocks(Material.GLOWSTONE));
|
||||||
assertTrue(Walls.wallBlocks(Material.ACACIA_DOOR));
|
assertTrue(addon.wallBlocks(Material.ACACIA_DOOR));
|
||||||
assertTrue(Walls.wallBlocks(Material.HOPPER));
|
assertTrue(addon.wallBlocks(Material.HOPPER));
|
||||||
assertFalse(Walls.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
assertFalse(addon.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
||||||
assertFalse(Walls.wallBlocks(Material.BIRCH_TRAPDOOR));
|
assertFalse(addon.wallBlocks(Material.BIRCH_TRAPDOOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,22 +83,22 @@ public class EcoSystemManagerTest {
|
|||||||
// Liquid false
|
// Liquid false
|
||||||
when(air.isEmpty()).thenReturn(true);
|
when(air.isEmpty()).thenReturn(true);
|
||||||
when(air.isPassable()).thenReturn(true);
|
when(air.isPassable()).thenReturn(true);
|
||||||
when(air.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(air.getRelative(BlockFace.UP)).thenReturn(air);
|
||||||
// Plant
|
// Plant
|
||||||
// Empty false
|
// Empty false
|
||||||
// Liquid false
|
// Liquid false
|
||||||
when(plant.isPassable()).thenReturn(true);
|
when(plant.isPassable()).thenReturn(true);
|
||||||
when(plant.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(plant.getRelative(BlockFace.UP)).thenReturn(air);
|
||||||
// Liquid
|
// Liquid
|
||||||
// Empty false
|
// Empty false
|
||||||
when(liquid.isLiquid()).thenReturn(true);
|
when(liquid.isLiquid()).thenReturn(true);
|
||||||
when(liquid.isPassable()).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
|
// Default for block
|
||||||
// Empty false
|
// Empty false
|
||||||
// Passable false
|
// Passable false
|
||||||
// Liquid false
|
// Liquid false
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(block.getRelative(BlockFace.UP)).thenReturn(air);
|
||||||
|
|
||||||
// Recipe
|
// Recipe
|
||||||
when(recipe.noMobs()).thenReturn(true);
|
when(recipe.noMobs()).thenReturn(true);
|
||||||
|
@ -71,12 +71,14 @@ public class GreenhouseFinderTest {
|
|||||||
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
||||||
// Declare mock after mocking Bukkit
|
// Declare mock after mocking Bukkit
|
||||||
roof = mock(Roof.class);
|
roof = mock(Roof.class);
|
||||||
|
when(roof.roofBlocks(any())).thenCallRealMethod();
|
||||||
// Location
|
// Location
|
||||||
when(location.getBlockX()).thenReturn(5);
|
when(location.getBlockX()).thenReturn(5);
|
||||||
when(location.getBlockY()).thenReturn(14);
|
when(location.getBlockY()).thenReturn(14);
|
||||||
when(location.getBlockZ()).thenReturn(25);
|
when(location.getBlockZ()).thenReturn(25);
|
||||||
when(location.getWorld()).thenReturn(world);
|
when(location.getWorld()).thenReturn(world);
|
||||||
|
// Addon
|
||||||
|
when(addon.wallBlocks(any())).thenCallRealMethod();
|
||||||
// Block
|
// Block
|
||||||
when(cache.getBlockType(any())).thenReturn(Material.GLASS);
|
when(cache.getBlockType(any())).thenReturn(Material.GLASS);
|
||||||
when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.GLASS);
|
when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.GLASS);
|
||||||
@ -94,7 +96,7 @@ public class GreenhouseFinderTest {
|
|||||||
when(cache.getMaxHeight()).thenReturn(30);
|
when(cache.getMaxHeight()).thenReturn(30);
|
||||||
|
|
||||||
|
|
||||||
gf = new GreenhouseFinder();
|
gf = new GreenhouseFinder(addon);
|
||||||
cc = new CounterCheck();
|
cc = new CounterCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user