mirror of
https://github.com/BentoBoxWorld/Greenhouses.git
synced 2024-09-28 22:57:34 +02:00
Compare commits
122 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
359354737f | ||
|
a51e9860f5 | ||
|
93e3152efc | ||
|
0fc5857a4a | ||
|
d1e771bad6 | ||
|
04a519ad51 | ||
|
3fc14f5cd8 | ||
|
8ce5cc0e3c | ||
|
15c2cea475 | ||
|
4084876c4b | ||
|
a7eeef7edc | ||
|
ca4f1a3f43 | ||
|
6bc1c5e4bc | ||
|
53cb40e7c4 | ||
|
e05e2806fe | ||
|
02c2135501 | ||
|
605144e9f9 | ||
|
3f4647b547 | ||
|
e75780e710 | ||
|
7e4f0764e6 | ||
|
398c8e91d5 | ||
|
2eed3dcd56 | ||
|
3dd950459f | ||
|
cce4a655c6 | ||
|
a2c2975329 | ||
|
e6a1cd17bb | ||
|
5fd9cbfd36 | ||
|
db5ef4d5da | ||
|
ac1d6e6638 | ||
|
3740268dfc | ||
|
308dc225cd | ||
|
95474d6c53 | ||
|
d2801dcd75 | ||
|
e4bbb70acb | ||
|
a4fc49689b | ||
|
66270cf3e7 | ||
|
4351247de2 | ||
|
9e407e659e | ||
|
d6df904fbc | ||
|
9af8816995 | ||
|
ce0eeae546 | ||
|
cf276bbb24 | ||
|
de6a939bb9 | ||
|
10a1d63778 | ||
|
bba0b33133 | ||
|
4b69c39496 | ||
|
fe0a794e68 | ||
|
1975df2732 | ||
|
1f0b579d5a | ||
|
e5c62047ff | ||
|
02490d3b85 | ||
|
717903e346 | ||
|
61478ff4d5 | ||
|
a96d4d4c67 | ||
|
8af2b2057d | ||
|
6f6745e849 | ||
|
0a016c2eaa | ||
|
d64be1c518 | ||
|
e2b779a9cb | ||
|
06230e4957 | ||
|
0e76838721 | ||
|
9a7cad85af | ||
|
5808c5933a | ||
|
cf7b1c7164 | ||
|
c5b80b2f4a | ||
|
b90559122b | ||
|
df60720e75 | ||
|
6e41588405 | ||
|
b7c30cb608 | ||
|
925e50eb46 | ||
|
61e1db5f43 | ||
|
024b311180 | ||
|
4aec983c81 | ||
|
c660575456 | ||
|
354806c060 | ||
|
47bead9145 | ||
|
8a3e0eb403 | ||
|
4708a70e24 | ||
|
308cb7f16a | ||
|
818f6fc925 | ||
|
0b9019fbfa | ||
|
e61e76134b | ||
|
a44d9d1578 | ||
|
38de645e6b | ||
|
de4a4c17c0 | ||
|
d1d3004262 | ||
|
db3054ab0c | ||
|
9621b2f5eb | ||
|
7154877f14 | ||
|
80c985ad7d | ||
|
f345496a6c | ||
|
19cd685900 | ||
|
999ea07ef0 | ||
|
29f04ef673 | ||
|
f2faeb71df | ||
|
69818923fc | ||
|
54f956cf23 | ||
|
88b655ee00 | ||
|
0e2a6159c5 | ||
|
39a88a4f84 | ||
|
b0a0ae6e88 | ||
|
a8dec9a89b | ||
|
79d1c743c1 | ||
|
63e6a5d3b0 | ||
|
8118280129 | ||
|
01a5548119 | ||
|
0397f8fcfa | ||
|
1e83703f9b | ||
|
07763cafdf | ||
|
5c583284ff | ||
|
b90cba0b60 | ||
|
148c92ecf8 | ||
|
27df88aaf3 | ||
|
cd5a0ce2a1 | ||
|
baa933881d | ||
|
ff487a7990 | ||
|
cc114027da | ||
|
08e9c25172 | ||
|
2ccb25e3fc | ||
|
5a4d1a35c3 | ||
|
fad9936e24 | ||
|
7dd9212797 |
38
.github/workflows/build.yml
vendored
Normal file
38
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: Build
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
|
java-version: 17
|
||||||
|
- name: Cache SonarCloud packages
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.sonar/cache
|
||||||
|
key: ${{ runner.os }}-sonar
|
||||||
|
restore-keys: ${{ runner.os }}-sonar
|
||||||
|
- name: Cache Maven packages
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.m2
|
||||||
|
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||||
|
restore-keys: ${{ runner.os }}-m2
|
||||||
|
- name: Build and analyze
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||||
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
|
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/target/
|
||||||
|
/.classpath
|
||||||
|
/.project
|
||||||
|
/.DS_Store
|
||||||
|
/Greenhouses-addon.iml
|
||||||
|
/.idea/
|
17
.travis.yml
17
.travis.yml
@ -1,17 +0,0 @@
|
|||||||
language: java
|
|
||||||
sudo: false
|
|
||||||
addons:
|
|
||||||
sonarcloud:
|
|
||||||
organization: "bentobox-world"
|
|
||||||
|
|
||||||
jdk:
|
|
||||||
- openjdk11
|
|
||||||
|
|
||||||
script:
|
|
||||||
# the following command line builds the project, runs the tests with coverage and then execute the SonarCloud analysis
|
|
||||||
- mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install sonar:sonar -Dsonar.projectKey=BentoBoxWorld_Greenhouses
|
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- '$HOME/.m2/repository'
|
|
||||||
- '$HOME/.sonar/cache'
|
|
13
README.md
13
README.md
@ -1,8 +1,9 @@
|
|||||||
# Greenhouses - an add-on for BentoBox
|
# Greenhouses - an add-on for BentoBox
|
||||||
|
|
||||||
## Note for 1.15.x + servers
|
[![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)
|
||||||
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!
|
[![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
|
## 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)
|
* Craft your own self-contained biome greenhouse on an island (or elsewhere if you like)
|
||||||
* Greenhouses can grow plants that cannot normally be grown, like sunflowers
|
* Greenhouses can grow plants that cannot normally be grown, like sunflowers
|
||||||
* Friendly mobs can spawn if your greenhouse is well designed - need slimes? Build a swamp greenhouse!
|
* Friendly mobs can spawn if your greenhouse is well-designed - need slimes? Build a swamp greenhouse!
|
||||||
* Blocks change in biomes over time - dirt becomes sand in a desert, dirt becomes clay in a river, for example.
|
* Blocks change in biomes over time - dirt becomes sand in a desert, dirt becomes clay in a river, for example.
|
||||||
* Greenhouses can run in multiple worlds.
|
* Greenhouses can run in multiple worlds.
|
||||||
* Easy to use GUI shows greenhouse recipes (e.g. **/is greenhouses**)
|
* Easy to use GUI shows greenhouse recipes (e.g. **/is greenhouses**)
|
||||||
@ -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.
|
1. Make glass blocks and build a rectangular set of walls with a flat roof.
|
||||||
2. Put a hopper in the wall or roof.
|
2. Put a hopper in the wall or roof.
|
||||||
3. Put a door in the wall so you can get in and out.
|
3. Put a door in the wall, so you can get in and out.
|
||||||
4. Type **/island greenhouses** and read the rules for the greenhouse you want.
|
4. Type **/island greenhouses** and read the rules for the greenhouse you want.
|
||||||
5. Exit the GUI and place blocks, water, lava, and ice so that you make your desired biome.
|
5. Exit the GUI and place blocks, water, lava, and ice so that you make your desired biome.
|
||||||
6. Type **/island greenhouses** again and click on the biome to make it.
|
6. Type **/island greenhouses** again and click on the biome to make it.
|
||||||
@ -41,7 +42,7 @@ This example is for when you are in the BSkyBlock world. For AcidIsland, just us
|
|||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
* Can I use stained glass? Yes, you can. It's pretty.
|
* Can I use stained-glass? Yes, you can. It's pretty.
|
||||||
* Can I fill my greenhouse full of water? Yes. That's an ocean.
|
* Can I fill my greenhouse full of water? Yes. That's an ocean.
|
||||||
* Will a squid spawn there? Maybe... okay, yes it will if it's a big enough ocean.
|
* Will a squid spawn there? Maybe... okay, yes it will if it's a big enough ocean.
|
||||||
* How do I place a door high up in the wall if the wall is all glass? Place it on a hopper.
|
* How do I place a door high up in the wall if the wall is all glass? Place it on a hopper.
|
||||||
|
71
pom.xml
71
pom.xml
@ -43,16 +43,19 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>17</java.version>
|
||||||
<powermock.version>2.0.2</powermock.version>
|
<powermock.version>2.0.9</powermock.version>
|
||||||
<!-- More visible way how to change dependency versions -->
|
<!-- More visible way how to change dependency versions -->
|
||||||
<spigot.version>1.16.3-R0.1-SNAPSHOT</spigot.version>
|
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
|
||||||
<bentobox.version>1.15.4</bentobox.version>
|
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
|
||||||
<!-- Revision variable removes warning about dynamic version -->
|
<!-- Revision variable removes warning about dynamic version -->
|
||||||
<revision>${build.version}-SNAPSHOT</revision>
|
<revision>${build.version}-SNAPSHOT</revision>
|
||||||
<!-- This allows to change between versions and snapshots. -->
|
<!-- This allows to change between versions and snapshots. -->
|
||||||
<build.version>1.4.2</build.version>
|
<build.version>1.8.0</build.version>
|
||||||
<build.number>-LOCAL</build.number>
|
<build.number>-LOCAL</build.number>
|
||||||
|
<sonar.projectKey>BentoBoxWorld_Greenhouses</sonar.projectKey>
|
||||||
|
<sonar.organization>bentobox-world</sonar.organization>
|
||||||
|
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
@ -93,30 +96,6 @@
|
|||||||
<build.number></build.number>
|
<build.number></build.number>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
|
||||||
<id>sonar</id>
|
|
||||||
<properties>
|
|
||||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
|
||||||
<sonar.organization>bentobox-world</sonar.organization>
|
|
||||||
</properties>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
|
||||||
<artifactId>sonar-maven-plugin</artifactId>
|
|
||||||
<version>3.7.0.1746</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>sonar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -147,7 +126,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.11.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -206,14 +185,21 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.7.0</version>
|
<version>3.7.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>${java.version}</source>
|
<release>${java.version}</release>
|
||||||
<target>${java.version}</target>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.22.0</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
|
||||||
|
</argLine>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
@ -228,10 +214,12 @@
|
|||||||
<show>public</show>
|
<show>public</show>
|
||||||
<failOnError>false</failOnError>
|
<failOnError>false</failOnError>
|
||||||
<additionalJOption>-Xdoclint:none</additionalJOption>
|
<additionalJOption>-Xdoclint:none</additionalJOption>
|
||||||
|
<javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-javadocs</id>
|
<id>attach-javadocs</id>
|
||||||
|
<phase>install</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>jar</goal>
|
<goal>jar</goal>
|
||||||
</goals>
|
</goals>
|
||||||
@ -264,27 +252,34 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>0.8.3</version>
|
<version>0.8.10</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<append>true</append>
|
<append>true</append>
|
||||||
<excludes>
|
<excludes>
|
||||||
<!-- This is required to prevent Jacoco from adding synthetic fields
|
<!-- This is required to prevent Jacoco from adding
|
||||||
to a JavaBean class (causes errors in testing) -->
|
synthetic fields to a JavaBean class (causes errors in testing) -->
|
||||||
<exclude>**/*Names*</exclude>
|
<exclude>**/*Names*</exclude>
|
||||||
|
<!-- Prevents the Material is too large to mock error -->
|
||||||
|
<exclude>org/bukkit/Material*</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>pre-unit-test</id>
|
<id>prepare-agent</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>prepare-agent</goal>
|
<goal>prepare-agent</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<id>post-unit-test</id>
|
<id>report</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>report</goal>
|
<goal>report</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<formats>
|
||||||
|
<format>XML</format>
|
||||||
|
</formats>
|
||||||
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
@ -11,6 +11,7 @@ import world.bentobox.bentobox.api.configuration.Config;
|
|||||||
import world.bentobox.bentobox.api.flags.Flag;
|
import world.bentobox.bentobox.api.flags.Flag;
|
||||||
import world.bentobox.bentobox.api.flags.Flag.Mode;
|
import world.bentobox.bentobox.api.flags.Flag.Mode;
|
||||||
import world.bentobox.bentobox.api.flags.Flag.Type;
|
import world.bentobox.bentobox.api.flags.Flag.Type;
|
||||||
|
import world.bentobox.greenhouses.greenhouse.Walls;
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseManager;
|
import world.bentobox.greenhouses.managers.GreenhouseManager;
|
||||||
import world.bentobox.greenhouses.managers.RecipeManager;
|
import world.bentobox.greenhouses.managers.RecipeManager;
|
||||||
import world.bentobox.greenhouses.ui.user.UserCommand;
|
import world.bentobox.greenhouses.ui.user.UserCommand;
|
||||||
@ -28,19 +29,13 @@ public class Greenhouses extends Addon {
|
|||||||
public static final Flag GREENHOUSES = new Flag.Builder("GREENHOUSE", Material.GREEN_STAINED_GLASS)
|
public static final Flag GREENHOUSES = new Flag.Builder("GREENHOUSE", Material.GREEN_STAINED_GLASS)
|
||||||
.mode(Mode.BASIC)
|
.mode(Mode.BASIC)
|
||||||
.type(Type.PROTECTION).build();
|
.type(Type.PROTECTION).build();
|
||||||
private static Greenhouses instance;
|
|
||||||
private final Config<Settings> config;
|
private final Config<Settings> config;
|
||||||
|
|
||||||
public static Greenhouses getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public Greenhouses() {
|
public Greenhouses() {
|
||||||
super();
|
super();
|
||||||
instance = this;
|
|
||||||
config = new Config<>(this, Settings.class);
|
config = new Config<>(this, Settings.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,9 +87,8 @@ public class Greenhouses extends Addon {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
if (manager != null) {
|
if (manager != null && manager.getEcoMgr() != null) {
|
||||||
manager.saveGreenhouses();
|
manager.getEcoMgr().cancel();
|
||||||
if (manager.getEcoMgr() != null) manager.getEcoMgr().cancel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,4 +117,15 @@ public class Greenhouses extends Addon {
|
|||||||
return activeWorlds;
|
return activeWorlds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if material is a wall material
|
||||||
|
* @param m - material
|
||||||
|
* @return true if wall material
|
||||||
|
*/
|
||||||
|
public boolean wallBlocks(Material m) {
|
||||||
|
return Walls.WALL_BLOCKS.contains(m)
|
||||||
|
|| (m.equals(Material.GLOWSTONE) && getSettings().isAllowGlowstone())
|
||||||
|
|| (m.name().endsWith("GLASS_PANE") && getSettings().isAllowPanes());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
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
|
||||||
|
{
|
||||||
|
private Addon addon;
|
||||||
|
@Override
|
||||||
|
public Addon getAddon()
|
||||||
|
{
|
||||||
|
if (addon == null) {
|
||||||
|
addon = new Greenhouses();
|
||||||
|
}
|
||||||
|
return addon;
|
||||||
|
}
|
||||||
|
}
|
@ -23,10 +23,13 @@ public class Settings implements ConfigObject {
|
|||||||
@ConfigEntry(path = "greenhouses.game-modes")
|
@ConfigEntry(path = "greenhouses.game-modes")
|
||||||
private List<String> gameModes = new ArrayList<>();
|
private List<String> gameModes = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
@ConfigComment("")
|
||||||
@ConfigComment("Show loaded recipe details during startup of server")
|
@ConfigComment("Show loaded recipe details during startup of server")
|
||||||
@ConfigEntry(path = "greenhouses.startup-log")
|
@ConfigEntry(path = "greenhouses.startup-log")
|
||||||
private boolean startupLog = false;
|
private boolean startupLog = false;
|
||||||
|
|
||||||
|
@ConfigComment("")
|
||||||
@ConfigComment("Weather and ecosystem settings")
|
@ConfigComment("Weather and ecosystem settings")
|
||||||
@ConfigComment("How often it should snow in the g/h when the weather is raining, in seconds")
|
@ConfigComment("How often it should snow in the g/h when the weather is raining, in seconds")
|
||||||
@ConfigEntry(path = "greenhouses.snowspeed")
|
@ConfigEntry(path = "greenhouses.snowspeed")
|
||||||
@ -40,6 +43,7 @@ public class Settings implements ConfigObject {
|
|||||||
@ConfigEntry(path = "greenhouses.snowdensity")
|
@ConfigEntry(path = "greenhouses.snowdensity")
|
||||||
private double snowDensity = 0.1;
|
private double snowDensity = 0.1;
|
||||||
|
|
||||||
|
@ConfigComment("")
|
||||||
@ConfigComment("Biome activity")
|
@ConfigComment("Biome activity")
|
||||||
@ConfigComment("How often should greenhouse biomes be checked to make sure they are still valid")
|
@ConfigComment("How often should greenhouse biomes be checked to make sure they are still valid")
|
||||||
@ConfigEntry(path = "greenhouses.ecotick")
|
@ConfigEntry(path = "greenhouses.ecotick")
|
||||||
@ -56,6 +60,7 @@ public class Settings implements ConfigObject {
|
|||||||
private int mobTick = 5;
|
private int mobTick = 5;
|
||||||
|
|
||||||
|
|
||||||
|
@ConfigComment("")
|
||||||
@ConfigComment("Default settings for greenhouse actions")
|
@ConfigComment("Default settings for greenhouse actions")
|
||||||
@ConfigComment("Allow lava or water to flow out of a greenhouse, e.g. through the door, floor")
|
@ConfigComment("Allow lava or water to flow out of a greenhouse, e.g. through the door, floor")
|
||||||
@ConfigEntry(path = "greenhouses.allowflowout")
|
@ConfigEntry(path = "greenhouses.allowflowout")
|
||||||
@ -64,10 +69,15 @@ public class Settings implements ConfigObject {
|
|||||||
@ConfigEntry(path = "greenhouses.allowflowin")
|
@ConfigEntry(path = "greenhouses.allowflowin")
|
||||||
private boolean allowFlowIn;
|
private boolean allowFlowIn;
|
||||||
|
|
||||||
|
@ConfigComment("")
|
||||||
@ConfigComment("Allow glowstone to be used as well as glass in roof and walls")
|
@ConfigComment("Allow glowstone to be used as well as glass in roof and walls")
|
||||||
@ConfigEntry(path = "greenhouses.allowglowstone")
|
@ConfigEntry(path = "greenhouses.allowglowstone")
|
||||||
private boolean allowGlowstone = true;
|
private boolean allowGlowstone = true;
|
||||||
|
|
||||||
|
@ConfigComment("")
|
||||||
|
@ConfigComment("Allow glass panes to be used to build greenhouses")
|
||||||
|
@ConfigEntry(path = "greenhouses.allowpanes")
|
||||||
|
private boolean allowPanes = true;
|
||||||
/**
|
/**
|
||||||
* @return the gameModes
|
* @return the gameModes
|
||||||
*/
|
*/
|
||||||
@ -212,5 +222,17 @@ public class Settings implements ConfigObject {
|
|||||||
public void setAllowGlowstone(boolean allowGlowstone) {
|
public void setAllowGlowstone(boolean allowGlowstone) {
|
||||||
this.allowGlowstone = allowGlowstone;
|
this.allowGlowstone = allowGlowstone;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @return the allowPanes
|
||||||
|
*/
|
||||||
|
public boolean isAllowPanes() {
|
||||||
|
return allowPanes;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param allowPanes the allowPanes to set
|
||||||
|
*/
|
||||||
|
public void setAllowPanes(boolean allowPanes) {
|
||||||
|
this.allowPanes = allowPanes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package world.bentobox.greenhouses.data;
|
package world.bentobox.greenhouses.data;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -8,6 +10,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.util.BoundingBox;
|
import org.bukkit.util.BoundingBox;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
@ -50,6 +53,12 @@ public class Greenhouse implements DataObject {
|
|||||||
*/
|
*/
|
||||||
public Greenhouse() {}
|
public Greenhouse() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a greenhouse
|
||||||
|
* @param world - world
|
||||||
|
* @param walls - wall object
|
||||||
|
* @param ceilingHeight - ceiling height
|
||||||
|
*/
|
||||||
public Greenhouse(World world, Walls walls, int ceilingHeight) {
|
public Greenhouse(World world, Walls walls, int ceilingHeight) {
|
||||||
this.location = new Location(world, walls.getMinX(), walls.getFloor(), walls.getMinZ());
|
this.location = new Location(world, walls.getMinX(), walls.getFloor(), walls.getMinZ());
|
||||||
Location location2 = new Location(world, walls.getMaxX() + 1D, ceilingHeight + 1D, walls.getMaxZ() + 1D);
|
Location location2 = new Location(world, walls.getMaxX() + 1D, ceilingHeight + 1D, walls.getMaxZ() + 1D);
|
||||||
@ -147,18 +156,30 @@ public class Greenhouse implements DataObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param roofHopperLocation the roofHopperLocation to set
|
* @param v the roofHopperLocation to set
|
||||||
*/
|
*/
|
||||||
public void setRoofHopperLocation(Location roofHopperLocation) {
|
public void setRoofHopperLocation(@Nullable Vector v) {
|
||||||
this.roofHopperLocation = roofHopperLocation;
|
if (v == null || getWorld() == null) {
|
||||||
|
this.roofHopperLocation = null;
|
||||||
|
} else {
|
||||||
|
this.roofHopperLocation = v.toLocation(getWorld());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the boundingBox
|
* @return the boundingBox
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@NonNull
|
||||||
public BoundingBox getBoundingBox() {
|
public BoundingBox getBoundingBox() {
|
||||||
return boundingBox;
|
return Objects.requireNonNull(boundingBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a bounding box of the greenhouse that does not include the walls or roof
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public BoundingBox getInternalBoundingBox() {
|
||||||
|
return getBoundingBox().clone().expand(-1D);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,9 +209,9 @@ public class Greenhouse implements DataObject {
|
|||||||
/**
|
/**
|
||||||
* @return the world
|
* @return the world
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@Nullable
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
return this.getLocation().getWorld();
|
return this.getLocation() == null ? null : this.getLocation().getWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +220,9 @@ public class Greenhouse implements DataObject {
|
|||||||
* @return true if inside the greenhouse
|
* @return true if inside the greenhouse
|
||||||
*/
|
*/
|
||||||
public boolean contains(Location location2) {
|
public boolean contains(Location location2) {
|
||||||
return location.getWorld().equals(location2.getWorld()) && boundingBox.contains(location2.toVector());
|
return getLocation() != null && getLocation().getWorld() != null
|
||||||
|
&& getLocation().getWorld().equals(location2.getWorld())
|
||||||
|
&& getBoundingBox().contains(location2.toVector());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,11 +236,11 @@ public class Greenhouse implements DataObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the biome recipe for this greenhouse
|
* Get the biome recipe for this greenhouse
|
||||||
* @return biome recipe or null
|
* @return biome recipe or a degenerate recipe
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@NonNull
|
||||||
public BiomeRecipe getBiomeRecipe() {
|
public BiomeRecipe getBiomeRecipe() {
|
||||||
return RecipeManager.getBiomeRecipies(biomeRecipeName).orElse(null);
|
return RecipeManager.getBiomeRecipies(biomeRecipeName).orElse(new BiomeRecipe());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -230,8 +253,24 @@ public class Greenhouse implements DataObject {
|
|||||||
/**
|
/**
|
||||||
* @return the missingBlocks
|
* @return the missingBlocks
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@NonNull
|
||||||
public Map<Material, Integer> getMissingBlocks() {
|
public Map<Material, Integer> getMissingBlocks() {
|
||||||
return missingBlocks;
|
return Objects.requireNonNullElseGet(missingBlocks, HashMap::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a location is a wall or roof block
|
||||||
|
* @param l - location
|
||||||
|
* @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)bb.getMinX()
|
||||||
|
|| l.getBlockX() == (int)bb.getMaxX() - 1
|
||||||
|
|| l.getBlockZ() == (int)bb.getMinZ()
|
||||||
|
|| l.getBlockZ() == (int)bb.getMaxZ() - 1
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
package world.bentobox.greenhouses.greenhouse;
|
package world.bentobox.greenhouses.greenhouse;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
@ -21,11 +25,13 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.Bisected;
|
import org.bukkit.block.data.Bisected;
|
||||||
import org.bukkit.block.data.BlockData;
|
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.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Hoglin;
|
import org.bukkit.entity.Hoglin;
|
||||||
import org.bukkit.entity.Piglin;
|
import org.bukkit.entity.Piglin;
|
||||||
import org.bukkit.util.BoundingBox;
|
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import com.google.common.base.Enums;
|
import com.google.common.base.Enums;
|
||||||
@ -35,7 +41,9 @@ import com.google.common.collect.Multimap;
|
|||||||
import world.bentobox.bentobox.util.Util;
|
import world.bentobox.bentobox.util.Util;
|
||||||
import world.bentobox.greenhouses.Greenhouses;
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
import world.bentobox.greenhouses.data.Greenhouse;
|
import world.bentobox.greenhouses.data.Greenhouse;
|
||||||
|
import world.bentobox.greenhouses.managers.EcoSystemManager.GrowthBlock;
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
||||||
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
|
|
||||||
public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
||||||
private static final String CHANCE_FOR = "% chance for ";
|
private static final String CHANCE_FOR = "% chance for ";
|
||||||
@ -46,13 +54,37 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
private String name;
|
private String name;
|
||||||
private String friendlyName;
|
private String friendlyName;
|
||||||
|
|
||||||
|
private static final List<Material> CEILING_PLANTS = new ArrayList<>();
|
||||||
|
static {
|
||||||
|
CEILING_PLANTS.add(Material.VINE);
|
||||||
|
Enums.getIfPresent(Material.class, "SPORE_BLOSSOM").toJavaUtil().ifPresent(CEILING_PLANTS::add);
|
||||||
|
Enums.getIfPresent(Material.class, "CAVE_VINES_PLANT").toJavaUtil().ifPresent(CEILING_PLANTS::add);
|
||||||
|
Enums.getIfPresent(Material.class, "TWISTING_VINES_PLANT").toJavaUtil().ifPresent(CEILING_PLANTS::add);
|
||||||
|
Enums.getIfPresent(Material.class, "WEEPING_VINES_PLANT").toJavaUtil().ifPresent(CEILING_PLANTS::add);
|
||||||
|
}
|
||||||
|
|
||||||
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> 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
|
// Content requirements
|
||||||
// Material, Type, Qty. There can be more than one type of material required
|
// Material, Type, Qty. There can be more than one type of material required
|
||||||
private final Map<Material, Integer> requiredBlocks = new EnumMap<>(Material.class);
|
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> plantTree = new TreeMap<>();
|
||||||
|
private final TreeMap<Double, GreenhousePlant> underwaterPlants = new TreeMap<>();
|
||||||
|
|
||||||
// Mobs
|
// Mobs
|
||||||
// Entity Type, Material to Spawn on, Probability
|
// Entity Type, Material to Spawn on, Probability
|
||||||
@ -60,8 +92,7 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
|
|
||||||
// Conversions
|
// Conversions
|
||||||
// Original Material, Original Type, New Material, New Type, Probability
|
// Original Material, Original Type, New Material, New Type, Probability
|
||||||
//private final Map<Material, GreenhouseBlockConversions> conversionBlocks = new EnumMap<>(Material.class);
|
private final Multimap<Material, GreenhouseBlockConversions> conversionBlocks = ArrayListMultimap.create();
|
||||||
private Multimap<Material, GreenhouseBlockConversions> conversionBlocks = ArrayListMultimap.create();
|
|
||||||
|
|
||||||
private int mobLimit;
|
private int mobLimit;
|
||||||
private int waterCoverage;
|
private int waterCoverage;
|
||||||
@ -70,8 +101,12 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
|
|
||||||
private String permission = "";
|
private String permission = "";
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
|
private int maxMob;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a degenerate recipe with nothing in it
|
||||||
|
*/
|
||||||
public BiomeRecipe() {}
|
public BiomeRecipe() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +139,7 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mobType - entity type
|
* @param mobType - entity type
|
||||||
* @param mobProbability - reltive probability
|
* @param mobProbability - relative probability
|
||||||
* @param mobSpawnOn - material to spawn on
|
* @param mobSpawnOn - material to spawn on
|
||||||
* @return true if add is successful
|
* @return true if add is successful
|
||||||
*/
|
*/
|
||||||
@ -118,7 +153,7 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
mobTree.put(lastProb + probability, new GreenhouseMob(mobType, mobSpawnOn));
|
mobTree.put(lastProb + probability, new GreenhouseMob(mobType, mobSpawnOn));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
addon.logError("Mob chances add up to > 100% in " + type.toString() + " biome recipe! Skipping " + mobType.toString());
|
addon.logError("Mob chances add up to > 100% in " + type.toString() + " biome recipe! Skipping " + mobType);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,11 +168,12 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
*/
|
*/
|
||||||
public boolean addPlants(Material plantMaterial, double plantProbability, Material plantGrowOn) {
|
public boolean addPlants(Material plantMaterial, double plantProbability, Material plantGrowOn) {
|
||||||
double probability = plantProbability/100;
|
double probability = plantProbability/100;
|
||||||
|
TreeMap<Double, GreenhousePlant> map = UNDERWATER_PLANTS.contains(plantMaterial) ? underwaterPlants : plantTree;
|
||||||
// Add up all the probabilities in the list so far
|
// 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) {
|
if ((1D - lastProb) >= probability) {
|
||||||
// Add to probability tree
|
// Add to probability tree
|
||||||
plantTree.put(lastProb + probability, new GreenhousePlant(plantMaterial, plantGrowOn));
|
map.put(lastProb + probability, new GreenhousePlant(plantMaterial, plantGrowOn));
|
||||||
} else {
|
} else {
|
||||||
addon.logError("Plant chances add up to > 100% in " + type.toString() + " biome recipe! Skipping " + plantMaterial.toString());
|
addon.logError("Plant chances add up to > 100% in " + type.toString() + " biome recipe! Skipping " + plantMaterial.toString());
|
||||||
return false;
|
return false;
|
||||||
@ -155,29 +191,48 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
startupLog(" " + blockMaterial + " x " + blockQty);
|
startupLog(" " + blockMaterial + " x " + blockQty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check required blocks
|
|
||||||
/**
|
/**
|
||||||
* Checks greenhouse meets recipe requirements.
|
* Checks greenhouse meets recipe requirements.
|
||||||
* @return GreenhouseResult - result
|
* @return GreenhouseResult - result
|
||||||
*/
|
*/
|
||||||
public Set<GreenhouseResult> checkRecipe(Greenhouse gh) {
|
public CompletableFuture<Set<GreenhouseResult>> checkRecipe(Greenhouse gh) {
|
||||||
Set<GreenhouseResult> result = new HashSet<>();
|
CompletableFuture<Set<GreenhouseResult>> r = new CompletableFuture<>();
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> checkRecipeAsync(r, gh));
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check greenhouse meets recipe requirements. Expected to be run async.
|
||||||
|
* @param r - future to complete when done
|
||||||
|
* @param gh - greenhouse
|
||||||
|
* @return set of results from the check
|
||||||
|
*/
|
||||||
|
private Set<GreenhouseResult> checkRecipeAsync(CompletableFuture<Set<GreenhouseResult>> r, Greenhouse gh) {
|
||||||
|
AsyncWorldCache cache = new AsyncWorldCache(addon, gh.getWorld());
|
||||||
long area = gh.getArea();
|
long area = gh.getArea();
|
||||||
Map<Material, Integer> blockCount = new EnumMap<>(Material.class);
|
|
||||||
// Look through the greenhouse and count what is in there
|
// Look through the greenhouse and count what is in there
|
||||||
for (int y = gh.getFloorHeight(); y< gh.getCeilingHeight();y++) {
|
Map<Material, Integer> blockCount = countBlocks(gh, cache);
|
||||||
for (int x = (int) (gh.getBoundingBox().getMinX()+1); x < gh.getBoundingBox().getMaxX(); x++) {
|
|
||||||
for (int z = (int) (gh.getBoundingBox().getMinZ()+1); z < gh.getBoundingBox().getMaxZ(); z++) {
|
// Calculate % water, ice and lava ratios and check them
|
||||||
Block b = gh.getWorld().getBlockAt(x, y, z);
|
Set<GreenhouseResult> result = checkRatios(blockCount, area);
|
||||||
Material t = b.getType();
|
|
||||||
if (!t.equals(Material.AIR)) {
|
// Compare to the required blocks
|
||||||
blockCount.putIfAbsent(t, 0);
|
Map<Material, Integer> missingBlocks = requiredBlocks.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - blockCount.getOrDefault(e.getKey(), 0)));
|
||||||
blockCount.merge(t, 1, Integer::sum);
|
// 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 Set<GreenhouseResult> checkRatios(Map<Material, Integer> blockCount, long area) {
|
||||||
// Calculate % water, ice and lava ratios
|
Set<GreenhouseResult> result = new HashSet<>();
|
||||||
double waterRatio = (double)blockCount.getOrDefault(Material.WATER, 0)/area * 100;
|
double waterRatio = (double)blockCount.getOrDefault(Material.WATER, 0)/area * 100;
|
||||||
double lavaRatio = (double)blockCount.getOrDefault(Material.LAVA, 0)/area * 100;
|
double lavaRatio = (double)blockCount.getOrDefault(Material.LAVA, 0)/area * 100;
|
||||||
int ice = blockCount.entrySet().stream().filter(en -> en.getKey().equals(Material.ICE)
|
int ice = blockCount.entrySet().stream().filter(en -> en.getKey().equals(Material.ICE)
|
||||||
@ -205,35 +260,55 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
if (iceCoverage > 0 && iceRatio < iceCoverage) {
|
if (iceCoverage > 0 && iceRatio < iceCoverage) {
|
||||||
result.add(GreenhouseResult.FAIL_INSUFFICIENT_ICE);
|
result.add(GreenhouseResult.FAIL_INSUFFICIENT_ICE);
|
||||||
}
|
}
|
||||||
// Compare to the required blocks
|
|
||||||
Map<Material, Integer> missingBlocks = requiredBlocks.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - blockCount.getOrDefault(e.getKey(), 0)));
|
|
||||||
// Remove any entries that are 0 or less
|
|
||||||
missingBlocks.values().removeIf(v -> v <= 0);
|
|
||||||
if (!missingBlocks.isEmpty()) {
|
|
||||||
result.add(GreenhouseResult.FAIL_INSUFFICIENT_BLOCKS);
|
|
||||||
gh.setMissingBlocks(missingBlocks);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<Material, Integer> countBlocks(Greenhouse gh, AsyncWorldCache cache) {
|
||||||
|
Map<Material, Integer> blockCount = new EnumMap<>(Material.class);
|
||||||
|
for (int y = gh.getFloorHeight(); y< gh.getCeilingHeight();y++) {
|
||||||
|
for (int x = (int) (gh.getBoundingBox().getMinX()+1); x < gh.getBoundingBox().getMaxX(); x++) {
|
||||||
|
for (int z = (int) (gh.getBoundingBox().getMinZ()+1); z < gh.getBoundingBox().getMaxZ(); z++) {
|
||||||
|
Material t = cache.getBlockType(x, y, z);
|
||||||
|
if (!t.equals(Material.AIR)) {
|
||||||
|
blockCount.putIfAbsent(t, 0);
|
||||||
|
blockCount.merge(t, 1, Integer::sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blockCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if block should be converted
|
* Check if block should be converted
|
||||||
* @param gh - greenhouse
|
|
||||||
* @param b - block to check
|
* @param b - block to check
|
||||||
*/
|
*/
|
||||||
public void convertBlock(Greenhouse gh, Block b) {
|
public void convertBlock(Block b) {
|
||||||
conversionBlocks.get(b.getType()).stream().filter(Objects::nonNull)
|
Material bType = b.getType();
|
||||||
.filter(bc -> random.nextDouble() < bc.getProbability())
|
// 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
|
||||||
.forEach(bc -> {
|
if(conversionBlocks.keySet().contains(bType)) {
|
||||||
// Check if the block is in the right area, up, down, n,s,e,w
|
for(GreenhouseBlockConversions conversionOption : conversionBlocks.get(bType)) {
|
||||||
if (ADJ_BLOCKS.stream().map(b::getRelative)
|
rollTheDice(b, conversionOption);
|
||||||
.filter(r -> gh.contains(r.getLocation()))
|
|
||||||
.map(Block::getType)
|
|
||||||
.anyMatch(m -> bc.getLocalMaterial() == null || m == bc.getLocalMaterial())) {
|
|
||||||
// Convert!
|
|
||||||
b.setType(bc.getNewMaterial());
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,28 +394,24 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
Location spawnLoc = b.getLocation().clone().add(new Vector(0.5, 0, 0.5));
|
Location spawnLoc = b.getLocation().clone().add(new Vector(0.5, 0, 0.5));
|
||||||
return getRandomMob()
|
return getRandomMob()
|
||||||
// Check if the spawn on block matches, if it exists
|
// Check if the spawn on block matches, if it exists
|
||||||
.filter(m -> m.getMobSpawnOn().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
|
// If spawn occurs, check if it can fit inside greenhouse
|
||||||
.map(m -> {
|
.map(m -> {
|
||||||
Entity entity = b.getWorld().spawnEntity(spawnLoc, m.getMobType());
|
Entity entity = b.getWorld().spawnEntity(spawnLoc, m.mobType());
|
||||||
if (entity != null) {
|
|
||||||
preventZombie(entity);
|
preventZombie(entity);
|
||||||
return addon
|
return addon
|
||||||
.getManager()
|
.getManager()
|
||||||
.getMap()
|
.getMap()
|
||||||
.getGreenhouse(b.getLocation()).map(gh -> {
|
.getGreenhouse(b.getLocation()).map(gh -> {
|
||||||
BoundingBox interior = gh.getBoundingBox().clone();
|
if (!gh.getInternalBoundingBox().contains(entity.getBoundingBox())) {
|
||||||
interior.expand(-1, -1, -1);
|
|
||||||
if (!interior.contains(entity.getBoundingBox())) {
|
|
||||||
entity.remove();
|
entity.remove();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).orElse(false);
|
}).orElse(false);
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}).orElse(false);
|
}).orElse(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -357,13 +428,11 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity instanceof Piglin) {
|
if (entity instanceof Piglin p) {
|
||||||
Piglin p = (Piglin)entity;
|
|
||||||
p.setImmuneToZombification(true);
|
p.setImmuneToZombification(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (entity instanceof Hoglin) {
|
if (entity instanceof Hoglin h) {
|
||||||
Hoglin h = (Hoglin)entity;
|
|
||||||
h.setImmuneToZombification(true);
|
h.setImmuneToZombification(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -377,18 +446,21 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
return key == null ? Optional.empty() : Optional.ofNullable(mobTree.get(key));
|
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
|
// Grow a random plant that can grow
|
||||||
double r = random.nextDouble();
|
double r = random.nextDouble();
|
||||||
Double key = plantTree.ceilingKey(r);
|
Double key = underwater ? underwaterPlants.ceilingKey(r) : plantTree.ceilingKey(r);
|
||||||
return key == null ? Optional.empty() : Optional.ofNullable(plantTree.get(key));
|
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
|
* @return a list of blocks that are required for this recipe
|
||||||
*/
|
*/
|
||||||
public List<String> getRecipeBlocks() {
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -400,19 +472,35 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Plants a plant on block bl if it makes sense.
|
* Plants a plant on block bl if it makes sense.
|
||||||
* @param bl - block
|
* @param block - block that can have growth
|
||||||
|
* @param underwater - if the block is underwater or not
|
||||||
* @return true if successful
|
* @return true if successful
|
||||||
*/
|
*/
|
||||||
public boolean growPlant(Block bl) {
|
public boolean growPlant(GrowthBlock block, boolean underwater) {
|
||||||
if (!bl.isEmpty()) {
|
Block bl = block.block();
|
||||||
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;
|
||||||
}
|
}
|
||||||
return getRandomPlant().map(p -> {
|
return false;
|
||||||
if (bl.getY() != 0 && p.getPlantGrownOn().map(m -> m.equals(bl.getRelative(BlockFace.DOWN).getType())).orElse(false)) {
|
}).orElse(false);
|
||||||
BlockData dataBottom = p.getPlantMaterial().createBlockData();
|
}
|
||||||
if (dataBottom instanceof Bisected) {
|
|
||||||
((Bisected) dataBottom).setHalf(Bisected.Half.BOTTOM);
|
/**
|
||||||
BlockData dataTop = p.getPlantMaterial().createBlockData();
|
* 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);
|
((Bisected) dataTop).setHalf(Bisected.Half.TOP);
|
||||||
if (bl.getRelative(BlockFace.UP).getType().equals(Material.AIR)) {
|
if (bl.getRelative(BlockFace.UP).getType().equals(Material.AIR)) {
|
||||||
bl.setBlockData(dataBottom, false);
|
bl.setBlockData(dataBottom, false);
|
||||||
@ -420,14 +508,121 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
} else {
|
} else {
|
||||||
return false; // No room
|
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 {
|
} else {
|
||||||
|
if (dataBottom instanceof Waterlogged wl) {
|
||||||
|
wl.setWaterlogged(underwater);
|
||||||
|
bl.setBlockData(wl, false);
|
||||||
|
} else {
|
||||||
|
// Single height plant
|
||||||
bl.setBlockData(dataBottom, false);
|
bl.setBlockData(dataBottom, false);
|
||||||
}
|
}
|
||||||
bl.getWorld().spawnParticle(Particle.SNOWBALL, bl.getLocation(), 10, 2, 2, 2);
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
// 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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}).orElse(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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -531,7 +726,22 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
|||||||
* @return the mob types that may spawn due to this recipe
|
* @return the mob types that may spawn due to this recipe
|
||||||
*/
|
*/
|
||||||
public Set<EntityType> getMobTypes() {
|
public Set<EntityType> getMobTypes() {
|
||||||
return mobTree.values().stream().map(GreenhouseMob::getMobType).collect(Collectors.toSet());
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,41 +2,4 @@ package world.bentobox.greenhouses.greenhouse;
|
|||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
class GreenhouseBlockConversions {
|
record GreenhouseBlockConversions (Material oldMaterial, Material newMaterial, double probability, Material localMaterial) { }
|
||||||
private final Material oldMaterial;
|
|
||||||
private final Material newMaterial;
|
|
||||||
private final double probability;
|
|
||||||
private final Material localMaterial;
|
|
||||||
|
|
||||||
public GreenhouseBlockConversions(Material oldMaterial, Material newMaterial, double probability, Material localMaterial) {
|
|
||||||
this.oldMaterial = oldMaterial;
|
|
||||||
this.newMaterial = newMaterial;
|
|
||||||
this.probability = probability;
|
|
||||||
this.localMaterial = localMaterial;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the oldMaterial
|
|
||||||
*/
|
|
||||||
public Material getOldMaterial() {
|
|
||||||
return oldMaterial;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the newMaterial
|
|
||||||
*/
|
|
||||||
public Material getNewMaterial() {
|
|
||||||
return newMaterial;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the probability
|
|
||||||
*/
|
|
||||||
public double getProbability() {
|
|
||||||
return probability;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the localMaterial
|
|
||||||
*/
|
|
||||||
public Material getLocalMaterial() {
|
|
||||||
return localMaterial;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -1,31 +1,6 @@
|
|||||||
package world.bentobox.greenhouses.greenhouse;
|
package world.bentobox.greenhouses.greenhouse;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
class GreenhouseMob {
|
record GreenhouseMob(EntityType mobType, Material mobSpawnOn) { }
|
||||||
private final EntityType mobType;
|
|
||||||
private final Material mobSpawnOn;
|
|
||||||
/**
|
|
||||||
* @param mobType - entity type of mob
|
|
||||||
* @param mobSpawnOn - material on which it much spawn, or null if any
|
|
||||||
*/
|
|
||||||
public GreenhouseMob(EntityType mobType, Material mobSpawnOn) {
|
|
||||||
this.mobType = mobType;
|
|
||||||
this.mobSpawnOn = mobSpawnOn;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the mobType
|
|
||||||
*/
|
|
||||||
public EntityType getMobType() {
|
|
||||||
return mobType;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the mobSpawnOn
|
|
||||||
*/
|
|
||||||
public Optional<Material> getMobSpawnOn() {
|
|
||||||
return Optional.of(mobSpawnOn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,32 +1,5 @@
|
|||||||
package world.bentobox.greenhouses.greenhouse;
|
package world.bentobox.greenhouses.greenhouse;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
class GreenhousePlant {
|
record GreenhousePlant(Material plantMaterial,Material plantGrownOn) { }
|
||||||
private final Material plantMaterial;
|
|
||||||
private final Material plantGrownOn;
|
|
||||||
/**
|
|
||||||
* Describes a recipe plant
|
|
||||||
* @param plantMaterial - material
|
|
||||||
* @param plantGrownOn - material on which this grows
|
|
||||||
*/
|
|
||||||
public GreenhousePlant(Material plantMaterial,Material plantGrownOn) {
|
|
||||||
this.plantMaterial = plantMaterial;
|
|
||||||
this.plantGrownOn = plantGrownOn;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the plantMaterial
|
|
||||||
*/
|
|
||||||
public Material getPlantMaterial() {
|
|
||||||
return plantMaterial;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the plantGrownOn
|
|
||||||
*/
|
|
||||||
public Optional<Material> getPlantGrownOn() {
|
|
||||||
return Optional.ofNullable(plantGrownOn);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -46,4 +46,11 @@ public abstract class MinMaxXZ {
|
|||||||
public int getArea() {
|
public int getArea() {
|
||||||
return (maxX - minX) * (maxZ - minZ);
|
return (maxX - minX) * (maxZ - minZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MinMaxXZ [minX=" + minX + ", maxX=" + maxX + ", minZ=" + minZ + ", maxZ=" + maxZ + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
package world.bentobox.greenhouses.greenhouse;
|
package world.bentobox.greenhouses.greenhouse;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.greenhouses.Greenhouses;
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the parameters of a greenhouse roof
|
* Contains the parameters of a greenhouse roof
|
||||||
@ -19,50 +24,119 @@ import world.bentobox.greenhouses.Greenhouses;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Roof extends MinMaxXZ {
|
public class Roof extends MinMaxXZ {
|
||||||
private static final List<Material> ROOF_BLOCKS;
|
private static final List<Material> ROOF_BLOCKS = Arrays.stream(Material.values())
|
||||||
static {
|
|
||||||
List<Material> r = Arrays.stream(Material.values())
|
|
||||||
.filter(Material::isBlock) // Blocks only, no items
|
.filter(Material::isBlock) // Blocks only, no items
|
||||||
.filter(m -> m.name().contains("TRAPDOOR") // All trapdoors
|
.filter(m -> Tag.TRAPDOORS.isTagged(m) // All trapdoors
|
||||||
|| m.name().contains("GLASS") // All glass blocks
|
|| (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks
|
||||||
|| m.equals(Material.HOPPER)) // Hoppers
|
|| m.equals(Material.HOPPER)).toList();
|
||||||
.collect(Collectors.toList());
|
private final AsyncWorldCache cache;
|
||||||
ROOF_BLOCKS = Collections.unmodifiableList(r);
|
|
||||||
}
|
|
||||||
private final Location location;
|
|
||||||
private int height;
|
private int height;
|
||||||
|
private final Location location;
|
||||||
private boolean roofFound;
|
private boolean roofFound;
|
||||||
|
private final Greenhouses addon;
|
||||||
|
private final World world;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a roof from a starting location under the roof and characterizes it
|
* Finds a roof from a starting location under the roof and characterizes it
|
||||||
|
* @param cache async world cache
|
||||||
* @param loc - starting location
|
* @param loc - starting location
|
||||||
*/
|
*/
|
||||||
public Roof(Location loc) {
|
public Roof(AsyncWorldCache cache, Location loc, Greenhouses addon) {
|
||||||
|
this.cache = cache;
|
||||||
this.location = loc;
|
this.location = loc;
|
||||||
roofFound = findRoof(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());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean findRoof(Location loc) {
|
/**
|
||||||
World world = loc.getWorld();
|
* This takes any location and tries to go as far as possible in NWSE directions finding contiguous roof blocks
|
||||||
|
* up to 100 in any direction
|
||||||
|
* @param vector - vector to start search
|
||||||
|
*/
|
||||||
|
private void expandCoords(Vector vector) {
|
||||||
|
Vector maxx = vector.clone();
|
||||||
|
Vector minx = vector.clone();
|
||||||
|
Vector maxz = vector.clone();
|
||||||
|
Vector minz = vector.clone();
|
||||||
|
int limit = 0;
|
||||||
|
while (roofBlocks(cache.getBlockType(maxx)) && limit < 100) {
|
||||||
|
limit++;
|
||||||
|
maxx.add(new Vector(1,0,0));
|
||||||
|
}
|
||||||
|
// Set Max x
|
||||||
|
if (maxx.getBlockX() - 1 > maxX) {
|
||||||
|
maxX = maxx.getBlockX() - 1;
|
||||||
|
}
|
||||||
|
limit = 0;
|
||||||
|
while (roofBlocks(cache.getBlockType(minx)) && limit < 100) {
|
||||||
|
limit++;
|
||||||
|
minx.subtract(new Vector(1,0,0));
|
||||||
|
}
|
||||||
|
if (minx.getBlockX() + 1 < minX) {
|
||||||
|
minX = minx.getBlockX() + 1;
|
||||||
|
}
|
||||||
|
limit = 0;
|
||||||
|
while (roofBlocks(cache.getBlockType(maxz)) && limit < 100) {
|
||||||
|
limit++;
|
||||||
|
maxz.add(new Vector(0,0,1));
|
||||||
|
}
|
||||||
|
if (maxz.getBlockZ() - 1 > maxZ) {
|
||||||
|
maxZ = maxz.getBlockZ() - 1;
|
||||||
|
}
|
||||||
|
limit = 0;
|
||||||
|
while (roofBlocks(cache.getBlockType(minz)) && limit < 100) {
|
||||||
|
limit++;
|
||||||
|
minz.subtract(new Vector(0,0,1));
|
||||||
|
}
|
||||||
|
if (minz.getBlockZ() + 1 < minZ) {
|
||||||
|
minZ = minz.getBlockZ() + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Boolean> findRoof() {
|
||||||
|
CompletableFuture<Boolean> r = new CompletableFuture<>();
|
||||||
|
Vector loc = location.toVector();
|
||||||
// This section tries to find a roof block
|
// This section tries to find a roof block
|
||||||
// Try just going up - this covers every case except if the player is standing under a hole
|
// Try just going up - this covers every case except if the player is standing under a hole
|
||||||
roofFound = false;
|
Bukkit.getScheduler().runTaskAsynchronously(BentoBox.getInstance(), () -> {
|
||||||
|
boolean found = findRoof(loc);
|
||||||
|
Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> r.complete(found));
|
||||||
|
});
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
// This does a ever-growing check around the player to find a wall block. It is possible for the player
|
boolean findRoof(Vector loc) {
|
||||||
|
// This does an ever-growing check around the player to find a wall block. It is possible for the player
|
||||||
// to be outside the greenhouse in this situation, so a check is done later to make sure the player is inside
|
// to be outside the greenhouse in this situation, so a check is done later to make sure the player is inside
|
||||||
int roofY = loc.getBlockY();
|
int startY = loc.getBlockY();
|
||||||
for (int y = roofY; y < world.getMaxHeight(); y++) {
|
for (int y = startY; y < world.getMaxHeight(); y++) {
|
||||||
if (roofBlocks(world.getBlockAt(loc.getBlockX(),y,loc.getBlockZ()).getType())) {
|
Vector v = new Vector(loc.getBlockX(),y,loc.getBlockZ());
|
||||||
|
if (roofBlocks(cache.getBlockType(v))) {
|
||||||
roofFound = true;
|
roofFound = true;
|
||||||
loc = new Location(world,loc.getBlockX(),y,loc.getBlockZ());
|
loc = v;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the roof was not found start going around in circles until something is found
|
// If the roof was not found start going around in circles until something is found
|
||||||
// Expand in ever increasing squares around location until a wall block is found
|
// Expand in ever-increasing squares around location until a wall block is found
|
||||||
spiralSearch(loc, roofY);
|
if (!roofFound) {
|
||||||
if (!roofFound) return false;
|
loc = spiralSearch(loc, startY);
|
||||||
|
if (!roofFound) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Record the height
|
// Record the height
|
||||||
this.height = loc.getBlockY();
|
this.height = loc.getBlockY();
|
||||||
// Now we have a roof block, find how far we can go NSWE
|
// Now we have a roof block, find how far we can go NSWE
|
||||||
@ -70,7 +144,7 @@ public class Roof extends MinMaxXZ {
|
|||||||
maxX = loc.getBlockX();
|
maxX = loc.getBlockX();
|
||||||
minZ = loc.getBlockZ();
|
minZ = loc.getBlockZ();
|
||||||
maxZ = loc.getBlockZ();
|
maxZ = loc.getBlockZ();
|
||||||
expandCoords(world, loc.toVector());
|
expandCoords(loc);
|
||||||
int minx;
|
int minx;
|
||||||
int maxx;
|
int maxx;
|
||||||
int minz;
|
int minz;
|
||||||
@ -84,7 +158,7 @@ public class Roof extends MinMaxXZ {
|
|||||||
for (int x = minx; x <= maxx; x++) {
|
for (int x = minx; x <= maxx; x++) {
|
||||||
for (int z = minz; z <= maxz; z++) {
|
for (int z = minz; z <= maxz; z++) {
|
||||||
// This will push out the coords if possible
|
// This will push out the coords if possible
|
||||||
expandCoords(world, new Vector(x, loc.getBlockY(), z));
|
expandCoords(new Vector(x, loc.getBlockY(), z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Repeat until nothing changes
|
// Repeat until nothing changes
|
||||||
@ -93,96 +167,6 @@ public class Roof extends MinMaxXZ {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spiralSearch(Location loc, int roofY) {
|
|
||||||
for (int radius = 0; radius < 3 && !roofFound; radius++) {
|
|
||||||
for (int x = loc.getBlockX() - radius; x <= loc.getBlockX() + radius && !roofFound; x++) {
|
|
||||||
for (int z = loc.getBlockZ() - radius; z <= loc.getBlockZ() + radius && !roofFound; z++) {
|
|
||||||
if (!((x > loc.getBlockX() - radius && x < loc.getBlockX() + radius) && (z > loc.getBlockZ() - radius && z < loc.getBlockZ() + radius))) {
|
|
||||||
checkVertically(loc, x, roofY, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkVertically(Location loc, int x, int roofY, int z) {
|
|
||||||
World world = loc.getWorld();
|
|
||||||
Block b = world.getBlockAt(x, roofY, z);
|
|
||||||
if (!Walls.wallBlocks(b.getType())) {
|
|
||||||
// Look up
|
|
||||||
for (int y = roofY; y < world.getMaxHeight() && !roofFound; y++) {
|
|
||||||
if (roofBlocks(world.getBlockAt(x,y,z).getType())) {
|
|
||||||
roofFound = true;
|
|
||||||
loc = new Location(world,x,y,z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This takes any location and tries to go as far as possible in NWSE directions finding contiguous roof blocks
|
|
||||||
* up to 100 in any direction
|
|
||||||
* @param height - location to start search
|
|
||||||
*/
|
|
||||||
private void expandCoords(World world, Vector height) {
|
|
||||||
Location maxx = height.toLocation(world);
|
|
||||||
Location minx = height.toLocation(world);
|
|
||||||
Location maxz = height.toLocation(world);
|
|
||||||
Location minz = height.toLocation(world);
|
|
||||||
int limit = 0;
|
|
||||||
while (ROOF_BLOCKS
|
|
||||||
.contains(world.getBlockAt(maxx).getType()) && limit < 100) {
|
|
||||||
limit++;
|
|
||||||
maxx.add(new Vector(1,0,0));
|
|
||||||
}
|
|
||||||
if (maxx.getBlockX()-1 > maxX) {
|
|
||||||
maxX = maxx.getBlockX()-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (roofBlocks(world.getBlockAt(minx).getType()) && limit < 200) {
|
|
||||||
limit++;
|
|
||||||
minx.subtract(new Vector(1,0,0));
|
|
||||||
}
|
|
||||||
if (minx.getBlockX() + 1 < minX) {
|
|
||||||
minX = minx.getBlockX() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (roofBlocks(world.getBlockAt(maxz).getType()) && limit < 300) {
|
|
||||||
limit++;
|
|
||||||
maxz.add(new Vector(0,0,1));
|
|
||||||
}
|
|
||||||
if (maxz.getBlockZ() - 1 > maxZ) {
|
|
||||||
maxZ = maxz.getBlockZ() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (roofBlocks(world.getBlockAt(minz).getType()) && limit < 400) {
|
|
||||||
limit++;
|
|
||||||
minz.subtract(new Vector(0,0,1));
|
|
||||||
}
|
|
||||||
if (minz.getBlockZ() + 1 < minZ) {
|
|
||||||
minZ = minz.getBlockZ() + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if material is a roof material
|
|
||||||
* @param m - material
|
|
||||||
* @return true if roof material
|
|
||||||
*/
|
|
||||||
public static boolean roofBlocks(Material m) {
|
|
||||||
return ROOF_BLOCKS.contains(m) || (m.equals(Material.GLOWSTONE) && Greenhouses.getInstance().getSettings().isAllowGlowstone());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the roofFound
|
|
||||||
*/
|
|
||||||
public boolean isRoofFound() {
|
|
||||||
return roofFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the height
|
* @return the height
|
||||||
*/
|
*/
|
||||||
@ -190,6 +174,7 @@ public class Roof extends MinMaxXZ {
|
|||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the location
|
* @return the location
|
||||||
*/
|
*/
|
||||||
@ -197,13 +182,48 @@ public class Roof extends MinMaxXZ {
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vector spiralSearch(Vector v, int startY) {
|
||||||
|
for (int radius = 0; radius < 3; radius++) {
|
||||||
|
for (int x = v.getBlockX() - radius; x <= v.getBlockX() + radius; x++) {
|
||||||
|
for (int z = v.getBlockZ() - radius; z <= v.getBlockZ() + radius; z++) {
|
||||||
|
if (!((x > v.getBlockX() - radius && x < v.getBlockX() + radius) && (z > v.getBlockZ() - radius && z < v.getBlockZ() + radius))) {
|
||||||
|
Optional<Vector> r = checkVertically(x, startY, z);
|
||||||
|
if (r.isPresent()) {
|
||||||
|
return r.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/**
|
||||||
* @see java.lang.Object#toString()
|
* 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 (!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))) {
|
||||||
|
|
||||||
|
roofFound = true;
|
||||||
|
// Roof block found
|
||||||
|
return Optional.of(new Vector(x,y,z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Roof [location=" + location + ", minX=" + minX + ", maxX=" + maxX + ", minZ=" + minZ + ", maxZ=" + maxZ
|
return "Roof [height=" + height + ", roofFound=" + roofFound + ", minX=" + minX + ", maxX=" + maxX + ", minZ="
|
||||||
+ ", height=" + height + ", roofFound=" + roofFound + "]";
|
+ minZ + ", maxZ=" + maxZ + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,28 @@
|
|||||||
package world.bentobox.greenhouses.greenhouse;
|
package world.bentobox.greenhouses.greenhouse;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
|
|
||||||
import world.bentobox.greenhouses.Greenhouses;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
|
|
||||||
public class Walls extends MinMaxXZ {
|
public class Walls extends MinMaxXZ {
|
||||||
private static final List<Material> WALL_BLOCKS;
|
public static final List<Material> WALL_BLOCKS = Arrays.stream(Material.values())
|
||||||
static {
|
|
||||||
List<Material> w = Arrays.stream(Material.values())
|
|
||||||
.filter(Material::isBlock) // Blocks only, no items
|
.filter(Material::isBlock) // Blocks only, no items
|
||||||
.filter(m -> !m.name().contains("TRAPDOOR")) // No trap doors
|
.filter(m -> !m.name().contains("TRAPDOOR")) // No trap doors
|
||||||
.filter(m -> m.name().contains("DOOR") // All doors
|
.filter(m -> m.name().contains("DOOR") // All doors
|
||||||
|| m.name().contains("GLASS") // All glass blocks
|
|| (m.name().contains("GLASS") && !m.name().contains("GLASS_PANE")) // All glass blocks
|
||||||
|| m.equals(Material.HOPPER)) // Hoppers
|
|| m.equals(Material.HOPPER)).toList();
|
||||||
.collect(Collectors.toList());
|
|
||||||
WALL_BLOCKS = Collections.unmodifiableList(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int floor;
|
private int floor;
|
||||||
|
private final AsyncWorldCache cache;
|
||||||
|
|
||||||
private static final List<BlockFace> ORDINALS = Arrays.asList(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
|
static class WallFinder {
|
||||||
|
|
||||||
class WallFinder {
|
|
||||||
int radiusMinX;
|
int radiusMinX;
|
||||||
int radiusMaxX;
|
int radiusMaxX;
|
||||||
int radiusMinZ;
|
int radiusMinZ;
|
||||||
@ -41,14 +34,34 @@ public class Walls extends MinMaxXZ {
|
|||||||
boolean isSearching() {
|
boolean isSearching() {
|
||||||
return !stopMinX || !stopMaxX || !stopMinZ || !stopMaxZ;
|
return !stopMinX || !stopMaxX || !stopMinZ || !stopMaxZ;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "WallFinder [radiusMinX=" + radiusMinX + ", radiusMaxX=" + radiusMaxX + ", radiusMinZ=" + radiusMinZ
|
||||||
|
+ ", radiusMaxZ=" + radiusMaxZ + ", stopMinX=" + stopMinX + ", stopMaxX=" + stopMaxX + ", stopMinZ="
|
||||||
|
+ stopMinZ + ", stopMaxZ=" + stopMaxZ + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Walls findWalls(Roof roof) {
|
public Walls(AsyncWorldCache cache) {
|
||||||
|
this.cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find walls given a roof
|
||||||
|
* @param roof - the roof
|
||||||
|
* @return Future walls
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Walls> findWalls(final Roof roof) {
|
||||||
|
CompletableFuture<Walls> r = new CompletableFuture<>();
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(BentoBox.getInstance(), () -> findWalls(r, roof));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
Walls findWalls(CompletableFuture<Walls> r, Roof roof) {
|
||||||
// The player is under the roof
|
// The player is under the roof
|
||||||
// Assume the player is inside the greenhouse they are trying to create
|
// Assume the player is inside the greenhouse they are trying to create
|
||||||
Location loc = roof.getLocation();
|
final Location loc = roof.getLocation();
|
||||||
World world = loc.getWorld();
|
floor = getFloorY(roof.getHeight(), roof.getMinX(), roof.getMaxX(), roof.getMinZ(), roof.getMaxZ(), loc.getWorld().getMinHeight());
|
||||||
floor = getFloorY(world, roof.getHeight(), roof.getMinX(), roof.getMaxX(), roof.getMinZ(), roof.getMaxZ());
|
|
||||||
// Now start with the player's x and z location
|
// Now start with the player's x and z location
|
||||||
WallFinder wf = new WallFinder();
|
WallFinder wf = new WallFinder();
|
||||||
minX = loc.getBlockX();
|
minX = loc.getBlockX();
|
||||||
@ -64,12 +77,14 @@ public class Walls extends MinMaxXZ {
|
|||||||
minZ--;
|
minZ--;
|
||||||
maxZ++;
|
maxZ++;
|
||||||
// Find the floor again, only looking within the walls
|
// Find the floor again, only looking within the walls
|
||||||
floor = getFloorY(world, 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;
|
return this;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lookAround(Location loc, WallFinder wf, Roof roof) {
|
void lookAround(final Location loc, WallFinder wf, final Roof roof) {
|
||||||
World world = loc.getWorld();
|
|
||||||
// Look around player in an ever expanding cube
|
// Look around player in an ever expanding cube
|
||||||
minX = loc.getBlockX() - wf.radiusMinX;
|
minX = loc.getBlockX() - wf.radiusMinX;
|
||||||
maxX = loc.getBlockX() + wf.radiusMaxX;
|
maxX = loc.getBlockX() + wf.radiusMaxX;
|
||||||
@ -81,7 +96,7 @@ public class Walls extends MinMaxXZ {
|
|||||||
// Only look around outside edge
|
// Only look around outside edge
|
||||||
if (!((x > minX && x < maxX) && (z > minZ && z < maxZ))) {
|
if (!((x > minX && x < maxX) && (z > minZ && z < maxZ))) {
|
||||||
// Look at block faces
|
// Look at block faces
|
||||||
lookAtBlockFaces(wf, world, x, y, z);
|
lookAtBlockFaces(wf, x, y, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,67 +132,43 @@ public class Walls extends MinMaxXZ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lookAtBlockFaces(WallFinder wf, World world, int x, int y, int z) {
|
void lookAtBlockFaces(WallFinder wf, int x, int y, int z) {
|
||||||
for (BlockFace bf: ORDINALS) {
|
|
||||||
switch (bf) {
|
|
||||||
case EAST:
|
|
||||||
// positive x
|
// positive x
|
||||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
if (WALL_BLOCKS.contains(cache.getBlockType(x + 1, y, z))) {
|
||||||
wf.stopMaxX = true;
|
wf.stopMaxX = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
// negative x
|
// negative x
|
||||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
if (WALL_BLOCKS.contains(cache.getBlockType(x - 1, y, z))) {
|
||||||
wf.stopMinX = true;
|
wf.stopMinX = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case NORTH:
|
|
||||||
// negative Z
|
// negative Z
|
||||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
if (WALL_BLOCKS.contains(cache.getBlockType(x, y, z - 1))) {
|
||||||
wf.stopMinZ = true;
|
wf.stopMinZ = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
// positive Z
|
// positive Z
|
||||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
if (WALL_BLOCKS.contains(cache.getBlockType(x, y, z + 1))) {
|
||||||
wf.stopMaxZ = true;
|
wf.stopMaxZ = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
int getFloorY(int y, int minX, int maxX, int minZ, int maxZ, int minY) {
|
||||||
|
|
||||||
int getFloorY(World world, int y, int minX, int maxX, int minZ, int maxZ) {
|
|
||||||
// Find the floor - defined as the last y under the roof where there are no wall blocks
|
// Find the floor - defined as the last y under the roof where there are no wall blocks
|
||||||
int wallBlockCount;
|
int wallBlockCount;
|
||||||
do {
|
do {
|
||||||
wallBlockCount = 0;
|
wallBlockCount = 0;
|
||||||
for (int x = minX; x <= maxX; x++) {
|
for (int x = minX; x <= maxX; x++) {
|
||||||
for (int z = minZ; z <= maxZ; z++) {
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getType())) {
|
if (WALL_BLOCKS.contains(cache.getBlockType(x, y, z))) {
|
||||||
wallBlockCount++;
|
wallBlockCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while( y-- > 0 && wallBlockCount > 0);
|
} while( y-- > minY && wallBlockCount > 0);
|
||||||
return y + 1;
|
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the floor
|
* @return the floor
|
||||||
*/
|
*/
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
package world.bentobox.greenhouses.listeners;
|
package world.bentobox.greenhouses.listeners;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
|
||||||
@ -29,6 +30,11 @@ import world.bentobox.greenhouses.data.Greenhouse;
|
|||||||
*/
|
*/
|
||||||
public class GreenhouseEvents implements Listener {
|
public class GreenhouseEvents implements Listener {
|
||||||
private static final String BIOME = "[biome]";
|
private static final String BIOME = "[biome]";
|
||||||
|
private static final Set<Biome> NETHER_BIOMES;
|
||||||
|
static {
|
||||||
|
NETHER_BIOMES = Set.of(Biome.NETHER_WASTES, Biome.WARPED_FOREST, Biome.CRIMSON_FOREST,
|
||||||
|
Biome.SOUL_SAND_VALLEY, Biome.BASALT_DELTAS);
|
||||||
|
}
|
||||||
private final Greenhouses addon;
|
private final Greenhouses addon;
|
||||||
|
|
||||||
public GreenhouseEvents(final Greenhouses addon) {
|
public GreenhouseEvents(final Greenhouses addon) {
|
||||||
@ -39,16 +45,30 @@ public class GreenhouseEvents implements Listener {
|
|||||||
* Permits water to be placed in the Nether if in a greenhouse and in an acceptable biome
|
* Permits water to be placed in the Nether if in a greenhouse and in an acceptable biome
|
||||||
* @param e - event
|
* @param e - event
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled=true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true)
|
||||||
public void onPlayerInteractInNether(PlayerInteractEvent e) {
|
public void onPlayerInteractInNether(PlayerBucketEmptyEvent e) {
|
||||||
if (!e.getPlayer().getWorld().getEnvironment().equals(World.Environment.NETHER)) {
|
if (!e.getBucket().equals(Material.WATER_BUCKET)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK) && e.getItem() != null && e.getItem().getType().equals(Material.WATER_BUCKET)
|
Block b = e.getBlockClicked().getRelative(e.getBlockFace());
|
||||||
&& addon.getManager().getMap().inGreenhouse(e.getClickedBlock().getLocation())) {
|
if (e.getPlayer().getWorld().getEnvironment().equals(World.Environment.NETHER)
|
||||||
|
&& !addon.getManager().getMap().getGreenhouse(b.getLocation())
|
||||||
|
.map(gh -> gh.getBiomeRecipe().getBiome()).map(NETHER_BIOMES::contains).orElse(true)) {
|
||||||
|
// In Nether not a nether greenhouse
|
||||||
|
b.setType(Material.WATER);
|
||||||
|
} else if (!e.getPlayer().getWorld().getEnvironment().equals(World.Environment.NETHER)
|
||||||
|
&& addon.getManager().getMap().getGreenhouse(b.getLocation())
|
||||||
|
.map(gh -> gh.getBiomeRecipe().getBiome()).map(NETHER_BIOMES::contains).orElse(false)) {
|
||||||
|
// Not in Nether, in a nether greenhouse
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
e.getClickedBlock().getRelative(e.getBlockFace()).setType(Material.WATER);
|
if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.WATER_BUCKET)) {
|
||||||
e.getItem().setType(Material.BUCKET);
|
e.getPlayer().getInventory().getItemInMainHand().setType(Material.BUCKET);
|
||||||
|
} else if (e.getPlayer().getInventory().getItemInOffHand().getType().equals(Material.WATER_BUCKET)) {
|
||||||
|
e.getPlayer().getInventory().getItemInOffHand().setType(Material.BUCKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
b.getWorld().spawnParticle(Particle.SMOKE_NORMAL, b.getLocation(), 10);
|
||||||
|
b.getWorld().playSound(b.getLocation(), Sound.ENTITY_GENERIC_EXTINGUISH_FIRE, 1F, 5F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,15 +76,25 @@ public class GreenhouseEvents implements Listener {
|
|||||||
* Makes water in the Nether if ice is broken and in a greenhouse
|
* Makes water in the Nether if ice is broken and in a greenhouse
|
||||||
* @param e - event
|
* @param e - event
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled=true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true)
|
||||||
public void onIceBreak(BlockBreakEvent e) {
|
public void onIceBreak(BlockBreakEvent e) {
|
||||||
if (!e.getBlock().getWorld().getEnvironment().equals(World.Environment.NETHER)
|
if (!Tag.ICE.isTagged(e.getBlock().getType())) {
|
||||||
|| !Tag.ICE.isTagged(e.getBlock().getType())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (addon.getManager().getMap().inGreenhouse(e.getBlock().getLocation())) {
|
Block b = e.getBlock();
|
||||||
|
if (b.getWorld().getEnvironment().equals(World.Environment.NETHER)
|
||||||
|
&& !addon.getManager().getMap().getGreenhouse(b.getLocation())
|
||||||
|
.map(gh -> gh.getBiomeRecipe().getBiome()).map(NETHER_BIOMES::contains).orElse(true)) {
|
||||||
|
//
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
e.getBlock().setType(Material.WATER);
|
b.setType(Material.WATER);
|
||||||
|
} else if (!e.getPlayer().getWorld().getEnvironment().equals(World.Environment.NETHER)
|
||||||
|
&& addon.getManager().getMap().getGreenhouse(b.getLocation())
|
||||||
|
.map(gh -> gh.getBiomeRecipe().getBiome()).map(NETHER_BIOMES::contains).orElse(false)) {
|
||||||
|
// Not in Nether, in a nether greenhouse
|
||||||
|
e.setCancelled(true);
|
||||||
|
b.setType(Material.AIR);
|
||||||
|
b.getWorld().playSound(b.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, 1F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,10 +108,18 @@ public class GreenhouseEvents implements Listener {
|
|||||||
handleTransition(User.getInstance(e.getPlayer()), e.getTo(), e.getFrom());
|
handleTransition(User.getInstance(e.getPlayer()), e.getTo(), e.getFrom());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param user user
|
||||||
|
* @param toLoc to location
|
||||||
|
* @param fromLoc from location
|
||||||
|
*/
|
||||||
private void handleTransition(User user, Location toLoc, Location fromLoc) {
|
private void handleTransition(User user, Location toLoc, Location fromLoc) {
|
||||||
|
if (user == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Optional<Greenhouse> to = addon.getManager().getMap().getGreenhouse(toLoc);
|
Optional<Greenhouse> to = addon.getManager().getMap().getGreenhouse(toLoc);
|
||||||
Optional<Greenhouse> from = addon.getManager().getMap().getGreenhouse(fromLoc);
|
Optional<Greenhouse> from = addon.getManager().getMap().getGreenhouse(fromLoc);
|
||||||
if (!to.isPresent() && !from.isPresent()) {
|
if (to.isEmpty() && from.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (to.isPresent() && from.isPresent()) {
|
if (to.isPresent() && from.isPresent()) {
|
||||||
@ -94,15 +132,13 @@ public class GreenhouseEvents implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// from is a greenhouse
|
// from is a greenhouse
|
||||||
if (from.isPresent() && !to.isPresent()) {
|
if (from.isPresent()) {
|
||||||
// Exiting
|
// Exiting
|
||||||
user.sendMessage("greenhouses.event.leaving", BIOME, from.get().getBiomeRecipe().getFriendlyName());
|
user.sendMessage("greenhouses.event.leaving", BIOME, from.get().getBiomeRecipe().getFriendlyName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!from.isPresent()) {
|
|
||||||
// Entering
|
// Entering
|
||||||
user.sendMessage("greenhouses.event.entering", BIOME, to.get().getBiomeRecipe().getFriendlyName());
|
user.sendMessage("greenhouses.event.entering", BIOME, to.get().getBiomeRecipe().getFriendlyName());
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,48 +159,15 @@ public class GreenhouseEvents implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true)
|
||||||
public void onBlockBreak(final BlockBreakEvent e) {
|
public void onBlockBreak(final BlockBreakEvent e) {
|
||||||
User user = User.getInstance(e.getPlayer());
|
User user = User.getInstance(e.getPlayer());
|
||||||
addon.getManager().getMap().getGreenhouse(e.getBlock().getLocation()).ifPresent(g -> {
|
addon.getManager().getMap().getGreenhouse(e.getBlock().getLocation())
|
||||||
// Check to see if wall or roof block broken
|
.filter(g -> g.isRoofOrWallBlock(e.getBlock().getLocation()))
|
||||||
if ((e.getBlock().getLocation().getBlockY() == g.getCeilingHeight() - 1)
|
.ifPresent(g -> {
|
||||||
|| e.getBlock().getLocation().getBlockX() == (int)g.getBoundingBox().getMinX()
|
if (g.getOriginalBiome() != null) {
|
||||||
|| e.getBlock().getLocation().getBlockX() == (int)g.getBoundingBox().getMaxX() - 1
|
|
||||||
|| e.getBlock().getLocation().getBlockZ() == (int)g.getBoundingBox().getMinZ()
|
|
||||||
|| e.getBlock().getLocation().getBlockZ() == (int)g.getBoundingBox().getMaxZ() - 1
|
|
||||||
) {
|
|
||||||
user.sendMessage("greenhouses.event.broke", BIOME, Util.prettifyText(g.getOriginalBiome().name()));
|
user.sendMessage("greenhouses.event.broke", BIOME, Util.prettifyText(g.getOriginalBiome().name()));
|
||||||
addon.getManager().removeGreenhouse(g);
|
|
||||||
}
|
}
|
||||||
|
addon.getManager().removeGreenhouse(g);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents placing of blocks above the greenhouses
|
|
||||||
* @param e - event
|
|
||||||
*/
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true)
|
|
||||||
public void onPlayerBlockPlace(final BlockPlaceEvent e) {
|
|
||||||
if (checkBlockHeight(e.getBlock())) {
|
|
||||||
e.setCancelled(true);
|
|
||||||
User user = User.getInstance(e.getPlayer());
|
|
||||||
user.sendMessage("greenhouses.error.cannot-place");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkBlockHeight(Block block) {
|
|
||||||
return addon.getManager().getMap().getGreenhouse(block.getLocation())
|
|
||||||
.filter(g -> g.getCeilingHeight() < block.getY())
|
|
||||||
.filter(g -> !block.getWorld().getEnvironment().equals(World.Environment.NETHER))
|
|
||||||
.isPresent();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check to see if anyone is sneaking a block over a greenhouse by using a piston
|
|
||||||
* @param e - event
|
|
||||||
*/
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true)
|
|
||||||
public void onPistonPush(final BlockPistonExtendEvent e) {
|
|
||||||
e.setCancelled(e.getBlocks().stream().anyMatch(this::checkBlockHeight));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,15 @@ package world.bentobox.greenhouses.listeners;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockFromToEvent;
|
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.Greenhouses;
|
||||||
import world.bentobox.greenhouses.data.Greenhouse;
|
import world.bentobox.greenhouses.data.Greenhouse;
|
||||||
@ -18,7 +23,7 @@ public class GreenhouseGuard implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop lava flow or water into or out of a greenhouse
|
// Stop lava flow or water into or out of a greenhouse
|
||||||
@EventHandler(priority = EventPriority.NORMAL)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
public void onFlow(final BlockFromToEvent e) {
|
public void onFlow(final BlockFromToEvent e) {
|
||||||
// Flow may be allowed anyway
|
// Flow may be allowed anyway
|
||||||
if (addon.getSettings().isAllowFlowIn() && addon.getSettings().isAllowFlowOut()) {
|
if (addon.getSettings().isAllowFlowIn() && addon.getSettings().isAllowFlowOut()) {
|
||||||
@ -34,7 +39,7 @@ public class GreenhouseGuard implements Listener {
|
|||||||
// 1. inside district or outside - always ok
|
// 1. inside district or outside - always ok
|
||||||
// 2. inside to outside - allowFlowOut determines
|
// 2. inside to outside - allowFlowOut determines
|
||||||
// 3. outside to inside - allowFlowIn determines
|
// 3. outside to inside - allowFlowIn determines
|
||||||
if (!to.isPresent() && !from.isPresent()) {
|
if (to.isEmpty() && from.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (to.isPresent() && from.isPresent() && to.equals(from)) {
|
if (to.isPresent() && from.isPresent() && to.equals(from)) {
|
||||||
@ -48,10 +53,51 @@ public class GreenhouseGuard implements Listener {
|
|||||||
if (from.isPresent() && addon.getSettings().isAllowFlowOut()) {
|
if (from.isPresent() && addon.getSettings().isAllowFlowOut()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Otherwise cancel - the flow is not allowed
|
// Otherwise, cancel - the flow is not allowed
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevents pistons from pushing greenhouse wall or roof blocks
|
||||||
|
* @param e - event
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void onPistonPush(BlockPistonExtendEvent e) {
|
||||||
|
e.setCancelled(e.getBlocks().stream()
|
||||||
|
.map(Block::getLocation)
|
||||||
|
.anyMatch(this::inGreenhouse));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevents sticky pistons from pulling greenhouse wall or roof blocks
|
||||||
|
* @param e - event
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void onPistonPull(BlockPistonRetractEvent e) {
|
||||||
|
e.setCancelled(e.getBlocks().stream()
|
||||||
|
.map(Block::getLocation)
|
||||||
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@ import world.bentobox.greenhouses.Greenhouses;
|
|||||||
*/
|
*/
|
||||||
public class IslandChangeEvents implements Listener {
|
public class IslandChangeEvents implements Listener {
|
||||||
|
|
||||||
private Greenhouses addon;
|
private final Greenhouses addon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param addon
|
* @param addon greenhouse addon
|
||||||
*/
|
*/
|
||||||
public IslandChangeEvents(Greenhouses addon) {
|
public IslandChangeEvents(Greenhouses addon) {
|
||||||
this.addon = addon;
|
this.addon = addon;
|
||||||
|
@ -4,6 +4,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -12,12 +14,17 @@ import org.bukkit.World;
|
|||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.Hopper;
|
import org.bukkit.block.Hopper;
|
||||||
|
import org.bukkit.block.data.Levelled;
|
||||||
|
import org.bukkit.block.data.type.Snow;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockFormEvent;
|
import org.bukkit.event.block.BlockFormEvent;
|
||||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
import org.bukkit.util.BoundingBox;
|
||||||
|
|
||||||
|
import com.google.common.base.Enums;
|
||||||
|
|
||||||
import world.bentobox.bentobox.util.Util;
|
import world.bentobox.bentobox.util.Util;
|
||||||
import world.bentobox.greenhouses.Greenhouses;
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
@ -41,13 +48,22 @@ public class SnowTracker implements Listener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param gh - greenhouse
|
||||||
|
* @return true if snow was create, false if not.
|
||||||
|
*/
|
||||||
private boolean getAirBlocks(Greenhouse gh) {
|
private boolean getAirBlocks(Greenhouse gh) {
|
||||||
|
if (gh.getLocation() == null) {
|
||||||
|
// Greenhouse does not have a location for some reason.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
boolean createdSnow = false;
|
boolean createdSnow = false;
|
||||||
List<Block> waterBlocks = new ArrayList<>();
|
List<Block> waterBlocks = new ArrayList<>();
|
||||||
for (int x = (int)gh.getBoundingBox().getMinX() + 1; x < (int)gh.getBoundingBox().getMaxX() -1; x++) {
|
final BoundingBox bb = gh.getBoundingBox();
|
||||||
for (int z = (int)gh.getBoundingBox().getMinZ() + 1; z < (int)gh.getBoundingBox().getMaxZ() - 1; z++) {
|
for (int x = (int)bb.getMinX() + 1; x < (int)bb.getMaxX() -1; x++) {
|
||||||
for (int y = (int)gh.getBoundingBox().getMaxY() - 2; y >= (int)gh.getBoundingBox().getMinY(); y--) {
|
for (int z = (int)bb.getMinZ() + 1; z < (int)bb.getMaxZ() - 1; z++) {
|
||||||
Block b = gh.getLocation().getWorld().getBlockAt(x, y, 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();
|
Material type = b.getType();
|
||||||
if (type.equals(Material.AIR) || type.equals(Material.SNOW)) {
|
if (type.equals(Material.AIR) || type.equals(Material.SNOW)) {
|
||||||
b.getWorld().spawnParticle(Particle.SNOWBALL, b.getLocation(), 5);
|
b.getWorld().spawnParticle(Particle.SNOWBALL, b.getLocation(), 5);
|
||||||
@ -59,9 +75,11 @@ public class SnowTracker implements Listener {
|
|||||||
// Not water
|
// Not water
|
||||||
if (Math.random() < addon.getSettings().getSnowDensity()
|
if (Math.random() < addon.getSettings().getSnowDensity()
|
||||||
&& !b.isLiquid()
|
&& !b.isLiquid()
|
||||||
&& b.getRelative(BlockFace.UP).getType().equals(Material.AIR)) {
|
&& (b.getRelative(BlockFace.UP).getType().equals(Material.AIR)
|
||||||
b.getRelative(BlockFace.UP).setType(Material.SNOW);
|
|| b.getRelative(BlockFace.UP).getType().equals(Material.SNOW))) {
|
||||||
createdSnow = true;
|
|
||||||
|
|
||||||
|
createdSnow = placeSnow(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +99,49 @@ public class SnowTracker implements Listener {
|
|||||||
return createdSnow;
|
return createdSnow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean placeSnow(Block b) {
|
||||||
|
Optional<Material> snowCauldron = Enums.getIfPresent(Material.class, "POWDER_SNOW_CAULDRON").toJavaUtil();
|
||||||
|
if (snowCauldron.isPresent()) {
|
||||||
|
if (b.getType().equals(Material.CAULDRON)) {
|
||||||
|
b.setType(snowCauldron.get());
|
||||||
|
return true;
|
||||||
|
} else if (b.getType().equals(snowCauldron.get())) {
|
||||||
|
// Fill up the snow cauldron some more
|
||||||
|
return incrementLevel(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Pile up snow
|
||||||
|
if (b.getRelative(BlockFace.UP).getType().equals(Material.SNOW)) {
|
||||||
|
return incrementLevel(b.getRelative(BlockFace.UP));
|
||||||
|
} else {
|
||||||
|
b.getRelative(BlockFace.UP).setType(Material.SNOW);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean incrementLevel(Block b) {
|
||||||
|
if (b.getBlockData() instanceof Levelled data) {
|
||||||
|
int max = data.getMaximumLevel();
|
||||||
|
if (data.getLevel() < max) {
|
||||||
|
data.setLevel(data.getLevel() + 1);
|
||||||
|
b.setBlockData(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (b.getBlockData() instanceof Snow data) {
|
||||||
|
int max = data.getMaximumLayers();
|
||||||
|
if (data.getLayers() < max) {
|
||||||
|
data.setLayers(data.getLayers() + 1);
|
||||||
|
b.setBlockData(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO finish
|
* TODO finish
|
||||||
* @param e
|
* @param e block form event
|
||||||
*/
|
*/
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockFormEvent(final BlockFormEvent e) {
|
public void onBlockFormEvent(final BlockFormEvent e) {
|
||||||
@ -108,7 +166,7 @@ public class SnowTracker implements Listener {
|
|||||||
|
|
||||||
private void removeWaterBucketAndShake(Greenhouse g) {
|
private void removeWaterBucketAndShake(Greenhouse g) {
|
||||||
// Scatter snow
|
// Scatter snow
|
||||||
if (getAirBlocks(g)) {
|
if (getAirBlocks(g) && g.getRoofHopperLocation() != null) {
|
||||||
Hopper h = ((Hopper)g.getRoofHopperLocation().getBlock().getState());
|
Hopper h = ((Hopper)g.getRoofHopperLocation().getBlock().getState());
|
||||||
h.getInventory().removeItem(new ItemStack(Material.WATER_BUCKET));
|
h.getInventory().removeItem(new ItemStack(Material.WATER_BUCKET));
|
||||||
h.getInventory().addItem(new ItemStack(Material.BUCKET));
|
h.getInventory().addItem(new ItemStack(Material.BUCKET));
|
||||||
@ -117,18 +175,16 @@ public class SnowTracker implements Listener {
|
|||||||
|
|
||||||
private void shakeGlobes(World world) {
|
private void shakeGlobes(World world) {
|
||||||
addon.getManager().getMap().getGreenhouses().stream().filter(g -> g.getBiomeRecipe().getIceCoverage() > 0)
|
addon.getManager().getMap().getGreenhouses().stream().filter(g -> g.getBiomeRecipe().getIceCoverage() > 0)
|
||||||
.filter(g -> (g.getLocation().getWorld().isChunkLoaded(((int) g.getBoundingBox().getMaxX()) >> 4, ((int) g.getBoundingBox().getMaxZ()) >> 4) && g.getLocation().getWorld().isChunkLoaded(((int) g.getBoundingBox().getMinX()) >> 4, ((int) g.getBoundingBox().getMinZ()) >> 4)))
|
.filter(g -> (Objects.requireNonNull(Objects.requireNonNull(g.getLocation()).getWorld()).isChunkLoaded(((int) g.getBoundingBox().getMaxX()) >> 4, ((int) g.getBoundingBox().getMaxZ()) >> 4) && g.getLocation().getWorld().isChunkLoaded(((int) g.getBoundingBox().getMinX()) >> 4, ((int) g.getBoundingBox().getMinZ()) >> 4)))
|
||||||
.filter(g -> g.getLocation().getWorld().equals(world))
|
.filter(g -> g.getLocation().getWorld().equals(world))
|
||||||
.filter(g -> !g.isBroken())
|
.filter(g -> !g.isBroken())
|
||||||
.filter(g -> g.getRoofHopperLocation() != null)
|
.filter(g -> g.getRoofHopperLocation() != null)
|
||||||
.forEach(g -> {
|
.forEach(g -> Util.getChunkAtAsync(g.getRoofHopperLocation()).thenRun(() -> {
|
||||||
Util.getChunkAtAsync(g.getRoofHopperLocation()).thenRun(() -> {
|
|
||||||
if (g.getRoofHopperLocation().getBlock().getType().equals(Material.HOPPER)
|
if (g.getRoofHopperLocation().getBlock().getType().equals(Material.HOPPER)
|
||||||
&& ((Hopper)g.getRoofHopperLocation().getBlock().getState()).getInventory().contains(Material.WATER_BUCKET)) {
|
&& ((Hopper)g.getRoofHopperLocation().getBlock().getState()).getInventory().contains(Material.WATER_BUCKET)) {
|
||||||
removeWaterBucketAndShake(g);
|
removeWaterBucketAndShake(g);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startSnow(World world) {
|
private void startSnow(World world) {
|
||||||
|
@ -9,14 +9,19 @@ import java.util.Objects;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Tag;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.Hopper;
|
import org.bukkit.block.Hopper;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
import org.bukkit.util.BoundingBox;
|
||||||
|
import org.bukkit.util.NumberConversions;
|
||||||
|
|
||||||
import world.bentobox.greenhouses.Greenhouses;
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
import world.bentobox.greenhouses.data.Greenhouse;
|
import world.bentobox.greenhouses.data.Greenhouse;
|
||||||
|
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the ecosystem for a greenhouse
|
* Runs the ecosystem for a greenhouse
|
||||||
@ -53,7 +58,7 @@ public class EcoSystemManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Kick block conversion growing
|
// Kick block conversion growing
|
||||||
long blockTick = addon.getSettings().getBlockTick() * 60 * 20l; // In minutes
|
long blockTick = addon.getSettings().getBlockTick() * 60 * 20L; // In minutes
|
||||||
|
|
||||||
if (blockTick > 0) {
|
if (blockTick > 0) {
|
||||||
addon.log("Kicking off block conversion scheduler every " + addon.getSettings().getBlockTick() + MINUTES);
|
addon.log("Kicking off block conversion scheduler every " + addon.getSettings().getBlockTick() + MINUTES);
|
||||||
@ -82,45 +87,74 @@ public class EcoSystemManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void convertBlocks(Greenhouse gh) {
|
private void convertBlocks(Greenhouse gh) {
|
||||||
if(!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)){
|
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) bb.getMaxX()) >> 4, ((int) bb.getMaxZ()) >> 4)
|
||||||
|
|| !gh.getLocation().getWorld().isChunkLoaded(((int) bb.getMinX()) >> 4, ((int) bb.getMinZ()) >> 4)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int x = (int)gh.getBoundingBox().getMinX() + 1; x < (int)gh.getBoundingBox().getMaxX(); x++) {
|
final BoundingBox ibb = gh.getInternalBoundingBox();
|
||||||
for (int z = (int)gh.getBoundingBox().getMinZ() + 1; z < (int)gh.getBoundingBox().getMaxZ(); z++) {
|
int ghMinX = NumberConversions.floor(ibb.getMinX());
|
||||||
for (int y = (int)gh.getBoundingBox().getMaxY() - 2; y >= (int)gh.getBoundingBox().getMinY() && y > 0; y--) {
|
int ghMaxX = NumberConversions.floor(ibb.getMaxX());
|
||||||
Block b = gh.getWorld().getBlockAt(x, y, z).getRelative(BlockFace.DOWN);
|
int ghMinY = NumberConversions.floor(gh.getBoundingBox().getMinY()); // Note: this gets the floor
|
||||||
if (!b.isEmpty()) gh.getBiomeRecipe().convertBlock(gh, b);
|
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 = 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()) {
|
||||||
|
biomeRecipe.convertBlock(b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verify(Greenhouse gh) {
|
private void verify(Greenhouse gh) {
|
||||||
if(!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)){
|
if(gh.getLocation() == null || gh.getLocation().getWorld() == null
|
||||||
//addon.log("Skipping verify for unloaded greenhouse at " + gh.getLocation());
|
|| !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)){
|
||||||
|
// Skipping verify for unloaded greenhouse
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!gh.getBiomeRecipe().checkRecipe(gh).isEmpty()) {
|
gh.getBiomeRecipe().checkRecipe(gh).thenAccept(rs -> {
|
||||||
|
if (!rs.isEmpty()) {
|
||||||
addon.log("Greenhouse failed verification at " + gh.getLocation());
|
addon.log("Greenhouse failed verification at " + gh.getLocation());
|
||||||
g.removeGreenhouse(gh);
|
g.removeGreenhouse(gh);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMobs(Greenhouse gh) {
|
/**
|
||||||
if(!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)){
|
* Try to spawn mobs in a greenhouse
|
||||||
//addon.log("Skipping addmobs for unloaded greenhouse at " + gh.getLocation());
|
* @param gh greenhouse
|
||||||
return;
|
* @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) 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 false;
|
||||||
}
|
}
|
||||||
if (gh.getBiomeRecipe().noMobs()) {
|
if (gh.getBiomeRecipe().noMobs()) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
// Check greenhouse chunks are loaded
|
// Check greenhouse chunks are loaded
|
||||||
for (double blockX = gh.getBoundingBox().getMinX(); blockX < gh.getBoundingBox().getMaxX(); blockX+=16) {
|
for (double blockX = bb.getMinX(); blockX < bb.getMaxX(); blockX+=16) {
|
||||||
for (double blockZ = gh.getBoundingBox().getMinZ(); blockZ < gh.getBoundingBox().getMaxZ(); blockZ+=16) {
|
for (double blockZ = bb.getMinZ(); blockZ < bb.getMaxZ(); blockZ+=16) {
|
||||||
int chunkX = (int)(blockX / 16);
|
int chunkX = (int)(blockX / 16);
|
||||||
int chunkZ = (int)(blockZ / 16);
|
int chunkZ = (int)(blockZ / 16);
|
||||||
if (!gh.getWorld().isChunkLoaded(chunkX, chunkZ)) {
|
if (!gh.getWorld().isChunkLoaded(chunkX, chunkZ)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,17 +163,21 @@ public class EcoSystemManager {
|
|||||||
.filter(e -> gh.getBiomeRecipe().getMobTypes().contains(e.getType()))
|
.filter(e -> gh.getBiomeRecipe().getMobTypes().contains(e.getType()))
|
||||||
.filter(e -> gh.contains(e.getLocation())).count();
|
.filter(e -> gh.contains(e.getLocation())).count();
|
||||||
// Get the blocks in the greenhouse where spawning could occur
|
// Get the blocks in the greenhouse where spawning could occur
|
||||||
List<Block> list = new ArrayList<>(getAvailableBlocks(gh, false));
|
List<GrowthBlock> list = new ArrayList<>(getAvailableBlocks(gh, false));
|
||||||
Collections.shuffle(list, new Random(System.currentTimeMillis()));
|
Collections.shuffle(list, new Random(System.currentTimeMillis()));
|
||||||
Iterator<Block> it = list.iterator();
|
Iterator<GrowthBlock> it = list.iterator();
|
||||||
// Check if the greenhouse is full
|
// 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())) {
|
while (it.hasNext() && (sum == 0 || gh.getArea() / sum >= gh.getBiomeRecipe().getMobLimit())) {
|
||||||
// Spawn something if chance says so
|
// Spawn something if chance says so
|
||||||
if (gh.getBiomeRecipe().spawnMob(it.next())) {
|
if (gh.getBiomeRecipe().spawnMob(it.next().block())) {
|
||||||
// Add a mob to the sum in the greenhouse
|
// Add a mob to the sum in the greenhouse
|
||||||
sum++;
|
sum++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return sum > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,14 +185,22 @@ public class EcoSystemManager {
|
|||||||
* @param gh - greenhouse
|
* @param gh - greenhouse
|
||||||
*/
|
*/
|
||||||
private void growPlants(Greenhouse gh) {
|
private void growPlants(Greenhouse gh) {
|
||||||
if(!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)){
|
final BoundingBox bb = gh.getBoundingBox();
|
||||||
//addon.log("Skipping growplants for unloaded greenhouse at " + gh.getLocation());
|
if (gh.getLocation() == null || gh.getLocation().getWorld() == null
|
||||||
|
|| !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;
|
return;
|
||||||
}
|
}
|
||||||
int bonemeal = getBoneMeal(gh);
|
int bonemeal = getBoneMeal(gh);
|
||||||
if (bonemeal > 0) {
|
if (bonemeal > 0) {
|
||||||
// Get a list of all available blocks
|
// Get a list of all available blocks
|
||||||
int plantsGrown = getAvailableBlocks(gh, true).stream().limit(bonemeal).mapToInt(bl -> gh.getBiomeRecipe().growPlant(bl) ? 1 : 0).sum();
|
List<GrowthBlock> list = getAvailableBlocks(gh, false);
|
||||||
|
Collections.shuffle(list);
|
||||||
|
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) {
|
if (plantsGrown > 0) {
|
||||||
setBoneMeal(gh, bonemeal - (int)Math.ceil((double)plantsGrown / PLANTS_PER_BONEMEAL ));
|
setBoneMeal(gh, bonemeal - (int)Math.ceil((double)plantsGrown / PLANTS_PER_BONEMEAL ));
|
||||||
}
|
}
|
||||||
@ -177,24 +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.
|
* 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 gh - greenhouse
|
||||||
* @param ignoreliquid - true if liquid blocks should be treated like air blocks
|
* @param ignoreLiquid - true if liquid blocks should be treated like air blocks
|
||||||
* @return List of blocks
|
* @return List of blocks
|
||||||
*/
|
*/
|
||||||
List<Block> getAvailableBlocks(Greenhouse gh, boolean ignoreLiquid) {
|
protected List<GrowthBlock> getAvailableBlocks(Greenhouse gh, boolean ignoreLiquid) {
|
||||||
List<Block> result = new ArrayList<>();
|
final BoundingBox bb = gh.getBoundingBox();
|
||||||
for (int x = (int)gh.getBoundingBox().getMinX() + 1; x < (int)gh.getBoundingBox().getMaxX(); x++) {
|
final BoundingBox ibb = gh.getInternalBoundingBox();
|
||||||
for (int z = (int)gh.getBoundingBox().getMinZ() + 1; z < (int)gh.getBoundingBox().getMaxZ(); z++) {
|
List<GrowthBlock> result = new ArrayList<>();
|
||||||
for (int y = (int)gh.getBoundingBox().getMaxY() - 2; y >= (int)gh.getBoundingBox().getMinY(); y--) {
|
if (gh.getWorld() == null) return result;
|
||||||
Block b = gh.getWorld().getBlockAt(x, y, z);
|
for (double x = ibb.getMinX(); x < ibb.getMaxX(); x++) {
|
||||||
if (!(b.isEmpty() || (ignoreLiquid && b.isLiquid()))
|
for (double z = ibb.getMinZ(); z < ibb.getMaxZ(); z++) {
|
||||||
&& (b.getRelative(BlockFace.UP).isEmpty()
|
for (double y = ibb.getMaxY() - 1; y >= bb.getMinY(); y--) {
|
||||||
|| (b.getRelative(BlockFace.UP).isPassable() && !b.isLiquid())
|
Block b = gh.getWorld().getBlockAt(NumberConversions.floor(x), NumberConversions.floor(y), NumberConversions.floor(z));
|
||||||
|| (ignoreLiquid && b.isLiquid() && b.getRelative(BlockFace.UP).isPassable()))) {
|
if (checkBlock(result, b, ignoreLiquid)) {
|
||||||
result.add(b.getRelative(BlockFace.UP));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,6 +250,31 @@ public class EcoSystemManager {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkBlock(List<GrowthBlock> result, Block b, boolean ignoreLiquid) {
|
||||||
|
// Check floor blocks
|
||||||
|
if (!ignoreLiquid) {
|
||||||
|
// Check ceiling blocks
|
||||||
|
if (b.isEmpty() && !b.getRelative(BlockFace.UP).isEmpty()) {
|
||||||
|
result.add(new GrowthBlock(b, false));
|
||||||
|
}
|
||||||
|
if (!b.isEmpty() && !Tag.LEAVES.isTagged(b.getType())
|
||||||
|
&& (b.getRelative(BlockFace.UP).isEmpty()
|
||||||
|
|| b.getRelative(BlockFace.UP).isPassable()
|
||||||
|
|| Tag.LEAVES.isTagged(b.getRelative(BlockFace.UP).getType())
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
result.add(new GrowthBlock(b.getRelative(BlockFace.UP), true));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!b.isEmpty() && !b.isLiquid() && b.getRelative(BlockFace.UP).isLiquid()) {
|
||||||
|
result.add(new GrowthBlock(b.getRelative(BlockFace.UP), true));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private int getBoneMeal(Greenhouse gh) {
|
private int getBoneMeal(Greenhouse gh) {
|
||||||
Hopper hopper = getHopper(gh);
|
Hopper hopper = getHopper(gh);
|
||||||
if (hopper == null || !hopper.getInventory().contains(Material.BONE_MEAL)) {
|
if (hopper == null || !hopper.getInventory().contains(Material.BONE_MEAL)) {
|
||||||
@ -213,12 +285,14 @@ public class EcoSystemManager {
|
|||||||
.mapToInt(ItemStack::getAmount).sum();
|
.mapToInt(ItemStack::getAmount).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hopper
|
||||||
|
* @param gh greenhouse
|
||||||
|
* @return hopper block or null if it does not exist
|
||||||
|
*/
|
||||||
private Hopper getHopper(Greenhouse gh) {
|
private Hopper getHopper(Greenhouse gh) {
|
||||||
if (gh.getRoofHopperLocation() == null) {
|
// Check if the hopper block is still a hopper
|
||||||
return null;
|
if (gh.getRoofHopperLocation() == null || !gh.getRoofHopperLocation().getBlock().getType().equals(Material.HOPPER)) {
|
||||||
}
|
|
||||||
// Check if there are any bonemeal in the hopper
|
|
||||||
if (gh.getRoofHopperLocation().getBlock().getType() != Material.HOPPER) {
|
|
||||||
gh.setRoofHopperLocation(null);
|
gh.setRoofHopperLocation(null);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -3,104 +3,124 @@ package world.bentobox.greenhouses.managers;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.World;
|
import org.bukkit.util.Vector;
|
||||||
import org.bukkit.World.Environment;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
import world.bentobox.greenhouses.data.Greenhouse;
|
import world.bentobox.greenhouses.data.Greenhouse;
|
||||||
import world.bentobox.greenhouses.greenhouse.Roof;
|
import world.bentobox.greenhouses.greenhouse.Roof;
|
||||||
import world.bentobox.greenhouses.greenhouse.Walls;
|
import world.bentobox.greenhouses.greenhouse.Walls;
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
||||||
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
|
|
||||||
public class GreenhouseFinder {
|
public class GreenhouseFinder {
|
||||||
|
|
||||||
private Greenhouse gh = new Greenhouse();
|
private Greenhouse gh;
|
||||||
private final Set<Location> redGlass = new HashSet<>();
|
private final Set<Vector> redGlass = new HashSet<>();
|
||||||
// Counts
|
|
||||||
private int wallDoors = 0;
|
|
||||||
// Hoppers
|
|
||||||
private int ghHopper = 0;
|
|
||||||
// Air
|
|
||||||
private boolean airHoles = false;
|
|
||||||
// Other blocks
|
|
||||||
private boolean otherBlocks = false;
|
|
||||||
// Ceiling issue
|
// Ceiling issue
|
||||||
private boolean inCeiling = false;
|
private boolean inCeiling = false;
|
||||||
// The y height where other blocks were found
|
// The y height where other blocks were found
|
||||||
// If this is the bottom layer, the player has most likely uneven walls
|
// If this is the bottom layer, the player has most likely uneven walls
|
||||||
private int otherBlockLayer = -1;
|
private int otherBlockLayer = -1;
|
||||||
private int wallBlockCount;
|
private int wallBlockCount;
|
||||||
|
private final Greenhouses addon;
|
||||||
|
/**
|
||||||
|
* This is the count of the various items
|
||||||
|
*/
|
||||||
|
private CounterCheck counterCheck = new CounterCheck();
|
||||||
|
|
||||||
class CounterCheck {
|
static class CounterCheck {
|
||||||
int doorCount;
|
int doorCount;
|
||||||
int hopperCount;
|
int hopperCount;
|
||||||
boolean airHole;
|
boolean airHole;
|
||||||
boolean otherBlock;
|
boolean otherBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param addon Addon
|
||||||
|
*/
|
||||||
|
public GreenhouseFinder(Greenhouses addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find out if there is a greenhouse here
|
* Find out if there is a greenhouse here
|
||||||
* @param location - start location
|
* @param location - start location
|
||||||
* @return GreenhouseResult class
|
* @return future GreenhouseResult class
|
||||||
*/
|
*/
|
||||||
public Set<GreenhouseResult> find(Location location) {
|
public CompletableFuture<Set<GreenhouseResult>> find(Location location) {
|
||||||
|
CompletableFuture<Set<GreenhouseResult>> r = new CompletableFuture<>();
|
||||||
Set<GreenhouseResult> result = new HashSet<>();
|
Set<GreenhouseResult> result = new HashSet<>();
|
||||||
redGlass.clear();
|
redGlass.clear();
|
||||||
|
|
||||||
|
// Get a world cache
|
||||||
|
AsyncWorldCache cache = new AsyncWorldCache(addon, location.getWorld());
|
||||||
// Find the roof
|
// Find the roof
|
||||||
Roof roof = new Roof(location);
|
Roof roof = new Roof(cache, location, addon);
|
||||||
if (!roof.isRoofFound()) {
|
roof.findRoof().thenAccept(found -> {
|
||||||
|
if (Boolean.FALSE.equals(found)) {
|
||||||
result.add(GreenhouseResult.FAIL_NO_ROOF);
|
result.add(GreenhouseResult.FAIL_NO_ROOF);
|
||||||
return result;
|
r.complete(result);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Find the walls
|
// Find the walls
|
||||||
Walls walls = new Walls().findWalls(roof);
|
new Walls(cache).findWalls(roof).thenAccept(walls -> {
|
||||||
// Make the initial greenhouse
|
// Make the initial greenhouse
|
||||||
gh = new Greenhouse(location.getWorld(), walls, roof.getHeight());
|
gh = new Greenhouse(location.getWorld(), walls, roof.getHeight());
|
||||||
// Set the original biome
|
// Set the original biome
|
||||||
gh.setOriginalBiome(location.getBlock().getBiome());
|
gh.setOriginalBiome(location.getBlock().getBiome());
|
||||||
|
|
||||||
// Now check to see if the floor really is the floor and the walls follow the rules
|
// Now check to see if the floor really is the floor and the walls follow the rules
|
||||||
result.addAll(checkGreenhouse(gh, roof, walls));
|
checkGreenhouse(cache, roof, walls).thenAccept(c -> {
|
||||||
|
result.addAll(c);
|
||||||
|
r.complete(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return result;
|
});
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<GreenhouseResult> checkGreenhouse(Greenhouse gh2, Roof roof, Walls walls) {
|
/**
|
||||||
Set<GreenhouseResult> result = new HashSet<>();
|
* Check the greenhouse has the right number of everything
|
||||||
World world = roof.getLocation().getWorld();
|
* @param cache async world cache
|
||||||
|
* @param roof - roof object
|
||||||
|
* @param walls - walls object
|
||||||
|
* @return future set of Greenhouse Results
|
||||||
|
*/
|
||||||
|
CompletableFuture<Set<GreenhouseResult>> checkGreenhouse(AsyncWorldCache cache, Roof roof, Walls walls) {
|
||||||
|
CompletableFuture<Set<GreenhouseResult>> r = new CompletableFuture<>();
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(BentoBox.getInstance(), () -> checkGreenhouseAsync(r, cache, roof, walls));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<GreenhouseResult> checkGreenhouseAsync(CompletableFuture<Set<GreenhouseResult>> r, AsyncWorldCache cache,
|
||||||
|
Roof roof, Walls walls) {
|
||||||
|
counterCheck = new CounterCheck();
|
||||||
int y;
|
int y;
|
||||||
for (y = world.getMaxHeight() - 1; y >= walls.getFloor(); y--) {
|
for (y = roof.getHeight(); y > walls.getFloor(); y--) {
|
||||||
CounterCheck cc = new CounterCheck();
|
|
||||||
wallBlockCount = 0;
|
wallBlockCount = 0;
|
||||||
for (int x = walls.getMinX(); x <= walls.getMaxX(); x++) {
|
for (int x = walls.getMinX(); x <= walls.getMaxX(); x++) {
|
||||||
for (int z = walls.getMinZ(); z <= walls.getMaxZ(); z++) {
|
for (int z = walls.getMinZ(); z <= walls.getMaxZ(); z++) {
|
||||||
result.addAll(checkBlock(cc, roof, walls, world.getBlockAt(x, y, z)));
|
checkBlock(counterCheck, cache.getBlockType(x,y,z), roof, walls, new Vector(x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wallBlockCount == 0 && y < roof.getHeight()) {
|
if (wallBlockCount == 0 && y < roof.getHeight()) {
|
||||||
// This is the floor
|
// This is the floor
|
||||||
break;
|
break;
|
||||||
} else {
|
} else if (counterCheck.otherBlock && otherBlockLayer < 0) {
|
||||||
wallDoors += cc.doorCount;
|
|
||||||
ghHopper += cc.hopperCount;
|
|
||||||
if (cc.airHole) {
|
|
||||||
airHoles = true;
|
|
||||||
}
|
|
||||||
if (cc.otherBlock) {
|
|
||||||
otherBlocks = true;
|
|
||||||
if (otherBlockLayer < 0) {
|
|
||||||
otherBlockLayer = y;
|
otherBlockLayer = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.addAll(checkErrors(roof, y));
|
Set<GreenhouseResult> result = new HashSet<>(checkErrors(roof, y));
|
||||||
|
Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> r.complete(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,102 +131,102 @@ public class GreenhouseFinder {
|
|||||||
result.add(GreenhouseResult.FAIL_BELOW);
|
result.add(GreenhouseResult.FAIL_BELOW);
|
||||||
}
|
}
|
||||||
// Show errors
|
// Show errors
|
||||||
if (airHoles && !inCeiling) {
|
if (isAirHoles() && !inCeiling) {
|
||||||
result.add(GreenhouseResult.FAIL_HOLE_IN_WALL);
|
result.add(GreenhouseResult.FAIL_HOLE_IN_WALL);
|
||||||
} else if (airHoles && inCeiling) {
|
} else if (isAirHoles() && inCeiling) {
|
||||||
result.add(GreenhouseResult.FAIL_HOLE_IN_ROOF);
|
result.add(GreenhouseResult.FAIL_HOLE_IN_ROOF);
|
||||||
}
|
}
|
||||||
if (otherBlocks && otherBlockLayer == y + 1) {
|
if (isOtherBlocks() && otherBlockLayer == y + 1) {
|
||||||
// Walls must be even all the way around
|
// Walls must be even all the way around
|
||||||
result.add(GreenhouseResult.FAIL_UNEVEN_WALLS);
|
result.add(GreenhouseResult.FAIL_UNEVEN_WALLS);
|
||||||
} else if (otherBlocks && otherBlockLayer == roof.getHeight()) {
|
} else if (isOtherBlocks() && otherBlockLayer == roof.getHeight()) {
|
||||||
// Roof blocks must be glass, glowstone, doors or a hopper.
|
// Roof blocks must be glass, glowstone, doors or a hopper.
|
||||||
result.add(GreenhouseResult.FAIL_BAD_ROOF_BLOCKS);
|
result.add(GreenhouseResult.FAIL_BAD_ROOF_BLOCKS);
|
||||||
} else if (otherBlocks) {
|
} else if (isOtherBlocks()) {
|
||||||
// "Wall blocks must be glass, glowstone, doors or a hopper.
|
// Wall blocks must be glass, glowstone, doors or a hopper.
|
||||||
result.add(GreenhouseResult.FAIL_BAD_WALL_BLOCKS);
|
result.add(GreenhouseResult.FAIL_BAD_WALL_BLOCKS);
|
||||||
}
|
}
|
||||||
if (wallDoors > 8) {
|
if (this.getWallDoors() > 8) {
|
||||||
result.add(GreenhouseResult.FAIL_TOO_MANY_DOORS);
|
result.add(GreenhouseResult.FAIL_TOO_MANY_DOORS);
|
||||||
}
|
}
|
||||||
if (ghHopper > 1) {
|
if (this.getGhHopper() > 1) {
|
||||||
result.add(GreenhouseResult.FAIL_TOO_MANY_HOPPERS);
|
result.add(GreenhouseResult.FAIL_TOO_MANY_HOPPERS);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<GreenhouseResult> checkBlock(CounterCheck cc, Roof roof, Walls walls, Block block) {
|
|
||||||
Set<GreenhouseResult> result = new HashSet<>();
|
|
||||||
World world = block.getWorld();
|
|
||||||
// Checking above greenhouse - no blocks allowed
|
|
||||||
if (block.getY() > roof.getHeight()) {
|
|
||||||
// We are above the greenhouse
|
|
||||||
if (!world.getEnvironment().equals(Environment.NETHER) && !block.isEmpty()) {
|
|
||||||
result.add(GreenhouseResult.FAIL_BLOCKS_ABOVE);
|
|
||||||
redGlass.add(block.getLocation());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Check just the walls
|
|
||||||
checkWalls(block, roof, walls, cc);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check a wall block
|
* Check if block is allowed to be in that location
|
||||||
* @param block - block
|
* @param cc - Counter Check object
|
||||||
|
* @param m - material of the block
|
||||||
* @param roof - roof object
|
* @param roof - roof object
|
||||||
* @param walls - wall object
|
* @param walls - walls object
|
||||||
* @param cc - count
|
* @param v - vector location of the block
|
||||||
* @return true if block was in the wall
|
* @return true if block is acceptable, false if not
|
||||||
*/
|
*/
|
||||||
boolean checkWalls(Block block, Roof roof, Walls walls, CounterCheck cc) {
|
boolean checkBlock(CounterCheck cc, Material m, Roof roof, Walls walls, Vector v) {
|
||||||
int x = block.getX();
|
final int x = v.getBlockX();
|
||||||
int y = block.getY();
|
final int y = v.getBlockY();
|
||||||
int z = block.getZ();
|
final int z = v.getBlockZ();
|
||||||
// Check wall blocks only
|
// Check wall blocks only
|
||||||
if (y == roof.getHeight() || x == walls.getMinX() || x == walls.getMaxX() || z == walls.getMinZ() || z== walls.getMaxZ()) {
|
if (y == roof.getHeight() || x == walls.getMinX() || x == walls.getMaxX() || z == walls.getMinZ() || z== walls.getMaxZ()) {
|
||||||
// Check for non-wall blocks or non-roof blocks at the top of walls
|
// Check for non-wall blocks or non-roof blocks at the top of walls
|
||||||
if ((y != roof.getHeight() && !Walls.wallBlocks(block.getType())) || (y == roof.getHeight() && !Roof.roofBlocks(block.getType()))) {
|
if ((y != roof.getHeight() && !addon.wallBlocks(m))
|
||||||
if (block.isEmpty()) {
|
|| (y == roof.getHeight() && !roof.roofBlocks(m))) {
|
||||||
|
if (m.equals(Material.AIR)) {
|
||||||
|
// Air hole found
|
||||||
cc.airHole = true;
|
cc.airHole = true;
|
||||||
if (y == roof.getHeight()) {
|
if (y == roof.getHeight()) {
|
||||||
|
// Air hole is in ceiling
|
||||||
inCeiling = true;
|
inCeiling = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// A non-wall or roof block found
|
||||||
cc.otherBlock = true;
|
cc.otherBlock = true;
|
||||||
}
|
}
|
||||||
redGlass.add(block.getLocation());
|
// Record the incorrect location
|
||||||
|
redGlass.add(v);
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Normal wall blocks
|
// Normal wall blocks
|
||||||
wallBlockCount++;
|
wallBlockCount++;
|
||||||
checkDoorsHoppers(cc, block);
|
return checkDoorsHoppers(cc, m, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkDoorsHoppers(CounterCheck cc, Block block) {
|
/**
|
||||||
|
* Check the count of doors and hopper and set the hopper location if it is found
|
||||||
|
* @param cc counter check
|
||||||
|
* @param m material of block
|
||||||
|
* @param v vector position of block
|
||||||
|
* @return false if there is an error, true if ok
|
||||||
|
*/
|
||||||
|
boolean checkDoorsHoppers(CounterCheck cc, Material m, Vector v) {
|
||||||
// Count doors
|
// Count doors
|
||||||
if (Tag.DOORS.isTagged(block.getType())) {
|
if (Tag.TRAPDOORS.isTagged(m) || Tag.DOORS.isTagged(m)) {
|
||||||
cc.doorCount++;
|
cc.doorCount = Tag.TRAPDOORS.isTagged(m) ? cc.doorCount + 2 : cc.doorCount + 1;
|
||||||
|
|
||||||
// If we already have 8 doors add these blocks to the red list
|
// If we already have 8 doors add these blocks to the red list
|
||||||
if (wallDoors == 8) {
|
if (cc.doorCount > 8) {
|
||||||
redGlass.add(block.getLocation());
|
redGlass.add(v);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Count hoppers
|
// Count hoppers
|
||||||
if (block.getType().equals(Material.HOPPER)) {
|
if (m.equals(Material.HOPPER)) {
|
||||||
cc.hopperCount++;
|
cc.hopperCount++;
|
||||||
if (ghHopper > 0) {
|
if (cc.hopperCount > 1) {
|
||||||
// Problem! Add extra hoppers to the red glass list
|
// Problem! Add extra hoppers to the red glass list
|
||||||
redGlass.add(block.getLocation());
|
redGlass.add(v);
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// This is the first hopper
|
// This is the first hopper
|
||||||
gh.setRoofHopperLocation(block.getLocation());
|
gh.setRoofHopperLocation(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,7 +239,7 @@ public class GreenhouseFinder {
|
|||||||
/**
|
/**
|
||||||
* @return the redGlass
|
* @return the redGlass
|
||||||
*/
|
*/
|
||||||
public Set<Location> getRedGlass() {
|
public Set<Vector> getRedGlass() {
|
||||||
return redGlass;
|
return redGlass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,35 +247,28 @@ public class GreenhouseFinder {
|
|||||||
* @return the wallDoors
|
* @return the wallDoors
|
||||||
*/
|
*/
|
||||||
int getWallDoors() {
|
int getWallDoors() {
|
||||||
return wallDoors;
|
return counterCheck.doorCount;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param wallDoors the wallDoors to set
|
|
||||||
*/
|
|
||||||
void setWallDoors(int wallDoors) {
|
|
||||||
this.wallDoors = wallDoors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the ghHopper
|
* @return the ghHopper
|
||||||
*/
|
*/
|
||||||
int getGhHopper() {
|
int getGhHopper() {
|
||||||
return ghHopper;
|
return counterCheck.hopperCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the airHoles
|
* @return the airHoles
|
||||||
*/
|
*/
|
||||||
boolean isAirHoles() {
|
boolean isAirHoles() {
|
||||||
return airHoles;
|
return counterCheck.airHole;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the otherBlocks
|
* @return the otherBlocks
|
||||||
*/
|
*/
|
||||||
boolean isOtherBlocks() {
|
boolean isOtherBlocks() {
|
||||||
return otherBlocks;
|
return counterCheck.otherBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -279,27 +292,6 @@ public class GreenhouseFinder {
|
|||||||
return wallBlockCount;
|
return wallBlockCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ghHopper the ghHopper to set
|
|
||||||
*/
|
|
||||||
void setGhHopper(int ghHopper) {
|
|
||||||
this.ghHopper = ghHopper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param airHoles the airHoles to set
|
|
||||||
*/
|
|
||||||
void setAirHoles(boolean airHoles) {
|
|
||||||
this.airHoles = airHoles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param otherBlocks the otherBlocks to set
|
|
||||||
*/
|
|
||||||
void setOtherBlocks(boolean otherBlocks) {
|
|
||||||
this.otherBlocks = otherBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param inCeiling the inCeiling to set
|
* @param inCeiling the inCeiling to set
|
||||||
*/
|
*/
|
||||||
@ -321,4 +313,30 @@ public class GreenhouseFinder {
|
|||||||
this.wallBlockCount = wallBlockCount;
|
this.wallBlockCount = wallBlockCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param gh the gh to set
|
||||||
|
*/
|
||||||
|
protected void setGh(Greenhouse gh) {
|
||||||
|
this.gh = gh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGhHopper(int i) {
|
||||||
|
counterCheck.hopperCount = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWallDoors(int i) {
|
||||||
|
counterCheck.doorCount = i;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAirHoles(boolean b) {
|
||||||
|
counterCheck.airHole = b;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOtherBlocks(boolean b) {
|
||||||
|
counterCheck.otherBlock = b;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package world.bentobox.greenhouses.managers;
|
package world.bentobox.greenhouses.managers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.util.BoundingBox;
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
|
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
|
||||||
import world.bentobox.bentobox.database.Database;
|
import world.bentobox.bentobox.database.Database;
|
||||||
@ -91,29 +96,19 @@ public class GreenhouseManager implements Listener {
|
|||||||
handler.loadObjects().forEach(g -> {
|
handler.loadObjects().forEach(g -> {
|
||||||
GreenhouseResult result = map.addGreenhouse(g);
|
GreenhouseResult result = map.addGreenhouse(g);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case FAIL_NO_ISLAND:
|
case FAIL_NO_ISLAND ->
|
||||||
// Delete the failed greenhouse
|
// Delete the failed greenhouse
|
||||||
toBeRemoved.add(g);
|
toBeRemoved.add(g);
|
||||||
break;
|
case FAIL_OVERLAPPING -> addon.logError("Greenhouse overlaps with another greenhouse. Skipping...");
|
||||||
case FAIL_OVERLAPPING:
|
case NULL -> addon.logError("Null location of greenhouse. Cannot load. Skipping...");
|
||||||
addon.logError("Greenhouse overlaps with another greenhouse. Skipping...");
|
case SUCCESS -> activateGreenhouse(g);
|
||||||
break;
|
case FAIL_NO_WORLD -> addon.logError("Database contains greenhouse for a non-loaded world. Skipping...");
|
||||||
case NULL:
|
case FAIL_UNKNOWN_RECIPE -> {
|
||||||
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:
|
|
||||||
addon.logError("Greenhouse uses a recipe that does not exist in the biomes.yml. Skipping...");
|
addon.logError("Greenhouse uses a recipe that does not exist in the biomes.yml. Skipping...");
|
||||||
addon.logError("Greenhouse Id " + g.getUniqueId());
|
addon.logError("Greenhouse Id " + g.getUniqueId());
|
||||||
break;
|
}
|
||||||
default:
|
default -> {
|
||||||
break;
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addon.log("Loaded " + map.getSize() + " greenhouses.");
|
addon.log("Loaded " + map.getSize() + " greenhouses.");
|
||||||
@ -121,27 +116,28 @@ public class GreenhouseManager implements Listener {
|
|||||||
toBeRemoved.forEach(handler::deleteObject);
|
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
|
* Removes the greenhouse from the world and resets biomes
|
||||||
* @param g - greenhouse
|
* @param gh - greenhouse
|
||||||
*/
|
*/
|
||||||
public void removeGreenhouse(Greenhouse g) {
|
public void removeGreenhouse(Greenhouse gh) {
|
||||||
handler.deleteObject(g);
|
handler.deleteObject(gh);
|
||||||
map.removeGreenhouse(g);
|
map.removeGreenhouse(gh);
|
||||||
addon.log("Returning biome to original state: " + g.getOriginalBiome().toString());
|
if (gh.getOriginalBiome() == null) {
|
||||||
for (int x = (int)g.getBoundingBox().getMinX(); x<= (int)g.getBoundingBox().getMaxX(); x+=4) {
|
addon.logError("Greenhouse had no original biome: " + gh.getLocation());
|
||||||
for (int z = (int)g.getBoundingBox().getMinZ(); z<= (int)g.getBoundingBox().getMaxZ(); z+=4) {
|
return;
|
||||||
for (int y = (int)g.getBoundingBox().getMinY(); y<= (int)g.getBoundingBox().getMaxY(); y+=4) {
|
}
|
||||||
|
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: " + 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
|
// Set back to the original biome
|
||||||
g.getLocation().getWorld().setBiome(x, y, z, g.getOriginalBiome());
|
gh.getLocation().getWorld().setBiome(x, y, z, gh.getOriginalBiome());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,39 +149,83 @@ public class GreenhouseManager implements Listener {
|
|||||||
* If type is stated then only this specific type will be checked
|
* If type is stated then only this specific type will be checked
|
||||||
* @param location - location to start search from
|
* @param location - location to start search from
|
||||||
* @param greenhouseRecipe - recipe requested, or null for a best-effort search
|
* @param greenhouseRecipe - recipe requested, or null for a best-effort search
|
||||||
* @return - greenhouse result {@link GhResult}
|
* @return - future greenhouse result {@link GhResult}
|
||||||
*/
|
*/
|
||||||
public GhResult tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) {
|
public CompletableFuture<GhResult> tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) {
|
||||||
GreenhouseFinder finder = new GreenhouseFinder();
|
CompletableFuture<GhResult> r = new CompletableFuture<>();
|
||||||
Set<GreenhouseResult> resultSet = finder.find(location);
|
GreenhouseFinder finder = new GreenhouseFinder(addon);
|
||||||
|
finder.find(location).thenAccept(resultSet -> {
|
||||||
if (!resultSet.isEmpty()) {
|
if (!resultSet.isEmpty()) {
|
||||||
// Failure!
|
// Failure!
|
||||||
return new GhResult().setFinder(finder).setResults(resultSet);
|
r.complete(new GhResult().setFinder(finder).setResults(resultSet));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Check if the greenhouse meets the requested recipe
|
// Check if the greenhouse meets the requested recipe
|
||||||
if (greenhouseRecipe != null) {
|
if (greenhouseRecipe != null) {
|
||||||
resultSet = greenhouseRecipe.checkRecipe(finder.getGh());
|
checkRecipe(finder, greenhouseRecipe, resultSet).thenAccept(r::complete);
|
||||||
if (resultSet.isEmpty()) {
|
return;
|
||||||
|
}
|
||||||
|
// Try ordered recipes
|
||||||
|
findRecipe(finder).thenAccept(rs -> {
|
||||||
|
resultSet.addAll(rs);
|
||||||
|
r.complete(new GhResult().setFinder(finder).setResults(resultSet));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to match the greenhouse to a recipe by going through all of them in order
|
||||||
|
* @param finder - finder object
|
||||||
|
*/
|
||||||
|
private CompletableFuture<Set<GreenhouseResult>> findRecipe(GreenhouseFinder finder) {
|
||||||
|
CompletableFuture<Set<GreenhouseResult>> r = new CompletableFuture<>();
|
||||||
|
// Get sorted list of all recipes
|
||||||
|
List<BiomeRecipe> list = addon.getRecipes().getBiomeRecipes().stream().sorted().collect(Collectors.toList());
|
||||||
|
findRecipe(r, list, finder);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findRecipe(CompletableFuture<Set<GreenhouseResult>> r, List<BiomeRecipe> list,
|
||||||
|
GreenhouseFinder finder) {
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
r.complete(Collections.singleton(GreenhouseResult.FAIL_NO_RECIPE_FOUND));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BiomeRecipe br = list.get(0);
|
||||||
|
list.remove(0);
|
||||||
|
br.checkRecipe(finder.getGh()).thenAccept(results -> {
|
||||||
|
if (results.isEmpty()) {
|
||||||
|
r.complete(Collections.singleton(GreenhouseResult.SUCCESS));
|
||||||
|
} else {
|
||||||
|
findRecipe(r, list, finder);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if the greenhouse meets the designated recipe and returns the result
|
||||||
|
* @param finder - finder object
|
||||||
|
* @param greenhouseRecipe - recipe requested
|
||||||
|
* @param resultSet - result set from finder
|
||||||
|
* @return Greenhouse result
|
||||||
|
*/
|
||||||
|
CompletableFuture<GhResult> checkRecipe(GreenhouseFinder finder, BiomeRecipe greenhouseRecipe, Set<GreenhouseResult> resultSet) {
|
||||||
|
CompletableFuture<GhResult> r = new CompletableFuture<>();
|
||||||
|
greenhouseRecipe.checkRecipe(finder.getGh()).thenAccept(rs -> {
|
||||||
|
if (rs.isEmpty()) {
|
||||||
// Success - set recipe and add to map
|
// Success - set recipe and add to map
|
||||||
finder.getGh().setBiomeRecipe(greenhouseRecipe);
|
finder.getGh().setBiomeRecipe(greenhouseRecipe);
|
||||||
resultSet.add(map.addGreenhouse(finder.getGh()));
|
resultSet.add(map.addGreenhouse(finder.getGh()));
|
||||||
activateGreenhouse(finder.getGh());
|
activateGreenhouse(finder.getGh());
|
||||||
handler.saveObjectAsync(finder.getGh());
|
handler.saveObjectAsync(finder.getGh());
|
||||||
|
rs.addAll(resultSet);
|
||||||
}
|
}
|
||||||
return new GhResult().setFinder(finder).setResults(resultSet);
|
GhResult recipe = new GhResult().setFinder(finder).setResults(rs);
|
||||||
}
|
r.complete(recipe);
|
||||||
|
});
|
||||||
// Try ordered recipes
|
return r;
|
||||||
resultSet.add(addon.getRecipes().getBiomeRecipes().stream().sorted()
|
|
||||||
.filter(r -> r.checkRecipe(finder.getGh()).isEmpty()).findFirst()
|
|
||||||
.map(r -> {
|
|
||||||
// Success - set recipe and add to map
|
|
||||||
finder.getGh().setBiomeRecipe(r);
|
|
||||||
activateGreenhouse(finder.getGh());
|
|
||||||
handler.saveObjectAsync(finder.getGh());
|
|
||||||
return map.addGreenhouse(finder.getGh());
|
|
||||||
}).orElse(GreenhouseResult.FAIL_NO_RECIPE_FOUND));
|
|
||||||
return new GhResult().setFinder(finder).setResults(resultSet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void activateGreenhouse(Greenhouse gh) {
|
private void activateGreenhouse(Greenhouse gh) {
|
||||||
@ -194,10 +234,11 @@ public class GreenhouseManager implements Listener {
|
|||||||
addon.logError("Biome recipe error - no such biome for " + gh.getBiomeRecipe().getName());
|
addon.logError("Biome recipe error - no such biome for " + gh.getBiomeRecipe().getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int x = (int)gh.getBoundingBox().getMinX(); x < gh.getBoundingBox().getMaxX(); x+=4) {
|
final BoundingBox bb = gh.getBoundingBox();
|
||||||
for (int z = (int)gh.getBoundingBox().getMinZ(); z < gh.getBoundingBox().getMaxZ(); z+=4) {
|
for (int x = (int)bb.getMinX(); x < bb.getMaxX(); x+=4) {
|
||||||
for (int y = (int)gh.getBoundingBox().getMinY(); y < gh.getBoundingBox().getMaxY(); y+=4) {
|
for (int z = (int)bb.getMinZ(); z < bb.getMaxZ(); z+=4) {
|
||||||
gh.getWorld().setBiome(x, y, z, ghBiome);
|
for (int y = (int)bb.getMinY(); y < bb.getMaxY(); y+=4) {
|
||||||
|
Objects.requireNonNull(gh.getWorld()).setBiome(x, y, z, ghBiome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,7 +248,7 @@ public class GreenhouseManager implements Listener {
|
|||||||
* Result of the greenhouse make effort
|
* Result of the greenhouse make effort
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class GhResult {
|
public static class GhResult {
|
||||||
private Set<GreenhouseResult> results;
|
private Set<GreenhouseResult> results;
|
||||||
private GreenhouseFinder finder;
|
private GreenhouseFinder finder;
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
|
||||||
@ -34,7 +33,7 @@ public class GreenhouseMap {
|
|||||||
*/
|
*/
|
||||||
public GreenhouseResult addGreenhouse(Greenhouse greenhouse) {
|
public GreenhouseResult addGreenhouse(Greenhouse greenhouse) {
|
||||||
// Validation checks
|
// Validation checks
|
||||||
if (greenhouse.getBiomeRecipe() == null) {
|
if (greenhouse.getBiomeRecipe().getBiome() == null) {
|
||||||
return GreenhouseResult.FAIL_UNKNOWN_RECIPE;
|
return GreenhouseResult.FAIL_UNKNOWN_RECIPE;
|
||||||
}
|
}
|
||||||
if (greenhouse.getWorld() == null) {
|
if (greenhouse.getWorld() == null) {
|
||||||
@ -105,9 +104,11 @@ public class GreenhouseMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOverlapping(Greenhouse greenhouse) {
|
private boolean isOverlapping(Greenhouse greenhouse) {
|
||||||
return addon.getIslands().getIslandAt(greenhouse.getLocation()).map(i -> {
|
return greenhouse.getLocation() != null && addon.getIslands().getIslandAt(greenhouse.getLocation()).map(i -> {
|
||||||
greenhouses.putIfAbsent(i, new ArrayList<>());
|
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);
|
}).orElse(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -117,13 +118,15 @@ public class GreenhouseMap {
|
|||||||
* @param greenhouse - greenhouse
|
* @param greenhouse - greenhouse
|
||||||
*/
|
*/
|
||||||
protected void removeGreenhouse(Greenhouse greenhouse) {
|
protected void removeGreenhouse(Greenhouse greenhouse) {
|
||||||
|
if (greenhouse.getLocation() != null) {
|
||||||
addon.getIslands().getIslandAt(greenhouse.getLocation()).ifPresent(i -> {
|
addon.getIslands().getIslandAt(greenhouse.getLocation()).ifPresent(i -> {
|
||||||
if (greenhouses.containsKey(i)) greenhouses.get(i).remove(greenhouse);
|
if (greenhouses.containsKey(i)) greenhouses.get(i).remove(greenhouse);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param island
|
* @param island island
|
||||||
*/
|
*/
|
||||||
public void removeGreenhouses(Island island) {
|
public void removeGreenhouses(Island island) {
|
||||||
greenhouses.remove(island);
|
greenhouses.remove(island);
|
||||||
@ -134,7 +137,7 @@ public class GreenhouseMap {
|
|||||||
* @return a list of all the Greenhouses
|
* @return a list of all the Greenhouses
|
||||||
*/
|
*/
|
||||||
public List<Greenhouse> getGreenhouses() {
|
public List<Greenhouse> getGreenhouses() {
|
||||||
return greenhouses.values().stream().flatMap(List::stream).collect(Collectors.toList());
|
return greenhouses.values().stream().flatMap(List::stream).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ public class RecipeManager {
|
|||||||
private static final int MAXIMUM_INVENTORY_SIZE = 49;
|
private static final int MAXIMUM_INVENTORY_SIZE = 49;
|
||||||
private final Greenhouses addon;
|
private final Greenhouses addon;
|
||||||
private static final List<BiomeRecipe> biomeRecipes = new ArrayList<>();
|
private static final List<BiomeRecipe> biomeRecipes = new ArrayList<>();
|
||||||
|
private static final String COULD_NOT_PARSE = "Could not parse ";
|
||||||
|
|
||||||
public RecipeManager(Greenhouses addon) {
|
public RecipeManager(Greenhouses addon) {
|
||||||
this.addon = addon;
|
this.addon = addon;
|
||||||
@ -68,6 +70,7 @@ public class RecipeManager {
|
|||||||
}
|
}
|
||||||
ConfigurationSection biomeSection = biomeConfig.getConfigurationSection("biomes");
|
ConfigurationSection biomeSection = biomeConfig.getConfigurationSection("biomes");
|
||||||
// Loop through all the entries
|
// Loop through all the entries
|
||||||
|
assert biomeSection != null;
|
||||||
for (String type: biomeSection.getValues(false).keySet()) {
|
for (String type: biomeSection.getValues(false).keySet()) {
|
||||||
processEntries(type, biomeSection);
|
processEntries(type, biomeSection);
|
||||||
// Check maximum number
|
// Check maximum number
|
||||||
@ -82,6 +85,7 @@ public class RecipeManager {
|
|||||||
private void processEntries(String biomeType, ConfigurationSection biomeSection) {
|
private void processEntries(String biomeType, ConfigurationSection biomeSection) {
|
||||||
try {
|
try {
|
||||||
ConfigurationSection biomeRecipeConfig = biomeSection.getConfigurationSection(biomeType);
|
ConfigurationSection biomeRecipeConfig = biomeSection.getConfigurationSection(biomeType);
|
||||||
|
assert biomeRecipeConfig != null;
|
||||||
Biome thisBiome = loadBiome(biomeType, biomeRecipeConfig);
|
Biome thisBiome = loadBiome(biomeType, biomeRecipeConfig);
|
||||||
if (thisBiome == null) return;
|
if (thisBiome == null) return;
|
||||||
int priority = biomeRecipeConfig.getInt("priority", 0);
|
int priority = biomeRecipeConfig.getInt("priority", 0);
|
||||||
@ -124,7 +128,7 @@ public class RecipeManager {
|
|||||||
addon.logError("No biome defined in the biome reciepe " + biomeType + ". Skipping...");
|
addon.logError("No biome defined in the biome reciepe " + biomeType + ". Skipping...");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String name = biomeRecipeConfig.getString("biome").toUpperCase(Locale.ENGLISH);
|
String name = Objects.requireNonNull(biomeRecipeConfig.getString("biome")).toUpperCase(Locale.ENGLISH);
|
||||||
if (Enums.getIfPresent(Biome.class, name).isPresent()) {
|
if (Enums.getIfPresent(Biome.class, name).isPresent()) {
|
||||||
return Biome.valueOf(name);
|
return Biome.valueOf(name);
|
||||||
}
|
}
|
||||||
@ -152,6 +156,7 @@ public class RecipeManager {
|
|||||||
b.setLavacoverage(biomeRecipeConfig.getInt("lavacoverage",-1));
|
b.setLavacoverage(biomeRecipeConfig.getInt("lavacoverage",-1));
|
||||||
b.setIcecoverage(biomeRecipeConfig.getInt("icecoverage",-1));
|
b.setIcecoverage(biomeRecipeConfig.getInt("icecoverage",-1));
|
||||||
b.setMobLimit(biomeRecipeConfig.getInt("moblimit", 9));
|
b.setMobLimit(biomeRecipeConfig.getInt("moblimit", 9));
|
||||||
|
b.setMaxMob(biomeRecipeConfig.getInt("maxmobs", -1));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,44 +180,59 @@ public class RecipeManager {
|
|||||||
ConfigurationSection conversionSec = biomeRecipeConfig.getConfigurationSection("conversions");
|
ConfigurationSection conversionSec = biomeRecipeConfig.getConfigurationSection("conversions");
|
||||||
if (conversionSec != null) {
|
if (conversionSec != null) {
|
||||||
for (String oldMat : conversionSec.getKeys(false)) {
|
for (String oldMat : conversionSec.getKeys(false)) {
|
||||||
try {
|
parseConversions(oldMat, conversionSec, b);
|
||||||
Material oldMaterial = Material.valueOf(oldMat.toUpperCase(Locale.ENGLISH));
|
|
||||||
String conversions = conversionSec.getString(oldMat);
|
|
||||||
if (!conversions.isEmpty()) {
|
|
||||||
String[] split = conversions.split(":");
|
|
||||||
double convChance = Double.parseDouble(split[0]);
|
|
||||||
Material newMaterial = Material.valueOf(split[1]);
|
|
||||||
Material localMaterial = Material.valueOf(split[2]);
|
|
||||||
b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
addon.logError("Could not parse " + oldMat);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get the list of conversions
|
// Get the list of conversions
|
||||||
for (String oldMat : biomeRecipeConfig.getStringList("conversion-list")) {
|
for (String oldMat : biomeRecipeConfig.getStringList("conversion-list")) {
|
||||||
|
parseConversionList(oldMat, b);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseConversionList(String oldMat, BiomeRecipe b) {
|
||||||
try {
|
try {
|
||||||
// Split the string
|
// Split the string
|
||||||
String[] split = oldMat.split(":");
|
String[] split = oldMat.split(":");
|
||||||
Material oldMaterial = Material.valueOf(split[0].toUpperCase());
|
Material oldMaterial = Material.valueOf(split[0].toUpperCase());
|
||||||
double convChance = Double.parseDouble(split[1]);
|
double convChance = Double.parseDouble(split[1]);
|
||||||
Material newMaterial = Material.valueOf(split[2]);
|
Material newMaterial = Material.valueOf(split[2]);
|
||||||
Material localMaterial = Material.valueOf(split[3]);
|
Material localMaterial = null;
|
||||||
|
if(split.length > 3) {
|
||||||
|
localMaterial = Material.valueOf(split[3]);
|
||||||
|
}
|
||||||
b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
addon.logError("Could not parse " + oldMat);
|
addon.logError(COULD_NOT_PARSE + oldMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void parseConversions(String oldMat, ConfigurationSection conversionSec, BiomeRecipe b) {
|
||||||
|
try {
|
||||||
|
Material oldMaterial = Material.valueOf(oldMat.toUpperCase(Locale.ENGLISH));
|
||||||
|
String conversions = conversionSec.getString(oldMat);
|
||||||
|
if (!Objects.requireNonNull(conversions).isEmpty()) {
|
||||||
|
String[] split = conversions.split(":");
|
||||||
|
double convChance = Double.parseDouble(split[0]);
|
||||||
|
Material newMaterial = Material.valueOf(split[1]);
|
||||||
|
Material localMaterial = null;
|
||||||
|
if(split.length > 2) {
|
||||||
|
localMaterial = Material.valueOf(split[2]);
|
||||||
|
}
|
||||||
|
b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
addon.logError(COULD_NOT_PARSE + oldMat);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadMobs(ConfigurationSection biomeRecipeConfig, BiomeRecipe b) {
|
private void loadMobs(ConfigurationSection biomeRecipeConfig, BiomeRecipe b) {
|
||||||
ConfigurationSection temp = biomeRecipeConfig.getConfigurationSection("mobs");
|
ConfigurationSection temp = biomeRecipeConfig.getConfigurationSection("mobs");
|
||||||
// Mob EntityType: Probability:Spawn on Material
|
// Mob EntityType: Probability:Spawn on Material
|
||||||
if (temp != null) {
|
if (temp != null) {
|
||||||
((HashMap<String,Object>)temp.getValues(false)).entrySet().forEach(s -> parseMob(s,b));
|
temp.getValues(false).entrySet().forEach(s -> parseMob(s,b));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -225,7 +245,7 @@ public class RecipeManager {
|
|||||||
Material mobSpawnOn = Material.valueOf(split[1]);
|
Material mobSpawnOn = Material.valueOf(split[1]);
|
||||||
b.addMobs(mobType, mobProbability, mobSpawnOn);
|
b.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
addon.logError("Could not parse " + s.getKey());
|
addon.logError(COULD_NOT_PARSE + s.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
package world.bentobox.greenhouses.ui.admin;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
|
||||||
import world.bentobox.bentobox.api.user.User;
|
|
||||||
import world.bentobox.greenhouses.Greenhouses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class handles commands for admins
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class AdminCmd extends CompositeCommand {
|
|
||||||
|
|
||||||
public AdminCmd(Greenhouses greenhouses) {
|
|
||||||
super(greenhouses, "gadmin");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
this.setPermission("greenhouses.admin");
|
|
||||||
this.setOnlyPlayer(false);
|
|
||||||
this.setParametersHelp("greenhouses.admin.parameters");
|
|
||||||
this.setDescription("greenhouses.admin.description");
|
|
||||||
|
|
||||||
new GreenhousesAdminReloadCommand(this);
|
|
||||||
new GreenhousesAdminInfoCommand(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(User user, String label, List<String> args) {
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
case 1:
|
|
||||||
if (split[0].equalsIgnoreCase("reload")) {
|
|
||||||
plugin.reloadConfig();
|
|
||||||
plugin.loadPluginConfig();
|
|
||||||
plugin.loadBiomeRecipes();
|
|
||||||
plugin.ecoTick();
|
|
||||||
sender.sendMessage(ChatColor.YELLOW + Locale.reloadconfigReloaded);
|
|
||||||
return true;
|
|
||||||
} else if (split[0].equalsIgnoreCase("info")) {
|
|
||||||
if (!(sender instanceof Player)) {
|
|
||||||
sender.sendMessage(ChatColor.RED + Locale.admininfoerror);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Player player = (Player)sender;
|
|
||||||
Greenhouse greenhouse = players.getInGreenhouse(player);
|
|
||||||
if (greenhouse == null) {
|
|
||||||
sender.sendMessage(ChatColor.RED + Locale.admininfoerror2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
sender.sendMessage(ChatColor.GREEN + Locale.infoinfo);
|
|
||||||
sender.sendMessage(ChatColor.GREEN + Locale.generalowner + ":" + greenhouse.getPlayerName());
|
|
||||||
sender.sendMessage(ChatColor.GREEN + Locale.admininfoflags);
|
|
||||||
for (String flag : greenhouse.getFlags().keySet()) {
|
|
||||||
sender.sendMessage(flag + ": " + greenhouse.getFlags().get(flag));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(ChatColor.RED + Locale.errorunknownCommand);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
if (split[0].equalsIgnoreCase("info")) {
|
|
||||||
sender.sendMessage(ChatColor.GREEN + Locale.infoinfo);
|
|
||||||
int index = 0;
|
|
||||||
boolean found = false;
|
|
||||||
for (Greenhouse g : plugin.getGreenhouses()) {
|
|
||||||
if (g.getPlayerName().equalsIgnoreCase(split[1])) {
|
|
||||||
if (!found)
|
|
||||||
sender.sendMessage(ChatColor.GREEN + Locale.generalowner + ":" + g.getPlayerName());
|
|
||||||
found = true;
|
|
||||||
sender.sendMessage("Greenhouse #" + (++index));
|
|
||||||
sender.sendMessage("Biome: " + g.getBiome().name());
|
|
||||||
sender.sendMessage("Recipe: " + g.getBiomeRecipe().getFriendlyName());
|
|
||||||
sender.sendMessage(g.getWorld().getName());
|
|
||||||
sender.sendMessage(g.getPos1().getBlockX() + ", " + g.getPos1().getBlockZ() + " to " + g.getPos2().getBlockX() + ", " + g.getPos2().getBlockZ());
|
|
||||||
sender.sendMessage("Base at " + g.getPos1().getBlockY());
|
|
||||||
sender.sendMessage("Height = " + g.getHeight());
|
|
||||||
sender.sendMessage("Area = " + g.getArea());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
if (index == 0) {
|
|
||||||
sender.sendMessage("Player has no greenhouses.");
|
|
||||||
} else {
|
|
||||||
Player player = plugin.getServer().getPlayer(split[1]);
|
|
||||||
if (player != null) {
|
|
||||||
sender.sendMessage("Player has " + index + " greenhouses and is allowed to build " + plugin.getMaxGreenhouses(player));
|
|
||||||
} else {
|
|
||||||
sender.sendMessage("Player has " + index + " greenhouses. Player is offline.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(ChatColor.RED + "Cannot find that player. (May not have logged on recently)");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(ChatColor.RED + Locale.errorunknownCommand);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package world.bentobox.greenhouses.ui.admin;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
|
||||||
import world.bentobox.bentobox.api.user.User;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tastybento
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class GreenhousesAdminInfoCommand extends CompositeCommand {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param parent - parent user command, e.g, /island
|
|
||||||
*/
|
|
||||||
public GreenhousesAdminInfoCommand(CompositeCommand parent) {
|
|
||||||
super(parent, "info");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see world.bentobox.bentobox.api.commands.BentoBoxCommand#setup()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see world.bentobox.bentobox.api.commands.BentoBoxCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean execute(User user, String label, List<String> args) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package world.bentobox.greenhouses.ui.admin;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
|
||||||
import world.bentobox.bentobox.api.user.User;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tastybento
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class GreenhousesAdminReloadCommand extends CompositeCommand {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param parent - parent command
|
|
||||||
*/
|
|
||||||
public GreenhousesAdminReloadCommand(CompositeCommand parent) {
|
|
||||||
super(parent, "reload");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see world.bentobox.bentobox.api.commands.BentoBoxCommand#setup()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see world.bentobox.bentobox.api.commands.BentoBoxCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean execute(User user, String label, List<String> args) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -13,7 +13,7 @@ import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
|||||||
public class Panel {
|
public class Panel {
|
||||||
|
|
||||||
private static final String COVERAGE = "[coverage]";
|
private static final String COVERAGE = "[coverage]";
|
||||||
private Greenhouses addon;
|
private final Greenhouses addon;
|
||||||
|
|
||||||
public Panel(Greenhouses addon) {
|
public Panel(Greenhouses addon) {
|
||||||
super();
|
super();
|
||||||
|
@ -22,8 +22,8 @@ import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
|||||||
*/
|
*/
|
||||||
public class PanelClick implements ClickHandler {
|
public class PanelClick implements ClickHandler {
|
||||||
|
|
||||||
private Greenhouses addon;
|
private final Greenhouses addon;
|
||||||
private BiomeRecipe br;
|
private final BiomeRecipe br;
|
||||||
|
|
||||||
public PanelClick(Greenhouses addon, BiomeRecipe br) {
|
public PanelClick(Greenhouses addon, BiomeRecipe br) {
|
||||||
this.addon = addon;
|
this.addon = addon;
|
||||||
@ -55,22 +55,24 @@ public class PanelClick implements ClickHandler {
|
|||||||
user.sendMessage("greenhouses.commands.user.make.error.already");
|
user.sendMessage("greenhouses.commands.user.make.error.already");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
GhResult result = addon.getManager().tryToMakeGreenhouse(location, br);
|
addon.getManager().tryToMakeGreenhouse(location, br).thenAccept(r -> processResult(user, r));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void processResult(User user, GhResult result) {
|
||||||
if (result.getResults().contains(GreenhouseResult.SUCCESS)) {
|
if (result.getResults().contains(GreenhouseResult.SUCCESS)) {
|
||||||
// Success
|
// Success
|
||||||
user.sendMessage("greenhouses.commands.user.make.success", "[biome]", result.getFinder().getGh().getBiomeRecipe().getFriendlyName());
|
user.sendMessage("greenhouses.commands.user.make.success", "[biome]", result.getFinder().getGh().getBiomeRecipe().getFriendlyName());
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
result.getResults().forEach(r -> user.sendMessage("greenhouses.commands.user.make.error." + r.name()));
|
result.getResults().forEach(r -> user.sendMessage("greenhouses.commands.user.make.error." + r.name()));
|
||||||
if (!result.getFinder().getRedGlass().isEmpty()) {
|
if (!result.getFinder().getRedGlass().isEmpty()) {
|
||||||
// Show red glass
|
// Show red glass
|
||||||
result.getFinder().getRedGlass().forEach(rg -> user.getPlayer().sendBlockChange(rg, Material.RED_STAINED_GLASS.createBlockData()));
|
result.getFinder().getRedGlass().stream().map(v -> v.toLocation(user.getWorld())).forEach(rg -> user.getPlayer().sendBlockChange(rg, Material.RED_STAINED_GLASS.createBlockData()));
|
||||||
Bukkit.getScheduler().runTaskLater(addon.getPlugin(), () -> result.getFinder().getRedGlass().forEach(rg -> user.getPlayer().sendBlockChange(rg, rg.getBlock().getBlockData())), 120L);
|
Bukkit.getScheduler().runTaskLater(addon.getPlugin(), () -> result.getFinder().getRedGlass().stream().map(v -> v.toLocation(user.getWorld())).forEach(rg -> user.getPlayer().sendBlockChange(rg, rg.getBlock().getBlockData())), 120L);
|
||||||
}
|
}
|
||||||
if (result.getResults().contains(GreenhouseResult.FAIL_INSUFFICIENT_BLOCKS)) {
|
if (result.getResults().contains(GreenhouseResult.FAIL_INSUFFICIENT_BLOCKS)) {
|
||||||
result.getFinder().getGh().getMissingBlocks().forEach((k,v) -> user.sendMessage("greenhouses.commands.user.make.missing-blocks", "[material]", Util.prettifyText(k.toString()), TextVariables.NUMBER, String.valueOf(v)));
|
result.getFinder().getGh().getMissingBlocks().forEach((k,v) -> user.sendMessage("greenhouses.commands.user.make.missing-blocks", "[material]", Util.prettifyText(k.toString()), TextVariables.NUMBER, String.valueOf(v)));
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class MakeCommand extends CompositeCommand {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(User user, String label, List<String> args) {
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
if (args.isEmpty()) {
|
if (args.isEmpty()) {
|
||||||
new Panel((Greenhouses)this.getAddon()).showPanel(user);
|
new Panel(this.getAddon()).showPanel(user);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Check recipe given matches
|
// Check recipe given matches
|
||||||
@ -76,16 +76,21 @@ class MakeCommand extends CompositeCommand {
|
|||||||
return getRecipes(user).get(arg);
|
return getRecipes(user).get(arg);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get a string list of recipies the player has permission to use
|
* Get a string list of recipes the player has permission to use
|
||||||
* @param user - user
|
* @param user - user
|
||||||
* @return list
|
* @return list
|
||||||
*/
|
*/
|
||||||
private Map<String, BiomeRecipe> getRecipes(User user) {
|
private Map<String, BiomeRecipe> getRecipes(User user) {
|
||||||
return ((Greenhouses)getAddon()).getRecipes().getBiomeRecipes().stream()
|
return ((Greenhouses)getAddon()).getRecipes().getBiomeRecipes().stream()
|
||||||
.filter(br -> user.hasPermission(br.getPermission()))
|
.filter(br -> user.hasPermission(br.getPermission()))
|
||||||
.collect(Collectors.toMap(br -> br.getName(), br -> br));
|
.collect(Collectors.toMap(BiomeRecipe::getName, br -> br));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param user - user
|
||||||
|
* @param br requested biome recipe, or null to try anything
|
||||||
|
* @return true if successful
|
||||||
|
*/
|
||||||
private boolean makeGreenhouse(User user, BiomeRecipe br) {
|
private boolean makeGreenhouse(User user, BiomeRecipe br) {
|
||||||
// Check flag
|
// Check flag
|
||||||
if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.isAllowed(user, Greenhouses.GREENHOUSES)).orElse(false)) {
|
if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.isAllowed(user, Greenhouses.GREENHOUSES)).orElse(false)) {
|
||||||
@ -99,7 +104,12 @@ class MakeCommand extends CompositeCommand {
|
|||||||
user.sendMessage("greenhouses.commands.user.make.error.already");
|
user.sendMessage("greenhouses.commands.user.make.error.already");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
GhResult result = ((Greenhouses)this.getAddon()).getManager().tryToMakeGreenhouse(location, br);
|
// Try to make the greenhouse
|
||||||
|
((Greenhouses)this.getAddon()).getManager().tryToMakeGreenhouse(location, br).thenAccept(result -> informUser(user, br, result));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean informUser(User user, BiomeRecipe br, GhResult result) {
|
||||||
if (result.getResults().contains(GreenhouseResult.SUCCESS)) {
|
if (result.getResults().contains(GreenhouseResult.SUCCESS)) {
|
||||||
// Success
|
// Success
|
||||||
user.sendMessage("greenhouses.commands.user.make.success", "[biome]", result.getFinder().getGh().getBiomeRecipe().getFriendlyName());
|
user.sendMessage("greenhouses.commands.user.make.success", "[biome]", result.getFinder().getGh().getBiomeRecipe().getFriendlyName());
|
||||||
@ -108,18 +118,18 @@ class MakeCommand extends CompositeCommand {
|
|||||||
result.getResults().forEach(r -> user.sendMessage("greenhouses.commands.user.make.error." + r.name()));
|
result.getResults().forEach(r -> user.sendMessage("greenhouses.commands.user.make.error." + r.name()));
|
||||||
if (!result.getFinder().getRedGlass().isEmpty()) {
|
if (!result.getFinder().getRedGlass().isEmpty()) {
|
||||||
// Show red glass
|
// Show red glass
|
||||||
result.getFinder().getRedGlass().forEach(rg -> user.getPlayer().sendBlockChange(rg, Material.RED_STAINED_GLASS.createBlockData()));
|
result.getFinder().getRedGlass().forEach(rg -> user.getPlayer().sendBlockChange(rg.toLocation(user.getWorld()), Material.RED_STAINED_GLASS.createBlockData()));
|
||||||
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> result.getFinder().getRedGlass().forEach(rg -> user.getPlayer().sendBlockChange(rg, rg.getBlock().getBlockData())), 120L);
|
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> result.getFinder().getRedGlass().stream().map(v -> v.toLocation(user.getWorld())).forEach(rg -> user.getPlayer().sendBlockChange(rg, rg.getBlock().getBlockData())), 120L);
|
||||||
}
|
}
|
||||||
if (br != null && result.getResults().contains(GreenhouseResult.FAIL_INSUFFICIENT_BLOCKS)) {
|
if (br != null && result.getResults().contains(GreenhouseResult.FAIL_INSUFFICIENT_BLOCKS)) {
|
||||||
result.getFinder().getGh().getMissingBlocks().forEach((k,v) -> user.sendMessage("greenhouses.commands.user.make.missing-blocks", "[material]", Util.prettifyText(k.toString()), TextVariables.NUMBER, String.valueOf(v)));
|
result.getFinder().getGh().getMissingBlocks().forEach((k,v) -> user.sendMessage("greenhouses.commands.user.make.missing-blocks", "[material]", Util.prettifyText(k.toString()), TextVariables.NUMBER, String.valueOf(v)));
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
|
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
|
||||||
return Optional.of(new ArrayList<String>(this.getRecipes(user).keySet()));
|
return Optional.of(new ArrayList<>(this.getRecipes(user).keySet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class RemoveCommand extends CompositeCommand {
|
|||||||
user.sendMessage("greenhouses.errors.no-rank");
|
user.sendMessage("greenhouses.errors.no-rank");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Greenhouses addon = ((Greenhouses)this.getAddon());
|
Greenhouses addon = this.getAddon();
|
||||||
// Remove greenhouse if it exists
|
// Remove greenhouse if it exists
|
||||||
if (!addon.getManager().getMap().getGreenhouse(user.getLocation()).map(gh -> {
|
if (!addon.getManager().getMap().getGreenhouse(user.getLocation()).map(gh -> {
|
||||||
user.sendMessage("general.success");
|
user.sendMessage("general.success");
|
||||||
|
@ -30,8 +30,7 @@ public class UserCommand extends CompositeCommand {
|
|||||||
public void setup() {
|
public void setup() {
|
||||||
this.setPermission("greenhouses.player");
|
this.setPermission("greenhouses.player");
|
||||||
this.setOnlyPlayer(true);
|
this.setOnlyPlayer(true);
|
||||||
this.setParametersHelp("greenhouses.command.parameters");
|
this.setDescription("greenhouses.commands.user.description");
|
||||||
this.setDescription("greenhouses.command.description");
|
|
||||||
|
|
||||||
//new InfoCommand(this);
|
//new InfoCommand(this);
|
||||||
//new ListCommand(this);
|
//new ListCommand(this);
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
package world.bentobox.greenhouses.world;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChunkSnapshot;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.World.Environment;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.util.Pair;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a thread-safe cache world chunks
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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(Greenhouses addon, World world) {
|
||||||
|
this.world = world;
|
||||||
|
cache = new HashMap<>();
|
||||||
|
this.addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the world's environment
|
||||||
|
*/
|
||||||
|
public Environment getEnvironment() {
|
||||||
|
return world.getEnvironment();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return maximum height of this world
|
||||||
|
*/
|
||||||
|
public int getMaxHeight() {
|
||||||
|
return world.getMaxHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get chunk snapshot from world
|
||||||
|
* @param x - coord
|
||||||
|
* @param z - coord
|
||||||
|
* @return future chunk snapshot
|
||||||
|
*/
|
||||||
|
private CompletableFuture<ChunkSnapshot> getAChunk(int x, int z) {
|
||||||
|
CompletableFuture<ChunkSnapshot> r = new CompletableFuture<>();
|
||||||
|
Bukkit.getScheduler().runTask(addon.getPlugin(), () ->
|
||||||
|
Util.getChunkAtAsync(world, x, z).thenAccept(chunk -> r.complete(chunk.getChunkSnapshot())));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get snapshot from cache or world
|
||||||
|
* @param x - block coord
|
||||||
|
* @param z - block coord
|
||||||
|
* @return chunk snapshot or null if there's an error getting the chunk
|
||||||
|
* @throws ExecutionException - if the chunk getting throws an exception
|
||||||
|
* @throws InterruptedException - if the future is interrupted
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private ChunkSnapshot getSnap(final int x, final int z) throws InterruptedException, ExecutionException {
|
||||||
|
// Convert from block to chunk coords
|
||||||
|
Pair<Integer, Integer> key = new Pair<>((x >> 4), (z >> 4));
|
||||||
|
// Get from cache if it is available
|
||||||
|
if (cache.containsKey(key)) {
|
||||||
|
return cache.get(key);
|
||||||
|
}
|
||||||
|
// Block on getting the chunk because this is running async
|
||||||
|
ChunkSnapshot cs = getAChunk(key.x, key.z).get();
|
||||||
|
// Store in cache
|
||||||
|
cache.put(key, cs);
|
||||||
|
return cs;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get block material for block at corresponding coordinates
|
||||||
|
*
|
||||||
|
* @param x block coordinate
|
||||||
|
* @param y 0-255
|
||||||
|
* @param z block coordinate
|
||||||
|
* @return material type or Material.AIR if there is an exception
|
||||||
|
*/
|
||||||
|
public Material getBlockType(final int x, final int y, final int z) {
|
||||||
|
// Convert block coords to chunk coords
|
||||||
|
// TODO: simplify this - it must be easier than this!
|
||||||
|
int xx = x >= 0 ? x % 16 : (16 + (x % 16)) % 16;
|
||||||
|
int zz = z >= 0 ? z % 16 : (16 + (z % 16)) % 16;
|
||||||
|
try {
|
||||||
|
return Objects.requireNonNull(getSnap(x, z)).getBlockType(xx, y, zz);
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
addon.logError("Chunk could not be obtained async! " + e);
|
||||||
|
// Restore interrupted state...
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return Material.AIR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get block material for block at corresponding coordinates
|
||||||
|
* @param v - vector
|
||||||
|
* @return Material
|
||||||
|
*/
|
||||||
|
public Material getBlockType(Vector v) {
|
||||||
|
return getBlockType(v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if block is AIR
|
||||||
|
* @param vector - vector
|
||||||
|
* @return true if AIR
|
||||||
|
*/
|
||||||
|
public boolean isEmpty(Vector vector) {
|
||||||
|
return getBlockType(vector).equals(Material.AIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -35,11 +35,41 @@ biomes:
|
|||||||
# Entity name: % chance:Block on which the mob will spawn
|
# Entity name: % chance:Block on which the mob will spawn
|
||||||
mobs:
|
mobs:
|
||||||
SQUID: 10:WATER
|
SQUID: 10:WATER
|
||||||
|
GLOW_SQUID: 5:WATER
|
||||||
|
TURTLE: 10:SAND
|
||||||
# The minimum number of blocks each mob requires.
|
# The minimum number of blocks each mob requires.
|
||||||
# Mobs will not spawn if there is more than 1 per this number of
|
# 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
|
# 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
|
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
|
||||||
|
MANGROVE_SWAMP:
|
||||||
|
# Credit: angelknight89
|
||||||
|
friendlyname: "Mangrove Swamp"
|
||||||
|
biome: MANGROVE_SWAMP
|
||||||
|
icon: LILY_PAD
|
||||||
|
priority: 19
|
||||||
|
contents:
|
||||||
|
GRASS_BLOCK: 4
|
||||||
|
MANGROVE_ROOTS: 3
|
||||||
|
MANGROVE_LEAVES: 4
|
||||||
|
# 50% water coverage required
|
||||||
|
watercoverage: 50
|
||||||
|
conversions:
|
||||||
|
GRASS_BLOCK: 50:MUD:GRASS_BLOCK
|
||||||
|
plants:
|
||||||
|
MOSS_CARPET: 5:GRASS_BLOCK
|
||||||
|
LILY_PAD: 5:WATER
|
||||||
|
mobs:
|
||||||
|
FROG: 5:MUD
|
||||||
|
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: 10
|
||||||
Snowy_beach:
|
Snowy_beach:
|
||||||
friendlyname: "Snowy beach"
|
friendlyname: "Snowy beach"
|
||||||
biome: SNOWY_BEACH
|
biome: SNOWY_BEACH
|
||||||
@ -49,6 +79,9 @@ biomes:
|
|||||||
SAND: 1
|
SAND: 1
|
||||||
watercoverage: 50
|
watercoverage: 50
|
||||||
icecoverage: 10
|
icecoverage: 10
|
||||||
|
mobs:
|
||||||
|
SQUID: 10:WATER
|
||||||
|
GLOW_SQUID: 10:WATER
|
||||||
ThreeWolfMoon:
|
ThreeWolfMoon:
|
||||||
friendlyname: "Three Wolf Moon Forest"
|
friendlyname: "Three Wolf Moon Forest"
|
||||||
# Could do with more wolves, but the magic works with 3.
|
# Could do with more wolves, but the magic works with 3.
|
||||||
@ -63,11 +96,17 @@ biomes:
|
|||||||
plants:
|
plants:
|
||||||
TALL_GRASS: 10:GRASS_BLOCK
|
TALL_GRASS: 10:GRASS_BLOCK
|
||||||
mobs:
|
mobs:
|
||||||
WOLF: 10:SNOW
|
WOLF: 15:SNOW
|
||||||
|
FOX: 15:GRASS_BLOCK
|
||||||
|
RABBIT: 7:GRASS_BLOCK
|
||||||
moblimit: 9
|
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:
|
Cold_Rabbit:
|
||||||
friendlyname: "Cold Taiga Forest"
|
friendlyname: "Cold Taiga Forest"
|
||||||
biome: TAIGA_HILLS
|
biome: OLD_GROWTH_SPRUCE_TAIGA
|
||||||
icon: SPRUCE_SAPLING
|
icon: SPRUCE_SAPLING
|
||||||
priority: 20
|
priority: 20
|
||||||
contents:
|
contents:
|
||||||
@ -79,7 +118,12 @@ biomes:
|
|||||||
TALL_GRASS: 10:GRASS_BLOCK
|
TALL_GRASS: 10:GRASS_BLOCK
|
||||||
mobs:
|
mobs:
|
||||||
RABBIT: 10:SNOW
|
RABBIT: 10:SNOW
|
||||||
|
FOX: 7:GRASS_BLOCK
|
||||||
moblimit: 9
|
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:
|
DESERT:
|
||||||
friendlyname: "Desert"
|
friendlyname: "Desert"
|
||||||
biome: DESERT
|
biome: DESERT
|
||||||
@ -101,6 +145,16 @@ biomes:
|
|||||||
# Multiple conversions can be listed
|
# Multiple conversions can be listed
|
||||||
conversion-list:
|
conversion-list:
|
||||||
- DIRT:30:SAND:SAND
|
- 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:
|
FOREST:
|
||||||
friendlyname: "Flowery forest"
|
friendlyname: "Flowery forest"
|
||||||
biome: FLOWER_FOREST
|
biome: FLOWER_FOREST
|
||||||
@ -115,6 +169,17 @@ biomes:
|
|||||||
ORANGE_TULIP: 2:GRASS_BLOCK
|
ORANGE_TULIP: 2:GRASS_BLOCK
|
||||||
SUNFLOWER: 4:GRASS_BLOCK
|
SUNFLOWER: 4:GRASS_BLOCK
|
||||||
TALL_GRASS: 20: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:
|
NETHER:
|
||||||
friendlyname: "&cNether"
|
friendlyname: "&cNether"
|
||||||
biome: NETHER_WASTES
|
biome: NETHER_WASTES
|
||||||
@ -132,6 +197,10 @@ biomes:
|
|||||||
STRIDER: 10:LAVA
|
STRIDER: 10:LAVA
|
||||||
ENDERMAN: 5:NETHERRACK
|
ENDERMAN: 5:NETHERRACK
|
||||||
moblimit: 9
|
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
|
permission: greenhouses.biome.nether
|
||||||
SOUL_SAND_VALLEY:
|
SOUL_SAND_VALLEY:
|
||||||
friendlyname: "&cSoul Sand Valley"
|
friendlyname: "&cSoul Sand Valley"
|
||||||
@ -146,7 +215,14 @@ biomes:
|
|||||||
watercoverage: 0
|
watercoverage: 0
|
||||||
mobs:
|
mobs:
|
||||||
SKELETON: 10:SOUL_SAND
|
SKELETON: 10:SOUL_SAND
|
||||||
|
GHAST: 10:SOUL_SAND
|
||||||
|
ENDERMAN: 1:SOUL_SAND
|
||||||
|
STRIDER: 20:LAVA
|
||||||
moblimit: 9
|
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
|
permission: greenhouses.biome.nether
|
||||||
# Conversion list - in this case, an adjacent block is required to convert
|
# Conversion list - in this case, an adjacent block is required to convert
|
||||||
# Format is:
|
# Format is:
|
||||||
@ -171,6 +247,10 @@ biomes:
|
|||||||
PIGLIN: 10:CRIMSON_NYLIUM
|
PIGLIN: 10:CRIMSON_NYLIUM
|
||||||
HOGLIN: 10:CRIMSON_NYLIUM
|
HOGLIN: 10:CRIMSON_NYLIUM
|
||||||
moblimit: 9
|
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
|
permission: greenhouses.biome.nether
|
||||||
WARPED_FOREST:
|
WARPED_FOREST:
|
||||||
friendlyname: "&cWarped Forest"
|
friendlyname: "&cWarped Forest"
|
||||||
@ -188,6 +268,10 @@ biomes:
|
|||||||
STRIDER: 10:LAVA
|
STRIDER: 10:LAVA
|
||||||
ENDERMAN: 20:WARPED_NYLIUM
|
ENDERMAN: 20:WARPED_NYLIUM
|
||||||
moblimit: 9
|
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
|
permission: greenhouses.biome.nether
|
||||||
JUNGLE:
|
JUNGLE:
|
||||||
biome: JUNGLE
|
biome: JUNGLE
|
||||||
@ -203,6 +287,11 @@ biomes:
|
|||||||
ROSE_BUSH: 20:GRASS_BLOCK
|
ROSE_BUSH: 20:GRASS_BLOCK
|
||||||
FERN: 20:GRASS_BLOCK
|
FERN: 20:GRASS_BLOCK
|
||||||
TALL_GRASS: 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:
|
MUSHROOM_FIELDS:
|
||||||
friendlyname: "Mushroom Fields"
|
friendlyname: "Mushroom Fields"
|
||||||
biome: MUSHROOM_FIELDS
|
biome: MUSHROOM_FIELDS
|
||||||
@ -218,6 +307,10 @@ biomes:
|
|||||||
mobs:
|
mobs:
|
||||||
MUSHROOM_COW: 10:MYCELIUM
|
MUSHROOM_COW: 10:MYCELIUM
|
||||||
moblimit: 9
|
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:
|
OCEAN:
|
||||||
biome: OCEAN
|
biome: OCEAN
|
||||||
icon: WATER_BUCKET
|
icon: WATER_BUCKET
|
||||||
@ -226,7 +319,13 @@ biomes:
|
|||||||
watercoverage: 95
|
watercoverage: 95
|
||||||
mobs:
|
mobs:
|
||||||
SQUID: 10:WATER
|
SQUID: 10:WATER
|
||||||
|
DROWNED: 1:WATER
|
||||||
|
COD: 40:WATER
|
||||||
|
DOLPHIN: 20:WATER
|
||||||
|
SQUID: 20:WATER
|
||||||
|
GLOW_SQUID: 10:WATER
|
||||||
moblimit: 9
|
moblimit: 9
|
||||||
|
maxmobs: 20
|
||||||
PLAINS:
|
PLAINS:
|
||||||
friendlyname: "Horse Plains"
|
friendlyname: "Horse Plains"
|
||||||
biome: PLAINS
|
biome: PLAINS
|
||||||
@ -237,8 +336,17 @@ biomes:
|
|||||||
plants:
|
plants:
|
||||||
TALL_GRASS: 10:GRASS_BLOCK
|
TALL_GRASS: 10:GRASS_BLOCK
|
||||||
mobs:
|
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
|
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:
|
RIVER:
|
||||||
friendlyname: "Clay river"
|
friendlyname: "Clay river"
|
||||||
biome: RIVER
|
biome: RIVER
|
||||||
@ -254,6 +362,15 @@ biomes:
|
|||||||
# So, for below, dirt has a 50% chance of changing into clay if it is next to water!
|
# So, for below, dirt has a 50% chance of changing into clay if it is next to water!
|
||||||
conversion-list:
|
conversion-list:
|
||||||
- DIRT:50:CLAY:WATER
|
- 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:
|
SAVANNA:
|
||||||
biome: SAVANNA
|
biome: SAVANNA
|
||||||
icon: ACACIA_LEAVES
|
icon: ACACIA_LEAVES
|
||||||
@ -264,6 +381,18 @@ biomes:
|
|||||||
GRASS_BLOCK: 4
|
GRASS_BLOCK: 4
|
||||||
plants:
|
plants:
|
||||||
TALL_GRASS: 10:GRASS_BLOCK
|
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:
|
SWAMP:
|
||||||
friendlyname: "&2Slimy Swamp"
|
friendlyname: "&2Slimy Swamp"
|
||||||
biome: SWAMP
|
biome: SWAMP
|
||||||
@ -278,7 +407,37 @@ biomes:
|
|||||||
plants:
|
plants:
|
||||||
RED_MUSHROOM: 20:GRASS_BLOCK
|
RED_MUSHROOM: 20:GRASS_BLOCK
|
||||||
BROWN_MUSHROOM: 20:GRASS_BLOCK
|
BROWN_MUSHROOM: 20:GRASS_BLOCK
|
||||||
|
BLUE_ORCHID: 10:GRASS_BLOCK
|
||||||
LILY_PAD: 5:WATER
|
LILY_PAD: 5:WATER
|
||||||
mobs:
|
mobs:
|
||||||
SLIME: 5:WATER
|
SLIME: 5:WATER
|
||||||
|
FROG: 20:WATER
|
||||||
moblimit: 3
|
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
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Greenhouses Configuration
|
# Greenhouses Configuration {$version}
|
||||||
#
|
#
|
||||||
greenhouses:
|
greenhouses:
|
||||||
# BentoBox GameModes that will use Greenhouses
|
# BentoBox GameModes that will use Greenhouses
|
||||||
@ -7,9 +7,10 @@ greenhouses:
|
|||||||
- AcidIsland
|
- AcidIsland
|
||||||
- SkyGrid
|
- SkyGrid
|
||||||
- AOneBlock
|
- AOneBlock
|
||||||
- CaveBlock
|
#
|
||||||
# Show loaded recipe details during startup of server
|
# Show loaded recipe details during startup of server
|
||||||
startup-log: false
|
startup-log: false
|
||||||
|
#
|
||||||
# Weather and ecosystem settings
|
# Weather and ecosystem settings
|
||||||
# How often it should snow in the g/h when the weather is raining, in seconds
|
# How often it should snow in the g/h when the weather is raining, in seconds
|
||||||
snowspeed: 30.0
|
snowspeed: 30.0
|
||||||
@ -18,6 +19,7 @@ greenhouses:
|
|||||||
snowchance: 1.0
|
snowchance: 1.0
|
||||||
# How many blocks should get snow 1 = all of them, 0 = none, 0.1 = 1 in 10
|
# How many blocks should get snow 1 = all of them, 0 = none, 0.1 = 1 in 10
|
||||||
snowdensity: 0.1
|
snowdensity: 0.1
|
||||||
|
#
|
||||||
# Biome activity
|
# Biome activity
|
||||||
# How often should greenhouse biomes be checked to make sure they are still valid
|
# How often should greenhouse biomes be checked to make sure they are still valid
|
||||||
ecotick: 5
|
ecotick: 5
|
||||||
@ -28,10 +30,15 @@ greenhouses:
|
|||||||
blocktick: 2
|
blocktick: 2
|
||||||
# How often should mobs be potentially spawned in a greenhouse, in minutes
|
# How often should mobs be potentially spawned in a greenhouse, in minutes
|
||||||
mobtick: 5
|
mobtick: 5
|
||||||
|
#
|
||||||
# Default settings for greenhouse actions
|
# Default settings for greenhouse actions
|
||||||
# Allow lava or water to flow out of a greenhouse, e.g. through the door, floor
|
# Allow lava or water to flow out of a greenhouse, e.g. through the door, floor
|
||||||
allowflowout: false
|
allowflowout: false
|
||||||
# Allow lava or water to flow into a greenhouse, e.g., through the door
|
# Allow lava or water to flow into a greenhouse, e.g., through the door
|
||||||
allowflowin: false
|
allowflowin: false
|
||||||
|
#
|
||||||
# Allow glowstone to be used as well as glass in roof and walls
|
# Allow glowstone to be used as well as glass in roof and walls
|
||||||
allowglowstone: true
|
allowglowstone: true
|
||||||
|
#
|
||||||
|
# Allow glass panes to be used to build greenhouses
|
||||||
|
allowpanes: true
|
||||||
|
163
src/main/resources/locales/de.yml
Normal file
163
src/main/resources/locales/de.yml
Normal file
@ -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"
|
@ -8,8 +8,8 @@ protection:
|
|||||||
GREENHOUSE:
|
GREENHOUSE:
|
||||||
name: Greenhouses
|
name: Greenhouses
|
||||||
description: |
|
description: |
|
||||||
&bToggle who can
|
&b Toggle who can
|
||||||
&bcontrol greenhouses
|
&b control greenhouses
|
||||||
|
|
||||||
greenhouses:
|
greenhouses:
|
||||||
general:
|
general:
|
||||||
@ -17,9 +17,9 @@ greenhouses:
|
|||||||
|
|
||||||
errors:
|
errors:
|
||||||
move: "Move to a greenhouse you own first."
|
move: "Move to a greenhouse you own first."
|
||||||
no-rank: "&cYou do not have rank to do that."
|
no-rank: "&c You do not have rank to do that."
|
||||||
notyours: "This is not your greenhouse!"
|
notyours: "This is not your greenhouse!"
|
||||||
not-inside: "&cYou are not in a greenhouse!"
|
not-inside: "&c You are not in a greenhouse!"
|
||||||
tooexpensive: "You cannot afford [price]"
|
tooexpensive: "You cannot afford [price]"
|
||||||
alreadyexists: "Greenhouse already exists!"
|
alreadyexists: "Greenhouse already exists!"
|
||||||
norecipe: "Cannot make a greenhouse!"
|
norecipe: "Cannot make a greenhouse!"
|
||||||
@ -41,6 +41,7 @@ greenhouses:
|
|||||||
|
|
||||||
commands:
|
commands:
|
||||||
user:
|
user:
|
||||||
|
description: "Opens the Greenhouse selection GUI"
|
||||||
remove:
|
remove:
|
||||||
description: "Removes a greenhouse that you are standing in if you are the owner"
|
description: "Removes a greenhouse that you are standing in if you are the owner"
|
||||||
make:
|
make:
|
||||||
@ -48,38 +49,42 @@ greenhouses:
|
|||||||
parameters: "<recipe>"
|
parameters: "<recipe>"
|
||||||
error:
|
error:
|
||||||
already: "&cThere is already a greenhouse here!"
|
already: "&cThere is already a greenhouse here!"
|
||||||
FAIL_BAD_ROOF_BLOCKS: "&cRoof contains disallowed blocks!"
|
FAIL_BAD_ROOF_BLOCKS: "&c Roof contains disallowed blocks!"
|
||||||
FAIL_BAD_WALL_BLOCKS: "&cWall contains disallowed blocks!"
|
FAIL_BAD_WALL_BLOCKS: "&c Wall contains disallowed blocks!"
|
||||||
FAIL_BELOW: "&cYou must be inside the greenhouse to try to make it"
|
FAIL_BELOW: "&c You must be inside the greenhouse to try to make it"
|
||||||
FAIL_BLOCKS_ABOVE: "&cThere can be no blocks above the greenhouse! Red glass blocks should show the problem blocks."
|
FAIL_BLOCKS_ABOVE: "&c There can be no blocks above the greenhouse! Red glass blocks should show the problem blocks."
|
||||||
FAIL_HOLE_IN_ROOF: "&cThere is a hole in the roof or it is not flat! Red glass blocks should show the problem."
|
FAIL_HOLE_IN_ROOF: |
|
||||||
FAIL_HOLE_IN_WALL: "&cThere is a hole in the wall!"
|
&c There is a hole in the roof or it is not flat!
|
||||||
FAIL_NO_ROOF: "&cThere seems to be no roof!"
|
&c Red glass blocks should show the problem.
|
||||||
FAIL_TOO_MANY_DOORS: "&cYou cannot have more than 4 doors in the greenhouse!"
|
&c Make sure you are inside your greenhouse to make it.
|
||||||
FAIL_TOO_MANY_HOPPERS: "&cOnly one hopper is allowed in the walls or roof."
|
FAIL_HOLE_IN_WALL: "&c There is a hole in the wall!"
|
||||||
FAIL_UNEVEN_WALLS: "&cThe walls are uneven. Red glass blocks should show the problem blocks."
|
FAIL_NO_ROOF: "&c There seems to be no roof! Make sure you are inside the greenhouse to make it."
|
||||||
FAIL_INSUFFICIENT_ICE: "&cInsufficent ice to make this recipe"
|
FAIL_TOO_MANY_DOORS: "&c You cannot have more than 4 doors in the greenhouse!"
|
||||||
FAIL_INSUFFICIENT_LAVA: "&cInsufficent lava to make this recipe"
|
FAIL_TOO_MANY_HOPPERS: "&c Only one hopper is allowed in the walls or roof."
|
||||||
FAIL_INSUFFICIENT_WATER: "&cInsufficent water to make this recipe"
|
FAIL_UNEVEN_WALLS: "&c The walls are uneven. Red glass blocks should show the problem blocks."
|
||||||
FAIL_NO_ICE: "&cIce is required to make this recipe"
|
FAIL_INSUFFICIENT_ICE: "&c Insufficient ice to make this recipe"
|
||||||
FAIL_NO_LAVA: "&cLava is required to make this recipe"
|
FAIL_INSUFFICIENT_LAVA: "&c Insufficient lava to make this recipe"
|
||||||
FAIL_NO_WATER: "&cWater is required to make this recipe"
|
FAIL_INSUFFICIENT_WATER: "&c Insufficient water to make this recipe"
|
||||||
FAIL_INSUFFICIENT_BLOCKS: "&cMore blocks are required to make this recipe!"
|
FAIL_NO_ICE: "&c Ice is required to make this recipe"
|
||||||
FAIL_OVERLAPPING: "&cGreenhouses cannot share walls, sorry."
|
FAIL_NO_LAVA: "&c Lava is required to make this recipe"
|
||||||
success: "&2You successfully made a [biome] biome greenhouse! Biome will sync at next teleport or login."
|
FAIL_NO_WATER: "&c Water is required to make this recipe"
|
||||||
missing-blocks: "&cMissing [material] x [number]"
|
FAIL_NO_RECIPE_FOUND: "&c No recipe could be found that matches this greenhouse"
|
||||||
unknown-recipe: "&cUnknown recipe"
|
FAIL_INSUFFICIENT_BLOCKS: "&c More blocks are required to make this recipe!"
|
||||||
try-these: "&cTry one of these:"
|
FAIL_OVERLAPPING: "&c Greenhouses cannot share walls, sorry."
|
||||||
|
success: "&2 You successfully made a [biome] biome greenhouse! Biome will sync at next teleport or login."
|
||||||
|
missing-blocks: "&c Missing [material] x [number]"
|
||||||
|
unknown-recipe: "&c Unknown recipe"
|
||||||
|
try-these: "&c Try one of these:"
|
||||||
recipe-format: "&3[name]"
|
recipe-format: "&3[name]"
|
||||||
info:
|
info:
|
||||||
title: "&A[How To Build A Greenhouse]"
|
title: "&a [How To Build A Greenhouse]"
|
||||||
instructions: |
|
instructions: |
|
||||||
&EMake a box out of out of glass with 4 walls and a flat glass
|
&e Make a box out of out of glass with 4 walls and a flat glass
|
||||||
&Eroof and add up to &F4 doors &Ein the walls.
|
&e roof and add up to &f 4 doors &Ein the walls.
|
||||||
&EPlace &F1 hopper &Ein a wall or roof and add water buckets.
|
&e Place &f 1 hopper &e in a wall or roof and add water buckets.
|
||||||
&Eto make snow and/or bonemeal to grow plants automatically.
|
&e to make snow and/or bonemeal to grow plants automatically.
|
||||||
&ECheck the biome recipes for what blocks must be inside a
|
&e Check the biome recipes for what blocks must be inside a
|
||||||
&Egreenhouse to make one successfully.
|
&e greenhouse to make one successfully.
|
||||||
|
|
||||||
|
|
||||||
######### Old locale for reference
|
######### Old locale for reference
|
||||||
@ -122,19 +127,19 @@ messages:
|
|||||||
info:
|
info:
|
||||||
title: "&A[How To Build A Greenhouse]"
|
title: "&A[How To Build A Greenhouse]"
|
||||||
instructions: |
|
instructions: |
|
||||||
&EMake a box out of out of glass with 4 walls and a flat glass
|
&E Make a box out of out of glass with 4 walls and a flat glass
|
||||||
&Eroof and add up to &F4 doors &Ein the walls.
|
&E roof and add up to &F 4 doors &Ein the walls.
|
||||||
&EPlace &F1 hopper &Ein a wall or roof and add water buckets.
|
&E Place &F 1 hopper &E in a wall or roof and add water buckets.
|
||||||
&Eto make snow and/or bonemeal to grow plants automatically.
|
&E to make snow and/or bonemeal to grow plants automatically.
|
||||||
&ECheck the biome recipes for what blocks must be inside a
|
&E Check the biome recipes for what blocks must be inside a
|
||||||
&Egreenhouse to make one successfully.
|
&E greenhouse to make one successfully.
|
||||||
info: "[Greenhouse Info]"
|
info: "[Greenhouse Info]"
|
||||||
none: "None"
|
none: "None"
|
||||||
nomore: "&4You cannot build any more greenhouses!"
|
nomore: "&4 You cannot build any more greenhouses!"
|
||||||
onemore: "&6You can build one more greenhouse."
|
onemore: "&6 You can build one more greenhouse."
|
||||||
youcanbuild: "&AYou can build up to [number] more greenhouses!"
|
youcanbuild: "&A You can build up to [number] more greenhouses!"
|
||||||
unlimited: "&AYou can build an unlimited number of greenhouses!"
|
unlimited: "&A You can build an unlimited number of greenhouses!"
|
||||||
welcome: "&BWelcome! Click here for instructions"
|
welcome: "&B Welcome! Click here for instructions"
|
||||||
|
|
||||||
recipe:
|
recipe:
|
||||||
blockscolor: "&f"
|
blockscolor: "&f"
|
||||||
|
@ -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:
|
protection:
|
||||||
flags:
|
flags:
|
||||||
GREENHOUSE:
|
GREENHOUSE:
|
||||||
name: Greenhouses
|
name: Greenhouses
|
||||||
description: |
|
description: "&bÁllítsd be, hogy ki\n&bkezelheti az üvegházat \n"
|
||||||
&bÁllítsd be, hogy ki
|
|
||||||
&bkezelheti az üvegházat
|
|
||||||
|
|
||||||
greenhouses:
|
greenhouses:
|
||||||
general:
|
general:
|
||||||
greenhouses: "Üvegházak"
|
greenhouses: Üvegházak
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
move: "Menj a saját üvegházadhoz."
|
move: Menj a saját üvegházadhoz.
|
||||||
no-rank: "&cNincs rangod ehhez."
|
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!"
|
not-inside: "&cNem vagy üvegházban!"
|
||||||
tooexpensive: "Ehhez nincs elég pénzed, ennyi szükséges: [price]"
|
tooexpensive: 'Ehhez nincs elég pénzed, ennyi szükséges: [price]'
|
||||||
alreadyexists: "Az üvegház már létezik!"
|
alreadyexists: Az üvegház már létezik!
|
||||||
norecipe: "Nem tudsz üvegházat csinálni!"
|
norecipe: Nem tudsz üvegházat csinálni!
|
||||||
|
|
||||||
event:
|
event:
|
||||||
broke: "Összetörted az üvegházad! Visszaállítjuk a biome-ot [biome]-ra/re!"
|
broke: Összetörted az üvegházad! Visszaállítjuk a biome-ot [biome]-ra/re!
|
||||||
entering: "Belépés a(z) [biome] üvegházba."
|
entering: Belépés a(z) [biome] üvegházba.
|
||||||
leaving: "Kilépés a(z) [biome] üvegházból."
|
leaving: Kilépés a(z) [biome] üvegházból.
|
||||||
|
|
||||||
recipe:
|
recipe:
|
||||||
blockscolor: "&f"
|
blockscolor: "&f"
|
||||||
title: "[[biome] recept]"
|
title: "[[biome] recept]"
|
||||||
watermustbe: "Víz > [coverage]% kell, hogy legyen az alapterületen."
|
watermustbe: Víz > [coverage]% kell, hogy legyen az alapterületen.
|
||||||
icemustbe: "Jég blokk > [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."
|
lavamustbe: Láva > [coverage]% kell, hogy legyen az alapterületen.
|
||||||
minimumblockstitle: "[Minimum blokkmennyiség]"
|
minimumblockstitle: "[Minimum blokkmennyiség]"
|
||||||
nootherblocks: "Nem szükséges több blokk."
|
nootherblocks: Nem szükséges több blokk.
|
||||||
missing: "Hiányzó üvegház."
|
missing: Hiányzó üvegház.
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
user:
|
user:
|
||||||
remove:
|
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:
|
make:
|
||||||
description: "Megpróbál készíteni egy üvegházat."
|
description: Megpróbál készíteni egy üvegházat.
|
||||||
parameters: "<recipe>"
|
parameters: "<recipe>"
|
||||||
error:
|
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_ROOF_BLOCKS: "&cA tető nem engedélyezett blokkokat tartalmaz!"
|
||||||
FAIL_BAD_WALL_BLOCKS: "&cA fal 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_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_BLOCKS_ABOVE: "&cAz üvegház felett nem lehetnek blokkok! A piros üvegblokkoknak
|
||||||
FAIL_HOLE_IN_ROOF: "&cVan egy lyuk a tetőn, vagy nem sík! A piros üvegblokkoknak meg kell mutatniuk a problémát."
|
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_HOLE_IN_WALL: "&cVan egy lyuk a falban!"
|
||||||
FAIL_NO_ROOF: "&cÚgy tűnik, nincs tető!"
|
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_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_TOO_MANY_HOPPERS: "&cCsak egy tölcsér megengedett a falakban vagy a
|
||||||
FAIL_UNEVEN_WALLS: "&cA falak egyenetlenek. A piros üvegblokkoknak meg kell mutatniuk a problémás blokkokat."
|
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_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_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_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_ICE: "&cA jég szükséges ehhez a recepthez."
|
||||||
FAIL_NO_LAVA: "&cA láva 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_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_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."
|
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]"
|
missing-blocks: "&cHiányzik [material] x [number]"
|
||||||
unknown-recipe: "&cIsmeretlen recept"
|
unknown-recipe: "&cIsmeretlen recept"
|
||||||
try-these: "&cPróbálj meg egyet az alábbiak közül:"
|
try-these: "&cPróbálj meg egyet az alábbiak közül:"
|
||||||
recipe-format: "&3[name]"
|
recipe-format: "&3[name]"
|
||||||
info:
|
info:
|
||||||
title: "&A[Hogyan Készíts Üvegházat]"
|
title: "&A[Hogyan Készíts Üvegházat]"
|
||||||
instructions: |
|
instructions: "&EKészíts egy üvegdobozt 4 fallal, egy üvegtetővel,\n&Eés akár
|
||||||
&EKészíts egy üvegdobozt 4 fallal, egy üvegtetővel,
|
4 ajtót is tehetsz a falba.\n&ERakj a falba vagy a tetőbe &F1 tölcsért,
|
||||||
&Eés akár 4 ajtót is tehetsz a falba.
|
&Eés helyezz bele vizes vödröket,\n&Ehogy havat és/vagy csontlisztet készíts,
|
||||||
&ERakj a falba vagy a tetőbe &F1 tölcsért, &Eés helyezz bele vizes vödröket,
|
mellyel automatikusan tudod növeszteni a növényeidet.\n&ENézd meg az éghajlatokhoz
|
||||||
&Ehogy havat és/vagy csontlisztet készíts, mellyel automatikusan tudod növeszteni a növényeidet.
|
tartozó recepteket, hogy megtudd milyen blokkok legyenek feltétlenül\n&Eaz
|
||||||
&ENézd meg az éghajlatokhoz tartozó recepteket, hogy megtudd milyen blokkok legyenek feltétlenül
|
üvegházban ahhoz, hogy sikeresen elkészítsd. \n"
|
||||||
&Eaz üvegházban ahhoz, hogy sikeresen elkészítsd.
|
|
||||||
|
|
||||||
|
|
||||||
######### Old locale for reference
|
|
||||||
help:
|
help:
|
||||||
help: "help"
|
help: help
|
||||||
make: "Tries to make a greenhouse"
|
make: Tries to make a greenhouse
|
||||||
remove: "Removes a greenhouse that you are standing in if you are the owner"
|
remove: Removes a greenhouse that you are standing in if you are the owner
|
||||||
info: "How to make a greenhouse"
|
info: How to make a greenhouse
|
||||||
list: "Lists all the greenhouse biomes that can be made"
|
list: Lists all the greenhouse biomes that can be made
|
||||||
recipe: "Tells you how to make greenhouse biome"
|
recipe: Tells you how to make greenhouse biome
|
||||||
opengui: "Opens the Greenhouse GUI"
|
opengui: Opens the Greenhouse GUI
|
||||||
|
|
||||||
list:
|
list:
|
||||||
title: "[Greenhouse Biome Recipes]"
|
title: "[Greenhouse Biome Recipes]"
|
||||||
info: "Use /greenhouse recipe <number> to see details on how to make each greenhouse"
|
info: Use /greenhouse recipe <number> to see details on how to make each greenhouse
|
||||||
|
|
||||||
|
|
||||||
################
|
|
||||||
#General Errors#
|
|
||||||
################
|
|
||||||
error:
|
error:
|
||||||
greenhouseProtected: "Greenhouse protected"
|
greenhouseProtected: Greenhouse protected
|
||||||
move: "Move to a greenhouse you own first."
|
move: Move to a greenhouse you own first.
|
||||||
notowner: "You must be the owner of this greenhouse to do that."
|
notowner: You must be the owner of this greenhouse to do that.
|
||||||
removing: "Removing greenhouse!"
|
removing: Removing greenhouse!
|
||||||
notyours: "This is not your greenhouse!"
|
notyours: This is not your greenhouse!
|
||||||
notinside: "You are not in a greenhouse!"
|
notinside: You are not in a greenhouse!
|
||||||
tooexpensive: "You cannot afford [price]"
|
tooexpensive: You cannot afford [price]
|
||||||
alreadyexists: "Greenhouse already exists!"
|
alreadyexists: Greenhouse already exists!
|
||||||
norecipe: "Cannot make a greenhouse!"
|
norecipe: Cannot make a greenhouse!
|
||||||
|
|
||||||
messages:
|
messages:
|
||||||
enter: "Entering [owner]'s [biome] greenhouse!"
|
enter: Entering [owner]'s [biome] greenhouse!
|
||||||
leave: "Now leaving [owner]'s greenhouse."
|
leave: Now leaving [owner]'s greenhouse.
|
||||||
youarein: "You are now in [owner]'s [biome] greenhouse!"
|
youarein: You are now in [owner]'s [biome] greenhouse!
|
||||||
removed: "This greenhouse is no more..."
|
removed: This greenhouse is no more...
|
||||||
removedmessage: "A [biome] greenhouse of yours is no more!"
|
removedmessage: A [biome] greenhouse of yours is no more!
|
||||||
ecolost: "Your greenhouse at [location] lost its eco system and was removed."
|
ecolost: Your greenhouse at [location] lost its eco system and was removed.
|
||||||
|
|
||||||
info:
|
info:
|
||||||
title: "&A[How To Build A Greenhouse]"
|
title: "&A[How To Build A Greenhouse]"
|
||||||
instructions: |
|
instructions: "&EMake a box out of out of glass with 4 walls and a flat glass\n&Eroof
|
||||||
&EMake a box out of out of glass with 4 walls and a flat glass
|
and add up to &F4 doors &Ein the walls.\n&EPlace &F1 hopper &Ein a wall or roof
|
||||||
&Eroof and add up to &F4 doors &Ein the walls.
|
and add water buckets.\n&Eto make snow and/or bonemeal to grow plants automatically.\n&ECheck
|
||||||
&EPlace &F1 hopper &Ein a wall or roof and add water buckets.
|
the biome recipes for what blocks must be inside a\n&Egreenhouse to make one successfully.
|
||||||
&Eto make snow and/or bonemeal to grow plants automatically.
|
\n"
|
||||||
&ECheck the biome recipes for what blocks must be inside a
|
|
||||||
&Egreenhouse to make one successfully.
|
|
||||||
info: "[Greenhouse Info]"
|
info: "[Greenhouse Info]"
|
||||||
none: "None"
|
none: None
|
||||||
nomore: "&4You cannot build any more greenhouses!"
|
nomore: "&4You cannot build any more greenhouses!"
|
||||||
onemore: "&6You can build one more greenhouse."
|
onemore: "&6You can build one more greenhouse."
|
||||||
youcanbuild: "&AYou can build up to [number] more greenhouses!"
|
youcanbuild: "&AYou can build up to [number] more greenhouses!"
|
||||||
unlimited: "&AYou can build an unlimited number of greenhouses!"
|
unlimited: "&AYou can build an unlimited number of greenhouses!"
|
||||||
welcome: "&BWelcome! Click here for instructions"
|
welcome: "&BWelcome! Click here for instructions"
|
||||||
|
|
||||||
recipe:
|
recipe:
|
||||||
blockscolor: "&f"
|
blockscolor: "&f"
|
||||||
hint: "Use /greenhouse list to see a list of recipe numbers!"
|
hint: Use /greenhouse list to see a list of recipe numbers!
|
||||||
wrongnumber: "Recipe number must be between 1 and [size]"
|
wrongnumber: Recipe number must be between 1 and [size]
|
||||||
title: "[[biome] recipe]"
|
title: "[[biome] recipe]"
|
||||||
nowater: "No water allowed."
|
nowater: No water allowed.
|
||||||
noice: "No ice allowed."
|
noice: No ice allowed.
|
||||||
nolava: "No lava allowed."
|
nolava: No lava allowed.
|
||||||
watermustbe: "Water > [coverage]% of floor area."
|
watermustbe: Water > [coverage]% of floor area.
|
||||||
icemustbe: "Ice blocks > [coverage]% of floor area."
|
icemustbe: Ice blocks > [coverage]% of floor area.
|
||||||
lavamustbe: "Lava > [coverage]% of floor area."
|
lavamustbe: Lava > [coverage]% of floor area.
|
||||||
minimumblockstitle: "[Minimum blocks required]"
|
minimumblockstitle: "[Minimum blocks required]"
|
||||||
nootherblocks: "No other blocks required."
|
nootherblocks: No other blocks required.
|
||||||
missing: "Greenhouse is missing"
|
missing: Greenhouse is missing
|
||||||
|
|
||||||
event:
|
event:
|
||||||
broke: "You broke this greenhouse! Reverting biome to [biome]!"
|
broke: You broke this greenhouse! Reverting biome to [biome]!
|
||||||
fix: "Fix the greenhouse and then make it again."
|
fix: Fix the greenhouse and then make it again.
|
||||||
cannotplace: "Blocks cannot be placed above a greenhouse!"
|
cannotplace: Blocks cannot be placed above a greenhouse!
|
||||||
pistonerror: "Pistons cannot push blocks over a greenhouse!"
|
pistonerror: Pistons cannot push blocks over a greenhouse!
|
||||||
|
|
||||||
|
|
||||||
limits:
|
limits:
|
||||||
noneallowed: "Permissions do not allow you any greenhouses so [number] were removed."
|
noneallowed: Permissions do not allow you any greenhouses so [number] were removed.
|
||||||
limitedto: "Permissions limit you to [limit] greenhouses so [number] were removed."
|
limitedto: Permissions limit you to [limit] greenhouses so [number] were removed.
|
||||||
|
|
||||||
|
|
||||||
##################################
|
|
||||||
#Admin commands that use /gadmin #
|
|
||||||
##################################
|
|
||||||
|
|
||||||
#Help
|
|
||||||
adminHelp:
|
adminHelp:
|
||||||
reload: "reload configuration from file."
|
reload: reload configuration from file.
|
||||||
info: "provides info on the greenhouse you are in"
|
info: provides info on the greenhouse you are in
|
||||||
|
|
||||||
#reload
|
|
||||||
reload:
|
reload:
|
||||||
configReloaded: "Configuration reloaded from file."
|
configReloaded: Configuration reloaded from file.
|
||||||
|
|
||||||
admininfo:
|
admininfo:
|
||||||
error: "Greenhouse info only available in-game"
|
error: Greenhouse info only available in-game
|
||||||
error2: "Put yourself in a greenhouse to see info."
|
error2: Put yourself in a greenhouse to see info.
|
||||||
flags: "[Greenhouse Flags]"
|
flags: "[Greenhouse Flags]"
|
||||||
|
|
||||||
news:
|
news:
|
||||||
headline: "[Greenhouse News]"
|
headline: "[Greenhouse News]"
|
||||||
|
|
||||||
controlpanel:
|
controlpanel:
|
||||||
title: "&AGreenhouses"
|
title: "&AGreenhouses"
|
||||||
|
|
||||||
|
@ -1,37 +1,42 @@
|
|||||||
---
|
---
|
||||||
adminHelp:
|
protection:
|
||||||
info: あなたがいる温室に関する情報を提供します
|
flags:
|
||||||
reload: ファイルから設定をリロードします。
|
GREENHOUSE:
|
||||||
admininfo:
|
name: 温室
|
||||||
error: ゲーム内でのみ利用可能な温室情報
|
description: |-
|
||||||
error2: 温室で情報を確認してください。
|
&b誰が温室を制御できるかを
|
||||||
flags: "[温室旗]"
|
&b設定する
|
||||||
controlpanel:
|
|
||||||
title: "&A温室"
|
|
||||||
error:
|
|
||||||
alreadyexists: 温室はすでに存在します!
|
|
||||||
greenhouseProtected: 温室保護
|
|
||||||
move: 最初に所有する温室に移動します。
|
|
||||||
norecipe: 温室を作ることができません!
|
|
||||||
notinside: あなたは温室の中にいません!
|
|
||||||
notowner: それを行うには、この温室の所有者でなければなりません。
|
|
||||||
notyours: これはあなたの温室ではありません!
|
|
||||||
removing: 温室を撤去!
|
|
||||||
tooexpensive: あなたは余裕がない[price]
|
|
||||||
event:
|
|
||||||
broke: あなたはこの温室を壊しました!バイオームを[biome]に戻しています!
|
|
||||||
cannotplace: ブロックを温室の上に置くことはできません!
|
|
||||||
fix: 温室を修理してから、もう一度作ります。
|
|
||||||
pistonerror: ピストンは温室の上でブロックを押すことができません!
|
|
||||||
greenhouses:
|
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:
|
commands:
|
||||||
user:
|
user:
|
||||||
info:
|
remove:
|
||||||
title: "&A [温室の作り方]"
|
description: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
||||||
instructions: 4つの壁と平らなガラス屋根でガラスから箱を作り、壁に最大4つのドアを追加します。 1つのホッパーを壁または屋根に置き、水バケツを追加します。
|
|
||||||
雪や骨粉を作り、植物を自動的に育てます。 バイオームレシピを確認して、温室内で正常にブロックするために必要なブロックを確認してください。
|
|
||||||
make:
|
make:
|
||||||
description: 温室を作ってみる
|
description: 温室を作ってみる
|
||||||
|
parameters: "<レシピ>"
|
||||||
error:
|
error:
|
||||||
already: "&cここには温室がすでにあります!"
|
already: "&cここには温室がすでにあります!"
|
||||||
FAIL_BAD_ROOF_BLOCKS: "&c屋根には許可されていないブロックが含まれています!"
|
FAIL_BAD_ROOF_BLOCKS: "&c屋根には許可されていないブロックが含まれています!"
|
||||||
@ -40,97 +45,99 @@ greenhouses:
|
|||||||
FAIL_BLOCKS_ABOVE: "&c温室の上にブロックを置くことはできません!赤いガラスブロックに問題のあるブロックが表示されます。"
|
FAIL_BLOCKS_ABOVE: "&c温室の上にブロックを置くことはできません!赤いガラスブロックに問題のあるブロックが表示されます。"
|
||||||
FAIL_HOLE_IN_ROOF: "&c屋根に穴があるか、平らではありません!赤いガラスブロックが問題を示しているはずです。"
|
FAIL_HOLE_IN_ROOF: "&c屋根に穴があるか、平らではありません!赤いガラスブロックが問題を示しているはずです。"
|
||||||
FAIL_HOLE_IN_WALL: "&c壁に穴が開いています!"
|
FAIL_HOLE_IN_WALL: "&c壁に穴が開いています!"
|
||||||
FAIL_INSUFFICIENT_ICE: "&cこのレシピを作成するには氷が足りません"
|
|
||||||
FAIL_INSUFFICIENT_LAVA: "&cこのレシピを作るには溶岩が足りません"
|
|
||||||
FAIL_INSUFFICIENT_WATER: "&cこのレシピを作るのに水が足りません"
|
|
||||||
FAIL_NO_ROOF: "&c屋根がないようです!"
|
FAIL_NO_ROOF: "&c屋根がないようです!"
|
||||||
FAIL_TOO_MANY_DOORS: "&c温室には4つ以上のドアを置くことはできません!"
|
FAIL_TOO_MANY_DOORS: "&c温室には4つ以上のドアを置くことはできません!"
|
||||||
FAIL_TOO_MANY_HOPPERS: "&c壁または屋根に使用できるホッパーは1つだけです。"
|
FAIL_TOO_MANY_HOPPERS: "&c壁または屋根に使用できるホッパーは1つだけです。"
|
||||||
FAIL_UNEVEN_WALLS: "&c壁が不均一です。赤いガラスブロックに問題のあるブロックが表示されます。"
|
FAIL_UNEVEN_WALLS: "&c壁が不均一です。赤いガラスブロックに問題のあるブロックが表示されます。"
|
||||||
|
FAIL_INSUFFICIENT_ICE: "&cこのレシピを作成するには氷が足りません"
|
||||||
|
FAIL_INSUFFICIENT_LAVA: "&cこのレシピを作るには溶岩が足りません"
|
||||||
|
FAIL_INSUFFICIENT_WATER: "&cこのレシピを作るのに水が足りません"
|
||||||
FAIL_NO_ICE: このレシピを作成するには&c氷が必要です
|
FAIL_NO_ICE: このレシピを作成するには&c氷が必要です
|
||||||
FAIL_NO_LAVA: このレシピを作成するには&c溶岩が必要です
|
FAIL_NO_LAVA: このレシピを作成するには&c溶岩が必要です
|
||||||
FAIL_NO_WATER: このレシピを作成するには&c水が必要です
|
FAIL_NO_WATER: このレシピを作成するには&c水が必要です
|
||||||
parameters: "<レシピ>"
|
FAIL_NO_RECIPE_FOUND: "&cこの温室に一致するレシピが見つかりませんでした"
|
||||||
|
FAIL_INSUFFICIENT_BLOCKS: "&cこのレシピを作成するには、さらに多くのブロックが必要です。"
|
||||||
|
FAIL_OVERLAPPING: "&c温室は壁を共有できません。申し訳ありません。"
|
||||||
success: "&2あなたは[biome]バイオーム温室を無事に作成しました!バイオームは次のテレポートまたはログインで同期します。"
|
success: "&2あなたは[biome]バイオーム温室を無事に作成しました!バイオームは次のテレポートまたはログインで同期します。"
|
||||||
remove:
|
missing-blocks: "&c欠落[material] x [number]"
|
||||||
description: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
unknown-recipe: "&c不明なレシピ"
|
||||||
errors:
|
try-these: "&c次のいずれかを試してください。"
|
||||||
alreadyexists: 温室はすでに存在します!
|
recipe-format: "&3[name]"
|
||||||
move: 最初に所有する温室に移動します。
|
info:
|
||||||
no-rank: "&cあなたにはそれをするランクがありません。"
|
title: "&A [温室の作り方]"
|
||||||
norecipe: 温室を作ることができません!
|
instructions: 4つの壁と平らなガラス屋根でガラスから箱を作り、壁に最大4つのドアを追加します。 1つのホッパーを壁または屋根に置き、水バケツを追加します。
|
||||||
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]の温室を離れる"
|
|
||||||
help:
|
help:
|
||||||
help: 手助け
|
help: 手助け
|
||||||
|
make: 温室を作ろうとする
|
||||||
|
remove: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
||||||
info: 温室の作り方
|
info: 温室の作り方
|
||||||
list: 作成可能なすべての温室バイオームをリストします
|
list: 作成可能なすべての温室バイオームをリストします
|
||||||
make: 温室を作ろうとする
|
|
||||||
recipe: 温室バイオームの作り方を説明します
|
recipe: 温室バイオームの作り方を説明します
|
||||||
remove: あなたが所有者である場合、あなたが立っている温室を取り除きます
|
|
||||||
opengui: 温室のGUI
|
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:
|
list:
|
||||||
title: "[温室効果バイオームのレシピ]"
|
title: "[温室効果バイオームのレシピ]"
|
||||||
info: "/greenhouse recipe <番号>を使用する各温室の作り方の詳細を見る"
|
info: "/greenhouse recipe <番号>を使用する各温室の作り方の詳細を見る"
|
||||||
|
error:
|
||||||
|
greenhouseProtected: 温室保護
|
||||||
|
move: 最初に所有する温室に移動します。
|
||||||
|
notowner: それを行うには、この温室の所有者でなければなりません。
|
||||||
|
removing: 温室を撤去!
|
||||||
|
notyours: これはあなたの温室ではありません!
|
||||||
|
notinside: あなたは温室の中にいません!
|
||||||
|
tooexpensive: あなたは余裕がない[price]
|
||||||
|
alreadyexists: 温室はすでに存在します!
|
||||||
|
norecipe: 温室を作ることができません!
|
||||||
messages:
|
messages:
|
||||||
ecolost: "[location]の温室はエコシステムを失い、撤去されました。"
|
|
||||||
leave: "[owner]の温室を離れます。"
|
|
||||||
removed: この温室はもうありません...
|
|
||||||
enter: "[owner]の[biome]の温室に入る!"
|
enter: "[owner]の[biome]の温室に入る!"
|
||||||
|
leave: "[owner]の温室を離れます。"
|
||||||
youarein: あなたは今[owner]の[biome]の温室にいます!
|
youarein: あなたは今[owner]の[biome]の温室にいます!
|
||||||
|
removed: この温室はもうありません...
|
||||||
removedmessage: あなたの[biome]の温室はもうありません!
|
removedmessage: あなたの[biome]の温室はもうありません!
|
||||||
news:
|
ecolost: "[location]の温室はエコシステムを失い、撤去されました。"
|
||||||
headline: "[温室ニュース]"
|
info:
|
||||||
protection:
|
title: "&A [温室の作り方]"
|
||||||
flags:
|
instructions: "&E 4つの壁と平らなガラスの&E屋根でガラスから箱を作り、壁に&F 4のドア&Eを追加します。 &E壁と屋根に&F 1ホッパー&Eを配置し、ウォーターバケツ&Eを追加して雪や骨粉を作り、植物を自動的に成長させます。
|
||||||
GREENHOUSE:
|
&Eバイオームレシピを確認して、&E温室内で正常にブロックを作成するために必要なブロックを確認します。"
|
||||||
name: 温室
|
info: "[温室情報]"
|
||||||
description: |-
|
none: 無し
|
||||||
&b誰が温室を制御できるかを
|
nomore: "&4これ以上温室を建設することはできません!"
|
||||||
&b設定する
|
onemore: "&6温室をもう1つ構築できます。"
|
||||||
|
youcanbuild: "&A温室を最大[number]個まで構築できます!"
|
||||||
|
unlimited: "&A温室を無制限に構築できます!"
|
||||||
|
welcome: "&B ようこそ!手順についてはここをクリックしてください"
|
||||||
recipe:
|
recipe:
|
||||||
blockscolor: "&f"
|
blockscolor: "&f"
|
||||||
hint: "/ greenhouse listを使用して、レシピ番号のリストを表示します!"
|
hint: "/ greenhouse listを使用して、レシピ番号のリストを表示します!"
|
||||||
|
wrongnumber: レシピ番号は1から[size]の間でなければなりません
|
||||||
|
title: "[[biome]レシピ]"
|
||||||
|
nowater: 水は許可されません。
|
||||||
|
noice: 氷は許可されていません。
|
||||||
|
nolava: 溶岩は許可されていません。
|
||||||
|
watermustbe: 水> [coverage]床面積の%。
|
||||||
icemustbe: 氷のブロック>床面積の[coverage]%。
|
icemustbe: 氷のブロック>床面積の[coverage]%。
|
||||||
lavamustbe: 溶岩> [coverage]床面積の%。
|
lavamustbe: 溶岩> [coverage]床面積の%。
|
||||||
minimumblockstitle: "[必要な最小ブロック]"
|
minimumblockstitle: "[必要な最小ブロック]"
|
||||||
missing: 温室がありません
|
|
||||||
noice: 氷は許可されていません。
|
|
||||||
nolava: 溶岩は許可されていません。
|
|
||||||
nootherblocks: 他のブロックは必要ありません。
|
nootherblocks: 他のブロックは必要ありません。
|
||||||
nowater: 水は許可されません。
|
missing: 温室がありません
|
||||||
title: "[[biome]レシピ]"
|
event:
|
||||||
watermustbe: 水> [coverage]床面積の%。
|
broke: あなたはこの温室を壊しました!バイオームを[biome]に戻しています!
|
||||||
wrongnumber: レシピ番号は1から[size]の間でなければなりません
|
fix: 温室を修理してから、もう一度作ります。
|
||||||
|
cannotplace: ブロックを温室の上に置くことはできません!
|
||||||
|
pistonerror: ピストンは温室の上でブロックを押すことができません!
|
||||||
|
limits:
|
||||||
|
noneallowed: 許可により温室が許可されないため、[number]は削除されました。
|
||||||
|
limitedto: 許可により温室が[limit]に制限されるため、[number]が削除されました。
|
||||||
|
adminHelp:
|
||||||
|
reload: ファイルから設定をリロードします。
|
||||||
|
info: あなたがいる温室に関する情報を提供します
|
||||||
reload:
|
reload:
|
||||||
configReloaded: ファイルから構成が再ロードされました。
|
configReloaded: ファイルから構成が再ロードされました。
|
||||||
|
admininfo:
|
||||||
|
error: ゲーム内でのみ利用可能な温室情報
|
||||||
|
error2: 温室で情報を確認してください。
|
||||||
|
flags: "[温室旗]"
|
||||||
|
news:
|
||||||
|
headline: "[温室ニュース]"
|
||||||
|
controlpanel:
|
||||||
|
title: "&A温室"
|
||||||
|
190
src/main/resources/locales/vi.yml
Normal file
190
src/main/resources/locales/vi.yml
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
###########################################################################################
|
||||||
|
# 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: Nhà kính
|
||||||
|
description: |
|
||||||
|
&b Chỉnh cho ai có thể
|
||||||
|
&b điều khiển nhà kính
|
||||||
|
|
||||||
|
greenhouses:
|
||||||
|
general:
|
||||||
|
greenhouses: "Nhà kính"
|
||||||
|
|
||||||
|
errors:
|
||||||
|
move: "Di chuyển đến nhà kính của bạn trước."
|
||||||
|
no-rank: "&c Bạn không có cấp bậc để làm điều đó."
|
||||||
|
notyours: "Đây không phải nhà kính của bạn!"
|
||||||
|
not-inside: "&c Bạn không có ở trong nhà kính của bạn!"
|
||||||
|
tooexpensive: "Bạn không có đủ [price]"
|
||||||
|
alreadyexists: "Nhà kính đã tồn tại!"
|
||||||
|
norecipe: "Không thể tạo nhà kính!"
|
||||||
|
|
||||||
|
event:
|
||||||
|
broke: "Bạn đã đập nhà kính! Chuyển về [biome]!"
|
||||||
|
entering: "Đã vào nhà kính [biome]"
|
||||||
|
leaving: "Đã rời nhà kính [biome]"
|
||||||
|
|
||||||
|
recipe:
|
||||||
|
blockscolor: "&f"
|
||||||
|
title: "[Công thức [biome]]"
|
||||||
|
watermustbe: "Nước > [coverage]% trong một khu vực."
|
||||||
|
icemustbe: "Băng > [coverage]% trong một khu vực."
|
||||||
|
lavamustbe: "Nham thạch > [coverage]% trong một khu vực."
|
||||||
|
minimumblockstitle: "[Cần số khối tối thiểu]"
|
||||||
|
nootherblocks: "Không cần khối khác."
|
||||||
|
missing: "Nhà kính đang bị thiếu"
|
||||||
|
|
||||||
|
commands:
|
||||||
|
user:
|
||||||
|
remove:
|
||||||
|
description: "Xóa nhà kính ở chỗ bạn đứng nếu bạn là chủ"
|
||||||
|
make:
|
||||||
|
description: "Tạo một nhà kính"
|
||||||
|
parameters: "<công thức>"
|
||||||
|
error:
|
||||||
|
already: "&cNhà kính đã tồn tại!"
|
||||||
|
FAIL_BAD_ROOF_BLOCKS: "&c Trần nhà có khối không hợp lệ!"
|
||||||
|
FAIL_BAD_WALL_BLOCKS: "&c Tường nhà có khối không hợp lệ!"
|
||||||
|
FAIL_BELOW: "&c Bạn phải ở trong nhà kính để tạo nó"
|
||||||
|
FAIL_BLOCKS_ABOVE: "&c Không có khối ở trên nhà kính! Khối kính đỏ sẽ cho biết chỗ có vấn đề."
|
||||||
|
FAIL_HOLE_IN_ROOF: "&c Có một lỗ trên trần hoặc trần không phẳng! Khối kính đỏ sẽ cho biết chỗ có vấn đề."
|
||||||
|
FAIL_HOLE_IN_WALL: "&c Có một lỗ trên tường!"
|
||||||
|
FAIL_NO_ROOF: "&c Có vẻ chưa có trần nhà!"
|
||||||
|
FAIL_TOO_MANY_DOORS: "&c Bạn không thể có hơn 4 cánh cửa trong nhà kính!"
|
||||||
|
FAIL_TOO_MANY_HOPPERS: "&c Chỉ có một phễu được cho phép trên tường hoặc trên trần."
|
||||||
|
FAIL_UNEVEN_WALLS: "&c Tường không cân bằng. Khối kính đỏ sẽ cho biết chỗ có vấn đề."
|
||||||
|
FAIL_INSUFFICIENT_ICE: "&c Không đủ băng để làm công thức này"
|
||||||
|
FAIL_INSUFFICIENT_LAVA: "&c Không đủ nham thạch để làm công thức này"
|
||||||
|
FAIL_INSUFFICIENT_WATER: "&c Không đủ nước để làm công thức này"
|
||||||
|
FAIL_NO_ICE: "&c Cần băng để làm công thức này"
|
||||||
|
FAIL_NO_LAVA: "&c Cần nham thạch để làm công thức này"
|
||||||
|
FAIL_NO_WATER: "&c Cần nước để làm công thức này"
|
||||||
|
FAIL_NO_RECIPE_FOUND: "&c Không có công thức phù hợp cho nhà kính này"
|
||||||
|
FAIL_INSUFFICIENT_BLOCKS: "&c Cần nhiều khối hơn để làm công thức này!"
|
||||||
|
FAIL_OVERLAPPING: "&c Nhà kính không thể có tường chung, xin lỗi."
|
||||||
|
success: "&2 Bạn đã tạo nhà kính [biome]! Nó sẽ đồng bộ ở lần dịch chuyển hoặc đăng nhập tiếp theo."
|
||||||
|
missing-blocks: "&c Thiếu [material] x [number]"
|
||||||
|
unknown-recipe: "&c Công thức không tồn tại"
|
||||||
|
try-these: "&c Thử một trong những cái này:"
|
||||||
|
recipe-format: "&3[name]"
|
||||||
|
info:
|
||||||
|
title: "&a [Cách tạo một nhà kính]"
|
||||||
|
instructions: |
|
||||||
|
&e Tạo một hộp bằng kính với 4 bức tường và một cái trần phẳng
|
||||||
|
&e và thêm vào tối đa &f 4 cánh cửa &Etrên tường.
|
||||||
|
&e Đặt &f 1 cái phễu &e trên tường hoặc trần nhà và thêm nào đó các xô nước.
|
||||||
|
&e để tạo tuyết hoặc thêm bột xương để mọc cây tự động.
|
||||||
|
&e Kiểm tra các công thức để biết các khối cần có
|
||||||
|
&e trong nhà kính để tạo một cái.
|
||||||
|
|
||||||
|
|
||||||
|
######### Old locale for reference
|
||||||
|
help:
|
||||||
|
help: "hướng dẫn"
|
||||||
|
make: "Tạo một nhà kính"
|
||||||
|
remove: "Xóa nhà kính ở chỗ bạn đứng nếu bạn là chủ"
|
||||||
|
info: "Cách tạo một nhà kính"
|
||||||
|
list: "Liệt kê các biome trong nhà kính bạn có thể tạo"
|
||||||
|
recipe: "Hướng dẫn cách tạo một biome trong nhà kính"
|
||||||
|
opengui: "Mở Menu nhà kính"
|
||||||
|
|
||||||
|
list:
|
||||||
|
title: "[Công thức Biome nhà kính]"
|
||||||
|
info: "Dùng /greenhouse recipe <số> để xem thông tin cách tạo nhà kính"
|
||||||
|
|
||||||
|
|
||||||
|
################
|
||||||
|
#General Errors#
|
||||||
|
################
|
||||||
|
error:
|
||||||
|
greenhouseProtected: "Đã bảo vệ nhà kính"
|
||||||
|
move: "Di chuyển đến nhà kính của bạn trước."
|
||||||
|
notowner: "Bạn phải là chủ nhà kính để làm điều này."
|
||||||
|
removing: "Đang xóa nhà kính!"
|
||||||
|
notyours: "Đây không phải nhà kính của bạn!"
|
||||||
|
notinside: "Bạn không có ở trong nhà kính!"
|
||||||
|
tooexpensive: "Bạn không có đủ [price]"
|
||||||
|
alreadyexists: "Nhà kính đã tồn tại!"
|
||||||
|
norecipe: "Không thể tạo nhà kính!"
|
||||||
|
|
||||||
|
messages:
|
||||||
|
enter: "Đang vào nhà kính [biome] của [owner]!"
|
||||||
|
leave: "Đang rời nhà kính của [owner]."
|
||||||
|
youarein: "Bạn đang ở nhà kính [biome] của [owner]!"
|
||||||
|
removed: "Nhà kính này không còn nữa..."
|
||||||
|
removedmessage: "Một nhà kính [biome] của bạn không còn nữa!"
|
||||||
|
ecolost: "Nhà kính của bạn ở [location] mất hệ sinh thái và đã bị xóa."
|
||||||
|
|
||||||
|
info:
|
||||||
|
title: "&A[Cách tạo một nhà kính]"
|
||||||
|
instructions: |
|
||||||
|
&e Tạo một hộp bằng kính với 4 bức tường và một cái trần phẳng
|
||||||
|
&e và thêm vào tối đa &f 4 cánh cửa &Etrên tường.
|
||||||
|
&e Đặt &f 1 cái phễu &e trên tường hoặc trần nhà và thêm nào đó các xô nước.
|
||||||
|
&e để tạo tuyết hoặc thêm bột xương để mọc cây tự động.
|
||||||
|
&e Kiểm tra các công thức để biết các khối cần có
|
||||||
|
&e trong nhà kính để tạo một cái.
|
||||||
|
info: "[Thông tin nhà kính]"
|
||||||
|
none: "Không có"
|
||||||
|
nomore: "&4 Bạn không thể xây thêm nhà kính!"
|
||||||
|
onemore: "&6 Bạn có thể xây thêm một nhà kính."
|
||||||
|
youcanbuild: "&A Bạn có thể xây thêm tối đa [number] nhà kính nữa!"
|
||||||
|
unlimited: "&A Bạn có thể xây vô hạn nhà kính!"
|
||||||
|
welcome: "&B Xin chào! Nhấp vào đây để xem hướng dẫn"
|
||||||
|
|
||||||
|
recipe:
|
||||||
|
blockscolor: "&f"
|
||||||
|
hint: "Dùng /greenhouse list để xem số công thức!"
|
||||||
|
wrongnumber: "Số công thức phải từ 1 đến [size]"
|
||||||
|
title: "[Công thức [biome]]"
|
||||||
|
nowater: "Không cho phép có nước."
|
||||||
|
noice: "Không cho phép có băng."
|
||||||
|
nolava: "Không cho phép có nham thạch."
|
||||||
|
watermustbe: "Nước > [coverage]% trong một khu vực."
|
||||||
|
icemustbe: "Băng > [coverage]% trong một khu vực."
|
||||||
|
lavamustbe: "Nham thạch > [coverage]% trong một khu vực."
|
||||||
|
minimumblockstitle: "[Cần số khối tối thiểu]"
|
||||||
|
nootherblocks: "Không cần khối khác."
|
||||||
|
missing: "Nhà kính đang bị thiếu"
|
||||||
|
|
||||||
|
event:
|
||||||
|
broke: "Bạn đã đập nhà kính! Chuyển về [biome]!"
|
||||||
|
fix: "Sửa nhà kính và tạo lại."
|
||||||
|
cannotplace: "Các khối không thể đặt trên nhà kính!"
|
||||||
|
pistonerror: "Pít tông không thể đẩy khối vào một nhà kính!"
|
||||||
|
|
||||||
|
|
||||||
|
limits:
|
||||||
|
noneallowed: "Quyền không cho phép bạn nên [number] đã bị xóa."
|
||||||
|
limitedto: "Quyền đã giới hạn bạn chỉ [limit] nhà kính nên [number] đã bị xóa."
|
||||||
|
|
||||||
|
|
||||||
|
##################################
|
||||||
|
#Admin commands that use /gadmin #
|
||||||
|
##################################
|
||||||
|
|
||||||
|
#Help
|
||||||
|
adminHelp:
|
||||||
|
reload: "nạp các tùy chỉnh từ tệp."
|
||||||
|
info: "xem các thông tin về nhà kính bạn đang đứng"
|
||||||
|
|
||||||
|
#reload
|
||||||
|
reload:
|
||||||
|
configReloaded: "Đã nạp các tùy chỉnh từ tệp."
|
||||||
|
|
||||||
|
admininfo:
|
||||||
|
error: "Thông tin nhà kính chỉ tồn tại trong game"
|
||||||
|
error2: "Đặt bạn vào một nhà kính để xem thông tin."
|
||||||
|
flags: "[Cờ Nhà Kính]"
|
||||||
|
|
||||||
|
news:
|
||||||
|
headline: "[Bản Tin Nhà Kính]"
|
||||||
|
|
||||||
|
controlpanel:
|
||||||
|
title: "&ANhà kính"
|
||||||
|
|
@ -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:
|
protection:
|
||||||
flags:
|
flags:
|
||||||
GREENHOUSE:
|
GREENHOUSE:
|
||||||
@ -12,9 +9,9 @@ greenhouses:
|
|||||||
greenhouses: 温室
|
greenhouses: 温室
|
||||||
errors:
|
errors:
|
||||||
move: 移动到你拥有的第一个温室.
|
move: 移动到你拥有的第一个温室.
|
||||||
no-rank: '&c你没有足够的阶级去做这个.'
|
no-rank: "&c你没有足够的阶级去做这个."
|
||||||
notyours: 这不是你的温室!
|
notyours: 这不是你的温室!
|
||||||
not-inside: '&c你并不处于一个温室之中!'
|
not-inside: "&c你并不处于一个温室之中!"
|
||||||
tooexpensive: 你的钱不足以支付 [price]
|
tooexpensive: 你的钱不足以支付 [price]
|
||||||
alreadyexists: 温室已经存在!
|
alreadyexists: 温室已经存在!
|
||||||
norecipe: 无法创建一个温室!
|
norecipe: 无法创建一个温室!
|
||||||
@ -23,12 +20,12 @@ greenhouses:
|
|||||||
entering: 你进入一个 [biome] 温室
|
entering: 你进入一个 [biome] 温室
|
||||||
leaving: 你离开了 [biome] 温室
|
leaving: 你离开了 [biome] 温室
|
||||||
recipe:
|
recipe:
|
||||||
blockscolor: '&f'
|
blockscolor: "&f"
|
||||||
title: '[[biome] 配方]'
|
title: "[[biome] 配方]"
|
||||||
watermustbe: 水在地面上的占比需要大于[coverage]%.
|
watermustbe: 水在地面上的占比需要大于[coverage]%.
|
||||||
icemustbe: 冰在地面上的占比需要大于[coverage]%.
|
icemustbe: 冰在地面上的占比需要大于[coverage]%.
|
||||||
lavamustbe: 岩浆在地面上的占比需要大于[coverage]%.
|
lavamustbe: 岩浆在地面上的占比需要大于[coverage]%.
|
||||||
minimumblockstitle: '[最少所需的方块数目]'
|
minimumblockstitle: "[最少所需的方块数目]"
|
||||||
nootherblocks: 没有其它需要的方块了.
|
nootherblocks: 没有其它需要的方块了.
|
||||||
missing: 温室缺失了
|
missing: 温室缺失了
|
||||||
commands:
|
commands:
|
||||||
@ -37,39 +34,37 @@ greenhouses:
|
|||||||
description: 如果你是你现在所处的温室的主人则移除这个温室
|
description: 如果你是你现在所处的温室的主人则移除这个温室
|
||||||
make:
|
make:
|
||||||
description: 尝试建造一个温室
|
description: 尝试建造一个温室
|
||||||
parameters: <recipe>
|
parameters: "<recipe>"
|
||||||
error:
|
error:
|
||||||
already: '&c这已经有一个温室了!'
|
already: "&c这已经有一个温室了!"
|
||||||
FAIL_BAD_ROOF_BLOCKS: '&c屋顶包含了不被允许的方块!'
|
FAIL_BAD_ROOF_BLOCKS: "&c屋顶包含了不被允许的方块!"
|
||||||
FAIL_BAD_WALL_BLOCKS: '&c墙壁包含了不被允许的方块!'
|
FAIL_BAD_WALL_BLOCKS: "&c墙壁包含了不被允许的方块!"
|
||||||
FAIL_BELOW: '&c你必须处于温室结构内才能尝试建造它'
|
FAIL_BELOW: "&c你必须处于温室结构内才能尝试建造它"
|
||||||
FAIL_BLOCKS_ABOVE: '&c温室的上方不能有方块,违规方块已被标红.'
|
FAIL_BLOCKS_ABOVE: "&c温室的上方不能有方块,违规方块已被标红."
|
||||||
FAIL_HOLE_IN_ROOF: '&c屋顶上有一个洞或者屋顶并不平整,违规方块已被标红.'
|
FAIL_HOLE_IN_ROOF: "&c屋顶上有一个洞或者屋顶并不平整,违规方块已被标红."
|
||||||
FAIL_HOLE_IN_WALL: '&c墙上有一个洞!'
|
FAIL_HOLE_IN_WALL: "&c墙上有一个洞!"
|
||||||
FAIL_NO_ROOF: '&c这儿看起来没有屋顶!'
|
FAIL_NO_ROOF: "&c这儿看起来没有屋顶!"
|
||||||
FAIL_TOO_MANY_DOORS: '&c你的温室最多只能有四个门!'
|
FAIL_TOO_MANY_DOORS: "&c你的温室最多只能有四个门!"
|
||||||
FAIL_TOO_MANY_HOPPERS: '&c墙或屋顶上至多有一个漏斗.'
|
FAIL_TOO_MANY_HOPPERS: "&c墙或屋顶上至多有一个漏斗."
|
||||||
FAIL_UNEVEN_WALLS: '&c墙壁不平坦,违规方块已被标红.'
|
FAIL_UNEVEN_WALLS: "&c墙壁不平坦,违规方块已被标红."
|
||||||
FAIL_INSUFFICIENT_ICE: '&c冰的数目不足以建造这个温室'
|
FAIL_INSUFFICIENT_ICE: "&c冰的数目不足以建造这个温室"
|
||||||
FAIL_INSUFFICIENT_LAVA: '&c岩浆的数目不足以建造这个温室'
|
FAIL_INSUFFICIENT_LAVA: "&c岩浆的数目不足以建造这个温室"
|
||||||
FAIL_INSUFFICIENT_WATER: '&c水的数目不足以建造这个温室'
|
FAIL_INSUFFICIENT_WATER: "&c水的数目不足以建造这个温室"
|
||||||
FAIL_NO_ICE: '&c对于这个温室来说冰是必须的'
|
FAIL_NO_ICE: "&c对于这个温室来说冰是必须的"
|
||||||
FAIL_NO_LAVA: '&c对于这个温室来说岩浆是必须的'
|
FAIL_NO_LAVA: "&c对于这个温室来说岩浆是必须的"
|
||||||
FAIL_NO_WATER: '&c对于这个温室来说水是必须的'
|
FAIL_NO_WATER: "&c对于这个温室来说水是必须的"
|
||||||
FAIL_INSUFFICIENT_BLOCKS: '&c你所用的方块数目不足!'
|
FAIL_NO_RECIPE_FOUND: "&c 找不到与此温室相匹配的配方"
|
||||||
FAIL_OVERLAPPING: '&c温室间不能共享墙壁.'
|
FAIL_INSUFFICIENT_BLOCKS: "&c你所用的方块数目不足!"
|
||||||
success: '&2你成功的建造了一个 [biome] 群系温室! 在你下次登陆时生物群系将会刷新.'
|
FAIL_OVERLAPPING: "&c温室间不能共享墙壁."
|
||||||
missing-blocks: '&c缺少了 [material] x [number]'
|
success: "&2你成功的建造了一个 [biome] 群系温室! 在你下次登陆时生物群系将会刷新."
|
||||||
unknown-recipe: '&c未知的温室配方'
|
missing-blocks: "&c缺少了 [material] x [number]"
|
||||||
try-these: '&c尝试以下操作:'
|
unknown-recipe: "&c未知的温室配方"
|
||||||
recipe-format: '&3[name]'
|
try-these: "&c尝试以下操作:"
|
||||||
|
recipe-format: "&3[name]"
|
||||||
info:
|
info:
|
||||||
title: '&A[温室建造指南]'
|
title: "&A[温室建造指南]"
|
||||||
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n\
|
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗
|
||||||
&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗\
|
\n&E来放置骨粉或雪 来让作物自动生长.\n&E检查温室配方确保 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
||||||
\ \n&E来放置骨粉或雪\
|
|
||||||
\ 来让作物自动生长.\n&E检查温室配方确保\
|
|
||||||
\ 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
|
||||||
help:
|
help:
|
||||||
help: 帮助
|
help: 帮助
|
||||||
make: 尝试建造一个温室
|
make: 尝试建造一个温室
|
||||||
@ -79,7 +74,7 @@ help:
|
|||||||
recipe: 告知你如何制造一个温室
|
recipe: 告知你如何制造一个温室
|
||||||
opengui: 打开温室GUI
|
opengui: 打开温室GUI
|
||||||
list:
|
list:
|
||||||
title: '[温室建造指南]'
|
title: "[温室建造指南]"
|
||||||
info: 使用指令 /greenhouse recipe <number> 来查看建造每一个温室的细节
|
info: 使用指令 /greenhouse recipe <number> 来查看建造每一个温室的细节
|
||||||
error:
|
error:
|
||||||
greenhouseProtected: 温室已被保护
|
greenhouseProtected: 温室已被保护
|
||||||
@ -99,31 +94,28 @@ messages:
|
|||||||
removedmessage: 你的 [biome] 温室已经被移除!
|
removedmessage: 你的 [biome] 温室已经被移除!
|
||||||
ecolost: 你位于 [location] 的温室生态环境遭到破坏,它已经不再是温室了.
|
ecolost: 你位于 [location] 的温室生态环境遭到破坏,它已经不再是温室了.
|
||||||
info:
|
info:
|
||||||
title: '&A[如何建造一个温室]'
|
title: "&A[如何建造一个温室]"
|
||||||
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n\
|
instructions: "&E用玻璃建造一个有四面墙和屋顶的平整的立方体\n&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗 \n&E来放置骨粉或雪
|
||||||
&E最多只能有 &F4 扇门. &E\n在墙壁或屋顶内&E放置 &F一个漏斗\
|
来让作物自动生长.\n&E检查温室配方确保 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
||||||
\ \n&E来放置骨粉或雪\
|
info: "[温室信息]"
|
||||||
\ 来让作物自动生长.\n&E检查温室配方确保\
|
|
||||||
\ 你的温室包含足够的必要方块\n&E温室就顺利建造了. \n"
|
|
||||||
info: '[温室信息]'
|
|
||||||
none: 无
|
none: 无
|
||||||
nomore: '&4你无法建造更多的温室了!'
|
nomore: "&4你无法建造更多的温室了!"
|
||||||
onemore: '&6你可以再建造一个温室.'
|
onemore: "&6你可以再建造一个温室."
|
||||||
youcanbuild: '&A你最多能建造 [number] 个温室!'
|
youcanbuild: "&A你最多能建造 [number] 个温室!"
|
||||||
unlimited: '&A你能建造无限多个温室!'
|
unlimited: "&A你能建造无限多个温室!"
|
||||||
welcome: '&B你好! 点击这里获得更多提示'
|
welcome: "&B你好! 点击这里获得更多提示"
|
||||||
recipe:
|
recipe:
|
||||||
blockscolor: '&f'
|
blockscolor: "&f"
|
||||||
hint: 使用 /greenhouse list 来看见所有温室配方的编号!
|
hint: 使用 /greenhouse list 来看见所有温室配方的编号!
|
||||||
wrongnumber: 温室配方编号必须位于 1 与 [size] 之间
|
wrongnumber: 温室配方编号必须位于 1 与 [size] 之间
|
||||||
title: '[[biome] 配方]'
|
title: "[[biome] 配方]"
|
||||||
nowater: 不允许有水.
|
nowater: 不允许有水.
|
||||||
noice: 不允许有冰.
|
noice: 不允许有冰.
|
||||||
nolava: 不允许有岩浆.
|
nolava: 不允许有岩浆.
|
||||||
watermustbe: 水在地面上的占比需要大于 [coverage]%.
|
watermustbe: 水在地面上的占比需要大于 [coverage]%.
|
||||||
icemustbe: 冰在地面上的占比需要大于 [coverage]%.
|
icemustbe: 冰在地面上的占比需要大于 [coverage]%.
|
||||||
lavamustbe: 岩浆在地面上的占比需要大于 [coverage]%.
|
lavamustbe: 岩浆在地面上的占比需要大于 [coverage]%.
|
||||||
minimumblockstitle: '[最少所需的方块]'
|
minimumblockstitle: "[最少所需的方块]"
|
||||||
nootherblocks: 没有其它必要的方块了.
|
nootherblocks: 没有其它必要的方块了.
|
||||||
missing: 温室缺失了
|
missing: 温室缺失了
|
||||||
event:
|
event:
|
||||||
@ -142,8 +134,8 @@ reload:
|
|||||||
admininfo:
|
admininfo:
|
||||||
error: 查看温室信息功能仅能在游戏中使用
|
error: 查看温室信息功能仅能在游戏中使用
|
||||||
error2: 进入一个温室才能查看其信息.
|
error2: 进入一个温室才能查看其信息.
|
||||||
flags: '[Greenhouse Flags]'
|
flags: "[Greenhouse Flags]"
|
||||||
news:
|
news:
|
||||||
headline: '[温室新闻]'
|
headline: "[温室新闻]"
|
||||||
controlpanel:
|
controlpanel:
|
||||||
title: '&A温室'
|
title: "&A温室"
|
||||||
|
9
src/main/resources/plugin.yml
Normal file
9
src/main/resources/plugin.yml
Normal file
@ -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}
|
175
src/test/java/world/bentobox/greenhouses/SettingsTest.java
Normal file
175
src/test/java/world/bentobox/greenhouses/SettingsTest.java
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
package world.bentobox.greenhouses;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
public class SettingsTest {
|
||||||
|
|
||||||
|
private Settings s;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
s = new Settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetGameModes() {
|
||||||
|
assertTrue(s.getGameModes().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSnowSpeed() {
|
||||||
|
assertEquals(30D, s.getSnowSpeed(), 0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSnowChanceGlobal() {
|
||||||
|
assertEquals(1D, s.getSnowChanceGlobal(), 0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSnowDensity() {
|
||||||
|
assertEquals(0.1D, s.getSnowDensity(), 0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEcoTick() {
|
||||||
|
assertEquals(5, s.getEcoTick());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPlantTick() {
|
||||||
|
assertEquals(1, s.getPlantTick());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetBlockTick() {
|
||||||
|
assertEquals(2, s.getBlockTick());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetMobTick() {
|
||||||
|
assertEquals(5, s.getMobTick());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsStartupLog() {
|
||||||
|
assertFalse(s.isStartupLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetStartupLog() {
|
||||||
|
s.setStartupLog(true);
|
||||||
|
assertTrue(s.isStartupLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsAllowFlowOut() {
|
||||||
|
assertFalse(s.isAllowFlowOut());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsAllowFlowIn() {
|
||||||
|
assertFalse(s.isAllowFlowIn());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetGameModes() {
|
||||||
|
s.setGameModes(Collections.singletonList("BSkyBlock"));
|
||||||
|
assertEquals("BSkyBlock", s.getGameModes().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSnowSpeed() {
|
||||||
|
s.setSnowSpeed(50);
|
||||||
|
assertEquals(50D, s.getSnowSpeed(), 0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSnowChanceGlobal() {
|
||||||
|
s.setSnowChanceGlobal(50);
|
||||||
|
assertEquals(50D, s.getSnowChanceGlobal(), 0D);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSnowDensity() {
|
||||||
|
s.setSnowDensity(50);
|
||||||
|
assertEquals(50D, s.getSnowDensity(), 0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetEcoTick() {
|
||||||
|
s.setEcoTick(50);
|
||||||
|
assertEquals(50, s.getEcoTick());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetPlantTick() {
|
||||||
|
s.setPlantTick(50);
|
||||||
|
assertEquals(50, s.getPlantTick());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetBlockTick() {
|
||||||
|
s.setBlockTick(50);
|
||||||
|
assertEquals(50, s.getBlockTick());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetMobTick() {
|
||||||
|
s.setMobTick(50);
|
||||||
|
assertEquals(50, s.getMobTick());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAllowFlowOut() {
|
||||||
|
assertFalse(s.isAllowFlowOut());
|
||||||
|
s.setAllowFlowOut(true);
|
||||||
|
assertTrue(s.isAllowFlowOut());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAllowFlowIn() {
|
||||||
|
assertFalse(s.isAllowFlowIn());
|
||||||
|
s.setAllowFlowIn(true);
|
||||||
|
assertTrue(s.isAllowFlowIn());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsAllowGlowstone() {
|
||||||
|
assertTrue(s.isAllowGlowstone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAllowGlowstone() {
|
||||||
|
assertTrue(s.isAllowGlowstone());
|
||||||
|
s.setAllowGlowstone(false);
|
||||||
|
assertFalse(s.isAllowGlowstone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsAllowPanes() {
|
||||||
|
assertTrue(s.isAllowPanes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAllowPanes() {
|
||||||
|
assertTrue(s.isAllowPanes());
|
||||||
|
s.setAllowPanes(false);
|
||||||
|
assertFalse(s.isAllowPanes());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,9 +2,9 @@ package world.bentobox.greenhouses.data;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ -16,6 +16,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.util.BoundingBox;
|
import org.bukkit.util.BoundingBox;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -54,15 +55,12 @@ public class GreenhouseTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private BiomeRecipe br;
|
private BiomeRecipe br;
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
// RecipeManager
|
// RecipeManager
|
||||||
PowerMockito.mockStatic(RecipeManager.class);
|
PowerMockito.mockStatic(RecipeManager.class);
|
||||||
when(br.getName()).thenReturn("test");
|
when(br.getName()).thenReturn("test");
|
||||||
when(RecipeManager.getBiomeRecipies(eq("test"))).thenReturn(Optional.of(br));
|
when(RecipeManager.getBiomeRecipies("test")).thenReturn(Optional.of(br));
|
||||||
// Walls
|
// Walls
|
||||||
when(walls.getMinX()).thenReturn(MINX);
|
when(walls.getMinX()).thenReturn(MINX);
|
||||||
when(walls.getMinZ()).thenReturn(MINZ);
|
when(walls.getMinZ()).thenReturn(MINZ);
|
||||||
@ -73,10 +71,9 @@ public class GreenhouseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
*/
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() {
|
||||||
Mockito.framework().clearInlineMocks();
|
Mockito.framework().clearInlineMocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,13 +185,15 @@ public class GreenhouseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.data.Greenhouse#setRoofHopperLocation(org.bukkit.Location)}.
|
* Test method for {@link world.bentobox.greenhouses.data.Greenhouse#setRoofHopperLocation(Vector)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSetRoofHopperLocation() {
|
public void testSetRoofHopperLocation() {
|
||||||
Location l = new Location(world, 1,2,3);
|
gh.setRoofHopperLocation(new Vector(1,2,3));
|
||||||
gh.setRoofHopperLocation(l);
|
assertEquals(world, gh.getRoofHopperLocation().getWorld());
|
||||||
assertEquals(l, gh.getRoofHopperLocation());
|
assertEquals(1, gh.getRoofHopperLocation().getBlockX());
|
||||||
|
assertEquals(2, gh.getRoofHopperLocation().getBlockY());
|
||||||
|
assertEquals(3, gh.getRoofHopperLocation().getBlockZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -276,7 +275,7 @@ public class GreenhouseTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetBiomeRecipe() {
|
public void testGetBiomeRecipe() {
|
||||||
assertNull(gh.getBiomeRecipe());
|
assertNotNull(gh.getBiomeRecipe());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,7 +284,7 @@ public class GreenhouseTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSetMissingBlocks() {
|
public void testSetMissingBlocks() {
|
||||||
gh.setMissingBlocks(Collections.singletonMap(Material.ACACIA_BOAT, 20));
|
gh.setMissingBlocks(Collections.singletonMap(Material.ACACIA_BOAT, 20));
|
||||||
assertTrue(gh.getMissingBlocks().get(Material.ACACIA_BOAT) == 20);
|
assertEquals(20, (int) gh.getMissingBlocks().get(Material.ACACIA_BOAT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -293,7 +292,7 @@ public class GreenhouseTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetMissingBlocks() {
|
public void testGetMissingBlocks() {
|
||||||
assertNull(gh.getMissingBlocks());
|
assertNotNull(gh.getMissingBlocks());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -47,8 +46,8 @@ import world.bentobox.bentobox.BentoBox;
|
|||||||
import world.bentobox.greenhouses.Greenhouses;
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
import world.bentobox.greenhouses.Settings;
|
import world.bentobox.greenhouses.Settings;
|
||||||
import world.bentobox.greenhouses.data.Greenhouse;
|
import world.bentobox.greenhouses.data.Greenhouse;
|
||||||
|
import world.bentobox.greenhouses.managers.EcoSystemManager.GrowthBlock;
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseManager;
|
import world.bentobox.greenhouses.managers.GreenhouseManager;
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseMap;
|
import world.bentobox.greenhouses.managers.GreenhouseMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +62,6 @@ public class BiomeRecipeTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Greenhouses addon;
|
private Greenhouses addon;
|
||||||
|
|
||||||
private Biome type;
|
|
||||||
@Mock
|
@Mock
|
||||||
private Greenhouse gh;
|
private Greenhouse gh;
|
||||||
|
|
||||||
@ -87,20 +85,19 @@ public class BiomeRecipeTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Settings settings;
|
private Settings settings;
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
PowerMockito.mockStatic(Bukkit.class);
|
PowerMockito.mockStatic(Bukkit.class);
|
||||||
when(Bukkit.createBlockData(any(Material.class))).thenReturn(bd);
|
when(Bukkit.createBlockData(any(Material.class))).thenReturn(bd);
|
||||||
type = Biome.BADLANDS;
|
Biome type = Biome.BADLANDS;
|
||||||
// Greenhouse
|
// Greenhouse
|
||||||
when(gh.getArea()).thenReturn(100);
|
when(gh.getArea()).thenReturn(100);
|
||||||
when(gh.getFloorHeight()).thenReturn(100);
|
when(gh.getFloorHeight()).thenReturn(100);
|
||||||
when(gh.getCeilingHeight()).thenReturn(120);
|
when(gh.getCeilingHeight()).thenReturn(120);
|
||||||
bb = new BoundingBox(10, 100, 10, 20, 120, 20);
|
bb = new BoundingBox(10, 100, 10, 20, 120, 20);
|
||||||
when(gh.getBoundingBox()).thenReturn(bb);
|
when(gh.getBoundingBox()).thenReturn(bb);
|
||||||
|
BoundingBox ibb = bb.clone().expand(-1);
|
||||||
|
when(gh.getInternalBoundingBox()).thenReturn(ibb);
|
||||||
when(gh.getWorld()).thenReturn(world);
|
when(gh.getWorld()).thenReturn(world);
|
||||||
when(gh.contains(any())).thenReturn(true);
|
when(gh.contains(any())).thenReturn(true);
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
||||||
@ -154,50 +151,50 @@ public class BiomeRecipeTest {
|
|||||||
double convChance = 100D;
|
double convChance = 100D;
|
||||||
Material localMaterial = Material.WATER;
|
Material localMaterial = Material.WATER;
|
||||||
br.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
br.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
||||||
verify(addon).log(eq(" 100.0% chance for Sand to convert to Clay"));
|
verify(addon).log(" 100.0% chance for Sand to convert to Clay");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addMobs(org.bukkit.entity.EntityType, int, org.bukkit.Material)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addMobs(org.bukkit.entity.EntityType, double, org.bukkit.Material)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddMobs() {
|
public void testAddMobs() {
|
||||||
EntityType mobType = EntityType.CAT;
|
EntityType mobType = EntityType.CAT;
|
||||||
int mobProbability = 50;
|
int mobProbability = 50;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
verify(addon).log(eq(" 50.0% chance for Cat to spawn on Grass Path."));
|
verify(addon).log(" 50.0% chance for Cat to spawn on Grass Block.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addMobs(org.bukkit.entity.EntityType, int, org.bukkit.Material)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addMobs(org.bukkit.entity.EntityType, double, org.bukkit.Material)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddMobsOver100Percent() {
|
public void testAddMobsOver100Percent() {
|
||||||
EntityType mobType = EntityType.CAT;
|
EntityType mobType = EntityType.CAT;
|
||||||
int mobProbability = 50;
|
int mobProbability = 50;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addMobs(org.bukkit.entity.EntityType, int, org.bukkit.Material)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addMobs(org.bukkit.entity.EntityType, double, org.bukkit.Material)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddMobsOver100PercentDouble() {
|
public void testAddMobsOver100PercentDouble() {
|
||||||
EntityType mobType = EntityType.CAT;
|
EntityType mobType = EntityType.CAT;
|
||||||
double mobProbability = 50.5;
|
double mobProbability = 50.5;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
verify(addon).logError(eq("Mob chances add up to > 100% in BADLANDS biome recipe! Skipping CAT"));
|
verify(addon).logError("Mob chances add up to > 100% in BADLANDS biome recipe! Skipping CAT");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addPlants(org.bukkit.Material, int, org.bukkit.Material)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addPlants(org.bukkit.Material, double, org.bukkit.Material)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddPlants() {
|
public void testAddPlants() {
|
||||||
@ -205,11 +202,11 @@ public class BiomeRecipeTest {
|
|||||||
int plantProbability = 20;
|
int plantProbability = 20;
|
||||||
Material plantGrowOn = Material.DIRT;
|
Material plantGrowOn = Material.DIRT;
|
||||||
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
||||||
verify(addon).log(eq(" 20.0% chance for Jungle Sapling to grow on Dirt"));
|
verify(addon).log(" 20.0% chance for Jungle Sapling to grow on Dirt");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addPlants(org.bukkit.Material, int, org.bukkit.Material)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#addPlants(org.bukkit.Material, double, org.bukkit.Material)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddPlantsOver100Percent() {
|
public void testAddPlantsOver100Percent() {
|
||||||
@ -218,7 +215,7 @@ public class BiomeRecipeTest {
|
|||||||
Material plantGrowOn = Material.DIRT;
|
Material plantGrowOn = Material.DIRT;
|
||||||
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
||||||
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
br.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
||||||
verify(addon).logError(eq("Plant chances add up to > 100% in BADLANDS biome recipe! Skipping JUNGLE_SAPLING"));
|
verify(addon).logError("Plant chances add up to > 100% in BADLANDS biome recipe! Skipping JUNGLE_SAPLING");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,7 +226,7 @@ public class BiomeRecipeTest {
|
|||||||
Material blockMaterial = Material.BLACK_CONCRETE;
|
Material blockMaterial = Material.BLACK_CONCRETE;
|
||||||
int blockQty = 30;
|
int blockQty = 30;
|
||||||
br.addReqBlocks(blockMaterial, blockQty);
|
br.addReqBlocks(blockMaterial, blockQty);
|
||||||
verify(addon).log(eq(" BLACK_CONCRETE x 30"));
|
verify(addon).log(" BLACK_CONCRETE x 30");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -237,8 +234,8 @@ public class BiomeRecipeTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCheckRecipe() {
|
public void testCheckRecipe() {
|
||||||
Set<GreenhouseResult> result = br.checkRecipe(gh);
|
br.checkRecipe(gh).thenAccept(result ->
|
||||||
assertTrue(result.isEmpty());
|
assertTrue(result.isEmpty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -247,8 +244,8 @@ public class BiomeRecipeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCheckRecipeNotEnough() {
|
public void testCheckRecipeNotEnough() {
|
||||||
br.addReqBlocks(Material.ACACIA_LEAVES, 3);
|
br.addReqBlocks(Material.ACACIA_LEAVES, 3);
|
||||||
Set<GreenhouseResult> result = br.checkRecipe(gh);
|
br.checkRecipe(gh).thenAccept(result ->
|
||||||
assertFalse(result.isEmpty());
|
assertFalse(result.isEmpty()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,29 +262,10 @@ public class BiomeRecipeTest {
|
|||||||
Block ab = mock(Block.class);
|
Block ab = mock(Block.class);
|
||||||
when(ab.getType()).thenReturn(Material.WATER);
|
when(ab.getType()).thenReturn(Material.WATER);
|
||||||
when(b.getRelative(any())).thenReturn(ab);
|
when(b.getRelative(any())).thenReturn(ab);
|
||||||
br.convertBlock(gh, b);
|
br.convertBlock(b);
|
||||||
verify(b).setType(Material.CLAY);
|
verify(b).setType(Material.CLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#convertBlock(org.bukkit.block.Block)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testConvertBlockNotInGreenhouse() {
|
|
||||||
// Setup
|
|
||||||
this.testAddConvBlocks();
|
|
||||||
// Mock
|
|
||||||
Block b = mock(Block.class);
|
|
||||||
when(b.getType()).thenReturn(Material.SAND);
|
|
||||||
Block ab = mock(Block.class);
|
|
||||||
when(ab.getType()).thenReturn(Material.WATER);
|
|
||||||
when(b.getRelative(any())).thenReturn(ab);
|
|
||||||
when(ab.getLocation()).thenReturn(location);
|
|
||||||
when(gh.contains(any())).thenReturn(false);
|
|
||||||
br.convertBlock(gh, b);
|
|
||||||
verify(b, never()).setType(any());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#convertBlock(org.bukkit.block.Block)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#convertBlock(org.bukkit.block.Block)}.
|
||||||
*/
|
*/
|
||||||
@ -301,7 +279,7 @@ public class BiomeRecipeTest {
|
|||||||
Block ab = mock(Block.class);
|
Block ab = mock(Block.class);
|
||||||
when(ab.getType()).thenReturn(Material.SAND);
|
when(ab.getType()).thenReturn(Material.SAND);
|
||||||
when(b.getRelative(any())).thenReturn(ab);
|
when(b.getRelative(any())).thenReturn(ab);
|
||||||
br.convertBlock(gh, b);
|
br.convertBlock(b);
|
||||||
verify(b, never()).setType(Material.CLAY);
|
verify(b, never()).setType(Material.CLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,10 +291,30 @@ public class BiomeRecipeTest {
|
|||||||
// Mock
|
// Mock
|
||||||
Block b = mock(Block.class);
|
Block b = mock(Block.class);
|
||||||
when(b.getType()).thenReturn(Material.SAND);
|
when(b.getType()).thenReturn(Material.SAND);
|
||||||
br.convertBlock(gh, b);
|
br.convertBlock(b);
|
||||||
verify(b, never()).setType(Material.CLAY);
|
verify(b, never()).setType(Material.CLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#convertBlock(org.bukkit.block.Block)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvertBlockNoLocalBlock() {
|
||||||
|
// Setup
|
||||||
|
Material oldMaterial = Material.SAND;
|
||||||
|
Material newMaterial = Material.CLAY;
|
||||||
|
double convChance = 100D;
|
||||||
|
br.addConvBlocks(oldMaterial, newMaterial, convChance, null);
|
||||||
|
|
||||||
|
// Mock
|
||||||
|
Block b = mock(Block.class);
|
||||||
|
when(b.getType()).thenReturn(Material.SAND);
|
||||||
|
br.convertBlock(b);
|
||||||
|
|
||||||
|
verify(b, never()).getRelative(any());
|
||||||
|
verify(b).setType(Material.CLAY);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#convertBlock(org.bukkit.block.Block)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#convertBlock(org.bukkit.block.Block)}.
|
||||||
*/
|
*/
|
||||||
@ -335,7 +333,7 @@ public class BiomeRecipeTest {
|
|||||||
Block ab = mock(Block.class);
|
Block ab = mock(Block.class);
|
||||||
when(ab.getType()).thenReturn(Material.WATER);
|
when(ab.getType()).thenReturn(Material.WATER);
|
||||||
when(b.getRelative(any())).thenReturn(ab);
|
when(b.getRelative(any())).thenReturn(ab);
|
||||||
br.convertBlock(gh, b);
|
br.convertBlock(b);
|
||||||
verify(b, never()).setType(Material.CLAY);
|
verify(b, never()).setType(Material.CLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,12 +435,12 @@ public class BiomeRecipeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSpawnMobOutsideWall() {
|
public void testSpawnMobOutsideWall() {
|
||||||
when(block.getY()).thenReturn(10);
|
when(block.getY()).thenReturn(10);
|
||||||
when(block.getType()).thenReturn(Material.GRASS_PATH);
|
when(block.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
when(block.getRelative(any())).thenReturn(block);
|
||||||
|
|
||||||
EntityType mobType = EntityType.CAT;
|
EntityType mobType = EntityType.CAT;
|
||||||
int mobProbability = 100;
|
int mobProbability = 100;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
|
|
||||||
Entity cat = mock(Cat.class);
|
Entity cat = mock(Cat.class);
|
||||||
// Same box as greenhouse
|
// Same box as greenhouse
|
||||||
@ -453,7 +451,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertFalse(br.spawnMob(block));
|
assertFalse(br.spawnMob(block));
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.CAT));
|
verify(world).spawnEntity(location, EntityType.CAT);
|
||||||
verify(location).add(any(Vector.class));
|
verify(location).add(any(Vector.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,12 +461,12 @@ public class BiomeRecipeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSpawnMob() {
|
public void testSpawnMob() {
|
||||||
when(block.getY()).thenReturn(10);
|
when(block.getY()).thenReturn(10);
|
||||||
when(block.getType()).thenReturn(Material.GRASS_PATH);
|
when(block.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
when(block.getRelative(any())).thenReturn(block);
|
||||||
|
|
||||||
EntityType mobType = EntityType.CAT;
|
EntityType mobType = EntityType.CAT;
|
||||||
int mobProbability = 100;
|
int mobProbability = 100;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
|
|
||||||
Entity cat = mock(Cat.class);
|
Entity cat = mock(Cat.class);
|
||||||
// Exactly 1 block smaller than the greenhouse blocks
|
// Exactly 1 block smaller than the greenhouse blocks
|
||||||
@ -479,7 +477,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
assertTrue(br.spawnMob(block));
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.CAT));
|
verify(world).spawnEntity(location, EntityType.CAT);
|
||||||
verify(location).add(any(Vector.class));
|
verify(location).add(any(Vector.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,12 +487,12 @@ public class BiomeRecipeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSpawnMobHoglin() {
|
public void testSpawnMobHoglin() {
|
||||||
when(block.getY()).thenReturn(10);
|
when(block.getY()).thenReturn(10);
|
||||||
when(block.getType()).thenReturn(Material.GRASS_PATH);
|
when(block.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
when(block.getRelative(any())).thenReturn(block);
|
||||||
|
|
||||||
EntityType mobType = EntityType.HOGLIN;
|
EntityType mobType = EntityType.HOGLIN;
|
||||||
int mobProbability = 100;
|
int mobProbability = 100;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
|
|
||||||
Hoglin hoglin = mock(Hoglin.class);
|
Hoglin hoglin = mock(Hoglin.class);
|
||||||
// Exactly 1 block smaller than the greenhouse blocks
|
// Exactly 1 block smaller than the greenhouse blocks
|
||||||
@ -506,7 +504,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
assertTrue(br.spawnMob(block));
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.HOGLIN));
|
verify(world).spawnEntity(location, EntityType.HOGLIN);
|
||||||
verify(location).add(any(Vector.class));
|
verify(location).add(any(Vector.class));
|
||||||
verify(hoglin).setImmuneToZombification(true);
|
verify(hoglin).setImmuneToZombification(true);
|
||||||
}
|
}
|
||||||
@ -517,12 +515,12 @@ public class BiomeRecipeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSpawnMobPiglin() {
|
public void testSpawnMobPiglin() {
|
||||||
when(block.getY()).thenReturn(10);
|
when(block.getY()).thenReturn(10);
|
||||||
when(block.getType()).thenReturn(Material.GRASS_PATH);
|
when(block.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
when(block.getRelative(any())).thenReturn(block);
|
||||||
|
|
||||||
EntityType mobType = EntityType.PIGLIN;
|
EntityType mobType = EntityType.PIGLIN;
|
||||||
int mobProbability = 100;
|
int mobProbability = 100;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
|
|
||||||
Piglin piglin = mock(Piglin.class);
|
Piglin piglin = mock(Piglin.class);
|
||||||
// Exactly 1 block smaller than the greenhouse blocks
|
// Exactly 1 block smaller than the greenhouse blocks
|
||||||
@ -534,7 +532,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
assertTrue(br.spawnMob(block));
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.PIGLIN));
|
verify(world).spawnEntity(location, EntityType.PIGLIN);
|
||||||
verify(location).add(any(Vector.class));
|
verify(location).add(any(Vector.class));
|
||||||
verify(piglin).setImmuneToZombification(true);
|
verify(piglin).setImmuneToZombification(true);
|
||||||
}
|
}
|
||||||
@ -547,12 +545,12 @@ public class BiomeRecipeTest {
|
|||||||
when(world.getEnvironment()).thenReturn(Environment.NETHER);
|
when(world.getEnvironment()).thenReturn(Environment.NETHER);
|
||||||
|
|
||||||
when(block.getY()).thenReturn(10);
|
when(block.getY()).thenReturn(10);
|
||||||
when(block.getType()).thenReturn(Material.GRASS_PATH);
|
when(block.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
when(block.getRelative(any())).thenReturn(block);
|
||||||
|
|
||||||
EntityType mobType = EntityType.PIGLIN;
|
EntityType mobType = EntityType.PIGLIN;
|
||||||
int mobProbability = 100;
|
int mobProbability = 100;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
|
|
||||||
Piglin piglin = mock(Piglin.class);
|
Piglin piglin = mock(Piglin.class);
|
||||||
// Exactly 1 block smaller than the greenhouse blocks
|
// Exactly 1 block smaller than the greenhouse blocks
|
||||||
@ -564,7 +562,7 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertTrue(br.spawnMob(block));
|
assertTrue(br.spawnMob(block));
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.PIGLIN));
|
verify(world).spawnEntity(location, EntityType.PIGLIN);
|
||||||
verify(location).add(any(Vector.class));
|
verify(location).add(any(Vector.class));
|
||||||
verify(piglin, never()).setImmuneToZombification(true);
|
verify(piglin, never()).setImmuneToZombification(true);
|
||||||
}
|
}
|
||||||
@ -575,12 +573,12 @@ public class BiomeRecipeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSpawnMobWrongSurface() {
|
public void testSpawnMobWrongSurface() {
|
||||||
when(block.getY()).thenReturn(10);
|
when(block.getY()).thenReturn(10);
|
||||||
when(block.getType()).thenReturn(Material.GRASS_BLOCK);
|
when(block.getType()).thenReturn(Material.STONE);
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
when(block.getRelative(any())).thenReturn(block);
|
||||||
|
|
||||||
EntityType mobType = EntityType.CAT;
|
EntityType mobType = EntityType.CAT;
|
||||||
int mobProbability = 100;
|
int mobProbability = 100;
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
Material mobSpawnOn = Material.GRASS_BLOCK;
|
||||||
|
|
||||||
Entity cat = mock(Cat.class);
|
Entity cat = mock(Cat.class);
|
||||||
when(world.spawnEntity(any(), any())).thenReturn(cat);
|
when(world.spawnEntity(any(), any())).thenReturn(cat);
|
||||||
@ -588,28 +586,9 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||||
assertFalse(br.spawnMob(block));
|
assertFalse(br.spawnMob(block));
|
||||||
verify(world, never()).spawnEntity(eq(location), eq(EntityType.CAT));
|
verify(world, never()).spawnEntity(location, EntityType.CAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#spawnMob(org.bukkit.block.Block)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSpawnMobFailToSpawn() {
|
|
||||||
when(block.getY()).thenReturn(10);
|
|
||||||
when(block.getType()).thenReturn(Material.GRASS_PATH);
|
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
|
||||||
|
|
||||||
EntityType mobType = EntityType.CAT;
|
|
||||||
int mobProbability = 100;
|
|
||||||
Material mobSpawnOn = Material.GRASS_PATH;
|
|
||||||
|
|
||||||
br.addMobs(mobType, mobProbability, mobSpawnOn);
|
|
||||||
assertFalse(br.spawnMob(block));
|
|
||||||
verify(world).spawnEntity(eq(location), eq(EntityType.CAT));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#getRecipeBlocks()}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#getRecipeBlocks()}.
|
||||||
*/
|
*/
|
||||||
@ -632,7 +611,7 @@ public class BiomeRecipeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGrowPlantNotAir() {
|
public void testGrowPlantNotAir() {
|
||||||
when(block.getType()).thenReturn(Material.SOUL_SAND);
|
when(block.getType()).thenReturn(Material.SOUL_SAND);
|
||||||
assertFalse(br.growPlant(block));
|
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -642,7 +621,7 @@ public class BiomeRecipeTest {
|
|||||||
public void testGrowPlantNoPlants() {
|
public void testGrowPlantNoPlants() {
|
||||||
when(block.getType()).thenReturn(Material.AIR);
|
when(block.getType()).thenReturn(Material.AIR);
|
||||||
when(block.isEmpty()).thenReturn(true);
|
when(block.isEmpty()).thenReturn(true);
|
||||||
assertFalse(br.growPlant(block));
|
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -654,7 +633,7 @@ public class BiomeRecipeTest {
|
|||||||
when(block.getType()).thenReturn(Material.AIR);
|
when(block.getType()).thenReturn(Material.AIR);
|
||||||
when(block.isEmpty()).thenReturn(true);
|
when(block.isEmpty()).thenReturn(true);
|
||||||
assertTrue(br.addPlants(Material.BAMBOO_SAPLING, 100, Material.GRASS_BLOCK));
|
assertTrue(br.addPlants(Material.BAMBOO_SAPLING, 100, Material.GRASS_BLOCK));
|
||||||
assertFalse(br.growPlant(block));
|
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -670,11 +649,46 @@ public class BiomeRecipeTest {
|
|||||||
|
|
||||||
when(block.getRelative(any())).thenReturn(ob);
|
when(block.getRelative(any())).thenReturn(ob);
|
||||||
assertTrue(br.addPlants(Material.BAMBOO_SAPLING, 100, Material.GRASS_BLOCK));
|
assertTrue(br.addPlants(Material.BAMBOO_SAPLING, 100, Material.GRASS_BLOCK));
|
||||||
assertTrue(br.growPlant(block));
|
assertTrue(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
||||||
verify(block).setBlockData(eq(bd), eq(false));
|
verify(block).setBlockData(eq(bd), eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#growPlant(org.bukkit.block.Block)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGrowPlantCeilingPlants() {
|
||||||
|
when(block.getY()).thenReturn(10);
|
||||||
|
when(block.getType()).thenReturn(Material.AIR);
|
||||||
|
when(block.isEmpty()).thenReturn(true);
|
||||||
|
Block ob = mock(Block.class);
|
||||||
|
when(ob.getType()).thenReturn(Material.GLASS);
|
||||||
|
|
||||||
|
when(block.getRelative(any())).thenReturn(ob);
|
||||||
|
assertTrue(br.addPlants(Material.SPORE_BLOSSOM, 100, Material.GLASS));
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#growPlant(org.bukkit.block.Block)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGrowPlantCeilingPlantsFail() {
|
||||||
|
when(block.getY()).thenReturn(10);
|
||||||
|
when(block.getType()).thenReturn(Material.AIR);
|
||||||
|
when(block.isEmpty()).thenReturn(true);
|
||||||
|
Block ob = mock(Block.class);
|
||||||
|
when(ob.getType()).thenReturn(Material.GLASS);
|
||||||
|
|
||||||
|
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), false));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#growPlant(org.bukkit.block.Block)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.BiomeRecipe#growPlant(org.bukkit.block.Block)}.
|
||||||
*/
|
*/
|
||||||
@ -687,13 +701,13 @@ public class BiomeRecipeTest {
|
|||||||
when(block.isEmpty()).thenReturn(true);
|
when(block.isEmpty()).thenReturn(true);
|
||||||
Block ob = mock(Block.class);
|
Block ob = mock(Block.class);
|
||||||
when(ob.getType()).thenReturn(Material.GRASS_BLOCK);
|
when(ob.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(eq(BlockFace.DOWN))).thenReturn(ob);
|
when(block.getRelative(BlockFace.DOWN)).thenReturn(ob);
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(block);
|
when(block.getRelative(BlockFace.UP)).thenReturn(block);
|
||||||
assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
||||||
assertTrue(br.growPlant(block));
|
assertTrue(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
verify(world).spawnParticle(eq(Particle.SNOWBALL), any(Location.class), anyInt(), anyDouble(), anyDouble(), anyDouble());
|
||||||
verify(bisected).setHalf(eq(Half.BOTTOM));
|
verify(bisected).setHalf(Half.BOTTOM);
|
||||||
verify(bisected).setHalf(eq(Half.TOP));
|
verify(bisected).setHalf(Half.TOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -708,10 +722,10 @@ public class BiomeRecipeTest {
|
|||||||
when(block.isEmpty()).thenReturn(true);
|
when(block.isEmpty()).thenReturn(true);
|
||||||
Block ob = mock(Block.class);
|
Block ob = mock(Block.class);
|
||||||
when(ob.getType()).thenReturn(Material.GRASS_BLOCK);
|
when(ob.getType()).thenReturn(Material.GRASS_BLOCK);
|
||||||
when(block.getRelative(eq(BlockFace.DOWN))).thenReturn(ob);
|
when(block.getRelative(BlockFace.DOWN)).thenReturn(ob);
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(ob);
|
when(block.getRelative(BlockFace.UP)).thenReturn(ob);
|
||||||
assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
assertTrue(br.addPlants(Material.SUNFLOWER, 100, Material.GRASS_BLOCK));
|
||||||
assertFalse(br.growPlant(block));
|
assertFalse(br.growPlant(new GrowthBlock(block, true), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -753,8 +767,8 @@ public class BiomeRecipeTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSetType() {
|
public void testSetType() {
|
||||||
br.setType(Biome.BADLANDS_PLATEAU);
|
br.setType(Biome.BADLANDS);
|
||||||
assertEquals(Biome.BADLANDS_PLATEAU, br.getBiome());
|
assertEquals(Biome.BADLANDS, br.getBiome());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,45 +1,61 @@
|
|||||||
package world.bentobox.greenhouses.greenhouse;
|
package world.bentobox.greenhouses.greenhouse;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.util.Vector;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
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 org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
|
import world.bentobox.greenhouses.Settings;
|
||||||
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@RunWith(PowerMockRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest({Greenhouses.class, Bukkit.class})
|
||||||
public class RoofTest {
|
public class RoofTest {
|
||||||
|
|
||||||
private Roof roof;
|
private Roof roof;
|
||||||
@Mock
|
@Mock
|
||||||
private Block block;
|
|
||||||
@Mock
|
|
||||||
private Location location;
|
private Location location;
|
||||||
@Mock
|
@Mock
|
||||||
private World world;
|
private World world;
|
||||||
|
@Mock
|
||||||
|
private Greenhouses addon;
|
||||||
|
private Settings s;
|
||||||
|
@Mock
|
||||||
|
private AsyncWorldCache cache;
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
|
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
||||||
|
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
||||||
|
s = new Settings();
|
||||||
|
when(addon.getSettings()).thenReturn(s);
|
||||||
|
|
||||||
when(world.getMaxHeight()).thenReturn(255);
|
when(world.getMaxHeight()).thenReturn(255);
|
||||||
// Block
|
// Block
|
||||||
when(block.getType()).thenReturn(Material.AIR, Material.AIR, Material.AIR, Material.AIR,
|
when(cache.getBlockType(any())).thenReturn(Material.AIR, Material.AIR, Material.AIR, Material.AIR,
|
||||||
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
||||||
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
||||||
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
||||||
@ -64,24 +80,22 @@ public class RoofTest {
|
|||||||
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
||||||
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
Material.GLASS, Material.GLASS, Material.GLASS, Material.GLASS,
|
||||||
Material.AIR);
|
Material.AIR);
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
|
||||||
when(world.getBlockAt(any(Location.class))).thenReturn(block);
|
|
||||||
when(location.getWorld()).thenReturn(world);
|
when(location.getWorld()).thenReturn(world);
|
||||||
when(location.getBlockX()).thenReturn(10);
|
when(location.getBlockX()).thenReturn(10);
|
||||||
when(location.getBlockY()).thenReturn(10);
|
when(location.getBlockY()).thenReturn(10);
|
||||||
when(location.getBlockZ()).thenReturn(10);
|
when(location.getBlockZ()).thenReturn(10);
|
||||||
when(location.getBlock()).thenReturn(block);
|
|
||||||
when(location.clone()).thenReturn(location);
|
when(location.clone()).thenReturn(location);
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
roof = new Roof(location);
|
roof = new Roof(cache, location, addon);
|
||||||
|
assertTrue(roof.findRoof(new Vector(10,10,10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoGlass() {
|
public void testNoGlass() {
|
||||||
when(block.getType()).thenReturn(Material.AIR);
|
when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.AIR);
|
||||||
roof = new Roof(location);
|
roof = new Roof(cache, location, addon);
|
||||||
|
assertFalse(roof.findRoof(new Vector(10,10,10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,14 +138,6 @@ public class RoofTest {
|
|||||||
assertEquals(1406, roof.getArea());
|
assertEquals(1406, roof.getArea());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Roof#isRoofFound()}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testIsRoofFound() {
|
|
||||||
assertTrue(roof.isRoofFound());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Roof#getHeight()}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Roof#getHeight()}.
|
||||||
*/
|
*/
|
||||||
@ -153,7 +159,36 @@ public class RoofTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testToString() {
|
public void testToString() {
|
||||||
assertTrue(roof.toString().endsWith("minX=-9, maxX=28, minZ=-9, maxZ=29, height=14, roofFound=true]"));
|
assertEquals("Roof [height=14, roofFound=true, minX=-9, maxX=28, minZ=-9, maxZ=29]", roof.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Roof#roofBlocks(org.bukkit.Material)}.
|
||||||
|
*/
|
||||||
|
@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));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Roof#roofBlocks(org.bukkit.Material)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,45 @@
|
|||||||
package world.bentobox.greenhouses.greenhouse;
|
package world.bentobox.greenhouses.greenhouse;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
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.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.junit.After;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Tag;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
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 org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.greenhouses.Greenhouses;
|
||||||
|
import world.bentobox.greenhouses.Settings;
|
||||||
import world.bentobox.greenhouses.greenhouse.Walls.WallFinder;
|
import world.bentobox.greenhouses.greenhouse.Walls.WallFinder;
|
||||||
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@RunWith(PowerMockRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest({Bukkit.class, Greenhouses.class})
|
||||||
public class WallsTest {
|
public class WallsTest {
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Roof roof;
|
private Roof roof;
|
||||||
@Mock
|
@Mock
|
||||||
private Block block;
|
|
||||||
@Mock
|
|
||||||
private Location location;
|
private Location location;
|
||||||
@Mock
|
@Mock
|
||||||
private World world;
|
private World world;
|
||||||
@ -41,35 +47,40 @@ public class WallsTest {
|
|||||||
* Class under test
|
* Class under test
|
||||||
*/
|
*/
|
||||||
private Walls walls;
|
private Walls walls;
|
||||||
|
@Mock
|
||||||
|
private Greenhouses addon;
|
||||||
|
private Settings s;
|
||||||
|
@Mock
|
||||||
|
private BentoBox plugin;
|
||||||
|
@Mock
|
||||||
|
private AsyncWorldCache cache;
|
||||||
|
|
||||||
|
private CompletableFuture<Walls> r;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
walls = new Walls();
|
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
||||||
|
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
||||||
|
// Declare mock after mocking Bukkit
|
||||||
|
roof = mock(Roof.class);
|
||||||
|
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(world.getMaxHeight()).thenReturn(255);
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
|
||||||
when(world.getBlockAt(any(Location.class))).thenReturn(block);
|
|
||||||
when(location.getWorld()).thenReturn(world);
|
when(location.getWorld()).thenReturn(world);
|
||||||
when(location.getBlockX()).thenReturn(10);
|
when(location.getBlockX()).thenReturn(10);
|
||||||
when(location.getBlockY()).thenReturn(10);
|
when(location.getBlockY()).thenReturn(10);
|
||||||
when(location.getBlockZ()).thenReturn(10);
|
when(location.getBlockZ()).thenReturn(10);
|
||||||
when(location.getBlock()).thenReturn(block);
|
|
||||||
when(location.clone()).thenReturn(location);
|
when(location.clone()).thenReturn(location);
|
||||||
when(block.getRelative(any())).thenReturn(block);
|
when(cache.getBlockType(any())).thenReturn(Material.GLASS);
|
||||||
when(block.getType()).thenReturn(Material.GLASS);
|
when(cache.getBlockType(anyInt(),anyInt(),anyInt())).thenReturn(Material.GLASS);
|
||||||
when(roof.getHeight()).thenReturn(1);
|
when(roof.getHeight()).thenReturn(1);
|
||||||
when(roof.getLocation()).thenReturn(location);
|
when(roof.getLocation()).thenReturn(location);
|
||||||
|
|
||||||
}
|
r = new CompletableFuture<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +88,7 @@ public class WallsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testFindWalls() {
|
public void testFindWalls() {
|
||||||
walls.findWalls(roof);
|
walls.findWalls(r, roof);
|
||||||
assertEquals("Walls [minX=-2, maxX=11, minZ=-2, maxZ=11, floor=0]", walls.toString());
|
assertEquals("Walls [minX=-2, maxX=11, minZ=-2, maxZ=11, floor=0]", walls.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +97,7 @@ public class WallsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testLookAround() {
|
public void testLookAround() {
|
||||||
WallFinder wf = walls.new WallFinder();
|
WallFinder wf = new WallFinder();
|
||||||
walls.lookAround(location, wf, roof);
|
walls.lookAround(location, wf, roof);
|
||||||
assertTrue(wf.stopMaxX);
|
assertTrue(wf.stopMaxX);
|
||||||
assertTrue(wf.stopMaxZ);
|
assertTrue(wf.stopMaxZ);
|
||||||
@ -103,7 +114,7 @@ public class WallsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAnalyzeFindings() {
|
public void testAnalyzeFindings() {
|
||||||
WallFinder wf = walls.new WallFinder();
|
WallFinder wf = new WallFinder();
|
||||||
walls.analyzeFindings(wf, roof);
|
walls.analyzeFindings(wf, roof);
|
||||||
assertFalse(wf.stopMaxX);
|
assertFalse(wf.stopMaxX);
|
||||||
assertFalse(wf.stopMaxZ);
|
assertFalse(wf.stopMaxZ);
|
||||||
@ -124,7 +135,7 @@ public class WallsTest {
|
|||||||
walls.maxX = 1;
|
walls.maxX = 1;
|
||||||
walls.minZ = -1;
|
walls.minZ = -1;
|
||||||
walls.maxZ = 1;
|
walls.maxZ = 1;
|
||||||
WallFinder wf = walls.new WallFinder();
|
WallFinder wf = new WallFinder();
|
||||||
walls.analyzeFindings(wf, roof);
|
walls.analyzeFindings(wf, roof);
|
||||||
assertTrue(wf.stopMaxX);
|
assertTrue(wf.stopMaxX);
|
||||||
assertTrue(wf.stopMaxZ);
|
assertTrue(wf.stopMaxZ);
|
||||||
@ -137,12 +148,12 @@ public class WallsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#lookAtBlockFaces(world.bentobox.greenhouses.greenhouse.Walls.WallFinder, org.bukkit.World, int, int, int)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#lookAtBlockFaces(WallFinder, int, int, int)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testLookAtBlockFaces() {
|
public void testLookAtBlockFaces() {
|
||||||
WallFinder wf = walls.new WallFinder();
|
WallFinder wf = new WallFinder();
|
||||||
walls.lookAtBlockFaces(wf, world, 0, 5, -1);
|
walls.lookAtBlockFaces(wf, 0, 5, -1);
|
||||||
assertTrue(wf.stopMaxX);
|
assertTrue(wf.stopMaxX);
|
||||||
assertTrue(wf.stopMaxZ);
|
assertTrue(wf.stopMaxZ);
|
||||||
assertTrue(wf.stopMinX);
|
assertTrue(wf.stopMinX);
|
||||||
@ -150,13 +161,13 @@ public class WallsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#lookAtBlockFaces(world.bentobox.greenhouses.greenhouse.Walls.WallFinder, org.bukkit.World, int, int, int)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#lookAtBlockFaces(WallFinder, int, int, int)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testLookAtBlockFacesNoGlass() {
|
public void testLookAtBlockFacesNoGlass() {
|
||||||
when(block.getType()).thenReturn(Material.AIR);
|
when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.AIR);
|
||||||
WallFinder wf = walls.new WallFinder();
|
WallFinder wf = new WallFinder();
|
||||||
walls.lookAtBlockFaces(wf, world, 0, 5, -1);
|
walls.lookAtBlockFaces(wf, 0, 5, -1);
|
||||||
assertFalse(wf.stopMaxX);
|
assertFalse(wf.stopMaxX);
|
||||||
assertFalse(wf.stopMaxZ);
|
assertFalse(wf.stopMaxZ);
|
||||||
assertFalse(wf.stopMinX);
|
assertFalse(wf.stopMinX);
|
||||||
@ -164,23 +175,23 @@ public class WallsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(org.bukkit.World, int, int, int, int, int)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(int, int, int, int, int, int)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetFloorYZeroY() {
|
public void testGetFloorYZeroY() {
|
||||||
assertEquals(0, walls.getFloorY(world, 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(org.bukkit.World, int, int, int, int, int)}.
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(int, int, int, int, int, int)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetFloorY() {
|
public void testGetFloorY() {
|
||||||
when(block.getType()).thenReturn(Material.GLASS, Material.GLASS,
|
when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.GLASS, Material.GLASS,
|
||||||
Material.GLASS, Material.GLASS,
|
Material.GLASS, Material.GLASS,
|
||||||
Material.GLASS, Material.GLASS,
|
Material.GLASS, Material.GLASS,
|
||||||
Material.AIR);
|
Material.AIR);
|
||||||
assertEquals(8, walls.getFloorY(world, 10, 0, 1, 0, 1));
|
assertEquals(8, walls.getFloorY(10, 0, 1, 0, 1, -64));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,12 +199,29 @@ public class WallsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWallBlocks() {
|
public void testWallBlocks() {
|
||||||
assertFalse(Walls.wallBlocks(Material.ACACIA_BOAT));
|
assertFalse(addon.wallBlocks(Material.ACACIA_BOAT));
|
||||||
assertTrue(Walls.wallBlocks(Material.GLASS));
|
assertTrue(addon.wallBlocks(Material.GLASS));
|
||||||
assertTrue(Walls.wallBlocks(Material.ACACIA_DOOR));
|
assertTrue(addon.wallBlocks(Material.GLOWSTONE));
|
||||||
assertTrue(Walls.wallBlocks(Material.HOPPER));
|
assertTrue(addon.wallBlocks(Material.ACACIA_DOOR));
|
||||||
assertTrue(Walls.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
assertTrue(addon.wallBlocks(Material.HOPPER));
|
||||||
assertFalse(Walls.wallBlocks(Material.BIRCH_TRAPDOOR));
|
assertTrue(addon.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE));
|
||||||
|
assertFalse(addon.wallBlocks(Material.BIRCH_TRAPDOOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#wallBlocks(org.bukkit.Material)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWallBlocksNoGlowStoneNoPanes() {
|
||||||
|
s.setAllowGlowstone(false);
|
||||||
|
s.setAllowPanes(false);
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package world.bentobox.greenhouses.listeners;
|
package world.bentobox.greenhouses.listeners;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
@ -10,33 +9,27 @@ import static org.mockito.Mockito.never;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.BlockState;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Event.Result;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.BoundingBox;
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -83,12 +76,13 @@ public class GreenhouseEventsTest {
|
|||||||
private Greenhouse gh1;
|
private Greenhouse gh1;
|
||||||
@Mock
|
@Mock
|
||||||
private Greenhouse gh2;
|
private Greenhouse gh2;
|
||||||
|
@Mock
|
||||||
|
private PlayerInventory inv;
|
||||||
|
@Mock
|
||||||
|
private ItemStack waterBucket;
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
PowerMockito.mockStatic(User.class);
|
PowerMockito.mockStatic(User.class);
|
||||||
when(User.getInstance(any(Player.class))).thenReturn(user);
|
when(User.getInstance(any(Player.class))).thenReturn(user);
|
||||||
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
||||||
@ -101,8 +95,10 @@ public class GreenhouseEventsTest {
|
|||||||
when(map.getGreenhouse(eq(location2))).thenReturn(Optional.of(gh2));
|
when(map.getGreenhouse(eq(location2))).thenReturn(Optional.of(gh2));
|
||||||
BiomeRecipe br = new BiomeRecipe();
|
BiomeRecipe br = new BiomeRecipe();
|
||||||
br.setFriendlyName("recipe1");
|
br.setFriendlyName("recipe1");
|
||||||
|
br.setType(Biome.PLAINS);
|
||||||
BiomeRecipe br2 = new BiomeRecipe();
|
BiomeRecipe br2 = new BiomeRecipe();
|
||||||
br2.setFriendlyName("recipe2");
|
br2.setFriendlyName("recipe2");
|
||||||
|
br2.setType(Biome.NETHER_WASTES);
|
||||||
// Names
|
// Names
|
||||||
when(gh1.getBiomeRecipe()).thenReturn(br);
|
when(gh1.getBiomeRecipe()).thenReturn(br);
|
||||||
when(gh2.getBiomeRecipe()).thenReturn(br2);
|
when(gh2.getBiomeRecipe()).thenReturn(br2);
|
||||||
@ -110,6 +106,9 @@ public class GreenhouseEventsTest {
|
|||||||
|
|
||||||
when(player.getWorld()).thenReturn(world);
|
when(player.getWorld()).thenReturn(world);
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NETHER);
|
when(world.getEnvironment()).thenReturn(Environment.NETHER);
|
||||||
|
when(player.getInventory()).thenReturn(inv);
|
||||||
|
when(inv.getItemInMainHand()).thenReturn(waterBucket);
|
||||||
|
|
||||||
// Location
|
// Location
|
||||||
when(location.getBlockX()).thenReturn(5);
|
when(location.getBlockX()).thenReturn(5);
|
||||||
when(location.getBlockY()).thenReturn(15);
|
when(location.getBlockY()).thenReturn(15);
|
||||||
@ -128,32 +127,57 @@ public class GreenhouseEventsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws java.lang.Exception
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(PlayerBucketEmptyEvent)}.
|
||||||
*/
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(org.bukkit.event.player.PlayerInteractEvent)}.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOnPlayerInteractInNether() {
|
public void testOnPlayerInteractInNetherInGreenhouse() {
|
||||||
Block clickedBlock = mock(Block.class);
|
Block clickedBlock = mock(Block.class);
|
||||||
when(clickedBlock.getLocation()).thenReturn(location);
|
when(clickedBlock.getLocation()).thenReturn(location);
|
||||||
Block nextBlock = mock(Block.class);
|
Block nextBlock = mock(Block.class);
|
||||||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||||
|
when(nextBlock.getLocation()).thenReturn(location);
|
||||||
ItemStack item = mock(ItemStack.class);
|
ItemStack item = mock(ItemStack.class);
|
||||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||||
PlayerInteractEvent e = new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST, EquipmentSlot.HAND);
|
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||||
ghe.onPlayerInteractInNether(e);
|
ghe.onPlayerInteractInNether(e);
|
||||||
assertEquals(Result.DENY, e.useItemInHand());
|
|
||||||
verify(nextBlock).setType(Material.WATER);
|
verify(nextBlock).setType(Material.WATER);
|
||||||
verify(item).setType(Material.BUCKET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(org.bukkit.event.player.PlayerInteractEvent)}.
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(PlayerBucketEmptyEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnPlayerInteractInNetherOutsideOfGreenhouse() {
|
||||||
|
Block clickedBlock = mock(Block.class);
|
||||||
|
when(clickedBlock.getLocation()).thenReturn(location);
|
||||||
|
Block nextBlock = mock(Block.class);
|
||||||
|
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||||
|
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, EquipmentSlot.HAND);
|
||||||
|
ghe.onPlayerInteractInNether(e);
|
||||||
|
verify(nextBlock, never()).setType(Material.WATER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(PlayerBucketEmptyEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnPlayerInteractInNetherGreenhouse() {
|
||||||
|
Block clickedBlock = mock(Block.class);
|
||||||
|
when(clickedBlock.getLocation()).thenReturn(location2);
|
||||||
|
Block nextBlock = mock(Block.class);
|
||||||
|
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, EquipmentSlot.HAND);
|
||||||
|
ghe.onPlayerInteractInNether(e);
|
||||||
|
verify(nextBlock, never()).setType(Material.WATER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(PlayerBucketEmptyEvent)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOnPlayerInteractInNetherNotInNether() {
|
public void testOnPlayerInteractInNetherNotInNether() {
|
||||||
@ -162,17 +186,17 @@ public class GreenhouseEventsTest {
|
|||||||
when(clickedBlock.getLocation()).thenReturn(location);
|
when(clickedBlock.getLocation()).thenReturn(location);
|
||||||
Block nextBlock = mock(Block.class);
|
Block nextBlock = mock(Block.class);
|
||||||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||||
|
when(clickedBlock.getWorld()).thenReturn(world);
|
||||||
|
when(nextBlock.getWorld()).thenReturn(world);
|
||||||
ItemStack item = mock(ItemStack.class);
|
ItemStack item = mock(ItemStack.class);
|
||||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||||
PlayerInteractEvent e = new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST, EquipmentSlot.HAND);
|
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||||
ghe.onPlayerInteractInNether(e);
|
ghe.onPlayerInteractInNether(e);
|
||||||
assertEquals(Result.DEFAULT, e.useItemInHand());
|
|
||||||
verify(nextBlock, never()).setType(Material.WATER);
|
verify(nextBlock, never()).setType(Material.WATER);
|
||||||
verify(item, never()).setType(Material.BUCKET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(org.bukkit.event.player.PlayerInteractEvent)}.
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(PlayerBucketEmptyEvent)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOnPlayerInteractInNetherNotWaterBucket() {
|
public void testOnPlayerInteractInNetherNotWaterBucket() {
|
||||||
@ -182,66 +206,26 @@ public class GreenhouseEventsTest {
|
|||||||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||||
ItemStack item = mock(ItemStack.class);
|
ItemStack item = mock(ItemStack.class);
|
||||||
when(item.getType()).thenReturn(Material.ACACIA_BOAT);
|
when(item.getType()).thenReturn(Material.ACACIA_BOAT);
|
||||||
PlayerInteractEvent e = new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST, EquipmentSlot.HAND);
|
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER, item, EquipmentSlot.HAND);
|
||||||
ghe.onPlayerInteractInNether(e);
|
ghe.onPlayerInteractInNether(e);
|
||||||
assertEquals(Result.DEFAULT, e.useItemInHand());
|
|
||||||
verify(nextBlock, never()).setType(Material.WATER);
|
verify(nextBlock, never()).setType(Material.WATER);
|
||||||
verify(item, never()).setType(Material.BUCKET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(org.bukkit.event.player.PlayerInteractEvent)}.
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(PlayerBucketEmptyEvent)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOnPlayerInteractInNetherNotInGreenhouse() {
|
public void testOnPlayerInteractInNetherNotInGreenhouse() {
|
||||||
when(map.inGreenhouse(any())).thenReturn(false);
|
when(map.getGreenhouse(eq(location))).thenReturn(Optional.empty());
|
||||||
Block clickedBlock = mock(Block.class);
|
Block clickedBlock = mock(Block.class);
|
||||||
when(clickedBlock.getLocation()).thenReturn(location);
|
when(clickedBlock.getLocation()).thenReturn(location);
|
||||||
Block nextBlock = mock(Block.class);
|
Block nextBlock = mock(Block.class);
|
||||||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
||||||
ItemStack item = mock(ItemStack.class);
|
ItemStack item = mock(ItemStack.class);
|
||||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
||||||
PlayerInteractEvent e = new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST, EquipmentSlot.HAND);
|
PlayerBucketEmptyEvent e = new PlayerBucketEmptyEvent(player, nextBlock, clickedBlock, BlockFace.UP, Material.WATER_BUCKET, item, EquipmentSlot.HAND);
|
||||||
ghe.onPlayerInteractInNether(e);
|
ghe.onPlayerInteractInNether(e);
|
||||||
assertEquals(Result.DEFAULT, e.useItemInHand());
|
|
||||||
verify(nextBlock, never()).setType(Material.WATER);
|
verify(nextBlock, never()).setType(Material.WATER);
|
||||||
verify(item, never()).setType(Material.BUCKET);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(org.bukkit.event.player.PlayerInteractEvent)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testOnPlayerInteractInNetherNullItem() {
|
|
||||||
Block clickedBlock = mock(Block.class);
|
|
||||||
when(clickedBlock.getLocation()).thenReturn(location);
|
|
||||||
Block nextBlock = mock(Block.class);
|
|
||||||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
|
||||||
ItemStack item = mock(ItemStack.class);
|
|
||||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
|
||||||
PlayerInteractEvent e = new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, null, clickedBlock, BlockFace.EAST, EquipmentSlot.HAND);
|
|
||||||
ghe.onPlayerInteractInNether(e);
|
|
||||||
assertEquals(Result.DEFAULT, e.useItemInHand());
|
|
||||||
verify(nextBlock, never()).setType(Material.WATER);
|
|
||||||
verify(item, never()).setType(Material.BUCKET);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerInteractInNether(org.bukkit.event.player.PlayerInteractEvent)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testOnPlayerInteractInNetherNotBlockClick() {
|
|
||||||
Block clickedBlock = mock(Block.class);
|
|
||||||
when(clickedBlock.getLocation()).thenReturn(location);
|
|
||||||
Block nextBlock = mock(Block.class);
|
|
||||||
when(clickedBlock.getRelative(any())).thenReturn(nextBlock);
|
|
||||||
ItemStack item = mock(ItemStack.class);
|
|
||||||
when(item.getType()).thenReturn(Material.WATER_BUCKET);
|
|
||||||
PlayerInteractEvent e = new PlayerInteractEvent(player, Action.RIGHT_CLICK_AIR, item, clickedBlock, BlockFace.EAST, EquipmentSlot.HAND);
|
|
||||||
ghe.onPlayerInteractInNether(e);
|
|
||||||
assertEquals(Result.DEFAULT, e.useItemInHand());
|
|
||||||
verify(nextBlock, never()).setType(Material.WATER);
|
|
||||||
verify(item, never()).setType(Material.BUCKET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,12 +238,30 @@ public class GreenhouseEventsTest {
|
|||||||
Block block = mock(Block.class);
|
Block block = mock(Block.class);
|
||||||
when(block.getType()).thenReturn(Material.ICE);
|
when(block.getType()).thenReturn(Material.ICE);
|
||||||
when(block.getWorld()).thenReturn(world);
|
when(block.getWorld()).thenReturn(world);
|
||||||
|
when(block.getLocation()).thenReturn(location);
|
||||||
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
||||||
ghe.onIceBreak(e);
|
ghe.onIceBreak(e);
|
||||||
verify(block).setType(Material.WATER);
|
verify(block).setType(Material.WATER);
|
||||||
assertTrue(e.isCancelled());
|
assertTrue(e.isCancelled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnIceBreakNetherBiomeGreenhouse() {
|
||||||
|
when(Tag.ICE.isTagged(any(Material.class))).thenReturn(true);
|
||||||
|
|
||||||
|
Block block = mock(Block.class);
|
||||||
|
when(block.getType()).thenReturn(Material.ICE);
|
||||||
|
when(block.getWorld()).thenReturn(world);
|
||||||
|
when(block.getLocation()).thenReturn(location2);
|
||||||
|
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
||||||
|
ghe.onIceBreak(e);
|
||||||
|
verify(block, never()).setType(Material.WATER);
|
||||||
|
assertFalse(e.isCancelled());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
||||||
*/
|
*/
|
||||||
@ -270,6 +272,8 @@ public class GreenhouseEventsTest {
|
|||||||
Block block = mock(Block.class);
|
Block block = mock(Block.class);
|
||||||
when(block.getType()).thenReturn(Material.ACACIA_BOAT);
|
when(block.getType()).thenReturn(Material.ACACIA_BOAT);
|
||||||
when(block.getWorld()).thenReturn(world);
|
when(block.getWorld()).thenReturn(world);
|
||||||
|
// Nether gh
|
||||||
|
when(block.getLocation()).thenReturn(location2);
|
||||||
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
||||||
ghe.onIceBreak(e);
|
ghe.onIceBreak(e);
|
||||||
verify(block, never()).setType(Material.WATER);
|
verify(block, never()).setType(Material.WATER);
|
||||||
@ -280,19 +284,42 @@ public class GreenhouseEventsTest {
|
|||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOnIceBreakNotNether() {
|
public void testOnIceBreakNotNetherNetherGreenhouse() {
|
||||||
when(world.getEnvironment()).thenReturn(Environment.THE_END);
|
when(world.getEnvironment()).thenReturn(Environment.THE_END);
|
||||||
when(Tag.ICE.isTagged(any(Material.class))).thenReturn(true);
|
when(Tag.ICE.isTagged(any(Material.class))).thenReturn(true);
|
||||||
|
|
||||||
Block block = mock(Block.class);
|
Block block = mock(Block.class);
|
||||||
when(block.getType()).thenReturn(Material.ICE);
|
when(block.getType()).thenReturn(Material.ICE);
|
||||||
when(block.getWorld()).thenReturn(world);
|
when(block.getWorld()).thenReturn(world);
|
||||||
|
// Nether gh
|
||||||
|
when(block.getLocation()).thenReturn(location2);
|
||||||
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
||||||
ghe.onIceBreak(e);
|
ghe.onIceBreak(e);
|
||||||
verify(block, never()).setType(Material.WATER);
|
verify(block).setType(Material.AIR);
|
||||||
assertFalse(e.isCancelled());
|
assertTrue(e.isCancelled());
|
||||||
|
verify(world).playSound(any(Location.class), eq(Sound.BLOCK_GLASS_BREAK), eq(1F), eq(1F));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnIceBreakNotNetherNotNetherGreenhouse() {
|
||||||
|
when(world.getEnvironment()).thenReturn(Environment.THE_END);
|
||||||
|
when(Tag.ICE.isTagged(any(Material.class))).thenReturn(true);
|
||||||
|
|
||||||
|
Block block = mock(Block.class);
|
||||||
|
when(block.getType()).thenReturn(Material.ICE);
|
||||||
|
when(block.getWorld()).thenReturn(world);
|
||||||
|
when(block.getLocation()).thenReturn(location);
|
||||||
|
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
||||||
|
ghe.onIceBreak(e);
|
||||||
|
assertFalse(e.isCancelled());
|
||||||
|
verify(block, never()).setType(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onIceBreak(org.bukkit.event.block.BlockBreakEvent)}.
|
||||||
*/
|
*/
|
||||||
@ -304,6 +331,7 @@ public class GreenhouseEventsTest {
|
|||||||
Block block = mock(Block.class);
|
Block block = mock(Block.class);
|
||||||
when(block.getType()).thenReturn(Material.ICE);
|
when(block.getType()).thenReturn(Material.ICE);
|
||||||
when(block.getWorld()).thenReturn(world);
|
when(block.getWorld()).thenReturn(world);
|
||||||
|
|
||||||
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
BlockBreakEvent e = new BlockBreakEvent(block, player);
|
||||||
ghe.onIceBreak(e);
|
ghe.onIceBreak(e);
|
||||||
verify(block, never()).setType(Material.WATER);
|
verify(block, never()).setType(Material.WATER);
|
||||||
@ -389,8 +417,7 @@ public class GreenhouseEventsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOnBlockBreak() {
|
public void testOnBlockBreak() {
|
||||||
BoundingBox bb = BoundingBox.of(location, location2);
|
when(gh1.isRoofOrWallBlock(any())).thenReturn(true);
|
||||||
when(gh1.getBoundingBox()).thenReturn(bb);
|
|
||||||
// Location is a wall block
|
// Location is a wall block
|
||||||
Block block = mock(Block.class);
|
Block block = mock(Block.class);
|
||||||
when(block.getLocation()).thenReturn(location);
|
when(block.getLocation()).thenReturn(location);
|
||||||
@ -400,91 +427,4 @@ public class GreenhouseEventsTest {
|
|||||||
verify(gm).removeGreenhouse(any());
|
verify(gm).removeGreenhouse(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerBlockPlace(org.bukkit.event.block.BlockPlaceEvent)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testOnPlayerBlockPlace() {
|
|
||||||
Block block = mock(Block.class);
|
|
||||||
when(block.getLocation()).thenReturn(location);
|
|
||||||
when(block.getY()).thenReturn(255);
|
|
||||||
when(block.getWorld()).thenReturn(world);
|
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NORMAL);
|
|
||||||
BlockState bs = mock(BlockState.class);
|
|
||||||
Block pa = mock(Block.class);
|
|
||||||
ItemStack item = mock(ItemStack.class);
|
|
||||||
BlockPlaceEvent e = new BlockPlaceEvent(block, bs, pa, item, player, true, EquipmentSlot.HAND);
|
|
||||||
ghe.onPlayerBlockPlace(e);
|
|
||||||
assertTrue(e.isCancelled());
|
|
||||||
verify(user).sendMessage(eq("greenhouses.error.cannot-place"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerBlockPlace(org.bukkit.event.block.BlockPlaceEvent)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testOnPlayerBlockPlaceNether() {
|
|
||||||
Block block = mock(Block.class);
|
|
||||||
when(block.getLocation()).thenReturn(location);
|
|
||||||
when(block.getY()).thenReturn(255);
|
|
||||||
when(block.getWorld()).thenReturn(world);
|
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NETHER);
|
|
||||||
BlockState bs = mock(BlockState.class);
|
|
||||||
Block pa = mock(Block.class);
|
|
||||||
ItemStack item = mock(ItemStack.class);
|
|
||||||
BlockPlaceEvent e = new BlockPlaceEvent(block, bs, pa, item, player, true, EquipmentSlot.HAND);
|
|
||||||
ghe.onPlayerBlockPlace(e);
|
|
||||||
assertFalse(e.isCancelled());
|
|
||||||
verify(user, never()).sendMessage(eq("greenhouses.error.cannot-place"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPlayerBlockPlace(org.bukkit.event.block.BlockPlaceEvent)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testOnPlayerBlockPlaceBelowGH() {
|
|
||||||
Block block = mock(Block.class);
|
|
||||||
when(block.getLocation()).thenReturn(location);
|
|
||||||
when(block.getY()).thenReturn(0);
|
|
||||||
when(block.getWorld()).thenReturn(world);
|
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NORMAL);
|
|
||||||
BlockState bs = mock(BlockState.class);
|
|
||||||
Block pa = mock(Block.class);
|
|
||||||
ItemStack item = mock(ItemStack.class);
|
|
||||||
BlockPlaceEvent e = new BlockPlaceEvent(block, bs, pa, item, player, true, EquipmentSlot.HAND);
|
|
||||||
ghe.onPlayerBlockPlace(e);
|
|
||||||
assertFalse(e.isCancelled());
|
|
||||||
verify(user, never()).sendMessage(eq("greenhouses.error.cannot-place"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPistonPush(org.bukkit.event.block.BlockPistonExtendEvent)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testOnPistonPush() {
|
|
||||||
Block block = mock(Block.class);
|
|
||||||
when(block.getLocation()).thenReturn(location);
|
|
||||||
when(block.getY()).thenReturn(255);
|
|
||||||
when(block.getWorld()).thenReturn(world);
|
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NORMAL);
|
|
||||||
BlockPistonExtendEvent e = new BlockPistonExtendEvent(block, Collections.singletonList(block), BlockFace.EAST);
|
|
||||||
ghe.onPistonPush(e);
|
|
||||||
assertTrue(e.isCancelled());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.listeners.GreenhouseEvents#onPistonPush(org.bukkit.event.block.BlockPistonExtendEvent)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testOnPistonPushUnderGH() {
|
|
||||||
Block block = mock(Block.class);
|
|
||||||
when(block.getLocation()).thenReturn(location);
|
|
||||||
when(block.getY()).thenReturn(0);
|
|
||||||
when(block.getWorld()).thenReturn(world);
|
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NORMAL);
|
|
||||||
BlockPistonExtendEvent e = new BlockPistonExtendEvent(block, Collections.singletonList(block), BlockFace.EAST);
|
|
||||||
ghe.onPistonPush(e);
|
|
||||||
assertFalse(e.isCancelled());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,49 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package world.bentobox.greenhouses.managers;
|
package world.bentobox.greenhouses.managers;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
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.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Keyed;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.util.BoundingBox;
|
import org.bukkit.util.BoundingBox;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.powermock.api.mockito.PowerMockito;
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
import org.powermock.modules.junit4.PowerMockRunner;
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.greenhouses.data.Greenhouse;
|
import world.bentobox.greenhouses.data.Greenhouse;
|
||||||
|
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||||
|
import world.bentobox.greenhouses.managers.EcoSystemManager.GrowthBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@RunWith(PowerMockRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
@PrepareForTest({Bukkit.class, BentoBox.class})
|
@PrepareForTest({Bukkit.class, BentoBox.class, Tag.class, RecipeManager.class})
|
||||||
public class EcoSystemManagerTest {
|
public class EcoSystemManagerTest {
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Greenhouse gh;
|
private Greenhouse gh;
|
||||||
@Mock
|
@Mock
|
||||||
private World world;
|
private World world;
|
||||||
@ -47,119 +55,138 @@ public class EcoSystemManagerTest {
|
|||||||
private Block liquid;
|
private Block liquid;
|
||||||
@Mock
|
@Mock
|
||||||
private Block plant;
|
private Block plant;
|
||||||
|
@Mock
|
||||||
|
private BiomeRecipe recipe;
|
||||||
|
|
||||||
// CUT
|
// CUT
|
||||||
private EcoSystemManager eco;
|
private EcoSystemManager eco;
|
||||||
/**
|
/**
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
*/
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
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
|
// 4x4x4 greenhouse
|
||||||
BoundingBox bb = BoundingBox.of(new Vector(0,0,0), new Vector(5,5,5));
|
BoundingBox bb = BoundingBox.of(new Vector(0,0,0), new Vector(6,5,6));
|
||||||
when(gh.getBoundingBox()).thenReturn(bb);
|
gh.setBoundingBox(bb);
|
||||||
// World
|
// World
|
||||||
when(gh.getWorld()).thenReturn(world);
|
Location l = new Location(world, 0,0,0);
|
||||||
|
gh.setLocation(l);
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
||||||
// Blocks
|
// Blocks
|
||||||
// Air
|
// Air
|
||||||
// Liquid false
|
// Liquid false
|
||||||
when(air.isEmpty()).thenReturn(true);
|
when(air.isEmpty()).thenReturn(true);
|
||||||
when(air.isPassable()).thenReturn(true);
|
when(air.isPassable()).thenReturn(true);
|
||||||
when(air.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(air.getRelative(BlockFace.UP)).thenReturn(air);
|
||||||
// Plant
|
// Plant
|
||||||
// Empty false
|
// Empty false
|
||||||
// Liquid false
|
// Liquid false
|
||||||
when(plant.isPassable()).thenReturn(true);
|
when(plant.isPassable()).thenReturn(true);
|
||||||
when(plant.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(plant.getRelative(BlockFace.UP)).thenReturn(air);
|
||||||
// Liquid
|
// Liquid
|
||||||
// Empty false
|
// Empty false
|
||||||
when(liquid.isLiquid()).thenReturn(true);
|
when(liquid.isLiquid()).thenReturn(true);
|
||||||
when(liquid.isPassable()).thenReturn(true);
|
when(liquid.isPassable()).thenReturn(true);
|
||||||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(liquid.getRelative(BlockFace.UP)).thenReturn(air);
|
||||||
// Default for block
|
// Default for block
|
||||||
// Empty false
|
// Empty false
|
||||||
// Passable false
|
// Passable false
|
||||||
// Liquid false
|
// Liquid false
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(block.getRelative(BlockFace.UP)).thenReturn(air);
|
||||||
|
|
||||||
|
// Recipe
|
||||||
|
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);
|
eco = new EcoSystemManager(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws java.lang.Exception
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksAirAboveBlock() {
|
public void testGetAvailableBlocksAirAboveBlock() {
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
List<GrowthBlock> result = eco.getAvailableBlocks(gh, false);
|
||||||
assertEquals(16, result.size());
|
assertEquals(16, result.size());
|
||||||
assertEquals(air, result.get(0));
|
assertEquals(air, result.get(0).block());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksPlantAboveBlock() {
|
public void testGetAvailableBlocksPlantAboveBlock() {
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(plant);
|
when(block.getRelative(eq(BlockFace.UP))).thenReturn(plant);
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
List<GrowthBlock> result = eco.getAvailableBlocks(gh, false);
|
||||||
assertEquals(16, result.size());
|
assertEquals(16, result.size());
|
||||||
assertEquals(plant, result.get(0));
|
assertEquals(plant, result.get(0).block());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksAllAir() {
|
public void testGetAvailableBlocksAllAir() {
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(air);
|
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(air);
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
List<GrowthBlock> result = eco.getAvailableBlocks(gh, false);
|
||||||
assertEquals(0, result.size());
|
assertEquals(0, result.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksAllLiquid() {
|
public void testGetAvailableBlocksAllLiquid() {
|
||||||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(liquid);
|
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(liquid);
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
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());
|
assertEquals(0, result.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksAllPlant() {
|
public void testGetAvailableBlocksAllPlant() {
|
||||||
when(plant.getRelative(eq(BlockFace.UP))).thenReturn(plant);
|
when(plant.getRelative(eq(BlockFace.UP))).thenReturn(plant);
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(plant);
|
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(plant);
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
List<GrowthBlock> result = eco.getAvailableBlocks(gh, false);
|
||||||
assertEquals(16, result.size());
|
assertEquals(16, result.size());
|
||||||
assertEquals(plant, result.get(0));
|
assertEquals(plant, result.get(0).block());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksLiquidAboveBlockIgnoreLiquids() {
|
public void testGetAvailableBlocksLiquidAboveBlockIgnoreLiquids() {
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, true);
|
List<GrowthBlock> result = eco.getAvailableBlocks(gh, true);
|
||||||
assertEquals(16, result.size());
|
assertEquals(16, result.size());
|
||||||
assertEquals(liquid, result.get(0));
|
assertEquals(liquid, result.get(0).block());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksAirAboveLiquidNotIgnoreLiquids() {
|
public void testGetAvailableBlocksAirAboveLiquidNotIgnoreLiquids() {
|
||||||
@ -169,15 +196,15 @@ public class EcoSystemManagerTest {
|
|||||||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||||
|
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
List<GrowthBlock> result = eco.getAvailableBlocks(gh, false);
|
||||||
assertEquals(16, result.size());
|
assertEquals(16, result.size());
|
||||||
for (int i = 0; i< result.size(); i++) {
|
for (GrowthBlock value : result) {
|
||||||
assertEquals(air, result.get(i));
|
assertEquals(air, value.block());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(Greenhouse, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetAvailableBlocksAirAboveLiquidIgnoreLiquids() {
|
public void testGetAvailableBlocksAirAboveLiquidIgnoreLiquids() {
|
||||||
@ -187,10 +214,63 @@ public class EcoSystemManagerTest {
|
|||||||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
||||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||||
|
|
||||||
List<Block> result = eco.getAvailableBlocks(gh, true);
|
List<GrowthBlock> result = eco.getAvailableBlocks(gh, true);
|
||||||
assertEquals(16, result.size());
|
assertEquals(16, result.size());
|
||||||
for (int i = 0; i< result.size(); i++) {
|
for (GrowthBlock value : result) {
|
||||||
assertEquals(liquid, result.get(i));
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,14 @@ package world.bentobox.greenhouses.managers;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -18,7 +17,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.Tag;
|
import org.bukkit.Tag;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.util.Vector;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -35,6 +34,7 @@ import world.bentobox.greenhouses.greenhouse.Roof;
|
|||||||
import world.bentobox.greenhouses.greenhouse.Walls;
|
import world.bentobox.greenhouses.greenhouse.Walls;
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck;
|
import world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck;
|
||||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
||||||
|
import world.bentobox.greenhouses.world.AsyncWorldCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
@ -54,34 +54,34 @@ public class GreenhouseFinderTest {
|
|||||||
private Location location;
|
private Location location;
|
||||||
// Class under test
|
// Class under test
|
||||||
private GreenhouseFinder gf;
|
private GreenhouseFinder gf;
|
||||||
@Mock
|
|
||||||
private Block block;
|
|
||||||
private CounterCheck cc;
|
private CounterCheck cc;
|
||||||
@Mock
|
|
||||||
private Roof roof;
|
private Roof roof;
|
||||||
@Mock
|
@Mock
|
||||||
private Walls walls;
|
private Walls walls;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AsyncWorldCache cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
*/
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
|
||||||
|
when(Tag.TRAPDOORS.isTagged(Material.BIRCH_TRAPDOOR)).thenReturn(true);
|
||||||
|
// Declare mock after mocking Bukkit
|
||||||
|
roof = mock(Roof.class);
|
||||||
|
when(roof.roofBlocks(any())).thenCallRealMethod();
|
||||||
// Location
|
// Location
|
||||||
when(location.getBlockX()).thenReturn(5);
|
when(location.getBlockX()).thenReturn(5);
|
||||||
when(location.getBlockY()).thenReturn(14);
|
when(location.getBlockY()).thenReturn(14);
|
||||||
when(location.getBlockZ()).thenReturn(25);
|
when(location.getBlockZ()).thenReturn(25);
|
||||||
when(location.getWorld()).thenReturn(world);
|
when(location.getWorld()).thenReturn(world);
|
||||||
|
// Addon
|
||||||
|
when(addon.wallBlocks(any())).thenCallRealMethod();
|
||||||
// Block
|
// Block
|
||||||
when(block.getX()).thenReturn(5);
|
when(cache.getBlockType(any())).thenReturn(Material.GLASS);
|
||||||
when(block.getY()).thenReturn(14);
|
when(cache.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.GLASS);
|
||||||
when(block.getZ()).thenReturn(25);
|
|
||||||
when(block.getType()).thenReturn(Material.GLASS);
|
|
||||||
when(block.getLocation()).thenReturn(location);
|
|
||||||
when(block.getWorld()).thenReturn(world);
|
|
||||||
|
|
||||||
// Roof
|
// Roof
|
||||||
when(roof.getHeight()).thenReturn(ROOF_HEIGHT);
|
when(roof.getHeight()).thenReturn(ROOF_HEIGHT);
|
||||||
when(walls.getMinX()).thenReturn(5);
|
when(walls.getMinX()).thenReturn(5);
|
||||||
@ -92,26 +92,25 @@ public class GreenhouseFinderTest {
|
|||||||
when(roof.getLocation()).thenReturn(location);
|
when(roof.getLocation()).thenReturn(location);
|
||||||
|
|
||||||
// World
|
// World
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NORMAL);
|
when(cache.getEnvironment()).thenReturn(Environment.NORMAL);
|
||||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
when(cache.getMaxHeight()).thenReturn(30);
|
||||||
when(world.getMaxHeight()).thenReturn(30);
|
|
||||||
|
|
||||||
|
|
||||||
gf = new GreenhouseFinder();
|
gf = new GreenhouseFinder(addon);
|
||||||
cc = gf.new CounterCheck();
|
cc = new CounterCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkGreenhouse(world.bentobox.greenhouses.data.Greenhouse, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkGreenhouse(AsyncWorldCache, Roof, Walls)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCheckGreenhouse() {
|
public void testCheckGreenhouse() {
|
||||||
Greenhouse gh2 = new Greenhouse(world, walls, ROOF_HEIGHT);
|
gf.checkGreenhouse(cache, roof, walls).thenAccept(result -> {
|
||||||
Set<GreenhouseResult> result = gf.checkGreenhouse(gh2, roof, walls);
|
|
||||||
assertTrue(result.isEmpty()); // Success
|
assertTrue(result.isEmpty()); // Success
|
||||||
assertEquals(441, gf.getWallBlockCount());
|
assertEquals(441, gf.getWallBlockCount());
|
||||||
assertEquals(0, gf.getWallDoors());
|
assertEquals(0, gf.getWallDoors());
|
||||||
assertEquals(0, gf.getGhHopper());
|
assertEquals(0, gf.getGhHopper());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,188 +179,77 @@ public class GreenhouseFinderTest {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkBlock(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, org.bukkit.block.Block)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkBlock(CounterCheck, Material, Roof, Walls, Vector)}
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckBlock() {
|
|
||||||
// Block has to be > roof height
|
|
||||||
when(block.getY()).thenReturn(ROOF_HEIGHT + 1);
|
|
||||||
Set<GreenhouseResult> result = gf.checkBlock(cc, roof, walls, block);
|
|
||||||
result.forEach(gr -> assertEquals(GreenhouseResult.FAIL_BLOCKS_ABOVE, gr));
|
|
||||||
gf.getRedGlass().forEach(l -> assertEquals(location, l));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkBlock(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, org.bukkit.block.Block)}.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCheckBlockRoofHeight() {
|
public void testCheckBlockRoofHeight() {
|
||||||
// Block has to be > roof height
|
// Glass block should be ok at roof height
|
||||||
when(block.getY()).thenReturn(ROOF_HEIGHT);
|
assertTrue(gf.checkBlock(cc, Material.GLASS, roof, walls, new Vector(0, ROOF_HEIGHT, 0)));
|
||||||
Set<GreenhouseResult> result = gf.checkBlock(cc, roof, walls, block);
|
|
||||||
assertTrue(result.isEmpty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkBlock(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, org.bukkit.block.Block)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckBlockNether() {
|
|
||||||
when(world.getEnvironment()).thenReturn(Environment.NETHER);
|
|
||||||
// Block has to be > roof height
|
|
||||||
when(block.getY()).thenReturn(ROOF_HEIGHT + 1);
|
|
||||||
Set<GreenhouseResult> result = gf.checkBlock(cc, roof, walls, block);
|
|
||||||
assertTrue(result.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkBlock(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, org.bukkit.block.Block)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkBlock(CounterCheck, Material, Roof, Walls, Vector)}
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCheckBlockAir() {
|
public void testCheckBlockAir() {
|
||||||
when(block.isEmpty()).thenReturn(true);
|
// Glass air should be not allowed at roof height
|
||||||
// Block has to be > roof height
|
assertFalse(gf.checkBlock(cc, Material.AIR, roof, walls, new Vector(0, ROOF_HEIGHT, 0)));
|
||||||
when(block.getY()).thenReturn(ROOF_HEIGHT + 1);
|
|
||||||
Set<GreenhouseResult> result = gf.checkBlock(cc, roof, walls, block);
|
|
||||||
assertTrue(result.isEmpty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkWalls(org.bukkit.block.Block, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckWallsAirHole() {
|
|
||||||
// Make block AIR
|
|
||||||
when(block.isEmpty()).thenReturn(true);
|
|
||||||
when(block.getType()).thenReturn(Material.AIR);
|
|
||||||
assertTrue(gf.checkWalls(block, roof, walls, cc));
|
|
||||||
assertFalse(gf.getRedGlass().isEmpty());
|
|
||||||
gf.getRedGlass().forEach(l -> assertEquals(location, l));
|
|
||||||
assertTrue(cc.airHole);
|
|
||||||
assertFalse(gf.isInCeiling());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkWalls(org.bukkit.block.Block, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkDoorsHoppers(CounterCheck, Material, Vector)}
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckWallsAirHoleInRoof() {
|
|
||||||
// Make block AIR
|
|
||||||
when(block.isEmpty()).thenReturn(true);
|
|
||||||
when(block.getType()).thenReturn(Material.AIR);
|
|
||||||
when(block.getY()).thenReturn(ROOF_HEIGHT);
|
|
||||||
assertTrue(gf.checkWalls(block, roof, walls, cc));
|
|
||||||
assertFalse(gf.getRedGlass().isEmpty());
|
|
||||||
gf.getRedGlass().stream().forEach(l -> assertEquals(location, l));
|
|
||||||
assertTrue(cc.airHole);
|
|
||||||
assertTrue(gf.isInCeiling());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkWalls(org.bukkit.block.Block, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckWalls() {
|
|
||||||
// Make block GLASS
|
|
||||||
when(block.isEmpty()).thenReturn(false);
|
|
||||||
when(block.getType()).thenReturn(Material.GLASS);
|
|
||||||
assertTrue(gf.checkWalls(block, roof, walls, cc));
|
|
||||||
assertTrue(gf.getRedGlass().isEmpty());
|
|
||||||
assertFalse(cc.airHole);
|
|
||||||
assertFalse(gf.isInCeiling());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkWalls(org.bukkit.block.Block, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckWallsInRoof() {
|
|
||||||
// Make block GLASS
|
|
||||||
when(block.isEmpty()).thenReturn(false);
|
|
||||||
when(block.getType()).thenReturn(Material.GLASS);
|
|
||||||
when(block.getY()).thenReturn(ROOF_HEIGHT);
|
|
||||||
assertTrue(gf.checkWalls(block, roof, walls, cc));
|
|
||||||
assertTrue(gf.getRedGlass().isEmpty());
|
|
||||||
assertFalse(cc.airHole);
|
|
||||||
assertFalse(gf.isInCeiling());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkWalls(org.bukkit.block.Block, world.bentobox.greenhouses.greenhouse.Roof, world.bentobox.greenhouses.greenhouse.Walls, world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckWallsNotInWall() {
|
|
||||||
when(block.getX()).thenReturn(0);
|
|
||||||
when(block.getY()).thenReturn(0);
|
|
||||||
when(block.getZ()).thenReturn(0);
|
|
||||||
// Make block GLASS
|
|
||||||
when(block.isEmpty()).thenReturn(false);
|
|
||||||
when(block.getType()).thenReturn(Material.GLASS);
|
|
||||||
assertFalse(gf.checkWalls(block, roof, walls, cc));
|
|
||||||
assertTrue(gf.getRedGlass().isEmpty());
|
|
||||||
assertFalse(cc.airHole);
|
|
||||||
assertFalse(gf.isInCeiling());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkDoorsHoppers(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, org.bukkit.block.Block)}.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCheckDoorsHoppers() {
|
public void testCheckDoorsHoppers() {
|
||||||
|
// Doors are 2 blocks
|
||||||
when(Tag.DOORS.isTagged(any(Material.class))).thenReturn(true);
|
when(Tag.DOORS.isTagged(any(Material.class))).thenReturn(true);
|
||||||
when(block.getType()).thenReturn(Material.ACACIA_DOOR);
|
for (int i = 0; i < 8; i++) {
|
||||||
gf.checkDoorsHoppers(cc, block);
|
assertTrue("Door number " + i, gf.checkDoorsHoppers(cc, Material.ACACIA_DOOR, new Vector(0,0,0)));
|
||||||
assertTrue(gf.getRedGlass().isEmpty());
|
}
|
||||||
|
// 5th door will fail
|
||||||
|
assertFalse(gf.checkDoorsHoppers(cc, Material.ACACIA_DOOR, new Vector(0,0,0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkDoorsHoppers(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, org.bukkit.block.Block)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkDoorsHoppers(CounterCheck, Material, Vector)}
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCheckDoorsHoppersTooManyDoors() {
|
public void testCheckDoorsHoppersTrapdoors() {
|
||||||
gf.setWallDoors(8);
|
// Trapdoors are one block
|
||||||
when(Tag.DOORS.isTagged(any(Material.class))).thenReturn(true);
|
for (int i = 0; i < 4; i++) {
|
||||||
when(block.getType()).thenReturn(Material.ACACIA_DOOR);
|
assertTrue("Door number " + i, gf.checkDoorsHoppers(cc, Material.BIRCH_TRAPDOOR, new Vector(0,0,0)));
|
||||||
CounterCheck cc = gf.new CounterCheck();
|
}
|
||||||
gf.checkDoorsHoppers(cc, block);
|
// 5th door will fail
|
||||||
assertFalse(gf.getRedGlass().isEmpty());
|
assertFalse(gf.checkDoorsHoppers(cc, Material.BIRCH_TRAPDOOR, new Vector(0,0,0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkDoorsHoppers(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, org.bukkit.block.Block)}.
|
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkDoorsHoppers(CounterCheck, Material, Vector)}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testCheckDoorsHoppersHopper() {
|
public void testCheckDoorsHoppersHopper() {
|
||||||
|
Greenhouse gh = new Greenhouse(world, walls, 10);
|
||||||
|
// Set the greenhouse so the world is known
|
||||||
|
gf.setGh(gh);
|
||||||
when(Tag.DOORS.isTagged(any(Material.class))).thenReturn(false);
|
when(Tag.DOORS.isTagged(any(Material.class))).thenReturn(false);
|
||||||
when(block.getType()).thenReturn(Material.HOPPER);
|
CounterCheck cc = new CounterCheck();
|
||||||
when(block.getLocation()).thenReturn(location);
|
assertTrue(gf.checkDoorsHoppers(cc, Material.HOPPER, new Vector(5,14,25)));
|
||||||
CounterCheck cc = gf.new CounterCheck();
|
|
||||||
gf.checkDoorsHoppers(cc, block);
|
|
||||||
assertTrue(gf.getRedGlass().isEmpty());
|
assertTrue(gf.getRedGlass().isEmpty());
|
||||||
assertEquals(location, gf.getGh().getRoofHopperLocation());
|
assertEquals(5, gf.getGh().getRoofHopperLocation().getBlockX());
|
||||||
|
assertEquals(14, gf.getGh().getRoofHopperLocation().getBlockY());
|
||||||
|
assertEquals(25, gf.getGh().getRoofHopperLocation().getBlockZ());
|
||||||
|
assertFalse(gf.checkDoorsHoppers(cc, Material.HOPPER, new Vector(5,14,25)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#checkDoorsHoppers(world.bentobox.greenhouses.managers.GreenhouseFinder.CounterCheck, org.bukkit.block.Block)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCheckDoorsHoppersTooManyHoppers() {
|
|
||||||
gf.setGhHopper(3);
|
|
||||||
when(Tag.DOORS.isTagged(any(Material.class))).thenReturn(false);
|
|
||||||
when(block.getType()).thenReturn(Material.HOPPER);
|
|
||||||
when(block.getLocation()).thenReturn(location);
|
|
||||||
CounterCheck cc = gf.new CounterCheck();
|
|
||||||
gf.checkDoorsHoppers(cc, block);
|
|
||||||
assertFalse(gf.getRedGlass().isEmpty());
|
|
||||||
assertNull(gf.getGh().getRoofHopperLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#getGh()}.
|
* Test method for {@link world.bentobox.greenhouses.managers.GreenhouseFinder#getGh()}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetGh() {
|
public void testGetGh() {
|
||||||
assertNotNull(gf.getGh());
|
assertNull(gf.getGh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user