diff --git a/.travis.yml b/.travis.yml
index 774b42c..af3496c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,8 +3,7 @@ sudo: false
addons:
sonarcloud:
organization: "bentobox-world"
- token:
- secure: $SONAR_TOKEN
+
jdk:
- openjdk8
diff --git a/pom.xml b/pom.xml
index 76a506c..b98962c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,16 +56,16 @@
UTF-8
1.8
- 2.0.2
+ 2.0.4
1.14.4-R0.1-SNAPSHOT
- 1.8.0
+ 1.9.0-SNAPSHOT
${build.version}-SNAPSHOT
-LOCAL
- 1.8.0
+ 1.9.0
diff --git a/src/main/java/world/bentobox/acidisland/AISettings.java b/src/main/java/world/bentobox/acidisland/AISettings.java
index d7de204..ec847cc 100644
--- a/src/main/java/world/bentobox/acidisland/AISettings.java
+++ b/src/main/java/world/bentobox/acidisland/AISettings.java
@@ -257,6 +257,11 @@ public class AISettings implements WorldSettings {
@ConfigEntry(path = "world.visitor-banned-commands")
private List visitorBannedCommands = new ArrayList<>();
+ @ConfigComment("Falling banned commands - players cannot use these commands when falling")
+ @ConfigComment("if the PREVENT_TELEPORT_WHEN_FALLING world setting flag is active")
+ @ConfigEntry(path = "world.falling-banned-commands")
+ private List fallingBannedCommands = new ArrayList<>();
+
// ---------------------------------------------
/* ISLAND */
@@ -272,18 +277,8 @@ public class AISettings implements WorldSettings {
@ConfigEntry(path = "island.max-homes")
private int maxHomes = 5;
- @ConfigComment("Island naming")
- @ConfigComment("Only players with the TODO can name their island")
- @ConfigComment("It is displayed in the top ten and enter and exit announcements")
- @ConfigComment("It replaces the owner's name. Players can use & for color coding if they have the TODO permission")
- @ConfigComment("These set the minimum and maximum size of a name.")
- @ConfigEntry(path = "island.name.min-length")
- private int nameMinLength = 4;
- @ConfigEntry(path = "island.name.max-length")
- private int nameMaxLength = 20;
-
// Reset
- @ConfigComment("How many resets a player is allowed (override with /acid clearresets )")
+ @ConfigComment("How many resets a player is allowed (manage with /acid reset add/remove/reset/set command)")
@ConfigComment("Value of -1 means unlimited, 0 means hardcore - no resets.")
@ConfigComment("Example, 2 resets means they get 2 resets or 3 islands lifetime")
@ConfigEntry(path = "island.reset.reset-limit")
@@ -360,6 +355,43 @@ public class AISettings implements WorldSettings {
@ConfigEntry(path = "island.reset.on-leave.ender-chest")
private boolean onLeaveResetEnderChest = false;
+ @ConfigComment("Toggles the automatic island creation upon the player's first login on your server.")
+ @ConfigComment("If set to true,")
+ @ConfigComment(" * Upon connecting to your server for the first time, the player will be told that")
+ @ConfigComment(" an island will be created for him.")
+ @ConfigComment(" * Make sure you have a Blueprint Bundle called \"default\": this is the one that will")
+ @ConfigComment(" be used to create the island.")
+ @ConfigComment(" * An island will be created for the player without needing him to run the create command.")
+ @ConfigComment("If set to false, this will disable this feature entirely.")
+ @ConfigComment("Warning:")
+ @ConfigComment(" * If you are running multiple gamemodes on your server, and all of them have")
+ @ConfigComment(" this feature enabled, an island in all the gamemodes will be created simultaneously.")
+ @ConfigComment(" However, it is impossible to know on which island the player will be teleported to afterwards.")
+ @ConfigComment(" * Island creation can be resource-intensive, please consider the options below to help mitigate")
+ @ConfigComment(" the potential issues, especially if you expect a lot of players to connect to your server")
+ @ConfigComment(" in a limited period of time.")
+ @ConfigEntry(path = "island.create-island-on-first-login.enable")
+ private boolean createIslandOnFirstLoginEnabled;
+
+ @ConfigComment("Time in seconds after the player logged in, before his island gets created.")
+ @ConfigComment("If set to 0 or less, the island will be created directly upon the player's login.")
+ @ConfigComment("It is recommended to keep this value under a minute's time.")
+ @ConfigEntry(path = "island.create-island-on-first-login.delay")
+ private int createIslandOnFirstLoginDelay = 5;
+
+ @ConfigComment("Toggles whether the island creation should be aborted if the player logged off while the")
+ @ConfigComment("delay (see the option above) has not worn off yet.")
+ @ConfigComment("If set to true,")
+ @ConfigComment(" * If the player has logged off the server while the delay (see the option above) has not")
+ @ConfigComment(" worn off yet, this will cancel the island creation.")
+ @ConfigComment(" * If the player relogs afterward, since he will not be recognized as a new player, no island")
+ @ConfigComment(" would be created for him.")
+ @ConfigComment(" * If the island creation started before the player logged off, it will continue.")
+ @ConfigComment("If set to false, the player's island will be created even if he went offline in the meantime.")
+ @ConfigComment("Note this option has no effect if the delay (see the option above) is set to 0 or less.")
+ @ConfigEntry(path = "island.create-island-on-first-login.abort-on-logout")
+ private boolean createIslandOnFirstLoginAbortOnLogout = true;
+
// Commands
@ConfigComment("List of commands to run when a player joins.")
@ConfigEntry(path = "island.commands.on-join")
@@ -623,18 +655,6 @@ public class AISettings implements WorldSettings {
public int getMaxTeamSize() {
return maxTeamSize;
}
- /**
- * @return the nameMaxLength
- */
- public int getNameMaxLength() {
- return nameMaxLength;
- }
- /**
- * @return the nameMinLength
- */
- public int getNameMinLength() {
- return nameMinLength;
- }
/**
* @return the netherSeaHeight
*/
@@ -691,6 +711,15 @@ public class AISettings implements WorldSettings {
public List getVisitorBannedCommands() {
return visitorBannedCommands;
}
+
+ /**
+ * @return the fallingBannedCommands
+ */
+ @Override
+ public List getFallingBannedCommands() {
+ return fallingBannedCommands;
+ }
+
/**
* @return the worldFlags
*/
@@ -777,6 +806,44 @@ public class AISettings implements WorldSettings {
public boolean isKickedKeepInventory() {
return kickedKeepInventory;
}
+
+
+ /**
+ * This method returns the createIslandOnFirstLoginEnabled boolean value.
+ * @return the createIslandOnFirstLoginEnabled value
+ * @since 1.9.0
+ */
+ @Override
+ public boolean isCreateIslandOnFirstLoginEnabled()
+ {
+ return createIslandOnFirstLoginEnabled;
+ }
+
+
+ /**
+ * This method returns the createIslandOnFirstLoginDelay int value.
+ * @return the createIslandOnFirstLoginDelay value
+ * @since 1.9.0
+ */
+ @Override
+ public int getCreateIslandOnFirstLoginDelay()
+ {
+ return createIslandOnFirstLoginDelay;
+ }
+
+
+ /**
+ * This method returns the createIslandOnFirstLoginAbortOnLogout boolean value.
+ * @return the createIslandOnFirstLoginAbortOnLogout value
+ * @since 1.9.0
+ */
+ @Override
+ public boolean isCreateIslandOnFirstLoginAbortOnLogout()
+ {
+ return createIslandOnFirstLoginAbortOnLogout;
+ }
+
+
/**
* @return the leaversLoseReset
*/
@@ -1129,19 +1196,6 @@ public class AISettings implements WorldSettings {
public void setMaxTeamSize(int maxTeamSize) {
this.maxTeamSize = maxTeamSize;
}
- /**
- * @param nameMaxLength the nameMaxLength to set
- */
- public void setNameMaxLength(int nameMaxLength) {
- this.nameMaxLength = nameMaxLength;
- }
- /**
- * @param nameMinLength the nameMinLength to set
- */
- public void setNameMinLength(int nameMinLength) {
- this.nameMinLength = nameMinLength;
- }
-
/**
* @param netherGenerate the netherGenerate to set
*/
@@ -1280,6 +1334,13 @@ public class AISettings implements WorldSettings {
this.visitorBannedCommands = visitorBannedCommands;
}
+ /**
+ * @param fallingBannedCommands the fallingBannedCommands to set
+ */
+ public void setFallingBannedCommands(List fallingBannedCommands) {
+ this.fallingBannedCommands = fallingBannedCommands;
+ }
+
/**
* @param worldFlags the worldFlags to set
*/
@@ -1423,4 +1484,27 @@ public class AISettings implements WorldSettings {
this.onLeaveResetXP = onLeaveResetXP;
}
+ /**
+ * @param createIslandOnFirstLoginEnabled the createIslandOnFirstLoginEnabled to set
+ */
+ public void setCreateIslandOnFirstLoginEnabled(boolean createIslandOnFirstLoginEnabled)
+ {
+ this.createIslandOnFirstLoginEnabled = createIslandOnFirstLoginEnabled;
+ }
+
+ /**
+ * @param createIslandOnFirstLoginDelay the createIslandOnFirstLoginDelay to set
+ */
+ public void setCreateIslandOnFirstLoginDelay(int createIslandOnFirstLoginDelay)
+ {
+ this.createIslandOnFirstLoginDelay = createIslandOnFirstLoginDelay;
+ }
+
+ /**
+ * @param createIslandOnFirstLoginAbortOnLogout the createIslandOnFirstLoginAbortOnLogout to set
+ */
+ public void setCreateIslandOnFirstLoginAbortOnLogout(boolean createIslandOnFirstLoginAbortOnLogout)
+ {
+ this.createIslandOnFirstLoginAbortOnLogout = createIslandOnFirstLoginAbortOnLogout;
+ }
}
diff --git a/src/main/java/world/bentobox/acidisland/AcidIsland.java b/src/main/java/world/bentobox/acidisland/AcidIsland.java
index 427c729..73a25d9 100644
--- a/src/main/java/world/bentobox/acidisland/AcidIsland.java
+++ b/src/main/java/world/bentobox/acidisland/AcidIsland.java
@@ -5,6 +5,7 @@ import org.bukkit.WorldCreator;
import org.bukkit.WorldType;
import org.bukkit.generator.ChunkGenerator;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.acidisland.commands.AcidCommand;
import world.bentobox.acidisland.commands.AiCommand;
@@ -24,9 +25,9 @@ import world.bentobox.bentobox.lists.Flags;
*/
public class AcidIsland extends GameModeAddon {
- private AISettings settings;
- private AcidTask acidTask;
- private @NonNull ChunkGenerator chunkGenerator;
+ private @Nullable AISettings settings;
+ private @Nullable AcidTask acidTask;
+ private @Nullable ChunkGenerator chunkGenerator;
private Config config = new Config<>(this, AISettings.class);
private static final String NETHER = "_nether";
@@ -78,10 +79,11 @@ public class AcidIsland extends GameModeAddon {
}
@Override
- public void onDisable(){
- acidTask.cancelTasks();
+ public void onDisable() {
+ if (acidTask != null) acidTask.cancelTasks();
}
+ @Nullable
public AISettings getSettings() {
return settings;
}
diff --git a/src/main/java/world/bentobox/acidisland/commands/AcidCommand.java b/src/main/java/world/bentobox/acidisland/commands/AcidCommand.java
index d1cf37a..ba1facd 100644
--- a/src/main/java/world/bentobox/acidisland/commands/AcidCommand.java
+++ b/src/main/java/world/bentobox/acidisland/commands/AcidCommand.java
@@ -25,7 +25,7 @@ import world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintComma
import world.bentobox.bentobox.api.commands.admin.deaths.AdminDeathsCommand;
import world.bentobox.bentobox.api.commands.admin.purge.AdminPurgeCommand;
import world.bentobox.bentobox.api.commands.admin.range.AdminRangeCommand;
-import world.bentobox.bentobox.api.commands.admin.resets.AdminResetsResetCommand;
+import world.bentobox.bentobox.api.commands.admin.resets.AdminResetsCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamAddCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamDisbandCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamKickCommand;
@@ -67,8 +67,7 @@ public class AcidCommand extends CompositeCommand {
// Range
new AdminRangeCommand(this);
// Resets
- new AdminResetsResetCommand(this);
- // TODO new AdminClearresetsallCommand(this);
+ new AdminResetsCommand(this);
// Delete
new AdminDeleteCommand(this);
// Why
diff --git a/src/main/java/world/bentobox/acidisland/world/ChunkGeneratorWorld.java b/src/main/java/world/bentobox/acidisland/world/ChunkGeneratorWorld.java
index 68fd06b..8d678c6 100644
--- a/src/main/java/world/bentobox/acidisland/world/ChunkGeneratorWorld.java
+++ b/src/main/java/world/bentobox/acidisland/world/ChunkGeneratorWorld.java
@@ -1,14 +1,19 @@
package world.bentobox.acidisland.world;
-import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
+import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
+import org.bukkit.util.Vector;
import org.bukkit.util.noise.PerlinOctaveGenerator;
import world.bentobox.acidisland.AcidIsland;
@@ -22,6 +27,8 @@ public class ChunkGeneratorWorld extends ChunkGenerator {
private final AcidIsland addon;
private final Random rand = new Random();
+ private Map seaHeight = new EnumMap<>(Environment.class);
+ private Map roofChunk = new HashMap<>();
/**
* @param addon - addon
@@ -29,29 +36,38 @@ public class ChunkGeneratorWorld extends ChunkGenerator {
public ChunkGeneratorWorld(AcidIsland addon) {
super();
this.addon = addon;
+ seaHeight.put(Environment.NORMAL, addon.getSettings().getSeaHeight());
+ seaHeight.put(Environment.NETHER, addon.getSettings().getNetherSeaHeight());
+ seaHeight.put(Environment.THE_END, addon.getSettings().getEndSeaHeight());
+ makeNetherRoof();
+ }
+
+ public ChunkData generateChunks(World world) {
+ ChunkData result = createChunkData(world);
+ int sh = seaHeight.getOrDefault(world.getEnvironment(), 0);
+ if (sh > 0) {
+ result.setRegion(0, 0, 0, 16, sh + 1, 16, Material.WATER);
+ }
+ if (world.getEnvironment().equals(Environment.NETHER) && addon.getSettings().isNetherRoof()) {
+ roofChunk.forEach((k,v) -> result.setBlock(k.getBlockX(), world.getMaxHeight() + k.getBlockY(), k.getBlockZ(), v));
+ }
+ return result;
}
@Override
- public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, ChunkGenerator.BiomeGrid biomeGrid) {
- if (world.getEnvironment().equals(World.Environment.NETHER)) {
- return generateNetherChunks(world, random, chunkX, chunkZ, biomeGrid);
- }
- int seaHeight = world.getEnvironment().equals(World.Environment.NORMAL) ? addon.getSettings().getSeaHeight() : addon.getSettings().getEndSeaHeight();
- ChunkData result = createChunkData(world);
- if (seaHeight != 0) {
- for (int x = 0; x < 16; x++) {
- for (int z = 0; z < 16; z++) {
- if (world.getEnvironment().equals(Environment.NORMAL)) {
- biomeGrid.setBiome(x, z, addon.getSettings().getDefaultBiome());
- }
- for (int y = 0; y <= seaHeight; y++) {
- result.setBlock(x, y, z, Material.WATER);
- }
- }
- }
+ public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biomeGrid) {
+ if (world.getEnvironment().equals(Environment.NORMAL)) setBiome(biomeGrid);
+ return generateChunks(world);
+ }
+ private void setBiome(BiomeGrid biomeGrid) {
+ Biome biome = addon.getSettings().getDefaultBiome();
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ biomeGrid.setBiome(x, z, biome);
+ }
}
- return result;
+
}
// This needs to be set to return true to override minecraft's default
@@ -63,95 +79,81 @@ public class ChunkGeneratorWorld extends ChunkGenerator {
@Override
public List getDefaultPopulators(final World world) {
- return Arrays.asList(new BlockPopulator[0]);
+ return Collections.emptyList();
}
/*
* Nether Section
*/
- private ChunkData generateNetherChunks(World world, Random random, int chunkX, int chunkZ, BiomeGrid biomeGrid) {
- ChunkData result = createChunkData(world);
- rand.setSeed(world.getSeed());
- PerlinOctaveGenerator gen = new PerlinOctaveGenerator((long) (random.nextLong() * random.nextGaussian()), 8);
- // This is a nether generator
- if (!world.getEnvironment().equals(Environment.NETHER)) {
- return result;
- }
- if (addon.getSettings().getSeaHeight() != 0) {
- for (int x = 0; x < 16; x++) {
- for (int z = 0; z < 16; z++) {
- for (int y = 0; y <= addon.getSettings().getNetherSeaHeight(); y++) {
- result.setBlock(x, y, z, Material.WATER);
+ private void makeNetherRoof() {
+ rand.setSeed(System.currentTimeMillis());
+ PerlinOctaveGenerator gen = new PerlinOctaveGenerator((long) (rand.nextLong() * rand.nextGaussian()), 8);
+
+ // Make the roof - common across the world
+ for (int x = 0; x < 16; x++) {
+ for (int z = 0; z < 16; z++) {
+ // Do the ceiling
+ setBlock(x, -1, z, Material.BEDROCK);
+ // Next three layers are a mix of bedrock and netherrack
+ for (int y = 2; y < 5; y++) {
+ double r = gen.noise(x, - y, z, 0.5, 0.5);
+ if (r > 0D) {
+ setBlock(x, - y, z, Material.BEDROCK);
}
}
- }
-
- }
- if (addon.getSettings().isNetherRoof()) {
- // Make the roof - common across the world
- for (int x = 0; x < 16; x++) {
- for (int z = 0; z < 16; z++) {
- // Do the ceiling
- int maxHeight = world.getMaxHeight();
- result.setBlock(x, (maxHeight - 1), z, Material.BEDROCK);
- // Next three layers are a mix of bedrock and netherrack
- for (int y = 2; y < 5; y++) {
- double r = gen.noise(x, (maxHeight - y), z, 0.5, 0.5);
- if (r > 0D) {
- result.setBlock(x, (maxHeight - y), z, Material.BEDROCK);
- }
+ // Next three layers are a mix of netherrack and air
+ for (int y = 5; y < 8; y++) {
+ double r = gen.noise(x, - y, z, 0.5, 0.5);
+ if (r > 0D) {
+ setBlock(x, -y, z, Material.NETHERRACK);
+ } else {
+ setBlock(x, -y, z, Material.AIR);
}
- // Next three layers are a mix of netherrack and air
- for (int y = 5; y < 8; y++) {
- double r = gen.noise(x, (double)maxHeight - y, z, 0.5, 0.5);
- if (r > 0D) {
- result.setBlock(x, (maxHeight - y), z, Material.NETHERRACK);
- } else {
- result.setBlock(x, (maxHeight - y), z, Material.AIR);
+ }
+ // Layer 8 may be glowstone
+ double r = gen.noise(x, - 8, z, rand.nextFloat(), rand.nextFloat());
+ if (r > 0.5D) {
+ // Have blobs of glowstone
+ switch (rand.nextInt(4)) {
+ case 1:
+ // Single block
+ setBlock(x, -8, z, Material.GLOWSTONE);
+ if (x < 14 && z < 14) {
+ setBlock(x + 1, -8, z + 1, Material.GLOWSTONE);
+ setBlock(x + 2, -8, z + 2, Material.GLOWSTONE);
+ setBlock(x + 1, -8, z + 2, Material.GLOWSTONE);
+ setBlock(x + 1, -8, z + 2, Material.GLOWSTONE);
}
- }
- // Layer 8 may be glowstone
- double r = gen.noise(x, (double)maxHeight - 8, z, random.nextFloat(), random.nextFloat());
- if (r > 0.5D) {
- // Have blobs of glowstone
- switch (random.nextInt(4)) {
- case 1:
- // Single block
- result.setBlock(x, (maxHeight - 8), z, Material.GLOWSTONE);
- if (x < 14 && z < 14) {
- result.setBlock(x + 1, (maxHeight - 8), z + 1, Material.GLOWSTONE);
- result.setBlock(x + 2, (maxHeight - 8), z + 2, Material.GLOWSTONE);
- result.setBlock(x + 1, (maxHeight - 8), z + 2, Material.GLOWSTONE);
- result.setBlock(x + 1, (maxHeight - 8), z + 2, Material.GLOWSTONE);
- }
- break;
- case 2:
- // Stalatite
- for (int i = 0; i < random.nextInt(10); i++) {
- result.setBlock(x, (maxHeight - 8 - i), z, Material.GLOWSTONE);
- }
- break;
- case 3:
- result.setBlock(x, (maxHeight - 8), z, Material.GLOWSTONE);
- if (x > 3 && z > 3) {
- for (int xx = 0; xx < 3; xx++) {
- for (int zz = 0; zz < 3; zz++) {
- result.setBlock(x - xx, (maxHeight - 8 - random.nextInt(2)), z - xx, Material.GLOWSTONE);
- }
+ break;
+ case 2:
+ // Stalatite
+ for (int i = 0; i < rand.nextInt(10); i++) {
+ setBlock(x, - 8 - i, z, Material.GLOWSTONE);
+ }
+ break;
+ case 3:
+ setBlock(x, -8, z, Material.GLOWSTONE);
+ if (x > 3 && z > 3) {
+ for (int xx = 0; xx < 3; xx++) {
+ for (int zz = 0; zz < 3; zz++) {
+ setBlock(x - xx, - 8 - rand.nextInt(2), z - xx, Material.GLOWSTONE);
}
}
- break;
- default:
- result.setBlock(x, (maxHeight - 8), z, Material.GLOWSTONE);
}
- result.setBlock(x, (maxHeight - 8), z, Material.GLOWSTONE);
- } else {
- result.setBlock(x, (maxHeight - 8), z, Material.AIR);
+ break;
+ default:
+ setBlock(x, -8, z, Material.GLOWSTONE);
}
+ setBlock(x, -8, z, Material.GLOWSTONE);
+ } else {
+ setBlock(x, -8, z, Material.AIR);
}
}
- }
- return result;
+ }
+ }
+
+ private void setBlock(int x, int y, int z, Material m) {
+ roofChunk.put(new Vector(x, y, z), m);
}
}
\ No newline at end of file
diff --git a/src/main/resources/blueprints/temple.blu b/src/main/resources/blueprints/temple.blu
index 0a07dea..324465d 100644
Binary files a/src/main/resources/blueprints/temple.blu and b/src/main/resources/blueprints/temple.blu differ
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index ed2d16e..cecf934 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -21,11 +21,16 @@ acid:
item: 0
# Damage from acid rain
rain: 1
+ # Damage from acid snow
+ snow: false
+ # Delay before acid or acid rain starts burning
+ # This can give time for conduit power to kick in
+ delay: 2
# Portion effects from going into acid water
# You can list multiple effects
effects:
- - CONFUSION
- - BLINDNESS
+ - CONFUSION
+ - BLINDNESS
protection:
# If player wears a helmet then they will not suffer from acid rain
helmet: false
@@ -33,9 +38,11 @@ acid:
full-armor: false
world:
# Friendly name for this world. Used in admin commands. Must be a single word
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
friendly-name: AcidIsland
# Name of the world - if it does not exist then it will be generated.
# It acts like a prefix for nether and end (e.g. acidisland_world, acidisland_world_nether, acidisland_world_end)
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
world-name: acidisland_world
# World difficulty setting - PEACEFUL, EASY, NORMAL, HARD
# Other plugins may override this setting
@@ -44,6 +51,7 @@ world:
# Will be rounded up to the nearest 16 blocks.
# It is the same for every dimension : Overworld, Nether and End.
# This value cannot be changed mid-game and the plugin will not start if it is different.
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
distance-between-islands: 64
# Default protection range radius in blocks. Cannot be larger than distance.
# Admins can change protection sizes for players individually using /acid range set
@@ -54,7 +62,9 @@ world:
# calculate the closest location on the grid. Islands develop around this location
# both positively and negatively in a square grid.
# If none of this makes sense, leave it at 0,0.
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
start-x: 0
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
start-z: 0
offset-x: 0
offset-z: 0
@@ -68,7 +78,7 @@ world:
# Sea height (don't changes this mid-game unless you delete the world)
# Minimum is 0, which means you are playing Skyblock!
sea-height: 54
- # Maximum number of islands in the world. Set to -1 or 0 for unlimited.
+ # Maximum number of islands in the world. Set to -1 or 0 for unlimited.
# If the number of islands is greater than this number, no new island will be created.
max-islands: 0
# The default game mode for this world. Players will be set to this mode when they create
@@ -88,13 +98,12 @@ world:
# portal will return them back to their islands.
generate: true
# Islands in Nether. Change to false for standard vanilla nether.
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
islands: true
# Sea height in Nether. Only operates if nether islands is true.
# Changing mid-game will cause problems!
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
sea-height: 54
- # Nether trees are made if a player grows a tree in the nether (gravel and glowstone)
- # Applies to both vanilla and islands Nether
- trees: true
# Make the nether roof, if false, there is nothing up there
# Change to false if lag is a problem from the generation
# Only applies to islands Nether
@@ -109,9 +118,11 @@ world:
# the end will not occur. Other plugins may still enable portal usage.
generate: true
# Islands in The End. Change to false for standard vanilla end.
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
islands: true
# Sea height in The End. Only operates if end islands is true.
# Changing mid-game will cause problems!
+ # /!\ BentoBox currently does not support changing this value mid-game. If you do need to change it, do a full reset of your databases and worlds.
sea-height: 54
# /!\ This feature is experimental and might not work as expected or might not work at all.
dragon-spawn: false
@@ -120,10 +131,10 @@ world:
# This setting is toggled in world flags and set by the settings GUI.
# Mob white list - these mobs will NOT be removed when logging in or doing /island
remove-mobs-whitelist:
- - ENDERMAN
- - ZOMBIE_VILLAGER
- - PIG_ZOMBIE
- - WITHER
+ - ZOMBIE_VILLAGER
+ - WITHER
+ - PIG_ZOMBIE
+ - ENDERMAN
# World flags. These are boolean settings for various flags for this world
flags:
CREEPER_DAMAGE: true
@@ -134,17 +145,22 @@ world:
ENDERMAN_GRIEFING: true
CLEAN_SUPER_FLAT: false
CHEST_DAMAGE: false
+ PREVENT_TELEPORT_WHEN_FALLING: false
+ NATURAL_SPAWNING_OUTSIDE_RANGE: true
ENTER_EXIT_MESSAGES: true
ENDERMAN_DEATH_DROP: true
OFFLINE_REDSTONE: true
+ OFFLINE_GROWTH: true
REMOVE_MOBS: true
ENDER_CHEST: false
ITEM_FRAME_DAMAGE: false
+ BOAT: true
# These are the default protection settings for new islands.
# The value is the minimum island rank required allowed to do the action
# Ranks are: Visitor = 0, Member = 900, Owner = 1000
default-island-flags:
HURT_ANIMALS: 500
+ DRAGON_EGG: 500
REDSTONE: 500
BUCKET: 500
LOCK: 0
@@ -152,42 +168,49 @@ world:
DOOR: 500
FURNACE: 500
ANVIL: 500
- FIRE: 500
+ MINECART: 500
FISH_SCOOPING: 500
END_PORTAL: 500
BREEDING: 500
HURT_VILLAGERS: 500
- TNT: 500
TURTLE_EGGS: 500
FROST_WALKER: 500
COLLECT_LAVA: 500
LEVER: 500
- HURT_MONSTERS: 0
+ ELYTRA: 0
RIDING: 500
- NAME_TAG: 500
+ HURT_MONSTERS: 0
+ CAKE: 500
ARMOR_STAND: 500
+ NAME_TAG: 500
TRADING: 0
EGGS: 500
ITEM_DROP: 0
NOTE_BLOCK: 0
+ FLINT_AND_STEEL: 500
NETHER_PORTAL: 500
CROP_TRAMPLE: 500
ITEM_PICKUP: 0
- DROPPER: 500
BREWING: 500
+ DROPPER: 500
+ TNT_PRIMING: 500
COLLECT_WATER: 500
BUTTON: 500
FIRE_EXTINGUISH: 500
+ COMMAND_RANKS: 500
BEACON: 500
TRAPDOOR: 500
+ EXPERIENCE_BOTTLE_THROWING: 500
PRESSURE_PLATE: 0
- PLACE_BLOCKS: 500
+ DYE: 500
ITEM_FRAME: 500
+ PLACE_BLOCKS: 500
CRAFTING: 0
- SHEARING: 500
ENCHANTING: 0
- BED: 500
+ SHEARING: 500
+ BOAT: 500
SPAWN_EGGS: 500
+ BED: 500
MILKING: 0
DISPENSER: 500
GATE: 0
@@ -199,21 +222,31 @@ world:
CHORUS_FRUIT: 500
CONTAINER: 500
JUKEBOX: 500
+ POTION_THROWING: 500
# These are the default settings for new islands
default-island-settings:
PVP_END: false
ANIMAL_SPAWN: true
PVP_NETHER: false
+ LEAF_DECAY: true
+ TNT_DAMAGE: true
+ FIRE_IGNITE: true
MONSTER_SPAWN: true
FIRE_SPREAD: true
+ FIRE_BURNING: true
PVP_OVERWORLD: false
# These settings/flags are hidden from users
# Ops can toggle hiding in-game using SHIFT-LEFT-CLICK on flags in settings
hidden-flags: []
# Visitor banned commands - Visitors to islands cannot use these commands in this world
visitor-banned-commands:
- - spawner
- - spawnmob
+ - spawner
+ - spawnmob
+ # Falling banned commands - players cannot use these commands when falling
+ # if the PREVENT_TELEPORT_WHEN_FALLING world setting flag is active
+ falling-banned-commands:
+ - warp
+ - spawn
island:
# Default max team size
# Use this permission to set for specific user groups: acidisland.team.maxsize.
@@ -223,14 +256,6 @@ island:
# Accessed via /ai sethome or /ai go
# Use this permission to set for specific user groups: acidisland.island.maxhomes.
max-homes: 1
- name:
- # Island naming
- # Only players with the TODO can name their island
- # It is displayed in the top ten and enter and exit announcements
- # It replaces the owner's name. Players can use & for color coding if they have the TODO permission
- # These set the minimum and maximum size of a name.
- min-length: 4
- max-length: 20
reset:
# How many resets a player is allowed (override with /acid clearresets )
# Value of -1 means unlimited, 0 means hardcore - no resets.
@@ -246,7 +271,7 @@ island:
# Overrides the on-leave inventory reset for kicked players.
kicked-keep-inventory: false
on-join:
- # What the addon should reset when the player joins or creates an island
+ # What the plugin should reset when the player joins or creates an island
# Reset Money - if this is true, will reset the player's money to the starting money
# Recommendation is that this is set to true, but if you run multi-worlds
# make sure your economy handles multi-worlds too.
@@ -281,10 +306,42 @@ island:
exp: false
# Reset Ender Chest - if true, the player's Ender Chest will be cleared.
ender-chest: false
+ create-island-on-first-login:
+ # Toggles the automatic island creation upon the player's first login on your server.
+ # If set to true,
+ # * Upon connecting to your server for the first time, the player will be told that
+ # an island will be created for him.
+ # * Make sure you have a Blueprint Bundle called "default": this is the one that will
+ # be used to create the island.
+ # * An island will be created for the player without needing him to run the create command.
+ # If set to false, this will disable this feature entirely.
+ # Warning:
+ # * If you are running multiple gamemodes on your server, and all of them have
+ # this feature enabled, an island in all the gamemodes will be created simultaneously.
+ # However, it is impossible to know on which island the player will be teleported to afterwards.
+ # * Island creation can be resource-intensive, please consider the options below to help mitigate
+ # the potential issues, especially if you expect a lot of players to connect to your server
+ # in a limited period of time.
+ enable: false
+ # Time in seconds after the player logged in, before his island gets created.
+ # If set to 0 or less, the island will be created directly upon the player's login.
+ # It is recommended to keep this value under a minute's time.
+ delay: 5
+ # Toggles whether the island creation should be aborted if the player logged off while the
+ # delay (see the option above) has not worn off yet.
+ # If set to true,
+ # * If the player has logged off the server while the delay (see the option above) has not
+ # worn off yet, this will cancel the island creation.
+ # * If the player relogs afterward, since he will not be recognized as a new player, no island
+ # would be created for him.
+ # * If the island creation started before the player logged off, it will continue.
+ # If set to false, the player's island will be created even if he went offline in the meantime.
+ # Note this option has no effect if the delay (see the option above) is set to 0 or less.
+ abort-on-logout: true
commands:
# List of commands to run when a player joins.
on-join: []
- # List of commands to run when a player leaves.
+ # list of commands to run when a player leaves.
on-leave: []
sethome:
nether:
@@ -310,31 +367,30 @@ protection:
# Invincible visitors. List of damages that will not affect visitors.
# Make list blank if visitors should receive all damages
invincible-visitors:
- - BLOCK_EXPLOSION
- - CONTACT
- - CUSTOM
- - DROWNING
- - ENTITY_ATTACK
- - ENTITY_EXPLOSION
- - FALL
- - FALLING_BLOCK
- - FIRE
- - FIRE_TICK
- - LAVA
- - LIGHTNING
- - MAGIC
- - POISON
- - PROJECTILE
- - STARVATION
- - SUFFOCATION
- - THORNS
- - WITHER
- - DRAGON_BREATH
- - FLY_INTO_WALL
- - HOT_FLOOR
- - CRAMMING
- - VOID
+ - BLOCK_EXPLOSION
+ - CONTACT
+ - CUSTOM
+ - DROWNING
+ - ENTITY_ATTACK
+ - ENTITY_EXPLOSION
+ - FALL
+ - FALLING_BLOCK
+ - FIRE
+ - FIRE_TICK
+ - LAVA
+ - LIGHTNING
+ - MAGIC
+ - POISON
+ - PROJECTILE
+ - STARVATION
+ - SUFFOCATION
+ - THORNS
+ - WITHER
+ - DRAGON_BREATH
+ - FLY_INTO_WALL
+ - HOT_FLOOR
+ - CRAMMING
+ - VOID
do-not-edit-these-settings:
# These settings should not be edited
reset-epoch: 0
-uniqueId: config
diff --git a/src/main/resources/locales/hu.yml b/src/main/resources/locales/hu.yml
new file mode 100644
index 0000000..e4551c9
--- /dev/null
+++ b/src/main/resources/locales/hu.yml
@@ -0,0 +1,12 @@
+###########################################################################################
+# 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 #
+###########################################################################################
+
+acidisland:
+ sign:
+ line0: "&2SavSziget"
+ line1: "[name]"
+ line2: "A víz savas!"
+ line3: "Légy óvatos! &d<3"
+
diff --git a/src/main/resources/locales/pl.yml b/src/main/resources/locales/pl.yml
new file mode 100644
index 0000000..a760e9b
--- /dev/null
+++ b/src/main/resources/locales/pl.yml
@@ -0,0 +1,7 @@
+---
+acidisland:
+ sign:
+ line0: "&1AcidIsland"
+ line1: "[name]"
+ line3: 'Bądź ostrożny! '
+ line2: Woda jest kwaśna!
diff --git a/src/test/java/world/bentobox/acidisland/world/ChunkGeneratorWorldTest.java b/src/test/java/world/bentobox/acidisland/world/ChunkGeneratorWorldTest.java
new file mode 100644
index 0000000..79e2846
--- /dev/null
+++ b/src/test/java/world/bentobox/acidisland/world/ChunkGeneratorWorldTest.java
@@ -0,0 +1,192 @@
+package world.bentobox.acidisland.world;
+
+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.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Random;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.Server;
+import org.bukkit.World;
+import org.bukkit.generator.ChunkGenerator.BiomeGrid;
+import org.bukkit.generator.ChunkGenerator.ChunkData;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import world.bentobox.acidisland.AcidIsland;
+import world.bentobox.acidisland.AISettings;
+
+/**
+ * @author tastybento
+ *
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Bukkit.class})
+public class ChunkGeneratorWorldTest {
+
+ @Mock
+ private AcidIsland addon;
+ private ChunkGeneratorWorld cg;
+ @Mock
+ private World world;
+ private final Random random = new Random();
+ @Mock
+ private BiomeGrid biomeGrid;
+ @Mock
+ private AISettings settings;
+ @Mock
+ private ChunkData data;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ // Bukkit
+ PowerMockito.mockStatic(Bukkit.class);
+ Server server = mock(Server.class);
+ when(server.createChunkData(any())).thenReturn(data);
+ when(Bukkit.getServer()).thenReturn(server);
+ // World
+ when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
+ // Settings
+ when(addon.getSettings()).thenReturn(settings);
+ when(settings.getSeaHeight()).thenReturn(0);
+ when(settings.isNetherRoof()).thenReturn(true);
+
+ // Instance
+ cg = new ChunkGeneratorWorld(addon);
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bskyblock.generators.ChunkGeneratorWorld#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)}.
+ */
+ @Test
+ public void testGenerateChunkDataWorldRandomIntIntBiomeGridOverworldVoid() {
+ ChunkData cd = cg.generateChunkData(world, random, 0 , 0 , biomeGrid);
+ assertEquals(data, cd);
+ // Verifications
+ // Default biome
+ verify(settings).getDefaultBiome();
+ verify(biomeGrid, times(16 * 16)).setBiome(anyInt(), anyInt(), any());
+ // Sea height
+ verify(settings).getSeaHeight();
+ // Void
+ verify(cd, never()).setRegion(anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(Material.class));
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bskyblock.generators.ChunkGeneratorWorld#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)}.
+ */
+ @Test
+ public void testGenerateChunkDataWorldRandomIntIntBiomeGridOverworldSea() {
+ // Set sea height
+ when(settings.getSeaHeight()).thenReturn(10);
+ // new instance
+ cg = new ChunkGeneratorWorld(addon);
+ ChunkData cd = cg.generateChunkData(world, random, 0 , 0 , biomeGrid);
+ assertEquals(data, cd);
+ // Verifications
+ // Default biome
+ verify(settings).getDefaultBiome();
+ verify(biomeGrid, times(16 * 16)).setBiome(anyInt(), anyInt(), any());
+ // Sea height
+ verify(settings, times(2)).getSeaHeight();
+ // Water. Blocks = 16 x 16 x 11 because block 0
+ verify(cd).setRegion(0, 0, 0, 16, 11, 16, Material.WATER);
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bskyblock.generators.ChunkGeneratorWorld#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)}.
+ */
+ @Test
+ public void testGenerateChunkDataWorldRandomIntIntBiomeGridEnd() {
+ when(world.getEnvironment()).thenReturn(World.Environment.THE_END);
+ ChunkData cd = cg.generateChunkData(world, random, 0 , 0 , biomeGrid);
+ assertEquals(data, cd);
+ // Verifications
+ // Default biome
+ verify(settings, never()).getDefaultBiome();
+ // Never set biome in end
+ verify(biomeGrid, never()).setBiome(anyInt(), anyInt(), any());
+ // Sea height
+ verify(settings).getSeaHeight();
+ // Void
+ verify(cd, never()).setRegion(anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(Material.class));
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bskyblock.generators.ChunkGeneratorWorld#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)}.
+ */
+ @Test
+ public void testGenerateChunkDataWorldRandomIntIntBiomeGridNetherWithRoof() {
+ when(world.getEnvironment()).thenReturn(World.Environment.NETHER);
+ ChunkData cd = cg.generateChunkData(world, random, 0 , 0 , biomeGrid);
+ assertEquals(data, cd);
+ // Verifications
+ // Nether roof check
+ verify(settings).isNetherRoof();
+ // Never set biome in nether
+ verify(biomeGrid, never()).setBiome(anyInt(), anyInt(), any());
+ // Nether roof - at least bedrock layer
+ verify(cd, atLeast(16 * 16)).setBlock(anyInt(), anyInt(), anyInt(), eq(Material.BEDROCK));
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bskyblock.generators.ChunkGeneratorWorld#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)}.
+ */
+ @Test
+ public void testGenerateChunkDataWorldRandomIntIntBiomeGridNetherNoRoof() {
+ when(settings.isNetherRoof()).thenReturn(false);
+ when(world.getEnvironment()).thenReturn(World.Environment.NETHER);
+ ChunkData cd = cg.generateChunkData(world, random, 0 , 0 , biomeGrid);
+ assertEquals(data, cd);
+ // Verifications
+ // Nether roof check
+ verify(settings).isNetherRoof();
+ // Never set biome in nether
+ verify(biomeGrid, never()).setBiome(anyInt(), anyInt(), any());
+ // Nether roof - at least bedrock layer
+ verify(cd, never()).setBlock(anyInt(), anyInt(), anyInt(), any(Material.class));
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bskyblock.generators.ChunkGeneratorWorld#canSpawn(org.bukkit.World, int, int)}.
+ */
+ @Test
+ public void testCanSpawnWorldIntInt() {
+ assertTrue(cg.canSpawn(mock(World.class), 0, 1));
+ }
+
+ /**
+ * Test method for {@link world.bentobox.bskyblock.generators.ChunkGeneratorWorld#getDefaultPopulators(org.bukkit.World)}.
+ */
+ @Test
+ public void testGetDefaultPopulatorsWorld() {
+ assertTrue(cg.getDefaultPopulators(mock(World.class)).isEmpty());
+ }
+
+}