mirror of
https://github.com/BentoBoxWorld/CaveBlock.git
synced 2024-11-22 11:35:11 +01:00
Merge changes from development branch.
This commit is contained in:
commit
7ed07f48f4
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,3 +21,4 @@
|
|||||||
|
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
hs_err_pid*
|
hs_err_pid*
|
||||||
|
/target/
|
||||||
|
@ -13,222 +13,228 @@ import world.bentobox.bentobox.api.configuration.WorldSettings;
|
|||||||
import world.bentobox.caveblock.commands.AdminCommand;
|
import world.bentobox.caveblock.commands.AdminCommand;
|
||||||
import world.bentobox.caveblock.commands.IslandCommand;
|
import world.bentobox.caveblock.commands.IslandCommand;
|
||||||
import world.bentobox.caveblock.generators.ChunkGeneratorWorld;
|
import world.bentobox.caveblock.generators.ChunkGeneratorWorld;
|
||||||
|
import world.bentobox.caveblock.listeners.BeaconEnabler;
|
||||||
|
import world.bentobox.caveblock.listeners.CustomHeightLimitations;
|
||||||
|
|
||||||
|
|
||||||
public class CaveBlock extends GameModeAddon
|
public class CaveBlock extends GameModeAddon
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Executes code when loading the addon. This is called before {@link #onEnable()}. This should preferably
|
* Executes code when loading the addon. This is called before {@link #onEnable()}. This should preferably
|
||||||
* be used to setup configuration and worlds.
|
* be used to setup configuration and worlds.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onLoad()
|
public void onLoad()
|
||||||
{
|
{
|
||||||
super.onLoad();
|
super.onLoad();
|
||||||
|
|
||||||
this.saveDefaultConfig();
|
this.saveDefaultConfig();
|
||||||
this.loadSettings();
|
this.loadSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes code when enabling the addon. This is called after {@link #onLoad()}.
|
* Executes code when enabling the addon. This is called after {@link #onLoad()}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onEnable()
|
public void onEnable()
|
||||||
{
|
{
|
||||||
this.playerCommand = new IslandCommand(this);
|
this.playerCommand = new IslandCommand(this);
|
||||||
this.adminCommand = new AdminCommand(this);
|
this.adminCommand = new AdminCommand(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes code when reloading the addon.
|
* Executes code when reloading the addon.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onReload()
|
public void onReload()
|
||||||
{
|
{
|
||||||
super.onReload();
|
super.onReload();
|
||||||
this.loadSettings();
|
this.loadSettings();
|
||||||
}
|
this.chunkGenerator.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes code when disabling the addon.
|
* Executes code when disabling the addon.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onDisable()
|
public void onDisable()
|
||||||
{
|
{
|
||||||
if (this.settings != null)
|
if (this.settings != null)
|
||||||
{
|
{
|
||||||
new Config<>(this, Settings.class).saveConfigObject(this.settings);
|
new Config<>(this, Settings.class).saveConfigObject(this.settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method loads CaveBlock settings
|
* This method loads CaveBlock settings
|
||||||
*/
|
*/
|
||||||
private void loadSettings()
|
private void loadSettings()
|
||||||
{
|
{
|
||||||
this.settings = new Config<>(this, Settings.class).loadConfigObject();
|
this.settings = new Config<>(this, Settings.class).loadConfigObject();
|
||||||
|
|
||||||
if (this.settings == null)
|
if (this.settings == null)
|
||||||
{
|
{
|
||||||
// Disable
|
// Disable
|
||||||
this.logError("CaveBlock settings could not load! Addon disabled.");
|
this.logError("CaveBlock settings could not load! Addon disabled.");
|
||||||
this.setState(State.DISABLED);
|
this.setState(State.DISABLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Section: World generators
|
// Section: World generators
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the worlds for this GameMode in this method. BentoBox will call it after onLoad() and before
|
* Make the worlds for this GameMode in this method. BentoBox will call it after onLoad() and before
|
||||||
* onEnable(). {@link #islandWorld} must be created and assigned, {@link #netherWorld} and {@link
|
* onEnable(). {@link #islandWorld} must be created and assigned, {@link #netherWorld} and {@link
|
||||||
* #endWorld} are optional and may be null.
|
* #endWorld} are optional and may be null.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void createWorlds()
|
public void createWorlds()
|
||||||
{
|
{
|
||||||
String worldName = this.settings.getWorldName();
|
String worldName = this.settings.getWorldName();
|
||||||
|
|
||||||
if (this.getServer().getWorld(worldName) == null)
|
if (this.getServer().getWorld(worldName) == null)
|
||||||
{
|
{
|
||||||
this.getLogger().info("Creating CaveBlock world ...");
|
this.getLogger().info("Creating CaveBlock world ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chunkGenerator = new ChunkGeneratorWorld(this);
|
this.chunkGenerator = new ChunkGeneratorWorld(this);
|
||||||
|
|
||||||
// Create the world if it does not exist
|
// Create the world if it does not exist
|
||||||
this.islandWorld = WorldCreator.name(worldName).
|
this.islandWorld = WorldCreator.name(worldName).
|
||||||
type(WorldType.FLAT).
|
type(WorldType.FLAT).
|
||||||
environment(World.Environment.NORMAL).
|
environment(World.Environment.NORMAL).
|
||||||
generator(new ChunkGeneratorWorld(this)).
|
generator(this.chunkGenerator).
|
||||||
createWorld();
|
createWorld();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Make the nether if it does not exist
|
// Make the nether if it does not exist
|
||||||
if (this.settings.isNetherGenerate())
|
if (this.settings.isNetherGenerate())
|
||||||
{
|
{
|
||||||
if (this.getServer().getWorld(worldName + NETHER) == null)
|
if (this.getServer().getWorld(worldName + NETHER) == null)
|
||||||
{
|
{
|
||||||
this.log("Creating CaveBlock's Nether...");
|
this.log("Creating CaveBlock's Nether...");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.settings.isNetherIslands())
|
if (!this.settings.isNetherIslands())
|
||||||
{
|
{
|
||||||
this.netherWorld = WorldCreator.name(worldName + NETHER).
|
this.netherWorld = WorldCreator.name(worldName + NETHER).
|
||||||
type(WorldType.NORMAL).
|
type(WorldType.NORMAL).
|
||||||
environment(World.Environment.NETHER).
|
environment(World.Environment.NETHER).
|
||||||
createWorld();
|
createWorld();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.netherWorld = WorldCreator.name(worldName + NETHER).
|
this.netherWorld = WorldCreator.name(worldName + NETHER).
|
||||||
type(WorldType.FLAT).
|
type(WorldType.FLAT).
|
||||||
generator(new ChunkGeneratorWorld(this)).
|
generator(this.chunkGenerator).
|
||||||
environment(World.Environment.NETHER).
|
environment(World.Environment.NETHER).
|
||||||
createWorld();
|
createWorld();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the end if it does not exist
|
// Make the end if it does not exist
|
||||||
if (this.settings.isEndGenerate())
|
if (this.settings.isEndGenerate())
|
||||||
{
|
{
|
||||||
if (this.getServer().getWorld(worldName + THE_END) == null)
|
if (this.getServer().getWorld(worldName + THE_END) == null)
|
||||||
{
|
{
|
||||||
this.log("Creating CaveBlock's End World...");
|
this.log("Creating CaveBlock's End World...");
|
||||||
}
|
}
|
||||||
if (!this.settings.isEndIslands())
|
if (!this.settings.isEndIslands())
|
||||||
{
|
{
|
||||||
this.endWorld = WorldCreator.name(worldName + THE_END).
|
this.endWorld = WorldCreator.name(worldName + THE_END).
|
||||||
type(WorldType.NORMAL).
|
type(WorldType.NORMAL).
|
||||||
environment(World.Environment.THE_END).
|
environment(World.Environment.THE_END).
|
||||||
createWorld();
|
createWorld();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.endWorld = WorldCreator.name(worldName + THE_END).
|
this.endWorld = WorldCreator.name(worldName + THE_END).
|
||||||
type(WorldType.FLAT).
|
type(WorldType.FLAT).
|
||||||
generator(new ChunkGeneratorWorld(this)).
|
generator(this.chunkGenerator).
|
||||||
environment(World.Environment.THE_END).
|
environment(World.Environment.THE_END).
|
||||||
createWorld();
|
createWorld();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
this.getServer().getPluginManager().registerEvents(new CustomHeightLimitations(this), this.getPlugin());
|
||||||
|
this.getServer().getPluginManager().registerEvents(new BeaconEnabler(this), this.getPlugin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the world generator for this game mode
|
* Defines the world generator for this game mode
|
||||||
*
|
*
|
||||||
* @param worldName - name of world that this applies to
|
* @param worldName - name of world that this applies to
|
||||||
* @param id - id if any
|
* @param id - id if any
|
||||||
* @return Chunk generator
|
* @return Chunk generator
|
||||||
* @since 1.2.0
|
* @since 1.2.0
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
public @NonNull ChunkGenerator getDefaultWorldGenerator(String worldName, String id)
|
||||||
{
|
{
|
||||||
return this.chunkGenerator;
|
return this.chunkGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Section: Getters
|
// Section: Getters
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return WorldSettings for this GameMode
|
* @return WorldSettings for this GameMode
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public WorldSettings getWorldSettings()
|
public WorldSettings getWorldSettings()
|
||||||
{
|
{
|
||||||
return this.settings;
|
return this.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Settings for this GameMode
|
* @return Settings for this GameMode
|
||||||
*/
|
*/
|
||||||
public Settings getSettings()
|
public Settings getSettings()
|
||||||
{
|
{
|
||||||
return this.settings;
|
return this.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Section: Variables
|
// Section: Variables
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This stores CaveBlock addon settings.
|
* This stores CaveBlock addon settings.
|
||||||
*/
|
*/
|
||||||
private Settings settings;
|
private Settings settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This stores CaveBlock addon WorldGenerator.
|
* This stores CaveBlock addon WorldGenerator.
|
||||||
*/
|
*/
|
||||||
private ChunkGeneratorWorld chunkGenerator;
|
private ChunkGeneratorWorld chunkGenerator;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Section: Constants
|
// Section: Constants
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String for nether world.
|
* String for nether world.
|
||||||
*/
|
*/
|
||||||
private static final String NETHER = "_nether";
|
private static final String NETHER = "_nether";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String for the end world.
|
* String for the end world.
|
||||||
*/
|
*/
|
||||||
private static final String THE_END = "_the_end";
|
private static final String THE_END = "_the_end";
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,14 @@
|
|||||||
package world.bentobox.caveblock.generators;
|
package world.bentobox.caveblock.generators;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import world.bentobox.caveblock.CaveBlock;
|
import world.bentobox.caveblock.CaveBlock;
|
||||||
import world.bentobox.caveblock.Settings;
|
import world.bentobox.caveblock.Settings;
|
||||||
@ -21,190 +24,199 @@ import world.bentobox.caveblock.generators.populators.MaterialPopulator;
|
|||||||
*/
|
*/
|
||||||
public class ChunkGeneratorWorld extends ChunkGenerator
|
public class ChunkGeneratorWorld extends ChunkGenerator
|
||||||
{
|
{
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Section: Constructor
|
// Section: Constructor
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param addon - CaveBlock object
|
* @param addon - CaveBlock object
|
||||||
*/
|
*/
|
||||||
public ChunkGeneratorWorld(CaveBlock addon)
|
public ChunkGeneratorWorld(CaveBlock addon)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.addon = addon;
|
this.addon = addon;
|
||||||
this.settings = addon.getSettings();
|
this.settings = addon.getSettings();
|
||||||
|
|
||||||
this.blockPopulators = new ArrayList<>(1);
|
reload();
|
||||||
|
}
|
||||||
this.blockPopulators.add(new MaterialPopulator(this.addon));
|
|
||||||
this.blockPopulators.add(new EntitiesPopulator(this.addon));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Section: Methods
|
// Section: Methods
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets if given coordinates can be set as spawn location
|
* This method sets if given coordinates can be set as spawn location
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canSpawn(World world, int x, int z)
|
public boolean canSpawn(World world, int x, int z)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method generates given chunk.
|
* This method generates given chunk.
|
||||||
* @param world World where chunk must be generated.
|
* @param world World where chunk must be generated.
|
||||||
* @param random Random that allows define object randomness.
|
* @param random Random that allows define object randomness.
|
||||||
* @param chunkX Chunk X coordinate.
|
* @param chunkX Chunk X coordinate.
|
||||||
* @param chunkZ Chunk Z coordinate.
|
* @param chunkZ Chunk Z coordinate.
|
||||||
* @param biomeGrid BiomeGrid that contains biomes.
|
* @param biomeGrid BiomeGrid that contains biomes.
|
||||||
* @return new ChunkData for given chunk.
|
* @return new ChunkData for given chunk.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ChunkData generateChunkData(World world,
|
public ChunkData generateChunkData(World world,
|
||||||
Random random,
|
Random random,
|
||||||
int chunkX,
|
int chunkX,
|
||||||
int chunkZ,
|
int chunkZ,
|
||||||
ChunkGenerator.BiomeGrid biomeGrid)
|
ChunkGenerator.BiomeGrid biomeGrid)
|
||||||
{
|
{
|
||||||
ChunkData result = this.createChunkData(world);
|
ChunkData result = this.createChunkData(world);
|
||||||
|
|
||||||
// Populate chunk with necessary information
|
// Populate chunk with necessary information
|
||||||
if (world.getEnvironment().equals(World.Environment.NETHER))
|
if (world.getEnvironment().equals(World.Environment.NETHER))
|
||||||
{
|
{
|
||||||
this.populateNetherChunk(result);
|
this.populateNetherChunk(result);
|
||||||
}
|
}
|
||||||
else if (world.getEnvironment().equals(World.Environment.THE_END))
|
else if (world.getEnvironment().equals(World.Environment.THE_END))
|
||||||
{
|
{
|
||||||
this.populateTheEndChunk(result);
|
this.populateTheEndChunk(result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.populateOverWorldChunk(result, biomeGrid);
|
this.populateOverWorldChunk(result, biomeGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method populates The End world chunk data.
|
* This method populates The End world chunk data.
|
||||||
* @param chunkData ChunkData that must be populated.
|
* @param chunkData ChunkData that must be populated.
|
||||||
*/
|
*/
|
||||||
private void populateTheEndChunk(ChunkData chunkData)
|
private void populateTheEndChunk(ChunkData chunkData)
|
||||||
{
|
{
|
||||||
// because everything starts at 0 and ends at 255
|
// because everything starts at 0 and ends at 255
|
||||||
final int worldHeight = this.settings.getWorldDepth();
|
final int worldHeight = this.settings.getWorldDepth();
|
||||||
|
|
||||||
// Fill all blocks
|
// Fill all blocks
|
||||||
chunkData.setRegion(0, 1, 0,
|
chunkData.setRegion(0, 1, 0,
|
||||||
16, worldHeight - 1, 16,
|
16, worldHeight - 1, 16,
|
||||||
this.settings.getEndMainBlock());
|
this.settings.getEndMainBlock());
|
||||||
|
|
||||||
// Generate ground and ceiling.
|
// Generate ground and ceiling.
|
||||||
chunkData.setRegion(0, 0, 0,
|
chunkData.setRegion(0, 0, 0,
|
||||||
16, 1, 16,
|
16, 1, 16,
|
||||||
this.settings.isEndFloor() ? Material.BEDROCK : this.settings.getEndMainBlock());
|
this.settings.isEndFloor() ? Material.BEDROCK : this.settings.getEndMainBlock());
|
||||||
chunkData.setRegion(0, worldHeight - 1, 0,
|
chunkData.setRegion(0, worldHeight - 1, 0,
|
||||||
16, worldHeight, 16,
|
16, worldHeight, 16,
|
||||||
this.settings.isEndRoof() ? Material.BEDROCK : this.settings.getEndMainBlock());
|
this.settings.isEndRoof() ? Material.BEDROCK : this.settings.getEndMainBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method populates nether world chunk data.
|
* This method populates nether world chunk data.
|
||||||
* @param chunkData ChunkData that must be populated.
|
* @param chunkData ChunkData that must be populated.
|
||||||
*/
|
*/
|
||||||
private void populateNetherChunk(ChunkData chunkData)
|
private void populateNetherChunk(ChunkData chunkData)
|
||||||
{
|
{
|
||||||
// because everything starts at 0 and ends at 255
|
// because everything starts at 0 and ends at 255
|
||||||
final int worldHeight = this.settings.getWorldDepth();
|
final int worldHeight = this.settings.getWorldDepth();
|
||||||
|
|
||||||
// Fill all blocks
|
// Fill all blocks
|
||||||
chunkData.setRegion(0, 1, 0,
|
chunkData.setRegion(0, 1, 0,
|
||||||
16, worldHeight - 1, 16,
|
16, worldHeight - 1, 16,
|
||||||
this.settings.getNetherMainBlock());
|
this.settings.getNetherMainBlock());
|
||||||
|
|
||||||
// Generate ground and ceiling.
|
// Generate ground and ceiling.
|
||||||
chunkData.setRegion(0, 0, 0,
|
chunkData.setRegion(0, 0, 0,
|
||||||
16, 1, 16,
|
16, 1, 16,
|
||||||
this.settings.isNetherFloor() ? Material.BEDROCK : this.settings.getNetherMainBlock());
|
this.settings.isNetherFloor() ? Material.BEDROCK : this.settings.getNetherMainBlock());
|
||||||
chunkData.setRegion(0, worldHeight - 1, 0,
|
chunkData.setRegion(0, worldHeight - 1, 0,
|
||||||
16, worldHeight, 16,
|
16, worldHeight, 16,
|
||||||
this.settings.isNetherRoof() ? Material.BEDROCK : this.settings.getNetherMainBlock());
|
this.settings.isNetherRoof() ? Material.BEDROCK : this.settings.getNetherMainBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method populates Over world chunk data.
|
* This method populates Over world chunk data.
|
||||||
* @param chunkData ChunkData that must be populated.
|
* @param chunkData ChunkData that must be populated.
|
||||||
* @param biomeGrid BiomeGrid for this chunk.
|
* @param biomeGrid BiomeGrid for this chunk.
|
||||||
*/
|
*/
|
||||||
private void populateOverWorldChunk(ChunkData chunkData, BiomeGrid biomeGrid)
|
private void populateOverWorldChunk(ChunkData chunkData, BiomeGrid biomeGrid)
|
||||||
{
|
{
|
||||||
// because everything starts at 0 and ends at 255
|
// because everything starts at 0 and ends at 255
|
||||||
final int worldHeight = this.settings.getWorldDepth();
|
final int worldHeight = this.settings.getWorldDepth();
|
||||||
|
|
||||||
// Fill all blocks
|
// Fill all blocks
|
||||||
chunkData.setRegion(0, 1, 0,
|
chunkData.setRegion(0, 1, 0,
|
||||||
16, worldHeight - 1, 16,
|
16, worldHeight - 1, 16,
|
||||||
this.settings.getNormalMainBlock());
|
this.settings.getNormalMainBlock());
|
||||||
|
|
||||||
// Generate ground and ceiling.
|
// Generate ground and ceiling.
|
||||||
chunkData.setRegion(0, 0, 0,
|
chunkData.setRegion(0, 0, 0,
|
||||||
16, 1, 16,
|
16, 1, 16,
|
||||||
this.settings.isNormalFloor() ? Material.BEDROCK : this.settings.getNormalMainBlock());
|
this.settings.isNormalFloor() ? Material.BEDROCK : this.settings.getNormalMainBlock());
|
||||||
chunkData.setRegion(0, worldHeight - 1, 0,
|
chunkData.setRegion(0, worldHeight - 1, 0,
|
||||||
16, worldHeight, 16,
|
16, worldHeight, 16,
|
||||||
this.settings.isNormalRoof() ? Material.BEDROCK : this.settings.getNormalMainBlock());
|
this.settings.isNormalRoof() ? Material.BEDROCK : this.settings.getNormalMainBlock());
|
||||||
|
|
||||||
// Set biome
|
// Set biome
|
||||||
for (int x = 0; x < 16; x++)
|
for (int x = 0; x < 16; x++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z < 16; z++)
|
for (int z = 0; z < 16; z++)
|
||||||
{
|
{
|
||||||
biomeGrid.setBiome(x, z, this.settings.getDefaultBiome());
|
biomeGrid.setBiome(x, z, this.settings.getDefaultBiome());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method set world block populators.
|
* This method set world block populators.
|
||||||
* @param world World where this must apply.
|
* @param world World where this must apply.
|
||||||
* @return List with block populators.
|
* @return List with block populators.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<BlockPopulator> getDefaultPopulators(final World world)
|
public List<BlockPopulator> getDefaultPopulators(final World world)
|
||||||
{
|
{
|
||||||
return this.blockPopulators;
|
return this.blockPopulators;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when config is reloaded
|
||||||
|
*/
|
||||||
|
public void reload() {
|
||||||
|
this.blockPopulators = new ArrayList<>(2);
|
||||||
|
|
||||||
|
this.blockPopulators.add(new MaterialPopulator(this.addon));
|
||||||
|
this.blockPopulators.add(new EntitiesPopulator(this.addon));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Variables
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
/**
|
||||||
// Section: Variables
|
* CaveBlock addon.
|
||||||
// ---------------------------------------------------------------------
|
*/
|
||||||
|
private CaveBlock addon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Addon settings.
|
||||||
|
*/
|
||||||
|
private Settings settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This list contains block populators that will be applied after chunk is generated.
|
||||||
|
*/
|
||||||
|
private List<BlockPopulator> blockPopulators;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CaveBlock addon.
|
|
||||||
*/
|
|
||||||
private CaveBlock addon;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Addon settings.
|
|
||||||
*/
|
|
||||||
private Settings settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This list contains block populators that will be applied after chunk is generated.
|
|
||||||
*/
|
|
||||||
private List<BlockPopulator> blockPopulators;
|
|
||||||
}
|
}
|
||||||
|
@ -1,272 +1,200 @@
|
|||||||
package world.bentobox.caveblock.generators.populators;
|
package world.bentobox.caveblock.generators.populators;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import java.util.*;
|
import org.bukkit.util.BoundingBox;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import world.bentobox.bentobox.util.Pair;
|
import world.bentobox.bentobox.util.Pair;
|
||||||
import world.bentobox.caveblock.CaveBlock;
|
import world.bentobox.caveblock.CaveBlock;
|
||||||
import world.bentobox.caveblock.Settings;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class populates generated chunk with enitites by random chance.
|
* This class populates generated chunk with entites by random chance.
|
||||||
*/
|
*/
|
||||||
public class EntitiesPopulator extends BlockPopulator
|
public class EntitiesPopulator extends BlockPopulator
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* This is default constructor
|
/**
|
||||||
* @param addon CaveBlock addon.
|
* This is default constructor
|
||||||
*/
|
* @param addon CaveBlock addon.
|
||||||
public EntitiesPopulator(CaveBlock addon)
|
*/
|
||||||
{
|
public EntitiesPopulator(CaveBlock addon)
|
||||||
this.addon = addon;
|
{
|
||||||
this.settings = addon.getSettings();
|
this.addon = addon;
|
||||||
}
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
public void loadSettings() {
|
||||||
* This method populates chunk with entities.
|
// Set up chances
|
||||||
* @param world World where population must be.
|
chances = new HashMap<>();
|
||||||
* @param random Randomness
|
// Normal
|
||||||
* @param chunk Chunk were populator operates.
|
chances.put(Environment.NORMAL, new Chances(this.getEntityMap(addon.getSettings().getNormalBlocks()), addon.getSettings().getNormalMainBlock()));
|
||||||
*/
|
// Nether
|
||||||
@Override
|
chances.put(Environment.NETHER, new Chances(this.getEntityMap(addon.getSettings().getNetherBlocks()), addon.getSettings().getNetherMainBlock()));
|
||||||
public void populate(World world, Random random, Chunk chunk)
|
// End
|
||||||
{
|
chances.put(Environment.THE_END, new Chances(this.getEntityMap(addon.getSettings().getEndBlocks()), addon.getSettings().getEndMainBlock()));
|
||||||
Map<EntityType, Pair<Integer, Integer>> entityChanceMap;
|
// Other settings
|
||||||
Material mainMaterial;
|
worldHeight = addon.getSettings().getWorldDepth() - 1;
|
||||||
|
}
|
||||||
if (world.getEnvironment().equals(World.Environment.NETHER))
|
|
||||||
{
|
|
||||||
entityChanceMap = this.getEntityMap(this.settings.getNetherBlocks());
|
|
||||||
mainMaterial = this.settings.getNetherMainBlock();
|
|
||||||
}
|
|
||||||
else if (world.getEnvironment().equals(World.Environment.THE_END))
|
|
||||||
{
|
|
||||||
entityChanceMap = this.getEntityMap(this.settings.getEndBlocks());
|
|
||||||
mainMaterial = this.settings.getEndMainBlock();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entityChanceMap = this.getEntityMap(this.settings.getNormalBlocks());
|
|
||||||
mainMaterial = this.settings.getNormalMainBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int generationTry = this.settings.getNumberOfBlockGenerationTries();
|
|
||||||
final int worldHeight = this.settings.getWorldDepth() - 1;
|
|
||||||
|
|
||||||
for (Map.Entry<EntityType, Pair<Integer, Integer>> entry : entityChanceMap.entrySet())
|
|
||||||
{
|
|
||||||
for (int subY = 0; subY < worldHeight; subY += 16)
|
|
||||||
{
|
|
||||||
for (int tries = 0; tries < generationTry; tries++)
|
|
||||||
{
|
|
||||||
if (random.nextInt(100) < entry.getValue().x)
|
|
||||||
{
|
|
||||||
int x = random.nextInt(15);
|
|
||||||
int z = random.nextInt(15);
|
|
||||||
int y = Math.min(worldHeight - 2, subY + random.nextInt(15));
|
|
||||||
|
|
||||||
this.tryToPlaceEntity(world, chunk.getBlock(x, y, z), entry.getKey(), x, z, mainMaterial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns Entity frequently and pack size map.
|
* This method populates chunk with entities.
|
||||||
* @param objectList List with objects that contains data.
|
* @param world World where population must be.
|
||||||
* @return Map that contains entity, its rarity and pack size.
|
* @param random Randomness
|
||||||
*/
|
* @param chunk Chunk were populator operates.
|
||||||
private Map<EntityType, Pair<Integer, Integer>> getEntityMap(List<String> objectList)
|
*/
|
||||||
{
|
@Override
|
||||||
Map<EntityType, Pair<Integer, Integer>> entityMap = new HashMap<>(objectList.size());
|
public void populate(World world, Random random, Chunk chunk)
|
||||||
|
{
|
||||||
Map<String, EntityType> entityTypeMap = Arrays.stream(EntityType.values()).
|
for (Map.Entry<EntityType, Pair<Double, Integer>> entry : chances.get(world.getEnvironment()).entityChanceMap.entrySet())
|
||||||
collect(Collectors.toMap(Enum::name,
|
{
|
||||||
entityType -> entityType,
|
for (int subY = 0; subY < worldHeight; subY += 16)
|
||||||
(a, b) -> b,
|
{
|
||||||
() -> new HashMap<>(EntityType.values().length)));
|
// Use double so chance can be < 1
|
||||||
|
if (random.nextDouble() * 100 < entry.getValue().x)
|
||||||
// wrong material object.
|
{
|
||||||
objectList.stream().
|
int y = Math.min(worldHeight - 2, subY + random.nextInt(15));
|
||||||
filter(object -> object.startsWith("ENTITY")).
|
// Spawn only in middle of chunk because bounding box will grow out from here
|
||||||
map(object -> object.split(":")).
|
this.tryToPlaceEntity(world, chunk.getBlock(7, y, 7), entry.getKey(), chances.get(world.getEnvironment()).mainMaterial);
|
||||||
filter(splitString -> splitString.length == 4).
|
}
|
||||||
forEach(splitString -> {
|
}
|
||||||
EntityType entity = entityTypeMap.getOrDefault(splitString[1], null);
|
}
|
||||||
|
}
|
||||||
if (entity != null)
|
|
||||||
{
|
|
||||||
entityMap.put(entity,
|
|
||||||
new Pair<>(Integer.parseInt(splitString[2]), Integer.parseInt(splitString[3])));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return entityMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks if all chunks around given block is generated.
|
* This method returns Entity frequently and pack size map.
|
||||||
* @param world World in which block is located
|
* @param objectList List with objects that contains data.
|
||||||
* @param block Block that must be checked.
|
* @return Map that contains entity, its rarity and pack size.
|
||||||
* @param x Block x-index in chunk
|
*/
|
||||||
* @param z Block z-index in chunk
|
private Map<EntityType, Pair<Double, Integer>> getEntityMap(List<String> objectList)
|
||||||
* @return true, if all chunks around given block are generated.
|
{
|
||||||
*/
|
Map<EntityType, Pair<Double, Integer>> entityMap = new HashMap<>(objectList.size());
|
||||||
private boolean isValidBlock(World world, Block block, int x, int z)
|
|
||||||
{
|
|
||||||
return x > 0 && x < 15 && z > 0 && z < 15 ||
|
|
||||||
world.isChunkGenerated(block.getX() + 1, block.getZ()) &&
|
|
||||||
world.isChunkGenerated(block.getX() - 1, block.getZ()) &&
|
|
||||||
world.isChunkGenerated(block.getX(), block.getZ() - 1) &&
|
|
||||||
world.isChunkGenerated(block.getX(), block.getZ() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Map<String, EntityType> entityTypeMap = Arrays.stream(EntityType.values()).
|
||||||
|
collect(Collectors.toMap(Enum::name,
|
||||||
|
entityType -> entityType,
|
||||||
|
(a, b) -> b,
|
||||||
|
() -> new HashMap<>(EntityType.values().length)));
|
||||||
|
|
||||||
/**
|
// wrong material object.
|
||||||
* This method is not completed. It must reserve space for entities to spawn, but
|
objectList.stream().
|
||||||
* current implementation just allows to spawn 2 high mobs that can be in single
|
filter(object -> object.startsWith("ENTITY")).
|
||||||
* place.
|
map(object -> object.split(":")).
|
||||||
* @param world - World were mob must be spawned.
|
filter(splitString -> splitString.length == 4).
|
||||||
* @param block - Block that was choosed by random.
|
forEach(splitString -> {
|
||||||
* @param entity - Entity that must be spawned.
|
EntityType entity = entityTypeMap.getOrDefault(splitString[1], null);
|
||||||
* @param x - ChunkX coordinate.
|
|
||||||
* @param z - ChunkY coordinate.
|
|
||||||
* @param originalMaterial - replacement manterial.
|
|
||||||
*/
|
|
||||||
private void tryToPlaceEntity(World world, Block block, EntityType entity, int x, int z, Material originalMaterial)
|
|
||||||
{
|
|
||||||
if (this.isValidBlock(world, block, x, z) && block.getType().equals(originalMaterial))
|
|
||||||
{
|
|
||||||
if (entity.isAlive())
|
|
||||||
{
|
|
||||||
int height = 0;
|
|
||||||
int width = 0;
|
|
||||||
int length = 0;
|
|
||||||
boolean water = false;
|
|
||||||
|
|
||||||
switch (entity)
|
if (entity != null)
|
||||||
{
|
{
|
||||||
case SPIDER:
|
entityMap.put(entity,
|
||||||
width = 1;
|
new Pair<>(Double.parseDouble(splitString[2]), Integer.parseInt(splitString[3])));
|
||||||
length = 1;
|
}
|
||||||
break;
|
});
|
||||||
case SLIME:
|
|
||||||
case ELDER_GUARDIAN:
|
|
||||||
case GHAST:
|
|
||||||
case MAGMA_CUBE:
|
|
||||||
case WITHER:
|
|
||||||
height = 2;
|
|
||||||
width = 2;
|
|
||||||
length = 2;
|
|
||||||
break;
|
|
||||||
case ENDERMAN:
|
|
||||||
case IRON_GOLEM:
|
|
||||||
height = 2;
|
|
||||||
break;
|
|
||||||
case WITHER_SKELETON:
|
|
||||||
case STRAY:
|
|
||||||
case HUSK:
|
|
||||||
case ZOMBIE_VILLAGER:
|
|
||||||
case EVOKER:
|
|
||||||
case VINDICATOR:
|
|
||||||
case ILLUSIONER:
|
|
||||||
case CREEPER:
|
|
||||||
case SKELETON:
|
|
||||||
case ZOMBIE:
|
|
||||||
case BLAZE:
|
|
||||||
case SNOWMAN:
|
|
||||||
case VILLAGER:
|
|
||||||
case PIG_ZOMBIE:
|
|
||||||
case WITCH:
|
|
||||||
case SHULKER:
|
|
||||||
case SHEEP:
|
|
||||||
case COW:
|
|
||||||
case MUSHROOM_COW:
|
|
||||||
height = 12;
|
|
||||||
break;
|
|
||||||
case SKELETON_HORSE:
|
|
||||||
case ZOMBIE_HORSE:
|
|
||||||
case DONKEY:
|
|
||||||
case MULE:
|
|
||||||
case HORSE:
|
|
||||||
case POLAR_BEAR:
|
|
||||||
case LLAMA:
|
|
||||||
height = 1;
|
|
||||||
width = 1;
|
|
||||||
break;
|
|
||||||
case GUARDIAN:
|
|
||||||
case SQUID:
|
|
||||||
case COD:
|
|
||||||
case SALMON:
|
|
||||||
case PUFFERFISH:
|
|
||||||
case TROPICAL_FISH:
|
|
||||||
water = true;
|
|
||||||
break;
|
|
||||||
case DROWNED:
|
|
||||||
case DOLPHIN:
|
|
||||||
water = true;
|
|
||||||
height = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block.getY() > 1 && block.getY() < world.getMaxHeight() - 2)
|
return entityMap;
|
||||||
{
|
}
|
||||||
Block otherBlock = world.getBlockAt(block.getX(), block.getY() + 1, block.getZ());
|
|
||||||
|
|
||||||
if (!otherBlock.getType().equals(originalMaterial))
|
/**
|
||||||
{
|
* Places entities if there is room for them.
|
||||||
otherBlock = world.getBlockAt(block.getX(), block.getY() - 1, block.getZ());
|
* @param world - World were mob must be spawned.
|
||||||
}
|
* @param block - Block that was chosen by random.
|
||||||
|
* @param entity - Entity that must be spawned.
|
||||||
if (otherBlock.getType().equals(originalMaterial))
|
* @param originalMaterial - replacement material.
|
||||||
{
|
*/
|
||||||
block.setType(Material.CAVE_AIR);
|
private void tryToPlaceEntity(World world, Block block, EntityType entity, Material originalMaterial)
|
||||||
otherBlock.setType(Material.CAVE_AIR);
|
{
|
||||||
|
if (block.getType().equals(originalMaterial)) {
|
||||||
if (otherBlock.getY() < block.getY())
|
// Spawn entity
|
||||||
{
|
Entity e = world.spawnEntity(block.getLocation().add(0.5, 0, 0.5), entity);
|
||||||
world.spawnEntity(otherBlock.getLocation(), entity);
|
if (e instanceof LivingEntity) {
|
||||||
}
|
// Do not despawn
|
||||||
else
|
((LivingEntity)e).setRemoveWhenFarAway(false);
|
||||||
{
|
}
|
||||||
world.spawnEntity(block.getLocation(), entity);
|
// Make space for entity based on the entity's size
|
||||||
}
|
BoundingBox bb = e.getBoundingBox();
|
||||||
}
|
for (int x = (int) bb.getMinX(); x < bb.getMaxX(); x++) {
|
||||||
}
|
for (int z = (int) bb.getMinZ(); z < bb.getMaxZ(); z++) {
|
||||||
}
|
int y = (int) bb.getMinY();
|
||||||
else
|
Block b = world.getBlockAt(x, y, z);
|
||||||
{
|
for (; y < bb.getMaxY(); y++) {
|
||||||
block.setType(Material.CAVE_AIR);
|
if (addon.getSettings().isDebug()) {
|
||||||
world.spawnEntity(block.getLocation(), entity);
|
addon.log("DEBUG: Entity spawn: " + world.getName() + " " + x + " " + y + " " + z + " " + e.getType());
|
||||||
}
|
}
|
||||||
}
|
b = world.getBlockAt(x, y, z);
|
||||||
}
|
if (!b.getType().equals(originalMaterial)) {
|
||||||
|
// Cannot place entity
|
||||||
|
e.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
b.setType(WATER_ENTITIES.contains(entity) ? Material.WATER : Material.CAVE_AIR);
|
||||||
|
}
|
||||||
|
// Add air block on top for all water entities (required for dolphin, okay for others)
|
||||||
|
if (WATER_ENTITIES.contains(entity) && b.getRelative(BlockFace.UP).getType().equals(originalMaterial)) {
|
||||||
|
b.getRelative(BlockFace.UP).setType(Material.CAVE_AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Section: Variables
|
// Section: Variables
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CaveBlock addon.
|
* CaveBlock addon.
|
||||||
*/
|
*/
|
||||||
private CaveBlock addon;
|
private CaveBlock addon;
|
||||||
|
|
||||||
/**
|
private Map<Environment, Chances> chances;
|
||||||
* CaveBlock settings.
|
|
||||||
*/
|
private int worldHeight;
|
||||||
private Settings settings;
|
|
||||||
|
private final static List<EntityType> WATER_ENTITIES = Arrays.asList(EntityType.GUARDIAN,
|
||||||
|
EntityType.SQUID,
|
||||||
|
EntityType.COD,
|
||||||
|
EntityType.SALMON,
|
||||||
|
EntityType.PUFFERFISH,
|
||||||
|
EntityType.TROPICAL_FISH,
|
||||||
|
EntityType.DROWNED,
|
||||||
|
EntityType.DOLPHIN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chances class to store chances for environments and main material
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class Chances {
|
||||||
|
final Map<EntityType, Pair<Double, Integer>> entityChanceMap;
|
||||||
|
final Material mainMaterial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param materialChanceMap
|
||||||
|
* @param mainMaterial
|
||||||
|
*/
|
||||||
|
public Chances(Map<EntityType, Pair<Double, Integer>> entityChanceMap, Material mainMaterial) {
|
||||||
|
this.entityChanceMap = entityChanceMap;
|
||||||
|
this.mainMaterial = mainMaterial;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,20 @@
|
|||||||
package world.bentobox.caveblock.generators.populators;
|
package world.bentobox.caveblock.generators.populators;
|
||||||
|
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.generator.BlockPopulator;
|
|
||||||
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.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.World.Environment;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
|
||||||
import world.bentobox.bentobox.util.Pair;
|
import world.bentobox.bentobox.util.Pair;
|
||||||
import world.bentobox.caveblock.CaveBlock;
|
import world.bentobox.caveblock.CaveBlock;
|
||||||
import world.bentobox.caveblock.Settings;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,173 +23,170 @@ import world.bentobox.caveblock.Settings;
|
|||||||
*/
|
*/
|
||||||
public class MaterialPopulator extends BlockPopulator
|
public class MaterialPopulator extends BlockPopulator
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* This is default constructor
|
/**
|
||||||
* @param addon CaveBlock addon.
|
* This is default constructor
|
||||||
*/
|
* @param addon CaveBlock addon.
|
||||||
public MaterialPopulator(CaveBlock addon)
|
*/
|
||||||
{
|
public MaterialPopulator(CaveBlock addon)
|
||||||
this.addon = addon;
|
{
|
||||||
this.settings = addon.getSettings();
|
this.addon = addon;
|
||||||
}
|
// Load settings
|
||||||
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method populates chunk with blocks.
|
* Loads chances for Material Populator
|
||||||
* @param world World where population must be.
|
*/
|
||||||
* @param random Randomness
|
public void loadSettings() {
|
||||||
* @param chunk Chunk were populator operates.
|
// Set up chances
|
||||||
*/
|
chances = new HashMap<>();
|
||||||
@Override
|
// Normal
|
||||||
public void populate(World world, Random random, Chunk chunk)
|
chances.put(Environment.NORMAL, new Chances(this.getMaterialMap(addon.getSettings().getNormalBlocks()), addon.getSettings().getNormalMainBlock()));
|
||||||
{
|
// Nether
|
||||||
Map<Material, Pair<Integer, Integer>> materialChanceMap;
|
chances.put(Environment.NETHER, new Chances(this.getMaterialMap(addon.getSettings().getNetherBlocks()), addon.getSettings().getNetherMainBlock()));
|
||||||
Material mainMaterial;
|
// End
|
||||||
|
chances.put(Environment.THE_END, new Chances(this.getMaterialMap(addon.getSettings().getEndBlocks()), addon.getSettings().getEndMainBlock()));
|
||||||
if (world.getEnvironment().equals(World.Environment.NETHER))
|
// Other settings
|
||||||
{
|
worldHeight = addon.getSettings().getWorldDepth() - 1;
|
||||||
materialChanceMap = this.getMaterialMap(this.settings.getNetherBlocks());
|
}
|
||||||
mainMaterial = this.settings.getNetherMainBlock();
|
|
||||||
}
|
|
||||||
else if (world.getEnvironment().equals(World.Environment.THE_END))
|
|
||||||
{
|
|
||||||
materialChanceMap = this.getMaterialMap(this.settings.getEndBlocks());
|
|
||||||
mainMaterial = this.settings.getEndMainBlock();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
materialChanceMap = this.getMaterialMap(this.settings.getNormalBlocks());
|
|
||||||
mainMaterial = this.settings.getNormalMainBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int generationTry = this.settings.getNumberOfBlockGenerationTries();
|
|
||||||
final int worldHeight = this.settings.getWorldDepth() - 1;
|
|
||||||
|
|
||||||
for (Map.Entry<Material, Pair<Integer, Integer>> entry : materialChanceMap.entrySet())
|
|
||||||
{
|
|
||||||
for (int subY = 0; subY < worldHeight; subY += 16)
|
|
||||||
{
|
|
||||||
for (int tries = 0; tries < generationTry; tries++)
|
|
||||||
{
|
|
||||||
if (random.nextInt(100) < entry.getValue().x)
|
|
||||||
{
|
|
||||||
int x = random.nextInt(15);
|
|
||||||
int z = random.nextInt(15);
|
|
||||||
int y = Math.min(worldHeight - 2, subY + random.nextInt(15));
|
|
||||||
|
|
||||||
Block block = chunk.getBlock(x, y, z);
|
|
||||||
|
|
||||||
if (block.getType().equals(mainMaterial) &&
|
|
||||||
this.isValidBlock(world, block, x, z))
|
|
||||||
{
|
|
||||||
int packSize = random.nextInt(entry.getValue().z);
|
|
||||||
|
|
||||||
boolean continuePlacing = true;
|
|
||||||
|
|
||||||
while (continuePlacing)
|
|
||||||
{
|
|
||||||
if (!block.getType().equals(entry.getKey()))
|
|
||||||
{
|
|
||||||
block.setType(entry.getKey());
|
|
||||||
packSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The direction chooser
|
|
||||||
switch (random.nextInt(5))
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
x = Math.min(15, x + 1);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
y = Math.min(worldHeight - 2, y + 1);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
z = Math.min(15, z + 1);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
x = Math.max(0, x - 1);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
y = Math.max(1, y - 1);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
z = Math.max(0, z - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
block = chunk.getBlock(x, y, z);
|
|
||||||
|
|
||||||
continuePlacing = this.isValidBlock(world, block, x, z) &&
|
|
||||||
packSize > 0 &&
|
|
||||||
(block.getType().equals(mainMaterial) ||
|
|
||||||
block.getType().equals(entry.getKey()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks if all chunks around given block is generated.
|
* This method populates chunk with blocks.
|
||||||
* @param world World in which block is located
|
* @param world World where population must be.
|
||||||
* @param block Block that must be checked.
|
* @param random Randomness
|
||||||
* @param x Block x-index in chunk
|
* @param chunk Chunk were populator operates.
|
||||||
* @param z Block z-index in chunk
|
*/
|
||||||
* @return true, if all chunks around given block are generated.
|
@Override
|
||||||
*/
|
public void populate(World world, Random random, Chunk chunk)
|
||||||
private boolean isValidBlock(World world, Block block, int x, int z)
|
{
|
||||||
{
|
for (Map.Entry<Material, Pair<Double, Integer>> entry : chances.get(world.getEnvironment()).materialChanceMap.entrySet())
|
||||||
return x > 0 && x < 15 && z > 0 && z < 15 ||
|
{
|
||||||
world.isChunkGenerated(block.getX() + 1, block.getZ()) &&
|
for (int subY = 1; subY < worldHeight; subY += 16)
|
||||||
world.isChunkGenerated(block.getX() - 1, block.getZ()) &&
|
{
|
||||||
world.isChunkGenerated(block.getX(), block.getZ() - 1) &&
|
if (random.nextDouble() * 100 < entry.getValue().x)
|
||||||
world.isChunkGenerated(block.getX(), block.getZ() + 1);
|
{
|
||||||
}
|
|
||||||
|
// Blocks must be 1 away from edge to avoid adjacent chunk loading
|
||||||
|
int x = random.nextInt(13) + 1;
|
||||||
|
int z = random.nextInt(13) + 1;
|
||||||
|
int y = Math.min(worldHeight - 2, subY + random.nextInt(15));
|
||||||
|
/*
|
||||||
|
* TODO: remove
|
||||||
|
if (addon.getSettings().isDebug()) {
|
||||||
|
addon.log("DEBUG: Material: " + world.getName() + " " + x + " " + y + " " + z + " " + entry.getKey());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Block block = chunk.getBlock(x, y, z);
|
||||||
|
|
||||||
|
if (block.getType().equals(chances.get(world.getEnvironment()).mainMaterial))
|
||||||
|
{
|
||||||
|
int packSize = random.nextInt(entry.getValue().z);
|
||||||
|
|
||||||
|
boolean continuePlacing = true;
|
||||||
|
|
||||||
|
while (continuePlacing)
|
||||||
|
{
|
||||||
|
if (!block.getType().equals(entry.getKey()))
|
||||||
|
{
|
||||||
|
block.setType(entry.getKey());
|
||||||
|
packSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The direction chooser
|
||||||
|
switch (random.nextInt(5))
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
x = Math.min(15, x + 1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
y = Math.min(worldHeight - 2, y + 1);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
z = Math.min(15, z + 1);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
x = Math.max(0, x - 1);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
y = Math.max(1, y - 1);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
z = Math.max(0, z - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = chunk.getBlock(x, y, z);
|
||||||
|
|
||||||
|
continuePlacing = packSize > 0 &&
|
||||||
|
(block.getType().equals(chances.get(world.getEnvironment()).mainMaterial) ||
|
||||||
|
block.getType().equals(entry.getKey()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns material frequently and pack size map.
|
||||||
|
* @param objectList List with objects that contains data.
|
||||||
|
* @return Map that contains material, its rarity and pack size.
|
||||||
|
*/
|
||||||
|
private Map<Material, Pair<Double, Integer>> getMaterialMap(List<String> objectList)
|
||||||
|
{
|
||||||
|
Map<Material, Pair<Double, Integer>> materialMap = new HashMap<>(objectList.size());
|
||||||
|
|
||||||
|
// wrong material object.
|
||||||
|
objectList.stream().
|
||||||
|
filter(object -> object.startsWith("MATERIAL")).
|
||||||
|
map(object -> object.split(":")).
|
||||||
|
filter(splitString -> splitString.length == 4).
|
||||||
|
forEach(splitString -> {
|
||||||
|
Material material = Material.getMaterial(splitString[1]);
|
||||||
|
|
||||||
|
if (material != null)
|
||||||
|
{
|
||||||
|
materialMap.put(material,
|
||||||
|
new Pair<>(Double.parseDouble(splitString[2]), Integer.parseInt(splitString[3])));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return materialMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
// ---------------------------------------------------------------------
|
||||||
* This method returns material frequently and pack size map.
|
// Section: Variables
|
||||||
* @param objectList List with objects that contains data.
|
// ---------------------------------------------------------------------
|
||||||
* @return Map that contains material, its rarity and pack size.
|
|
||||||
*/
|
|
||||||
private Map<Material, Pair<Integer, Integer>> getMaterialMap(List<String> objectList)
|
|
||||||
{
|
|
||||||
Map<Material, Pair<Integer, Integer>> materialMap = new HashMap<>(objectList.size());
|
|
||||||
|
|
||||||
// wrong material object.
|
|
||||||
objectList.stream().
|
|
||||||
filter(object -> object.startsWith("MATERIAL")).
|
|
||||||
map(object -> object.split(":")).
|
|
||||||
filter(splitString -> splitString.length == 4).
|
|
||||||
forEach(splitString -> {
|
|
||||||
Material material = Material.getMaterial(splitString[1]);
|
|
||||||
|
|
||||||
if (material != null)
|
|
||||||
{
|
|
||||||
materialMap.put(material,
|
|
||||||
new Pair<>(Integer.parseInt(splitString[2]), Integer.parseInt(splitString[3])));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return materialMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
/**
|
||||||
// Section: Variables
|
* CaveBlock addon.
|
||||||
// ---------------------------------------------------------------------
|
*/
|
||||||
|
private CaveBlock addon;
|
||||||
|
|
||||||
|
private Map<Environment, Chances> chances;
|
||||||
|
|
||||||
/**
|
private int worldHeight;
|
||||||
* CaveBlock addon.
|
|
||||||
*/
|
|
||||||
private CaveBlock addon;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CaveBlock settings.
|
* Chances class to store chances for environments and main material
|
||||||
*/
|
*
|
||||||
private Settings settings;
|
*/
|
||||||
|
private class Chances {
|
||||||
|
final Map<Material, Pair<Double, Integer>> materialChanceMap;
|
||||||
|
final Material mainMaterial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param materialChanceMap
|
||||||
|
* @param mainMaterial
|
||||||
|
*/
|
||||||
|
public Chances(Map<Material, Pair<Double, Integer>> materialChanceMap, Material mainMaterial) {
|
||||||
|
this.materialChanceMap = materialChanceMap;
|
||||||
|
this.mainMaterial = mainMaterial;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,203 @@
|
|||||||
|
package world.bentobox.caveblock.listeners;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockDamageEvent;
|
||||||
|
import org.bukkit.event.block.BlockExplodeEvent;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
import world.bentobox.caveblock.CaveBlock;
|
||||||
|
import world.bentobox.caveblock.Settings;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class allows to enable beacon in CaveBlock, if cave roof is made of bedrock.
|
||||||
|
* It will replace Bedrock with black glass.
|
||||||
|
*/
|
||||||
|
public class BeaconEnabler implements Listener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor BeaconEnabler creates a new BeaconEnabler instance.
|
||||||
|
*
|
||||||
|
* @param addon of type CaveBlock
|
||||||
|
*/
|
||||||
|
public BeaconEnabler(CaveBlock addon)
|
||||||
|
{
|
||||||
|
this.addon = addon;
|
||||||
|
this.settings = addon.getSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method onBlockPlacement detects if beacon is placed and replace roof bedrock with black glass.
|
||||||
|
*
|
||||||
|
* @param event of type BlockPlaceEvent
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onBlockPlacement(BlockPlaceEvent event)
|
||||||
|
{
|
||||||
|
World world = event.getPlayer().getWorld();
|
||||||
|
|
||||||
|
if (!Util.sameWorld(this.addon.getOverWorld(), world) ||
|
||||||
|
!this.settings.isBeaconAllowed() ||
|
||||||
|
!this.isRoofEnabled(world) ||
|
||||||
|
!event.getBlock().getType().equals(Material.BEACON))
|
||||||
|
{
|
||||||
|
// This should work only if it is cave block world or world has roof from bedrock. Otherwise,
|
||||||
|
// players can dig till top themself.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Block roofBlock = world.getBlockAt(event.getBlock().getX(), this.settings.getWorldDepth() - 1, event.getBlock().getZ());
|
||||||
|
|
||||||
|
if (roofBlock.getType().equals(Material.BEDROCK))
|
||||||
|
{
|
||||||
|
// Replace only bedrock.
|
||||||
|
roofBlock.setType(Material.BLACK_STAINED_GLASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method onBlockBreak detects if beacon is destroyed and replace roof black glass with bedrock.
|
||||||
|
*
|
||||||
|
* @param event of type BlockBreakEvent
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onBlockBreak(BlockBreakEvent event)
|
||||||
|
{
|
||||||
|
World world = event.getPlayer().getWorld();
|
||||||
|
|
||||||
|
if (!Util.sameWorld(this.addon.getOverWorld(), world) ||
|
||||||
|
!this.isRoofEnabled(world) ||
|
||||||
|
!this.settings.isBeaconAllowed() ||
|
||||||
|
!event.getBlock().getType().equals(Material.BEACON))
|
||||||
|
{
|
||||||
|
// This should work only if it is cave block world or world has roof from bedrock.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block roofBlock = world.getBlockAt(event.getBlock().getX(), this.settings.getWorldDepth() - 1, event.getBlock().getZ());
|
||||||
|
|
||||||
|
if (roofBlock.getType().equals(Material.BLACK_STAINED_GLASS))
|
||||||
|
{
|
||||||
|
// Replace only black glass.
|
||||||
|
roofBlock.setType(Material.BEDROCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method onBlockDamage detects if user tries to destroy black glass on roof and disable it.
|
||||||
|
*
|
||||||
|
* @param event of type BlockDamageEvent
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onBlockDamage(BlockDamageEvent event)
|
||||||
|
{
|
||||||
|
World world = event.getPlayer().getWorld();
|
||||||
|
|
||||||
|
if (!Util.sameWorld(this.addon.getOverWorld(), world) ||
|
||||||
|
!this.isRoofEnabled(world) ||
|
||||||
|
!this.settings.isBeaconAllowed() ||
|
||||||
|
event.getBlock().getY() != this.settings.getWorldDepth() - 1)
|
||||||
|
{
|
||||||
|
// This should work only if it is cave block world or world has roof from bedrock.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel break event if it is black glass.
|
||||||
|
event.setCancelled(event.getBlock().getType().equals(Material.BLACK_STAINED_GLASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method onBlockExplode detects if explosion tries to destroy black glass on roof and disable it.
|
||||||
|
*
|
||||||
|
* @param event of type BlockExplodeEvent
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onBlockExplode(BlockExplodeEvent event)
|
||||||
|
{
|
||||||
|
World world = event.getBlock().getWorld();
|
||||||
|
|
||||||
|
if (!Util.sameWorld(this.addon.getOverWorld(), world) ||
|
||||||
|
!this.isRoofEnabled(world) ||
|
||||||
|
!this.settings.isBeaconAllowed() ||
|
||||||
|
event.getBlock().getY() < this.settings.getWorldDepth() - 9)
|
||||||
|
{
|
||||||
|
// This should work only if it is cave block world or world has roof from bedrock.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int blockY = this.settings.getWorldDepth() - 1;
|
||||||
|
|
||||||
|
// Remove all black stained glass from explosion block list if it is on the roof.
|
||||||
|
event.blockList().removeIf(block ->
|
||||||
|
block.getY() == blockY && block.getType().equals(Material.BLACK_STAINED_GLASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method onEntityExplode detects if explosion tries to destroy black glass on roof and disable it.
|
||||||
|
*
|
||||||
|
* @param event of type EntityExplodeEvent
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onEntityExplode(EntityExplodeEvent event)
|
||||||
|
{
|
||||||
|
World world = event.getLocation().getWorld();
|
||||||
|
|
||||||
|
if (!Util.sameWorld(this.addon.getOverWorld(), world) ||
|
||||||
|
!this.isRoofEnabled(world) ||
|
||||||
|
!this.settings.isBeaconAllowed() ||
|
||||||
|
event.getLocation().getY() < this.settings.getWorldDepth() - 9)
|
||||||
|
{
|
||||||
|
// This should work only if it is cave block world or world has roof from bedrock.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int blockY = this.settings.getWorldDepth() - 1;
|
||||||
|
|
||||||
|
// Remove all black stained glass from explosion block list if it is on the roof.
|
||||||
|
event.blockList().removeIf(block ->
|
||||||
|
block.getY() == blockY && block.getType().equals(Material.BLACK_STAINED_GLASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks if in given world bedrock roof is enabled.
|
||||||
|
* @param world World that must be checked.
|
||||||
|
* @return <code>true</code> - bedrock roof is enabled, otherwise <code>false</code>
|
||||||
|
*/
|
||||||
|
private boolean isRoofEnabled(World world)
|
||||||
|
{
|
||||||
|
return world.getEnvironment().equals(World.Environment.NORMAL) && this.settings.isNormalRoof() ||
|
||||||
|
world.getEnvironment().equals(World.Environment.NETHER) && this.settings.isNetherRoof() ||
|
||||||
|
world.getEnvironment().equals(World.Environment.THE_END) && this.settings.isEndRoof();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Variables
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CaveBlock addon.
|
||||||
|
*/
|
||||||
|
private CaveBlock addon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Addon settings.
|
||||||
|
*/
|
||||||
|
private Settings settings;
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
package world.bentobox.caveblock.listeners;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.GameMode;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
import world.bentobox.bentobox.util.teleport.SafeSpotTeleport;
|
||||||
|
import world.bentobox.caveblock.CaveBlock;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This listener checks player movement. If enabled, players will be deny to get over world depth limit and
|
||||||
|
* if alternative teleports is enabled, then falling in void also will be processed.
|
||||||
|
*/
|
||||||
|
public class CustomHeightLimitations implements Listener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Simple constructor
|
||||||
|
* @param addon
|
||||||
|
*/
|
||||||
|
public CustomHeightLimitations(CaveBlock addon)
|
||||||
|
{
|
||||||
|
this.addon = addon;
|
||||||
|
this.worldHeight = addon.getSettings().getWorldDepth() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method onPlayerMove disables movement if user tries to get on top of the world.
|
||||||
|
* It allows movement only downwards.
|
||||||
|
*
|
||||||
|
* @param event of type PlayerMoveEvent
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event)
|
||||||
|
{
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
final double nextY = event.getTo().getY();
|
||||||
|
|
||||||
|
if (this.addon.getSettings().isSkyWalking() ||
|
||||||
|
player.isOp() ||
|
||||||
|
player.isDead() ||
|
||||||
|
player.getGameMode().equals(GameMode.CREATIVE) ||
|
||||||
|
player.getGameMode().equals(GameMode.SPECTATOR) ||
|
||||||
|
this.addon.getPlayers().isInTeleport(player.getUniqueId()) ||
|
||||||
|
player.hasPermission("caveblock.skywalker") ||
|
||||||
|
!Util.sameWorld(this.addon.getOverWorld(), player.getWorld()) ||
|
||||||
|
nextY > 0 && nextY < this.worldHeight ||
|
||||||
|
// Next check will allow to go down, but never up.
|
||||||
|
event.getFrom().getBlockY() <= event.getFrom().getBlockY() &&
|
||||||
|
event.getFrom().getBlockX() == event.getTo().getBlockX() &&
|
||||||
|
event.getFrom().getBlockZ() == event.getTo().getBlockZ())
|
||||||
|
{
|
||||||
|
// interested only in movements that is below 0 or above height limit.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use custom teleport to different world
|
||||||
|
if (this.addon.getSettings().isAlternativeTeleports() && nextY <= 0)
|
||||||
|
{
|
||||||
|
switch (player.getWorld().getEnvironment())
|
||||||
|
{
|
||||||
|
case NORMAL:
|
||||||
|
{
|
||||||
|
// From normal world users will get to nether.
|
||||||
|
|
||||||
|
Location to = this.addon.getIslands().getIslandAt(event.getFrom()).
|
||||||
|
map(i -> i.getSpawnPoint(World.Environment.NETHER)).
|
||||||
|
orElse(event.getFrom().toVector().toLocation(this.addon.getNetherWorld()));
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
new SafeSpotTeleport.Builder(this.addon.getPlugin()).
|
||||||
|
entity(event.getPlayer()).
|
||||||
|
location(to).
|
||||||
|
portal().
|
||||||
|
build();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NETHER:
|
||||||
|
{
|
||||||
|
// From nether world users will get to the end.
|
||||||
|
|
||||||
|
Location to = this.addon.getIslands().getIslandAt(event.getFrom()).
|
||||||
|
map(i -> i.getSpawnPoint(World.Environment.THE_END)).
|
||||||
|
orElse(event.getFrom().toVector().toLocation(this.addon.getEndWorld()));
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
new SafeSpotTeleport.Builder(this.addon.getPlugin()).
|
||||||
|
entity(event.getPlayer()).
|
||||||
|
location(to).
|
||||||
|
portal().
|
||||||
|
build();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case THE_END:
|
||||||
|
{
|
||||||
|
// From the end users will get to over world.
|
||||||
|
|
||||||
|
Location to = this.addon.getIslands().getIslandAt(event.getFrom()).
|
||||||
|
map(i -> i.getSpawnPoint(World.Environment.NORMAL)).
|
||||||
|
orElse(event.getFrom().toVector().toLocation(this.addon.getOverWorld()));
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
new SafeSpotTeleport.Builder(this.addon.getPlugin()).
|
||||||
|
entity(event.getPlayer()).
|
||||||
|
location(to).
|
||||||
|
portal().
|
||||||
|
build();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent to get over world height
|
||||||
|
if (nextY >= this.worldHeight)
|
||||||
|
{
|
||||||
|
User.getInstance(player).sendMessage("caveblock.general.errors.cave-limit-reached");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method onPlayerTeleport disables all teleports that involves moving on top of the world.
|
||||||
|
*
|
||||||
|
* @param event of type PlayerTeleportEvent
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onPlayerTeleport(PlayerTeleportEvent event)
|
||||||
|
{
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
final double nextY = event.getTo().getY();
|
||||||
|
|
||||||
|
if (this.addon.getSettings().isSkyWalking() ||
|
||||||
|
player.isOp() ||
|
||||||
|
player.isDead() ||
|
||||||
|
player.getGameMode().equals(GameMode.CREATIVE) ||
|
||||||
|
player.getGameMode().equals(GameMode.SPECTATOR) ||
|
||||||
|
this.addon.getPlayers().isInTeleport(player.getUniqueId()) ||
|
||||||
|
player.hasPermission("caveblock.skywalker") ||
|
||||||
|
!Util.sameWorld(this.addon.getOverWorld(), player.getWorld()) ||
|
||||||
|
nextY > 0 && nextY < this.worldHeight ||
|
||||||
|
// Next check will allow to go down, but never up.
|
||||||
|
event.getFrom().getBlockY() <= event.getFrom().getBlockY() &&
|
||||||
|
event.getFrom().getBlockX() == event.getTo().getBlockX() &&
|
||||||
|
event.getFrom().getBlockZ() == event.getTo().getBlockZ())
|
||||||
|
{
|
||||||
|
// interested only in movements that is below 0 or above height limit.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent to get over world height
|
||||||
|
if (nextY >= this.worldHeight)
|
||||||
|
{
|
||||||
|
User.getInstance(player).sendMessage("caveblock.general.errors.cave-limit-reached");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Section: Variables
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CaveBlock addon
|
||||||
|
*/
|
||||||
|
private CaveBlock addon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This variable store world height.
|
||||||
|
*/
|
||||||
|
private int worldHeight;
|
||||||
|
}
|
@ -6,25 +6,25 @@ authors: BONNe
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
caveblock.island:
|
caveblock.island:
|
||||||
description: Allow island command usage
|
description: Allow cave command usage
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.create:
|
caveblock.island.create:
|
||||||
description: Allow island creation
|
description: Allow cave creation
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.home:
|
caveblock.island.home:
|
||||||
description: Allow teleporting to player island
|
description: Allow teleporting to player cave
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.sethome:
|
caveblock.island.sethome:
|
||||||
description: Let the player use the sethome command
|
description: Let the player use the sethome command
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.info:
|
caveblock.island.info:
|
||||||
description: Let the player check their island level
|
description: Let the player check their cave level
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.sethome:
|
caveblock.island.sethome:
|
||||||
description: Let the player set their island teleport point
|
description: Let the player set their cave teleport point
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.lock:
|
caveblock.island.lock:
|
||||||
description: Allows island locking
|
description: Allows cave locking
|
||||||
default: false
|
default: false
|
||||||
caveblock.island.expel:
|
caveblock.island.expel:
|
||||||
description: Allows expelling of visitors
|
description: Allows expelling of visitors
|
||||||
@ -39,13 +39,13 @@ permissions:
|
|||||||
description: Player can select a language
|
description: Player can select a language
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.name:
|
caveblock.island.name:
|
||||||
description: Player can set the name of their island
|
description: Player can set the name of their cave
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.spawn:
|
caveblock.island.spawn:
|
||||||
description: Player can use the island spawn command if spawn exists
|
description: Player can use the cave spawn command if spawn exists
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.reset:
|
caveblock.island.reset:
|
||||||
description: Player can use the island reset or restart command
|
description: Player can use the cave reset or restart command
|
||||||
default: true
|
default: true
|
||||||
caveblock.island.team:
|
caveblock.island.team:
|
||||||
description: Let a player use team commands
|
description: Let a player use team commands
|
||||||
@ -57,7 +57,7 @@ permissions:
|
|||||||
description: Let a player use team coop commands
|
description: Let a player use team coop commands
|
||||||
default: true
|
default: true
|
||||||
caveblock.settings.*:
|
caveblock.settings.*:
|
||||||
description: Allow use of settings on island
|
description: Allow use of settings on cave
|
||||||
default: true
|
default: true
|
||||||
caveblock.mod.info:
|
caveblock.mod.info:
|
||||||
description: Let a moderator see info on a player
|
description: Let a moderator see info on a player
|
||||||
@ -66,71 +66,74 @@ permissions:
|
|||||||
description: Allows setting or reseting of a player's home position
|
description: Allows setting or reseting of a player's home position
|
||||||
default: op
|
default: op
|
||||||
caveblock.mod.clearreset:
|
caveblock.mod.clearreset:
|
||||||
description: Allow clearing of island reset limit
|
description: Allow clearing of cave reset limit
|
||||||
default: false
|
default: false
|
||||||
caveblock.mod.tp:
|
caveblock.mod.tp:
|
||||||
description: Allows teleport to an island
|
description: Allows teleport to an cave
|
||||||
default: op
|
default: op
|
||||||
caveblock.mod.bypasscooldowns:
|
caveblock.mod.bypasscooldowns:
|
||||||
description: Allow moderator to bypass cooldowns
|
description: Allow moderator to bypass cooldowns
|
||||||
default: op
|
default: op
|
||||||
caveblock.mod.bypassprotect:
|
caveblock.mod.bypassprotect:
|
||||||
description: Allow moderator to bypass island protection
|
description: Allow moderator to bypass cave protection
|
||||||
default: op
|
default: op
|
||||||
caveblock.mod.bypassexpel:
|
caveblock.mod.bypassexpel:
|
||||||
description: Allow moderator to bypass island expulsion
|
description: Allow moderator to bypass cave expulsion
|
||||||
default: op
|
default: op
|
||||||
caveblock.mod.lock:
|
caveblock.mod.lock:
|
||||||
description: Locks or unlocks an island
|
description: Locks or unlocks an cave
|
||||||
default: op
|
default: op
|
||||||
caveblock.mod.bypasslock:
|
caveblock.mod.bypasslock:
|
||||||
description: Bypasses an island lock
|
description: Bypasses an cave lock
|
||||||
default: op
|
default: op
|
||||||
caveblock.mod.team:
|
caveblock.mod.team:
|
||||||
description: Enables modification of teams via kick and add commands
|
description: Enables modification of teams via kick and add commands
|
||||||
default: false
|
default: false
|
||||||
caveblock.mod.name:
|
caveblock.mod.name:
|
||||||
description: Enables naming of player's islands
|
description: Enables naming of player's caves
|
||||||
default: false
|
default: false
|
||||||
caveblock.mod.resetname:
|
caveblock.mod.resetname:
|
||||||
description: Enables reset of player's island names
|
description: Enables reset of player's cave names
|
||||||
default: false
|
default: false
|
||||||
caveblock.admin.clearresetall:
|
caveblock.admin.clearresetall:
|
||||||
description: Allow clearing of island reset limit of all players
|
description: Allow clearing of cave reset limit of all players
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.reload:
|
caveblock.admin.reload:
|
||||||
description: Reload the config.yml
|
description: Reload the config.yml
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.delete:
|
caveblock.admin.delete:
|
||||||
description: Let a player completely remove a player (including island)
|
description: Let a player completely remove a player (including cave)
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.deleteisland:
|
caveblock.admin.deleteisland:
|
||||||
description: Let a player completely remove the island the player is on
|
description: Let a player completely remove the cave the player is on
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.register:
|
caveblock.admin.register:
|
||||||
description: Let a player register the nearest island to another player.
|
description: Let a player register the nearest cave to another player.
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.unregister:
|
caveblock.admin.unregister:
|
||||||
description: Removes a player from an island without deleting the island blocks.
|
description: Removes a player from an cave without deleting the cave blocks.
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.purge:
|
caveblock.admin.purge:
|
||||||
description: Let a player purge old islands.
|
description: Let a player purge old caves.
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.setspawn:
|
caveblock.admin.setspawn:
|
||||||
description: Allows use of spawn tools
|
description: Allows use of spawn tools
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.setrange:
|
caveblock.admin.setrange:
|
||||||
description: Allows setting of island protection range
|
description: Allows setting of cave protection range
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.reserve:
|
caveblock.admin.reserve:
|
||||||
description: Reserves an empty spot for a player's next island
|
description: Reserves an empty spot for a player's next cave
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.settingsreset:
|
caveblock.admin.settingsreset:
|
||||||
description: Resets all the islands to default protection settings
|
description: Resets all the caves to default protection settings
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.noban:
|
caveblock.admin.noban:
|
||||||
description: Player cannot be banned from an island
|
description: Player cannot be banned from an cave
|
||||||
default: op
|
default: op
|
||||||
caveblock.admin.setlanguage:
|
caveblock.admin.setlanguage:
|
||||||
description: Resets all player languages and sets the default language
|
description: Resets all player languages and sets the default language
|
||||||
default: op
|
default: op
|
||||||
|
caveblock.skywalker:
|
||||||
|
description: Allows player to walk over the heigh limit.
|
||||||
|
default: op
|
@ -1,7 +1,7 @@
|
|||||||
# CaveBlock Configuration ${version}
|
# CaveBlock Configuration ${version}
|
||||||
# This config file is dynamic and saved when the server is shutdown.
|
# This config file is dynamic and saved when the server is shutdown.
|
||||||
# You cannot edit it while the server is running because changes will
|
# If you edit it while the server is running use /cbadmin reload
|
||||||
# be lost! Use in-game settings GUI or edit when server is offline.
|
# otherwise your settings will be lost.
|
||||||
world:
|
world:
|
||||||
# Friendly name for this world. Used in admin commands. Must be a single word
|
# Friendly name for this world. Used in admin commands. Must be a single word
|
||||||
friendly-name: CaveBlock
|
friendly-name: CaveBlock
|
||||||
@ -11,11 +11,11 @@ world:
|
|||||||
# World difficulty setting - PEACEFUL, EASY, NORMAL, HARD
|
# World difficulty setting - PEACEFUL, EASY, NORMAL, HARD
|
||||||
# Other plugins may override this setting
|
# Other plugins may override this setting
|
||||||
difficulty: NORMAL
|
difficulty: NORMAL
|
||||||
# Radius of island in blocks. (So distance between islands is twice this)
|
# Radius of cave in blocks. (So distance between caves is twice this)
|
||||||
# Will be rounded up to the nearest 16 blocks.
|
# Will be rounded up to the nearest 16 blocks.
|
||||||
# It is the same for every dimension : Overworld, Nether and End.
|
# 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.
|
# This value cannot be changed mid-game and the plugin will not start if it is different.
|
||||||
distance-between-islands: 64
|
distance-between-caves: 64
|
||||||
# Default protection range radius in blocks. Cannot be larger than distance.
|
# Default protection range radius in blocks. Cannot be larger than distance.
|
||||||
# Admins can change protection sizes for players individually using /cbadmin range set <player> <new range>
|
# Admins can change protection sizes for players individually using /cbadmin range set <player> <new range>
|
||||||
# or set this permission: caveblock.island.range.<number>
|
# or set this permission: caveblock.island.range.<number>
|
||||||
@ -29,18 +29,13 @@ world:
|
|||||||
start-z: 0
|
start-z: 0
|
||||||
offset-x: 0
|
offset-x: 0
|
||||||
offset-z: 0
|
offset-z: 0
|
||||||
# Island height - Lowest is 5.
|
# Cave height - Lowest is 5.
|
||||||
# It is the y coordinate of the bedrock block in the schem.
|
# It is the y coordinate of the bedrock block in the schem.
|
||||||
island-height: 60
|
cave-height: 60
|
||||||
# Use your own world generator for this world.
|
# Use your own world generator for this world.
|
||||||
# In this case, the plugin will not generate anything.
|
# In this case, the plugin will not generate anything.
|
||||||
# /!\ This feature is experimental and might not work as expected or might not work at all.
|
# /!\ This feature is experimental and might not work as expected or might not work at all.
|
||||||
use-own-generator: true
|
use-own-generator: true
|
||||||
# Sea height (don't changes this mid-game unless you delete the world)
|
|
||||||
# Minimum is 0, which means you are playing CaveBlock!
|
|
||||||
# If sea height is less than about 10, then players will drop right through it
|
|
||||||
# if it exists. Makes for an interesting variation on caveblock.
|
|
||||||
sea-height: 0
|
|
||||||
# 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, it will stop players from creating islands.
|
# If the number of islands is greater than this number, it will stop players from creating islands.
|
||||||
max-islands: 0
|
max-islands: 0
|
||||||
@ -50,7 +45,7 @@ world:
|
|||||||
# The default biome for the overworld
|
# The default biome for the overworld
|
||||||
default-biome: MOUNTAINS
|
default-biome: MOUNTAINS
|
||||||
# The maximum number of players a player can ban at any one time in this game mode.
|
# The maximum number of players a player can ban at any one time in this game mode.
|
||||||
# The permission acidisland.ban.maxlimit.X where X is a number can also be used per player
|
# The permission caveblock.ban.maxlimit.X where X is a number can also be used per player
|
||||||
# -1 = unlimited
|
# -1 = unlimited
|
||||||
ban-limit: -1
|
ban-limit: -1
|
||||||
#
|
#
|
||||||
@ -59,6 +54,20 @@ world:
|
|||||||
world-depth: 256
|
world-depth: 256
|
||||||
# This indicate how many times block should be tried to generate.
|
# This indicate how many times block should be tried to generate.
|
||||||
generation-tries: 2
|
generation-tries: 2
|
||||||
|
#
|
||||||
|
# Allows to walk over the world roof.
|
||||||
|
sky-walking: false
|
||||||
|
# Enables different ways how to get to other worlds.
|
||||||
|
# If players fall into void, then they will be teleported:
|
||||||
|
# - to nether if falls into void from over world
|
||||||
|
# - to the end if falls into void from nether
|
||||||
|
# - to over world if falls into void from the end
|
||||||
|
alternative-teleports: true
|
||||||
|
# Enables ability to use beacon, if world roof is made of Bedrock. It will replace
|
||||||
|
# bedrock with black stained glass and on beacon placing, and replace it with bedrock if
|
||||||
|
# beacon is destroyed.
|
||||||
|
# This will not do anything, if roof is not made of bedrock.
|
||||||
|
allow-beacon: false
|
||||||
normal:
|
normal:
|
||||||
#
|
#
|
||||||
# Make over world roof of bedrock, if false, it will be made from stone
|
# Make over world roof of bedrock, if false, it will be made from stone
|
||||||
@ -74,11 +83,11 @@ world:
|
|||||||
# Entities spawned via generator are not protected from despawing.
|
# Entities spawned via generator are not protected from despawing.
|
||||||
# Working only with 2 high mobs currently.
|
# Working only with 2 high mobs currently.
|
||||||
# Example:
|
# Example:
|
||||||
# MATERIAL:DIAMOND:100:5 - means there is 100% chace of spawing diamonds
|
# MATERIAL:DIAMOND_ORE:100:5 - means there is 100% chace of spawing diamonds
|
||||||
# where max amount in pack are 5 per each subchunk!
|
# where max amount in pack are 5 per each subchunk!
|
||||||
blocks:
|
blocks:
|
||||||
- MATERIAL:DIAMOND_ORE:1:3
|
- MATERIAL:DIAMOND_ORE:1:5
|
||||||
- MATERIAL:GOLD_ORE:5:4
|
- MATERIAL:GOLD_ORE:1:4
|
||||||
- MATERIAL:IRON_ORE:5:4
|
- MATERIAL:IRON_ORE:5:4
|
||||||
- MATERIAL:COAL_ORE:10:6
|
- MATERIAL:COAL_ORE:10:6
|
||||||
- MATERIAL:EMERALD_ORE:1:1
|
- MATERIAL:EMERALD_ORE:1:1
|
||||||
@ -88,6 +97,9 @@ world:
|
|||||||
- MATERIAL:GRANITE:20:10
|
- MATERIAL:GRANITE:20:10
|
||||||
- MATERIAL:ANDESITE:20:10
|
- MATERIAL:ANDESITE:20:10
|
||||||
- MATERIAL:DIORITE:30:8
|
- MATERIAL:DIORITE:30:8
|
||||||
|
- ENTITY:ZOMBIE:1:1
|
||||||
|
- ENTITY:DOLPHIN:0.1:1
|
||||||
|
- ENTITY:CAVE_SPIDER:1:1
|
||||||
nether:
|
nether:
|
||||||
# Generate Nether - if this is false, the nether world will not be made and access to
|
# Generate Nether - if this is false, the nether world will not be made and access to
|
||||||
# the nether will not occur. Other plugins may still enable portal usage.
|
# the nether will not occur. Other plugins may still enable portal usage.
|
||||||
@ -118,14 +130,19 @@ world:
|
|||||||
# Entities spawned via generator are not protected from despawing.
|
# Entities spawned via generator are not protected from despawing.
|
||||||
# Working only with 2 high mobs currently.
|
# Working only with 2 high mobs currently.
|
||||||
# Example:
|
# Example:
|
||||||
# MATERIAL:DIAMOND:100:5 - means there is 100% chace of spawing diamonds
|
# MATERIAL:DIAMOND_ORE:100:5 - means there is 100% chace of spawing diamonds
|
||||||
# where max amount in pack are 5 per each subchunk!
|
# where max amount in pack are 5 per each subchunk!
|
||||||
blocks:
|
blocks:
|
||||||
- MATERIAL:QUARTZ_ORE:30:5
|
- MATERIAL:QUARTZ_ORE:30:5
|
||||||
- MATERIAL:SOUL_SAND:40:10
|
- MATERIAL:SOUL_SAND:40:10
|
||||||
- MATERIAL:MAGMA_BLOCK:10:3
|
- MATERIAL:MAGMA_BLOCK:10:3
|
||||||
- MATERIAL:GLOWSTONE:20:8
|
- MATERIAL:GLOWSTONE:20:8
|
||||||
|
- MATERIAL:NETHER_BRICK:10:5
|
||||||
- MATERIAL:LAVA:10:1
|
- MATERIAL:LAVA:10:1
|
||||||
|
- ENTITY:MAGMA_CUBE:0.5:1
|
||||||
|
- ENTITY:GHAST:0.1:1
|
||||||
|
- ENTITY:WITHER_SKELETON:0.1:1
|
||||||
|
- MATERIAL:FIRE:10:1
|
||||||
end:
|
end:
|
||||||
generate: true
|
generate: true
|
||||||
islands: true
|
islands: true
|
||||||
@ -144,14 +161,16 @@ world:
|
|||||||
# Entities spawned via generator are not protected from despawing.
|
# Entities spawned via generator are not protected from despawing.
|
||||||
# Working only with 2 high mobs currently.
|
# Working only with 2 high mobs currently.
|
||||||
# Example:
|
# Example:
|
||||||
# MATERIAL:DIAMOND:100:5 - means there is 100% chace of spawing diamonds
|
# MATERIAL:DIAMOND_ORE:100:5 - means there is 100% chace of spawing diamonds
|
||||||
# where max amount in pack are 5 per each subchunk!
|
# where max amount in pack are 5 per each subchunk!
|
||||||
blocks:
|
blocks:
|
||||||
- ENTITY:SHULKER:1:1
|
- ENTITY:SHULKER:0.2:1
|
||||||
|
- MATERIAL:OBSIDIAN:1:1
|
||||||
|
- MATERIAL:CHORUS_FRUIT:1:3
|
||||||
# Mob white list - these mobs will NOT be removed when logging in or doing /cave
|
# Mob white list - these mobs will NOT be removed when logging in or doing /cave
|
||||||
remove-mobs-whitelist:
|
remove-mobs-whitelist:
|
||||||
- ZOMBIE_VILLAGER
|
|
||||||
- WITHER
|
- WITHER
|
||||||
|
- ZOMBIE_VILLAGER
|
||||||
- PIG_ZOMBIE
|
- PIG_ZOMBIE
|
||||||
- ENDERMAN
|
- ENDERMAN
|
||||||
# World flags. These are boolean settings for various flags for this world
|
# World flags. These are boolean settings for various flags for this world
|
||||||
@ -193,8 +212,8 @@ world:
|
|||||||
FROST_WALKER: 500
|
FROST_WALKER: 500
|
||||||
COLLECT_LAVA: 500
|
COLLECT_LAVA: 500
|
||||||
LEVER: 500
|
LEVER: 500
|
||||||
HURT_MONSTERS: 0
|
|
||||||
RIDING: 500
|
RIDING: 500
|
||||||
|
HURT_MONSTERS: 0
|
||||||
NAME_TAG: 500
|
NAME_TAG: 500
|
||||||
ARMOR_STAND: 500
|
ARMOR_STAND: 500
|
||||||
TRADING: 0
|
TRADING: 0
|
||||||
@ -202,8 +221,8 @@ world:
|
|||||||
ITEM_DROP: 0
|
ITEM_DROP: 0
|
||||||
NOTE_BLOCK: 0
|
NOTE_BLOCK: 0
|
||||||
NETHER_PORTAL: 500
|
NETHER_PORTAL: 500
|
||||||
ITEM_PICKUP: 0
|
|
||||||
CROP_TRAMPLE: 500
|
CROP_TRAMPLE: 500
|
||||||
|
ITEM_PICKUP: 0
|
||||||
BREWING: 500
|
BREWING: 500
|
||||||
DROPPER: 500
|
DROPPER: 500
|
||||||
COLLECT_WATER: 500
|
COLLECT_WATER: 500
|
||||||
@ -215,26 +234,27 @@ world:
|
|||||||
PLACE_BLOCKS: 500
|
PLACE_BLOCKS: 500
|
||||||
ITEM_FRAME: 500
|
ITEM_FRAME: 500
|
||||||
CRAFTING: 0
|
CRAFTING: 0
|
||||||
SHEARING: 500
|
|
||||||
ENCHANTING: 0
|
ENCHANTING: 0
|
||||||
SPAWN_EGGS: 500
|
SHEARING: 500
|
||||||
BED: 500
|
BED: 500
|
||||||
|
SPAWN_EGGS: 500
|
||||||
MILKING: 0
|
MILKING: 0
|
||||||
DISPENSER: 500
|
DISPENSER: 500
|
||||||
GATE: 0
|
GATE: 0
|
||||||
EXPERIENCE_PICKUP: 500
|
EXPERIENCE_PICKUP: 500
|
||||||
HOPPER: 500
|
HOPPER: 500
|
||||||
LEASH: 500
|
LEASH: 500
|
||||||
MOUNT_INVENTORY: 500
|
|
||||||
BREAK_BLOCKS: 500
|
BREAK_BLOCKS: 500
|
||||||
|
MOUNT_INVENTORY: 500
|
||||||
CHORUS_FRUIT: 500
|
CHORUS_FRUIT: 500
|
||||||
CONTAINER: 500
|
CONTAINER: 500
|
||||||
|
POTION_THROWING: 500
|
||||||
JUKEBOX: 500
|
JUKEBOX: 500
|
||||||
# These are the default settings for new islands
|
# These are the default settings for new islands
|
||||||
default-island-settings:
|
default-island-settings:
|
||||||
PVP_END: false
|
PVP_END: false
|
||||||
ANIMAL_SPAWN: true
|
|
||||||
PVP_NETHER: false
|
PVP_NETHER: false
|
||||||
|
ANIMAL_SPAWN: true
|
||||||
MONSTER_SPAWN: true
|
MONSTER_SPAWN: true
|
||||||
FIRE_SPREAD: true
|
FIRE_SPREAD: true
|
||||||
PVP_OVERWORLD: false
|
PVP_OVERWORLD: false
|
||||||
@ -247,7 +267,7 @@ world:
|
|||||||
- spawnmob
|
- spawnmob
|
||||||
island:
|
island:
|
||||||
# Default max team size
|
# Default max team size
|
||||||
# Permission size cannot be less than the default below.
|
# Permission size cannot be less than the default below.
|
||||||
max-team-size: 4
|
max-team-size: 4
|
||||||
# Default maximum number of homes a player can have. Min = 1
|
# Default maximum number of homes a player can have. Min = 1
|
||||||
# Accessed via /cave sethome <number> or /cave go <number>
|
# Accessed via /cave sethome <number> or /cave go <number>
|
||||||
@ -350,4 +370,5 @@ panel:
|
|||||||
do-not-edit-these-settings:
|
do-not-edit-these-settings:
|
||||||
# These settings should not be edited
|
# These settings should not be edited
|
||||||
reset-epoch: 0
|
reset-epoch: 0
|
||||||
|
debug: false
|
||||||
uniqueId: config
|
uniqueId: config
|
||||||
|
@ -9,4 +9,234 @@ caveblock:
|
|||||||
line1: "Welcome!"
|
line1: "Welcome!"
|
||||||
line2: "[name]"
|
line2: "[name]"
|
||||||
line3: "Start digging! &c<3"
|
line3: "Start digging! &c<3"
|
||||||
|
|
||||||
|
informational:
|
||||||
|
to-nether: "So unlucky to fall into nether."
|
||||||
|
to-the-end: "You have reached the end."
|
||||||
|
to-normal: "Back to your cave."
|
||||||
|
# Override BentoBox default command strings
|
||||||
|
# General strings
|
||||||
|
general:
|
||||||
|
errors:
|
||||||
|
no-island: "&cYou do not have a cave!"
|
||||||
|
player-has-island: "&cPlayer already has a cave!"
|
||||||
|
player-has-no-island: "&cThat player has no cave!"
|
||||||
|
already-have-island: "&cYou already have a cave!"
|
||||||
|
no-safe-location: "&cNo safe location found!"
|
||||||
|
not-owner: "&cYou are not the owner of your team!"
|
||||||
|
cave-limit-reached: "&cYou have reached the top of your cave. You cannot get higher!"
|
||||||
|
commands:
|
||||||
|
# Override BentoBox default island command strings
|
||||||
|
island:
|
||||||
|
info:
|
||||||
|
description: "display info about your cave or the player's cave"
|
||||||
|
go:
|
||||||
|
description: "teleport you to your cave"
|
||||||
|
teleport: "&aTeleporting you to your cave."
|
||||||
|
create:
|
||||||
|
description: "create a cave, using optional schem (requires permission)"
|
||||||
|
too-many-islands: "&cThere are too many caves in this world: there isn't enough room for yours to be created."
|
||||||
|
unable-create-island: "&cYour cave could not be generated, please contact an administrator."
|
||||||
|
creating-island: "&aCreating your cave, please wait a moment..."
|
||||||
|
reset:
|
||||||
|
description: "restart your cave from scratch"
|
||||||
|
parameters: ""
|
||||||
|
must-remove-members: "&cYou must remove all team players before you can restart (/[label] team kick <player>)."
|
||||||
|
sethome:
|
||||||
|
must-be-on-your-island: "&cYou must be in your cave to set home!"
|
||||||
|
home-set: "&6Your home has been set to your current location."
|
||||||
|
setname:
|
||||||
|
description: "set a name for your cave"
|
||||||
|
resetname:
|
||||||
|
description: "reset your cave name"
|
||||||
|
team:
|
||||||
|
coop:
|
||||||
|
description: "make a player coop rank"
|
||||||
|
uncoop:
|
||||||
|
you-are-no-longer-a-coop-member: "&cYou are no longer a coop member of [name]'s cave"
|
||||||
|
all-members-logged-off: "&cAll team members logged off so you are no longer a coop member of [name]'s cave"
|
||||||
|
trust:
|
||||||
|
description: "give a player trusted rank"
|
||||||
|
invite:
|
||||||
|
description: "invite a player to join your team"
|
||||||
|
name-has-invited-you: "&a[name] has invited you to join their team."
|
||||||
|
to-accept-or-reject: "&aDo /[label] team accept to accept, or /[label] team reject to reject"
|
||||||
|
you-will-lose-your-island: "&cWARNING! You will lose your our cave if you accept!"
|
||||||
|
errors:
|
||||||
|
island-is-full: "&cYour team is full, you can't invite anyone else."
|
||||||
|
accept:
|
||||||
|
you-joined-island: "&aYou joined a team! Use /[label] team info to see the other members."
|
||||||
|
name-joined-your-island: "&a[name] joined your team!"
|
||||||
|
confirmation: |-
|
||||||
|
&cAre you sure you want to accept this invite?
|
||||||
|
&c&lThis will &nDESTORY &r&c&lyour current cave!
|
||||||
|
reject:
|
||||||
|
you-rejected-invite: "&aYou rejected the invitation to join a team."
|
||||||
|
name-rejected-your-invite: "&c[name] rejected your invite!"
|
||||||
|
cancel:
|
||||||
|
description: "cancel the pending invite to join your team"
|
||||||
|
leave:
|
||||||
|
description: "leave your team"
|
||||||
|
left-your-island: "&c[name] &cleft your team"
|
||||||
|
kick:
|
||||||
|
description: "remove a team member"
|
||||||
|
owner-kicked: "&cThe owner kicked you from the team!"
|
||||||
|
demote:
|
||||||
|
description: "demote a player one rank"
|
||||||
|
promote:
|
||||||
|
description: "promote a player one rank"
|
||||||
|
setowner:
|
||||||
|
description: "transfer team ownership to a member"
|
||||||
|
errors:
|
||||||
|
target-is-not-member: "&cThat player is not part of your team!"
|
||||||
|
name-is-the-owner: "&a[name] is now the cave owner!"
|
||||||
|
you-are-the-owner: "&aYou are now the cave owner!"
|
||||||
|
ban:
|
||||||
|
description: "ban a player from your cave"
|
||||||
|
cannot-ban-more-players: "&cYou reached the ban limit, you cannot ban any more players."
|
||||||
|
owner-banned-you: "&b[name]&c banned you from their cave!"
|
||||||
|
you-are-banned: "&bYou are banned from this cave!"
|
||||||
|
unban:
|
||||||
|
description: "unban a player from your cave"
|
||||||
|
you-are-unbanned: "&b[name]&a unbanned you from their cave!"
|
||||||
|
banlist:
|
||||||
|
noone: "&aNo one is banned on this cave"
|
||||||
|
settings:
|
||||||
|
description: "display cave settings"
|
||||||
|
# Admin commands
|
||||||
|
admin:
|
||||||
|
team:
|
||||||
|
add:
|
||||||
|
name-has-island: "&c[name] has a cave. Unregister or delete them first!"
|
||||||
|
setowner:
|
||||||
|
description: "transfers cave ownership to the player"
|
||||||
|
already-owner: "&cPlayer is already the owner of this cave!"
|
||||||
|
range:
|
||||||
|
description: "Admin cave range command"
|
||||||
|
display:
|
||||||
|
description: "Show/hide cave range indicators"
|
||||||
|
hint: |-
|
||||||
|
&cRed Barrier icons &fshow the current protected range limit.
|
||||||
|
&7Gray Particles &fshow the max limit.
|
||||||
|
&aGreen Particles &fshow the default protected range if the protection range differs from it.
|
||||||
|
set:
|
||||||
|
description: "Sets the cave protected range"
|
||||||
|
reset:
|
||||||
|
description: "Resets the protected range to the world default"
|
||||||
|
register:
|
||||||
|
parameters: "<player>"
|
||||||
|
description: "register player to unowned cave you are in"
|
||||||
|
registered-island: "&aRegistered player to cave at [xyz]."
|
||||||
|
already-owned: "&ccave is already owned by another player!"
|
||||||
|
no-island-here: "&cThere is no player cave here. Confirm to make one."
|
||||||
|
in-deletion: "&cThis space is currently being regenerated. Try later."
|
||||||
|
unregister:
|
||||||
|
description: "unregister owner from a cave, but keep cave blocks as-is"
|
||||||
|
unregistered-island: "&aUnregistered player from cave at [xyz]."
|
||||||
|
info:
|
||||||
|
parameters: "<player>"
|
||||||
|
description: "get info on where you are or on player"
|
||||||
|
no-island: "&cYou are not in a registered cave right now..."
|
||||||
|
title: "========== Cave Info ============"
|
||||||
|
owner: "Owner: [owner] ([uuid])"
|
||||||
|
last-login: "Last login: [date]"
|
||||||
|
deaths: "Deaths: [number]"
|
||||||
|
resets-left: "Resets: [number] (Max: [total])"
|
||||||
|
team-members-title: "Team members:"
|
||||||
|
team-owner-format: "&a[name] [rank]"
|
||||||
|
team-member-format: "&b[name] [rank]"
|
||||||
|
island-location: "Cave location: [xyz]"
|
||||||
|
island-coords: "Cave coordinates: [xz1] to [xz2]"
|
||||||
|
protection-range: "Protection range: [range]"
|
||||||
|
max-protection-range: "Largest historical protection range: [range]"
|
||||||
|
protection-coords: "Protection coordinates: [xz1] to [xz2]"
|
||||||
|
is-spawn: "Cave is a spawn cave"
|
||||||
|
banned-players: "Banned players:"
|
||||||
|
banned-format: "&c[name]"
|
||||||
|
unowned: "&cUnowned"
|
||||||
|
setrange:
|
||||||
|
description: "set the range of player's cave"
|
||||||
|
range-updated: "Cave range updated to [number]"
|
||||||
|
tp:
|
||||||
|
parameters: "<player>"
|
||||||
|
description: "teleport to a player's cave"
|
||||||
|
getrank:
|
||||||
|
description: "get a player's rank in their cave"
|
||||||
|
rank-is: "&aRank is [rank] in their cave."
|
||||||
|
setrank:
|
||||||
|
description: "set a player's rank in their cave"
|
||||||
|
setspawn:
|
||||||
|
description: "set a cave as spawn for this world"
|
||||||
|
already-spawn: "&cThis cave is already a spawn!"
|
||||||
|
no-island-here: "&cThere is no registered cave here."
|
||||||
|
confirmation: "&cAre you sure you want to set this cave as the spawn for this world?"
|
||||||
|
delete:
|
||||||
|
parameters: ""
|
||||||
|
description: "deletes a player and regenerates their cave"
|
||||||
|
cannot-delete-owner: "&cAll team members must be kicked before deleting."
|
||||||
|
deleted-island: "&aCave at &e[xyz] &ahas been successfully regenerated."
|
||||||
|
|
||||||
|
protection:
|
||||||
|
flags:
|
||||||
|
ELYTRA:
|
||||||
|
description: "Toggle use"
|
||||||
|
ENDERMAN_GRIEFING:
|
||||||
|
description: |-
|
||||||
|
&aEndermen can remove
|
||||||
|
&ablocks
|
||||||
|
ENTER_EXIT_MESSAGES:
|
||||||
|
description: "Display entry and exit messages"
|
||||||
|
island: "[name]'s protected cave"
|
||||||
|
name: "Enter/Exit messages"
|
||||||
|
now-entering: "&bNow entering [name]"
|
||||||
|
now-leaving: "&bNow leaving [name]"
|
||||||
|
GEO_LIMIT_MOBS:
|
||||||
|
description: |-
|
||||||
|
&aRemove mobs that go
|
||||||
|
&aoutside protected
|
||||||
|
&aplayer space
|
||||||
|
name: "&eLimit mobs to player cave"
|
||||||
|
ISLAND_RESPAWN:
|
||||||
|
description: |-
|
||||||
|
&aPlayers respawn
|
||||||
|
&ain their cave
|
||||||
|
name: "Cave respawn"
|
||||||
|
LOCK:
|
||||||
|
name: "Lock player cave"
|
||||||
|
OFFLINE_REDSTONE:
|
||||||
|
description: |-
|
||||||
|
&aWhen disabled, redstone
|
||||||
|
&awill not operate in caves
|
||||||
|
&awhere all members are offline.
|
||||||
|
&aMay help reduce lag.
|
||||||
|
PISTON_PUSH:
|
||||||
|
description: |-
|
||||||
|
&aAllow pistons to push
|
||||||
|
&ablocks outside a player's cave
|
||||||
|
PVP_OVERWORLD:
|
||||||
|
description: |-
|
||||||
|
&cEnable/Disable PVP
|
||||||
|
&cin protected cave.
|
||||||
|
REMOVE_MOBS:
|
||||||
|
description: |-
|
||||||
|
&aRemove monsters when
|
||||||
|
&ateleporting to a cave
|
||||||
|
PREVENT_TELEPORT_WHEN_FALLING:
|
||||||
|
description: |-
|
||||||
|
&aPrevent players from teleporting
|
||||||
|
&aif they are falling.
|
||||||
|
hint: "&cYou cannot teleport while you are falling!"
|
||||||
|
locked: "&cThis cave is locked!"
|
||||||
|
protected: "&ccave protected: [description]"
|
||||||
|
|
||||||
|
panel:
|
||||||
|
PROTECTION:
|
||||||
|
title: "&6Protection"
|
||||||
|
description: |-
|
||||||
|
&aProtection settings
|
||||||
|
&afor this cave
|
||||||
|
SETTING:
|
||||||
|
description: |-
|
||||||
|
&aGeneral settings
|
||||||
|
&afor this cave
|
||||||
|
|
@ -578,7 +578,7 @@ blocks:
|
|||||||
'24':
|
'24':
|
||||||
==: org.bukkit.inventory.ItemStack
|
==: org.bukkit.inventory.ItemStack
|
||||||
v: 1631
|
v: 1631
|
||||||
type: BEETROOT
|
type: beetroot_seeds
|
||||||
'26':
|
'26':
|
||||||
==: org.bukkit.inventory.ItemStack
|
==: org.bukkit.inventory.ItemStack
|
||||||
v: 1631
|
v: 1631
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
Reference in New Issue
Block a user