Compare commits
70 Commits
Author | SHA1 | Date |
---|---|---|
tastybento | 93e3152efc | |
tastybento | 0fc5857a4a | |
tastybento | d1e771bad6 | |
tastybento | 04a519ad51 | |
tastybento | 3fc14f5cd8 | |
tastybento | 8ce5cc0e3c | |
tastybento | 15c2cea475 | |
tastybento | 4084876c4b | |
tastybento | a7eeef7edc | |
tastybento | ca4f1a3f43 | |
tastybento | 6bc1c5e4bc | |
tastybento | 53cb40e7c4 | |
tastybento | e05e2806fe | |
tastybento | 02c2135501 | |
tastybento | 605144e9f9 | |
tastybento | 3f4647b547 | |
tastybento | e75780e710 | |
tastybento | 7e4f0764e6 | |
tastybento | 398c8e91d5 | |
tastybento | 2eed3dcd56 | |
tastybento | 3dd950459f | |
tastybento | cce4a655c6 | |
tastybento | a2c2975329 | |
tastybento | e6a1cd17bb | |
BONNe | 5fd9cbfd36 | |
BONNe | db5ef4d5da | |
tastybento | ac1d6e6638 | |
BONNe | 3740268dfc | |
tastybento | 308dc225cd | |
tastybento | 95474d6c53 | |
tastybento | d2801dcd75 | |
tastybento | e4bbb70acb | |
tastybento | a4fc49689b | |
tastybento | 66270cf3e7 | |
tastybento | 4351247de2 | |
tastybento | 9e407e659e | |
tastybento | d6df904fbc | |
tastybento | 9af8816995 | |
tastybento | ce0eeae546 | |
tastybento | cf276bbb24 | |
tastybento | de6a939bb9 | |
tastybento | 10a1d63778 | |
tastybento | bba0b33133 | |
tastybento | 4b69c39496 | |
tastybento | fe0a794e68 | |
tastybento | 1975df2732 | |
tastybento | 1f0b579d5a | |
tastybento | e5c62047ff | |
tastybento | 02490d3b85 | |
tastybento | 717903e346 | |
Zorua162 | 61478ff4d5 | |
BONNe | a96d4d4c67 | |
tastybento | 8af2b2057d | |
tastybento | 6f6745e849 | |
BONNe | 0a016c2eaa | |
tastybento | d64be1c518 | |
BONNe | e2b779a9cb | |
tastybento | 06230e4957 | |
tastybento | 0e76838721 | |
tastybento | 9a7cad85af | |
tastybento | 5808c5933a | |
gitlocalize-app[bot] | cf7b1c7164 | |
gitlocalize-app[bot] | c5b80b2f4a | |
gitlocalize-app[bot] | b90559122b | |
gitlocalize-app[bot] | df60720e75 | |
tastybento | 6e41588405 | |
tastybento | b7c30cb608 | |
Florian CUNY | 925e50eb46 | |
Florian CUNY | 61e1db5f43 | |
tastybento | 024b311180 |
|
@ -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 16
|
||||
uses: actions/setup-java@v1
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 16
|
||||
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') }}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
/target/
|
||||
/.classpath
|
||||
/.project
|
||||
/.DS_Store
|
||||
/Greenhouses-addon.iml
|
||||
/.idea/
|
13
README.md
13
README.md
|
@ -1,8 +1,9 @@
|
|||
# Greenhouses - an add-on for BentoBox
|
||||
|
||||
## Note for 1.15.x + servers
|
||||
|
||||
Biomes have changed so that they take up a 4x4 area and so greenhouse biomes now can bleed outside of the greenhouse. Unfortunately, this cannot be mitigated (as far as I know). If you have a good imagination, you can say that the biome of the greenhouse influences the surroundings a bit and it is natural! So it's a feature, not a bug!
|
||||
[![Build Status](https://ci.codemc.org/buildStatus/icon?job=BentoBoxWorld/Greenhouses)](https://ci.codemc.org/job/BentoBoxWorld/job/Greenhouses/)[
|
||||
![Bugs](https://sonarcloud.io/api/project_badges/measure?project=BentoBoxWorld_Greenhouses&metric=bugs)](https://sonarcloud.io/dashboard?id=BentoBoxWorld_Greenhouses)
|
||||
[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=BentoBoxWorld_Greenhouses&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=BentoBoxWorld_Greenhouses)
|
||||
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=BentoBoxWorld_Greenhouses&metric=ncloc)](https://sonarcloud.io/dashboard?id=BentoBoxWorld_Greenhouses)
|
||||
|
||||
## About
|
||||
|
||||
|
@ -14,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**)
|
||||
|
@ -26,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.
|
||||
|
@ -41,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.
|
||||
|
|
26
pom.xml
26
pom.xml
|
@ -43,15 +43,15 @@
|
|||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>16</java.version>
|
||||
<java.version>17</java.version>
|
||||
<powermock.version>2.0.9</powermock.version>
|
||||
<!-- More visible way how to change dependency versions -->
|
||||
<spigot.version>1.17.1-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>1.16.0</bentobox.version>
|
||||
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
|
||||
<!-- Revision variable removes warning about dynamic version -->
|
||||
<revision>${build.version}-SNAPSHOT</revision>
|
||||
<!-- This allows to change between versions and snapshots. -->
|
||||
<build.version>1.6.0</build.version>
|
||||
<build.version>1.8.0</build.version>
|
||||
<build.number>-LOCAL</build.number>
|
||||
<sonar.projectKey>BentoBoxWorld_Greenhouses</sonar.projectKey>
|
||||
<sonar.organization>bentobox-world</sonar.organization>
|
||||
|
@ -191,9 +191,10 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
${argLine}
|
||||
--add-opens java.base/java.lang=ALL-UNNAMED
|
||||
--add-opens java.base/java.util=ALL-UNNAMED
|
||||
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
|
||||
|
@ -251,30 +252,37 @@
|
|||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.3</version>
|
||||
<version>0.8.10</version>
|
||||
<configuration>
|
||||
<append>true</append>
|
||||
<excludes>
|
||||
<!-- This is required to prevent Jacoco from adding
|
||||
synthetic fields to a JavaBean class (causes errors in testing) -->
|
||||
<exclude>**/*Names*</exclude>
|
||||
<!-- Prevents the Material is too large to mock error -->
|
||||
<exclude>org/bukkit/Material*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-unit-test</id>
|
||||
<id>prepare-agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>post-unit-test</id>
|
||||
<id>report</id>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<formats>
|
||||
<format>XML</format>
|
||||
</formats>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -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<Settings> config;
|
||||
|
||||
public static Greenhouses getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Greenhouses() {
|
||||
super();
|
||||
instance = this;
|
||||
config = new Config<>(this, Settings.class);
|
||||
}
|
||||
|
||||
|
@ -92,9 +87,8 @@ public class Greenhouses extends Addon {
|
|||
*/
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (manager != null) {
|
||||
manager.saveGreenhouses();
|
||||
if (manager.getEcoMgr() != null) manager.getEcoMgr().cancel();
|
||||
if (manager != null && manager.getEcoMgr() != null) {
|
||||
manager.getEcoMgr().cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package world.bentobox.greenhouses;
|
||||
|
||||
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.addons.Pladdon;
|
||||
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*/
|
||||
public class GreenhousesPladdon extends Pladdon
|
||||
{
|
||||
@Override
|
||||
public Addon getAddon()
|
||||
{
|
||||
return new Greenhouses();
|
||||
}
|
||||
}
|
|
@ -171,7 +171,7 @@ public class Greenhouse implements DataObject {
|
|||
*/
|
||||
@NonNull
|
||||
public BoundingBox getBoundingBox() {
|
||||
return Objects.requireNonNullElseGet(boundingBox, BoundingBox::new);
|
||||
return Objects.requireNonNull(boundingBox);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,7 +220,9 @@ public class Greenhouse implements DataObject {
|
|||
* @return true if inside the greenhouse
|
||||
*/
|
||||
public boolean contains(Location location2) {
|
||||
return location.getWorld() != null && location.getWorld().equals(location2.getWorld()) && boundingBox.contains(location2.toVector());
|
||||
return getLocation() != null && getLocation().getWorld() != null
|
||||
&& getLocation().getWorld().equals(location2.getWorld())
|
||||
&& getBoundingBox().contains(location2.toVector());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,12 +264,13 @@ public class Greenhouse implements DataObject {
|
|||
* @return true if wall or roof block
|
||||
*/
|
||||
public boolean isRoofOrWallBlock(Location l) {
|
||||
final BoundingBox bb = getBoundingBox();
|
||||
return (l.getBlockY() > this.getFloorHeight()
|
||||
&& ((l.getBlockY() == getCeilingHeight() - 1)
|
||||
|| l.getBlockX() == (int)getBoundingBox().getMinX()
|
||||
|| l.getBlockX() == (int)getBoundingBox().getMaxX() - 1
|
||||
|| l.getBlockZ() == (int)getBoundingBox().getMinZ()
|
||||
|| l.getBlockZ() == (int)getBoundingBox().getMaxZ() - 1
|
||||
|| l.getBlockX() == (int)bb.getMinX()
|
||||
|| l.getBlockX() == (int)bb.getMaxX() - 1
|
||||
|| l.getBlockZ() == (int)bb.getMinZ()
|
||||
|| l.getBlockZ() == (int)bb.getMaxZ() - 1
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package world.bentobox.greenhouses.greenhouse;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -24,11 +25,13 @@ import org.bukkit.block.Block;
|
|||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.Cocoa;
|
||||
import org.bukkit.block.data.type.GlowLichen;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Hoglin;
|
||||
import org.bukkit.entity.Piglin;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
|
@ -61,12 +64,27 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
}
|
||||
|
||||
private static final List<BlockFace> ADJ_BLOCKS = Arrays.asList( BlockFace.DOWN, BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.UP, BlockFace.WEST);
|
||||
private static final List<BlockFace> SIDE_BLOCKS = Arrays.asList( BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST);
|
||||
private static final List<Material> UNDERWATER_PLANTS;
|
||||
static {
|
||||
List<Material> m = new ArrayList<>();
|
||||
Arrays.stream(Material.values()).filter(c -> c.name().contains("CORAL")).forEach(m::add);
|
||||
m.add(Material.SEA_LANTERN);
|
||||
m.add(Material.SEA_PICKLE);
|
||||
m.add(Material.SEAGRASS);
|
||||
m.add(Material.KELP);
|
||||
m.add(Material.GLOW_LICHEN);
|
||||
UNDERWATER_PLANTS = Collections.unmodifiableList(m);
|
||||
}
|
||||
|
||||
// Content requirements
|
||||
// Material, Type, Qty. There can be more than one type of material required
|
||||
private final Map<Material, Integer> requiredBlocks = new EnumMap<>(Material.class);
|
||||
// Plants
|
||||
/**
|
||||
* Tree map of plants
|
||||
*/
|
||||
private final TreeMap<Double, GreenhousePlant> plantTree = new TreeMap<>();
|
||||
private final TreeMap<Double, GreenhousePlant> underwaterPlants = new TreeMap<>();
|
||||
|
||||
// Mobs
|
||||
// Entity Type, Material to Spawn on, Probability
|
||||
|
@ -83,6 +101,7 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
|
||||
private String permission = "";
|
||||
private final Random random = new Random();
|
||||
private int maxMob;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -149,11 +168,12 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
*/
|
||||
public boolean addPlants(Material plantMaterial, double plantProbability, Material plantGrowOn) {
|
||||
double probability = plantProbability/100;
|
||||
TreeMap<Double, GreenhousePlant> map = UNDERWATER_PLANTS.contains(plantMaterial) ? underwaterPlants : plantTree;
|
||||
// Add up all the probabilities in the list so far
|
||||
double lastProb = plantTree.isEmpty() ? 0D : plantTree.lastKey();
|
||||
double lastProb = map.isEmpty() ? 0D : map.lastKey();
|
||||
if ((1D - lastProb) >= probability) {
|
||||
// Add to probability tree
|
||||
plantTree.put(lastProb + probability, new GreenhousePlant(plantMaterial, plantGrowOn));
|
||||
map.put(lastProb + probability, new GreenhousePlant(plantMaterial, plantGrowOn));
|
||||
} else {
|
||||
addon.logError("Plant chances add up to > 100% in " + type.toString() + " biome recipe! Skipping " + plantMaterial.toString());
|
||||
return false;
|
||||
|
@ -189,24 +209,30 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
* @return set of results from the check
|
||||
*/
|
||||
private Set<GreenhouseResult> checkRecipeAsync(CompletableFuture<Set<GreenhouseResult>> r, Greenhouse gh) {
|
||||
AsyncWorldCache cache = new AsyncWorldCache(gh.getWorld());
|
||||
Set<GreenhouseResult> result = new HashSet<>();
|
||||
AsyncWorldCache cache = new AsyncWorldCache(addon, gh.getWorld());
|
||||
long area = gh.getArea();
|
||||
Map<Material, Integer> 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<Material, Integer> blockCount = countBlocks(gh, cache);
|
||||
|
||||
// Calculate % water, ice and lava ratios and check them
|
||||
Set<GreenhouseResult> result = checkRatios(blockCount, area);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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 lavaRatio = (double)blockCount.getOrDefault(Material.LAVA, 0)/area * 100;
|
||||
int ice = blockCount.entrySet().stream().filter(en -> en.getKey().equals(Material.ICE)
|
||||
|
@ -234,47 +260,57 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
if (iceCoverage > 0 && iceRatio < iceCoverage) {
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
* @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
|
||||
*/
|
||||
|
@ -358,7 +394,9 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
Location spawnLoc = b.getLocation().clone().add(new Vector(0.5, 0, 0.5));
|
||||
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).orElse(true))
|
||||
.filter(m -> Optional.of(m.mobSpawnOn())
|
||||
.map(b.getRelative(BlockFace.DOWN).getType()::equals)
|
||||
.orElse(true))
|
||||
// If spawn occurs, check if it can fit inside greenhouse
|
||||
.map(m -> {
|
||||
Entity entity = b.getWorld().spawnEntity(spawnLoc, m.mobType());
|
||||
|
@ -367,16 +405,13 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
.getManager()
|
||||
.getMap()
|
||||
.getGreenhouse(b.getLocation()).map(gh -> {
|
||||
BoundingBox interior = gh.getBoundingBox().clone();
|
||||
interior.expand(-1, -1, -1);
|
||||
if (!interior.contains(entity.getBoundingBox())) {
|
||||
if (!gh.getInternalBoundingBox().contains(entity.getBoundingBox())) {
|
||||
entity.remove();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}).orElse(false);
|
||||
}).orElse(false);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -411,18 +446,21 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
return key == null ? Optional.empty() : Optional.ofNullable(mobTree.get(key));
|
||||
}
|
||||
|
||||
private Optional<GreenhousePlant> getRandomPlant() {
|
||||
private Optional<GreenhousePlant> getRandomPlant(boolean underwater) {
|
||||
// Grow a random plant that can grow
|
||||
double r = random.nextDouble();
|
||||
Double key = plantTree.ceilingKey(r);
|
||||
return key == null ? Optional.empty() : Optional.ofNullable(plantTree.get(key));
|
||||
Double key = underwater ? underwaterPlants.ceilingKey(r) : plantTree.ceilingKey(r);
|
||||
if (key == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.ofNullable(underwater ? underwaterPlants.get(key) : plantTree.get(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of blocks that are required for this recipe
|
||||
*/
|
||||
public List<String> getRecipeBlocks() {
|
||||
return requiredBlocks.entrySet().stream().map(en -> Util.prettifyText(en.getKey().toString()) + " x " + en.getValue()).collect(Collectors.toList());
|
||||
return requiredBlocks.entrySet().stream().map(en -> Util.prettifyText(en.getKey().toString()) + " x " + en.getValue()).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -435,18 +473,13 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
/**
|
||||
* Plants a plant on block bl if it makes sense.
|
||||
* @param block - block that can have growth
|
||||
* @param underwater - if the block is underwater or not
|
||||
* @return true if successful
|
||||
*/
|
||||
public boolean growPlant(GrowthBlock block) {
|
||||
public boolean growPlant(GrowthBlock block, boolean underwater) {
|
||||
Block bl = block.block();
|
||||
if (!bl.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return getRandomPlant().map(p -> {
|
||||
if (bl.getY() != 0 && canGrowOn(block, p)) {
|
||||
if (!isBisected(bl, p)) {
|
||||
return false;
|
||||
}
|
||||
return getRandomPlant(underwater).map(p -> {
|
||||
if (bl.getY() != 0 && canGrowOn(block, p) && plantIt(bl, p)) {
|
||||
bl.getWorld().spawnParticle(Particle.SNOWBALL, bl.getLocation(), 10, 2, 2, 2);
|
||||
return true;
|
||||
}
|
||||
|
@ -454,9 +487,18 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
}).orElse(false);
|
||||
}
|
||||
|
||||
private boolean isBisected(Block bl, GreenhousePlant p) {
|
||||
/**
|
||||
* Plants the plant
|
||||
* @param bl - block to turn into a plant
|
||||
* @param p - the greenhouse plant to be grown
|
||||
* @return true if successful, false if not
|
||||
*/
|
||||
private boolean plantIt(Block bl, GreenhousePlant p) {
|
||||
boolean underwater = bl.getType().equals(Material.WATER);
|
||||
BlockData dataBottom = p.plantMaterial().createBlockData();
|
||||
// Check if this is a double-height plant
|
||||
if (dataBottom instanceof Bisected bi) {
|
||||
// Double-height plant
|
||||
bi.setHalf(Bisected.Half.BOTTOM);
|
||||
BlockData dataTop = p.plantMaterial().createBlockData();
|
||||
((Bisected) dataTop).setHalf(Bisected.Half.TOP);
|
||||
|
@ -466,18 +508,121 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
} else {
|
||||
return false; // No room
|
||||
}
|
||||
} else if (p.plantMaterial().equals(Material.GLOW_LICHEN)) {
|
||||
return placeLichen(bl);
|
||||
} else if (p.plantMaterial().equals(Material.COCOA)) {
|
||||
return placeCocoa(bl);
|
||||
} else {
|
||||
bl.setBlockData(dataBottom, false);
|
||||
if (dataBottom instanceof Waterlogged wl) {
|
||||
wl.setWaterlogged(underwater);
|
||||
bl.setBlockData(wl, false);
|
||||
} else {
|
||||
// Single height plant
|
||||
bl.setBlockData(dataBottom, false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canGrowOn(GrowthBlock block, GreenhousePlant p) {
|
||||
// Ceiling plants can only grow on ceiling blocks
|
||||
if (CEILING_PLANTS.contains(p.plantMaterial()) && block.floor()) {
|
||||
private boolean placeCocoa(Block bl) {
|
||||
// Get the source block below this one
|
||||
Block b = bl.getRelative(BlockFace.DOWN);
|
||||
if (!b.getType().equals(Material.JUNGLE_LOG)) {
|
||||
return false;
|
||||
}
|
||||
return p.plantGrownOn().equals(block.block().getRelative(block.floor() ? BlockFace.DOWN : BlockFace.UP).getType());
|
||||
// Find a spot for cocoa
|
||||
BlockFace d = null;
|
||||
for (BlockFace adj : SIDE_BLOCKS) {
|
||||
if (b.getRelative(adj).getType().equals(Material.AIR)) {
|
||||
d = adj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == null) {
|
||||
return false;
|
||||
}
|
||||
Block bb = b.getRelative(d);
|
||||
bb.setType(Material.COCOA);
|
||||
BlockFace opp = d.getOppositeFace();
|
||||
|
||||
if(bb.getBlockData() instanceof Cocoa v){
|
||||
v.setFacing(opp);
|
||||
bb.setBlockData(v);
|
||||
bb.getState().setBlockData(v);
|
||||
bb.getState().update(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the placing of Glow Lichen. This needs to stick to a block rather than grow on it.
|
||||
* If the block is set to Glow Lichen then it appears as an air block with 6 sides of lichen so
|
||||
* they need to be switched off and only the side next to the block should be set.
|
||||
* @param bl - block where plants would usually be placed
|
||||
* @return true if successful, false if not
|
||||
*/
|
||||
private boolean placeLichen(Block bl) {
|
||||
// Get the source block below this one
|
||||
Block b = bl.getRelative(BlockFace.DOWN);
|
||||
|
||||
// Find a spot for licen
|
||||
BlockFace d = null;
|
||||
boolean waterLogged = false;
|
||||
for (BlockFace adj : ADJ_BLOCKS) {
|
||||
Material type = b.getRelative(adj).getType();
|
||||
if (type.equals(Material.AIR) || type.equals(Material.WATER)) {
|
||||
d = adj;
|
||||
if (type.equals(Material.WATER)) {
|
||||
waterLogged = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == null) {
|
||||
return false;
|
||||
}
|
||||
Block bb = b.getRelative(d);
|
||||
bb.setType(Material.GLOW_LICHEN);
|
||||
BlockFace opp = d.getOppositeFace();
|
||||
|
||||
if(bb.getBlockData() instanceof GlowLichen v){
|
||||
for (BlockFace f : v.getAllowedFaces()) {
|
||||
v.setFace(f, false);
|
||||
}
|
||||
v.setFace(opp, true);
|
||||
v.setWaterlogged(waterLogged);
|
||||
bb.setBlockData(v);
|
||||
bb.getState().setBlockData(v);
|
||||
bb.getState().update(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a particular plant can group at the location of a block
|
||||
* @param block - block being checked
|
||||
* @param p - greenhouse plant
|
||||
* @return true if it can be grown otherwise false
|
||||
*/
|
||||
private boolean canGrowOn(GrowthBlock block, GreenhousePlant p) {
|
||||
// Ceiling plants can only grow on ceiling blocks
|
||||
if (CEILING_PLANTS.contains(p.plantMaterial()) && Boolean.TRUE.equals(block.floor())) {
|
||||
return false;
|
||||
}
|
||||
// Underwater plants can only be placed in water and regular plants cannot be placed in water
|
||||
if (block.block().getType().equals(Material.WATER)) {
|
||||
if (!UNDERWATER_PLANTS.contains(p.plantMaterial())) {
|
||||
return false;
|
||||
}
|
||||
} else if (UNDERWATER_PLANTS.contains(p.plantMaterial())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return p.plantGrownOn().equals(block.block().getRelative(Boolean.TRUE.equals(block.floor()) ?
|
||||
BlockFace.DOWN :
|
||||
BlockFace.UP).getType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -584,5 +729,20 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||
return mobTree.values().stream().map(GreenhouseMob::mobType).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of mobs in a greenhouse
|
||||
* @param maxMob maximum
|
||||
*/
|
||||
public void setMaxMob(int maxMob) {
|
||||
this.maxMob = maxMob;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maxMob
|
||||
*/
|
||||
public int getMaxMob() {
|
||||
return maxMob;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -23,33 +23,17 @@ import world.bentobox.greenhouses.world.AsyncWorldCache;
|
|||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Roof extends MinMaxXZ {
|
||||
private static final List<Material> 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<Material> 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<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
|
||||
for (int y = startY; y < world.getMaxHeight() && !roofFound; y++) {
|
||||
if (roofBlocks(cache.getBlockType(x,y,z))) {
|
||||
|
|
|
@ -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<Material> 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<Material> 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 {
|
||||
|
@ -69,7 +61,7 @@ public class Walls extends MinMaxXZ {
|
|||
// The player is under the roof
|
||||
// Assume the player is inside the greenhouse they are trying to create
|
||||
final Location loc = roof.getLocation();
|
||||
floor = getFloorY(roof.getHeight(), roof.getMinX(), roof.getMaxX(), roof.getMinZ(), roof.getMaxZ());
|
||||
floor = getFloorY(roof.getHeight(), roof.getMinX(), roof.getMaxX(), roof.getMinZ(), roof.getMaxZ(), loc.getWorld().getMinHeight());
|
||||
// Now start with the player's x and z location
|
||||
WallFinder wf = new WallFinder();
|
||||
minX = loc.getBlockX();
|
||||
|
@ -85,7 +77,7 @@ public class Walls extends MinMaxXZ {
|
|||
minZ--;
|
||||
maxZ++;
|
||||
// Find the floor again, only looking within the walls
|
||||
floor = getFloorY(roof.getHeight(), minX, maxX, minZ,maxZ);
|
||||
floor = getFloorY(roof.getHeight(), minX, maxX, minZ,maxZ,loc.getWorld().getMinHeight());
|
||||
// Complete on main thread
|
||||
Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> r.complete(this));
|
||||
return this;
|
||||
|
@ -159,7 +151,7 @@ public class Walls extends MinMaxXZ {
|
|||
}
|
||||
}
|
||||
|
||||
int getFloorY(int y, int minX, int maxX, int minZ, int maxZ) {
|
||||
int getFloorY(int y, int minX, int maxX, int minZ, int maxZ, int minY) {
|
||||
// Find the floor - defined as the last y under the roof where there are no wall blocks
|
||||
int wallBlockCount;
|
||||
do {
|
||||
|
@ -172,22 +164,11 @@ public class Walls extends MinMaxXZ {
|
|||
}
|
||||
}
|
||||
|
||||
} while( y-- > 0 && wallBlockCount > 0);
|
||||
} while( y-- > minY && wallBlockCount > 0);
|
||||
return y + 1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.bukkit.event.Listener;
|
|||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
|
@ -52,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);
|
||||
}
|
||||
|
||||
|
@ -78,6 +79,23 @@ public class GreenhouseGuard implements Listener {
|
|||
.anyMatch(this::inGreenhouse));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Guard Greenhouse from natural entity spawning.
|
||||
*
|
||||
* @param spawnEvent the spawn event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onCreatureSpawn(CreatureSpawnEvent spawnEvent)
|
||||
{
|
||||
if (CreatureSpawnEvent.SpawnReason.NATURAL == spawnEvent.getSpawnReason())
|
||||
{
|
||||
// Natural spawn events should be cancelled. Greenhouse spawns its own mobs.
|
||||
spawnEvent.setCancelled(this.inGreenhouse(spawnEvent.getLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean inGreenhouse(Location l) {
|
||||
return addon.getManager().getMap().getGreenhouse(l).map(g -> g.isRoofOrWallBlock(l)).orElse(false);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
|
@ -21,9 +22,9 @@ import org.bukkit.event.block.BlockFormEvent;
|
|||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
|
@ -58,9 +59,10 @@ public class SnowTracker implements Listener {
|
|||
}
|
||||
boolean createdSnow = false;
|
||||
List<Block> waterBlocks = new ArrayList<>();
|
||||
for (int x = (int)gh.getBoundingBox().getMinX() + 1; x < (int)gh.getBoundingBox().getMaxX() -1; x++) {
|
||||
for (int z = (int)gh.getBoundingBox().getMinZ() + 1; z < (int)gh.getBoundingBox().getMaxZ() - 1; z++) {
|
||||
for (int y = (int)gh.getBoundingBox().getMaxY() - 2; y >= (int)gh.getBoundingBox().getMinY(); y--) {
|
||||
final BoundingBox bb = gh.getBoundingBox();
|
||||
for (int x = (int)bb.getMinX() + 1; x < (int)bb.getMaxX() -1; x++) {
|
||||
for (int z = (int)bb.getMinZ() + 1; z < (int)bb.getMaxZ() - 1; z++) {
|
||||
for (int y = (int)bb.getMaxY() - 2; y >= (int)bb.getMinY(); y--) {
|
||||
Block b = Objects.requireNonNull(gh.getLocation().getWorld()).getBlockAt(x, y, z);
|
||||
Material type = b.getType();
|
||||
if (type.equals(Material.AIR) || type.equals(Material.SNOW)) {
|
||||
|
@ -98,7 +100,7 @@ public class SnowTracker implements Listener {
|
|||
}
|
||||
|
||||
private boolean placeSnow(Block b) {
|
||||
Optional<Material> snowCauldron = Enums.getIfPresent(Material.class, "POWDER_SNOW_CAULDRON");
|
||||
Optional<Material> snowCauldron = Enums.getIfPresent(Material.class, "POWDER_SNOW_CAULDRON").toJavaUtil();
|
||||
if (snowCauldron.isPresent()) {
|
||||
if (b.getType().equals(Material.CAULDRON)) {
|
||||
b.setType(snowCauldron.get());
|
||||
|
|
|
@ -9,12 +9,14 @@ import java.util.Objects;
|
|||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
|
@ -85,23 +87,25 @@ public class EcoSystemManager {
|
|||
}
|
||||
|
||||
private void convertBlocks(Greenhouse gh) {
|
||||
World world = gh.getWorld();
|
||||
final World world = gh.getWorld();
|
||||
final BoundingBox bb = gh.getBoundingBox();
|
||||
if(world == null || gh.getLocation() == null || gh.getLocation().getWorld() == null
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMaxX()) >> 4, ((int) gh.getBoundingBox().getMaxZ()) >> 4)
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMinX()) >> 4, ((int) gh.getBoundingBox().getMinZ()) >> 4)){
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) bb.getMaxX()) >> 4, ((int) bb.getMaxZ()) >> 4)
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) bb.getMinX()) >> 4, ((int) bb.getMinZ()) >> 4)){
|
||||
return;
|
||||
}
|
||||
int gh_min_x = NumberConversions.floor(gh.getInternalBoundingBox().getMinX());
|
||||
int gh_max_x = NumberConversions.floor(gh.getInternalBoundingBox().getMaxX());
|
||||
int gh_min_y = NumberConversions.floor(gh.getBoundingBox().getMinY()); // Note: this gets the floor
|
||||
int gh_max_y = NumberConversions.floor(gh.getInternalBoundingBox().getMaxY());
|
||||
int gh_min_z = NumberConversions.floor(gh.getInternalBoundingBox().getMinZ());
|
||||
int gh_max_z = NumberConversions.floor(gh.getInternalBoundingBox().getMaxZ());
|
||||
final BoundingBox ibb = gh.getInternalBoundingBox();
|
||||
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()) {
|
||||
|
@ -128,22 +132,29 @@ public class EcoSystemManager {
|
|||
|
||||
}
|
||||
|
||||
private void addMobs(Greenhouse gh) {
|
||||
/**
|
||||
* Try to spawn mobs in a greenhouse
|
||||
* @param gh greenhouse
|
||||
* @return true if mobs were spawned, false if not
|
||||
*/
|
||||
boolean addMobs(Greenhouse gh) {
|
||||
final BoundingBox bb = gh.getBoundingBox();
|
||||
if(gh.getLocation() == null || gh.getLocation().getWorld() == null || gh.getWorld() == null
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMaxX()) >> 4, ((int) gh.getBoundingBox().getMaxZ()) >> 4) || !gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMinX()) >> 4, ((int) gh.getBoundingBox().getMinZ()) >> 4)){
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) bb.getMaxX()) >> 4, ((int) bb.getMaxZ()) >> 4)
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) bb.getMinX()) >> 4, ((int) bb.getMinZ()) >> 4)){
|
||||
// Skipping addmobs for unloaded greenhouse
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (gh.getBiomeRecipe().noMobs()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// Check greenhouse chunks are loaded
|
||||
for (double blockX = gh.getBoundingBox().getMinX(); blockX < gh.getBoundingBox().getMaxX(); blockX+=16) {
|
||||
for (double blockZ = gh.getBoundingBox().getMinZ(); blockZ < gh.getBoundingBox().getMaxZ(); blockZ+=16) {
|
||||
for (double blockX = bb.getMinX(); blockX < bb.getMaxX(); blockX+=16) {
|
||||
for (double blockZ = bb.getMinZ(); blockZ < bb.getMaxZ(); blockZ+=16) {
|
||||
int chunkX = (int)(blockX / 16);
|
||||
int chunkZ = (int)(blockZ / 16);
|
||||
if (!gh.getWorld().isChunkLoaded(chunkX, chunkZ)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +167,9 @@ public class EcoSystemManager {
|
|||
Collections.shuffle(list, new Random(System.currentTimeMillis()));
|
||||
Iterator<GrowthBlock> it = list.iterator();
|
||||
// Check if the greenhouse is full
|
||||
if (gh.getBiomeRecipe().getMaxMob() > -1 && sum >= gh.getBiomeRecipe().getMaxMob()) {
|
||||
return false;
|
||||
}
|
||||
while (it.hasNext() && (sum == 0 || gh.getArea() / sum >= gh.getBiomeRecipe().getMobLimit())) {
|
||||
// Spawn something if chance says so
|
||||
if (gh.getBiomeRecipe().spawnMob(it.next().block())) {
|
||||
|
@ -163,6 +177,7 @@ public class EcoSystemManager {
|
|||
sum++;
|
||||
}
|
||||
}
|
||||
return sum > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,17 +185,22 @@ public class EcoSystemManager {
|
|||
* @param gh - greenhouse
|
||||
*/
|
||||
private void growPlants(Greenhouse gh) {
|
||||
final BoundingBox bb = gh.getBoundingBox();
|
||||
if (gh.getLocation() == null || gh.getLocation().getWorld() == null
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMaxX()) >> 4, ((int) gh.getBoundingBox().getMaxZ()) >> 4) || !gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMinX()) >> 4, ((int) gh.getBoundingBox().getMinZ()) >> 4)){
|
||||
|| !gh.getLocation().getWorld().isChunkLoaded(((int) bb.getMaxX()) >> 4, ((int) bb.getMaxZ()) >> 4) || !gh.getLocation().getWorld().isChunkLoaded(((int) bb.getMinX()) >> 4, ((int) bb.getMinZ()) >> 4)){
|
||||
//Skipping growplants for unloaded greenhouse
|
||||
return;
|
||||
}
|
||||
int bonemeal = getBoneMeal(gh);
|
||||
if (bonemeal > 0) {
|
||||
// Get a list of all available blocks
|
||||
List<GrowthBlock> list = getAvailableBlocks(gh, true);
|
||||
List<GrowthBlock> list = getAvailableBlocks(gh, false);
|
||||
Collections.shuffle(list);
|
||||
int plantsGrown = list.stream().limit(bonemeal).mapToInt(bl -> gh.getBiomeRecipe().growPlant(bl) ? 1 : 0).sum();
|
||||
int plantsGrown = list.stream().limit(bonemeal).mapToInt(bl -> gh.getBiomeRecipe().growPlant(bl, false) ? 1 : 0).sum();
|
||||
// Underwater plants
|
||||
list = getAvailableBlocks(gh, true);
|
||||
Collections.shuffle(list);
|
||||
plantsGrown += list.stream().limit(bonemeal).mapToInt(bl -> gh.getBiomeRecipe().growPlant(bl, true) ? 1 : 0).sum();
|
||||
if (plantsGrown > 0) {
|
||||
setBoneMeal(gh, bonemeal - (int)Math.ceil((double)plantsGrown / PLANTS_PER_BONEMEAL ));
|
||||
}
|
||||
|
@ -203,32 +223,25 @@ public class EcoSystemManager {
|
|||
|
||||
}
|
||||
|
||||
public record GrowthBlock(Block block, Boolean floor) {}
|
||||
|
||||
/**
|
||||
* Get a list of the lowest level blocks inside the greenhouse. May be air, liquid or plants.
|
||||
* These blocks sit just above solid blocks
|
||||
* These blocks sit just above solid blocks. Leaves are ignored too.
|
||||
* @param gh - greenhouse
|
||||
* @param ignoreLiquid - true if liquid blocks should be treated like air blocks
|
||||
* @return List of blocks
|
||||
*/
|
||||
protected List<GrowthBlock> getAvailableBlocks(Greenhouse gh, boolean ignoreLiquid) {
|
||||
final BoundingBox bb = gh.getBoundingBox();
|
||||
final BoundingBox ibb = gh.getInternalBoundingBox();
|
||||
List<GrowthBlock> result = new ArrayList<>();
|
||||
if (gh.getWorld() == null) return result;
|
||||
for (double x = gh.getInternalBoundingBox().getMinX(); x < gh.getInternalBoundingBox().getMaxX(); x++) {
|
||||
for (double z = gh.getInternalBoundingBox().getMinZ(); z < gh.getInternalBoundingBox().getMaxZ(); z++) {
|
||||
for (double y = gh.getInternalBoundingBox().getMaxY() - 1; y >= gh.getBoundingBox().getMinY(); y--) {
|
||||
for (double x = ibb.getMinX(); x < ibb.getMaxX(); x++) {
|
||||
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 ceiling blocks
|
||||
if (b.isEmpty() && !b.getRelative(BlockFace.UP).isEmpty()) {
|
||||
result.add(new GrowthBlock(b, false));
|
||||
}
|
||||
|
||||
// Check floor blocks
|
||||
if (!(b.isEmpty() || (ignoreLiquid && b.isLiquid()))
|
||||
&& (b.getRelative(BlockFace.UP).isEmpty()
|
||||
|| (b.getRelative(BlockFace.UP).isPassable() && !b.isLiquid())
|
||||
|| (ignoreLiquid && b.isLiquid() && b.getRelative(BlockFace.UP).isPassable()))) {
|
||||
result.add(new GrowthBlock(b.getRelative(BlockFace.UP), true));
|
||||
if (checkBlock(result, b, ignoreLiquid)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +250,30 @@ public class EcoSystemManager {
|
|||
return result;
|
||||
}
|
||||
|
||||
public record GrowthBlock(Block block, Boolean floor) {}
|
||||
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) {
|
||||
Hopper hopper = getHopper(gh);
|
||||
|
|
|
@ -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<Set<GreenhouseResult>> checkGreenhouse(AsyncWorldCache cache, Roof roof, Walls walls) {
|
||||
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;
|
||||
}
|
||||
|
||||
private Set<GreenhouseResult> checkGHAsync(CompletableFuture<Set<GreenhouseResult>> r, AsyncWorldCache cache,
|
||||
private Set<GreenhouseResult> checkGreenhouseAsync(CompletableFuture<Set<GreenhouseResult>> 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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.bukkit.Location;
|
|||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
|
||||
import world.bentobox.bentobox.database.Database;
|
||||
|
@ -95,29 +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);
|
||||
break;
|
||||
case FAIL_OVERLAPPING:
|
||||
addon.logError("Greenhouse overlaps with another greenhouse. Skipping...");
|
||||
break;
|
||||
case NULL:
|
||||
addon.logError("Null location of greenhouse. Cannot load. Skipping...");
|
||||
break;
|
||||
case SUCCESS:
|
||||
activateGreenhouse(g);
|
||||
break;
|
||||
case FAIL_NO_WORLD:
|
||||
addon.logError("Database contains greenhouse for a non-loaded world. Skipping...");
|
||||
break;
|
||||
case FAIL_UNKNOWN_RECIPE:
|
||||
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());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
});
|
||||
addon.log("Loaded " + map.getSize() + " greenhouses.");
|
||||
|
@ -125,35 +116,28 @@ public class GreenhouseManager implements Listener {
|
|||
toBeRemoved.forEach(handler::deleteObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all the greenhouses to database
|
||||
*/
|
||||
public void saveGreenhouses() {
|
||||
addon.log("Saving greenhouses...");
|
||||
map.getGreenhouses().forEach(handler::saveObjectAsync);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the greenhouse from the world and resets biomes
|
||||
* @param g - greenhouse
|
||||
* @param gh - greenhouse
|
||||
*/
|
||||
public void removeGreenhouse(Greenhouse g) {
|
||||
handler.deleteObject(g);
|
||||
map.removeGreenhouse(g);
|
||||
if (g.getOriginalBiome() == null) {
|
||||
addon.logError("Greenhouse had no original biome: " + g.getLocation());
|
||||
public void removeGreenhouse(Greenhouse gh) {
|
||||
handler.deleteObject(gh);
|
||||
map.removeGreenhouse(gh);
|
||||
if (gh.getOriginalBiome() == null) {
|
||||
addon.logError("Greenhouse had no original biome: " + gh.getLocation());
|
||||
return;
|
||||
}
|
||||
if (g.getLocation() == null || g.getLocation().getWorld() == null) {
|
||||
if (gh.getLocation() == null || gh.getLocation().getWorld() == null) {
|
||||
// Greenhouse is messed up. It's being deleted anyway.
|
||||
return;
|
||||
}
|
||||
addon.log("Returning biome to original state: " + g.getOriginalBiome().toString());
|
||||
for (int x = (int)g.getBoundingBox().getMinX(); x<= (int)g.getBoundingBox().getMaxX(); x+=4) {
|
||||
for (int z = (int)g.getBoundingBox().getMinZ(); z<= (int)g.getBoundingBox().getMaxZ(); z+=4) {
|
||||
for (int y = (int)g.getBoundingBox().getMinY(); y<= (int)g.getBoundingBox().getMaxY(); y+=4) {
|
||||
addon.log("Returning biome to original state: " + gh.getOriginalBiome().toString());
|
||||
final BoundingBox bb = gh.getBoundingBox();
|
||||
for (int x = (int)bb.getMinX(); x<= (int)bb.getMaxX(); x+=4) {
|
||||
for (int z = (int)bb.getMinZ(); z<= (int)bb.getMaxZ(); z+=4) {
|
||||
for (int y = (int)bb.getMinY(); y<= (int)bb.getMaxY(); y+=4) {
|
||||
// Set back to the original biome
|
||||
g.getLocation().getWorld().setBiome(x, y, z, g.getOriginalBiome());
|
||||
gh.getLocation().getWorld().setBiome(x, y, z, gh.getOriginalBiome());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +153,7 @@ public class GreenhouseManager implements Listener {
|
|||
*/
|
||||
public CompletableFuture<GhResult> tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) {
|
||||
CompletableFuture<GhResult> r = new CompletableFuture<>();
|
||||
GreenhouseFinder finder = new GreenhouseFinder();
|
||||
GreenhouseFinder finder = new GreenhouseFinder(addon);
|
||||
finder.find(location).thenAccept(resultSet -> {
|
||||
if (!resultSet.isEmpty()) {
|
||||
// Failure!
|
||||
|
@ -250,9 +234,10 @@ public class GreenhouseManager implements Listener {
|
|||
addon.logError("Biome recipe error - no such biome for " + gh.getBiomeRecipe().getName());
|
||||
return;
|
||||
}
|
||||
for (int x = (int)gh.getBoundingBox().getMinX(); x < gh.getBoundingBox().getMaxX(); x+=4) {
|
||||
for (int z = (int)gh.getBoundingBox().getMinZ(); z < gh.getBoundingBox().getMaxZ(); z+=4) {
|
||||
for (int y = (int)gh.getBoundingBox().getMinY(); y < gh.getBoundingBox().getMaxY(); y+=4) {
|
||||
final BoundingBox bb = gh.getBoundingBox();
|
||||
for (int x = (int)bb.getMinX(); x < bb.getMaxX(); x+=4) {
|
||||
for (int z = (int)bb.getMinZ(); z < bb.getMaxZ(); z+=4) {
|
||||
for (int y = (int)bb.getMinY(); y < bb.getMaxY(); y+=4) {
|
||||
Objects.requireNonNull(gh.getWorld()).setBiome(x, y, z, ghBiome);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -107,7 +106,9 @@ public class GreenhouseMap {
|
|||
private boolean isOverlapping(Greenhouse greenhouse) {
|
||||
return greenhouse.getLocation() != null && addon.getIslands().getIslandAt(greenhouse.getLocation()).map(i -> {
|
||||
greenhouses.putIfAbsent(i, new ArrayList<>());
|
||||
return greenhouses.get(i).stream().anyMatch(g -> g.getBoundingBox().overlaps(greenhouse.getBoundingBox()));
|
||||
return greenhouses.get(i).stream().anyMatch(g ->
|
||||
g.getLocation().getWorld().equals(greenhouse.getLocation().getWorld()) &&
|
||||
g.getBoundingBox().overlaps(greenhouse.getBoundingBox()));
|
||||
}).orElse(false);
|
||||
|
||||
}
|
||||
|
@ -136,7 +137,7 @@ public class GreenhouseMap {
|
|||
* @return a list of all the Greenhouses
|
||||
*/
|
||||
public List<Greenhouse> getGreenhouses() {
|
||||
return greenhouses.values().stream().flatMap(List::stream).collect(Collectors.toList());
|
||||
return greenhouses.values().stream().flatMap(List::stream).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
package world.bentobox.greenhouses.managers;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
@ -24,6 +30,7 @@ public class RecipeManager {
|
|||
private static final int MAXIMUM_INVENTORY_SIZE = 49;
|
||||
private final Greenhouses addon;
|
||||
private static final List<BiomeRecipe> biomeRecipes = new ArrayList<>();
|
||||
private static final String COULD_NOT_PARSE = "Could not parse ";
|
||||
|
||||
public RecipeManager(Greenhouses addon) {
|
||||
this.addon = addon;
|
||||
|
@ -149,6 +156,7 @@ public class RecipeManager {
|
|||
b.setLavacoverage(biomeRecipeConfig.getInt("lavacoverage",-1));
|
||||
b.setIcecoverage(biomeRecipeConfig.getInt("icecoverage",-1));
|
||||
b.setMobLimit(biomeRecipeConfig.getInt("moblimit", 9));
|
||||
b.setMaxMob(biomeRecipeConfig.getInt("maxmobs", -1));
|
||||
return b;
|
||||
}
|
||||
|
||||
|
@ -172,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
|
||||
|
@ -228,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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,6 @@ public class PanelClick implements ClickHandler {
|
|||
}
|
||||
|
||||
private boolean makeGreenhouse(User user, BiomeRecipe br) {
|
||||
if (user.getLocation() == null) {
|
||||
addon.logError("User has no location : " + user.getName());
|
||||
return false;
|
||||
}
|
||||
// Check flag
|
||||
if (!addon.getIslands().getIslandAt(user.getLocation()).map(i -> i.isAllowed(user, Greenhouses.GREENHOUSES)).orElse(false)) {
|
||||
user.sendMessage("greenhouses.errors.no-rank");
|
||||
|
|
|
@ -92,10 +92,6 @@ class MakeCommand extends CompositeCommand {
|
|||
* @return true if successful
|
||||
*/
|
||||
private boolean makeGreenhouse(User user, BiomeRecipe br) {
|
||||
if (user.getLocation() == null) {
|
||||
getAddon().logError("User had no location");
|
||||
return false;
|
||||
}
|
||||
// Check flag
|
||||
if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.isAllowed(user, Greenhouses.GREENHOUSES)).orElse(false)) {
|
||||
user.sendMessage("greenhouses.errors.no-rank");
|
||||
|
|
|
@ -35,10 +35,6 @@ class RemoveCommand extends CompositeCommand {
|
|||
*/
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
if (user.getLocation() == null) {
|
||||
getAddon().logError("User had no location");
|
||||
return false;
|
||||
}
|
||||
// Check flag
|
||||
if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.isAllowed(user, Greenhouses.GREENHOUSES)).orElse(false)) {
|
||||
user.sendMessage("greenhouses.errors.no-rank");
|
||||
|
|
|
@ -30,8 +30,7 @@ public class UserCommand extends CompositeCommand {
|
|||
public void setup() {
|
||||
this.setPermission("greenhouses.player");
|
||||
this.setOnlyPlayer(true);
|
||||
this.setParametersHelp("greenhouses.command.parameters");
|
||||
this.setDescription("greenhouses.command.description");
|
||||
this.setDescription("greenhouses.commands.user.description");
|
||||
|
||||
//new InfoCommand(this);
|
||||
//new ListCommand(this);
|
||||
|
|
|
@ -27,14 +27,16 @@ public class AsyncWorldCache {
|
|||
|
||||
private final World world;
|
||||
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
|
||||
* @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<ChunkSnapshot> getAChunk(int x, int z) {
|
||||
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())));
|
||||
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;
|
||||
|
|
|
@ -35,11 +35,17 @@ biomes:
|
|||
# Entity name: % chance:Block on which the mob will spawn
|
||||
mobs:
|
||||
SQUID: 10:WATER
|
||||
GLOW_SQUID: 5:WATER
|
||||
TURTLE: 10:SAND
|
||||
# The minimum number of blocks each mob requires.
|
||||
# Mobs will not spawn if there is more than 1 per this number of
|
||||
# blocks in the greenhouse. e.g., in this case only 2 mobs will spawn if the
|
||||
# greenhouse area is 18 blocks
|
||||
# greenhouse area is 18 blocks. This enables bigger greenhouses to spawn more.
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 5
|
||||
Snowy_beach:
|
||||
friendlyname: "Snowy beach"
|
||||
biome: SNOWY_BEACH
|
||||
|
@ -49,6 +55,9 @@ biomes:
|
|||
SAND: 1
|
||||
watercoverage: 50
|
||||
icecoverage: 10
|
||||
mobs:
|
||||
SQUID: 10:WATER
|
||||
GLOW_SQUID: 10:WATER
|
||||
ThreeWolfMoon:
|
||||
friendlyname: "Three Wolf Moon Forest"
|
||||
# Could do with more wolves, but the magic works with 3.
|
||||
|
@ -63,11 +72,17 @@ biomes:
|
|||
plants:
|
||||
TALL_GRASS: 10:GRASS_BLOCK
|
||||
mobs:
|
||||
WOLF: 10:SNOW
|
||||
WOLF: 15:SNOW
|
||||
FOX: 15:GRASS_BLOCK
|
||||
RABBIT: 7:GRASS_BLOCK
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 5
|
||||
Cold_Rabbit:
|
||||
friendlyname: "Cold Taiga Forest"
|
||||
biome: TAIGA_HILLS
|
||||
biome: OLD_GROWTH_SPRUCE_TAIGA
|
||||
icon: SPRUCE_SAPLING
|
||||
priority: 20
|
||||
contents:
|
||||
|
@ -79,7 +94,12 @@ biomes:
|
|||
TALL_GRASS: 10:GRASS_BLOCK
|
||||
mobs:
|
||||
RABBIT: 10:SNOW
|
||||
FOX: 7:GRASS_BLOCK
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 20
|
||||
DESERT:
|
||||
friendlyname: "Desert"
|
||||
biome: DESERT
|
||||
|
@ -103,6 +123,14 @@ biomes:
|
|||
- DIRT:30:SAND:SAND
|
||||
- GRASS_BLOCK:30:SAND:SAND
|
||||
- COARSE_DIRT:30:GRAVEL:SAND
|
||||
mobs:
|
||||
RABBIT: 10:SAND
|
||||
HUSK: 10:SAND
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 20
|
||||
FOREST:
|
||||
friendlyname: "Flowery forest"
|
||||
biome: FLOWER_FOREST
|
||||
|
@ -117,6 +145,17 @@ biomes:
|
|||
ORANGE_TULIP: 2:GRASS_BLOCK
|
||||
SUNFLOWER: 4:GRASS_BLOCK
|
||||
TALL_GRASS: 20:GRASS_BLOCK
|
||||
mobs:
|
||||
SHEEP: 10:GRASS_BLOCK
|
||||
CHICKEN: 7:GRASS_BLOCK
|
||||
PIG: 10:GRASS_BLOCK
|
||||
COW: 10:GRASS_BLOCK
|
||||
WOLF: 5:GRASS_BLOCK
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 20
|
||||
NETHER:
|
||||
friendlyname: "&cNether"
|
||||
biome: NETHER_WASTES
|
||||
|
@ -134,6 +173,10 @@ biomes:
|
|||
STRIDER: 10:LAVA
|
||||
ENDERMAN: 5:NETHERRACK
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 50
|
||||
permission: greenhouses.biome.nether
|
||||
SOUL_SAND_VALLEY:
|
||||
friendlyname: "&cSoul Sand Valley"
|
||||
|
@ -148,7 +191,14 @@ biomes:
|
|||
watercoverage: 0
|
||||
mobs:
|
||||
SKELETON: 10:SOUL_SAND
|
||||
GHAST: 10:SOUL_SAND
|
||||
ENDERMAN: 1:SOUL_SAND
|
||||
STRIDER: 20:LAVA
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 50
|
||||
permission: greenhouses.biome.nether
|
||||
# Conversion list - in this case, an adjacent block is required to convert
|
||||
# Format is:
|
||||
|
@ -173,6 +223,10 @@ biomes:
|
|||
PIGLIN: 10:CRIMSON_NYLIUM
|
||||
HOGLIN: 10:CRIMSON_NYLIUM
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 50
|
||||
permission: greenhouses.biome.nether
|
||||
WARPED_FOREST:
|
||||
friendlyname: "&cWarped Forest"
|
||||
|
@ -190,6 +244,10 @@ biomes:
|
|||
STRIDER: 10:LAVA
|
||||
ENDERMAN: 20:WARPED_NYLIUM
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 50
|
||||
permission: greenhouses.biome.nether
|
||||
JUNGLE:
|
||||
biome: JUNGLE
|
||||
|
@ -205,6 +263,11 @@ biomes:
|
|||
ROSE_BUSH: 20:GRASS_BLOCK
|
||||
FERN: 20:GRASS_BLOCK
|
||||
TALL_GRASS: 20:GRASS_BLOCK
|
||||
COCOA: 10:JUNGLE_LOG
|
||||
mobs:
|
||||
PARROT: 30:GRASS_BLOCK
|
||||
CHICKEN: 20:GRASS_BLOCK
|
||||
PANDA: 1:GRASS_BLOCK
|
||||
MUSHROOM_FIELDS:
|
||||
friendlyname: "Mushroom Fields"
|
||||
biome: MUSHROOM_FIELDS
|
||||
|
@ -220,6 +283,10 @@ biomes:
|
|||
mobs:
|
||||
MUSHROOM_COW: 10:MYCELIUM
|
||||
moblimit: 9
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 20
|
||||
OCEAN:
|
||||
biome: OCEAN
|
||||
icon: WATER_BUCKET
|
||||
|
@ -228,7 +295,13 @@ biomes:
|
|||
watercoverage: 95
|
||||
mobs:
|
||||
SQUID: 10:WATER
|
||||
DROWNED: 1:WATER
|
||||
COD: 40:WATER
|
||||
DOLPHIN: 20:WATER
|
||||
SQUID: 20:WATER
|
||||
GLOW_SQUID: 10:WATER
|
||||
moblimit: 9
|
||||
maxmobs: 20
|
||||
PLAINS:
|
||||
friendlyname: "Horse Plains"
|
||||
biome: PLAINS
|
||||
|
@ -239,8 +312,17 @@ biomes:
|
|||
plants:
|
||||
TALL_GRASS: 10:GRASS_BLOCK
|
||||
mobs:
|
||||
HORSE: 10:GRASS_BLOCK
|
||||
HORSE: 18:GRASS_BLOCK
|
||||
DONKEY: 2:GRASS_BLOCK
|
||||
COW: 20:GRASS_BLOCK
|
||||
CHICKEN: 25:GRASS_BLOCK
|
||||
PIG: 25:GRASS_BLOCK
|
||||
SHEEP: 25:GRASS_BLOCK
|
||||
moblimit: 1
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 10
|
||||
RIVER:
|
||||
friendlyname: "Clay river"
|
||||
biome: RIVER
|
||||
|
@ -256,6 +338,15 @@ biomes:
|
|||
# So, for below, dirt has a 50% chance of changing into clay if it is next to water!
|
||||
conversion-list:
|
||||
- DIRT:50:CLAY:WATER
|
||||
mobs:
|
||||
SALMON: 10:WATER
|
||||
SQUID: 10:WATER
|
||||
GLOW_SQUID: 5:WATER
|
||||
moblimit: 1
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 10
|
||||
SAVANNA:
|
||||
biome: SAVANNA
|
||||
icon: ACACIA_LEAVES
|
||||
|
@ -266,6 +357,18 @@ biomes:
|
|||
GRASS_BLOCK: 4
|
||||
plants:
|
||||
TALL_GRASS: 10:GRASS_BLOCK
|
||||
mobs:
|
||||
HORSE: 2:GRASS_BLOCK
|
||||
DONKEY: 2:GRASS_BLOCK
|
||||
COW: 20:GRASS_BLOCK
|
||||
CHICKEN: 25:GRASS_BLOCK
|
||||
PIG: 25:GRASS_BLOCK
|
||||
SHEEP: 25:GRASS_BLOCK
|
||||
moblimit: 1
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 10
|
||||
SWAMP:
|
||||
friendlyname: "&2Slimy Swamp"
|
||||
biome: SWAMP
|
||||
|
@ -280,7 +383,37 @@ biomes:
|
|||
plants:
|
||||
RED_MUSHROOM: 20:GRASS_BLOCK
|
||||
BROWN_MUSHROOM: 20:GRASS_BLOCK
|
||||
BLUE_ORCHID: 10:GRASS_BLOCK
|
||||
LILY_PAD: 5:WATER
|
||||
mobs:
|
||||
SLIME: 5:WATER
|
||||
FROG: 20:WATER
|
||||
moblimit: 3
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 10
|
||||
dripstone_caves:
|
||||
friendlyname: "&6Drippy Drops"
|
||||
biome: dripstone_caves
|
||||
icon: DRIPSTONE_BLOCK
|
||||
priority: 15
|
||||
contents:
|
||||
STONE: 8
|
||||
CLAY: 8
|
||||
# 50% water coverage required
|
||||
watercoverage: 25
|
||||
conversions:
|
||||
CLAY: 50:DRIPSTONE_BLOCK:WATER
|
||||
STONE: 0.005:COPPER_ORE:STONE
|
||||
plants:
|
||||
GLOW_LICHEN: 20:STONE
|
||||
mobs:
|
||||
skeleton: 5:STONE
|
||||
glow_squid: 5:WATER
|
||||
BAT: 10:STONE
|
||||
moblimit: 5
|
||||
# Maxmobs - this is the maximum number of greenhouse-spawed mobs allowed in
|
||||
# the greenhouse at once. Spawning will stop when this limit is reached.
|
||||
# If this value is not given, there is no maximum.
|
||||
maxmobs: 25
|
|
@ -0,0 +1,163 @@
|
|||
---
|
||||
protection:
|
||||
flags:
|
||||
GREENHOUSE:
|
||||
name: Gewächshäuser
|
||||
description: |-
|
||||
&bUmschalten, wer
|
||||
&bdie Gewächshäuser kontrollieren kann
|
||||
greenhouses:
|
||||
general:
|
||||
greenhouses: Gewächshäuser
|
||||
errors:
|
||||
move: Gehe zuerst in ein Gewächshaus, das dir gehört.
|
||||
no-rank: "& cDu hast keinen Rang, um das zu tun."
|
||||
notyours: Das ist nicht dein Gewächshaus!
|
||||
not-inside: "& cDu bist nicht in einem Gewächshaus!"
|
||||
tooexpensive: Du kannst dir das nicht leisten [price]
|
||||
alreadyexists: Gewächshaus existiert bereits!
|
||||
norecipe: Kann kein Gewächshaus bauen!
|
||||
event:
|
||||
broke: Du hast das Gewächshaus kaputt gemacht! Biome auf [biome] umstellen!
|
||||
entering: Betreten des Gewächshauses [biome]
|
||||
leaving: Das Gewächshaus verlassen [biome]
|
||||
recipe:
|
||||
blockscolor: "&f"
|
||||
title: "[[biome] recipe]"
|
||||
watermustbe: Wasser > [coverage]% der Bodenfläche.
|
||||
icemustbe: Eisblöcke > [coverage]% der Bodenfläche.
|
||||
lavamustbe: Lava > [coverage]% der Bodenfläche.
|
||||
minimumblockstitle: "[Minimum blocks required]"
|
||||
nootherblocks: Keine weiteren Blöcke erforderlich.
|
||||
missing: Gewächshaus fehlt
|
||||
commands:
|
||||
user:
|
||||
remove:
|
||||
description: Entfernt ein Gewächshaus, in dem Sie stehen, wenn Sie der Eigentümer
|
||||
sind
|
||||
make:
|
||||
description: Versuche ein Gewächshaus zu bauen
|
||||
parameters: "<recipe>"
|
||||
error:
|
||||
already: "&cEs gibt hier schon ein Gewächshaus!"
|
||||
FAIL_BAD_ROOF_BLOCKS: "&cDach enthält unzulässige Blöcke!"
|
||||
FAIL_BAD_WALL_BLOCKS: "&cWand enthält unzulässige Blöcke!"
|
||||
FAIL_BELOW: "&cDu musst im Gewächshaus sein, um es zu versuchen."
|
||||
FAIL_BLOCKS_ABOVE: "&cEs dürfen keine Blöcke über dem Gewächshaus sein!
|
||||
Rote Glasblöcke sollten die Problemblöcke anzeigen."
|
||||
FAIL_HOLE_IN_ROOF: "&cIn dem Dach ist ein Loch oder es ist nicht flach!
|
||||
Rote Glasblöcke sollten das Problem anzeigen."
|
||||
FAIL_HOLE_IN_WALL: "&cIn der Wand ist ein Loch!"
|
||||
FAIL_NO_ROOF: "&cEs scheint kein Dach zu geben!"
|
||||
FAIL_TOO_MANY_DOORS: "&cEs dürfen nicht mehr als 4 Türen im Gewächshaus
|
||||
sein!"
|
||||
FAIL_TOO_MANY_HOPPERS: "&cIn den Wänden oder im Dach ist nur ein Trichter
|
||||
zulässig."
|
||||
FAIL_UNEVEN_WALLS: "&cDie Wände sind uneben. Rote Glasblöcke sollten die
|
||||
Problemblöcke anzeigen."
|
||||
FAIL_INSUFFICIENT_ICE: "&cZu wenig Eis für dieses Rezept"
|
||||
FAIL_INSUFFICIENT_LAVA: "&cZu wenig Lava für dieses Rezept"
|
||||
FAIL_INSUFFICIENT_WATER: "&cZu wenig Wasser für dieses Rezept"
|
||||
FAIL_NO_ICE: "&cFür dieses Rezept wird Eis benötigt"
|
||||
FAIL_NO_LAVA: "&cFür dieses Rezept wird Lava benötigt"
|
||||
FAIL_NO_WATER: "&cFür dieses Rezept wird Wasser benötigt"
|
||||
FAIL_NO_RECIPE_FOUND: "&c Zu diesem Gewächshaus konnte kein passendes Rezept
|
||||
gefunden werden"
|
||||
FAIL_INSUFFICIENT_BLOCKS: "&cWeitere Blöcke sind erforderlich, um dieses
|
||||
Rezept zu erstellen!"
|
||||
FAIL_OVERLAPPING: "&cGewächshäuser können sich keine Wände teilen, sorry."
|
||||
success: "&2Du hast erfolgreich ein [biome] Biom Gewächshaus gebaut! Beim
|
||||
nächsten Teleport oder Login wird Biom synchronisiert."
|
||||
missing-blocks: "[material] x [number] &cFehlt"
|
||||
unknown-recipe: "&Unbekanntes Rezept"
|
||||
try-these: "&cVersuche einen von diesen:"
|
||||
recipe-format: "&3[name]"
|
||||
info:
|
||||
title: "&A[Wie man ein Gewächshaus baut]"
|
||||
instructions: "&EStelle einen Kasten aus Glas mit 4 Wänden und einem flachen
|
||||
&EGlasdach her und füge bis zu &F4 Türen &Ein den Wänden hinzu. &EPlatziere
|
||||
&F1 Trichter &Ein eine Wand oder ein Dach und füge Wassereimer hinzu. &EUm
|
||||
Schnee und/oder Knochenmehl herzustellen, um Pflanzen automatisch wachsen
|
||||
zu lassen. &EPrüfe die Biom-Rezepte, welche Blöcke in einem Gewächshaus
|
||||
sein müssen, um ein &EGewächshaus erfolgreich zu machen."
|
||||
help:
|
||||
help: Hilfe
|
||||
make: Versucht ein Gewächshaus zu bauen
|
||||
remove: Entfernt ein Gewächshaus, in dem du stehst, wenn du der Besitzer bist
|
||||
info: Wie man ein Gewächshaus baut
|
||||
list: Listet alle Gewächshausbiome auf, die hergestellt werden können
|
||||
recipe: Erklärt dir, wie man das Gewächshaus biome macht
|
||||
opengui: Öffnet die Gewächshaus-GUI
|
||||
list:
|
||||
title: "[Gewächshaus-Biom-Rezepte]"
|
||||
info: Benutze /greenhouse recipe <number> um Details über die Herstellung jedes
|
||||
Gewächshauses zu sehen
|
||||
error:
|
||||
greenhouseProtected: Gewächshaus geschützt
|
||||
move: Gehe zuerst in ein Gewächshaus, das dir gehört.
|
||||
notowner: Du musst der Besitzer dieses Gewächshauses sein, um das zu tun.
|
||||
removing: Gewächshaus entfernen!
|
||||
notyours: Das ist nicht dein Gewächshaus!
|
||||
notinside: Du bist nicht in einem Gewächshaus!
|
||||
tooexpensive: du kannst dir das nicht leisten [price]
|
||||
alreadyexists: Gewächshaus existiert bereits!
|
||||
norecipe: Kann kein Gewächshaus bauen!
|
||||
messages:
|
||||
enter: Betreten des [biome] Gewächshauses von [owner]!
|
||||
leave: Verlässt jetzt das Gewächshaus von [owner].
|
||||
youarein: Du bist jetzt in [owner]'s [biome] Gewächshaus!
|
||||
removed: Dieses Gewächshaus ist nicht mehr ...
|
||||
removedmessage: Ein [biome] Gewächshaus von dir ist nicht mehr!
|
||||
ecolost: Dein Gewächshaus in [location] hat sein Ökosystem verloren und wurde entfernt.
|
||||
info:
|
||||
title: "&A [Gewächshaus bauen]"
|
||||
instructions: "&EStelle einen Kasten aus Glas mit 4 Wänden und einem flachen &EGlasdach
|
||||
her und füge bis zu &F4 Türen &Ein den Wänden hinzu. &EPlatziere &F1 Trichter
|
||||
&Ein eine Wand oder ein Dach und füge Wassereimer hinzu. &EUm Schnee und/oder
|
||||
Knochenmehl herzustellen, um Pflanzen automatisch wachsen zu lassen. &EPrüfe die
|
||||
\ Biom-Rezepte, welche Blöcke in einem Gewächshaus sein müssen, um ein &EGewächshaus
|
||||
erfolgreich zu machen."
|
||||
info: "[Gewächshaus Info]"
|
||||
none: Keiner
|
||||
nomore: "&4Du kannst keine Gewächshäuser mehr bauen!"
|
||||
onemore: "&6Du kannst noch ein weiteres Gewächshaus bauen."
|
||||
youcanbuild: "&ADu kannst bis zu [number] mehr Gewächshäuser bauen!"
|
||||
unlimited: "&ADu kannst eine unbegrenzte Anzahl von Gewächshäusern bauen!"
|
||||
welcome: "&BHerzlich willkommen! Klicken Sie hier für Anweisungen"
|
||||
recipe:
|
||||
blockscolor: "&f"
|
||||
hint: benutze /greenhouse list, um eine Liste von Rezeptnummern zu sehen!
|
||||
wrongnumber: Die Rezeptnummer muss zwischen 1 und [size] liegen
|
||||
title: "[[biome] recipe]"
|
||||
nowater: Kein Wasser erlaubt.
|
||||
noice: Kein Eis erlaubt.
|
||||
nolava: Keine Lava erlaubt.
|
||||
watermustbe: Wasser > [coverage]% der Bodenfläche.
|
||||
icemustbe: Eisblöcke > [coverage]% der Bodenfläche.
|
||||
lavamustbe: Lava > [coverage]% der Bodenfläche.
|
||||
minimumblockstitle: "[Minimum blocks required]"
|
||||
nootherblocks: Keine weiteren Blöcke erforderlich.
|
||||
missing: Gewächshaus fehlt
|
||||
event:
|
||||
broke: Du hast das Gewächshaus kaputt gemacht! Biome auf [biome] umstellen!
|
||||
fix: repariere das Gewächshaus und baue es dann wieder auf
|
||||
cannotplace: Blöcke können nicht über einem Gewächshaus platziert werden!
|
||||
pistonerror: Kolben können keine Blöcke über ein Gewächshaus schieben!
|
||||
limits:
|
||||
noneallowed: Die Berechtigungen erlauben dir keine Gewächshäuser, deshalb wurden
|
||||
[nummer] entfernt.
|
||||
limitedto: Die Berechtigungen beschränken dich auf [limit] Gewächshäuser, so dass
|
||||
[number] entfernt wurden.
|
||||
adminHelp:
|
||||
reload: Konfiguration aus Datei neu laden.
|
||||
info: Liefert Informationen über das Gewächshaus, in dem du dich befindest
|
||||
reload:
|
||||
configReloaded: Konfiguration aus Datei neu geladen.
|
||||
admininfo:
|
||||
error: Gewächshaus-Info nur im Spiel verfügbar
|
||||
error2: Versetzt dich in ein Gewächshaus, um Infos zu sehen.
|
||||
flags: "[Greenhouse Flags]"
|
||||
news:
|
||||
headline: "[Greenhouse News]"
|
||||
controlpanel:
|
||||
title: "&AGewächshäuser"
|
|
@ -38,9 +38,10 @@ greenhouses:
|
|||
minimumblockstitle: "[Minimum blocks required]"
|
||||
nootherblocks: "No other blocks required."
|
||||
missing: "Greenhouse is missing"
|
||||
|
||||
|
||||
commands:
|
||||
user:
|
||||
description: "Opens the Greenhouse selection GUI"
|
||||
remove:
|
||||
description: "Removes a greenhouse that you are standing in if you are the owner"
|
||||
make:
|
||||
|
@ -52,15 +53,18 @@ greenhouses:
|
|||
FAIL_BAD_WALL_BLOCKS: "&c Wall contains disallowed blocks!"
|
||||
FAIL_BELOW: "&c You must be inside the greenhouse to try to make it"
|
||||
FAIL_BLOCKS_ABOVE: "&c There can be no blocks above the greenhouse! Red glass blocks should show the problem blocks."
|
||||
FAIL_HOLE_IN_ROOF: "&c There is a hole in the roof or it is not flat! Red glass blocks should show the problem."
|
||||
FAIL_HOLE_IN_ROOF: |
|
||||
&c There is a hole in the roof or it is not flat!
|
||||
&c Red glass blocks should show the problem.
|
||||
&c Make sure you are inside your greenhouse to make it.
|
||||
FAIL_HOLE_IN_WALL: "&c There is a hole in the wall!"
|
||||
FAIL_NO_ROOF: "&c There seems to be no roof!"
|
||||
FAIL_NO_ROOF: "&c There seems to be no roof! Make sure you are inside the greenhouse to make it."
|
||||
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"
|
||||
|
|
|
@ -1,189 +1,153 @@
|
|||
###########################################################################################
|
||||
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
|
||||
# the one at http://yaml-online-parser.appspot.com #
|
||||
# If this file is deleted, then it will be recreate at the next reload. #
|
||||
###########################################################################################
|
||||
---
|
||||
protection:
|
||||
flags:
|
||||
GREENHOUSE:
|
||||
name: Greenhouses
|
||||
description: |
|
||||
&bÁllítsd be, hogy ki
|
||||
&bkezelheti az üvegházat
|
||||
|
||||
description: "&bÁllítsd be, hogy ki\n&bkezelheti az üvegházat \n"
|
||||
greenhouses:
|
||||
general:
|
||||
greenhouses: "Üvegházak"
|
||||
|
||||
greenhouses: Üvegházak
|
||||
errors:
|
||||
move: "Menj a saját üvegházadhoz."
|
||||
move: Menj a saját üvegházadhoz.
|
||||
no-rank: "&cNincs rangod ehhez."
|
||||
notyours: "Ez nem a te üvegházad!"
|
||||
notyours: Ez nem a te üvegházad!
|
||||
not-inside: "&cNem vagy üvegházban!"
|
||||
tooexpensive: "Ehhez nincs elég pénzed, ennyi szükséges: [price]"
|
||||
alreadyexists: "Az üvegház már létezik!"
|
||||
norecipe: "Nem tudsz üvegházat csinálni!"
|
||||
|
||||
tooexpensive: 'Ehhez nincs elég pénzed, ennyi szükséges: [price]'
|
||||
alreadyexists: Az üvegház már létezik!
|
||||
norecipe: Nem tudsz üvegházat csinálni!
|
||||
event:
|
||||
broke: "Összetörted az üvegházad! Visszaállítjuk a biome-ot [biome]-ra/re!"
|
||||
entering: "Belépés a(z) [biome] üvegházba."
|
||||
leaving: "Kilépés a(z) [biome] üvegházból."
|
||||
|
||||
broke: Összetörted az üvegházad! Visszaállítjuk a biome-ot [biome]-ra/re!
|
||||
entering: Belépés a(z) [biome] üvegházba.
|
||||
leaving: Kilépés a(z) [biome] üvegházból.
|
||||
recipe:
|
||||
blockscolor: "&f"
|
||||
title: "[[biome] recept]"
|
||||
watermustbe: "Víz > [coverage]% kell, hogy legyen az alapterületen."
|
||||
icemustbe: "Jég blokk > [coverage]% kell, hogy legyen az alapterületen."
|
||||
lavamustbe: "Láva > [coverage]% kell, hogy legyen az alapterületen."
|
||||
minimumblockstitle: "[Minimum blokkmennyiség]"
|
||||
nootherblocks: "Nem szükséges több blokk."
|
||||
missing: "Hiányzó üvegház."
|
||||
|
||||
blockscolor: "&f"
|
||||
title: "[[biome] recept]"
|
||||
watermustbe: Víz > [coverage]% kell, hogy legyen az alapterületen.
|
||||
icemustbe: Jég blokk > [coverage]% kell, hogy legyen az alapterületen.
|
||||
lavamustbe: Láva > [coverage]% kell, hogy legyen az alapterületen.
|
||||
minimumblockstitle: "[Minimum blokkmennyiség]"
|
||||
nootherblocks: Nem szükséges több blokk.
|
||||
missing: Hiányzó üvegház.
|
||||
commands:
|
||||
user:
|
||||
remove:
|
||||
description: "Ha az üvegházadban állsz és te vagy a tulaja, akkor törli azt."
|
||||
description: Ha az üvegházadban állsz és te vagy a tulaja, akkor törli azt.
|
||||
make:
|
||||
description: "Megpróbál készíteni egy üvegházat."
|
||||
description: Megpróbál készíteni egy üvegházat.
|
||||
parameters: "<recipe>"
|
||||
error:
|
||||
already: "Az üvegház már létezik!"
|
||||
already: Az üvegház már létezik!
|
||||
FAIL_BAD_ROOF_BLOCKS: "&cA tető nem engedélyezett blokkokat tartalmaz!"
|
||||
FAIL_BAD_WALL_BLOCKS: "&cA fal nem engedélyezett blokkokat tartalmaz!"
|
||||
FAIL_BELOW: "&cAz üvegházban kell lenned, hogy megpróbáld elkészíteni"
|
||||
FAIL_BLOCKS_ABOVE: "&cAz üvegház felett nem lehetnek blokkok! A piros üvegblokkoknak meg kell mutatniuk a problémás blokkokat."
|
||||
FAIL_HOLE_IN_ROOF: "&cVan egy lyuk a tetőn, vagy nem sík! A piros üvegblokkoknak meg kell mutatniuk a problémát."
|
||||
FAIL_BLOCKS_ABOVE: "&cAz üvegház felett nem lehetnek blokkok! A piros üvegblokkoknak
|
||||
meg kell mutatniuk a problémás blokkokat."
|
||||
FAIL_HOLE_IN_ROOF: "&cVan egy lyuk a tetőn, vagy nem sík! A piros üvegblokkoknak
|
||||
meg kell mutatniuk a problémát."
|
||||
FAIL_HOLE_IN_WALL: "&cVan egy lyuk a falban!"
|
||||
FAIL_NO_ROOF: "&cÚgy tűnik, nincs tető!"
|
||||
FAIL_TOO_MANY_DOORS: "&cAz üvegházban nem lehet négynél több ajtó!"
|
||||
FAIL_TOO_MANY_HOPPERS: "&cCsak egy tölcsér megengedett a falakban vagy a tetőben."
|
||||
FAIL_UNEVEN_WALLS: "&cA falak egyenetlenek. A piros üvegblokkoknak meg kell mutatniuk a problémás blokkokat."
|
||||
FAIL_TOO_MANY_HOPPERS: "&cCsak egy tölcsér megengedett a falakban vagy a
|
||||
tetőben."
|
||||
FAIL_UNEVEN_WALLS: "&cA falak egyenetlenek. A piros üvegblokkoknak meg kell
|
||||
mutatniuk a problémás blokkokat."
|
||||
FAIL_INSUFFICIENT_ICE: "&cNem elegendő a jég ehhez a recept elkészítéséhez."
|
||||
FAIL_INSUFFICIENT_LAVA: "&cNem elegendő a láva ehhez a recept elkészítéséhez."
|
||||
FAIL_INSUFFICIENT_WATER: "&cNem elegendő a víz ehhez a recept elkészítéséhez."
|
||||
FAIL_NO_ICE: "&cA jég szükséges ehhez a recepthez."
|
||||
FAIL_NO_LAVA: "&cA láva szükséges ehhez a recepthez."
|
||||
FAIL_NO_WATER: "&cA víz szükséges ehhez a recepthez."
|
||||
FAIL_NO_RECIPE_FOUND: "&c Nem található ilyen recept ebben a melegházban."
|
||||
FAIL_INSUFFICIENT_BLOCKS: "&cTovábbi blokkokra van szükség a recept elkészítéséhez!"
|
||||
FAIL_OVERLAPPING: "&cAz üvegházak nem oszthatják meg a falakat, bocs."
|
||||
success: "Sikeresen elkészítettél egy [biome] üvegházat! Az éghajlat szinkronizálódik a következő teleportálásnál, vagy belépésnél."
|
||||
success: Sikeresen elkészítettél egy [biome] üvegházat! Az éghajlat szinkronizálódik
|
||||
a következő teleportálásnál, vagy belépésnél.
|
||||
missing-blocks: "&cHiányzik [material] x [number]"
|
||||
unknown-recipe: "&cIsmeretlen recept"
|
||||
try-these: "&cPróbálj meg egyet az alábbiak közül:"
|
||||
recipe-format: "&3[name]"
|
||||
info:
|
||||
title: "&A[Hogyan Készíts Üvegházat]"
|
||||
instructions: |
|
||||
&EKészíts egy üvegdobozt 4 fallal, egy üvegtetővel,
|
||||
&Eés akár 4 ajtót is tehetsz a falba.
|
||||
&ERakj a falba vagy a tetőbe &F1 tölcsért, &Eés helyezz bele vizes vödröket,
|
||||
&Ehogy havat és/vagy csontlisztet készíts, mellyel automatikusan tudod növeszteni a növényeidet.
|
||||
&ENézd meg az éghajlatokhoz tartozó recepteket, hogy megtudd milyen blokkok legyenek feltétlenül
|
||||
&Eaz üvegházban ahhoz, hogy sikeresen elkészítsd.
|
||||
|
||||
|
||||
######### Old locale for reference
|
||||
instructions: "&EKészíts egy üvegdobozt 4 fallal, egy üvegtetővel,\n&Eés akár
|
||||
4 ajtót is tehetsz a falba.\n&ERakj a falba vagy a tetőbe &F1 tölcsért,
|
||||
&Eés helyezz bele vizes vödröket,\n&Ehogy havat és/vagy csontlisztet készíts,
|
||||
mellyel automatikusan tudod növeszteni a növényeidet.\n&ENézd meg az éghajlatokhoz
|
||||
tartozó recepteket, hogy megtudd milyen blokkok legyenek feltétlenül\n&Eaz
|
||||
üvegházban ahhoz, hogy sikeresen elkészítsd. \n"
|
||||
help:
|
||||
help: "help"
|
||||
make: "Tries to make a greenhouse"
|
||||
remove: "Removes a greenhouse that you are standing in if you are the owner"
|
||||
info: "How to make a greenhouse"
|
||||
list: "Lists all the greenhouse biomes that can be made"
|
||||
recipe: "Tells you how to make greenhouse biome"
|
||||
opengui: "Opens the Greenhouse GUI"
|
||||
|
||||
help: help
|
||||
make: Tries to make a greenhouse
|
||||
remove: Removes a greenhouse that you are standing in if you are the owner
|
||||
info: How to make a greenhouse
|
||||
list: Lists all the greenhouse biomes that can be made
|
||||
recipe: Tells you how to make greenhouse biome
|
||||
opengui: Opens the Greenhouse GUI
|
||||
list:
|
||||
title: "[Greenhouse Biome Recipes]"
|
||||
info: "Use /greenhouse recipe <number> to see details on how to make each greenhouse"
|
||||
|
||||
|
||||
################
|
||||
#General Errors#
|
||||
################
|
||||
title: "[Greenhouse Biome Recipes]"
|
||||
info: Use /greenhouse recipe <number> to see details on how to make each greenhouse
|
||||
error:
|
||||
greenhouseProtected: "Greenhouse protected"
|
||||
move: "Move to a greenhouse you own first."
|
||||
notowner: "You must be the owner of this greenhouse to do that."
|
||||
removing: "Removing greenhouse!"
|
||||
notyours: "This is not your greenhouse!"
|
||||
notinside: "You are not in a greenhouse!"
|
||||
tooexpensive: "You cannot afford [price]"
|
||||
alreadyexists: "Greenhouse already exists!"
|
||||
norecipe: "Cannot make a greenhouse!"
|
||||
|
||||
greenhouseProtected: Greenhouse protected
|
||||
move: Move to a greenhouse you own first.
|
||||
notowner: You must be the owner of this greenhouse to do that.
|
||||
removing: Removing greenhouse!
|
||||
notyours: This is not your greenhouse!
|
||||
notinside: You are not in a greenhouse!
|
||||
tooexpensive: You cannot afford [price]
|
||||
alreadyexists: Greenhouse already exists!
|
||||
norecipe: Cannot make a greenhouse!
|
||||
messages:
|
||||
enter: "Entering [owner]'s [biome] greenhouse!"
|
||||
leave: "Now leaving [owner]'s greenhouse."
|
||||
youarein: "You are now in [owner]'s [biome] greenhouse!"
|
||||
removed: "This greenhouse is no more..."
|
||||
removedmessage: "A [biome] greenhouse of yours is no more!"
|
||||
ecolost: "Your greenhouse at [location] lost its eco system and was removed."
|
||||
|
||||
enter: Entering [owner]'s [biome] greenhouse!
|
||||
leave: Now leaving [owner]'s greenhouse.
|
||||
youarein: You are now in [owner]'s [biome] greenhouse!
|
||||
removed: This greenhouse is no more...
|
||||
removedmessage: A [biome] greenhouse of yours is no more!
|
||||
ecolost: Your greenhouse at [location] lost its eco system and was removed.
|
||||
info:
|
||||
title: "&A[How To Build A Greenhouse]"
|
||||
instructions: |
|
||||
&EMake a box out of out of glass with 4 walls and a flat glass
|
||||
&Eroof and add up to &F4 doors &Ein the walls.
|
||||
&EPlace &F1 hopper &Ein a wall or roof and add water buckets.
|
||||
&Eto make snow and/or bonemeal to grow plants automatically.
|
||||
&ECheck the biome recipes for what blocks must be inside a
|
||||
&Egreenhouse to make one successfully.
|
||||
info: "[Greenhouse Info]"
|
||||
none: "None"
|
||||
nomore: "&4You cannot build any more greenhouses!"
|
||||
onemore: "&6You can build one more greenhouse."
|
||||
youcanbuild: "&AYou can build up to [number] more greenhouses!"
|
||||
unlimited: "&AYou can build an unlimited number of greenhouses!"
|
||||
welcome: "&BWelcome! Click here for instructions"
|
||||
|
||||
title: "&A[How To Build A Greenhouse]"
|
||||
instructions: "&EMake a box out of out of glass with 4 walls and a flat glass\n&Eroof
|
||||
and add up to &F4 doors &Ein the walls.\n&EPlace &F1 hopper &Ein a wall or roof
|
||||
and add water buckets.\n&Eto make snow and/or bonemeal to grow plants automatically.\n&ECheck
|
||||
the biome recipes for what blocks must be inside a\n&Egreenhouse to make one successfully.
|
||||
\n"
|
||||
info: "[Greenhouse Info]"
|
||||
none: None
|
||||
nomore: "&4You cannot build any more greenhouses!"
|
||||
onemore: "&6You can build one more greenhouse."
|
||||
youcanbuild: "&AYou can build up to [number] more greenhouses!"
|
||||
unlimited: "&AYou can build an unlimited number of greenhouses!"
|
||||
welcome: "&BWelcome! Click here for instructions"
|
||||
recipe:
|
||||
blockscolor: "&f"
|
||||
hint: "Use /greenhouse list to see a list of recipe numbers!"
|
||||
wrongnumber: "Recipe number must be between 1 and [size]"
|
||||
title: "[[biome] recipe]"
|
||||
nowater: "No water allowed."
|
||||
noice: "No ice allowed."
|
||||
nolava: "No lava allowed."
|
||||
watermustbe: "Water > [coverage]% of floor area."
|
||||
icemustbe: "Ice blocks > [coverage]% of floor area."
|
||||
lavamustbe: "Lava > [coverage]% of floor area."
|
||||
minimumblockstitle: "[Minimum blocks required]"
|
||||
nootherblocks: "No other blocks required."
|
||||
missing: "Greenhouse is missing"
|
||||
|
||||
blockscolor: "&f"
|
||||
hint: Use /greenhouse list to see a list of recipe numbers!
|
||||
wrongnumber: Recipe number must be between 1 and [size]
|
||||
title: "[[biome] recipe]"
|
||||
nowater: No water allowed.
|
||||
noice: No ice allowed.
|
||||
nolava: No lava allowed.
|
||||
watermustbe: Water > [coverage]% of floor area.
|
||||
icemustbe: Ice blocks > [coverage]% of floor area.
|
||||
lavamustbe: Lava > [coverage]% of floor area.
|
||||
minimumblockstitle: "[Minimum blocks required]"
|
||||
nootherblocks: No other blocks required.
|
||||
missing: Greenhouse is missing
|
||||
event:
|
||||
broke: "You broke this greenhouse! Reverting biome to [biome]!"
|
||||
fix: "Fix the greenhouse and then make it again."
|
||||
cannotplace: "Blocks cannot be placed above a greenhouse!"
|
||||
pistonerror: "Pistons cannot push blocks over a greenhouse!"
|
||||
|
||||
|
||||
broke: You broke this greenhouse! Reverting biome to [biome]!
|
||||
fix: Fix the greenhouse and then make it again.
|
||||
cannotplace: Blocks cannot be placed above a greenhouse!
|
||||
pistonerror: Pistons cannot push blocks over a greenhouse!
|
||||
limits:
|
||||
noneallowed: "Permissions do not allow you any greenhouses so [number] were removed."
|
||||
limitedto: "Permissions limit you to [limit] greenhouses so [number] were removed."
|
||||
|
||||
|
||||
##################################
|
||||
#Admin commands that use /gadmin #
|
||||
##################################
|
||||
|
||||
#Help
|
||||
noneallowed: Permissions do not allow you any greenhouses so [number] were removed.
|
||||
limitedto: Permissions limit you to [limit] greenhouses so [number] were removed.
|
||||
adminHelp:
|
||||
reload: "reload configuration from file."
|
||||
info: "provides info on the greenhouse you are in"
|
||||
|
||||
#reload
|
||||
reload: reload configuration from file.
|
||||
info: provides info on the greenhouse you are in
|
||||
reload:
|
||||
configReloaded: "Configuration reloaded from file."
|
||||
|
||||
configReloaded: Configuration reloaded from file.
|
||||
admininfo:
|
||||
error: "Greenhouse info only available in-game"
|
||||
error2: "Put yourself in a greenhouse to see info."
|
||||
flags: "[Greenhouse Flags]"
|
||||
|
||||
error: Greenhouse info only available in-game
|
||||
error2: Put yourself in a greenhouse to see info.
|
||||
flags: "[Greenhouse Flags]"
|
||||
news:
|
||||
headline: "[Greenhouse News]"
|
||||
|
||||
headline: "[Greenhouse News]"
|
||||
controlpanel:
|
||||
title: "&AGreenhouses"
|
||||
|
||||
title: "&AGreenhouses"
|
||||
|
|
|
@ -1,37 +1,42 @@
|
|||
---
|
||||
adminHelp:
|
||||
info: あなたがいる温室に関する情報を提供します
|
||||
reload: ファイルから設定をリロードします。
|
||||
admininfo:
|
||||
error: ゲーム内でのみ利用可能な温室情報
|
||||
error2: 温室で情報を確認してください。
|
||||
flags: "[温室旗]"
|
||||
controlpanel:
|
||||
title: "&A温室"
|
||||
error:
|
||||
alreadyexists: 温室はすでに存在します!
|
||||
greenhouseProtected: 温室保護
|
||||
move: 最初に所有する温室に移動します。
|
||||
norecipe: 温室を作ることができません!
|
||||
notinside: あなたは温室の中にいません!
|
||||
notowner: それを行うには、この温室の所有者でなければなりません。
|
||||
notyours: これはあなたの温室ではありません!
|
||||
removing: 温室を撤去!
|
||||
tooexpensive: あなたは余裕がない[price]
|
||||
event:
|
||||
broke: あなたはこの温室を壊しました!バイオームを[biome]に戻しています!
|
||||
cannotplace: ブロックを温室の上に置くことはできません!
|
||||
fix: 温室を修理してから、もう一度作ります。
|
||||
pistonerror: ピストンは温室の上でブロックを押すことができません!
|
||||
protection:
|
||||
flags:
|
||||
GREENHOUSE:
|
||||
name: 温室
|
||||
description: |-
|
||||
&b誰が温室を制御できるかを
|
||||
&b設定する
|
||||
greenhouses:
|
||||
general:
|
||||
greenhouses: 温室
|
||||
errors:
|
||||
move: 最初に所有する温室に移動します。
|
||||
no-rank: "&cあなたにはそれをするランクがありません。"
|
||||
notyours: これはあなたの温室ではありません!
|
||||
not-inside: "&cあなたは温室の中にいません!"
|
||||
tooexpensive: あなたは余裕がない[price]
|
||||
alreadyexists: 温室はすでに存在します!
|
||||
norecipe: 温室を作ることができません!
|
||||
event:
|
||||
broke: "&c温室を壊しました!バイオームを [biome]に戻しています!"
|
||||
entering: "[biome]の温室に入る"
|
||||
leaving: "[biome]の温室を離れる"
|
||||
recipe:
|
||||
blockscolor: "&f"
|
||||
title: "[[biome]レシピ]"
|
||||
watermustbe: 水>[coverage]床面積の%。
|
||||
icemustbe: 氷のブロック>床面積の[coverage]%。
|
||||
lavamustbe: 溶岩> [coverage]床面積の%。
|
||||
minimumblockstitle: "[必要な最小ブロック]"
|
||||
nootherblocks: 他のブロックは必要ありません。
|
||||
missing: 温室がありません
|
||||
commands:
|
||||
user:
|
||||
info:
|
||||
title: "&A [温室の作り方]"
|
||||
instructions: 4つの壁と平らなガラス屋根でガラスから箱を作り、壁に最大4つのドアを追加します。 1つのホッパーを壁または屋根に置き、水バケツを追加します。
|
||||
雪や骨粉を作り、植物を自動的に育てます。 バイオームレシピを確認して、温室内で正常にブロックするために必要なブロックを確認してください。
|
||||
remove:
|
||||
description: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
||||
make:
|
||||
description: 温室を作ってみる
|
||||
parameters: "<レシピ>"
|
||||
error:
|
||||
already: "&cここには温室がすでにあります!"
|
||||
FAIL_BAD_ROOF_BLOCKS: "&c屋根には許可されていないブロックが含まれています!"
|
||||
|
@ -40,97 +45,99 @@ greenhouses:
|
|||
FAIL_BLOCKS_ABOVE: "&c温室の上にブロックを置くことはできません!赤いガラスブロックに問題のあるブロックが表示されます。"
|
||||
FAIL_HOLE_IN_ROOF: "&c屋根に穴があるか、平らではありません!赤いガラスブロックが問題を示しているはずです。"
|
||||
FAIL_HOLE_IN_WALL: "&c壁に穴が開いています!"
|
||||
FAIL_INSUFFICIENT_ICE: "&cこのレシピを作成するには氷が足りません"
|
||||
FAIL_INSUFFICIENT_LAVA: "&cこのレシピを作るには溶岩が足りません"
|
||||
FAIL_INSUFFICIENT_WATER: "&cこのレシピを作るのに水が足りません"
|
||||
FAIL_NO_ROOF: "&c屋根がないようです!"
|
||||
FAIL_TOO_MANY_DOORS: "&c温室には4つ以上のドアを置くことはできません!"
|
||||
FAIL_TOO_MANY_HOPPERS: "&c壁または屋根に使用できるホッパーは1つだけです。"
|
||||
FAIL_UNEVEN_WALLS: "&c壁が不均一です。赤いガラスブロックに問題のあるブロックが表示されます。"
|
||||
FAIL_INSUFFICIENT_ICE: "&cこのレシピを作成するには氷が足りません"
|
||||
FAIL_INSUFFICIENT_LAVA: "&cこのレシピを作るには溶岩が足りません"
|
||||
FAIL_INSUFFICIENT_WATER: "&cこのレシピを作るのに水が足りません"
|
||||
FAIL_NO_ICE: このレシピを作成するには&c氷が必要です
|
||||
FAIL_NO_LAVA: このレシピを作成するには&c溶岩が必要です
|
||||
FAIL_NO_WATER: このレシピを作成するには&c水が必要です
|
||||
parameters: "<レシピ>"
|
||||
FAIL_NO_RECIPE_FOUND: "&cこの温室に一致するレシピが見つかりませんでした"
|
||||
FAIL_INSUFFICIENT_BLOCKS: "&cこのレシピを作成するには、さらに多くのブロックが必要です。"
|
||||
FAIL_OVERLAPPING: "&c温室は壁を共有できません。申し訳ありません。"
|
||||
success: "&2あなたは[biome]バイオーム温室を無事に作成しました!バイオームは次のテレポートまたはログインで同期します。"
|
||||
remove:
|
||||
description: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
||||
errors:
|
||||
alreadyexists: 温室はすでに存在します!
|
||||
move: 最初に所有する温室に移動します。
|
||||
no-rank: "&cあなたにはそれをするランクがありません。"
|
||||
norecipe: 温室を作ることができません!
|
||||
not-inside: "&cあなたは温室の中にいません!"
|
||||
notyours: これはあなたの温室ではありません!
|
||||
tooexpensive: あなたは余裕がない[price]
|
||||
general:
|
||||
greenhouses: 温室
|
||||
recipe:
|
||||
blockscolor: "&f"
|
||||
minimumblockstitle: "[必要な最小ブロック]"
|
||||
missing: 温室がありません
|
||||
nootherblocks: 他のブロックは必要ありません。
|
||||
title: "[[biome]レシピ]"
|
||||
watermustbe: 水>[coverage]床面積の%。
|
||||
icemustbe: 氷のブロック>床面積の[coverage]%。
|
||||
lavamustbe: 溶岩> [coverage]床面積の%。
|
||||
event:
|
||||
broke: "&c温室を壊しました!バイオームを [biome]に戻しています!"
|
||||
entering: "[biome]の温室に入る"
|
||||
leaving: "[biome]の温室を離れる"
|
||||
missing-blocks: "&c欠落[material] x [number]"
|
||||
unknown-recipe: "&c不明なレシピ"
|
||||
try-these: "&c次のいずれかを試してください。"
|
||||
recipe-format: "&3[name]"
|
||||
info:
|
||||
title: "&A [温室の作り方]"
|
||||
instructions: 4つの壁と平らなガラス屋根でガラスから箱を作り、壁に最大4つのドアを追加します。 1つのホッパーを壁または屋根に置き、水バケツを追加します。
|
||||
雪や骨粉を作り、植物を自動的に育てます。 バイオームレシピを確認して、温室内で正常にブロックするために必要なブロックを確認してください。
|
||||
help:
|
||||
help: 手助け
|
||||
make: 温室を作ろうとする
|
||||
remove: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
||||
info: 温室の作り方
|
||||
list: 作成可能なすべての温室バイオームをリストします
|
||||
make: 温室を作ろうとする
|
||||
recipe: 温室バイオームの作り方を説明します
|
||||
remove: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
||||
opengui: 温室のGUI
|
||||
info:
|
||||
info: "[温室情報]"
|
||||
instructions: "&E 4つの壁と平らなガラスの&E屋根でガラスから箱を作り、壁に&F 4のドア&Eを追加します。 &E壁と屋根に&F 1ホッパー&Eを配置し、ウォーターバケツ&Eを追加して雪や骨粉を作り、植物を自動的に成長させます。
|
||||
&Eバイオームレシピを確認して、&E温室内で正常にブロックを作成するために必要なブロックを確認します。"
|
||||
nomore: "&4これ以上温室を建設することはできません!"
|
||||
none: 無し
|
||||
onemore: "&6温室をもう1つ構築できます。"
|
||||
title: "&A [温室の作り方]"
|
||||
unlimited: "&A温室を無制限に構築できます!"
|
||||
welcome: "&B ようこそ!手順についてはここをクリックしてください"
|
||||
youcanbuild: "&A温室を最大[number]個まで構築できます!"
|
||||
limits:
|
||||
limitedto: 許可により温室が[limit]に制限されるため、[number]が削除されました。
|
||||
noneallowed: 許可により温室が許可されないため、[number]は削除されました。
|
||||
list:
|
||||
title: "[温室効果バイオームのレシピ]"
|
||||
info: "/greenhouse recipe <番号>を使用する各温室の作り方の詳細を見る"
|
||||
error:
|
||||
greenhouseProtected: 温室保護
|
||||
move: 最初に所有する温室に移動します。
|
||||
notowner: それを行うには、この温室の所有者でなければなりません。
|
||||
removing: 温室を撤去!
|
||||
notyours: これはあなたの温室ではありません!
|
||||
notinside: あなたは温室の中にいません!
|
||||
tooexpensive: あなたは余裕がない[price]
|
||||
alreadyexists: 温室はすでに存在します!
|
||||
norecipe: 温室を作ることができません!
|
||||
messages:
|
||||
ecolost: "[location]の温室はエコシステムを失い、撤去されました。"
|
||||
leave: "[owner]の温室を離れます。"
|
||||
removed: この温室はもうありません...
|
||||
enter: "[owner]の[biome]の温室に入る!"
|
||||
leave: "[owner]の温室を離れます。"
|
||||
youarein: あなたは今[owner]の[biome]の温室にいます!
|
||||
removed: この温室はもうありません...
|
||||
removedmessage: あなたの[biome]の温室はもうありません!
|
||||
news:
|
||||
headline: "[温室ニュース]"
|
||||
protection:
|
||||
flags:
|
||||
GREENHOUSE:
|
||||
name: 温室
|
||||
description: |-
|
||||
&b誰が温室を制御できるかを
|
||||
&b設定する
|
||||
ecolost: "[location]の温室はエコシステムを失い、撤去されました。"
|
||||
info:
|
||||
title: "&A [温室の作り方]"
|
||||
instructions: "&E 4つの壁と平らなガラスの&E屋根でガラスから箱を作り、壁に&F 4のドア&Eを追加します。 &E壁と屋根に&F 1ホッパー&Eを配置し、ウォーターバケツ&Eを追加して雪や骨粉を作り、植物を自動的に成長させます。
|
||||
&Eバイオームレシピを確認して、&E温室内で正常にブロックを作成するために必要なブロックを確認します。"
|
||||
info: "[温室情報]"
|
||||
none: 無し
|
||||
nomore: "&4これ以上温室を建設することはできません!"
|
||||
onemore: "&6温室をもう1つ構築できます。"
|
||||
youcanbuild: "&A温室を最大[number]個まで構築できます!"
|
||||
unlimited: "&A温室を無制限に構築できます!"
|
||||
welcome: "&B ようこそ!手順についてはここをクリックしてください"
|
||||
recipe:
|
||||
blockscolor: "&f"
|
||||
hint: "/ greenhouse listを使用して、レシピ番号のリストを表示します!"
|
||||
wrongnumber: レシピ番号は1から[size]の間でなければなりません
|
||||
title: "[[biome]レシピ]"
|
||||
nowater: 水は許可されません。
|
||||
noice: 氷は許可されていません。
|
||||
nolava: 溶岩は許可されていません。
|
||||
watermustbe: 水> [coverage]床面積の%。
|
||||
icemustbe: 氷のブロック>床面積の[coverage]%。
|
||||
lavamustbe: 溶岩> [coverage]床面積の%。
|
||||
minimumblockstitle: "[必要な最小ブロック]"
|
||||
missing: 温室がありません
|
||||
noice: 氷は許可されていません。
|
||||
nolava: 溶岩は許可されていません。
|
||||
nootherblocks: 他のブロックは必要ありません。
|
||||
nowater: 水は許可されません。
|
||||
title: "[[biome]レシピ]"
|
||||
watermustbe: 水> [coverage]床面積の%。
|
||||
wrongnumber: レシピ番号は1から[size]の間でなければなりません
|
||||
missing: 温室がありません
|
||||
event:
|
||||
broke: あなたはこの温室を壊しました!バイオームを[biome]に戻しています!
|
||||
fix: 温室を修理してから、もう一度作ります。
|
||||
cannotplace: ブロックを温室の上に置くことはできません!
|
||||
pistonerror: ピストンは温室の上でブロックを押すことができません!
|
||||
limits:
|
||||
noneallowed: 許可により温室が許可されないため、[number]は削除されました。
|
||||
limitedto: 許可により温室が[limit]に制限されるため、[number]が削除されました。
|
||||
adminHelp:
|
||||
reload: ファイルから設定をリロードします。
|
||||
info: あなたがいる温室に関する情報を提供します
|
||||
reload:
|
||||
configReloaded: ファイルから構成が再ロードされました。
|
||||
admininfo:
|
||||
error: ゲーム内でのみ利用可能な温室情報
|
||||
error2: 温室で情報を確認してください。
|
||||
flags: "[温室旗]"
|
||||
news:
|
||||
headline: "[温室ニュース]"
|
||||
controlpanel:
|
||||
title: "&A温室"
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#
|
||||
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
|
||||
# the one at http://yaml-online-parser.appspot.com #
|
||||
# If this file is deleted, then it will be recreate at the next reload. #
|
||||
---
|
||||
protection:
|
||||
flags:
|
||||
GREENHOUSE:
|
||||
|
@ -12,9 +9,9 @@ greenhouses:
|
|||
greenhouses: 温室
|
||||
errors:
|
||||
move: 移动到你拥有的第一个温室.
|
||||
no-rank: '&c你没有足够的阶级去做这个.'
|
||||
no-rank: "&c你没有足够的阶级去做这个."
|
||||
notyours: 这不是你的温室!
|
||||
not-inside: '&c你并不处于一个温室之中!'
|
||||
not-inside: "&c你并不处于一个温室之中!"
|
||||
tooexpensive: 你的钱不足以支付 [price]
|
||||
alreadyexists: 温室已经存在!
|
||||
norecipe: 无法创建一个温室!
|
||||
|
@ -23,12 +20,12 @@ greenhouses:
|
|||
entering: 你进入一个 [biome] 温室
|
||||
leaving: 你离开了 [biome] 温室
|
||||
recipe:
|
||||
blockscolor: '&f'
|
||||
title: '[[biome] 配方]'
|
||||
blockscolor: "&f"
|
||||
title: "[[biome] 配方]"
|
||||
watermustbe: 水在地面上的占比需要大于[coverage]%.
|
||||
icemustbe: 冰在地面上的占比需要大于[coverage]%.
|
||||
lavamustbe: 岩浆在地面上的占比需要大于[coverage]%.
|
||||
minimumblockstitle: '[最少所需的方块数目]'
|
||||
minimumblockstitle: "[最少所需的方块数目]"
|
||||
nootherblocks: 没有其它需要的方块了.
|
||||
missing: 温室缺失了
|
||||
commands:
|
||||
|
@ -37,39 +34,37 @@ greenhouses:
|
|||
description: 如果你是你现在所处的温室的主人则移除这个温室
|
||||
make:
|
||||
description: 尝试建造一个温室
|
||||
parameters: <recipe>
|
||||
parameters: "<recipe>"
|
||||
error:
|
||||
already: '&c这已经有一个温室了!'
|
||||
FAIL_BAD_ROOF_BLOCKS: '&c屋顶包含了不被允许的方块!'
|
||||
FAIL_BAD_WALL_BLOCKS: '&c墙壁包含了不被允许的方块!'
|
||||
FAIL_BELOW: '&c你必须处于温室结构内才能尝试建造它'
|
||||
FAIL_BLOCKS_ABOVE: '&c温室的上方不能有方块,违规方块已被标红.'
|
||||
FAIL_HOLE_IN_ROOF: '&c屋顶上有一个洞或者屋顶并不平整,违规方块已被标红.'
|
||||
FAIL_HOLE_IN_WALL: '&c墙上有一个洞!'
|
||||
FAIL_NO_ROOF: '&c这儿看起来没有屋顶!'
|
||||
FAIL_TOO_MANY_DOORS: '&c你的温室最多只能有四个门!'
|
||||
FAIL_TOO_MANY_HOPPERS: '&c墙或屋顶上至多有一个漏斗.'
|
||||
FAIL_UNEVEN_WALLS: '&c墙壁不平坦,违规方块已被标红.'
|
||||
FAIL_INSUFFICIENT_ICE: '&c冰的数目不足以建造这个温室'
|
||||
FAIL_INSUFFICIENT_LAVA: '&c岩浆的数目不足以建造这个温室'
|
||||
FAIL_INSUFFICIENT_WATER: '&c水的数目不足以建造这个温室'
|
||||
FAIL_NO_ICE: '&c对于这个温室来说冰是必须的'
|
||||
FAIL_NO_LAVA: '&c对于这个温室来说岩浆是必须的'
|
||||
FAIL_NO_WATER: '&c对于这个温室来说水是必须的'
|
||||
FAIL_INSUFFICIENT_BLOCKS: '&c你所用的方块数目不足!'
|
||||
FAIL_OVERLAPPING: '&c温室间不能共享墙壁.'
|
||||
success: '&2你成功的建造了一个 [biome] 群系温室! 在你下次登陆时生物群系将会刷新.'
|
||||
missing-blocks: '&c缺少了 [material] x [number]'
|
||||
unknown-recipe: '&c未知的温室配方'
|
||||
try-these: '&c尝试以下操作:'
|
||||
recipe-format: '&3[name]'
|
||||
already: "&c这已经有一个温室了!"
|
||||
FAIL_BAD_ROOF_BLOCKS: "&c屋顶包含了不被允许的方块!"
|
||||
FAIL_BAD_WALL_BLOCKS: "&c墙壁包含了不被允许的方块!"
|
||||
FAIL_BELOW: "&c你必须处于温室结构内才能尝试建造它"
|
||||
FAIL_BLOCKS_ABOVE: "&c温室的上方不能有方块,违规方块已被标红."
|
||||
FAIL_HOLE_IN_ROOF: "&c屋顶上有一个洞或者屋顶并不平整,违规方块已被标红."
|
||||
FAIL_HOLE_IN_WALL: "&c墙上有一个洞!"
|
||||
FAIL_NO_ROOF: "&c这儿看起来没有屋顶!"
|
||||
FAIL_TOO_MANY_DOORS: "&c你的温室最多只能有四个门!"
|
||||
FAIL_TOO_MANY_HOPPERS: "&c墙或屋顶上至多有一个漏斗."
|
||||
FAIL_UNEVEN_WALLS: "&c墙壁不平坦,违规方块已被标红."
|
||||
FAIL_INSUFFICIENT_ICE: "&c冰的数目不足以建造这个温室"
|
||||
FAIL_INSUFFICIENT_LAVA: "&c岩浆的数目不足以建造这个温室"
|
||||
FAIL_INSUFFICIENT_WATER: "&c水的数目不足以建造这个温室"
|
||||
FAIL_NO_ICE: "&c对于这个温室来说冰是必须的"
|
||||
FAIL_NO_LAVA: "&c对于这个温室来说岩浆是必须的"
|
||||
FAIL_NO_WATER: "&c对于这个温室来说水是必须的"
|
||||
FAIL_NO_RECIPE_FOUND: "&c 找不到与此温室相匹配的配方"
|
||||
FAIL_INSUFFICIENT_BLOCKS: "&c你所用的方块数目不足!"
|
||||
FAIL_OVERLAPPING: "&c温室间不能共享墙壁."
|
||||
success: "&2你成功的建造了一个 [biome] 群系温室! 在你下次登陆时生物群系将会刷新."
|
||||
missing-blocks: "&c缺少了 [material] x [number]"
|
||||
unknown-recipe: "&c未知的温室配方"
|
||||
try-these: "&c尝试以下操作:"
|
||||
recipe-format: "&3[name]"
|
||||
info:
|
||||
title: '&A[温室建造指南]'
|
||||
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n\
|
||||
&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗\
|
||||
\ \n&E来放置骨粉或雪\
|
||||
\ 来让作物自动生长.\n&E检查温室配方确保\
|
||||
\ 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
||||
title: "&A[温室建造指南]"
|
||||
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗
|
||||
\n&E来放置骨粉或雪 来让作物自动生长.\n&E检查温室配方确保 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
||||
help:
|
||||
help: 帮助
|
||||
make: 尝试建造一个温室
|
||||
|
@ -79,7 +74,7 @@ help:
|
|||
recipe: 告知你如何制造一个温室
|
||||
opengui: 打开温室GUI
|
||||
list:
|
||||
title: '[温室建造指南]'
|
||||
title: "[温室建造指南]"
|
||||
info: 使用指令 /greenhouse recipe <number> 来查看建造每一个温室的细节
|
||||
error:
|
||||
greenhouseProtected: 温室已被保护
|
||||
|
@ -99,31 +94,28 @@ messages:
|
|||
removedmessage: 你的 [biome] 温室已经被移除!
|
||||
ecolost: 你位于 [location] 的温室生态环境遭到破坏,它已经不再是温室了.
|
||||
info:
|
||||
title: '&A[如何建造一个温室]'
|
||||
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n\
|
||||
&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗\
|
||||
\ \n&E来放置骨粉或雪\
|
||||
\ 来让作物自动生长.\n&E检查温室配方确保\
|
||||
\ 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
||||
info: '[温室信息]'
|
||||
title: "&A[如何建造一个温室]"
|
||||
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗 \n&E来放置骨粉或雪
|
||||
来让作物自动生长.\n&E检查温室配方确保 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
||||
info: "[温室信息]"
|
||||
none: 无
|
||||
nomore: '&4你无法建造更多的温室了!'
|
||||
onemore: '&6你可以再建造一个温室.'
|
||||
youcanbuild: '&A你最多能建造 [number] 个温室!'
|
||||
unlimited: '&A你能建造无限多个温室!'
|
||||
welcome: '&B你好! 点击这里获得更多提示'
|
||||
nomore: "&4你无法建造更多的温室了!"
|
||||
onemore: "&6你可以再建造一个温室."
|
||||
youcanbuild: "&A你最多能建造 [number] 个温室!"
|
||||
unlimited: "&A你能建造无限多个温室!"
|
||||
welcome: "&B你好! 点击这里获得更多提示"
|
||||
recipe:
|
||||
blockscolor: '&f'
|
||||
blockscolor: "&f"
|
||||
hint: 使用 /greenhouse list 来看见所有温室配方的编号!
|
||||
wrongnumber: 温室配方编号必须位于 1 与 [size] 之间
|
||||
title: '[[biome] 配方]'
|
||||
title: "[[biome] 配方]"
|
||||
nowater: 不允许有水.
|
||||
noice: 不允许有冰.
|
||||
nolava: 不允许有岩浆.
|
||||
watermustbe: 水在地面上的占比需要大于 [coverage]%.
|
||||
icemustbe: 冰在地面上的占比需要大于 [coverage]%.
|
||||
lavamustbe: 岩浆在地面上的占比需要大于 [coverage]%.
|
||||
minimumblockstitle: '[最少所需的方块]'
|
||||
minimumblockstitle: "[最少所需的方块]"
|
||||
nootherblocks: 没有其它必要的方块了.
|
||||
missing: 温室缺失了
|
||||
event:
|
||||
|
@ -142,8 +134,8 @@ reload:
|
|||
admininfo:
|
||||
error: 查看温室信息功能仅能在游戏中使用
|
||||
error2: 进入一个温室才能查看其信息.
|
||||
flags: '[Greenhouse Flags]'
|
||||
flags: "[Greenhouse Flags]"
|
||||
news:
|
||||
headline: '[温室新闻]'
|
||||
headline: "[温室新闻]"
|
||||
controlpanel:
|
||||
title: '&A温室'
|
||||
title: "&A温室"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
name: BentoBox-Greenhouses
|
||||
main: world.bentobox.greenhouses.GreenhousesPladdon
|
||||
version: ${project.version}${build.number}
|
||||
api-version: "1.19"
|
||||
|
||||
authors: [tastybento]
|
||||
contributors: ["The BentoBoxWorld Community"]
|
||||
website: https://bentobox.world
|
||||
description: ${project.description}
|
|
@ -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);
|
||||
|
|
|
@ -96,6 +96,8 @@ public class BiomeRecipeTest {
|
|||
when(gh.getCeilingHeight()).thenReturn(120);
|
||||
bb = new BoundingBox(10, 100, 10, 20, 120, 20);
|
||||
when(gh.getBoundingBox()).thenReturn(bb);
|
||||
BoundingBox ibb = bb.clone().expand(-1);
|
||||
when(gh.getInternalBoundingBox()).thenReturn(ibb);
|
||||
when(gh.getWorld()).thenReturn(world);
|
||||
when(gh.contains(any())).thenReturn(true);
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
||||
|
@ -149,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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,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.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -188,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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -213,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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -449,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));
|
||||
}
|
||||
|
||||
|
@ -475,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));
|
||||
}
|
||||
|
||||
|
@ -502,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);
|
||||
}
|
||||
|
@ -530,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);
|
||||
}
|
||||
|
@ -560,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);
|
||||
}
|
||||
|
@ -584,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -609,7 +611,7 @@ public class BiomeRecipeTest {
|
|||
@Test
|
||||
public void testGrowPlantNotAir() {
|
||||
when(block.getType()).thenReturn(Material.SOUL_SAND);
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true)));
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -619,7 +621,7 @@ public class BiomeRecipeTest {
|
|||
public void testGrowPlantNoPlants() {
|
||||
when(block.getType()).thenReturn(Material.AIR);
|
||||
when(block.isEmpty()).thenReturn(true);
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true)));
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -631,7 +633,7 @@ public class BiomeRecipeTest {
|
|||
when(block.getType()).thenReturn(Material.AIR);
|
||||
when(block.isEmpty()).thenReturn(true);
|
||||
assertTrue(br.addPlants(Material.BAMBOO_SAPLING, 100, Material.GRASS_BLOCK));
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true)));
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -647,7 +649,7 @@ public class BiomeRecipeTest {
|
|||
|
||||
when(block.getRelative(any())).thenReturn(ob);
|
||||
assertTrue(br.addPlants(Material.BAMBOO_SAPLING, 100, Material.GRASS_BLOCK));
|
||||
assertTrue(br.growPlant(new GrowthBlock(block, true)));
|
||||
assertTrue(br.growPlant(new GrowthBlock(block, true), false));
|
||||
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
||||
verify(block).setBlockData(eq(bd), eq(false));
|
||||
}
|
||||
|
@ -665,7 +667,7 @@ public class BiomeRecipeTest {
|
|||
|
||||
when(block.getRelative(any())).thenReturn(ob);
|
||||
assertTrue(br.addPlants(Material.SPORE_BLOSSOM, 100, Material.GLASS));
|
||||
assertTrue(br.growPlant(new GrowthBlock(block, false)));
|
||||
assertTrue(br.growPlant(new GrowthBlock(block, false), false));
|
||||
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
||||
verify(block).setBlockData(eq(bd), eq(false));
|
||||
}
|
||||
|
@ -684,7 +686,7 @@ public class BiomeRecipeTest {
|
|||
when(block.getRelative(any())).thenReturn(ob);
|
||||
assertTrue(br.addPlants(Material.SPORE_BLOSSOM, 100, Material.GLASS));
|
||||
// Not a ceiling block
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true)));
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -702,10 +704,10 @@ public class BiomeRecipeTest {
|
|||
when(block.getRelative(BlockFace.DOWN)).thenReturn(ob);
|
||||
when(block.getRelative(BlockFace.UP)).thenReturn(block);
|
||||
assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
||||
assertTrue(br.growPlant(new GrowthBlock(block, true)));
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -720,10 +722,10 @@ 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)));
|
||||
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -765,8 +767,8 @@ public class BiomeRecipeTest {
|
|||
*/
|
||||
@Test
|
||||
public void testSetType() {
|
||||
br.setType(Biome.BADLANDS_PLATEAU);
|
||||
assertEquals(Biome.BADLANDS_PLATEAU, br.getBiome());
|
||||
br.setType(Biome.BADLANDS);
|
||||
assertEquals(Biome.BADLANDS, br.getBiome());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -177,15 +175,15 @@ public class WallsTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(int, int, int, int, int)}.
|
||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(int, int, int, int, int, int)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetFloorYZeroY() {
|
||||
assertEquals(0, walls.getFloorY(10, 0, 1, 0, 1));
|
||||
assertEquals(-64, walls.getFloorY(10, 0, 1, 0, 1, -64));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(int, int, int, int, int)}.
|
||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(int, int, int, int, int, int)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetFloorY() {
|
||||
|
@ -193,7 +191,7 @@ public class WallsTest {
|
|||
Material.GLASS, Material.GLASS,
|
||||
Material.GLASS, Material.GLASS,
|
||||
Material.AIR);
|
||||
assertEquals(8, walls.getFloorY(10, 0, 1, 0, 1));
|
||||
assertEquals(8, walls.getFloorY(10, 0, 1, 0, 1, -64));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
|||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.junit.Before;
|
||||
|
@ -137,7 +138,7 @@ public class GreenhouseEventsTest {
|
|||
when(nextBlock.getLocation()).thenReturn(location);
|
||||
ItemStack item = mock(ItemStack.class);
|
||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||
ghe.onPlayerInteractInNether(e);
|
||||
verify(nextBlock).setType(Material.WATER);
|
||||
}
|
||||
|
@ -154,7 +155,7 @@ public class GreenhouseEventsTest {
|
|||
when(nextBlock.getLocation()).thenReturn(mock(Location.class));
|
||||
ItemStack item = mock(ItemStack.class);
|
||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||
ghe.onPlayerInteractInNether(e);
|
||||
verify(nextBlock, never()).setType(Material.WATER);
|
||||
}
|
||||
|
@ -170,7 +171,7 @@ public class GreenhouseEventsTest {
|
|||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||
ItemStack item = mock(ItemStack.class);
|
||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||
ghe.onPlayerInteractInNether(e);
|
||||
verify(nextBlock, never()).setType(Material.WATER);
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ public class GreenhouseEventsTest {
|
|||
when(nextBlock.getWorld()).thenReturn(world);
|
||||
ItemStack item = mock(ItemStack.class);
|
||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||
ghe.onPlayerInteractInNether(e);
|
||||
verify(nextBlock, never()).setType(Material.WATER);
|
||||
}
|
||||
|
@ -205,7 +206,7 @@ public class GreenhouseEventsTest {
|
|||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||
ItemStack item = mock(ItemStack.class);
|
||||
when(item.getType()).thenReturn(Material.ACACIA_BOAT);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER, item);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER, item, EquipmentSlot.HAND);
|
||||
ghe.onPlayerInteractInNether(e);
|
||||
verify(nextBlock, never()).setType(Material.WATER);
|
||||
}
|
||||
|
@ -222,7 +223,7 @@ public class GreenhouseEventsTest {
|
|||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||
ItemStack item = mock(ItemStack.class);
|
||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item);
|
||||
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||
ghe.onPlayerInteractInNether(e);
|
||||
verify(nextBlock, never()).setType(Material.WATER);
|
||||
}
|
||||
|
@ -296,7 +297,7 @@ public class GreenhouseEventsTest {
|
|||
ghe.onIceBreak(e);
|
||||
verify(block).setType(Material.AIR);
|
||||
assertTrue(e.isCancelled());
|
||||
verify(world).playSound(any(), eq(Sound.BLOCK_GLASS_BREAK), eq(1F), eq(1F));
|
||||
verify(world).playSound(any(Location.class), eq(Sound.BLOCK_GLASS_BREAK), eq(1F), eq(1F));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
package world.bentobox.greenhouses.managers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
@ -18,11 +26,14 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
import world.bentobox.greenhouses.managers.EcoSystemManager.GrowthBlock;
|
||||
|
||||
/**
|
||||
|
@ -30,7 +41,7 @@ import world.bentobox.greenhouses.managers.EcoSystemManager.GrowthBlock;
|
|||
*
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Bukkit.class, BentoBox.class})
|
||||
@PrepareForTest({Bukkit.class, BentoBox.class, Tag.class, RecipeManager.class})
|
||||
public class EcoSystemManagerTest {
|
||||
|
||||
private Greenhouse gh;
|
||||
|
@ -44,6 +55,8 @@ public class EcoSystemManagerTest {
|
|||
private Block liquid;
|
||||
@Mock
|
||||
private Block plant;
|
||||
@Mock
|
||||
private BiomeRecipe recipe;
|
||||
|
||||
// CUT
|
||||
private EcoSystemManager eco;
|
||||
|
@ -51,6 +64,12 @@ public class EcoSystemManagerTest {
|
|||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
PowerMockito.mockStatic(Tag.class, Mockito.RETURNS_MOCKS);
|
||||
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
||||
@SuppressWarnings("unchecked")
|
||||
Tag<Keyed> tag = mock(Tag.class);
|
||||
when(Bukkit.getTag(anyString(), any(), any())).thenReturn(tag);
|
||||
|
||||
gh = new Greenhouse();
|
||||
// 4x4x4 greenhouse
|
||||
BoundingBox bb = BoundingBox.of(new Vector(0,0,0), new Vector(6,5,6));
|
||||
|
@ -64,22 +83,28 @@ 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);
|
||||
PowerMockito.mockStatic(RecipeManager.class, Mockito.RETURNS_MOCKS);
|
||||
when(RecipeManager.getBiomeRecipies(any())).thenReturn(Optional.of(recipe));
|
||||
|
||||
|
||||
eco = new EcoSystemManager(null, null);
|
||||
}
|
||||
|
@ -123,6 +148,17 @@ public class EcoSystemManagerTest {
|
|||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(liquid);
|
||||
List<GrowthBlock> result = eco.getAvailableBlocks(gh, false);
|
||||
assertEquals(16, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksAllLiquid2() {
|
||||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(liquid);
|
||||
List<GrowthBlock> result = eco.getAvailableBlocks(gh, true);
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
|
@ -184,4 +220,57 @@ public class EcoSystemManagerTest {
|
|||
assertEquals(liquid, value.block());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#addMobs(Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testAddMobsChunkNotLoaded() {
|
||||
assertFalse(eco.addMobs(gh));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#addMobs(Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testAddMobsChunkLoadedNoMobs() {
|
||||
when(world.isChunkLoaded(anyInt(), anyInt())).thenReturn(true);
|
||||
assertFalse(eco.addMobs(gh));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#addMobs(Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testAddMobsChunkLoadedWithMobsInRecipeMaxMobsZero() {
|
||||
when(world.isChunkLoaded(anyInt(), anyInt())).thenReturn(true);
|
||||
when(recipe.noMobs()).thenReturn(false);
|
||||
assertFalse(eco.addMobs(gh));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#addMobs(Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testAddMobsChunkLoadedWithMobsInRecipeMaxMobsNotZero() {
|
||||
// Nothing spawned here
|
||||
when(world.isChunkLoaded(anyInt(), anyInt())).thenReturn(true);
|
||||
when(recipe.noMobs()).thenReturn(false);
|
||||
when(recipe.getMaxMob()).thenReturn(10);
|
||||
assertFalse(eco.addMobs(gh));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#addMobs(Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testAddMobsSpawnMob() {
|
||||
// Nothing spawned here
|
||||
when(world.isChunkLoaded(anyInt(), anyInt())).thenReturn(true);
|
||||
when(recipe.noMobs()).thenReturn(false);
|
||||
when(recipe.getMaxMob()).thenReturn(10);
|
||||
when(recipe.spawnMob(any())).thenReturn(true);
|
||||
assertTrue(eco.addMobs(gh));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue