mirror of
https://github.com/BentoBoxWorld/Greenhouses.git
synced 2024-11-29 14:16:08 +01:00
Basics there. Lots of bugs.
This commit is contained in:
parent
075c9bcc78
commit
71383b0adb
5
.settings/org.eclipse.core.resources.prefs
Normal file
5
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding/<project>=UTF-8
|
File diff suppressed because it is too large
Load Diff
@ -1,193 +0,0 @@
|
||||
package world.bentobox.greenhouses;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
* Provides a memory cache of online player information
|
||||
* This is the one-stop-shop of player info
|
||||
*/
|
||||
public class PlayerCache {
|
||||
private HashMap<UUID, Players> playerCache = new HashMap<UUID, Players>();
|
||||
private final Greenhouses plugin;
|
||||
|
||||
public PlayerCache(Greenhouses plugin) {
|
||||
this.plugin = plugin;
|
||||
playerCache.clear();
|
||||
// Add any players currently online (handles the /reload condition)
|
||||
final Collection<? extends Player> serverPlayers = plugin.getServer().getOnlinePlayers();
|
||||
for (Player p : serverPlayers) {
|
||||
// Add this player to the online cache
|
||||
playerCache.put(p.getUniqueId(), new Players(p));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a player to the cache when they join the server (called in JoinLeaveEvents)
|
||||
* @param player
|
||||
*/
|
||||
public void addPlayer(Player player) {
|
||||
if (!playerCache.containsKey(player.getUniqueId())) {
|
||||
playerCache.put(player.getUniqueId(),new Players(player));
|
||||
}
|
||||
// Check permission limits on number of greenhouses
|
||||
int limit = plugin.getMaxGreenhouses(player); // 0 = none allowed. Positive numbers = limit. Negative = unlimited
|
||||
/*
|
||||
if (plugin.getPlayerGHouse(player.getUniqueId()) == null) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
List<Greenhouse> toBeRemoved = new ArrayList<Greenhouse>();
|
||||
// Look at how many greenhouses player has and remove any over their limit
|
||||
int owned = 0;
|
||||
for (Greenhouse g: plugin.getGreenhouses()) {
|
||||
if (g.getOwner().equals(player.getUniqueId())) {
|
||||
owned++;
|
||||
if (owned <= limit) {
|
||||
// Allowed
|
||||
playerCache.get(player.getUniqueId()).incrementGreenhouses();
|
||||
g.setPlayerName(player.getName());
|
||||
} else {
|
||||
// Over the limit
|
||||
toBeRemoved.add(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Settings.deleteExtras && limit >= 0) {
|
||||
// Remove greenhouses
|
||||
for (Greenhouse g : toBeRemoved) {
|
||||
plugin.removeGreenhouse(g);
|
||||
plugin.logger(2,"Removed greenhouse over the limit for " + player.getName());
|
||||
}
|
||||
if (toBeRemoved.size() > 0) {
|
||||
if (limit == 0) {
|
||||
player.sendMessage(ChatColor.RED + Locale.limitsnoneallowed.replace("[number]",String.valueOf(toBeRemoved.size())));
|
||||
} else {
|
||||
player.sendMessage(ChatColor.RED + Locale.limitslimitedto.replace("[limit]", String.valueOf(limit)).replace("[number]",String.valueOf(toBeRemoved.size())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void removeOnlinePlayer(Player player) {
|
||||
if (playerCache.containsKey(player.getUniqueId())) {
|
||||
playerCache.remove(player);
|
||||
plugin.logger(3,"Removing player from cache: " + player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all players on the server now from cache and saves their info
|
||||
*/
|
||||
public void removeAllPlayers() {
|
||||
playerCache.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* Player info query methods
|
||||
*/
|
||||
/*
|
||||
public void setInGreenhouse(Player player, Greenhouse inGreenhouse) {
|
||||
if (playerCache.containsKey(player.getUniqueId())) {
|
||||
playerCache.get(player.getUniqueId()).setInGreenhouse(inGreenhouse);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* @param playerUUID
|
||||
* @return the greenhouse the player is in or null if no greenhouse
|
||||
*/
|
||||
public Greenhouse getInGreenhouse(Player player) {
|
||||
for (Greenhouse g : plugin.getGreenhouses()) {
|
||||
if (g.insideGreenhouse(player.getLocation())) {
|
||||
return g;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the player's greenhouse count if permissions allow
|
||||
* @param player
|
||||
* @return true if successful, otherwise false
|
||||
*/
|
||||
public boolean incGreenhouseCount(Player player) {
|
||||
// Do a permission check if there are limits
|
||||
// Check permission limits on number of greenhouses
|
||||
int limit = plugin.getMaxGreenhouses(player); // 0 = none allowed. Positive numbers = limit. Negative = unlimited
|
||||
if (limit < 0 || playerCache.get(player.getUniqueId()).getNumberOfGreenhouses() < limit) {
|
||||
playerCache.get(player.getUniqueId()).incrementGreenhouses();
|
||||
return true;
|
||||
}
|
||||
|
||||
// At the limit, sorry
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the number of greenhouses this player has
|
||||
* @param player
|
||||
*/
|
||||
public void decGreenhouseCount(Player player) {
|
||||
playerCache.get(player.getUniqueId()).decrementGreenhouses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements by UUID
|
||||
* @param playerUUID
|
||||
*/
|
||||
public void decGreenhouseCount(UUID playerUUID) {
|
||||
if (playerCache.containsKey(playerUUID)) {
|
||||
playerCache.get(playerUUID).decrementGreenhouses();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the player is at their permitted limit of greenhouses otherwise false
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean isAtLimit(Player player) {
|
||||
if (getRemainingGreenhouses(player) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many greenhouses the player is allowed to make
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public int getRemainingGreenhouses(Player player) {
|
||||
int limit = plugin.getMaxGreenhouses(player);
|
||||
if (limit < 0) {
|
||||
return -1;
|
||||
}
|
||||
int size = 0;
|
||||
if (plugin.getPlayerhouses().containsKey(player.getUniqueId())) {
|
||||
size = plugin.getPlayerhouses().get(player.getUniqueId()).size();
|
||||
}
|
||||
int remaining = limit - size;
|
||||
if (remaining < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return remaining;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
package world.bentobox.greenhouses;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
|
||||
/**
|
||||
* Tracks the following info on the player
|
||||
* UUID, player name, whether they are in a greenhouse or not and how many greenhouses they have
|
||||
*/
|
||||
public class Players {
|
||||
private UUID uuid;
|
||||
private Greenhouse inGreenhouse;
|
||||
private int numberOfGreenhouses;
|
||||
|
||||
/**
|
||||
* @param uuid
|
||||
* Constructor - initializes the state variables
|
||||
*
|
||||
*/
|
||||
public Players(final Player player) {
|
||||
this.uuid = player.getUniqueId();
|
||||
// We do not know if the player is in a greenhouse or not yet
|
||||
this.inGreenhouse = null;
|
||||
// We start with the assumption they have no greenhouses yet
|
||||
this.numberOfGreenhouses = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the inGreenhouse
|
||||
*/
|
||||
public Greenhouse getInGreenhouse() {
|
||||
return inGreenhouse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inGreenhouse the inGreenhouse to set
|
||||
*/
|
||||
public void setInGreenhouse(Greenhouse inGreenhouse) {
|
||||
this.inGreenhouse = inGreenhouse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the numberOfGreenhouses
|
||||
*/
|
||||
public int getNumberOfGreenhouses() {
|
||||
return numberOfGreenhouses;
|
||||
}
|
||||
|
||||
public void incrementGreenhouses() {
|
||||
numberOfGreenhouses++;
|
||||
}
|
||||
|
||||
public void decrementGreenhouses() {
|
||||
numberOfGreenhouses--;
|
||||
if (numberOfGreenhouses < 0) {
|
||||
numberOfGreenhouses = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the uuid
|
||||
*/
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +1,193 @@
|
||||
package world.bentobox.greenhouses;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.configuration.ConfigComment;
|
||||
import world.bentobox.bentobox.api.configuration.ConfigEntry;
|
||||
import world.bentobox.bentobox.api.configuration.StoreAt;
|
||||
import world.bentobox.bentobox.database.objects.DataObject;
|
||||
|
||||
|
||||
/**
|
||||
* @author ben
|
||||
* @author tastybento
|
||||
* Where all the settings are
|
||||
*/
|
||||
public class Settings {
|
||||
@StoreAt(filename="config.yml", path="addons/Greenhouses") // Explicitly call out what name this should have.
|
||||
@ConfigComment("Greenhouses Configuration [version]")
|
||||
@ConfigComment("")
|
||||
public class Settings implements DataObject {
|
||||
|
||||
// General
|
||||
public static List<String> worldName;
|
||||
public static double snowChanceGlobal;
|
||||
public static double snowDensity;
|
||||
public static long snowSpeed;
|
||||
public static int plantTick;
|
||||
public static int iceInfluence;
|
||||
public static int blockTick;
|
||||
public static int mobTick;
|
||||
public static int ecoTick;
|
||||
public static boolean allowFlowIn;
|
||||
public static boolean allowFlowOut;
|
||||
public static boolean deleteExtras;
|
||||
public static int maxGreenhouses;
|
||||
@ConfigComment("BentoBox GameModes that will use Greenhouses")
|
||||
@ConfigEntry(path = "greenhouses.game-modes")
|
||||
private List<String> gameModes = new ArrayList<>();
|
||||
|
||||
@ConfigComment("Weather and ecosystem settings")
|
||||
@ConfigComment("How often it should snow in the g/h when the weather is raining, in seconds")
|
||||
@ConfigEntry(path = "greenhouses.snowspeed")
|
||||
private double snowSpeed = 30;
|
||||
|
||||
@ConfigComment("Chance of any snow falling in a greenhouse when the snow tick occurs")
|
||||
@ConfigComment("(1.0 = always, 0.0 = never)")
|
||||
@ConfigEntry(path = "greenhouses.snowchance")
|
||||
private double snowChanceGlobal = 1;
|
||||
@ConfigComment("How many blocks should get snow 1 = all of them, 0 = none, 0.1 = 1 in 10")
|
||||
@ConfigEntry(path = "greenhouses.snowdensity")
|
||||
private double snowDensity = 0.1;
|
||||
|
||||
@ConfigComment("Biome activity")
|
||||
@ConfigComment("How often should greenhouse biomes be checked to make sure they are still valid")
|
||||
@ConfigEntry(path = "greenhouses.ecotick")
|
||||
private int ecoTick = 5;
|
||||
@ConfigComment("How often should plants potentially grow in minutes if bonemeal is in the hopper")
|
||||
@ConfigEntry(path = "greenhouses.planttick")
|
||||
private int plantTick = 1;
|
||||
@ConfigComment("How often should blocks potentially convert, in minutes ")
|
||||
@ConfigComment("Example: dirt-> sand in desert greenhouse")
|
||||
@ConfigEntry(path = "greenhouses.blocktick")
|
||||
private int blockTick = 2;
|
||||
@ConfigComment("How often should mobs be potentially spawned in a greenhouse, in minutes")
|
||||
@ConfigEntry(path = "greenhouses.mobtick")
|
||||
private int mobTick = 5;
|
||||
|
||||
|
||||
@ConfigComment("Default settings for greenhouse actions")
|
||||
@ConfigComment("Allow lava or water to flow out of a greenhouse, e.g. through the door, floor")
|
||||
@ConfigEntry(path = "greenhouses.allowflowout")
|
||||
private boolean allowFlowOut;
|
||||
@ConfigComment("Allow lava or water to flow into a greenhouse, e.g., through the door")
|
||||
@ConfigEntry(path = "greenhouses.allowflowin")
|
||||
private boolean allowFlowIn;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return "config";
|
||||
}
|
||||
@Override
|
||||
public void setUniqueId(String uniqueId) {}
|
||||
/**
|
||||
* @return the gameModes
|
||||
*/
|
||||
public List<String> getGameModes() {
|
||||
return gameModes;
|
||||
}
|
||||
/**
|
||||
* @return the snowSpeed
|
||||
*/
|
||||
public double getSnowSpeed() {
|
||||
return snowSpeed;
|
||||
}
|
||||
/**
|
||||
* @return the snowChanceGlobal
|
||||
*/
|
||||
public double getSnowChanceGlobal() {
|
||||
return snowChanceGlobal;
|
||||
}
|
||||
/**
|
||||
* @return the snowDensity
|
||||
*/
|
||||
public double getSnowDensity() {
|
||||
return snowDensity;
|
||||
}
|
||||
/**
|
||||
* @return the ecoTick
|
||||
*/
|
||||
public int getEcoTick() {
|
||||
return ecoTick;
|
||||
}
|
||||
/**
|
||||
* @return the plantTick
|
||||
*/
|
||||
public int getPlantTick() {
|
||||
return plantTick;
|
||||
}
|
||||
/**
|
||||
* @return the blockTick
|
||||
*/
|
||||
public int getBlockTick() {
|
||||
return blockTick;
|
||||
}
|
||||
/**
|
||||
* @return the mobTick
|
||||
*/
|
||||
public int getMobTick() {
|
||||
return mobTick;
|
||||
}
|
||||
/**
|
||||
* @return the allowFlowOut
|
||||
*/
|
||||
public boolean isAllowFlowOut() {
|
||||
return allowFlowOut;
|
||||
}
|
||||
/**
|
||||
* @return the allowFlowIn
|
||||
*/
|
||||
public boolean isAllowFlowIn() {
|
||||
return allowFlowIn;
|
||||
}
|
||||
/**
|
||||
* @param gameModes the gameModes to set
|
||||
*/
|
||||
public void setGameModes(List<String> gameModes) {
|
||||
this.gameModes = gameModes;
|
||||
}
|
||||
/**
|
||||
* @param snowSpeed the snowSpeed to set
|
||||
*/
|
||||
public void setSnowSpeed(double snowSpeed) {
|
||||
this.snowSpeed = snowSpeed;
|
||||
}
|
||||
/**
|
||||
* @param snowChanceGlobal the snowChanceGlobal to set
|
||||
*/
|
||||
public void setSnowChanceGlobal(double snowChanceGlobal) {
|
||||
this.snowChanceGlobal = snowChanceGlobal;
|
||||
}
|
||||
/**
|
||||
* @param snowDensity the snowDensity to set
|
||||
*/
|
||||
public void setSnowDensity(double snowDensity) {
|
||||
this.snowDensity = snowDensity;
|
||||
}
|
||||
/**
|
||||
* @param ecoTick the ecoTick to set
|
||||
*/
|
||||
public void setEcoTick(int ecoTick) {
|
||||
this.ecoTick = ecoTick;
|
||||
}
|
||||
/**
|
||||
* @param plantTick the plantTick to set
|
||||
*/
|
||||
public void setPlantTick(int plantTick) {
|
||||
this.plantTick = plantTick;
|
||||
}
|
||||
/**
|
||||
* @param blockTick the blockTick to set
|
||||
*/
|
||||
public void setBlockTick(int blockTick) {
|
||||
this.blockTick = blockTick;
|
||||
}
|
||||
/**
|
||||
* @param mobTick the mobTick to set
|
||||
*/
|
||||
public void setMobTick(int mobTick) {
|
||||
this.mobTick = mobTick;
|
||||
}
|
||||
/**
|
||||
* @param allowFlowOut the allowFlowOut to set
|
||||
*/
|
||||
public void setAllowFlowOut(boolean allowFlowOut) {
|
||||
this.allowFlowOut = allowFlowOut;
|
||||
}
|
||||
/**
|
||||
* @param allowFlowIn the allowFlowIn to set
|
||||
*/
|
||||
public void setAllowFlowIn(boolean allowFlowIn) {
|
||||
this.allowFlowIn = allowFlowIn;
|
||||
}
|
||||
|
||||
}
|
195
src/main/java/world/bentobox/greenhouses/data/Greenhouse.java
Normal file
195
src/main/java/world/bentobox/greenhouses/data/Greenhouse.java
Normal file
@ -0,0 +1,195 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package world.bentobox.greenhouses.data;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import world.bentobox.bentobox.database.objects.DataObject;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class Greenhouse implements DataObject {
|
||||
|
||||
private String uniqueId = UUID.randomUUID().toString();
|
||||
private Location location;
|
||||
private Rectangle footprint;
|
||||
private int ceilingHeight;
|
||||
private Biome originalBiome;
|
||||
private Biome greenhouseBiome;
|
||||
private Location roofHopperLocation;
|
||||
private BiomeRecipe biomeRecipe;
|
||||
private boolean broken;
|
||||
|
||||
public Greenhouse() {}
|
||||
|
||||
/**
|
||||
* @param world
|
||||
* @param footprint
|
||||
* @param ceilingHeight
|
||||
*/
|
||||
public Greenhouse(World world, Rectangle footprint, int floorHeight, int ceilingHeight) {
|
||||
this.location = new Location(world, footprint.getMinX(), floorHeight, footprint.getMinY());
|
||||
this.footprint = footprint;
|
||||
this.ceilingHeight = ceilingHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the biomeRecipe
|
||||
*/
|
||||
public BiomeRecipe getBiomeRecipe() {
|
||||
return biomeRecipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ceilingHeight
|
||||
*/
|
||||
public int getCeilingHeight() {
|
||||
return ceilingHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the floorHeight
|
||||
*/
|
||||
public int getFloorHeight() {
|
||||
return location.getBlockY();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the floor
|
||||
*/
|
||||
public Rectangle getFootprint() {
|
||||
return footprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the greenhouseBiome
|
||||
*/
|
||||
public Biome getGreenhouseBiome() {
|
||||
return greenhouseBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the originalBiome
|
||||
*/
|
||||
public Biome getOriginalBiome() {
|
||||
return originalBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roofHopperLocation
|
||||
*/
|
||||
public Location getRoofHopperLocation() {
|
||||
return roofHopperLocation;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see world.bentobox.bentobox.database.objects.DataObject#getUniqueId()
|
||||
*/
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the broken
|
||||
*/
|
||||
public boolean isBroken() {
|
||||
return broken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param biomeRecipe the biomeRecipe to set
|
||||
*/
|
||||
public void setBiomeRecipe(BiomeRecipe biomeRecipe) {
|
||||
this.biomeRecipe = biomeRecipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param broken the broken to set
|
||||
*/
|
||||
public void setBroken(boolean broken) {
|
||||
this.broken = broken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ceilingHeight the ceilingHeight to set
|
||||
*/
|
||||
public void setCeilingHeight(int ceilingHeight) {
|
||||
this.ceilingHeight = ceilingHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param floor the floor to set
|
||||
*/
|
||||
public void setFootprint(Rectangle floor) {
|
||||
this.footprint = floor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param greenhouseBiome the greenhouseBiome to set
|
||||
*/
|
||||
public void setGreenhouseBiome(Biome greenhouseBiome) {
|
||||
this.greenhouseBiome = greenhouseBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param location the location to set
|
||||
*/
|
||||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param originalBiome the originalBiome to set
|
||||
*/
|
||||
public void setOriginalBiome(Biome originalBiome) {
|
||||
this.originalBiome = originalBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param roofHopperLocation the roofHopperLocation to set
|
||||
*/
|
||||
public void setRoofHopperLocation(Location roofHopperLocation) {
|
||||
this.roofHopperLocation = roofHopperLocation;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see world.bentobox.bentobox.database.objects.DataObject#setUniqueId(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setUniqueId(String uniqueId) {
|
||||
this.uniqueId = uniqueId;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return area of greenhouse
|
||||
*/
|
||||
public int getArea() {
|
||||
return this.footprint.height * this.footprint.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the world
|
||||
*/
|
||||
public World getWorld() {
|
||||
return this.getLocation().getWorld();
|
||||
}
|
||||
|
||||
}
|
@ -2,27 +2,27 @@ package world.bentobox.greenhouses.greenhouse;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
||||
|
||||
public class BiomeRecipe {
|
||||
public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
||||
private Greenhouses plugin;
|
||||
private Biome type;
|
||||
private Material icon; // Biome icon for control panel
|
||||
@ -53,16 +53,17 @@ public class BiomeRecipe {
|
||||
|
||||
private String permission = "";
|
||||
private Random random = new Random();
|
||||
private Map<Material, Integer> missingBlocks;
|
||||
|
||||
/**
|
||||
* @param type
|
||||
* @param priority
|
||||
*/
|
||||
public BiomeRecipe(Greenhouses plugin, Biome type, int priority) {
|
||||
this.plugin = plugin;
|
||||
public BiomeRecipe(Greenhouses addon, Biome type, int priority) {
|
||||
this.plugin = addon;
|
||||
this.type = type;
|
||||
this.priority = priority;
|
||||
plugin.logger(3,"" + type.toString() + " priority " + priority);
|
||||
//addon.logger(3,"" + type.toString() + " priority " + priority);
|
||||
mobLimit = 9; // Default
|
||||
}
|
||||
|
||||
@ -75,7 +76,7 @@ public class BiomeRecipe {
|
||||
public void addConvBlocks(Material oldMaterial, Material newMaterial, double convChance, Material localMaterial) {
|
||||
double probability = Math.min(convChance/100 , 1D);
|
||||
conversionBlocks.put(oldMaterial, new GreenhouseBlockConversions(oldMaterial, newMaterial, probability, localMaterial));
|
||||
plugin.logger(1," " + convChance + "% chance for " + Util.prettifyText(oldMaterial.toString()) + " to convert to " + Util.prettifyText(newMaterial.toString()));
|
||||
//plugin.logger(1," " + convChance + "% chance for " + Util.prettifyText(oldMaterial.toString()) + " to convert to " + Util.prettifyText(newMaterial.toString()));
|
||||
}
|
||||
|
||||
|
||||
@ -85,12 +86,13 @@ public class BiomeRecipe {
|
||||
* @param mobSpawnOn
|
||||
*/
|
||||
public void addMobs(EntityType mobType, int mobProbability, Material mobSpawnOn) {
|
||||
plugin.logger(1," " + mobProbability + "% chance for " + Util.prettifyText(mobType.toString()) + " to spawn on " + Util.prettifyText(mobSpawnOn.toString())+ ".");
|
||||
//plugin.logger(1," " + mobProbability + "% chance for " + Util.prettifyText(mobType.toString()) + " to spawn on " + Util.prettifyText(mobSpawnOn.toString())+ ".");
|
||||
double probability = ((double)mobProbability/100);
|
||||
double lastProb = mobTree.isEmpty() ? 0D : mobTree.lastKey();
|
||||
// Add up all the probabilities in the list so far
|
||||
if ((1D - mobTree.lastKey()) >= probability) {
|
||||
if ((1D - lastProb) >= probability) {
|
||||
// Add to probability tree
|
||||
mobTree.put(mobTree.lastKey() + probability, new GreenhouseMob(mobType, mobSpawnOn));
|
||||
mobTree.put(lastProb + probability, new GreenhouseMob(mobType, mobSpawnOn));
|
||||
} else {
|
||||
plugin.logError("Mob chances add up to > 100% in " + type.toString() + " biome recipe! Skipping " + mobType.toString());
|
||||
}
|
||||
@ -106,13 +108,14 @@ public class BiomeRecipe {
|
||||
public void addPlants(Material plantMaterial, int plantProbability, Material plantGrowOn) {
|
||||
double probability = ((double)plantProbability/100);
|
||||
// Add up all the probabilities in the list so far
|
||||
if ((1D - plantTree.lastKey()) >= probability) {
|
||||
double lastProb = plantTree.isEmpty() ? 0D : plantTree.lastKey();
|
||||
if ((1D - lastProb) >= probability) {
|
||||
// Add to probability tree
|
||||
plantTree.put(plantTree.lastKey() + probability, new GreenhousePlant(plantMaterial, plantGrowOn));
|
||||
plantTree.put(lastProb + probability, new GreenhousePlant(plantMaterial, plantGrowOn));
|
||||
} else {
|
||||
plugin.logError("Plant chances add up to > 100% in " + type.toString() + " biome recipe! Skipping " + plantMaterial.toString());
|
||||
}
|
||||
plugin.logger(1," " + plantProbability + "% chance for " + Util.prettifyText(plantMaterial.toString()) + " to grow on " + Util.prettifyText(plantGrowOn.toString()));
|
||||
//plugin.logger(1," " + plantProbability + "% chance for " + Util.prettifyText(plantMaterial.toString()) + " to grow on " + Util.prettifyText(plantGrowOn.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,31 +124,24 @@ public class BiomeRecipe {
|
||||
*/
|
||||
public void addReqBlocks(Material blockMaterial, int blockQty) {
|
||||
requiredBlocks.put(blockMaterial, blockQty);
|
||||
plugin.logger(1," " + blockMaterial + " x " + blockQty);
|
||||
//plugin.logger(1," " + blockMaterial + " x " + blockQty);
|
||||
}
|
||||
|
||||
// Check required blocks
|
||||
/**
|
||||
* Checks greenhouse meets recipe requirements. If player is not null, a explanation of
|
||||
* any failures will be provided.
|
||||
* @param pos1
|
||||
* @param pos2
|
||||
* @param player
|
||||
* @return true if a cube defined by pos1 and pos2 meet this biome recipe.
|
||||
* @return true if meet this biome recipe.
|
||||
*/
|
||||
public boolean checkRecipe(Location pos1, Location pos2, Player player) {
|
||||
plugin.logger(3,"Checking for biome " + type.toString());
|
||||
long area = (pos2.getBlockX()-pos1.getBlockX()-1) * (pos2.getBlockZ()-pos1.getBlockZ()-1);
|
||||
plugin.logger(3,"area =" + area);
|
||||
plugin.logger(3,"Pos1 = " + pos1.toString());
|
||||
plugin.logger(3,"Pos1 = " + pos2.toString());
|
||||
boolean pass = true;
|
||||
public Set<GreenhouseResult> checkRecipe(Greenhouse gh) {
|
||||
Set<GreenhouseResult> result = new HashSet<>();
|
||||
long area = gh.getArea();
|
||||
Map<Material, Integer> blockCount = new HashMap<>();
|
||||
// Look through the greenhouse and count what is in there
|
||||
for (int y = pos1.getBlockY(); y<pos2.getBlockY();y++) {
|
||||
for (int x = pos1.getBlockX()+1;x<pos2.getBlockX();x++) {
|
||||
for (int z = pos1.getBlockZ()+1;z<pos2.getBlockZ();z++) {
|
||||
Block b = pos1.getWorld().getBlockAt(x, y, z);
|
||||
for (int y = gh.getFloorHeight(); y< gh.getCeilingHeight();y++) {
|
||||
for (int x = (int) (gh.getFootprint().getMinX()+1); x < gh.getFootprint().getMaxX(); x++) {
|
||||
for (int z = (int) (gh.getFootprint().getMinY()+1); z < gh.getFootprint().getMaxY(); z++) {
|
||||
Block b = gh.getWorld().getBlockAt(x, y, z);
|
||||
if (!b.getType().equals(Material.AIR)) {
|
||||
blockCount.putIfAbsent(b.getType(), 0);
|
||||
blockCount.merge(b.getType(), 1, Integer::sum);
|
||||
@ -161,64 +157,41 @@ public class BiomeRecipe {
|
||||
|| en.getKey().equals(Material.PACKED_ICE))
|
||||
.mapToInt(Map.Entry::getValue).sum();
|
||||
double iceRatio = (double)ice/(double)area * 100;
|
||||
plugin.logger(3,"water req=" + waterCoverage + " lava req=" + lavaCoverage + " ice req="+iceCoverage);
|
||||
plugin.logger(3,"waterRatio=" + waterRatio + " lavaRatio=" + lavaRatio + " iceRatio="+iceRatio);
|
||||
//plugin.logger(3,"water req=" + waterCoverage + " lava req=" + lavaCoverage + " ice req="+iceCoverage);
|
||||
//plugin.logger(3,"waterRatio=" + waterRatio + " lavaRatio=" + lavaRatio + " iceRatio="+iceRatio);
|
||||
|
||||
|
||||
// Check required ratios - a zero means none of these are allowed, e.g.desert has no water
|
||||
if (waterCoverage == 0 && waterRatio > 0) {
|
||||
if (player != null) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipenowater);
|
||||
}
|
||||
pass=false;
|
||||
result.add(GreenhouseResult.FAIL_NO_WATER);
|
||||
}
|
||||
if (lavaCoverage == 0 && lavaRatio > 0) {
|
||||
if (player != null) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipenolava);
|
||||
}
|
||||
pass=false;
|
||||
result.add(GreenhouseResult.FAIL_NO_LAVA);
|
||||
}
|
||||
if (iceCoverage == 0 && iceRatio > 0) {
|
||||
if (player != null) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipenoice);
|
||||
}
|
||||
pass=false;
|
||||
result.add(GreenhouseResult.FAIL_NO_ICE);
|
||||
}
|
||||
if (waterCoverage > 0 && waterRatio < waterCoverage) {
|
||||
if (player != null) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipewatermustbe.replace("[coverage]", String.valueOf(waterCoverage)));
|
||||
}
|
||||
pass=false;
|
||||
result.add(GreenhouseResult.FAIL_INSUFFICIENT_WATER);
|
||||
}
|
||||
if (lavaCoverage > 0 && lavaRatio < lavaCoverage) {
|
||||
if (player != null) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipelavamustbe.replace("[coverage]", String.valueOf(lavaCoverage)));
|
||||
}
|
||||
pass=false;
|
||||
|
||||
result.add(GreenhouseResult.FAIL_INSUFFICIENT_LAVA);
|
||||
}
|
||||
if (iceCoverage > 0 && iceRatio < iceCoverage) {
|
||||
if (player != null) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipeicemustbe.replace("[coverage]", String.valueOf(iceCoverage)));
|
||||
}
|
||||
pass=false;
|
||||
result.add(GreenhouseResult.FAIL_INSUFFICIENT_ICE);
|
||||
}
|
||||
// Compare to the required blocks
|
||||
Map<Material, Integer> missingBlocks = requiredBlocks.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - blockCount.getOrDefault(e.getKey(), 0)));
|
||||
missingBlocks = requiredBlocks.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - blockCount.getOrDefault(e.getKey(), 0)));
|
||||
// Remove any entries that are 0 or less
|
||||
missingBlocks.values().removeIf(v -> v <= 0);
|
||||
if (!missingBlocks.isEmpty()) {
|
||||
pass = false;
|
||||
}
|
||||
missingBlocks.forEach((k,v) -> player.sendMessage(ChatColor.RED + Locale.recipemissing + " " + Util.prettifyText(k.toString()) + " x " + v));
|
||||
return pass;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param b
|
||||
*/
|
||||
public void convertBlock(Block b) {
|
||||
plugin.logger(3,"try to convert block");
|
||||
//plugin.logger(3,"try to convert block");
|
||||
GreenhouseBlockConversions bc = conversionBlocks.get(b.getType());
|
||||
if (bc == null || random.nextDouble() > bc.getProbability()) {
|
||||
return;
|
||||
@ -226,7 +199,7 @@ public class BiomeRecipe {
|
||||
// Check if the block is in the right area, up, down, n,s,e,w
|
||||
if (ADJ_BLOCKS.stream().map(b::getRelative).map(Block::getType).anyMatch(m -> bc.getLocalMaterial() == null || m == bc.getLocalMaterial())) {
|
||||
// Convert!
|
||||
plugin.logger(3,"Convert block");
|
||||
//plugin.logger(3,"Convert block");
|
||||
b.setType(bc.getNewMaterial());
|
||||
}
|
||||
}
|
||||
@ -333,18 +306,20 @@ public class BiomeRecipe {
|
||||
|
||||
/**
|
||||
* Plants a plant on block bl if it makes sense.
|
||||
* @param bl
|
||||
* @return
|
||||
* @param bl - block
|
||||
* @return true if successful
|
||||
*/
|
||||
public void growPlant(Block bl) {
|
||||
public boolean growPlant(Block bl) {
|
||||
if (bl.getType() != Material.AIR) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
getRandomPlant().ifPresent(p -> {
|
||||
return getRandomPlant().map(p -> {
|
||||
if (bl.getY() != 0 && p.getPlantGrownOn().map(m -> m.equals(bl.getRelative(BlockFace.DOWN).getType())).orElse(true)) {
|
||||
bl.setType(p.getPlantMaterial());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}).orElse(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,9 +333,9 @@ public class BiomeRecipe {
|
||||
*/
|
||||
public void setIcecoverage(int icecoverage) {
|
||||
if (icecoverage == 0) {
|
||||
plugin.logger(1," No Ice Allowed");
|
||||
//plugin.logger(1," No Ice Allowed");
|
||||
} else if (icecoverage > 0) {
|
||||
plugin.logger(1," Ice > " + icecoverage + "%");
|
||||
//plugin.logger(1," Ice > " + icecoverage + "%");
|
||||
}
|
||||
this.iceCoverage = icecoverage;
|
||||
}
|
||||
@ -377,9 +352,9 @@ public class BiomeRecipe {
|
||||
*/
|
||||
public void setLavacoverage(int lavacoverage) {
|
||||
if (lavacoverage == 0) {
|
||||
plugin.logger(1," No Lava Allowed");
|
||||
//plugin.logger(1," No Lava Allowed");
|
||||
} else if (lavacoverage > 0) {
|
||||
plugin.logger(1," Lava > " + lavacoverage + "%");
|
||||
//plugin.logger(1," Lava > " + lavacoverage + "%");
|
||||
}
|
||||
this.lavaCoverage = lavacoverage;
|
||||
}
|
||||
@ -424,11 +399,23 @@ public class BiomeRecipe {
|
||||
*/
|
||||
public void setWatercoverage(int watercoverage) {
|
||||
if (watercoverage == 0) {
|
||||
plugin.logger(1," No Water Allowed");
|
||||
//plugin.logger(1," No Water Allowed");
|
||||
} else if (watercoverage > 0) {
|
||||
plugin.logger(1," Water > " + watercoverage + "%");
|
||||
//plugin.logger(1," Water > " + watercoverage + "%");
|
||||
}
|
||||
this.waterCoverage = watercoverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the missingBlocks
|
||||
*/
|
||||
public Map<Material, Integer> getMissingBlocks() {
|
||||
return missingBlocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BiomeRecipe o) {
|
||||
return Integer.compare(o.getPriority(), this.getPriority());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,144 +0,0 @@
|
||||
package world.bentobox.greenhouses.greenhouse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.Settings;
|
||||
|
||||
/**
|
||||
* Monitors the greenhouses and grows things, adds weather etc.
|
||||
* @author ben
|
||||
*
|
||||
*/
|
||||
public class Ecosystem implements Listener {
|
||||
private final Greenhouses addon;
|
||||
private final static List<Biome> SNOWBIOMES = Arrays.stream(Biome.values()).filter(b -> b.name().contains("COLD") || b.name().contains("ICE") || b.name().contains("FROZEN")).collect(Collectors.toList());
|
||||
private BukkitTask snow;
|
||||
private List<Greenhouse> snowGlobes = new ArrayList<Greenhouse>();
|
||||
|
||||
public Ecosystem(final Greenhouses plugin) {
|
||||
this.addon = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWeatherChangeEvent(final WeatherChangeEvent e) {
|
||||
if (!Settings.worldName.contains(e.getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
if (e.toWeatherState()) {
|
||||
// It's raining
|
||||
addon.logger(3,"It's raining!");
|
||||
startSnow();
|
||||
} else {
|
||||
// It's stopped raining!
|
||||
addon.logger(3,"Stopped raining!");
|
||||
if (snow != null)
|
||||
snow.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void startSnow() {
|
||||
if (snow != null) {
|
||||
// Cancel the old snow task
|
||||
snow.cancel();
|
||||
}
|
||||
|
||||
// Spin off scheduler
|
||||
snowGlobes.clear();
|
||||
snow = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
|
||||
|
||||
// Run through each greenhouse - only bother with snow biomes
|
||||
addon.logger(3,"started scheduler");
|
||||
// Check all the greenhouses and their hoppers and build a list of snow greenhouses that exist now
|
||||
List<Greenhouse> toBeRemoved = new ArrayList<Greenhouse>();
|
||||
for (Greenhouse g : addon.getGreenhouses()) {
|
||||
addon.logger(3,"Testing greenhouse biome : " + g.getBiome().toString());
|
||||
if (SNOWBIOMES.contains(g.getBiome())) {
|
||||
addon.logger(3,"Snow biome found!");
|
||||
// If it is already on the list, just snow, otherwise check if the hopper has water
|
||||
if (!snowGlobes.contains(g)) {
|
||||
Location hopper = g.getRoofHopperLocation();
|
||||
if (hopper != null) {
|
||||
addon.logger(3,"Hopper location:" + hopper.toString());
|
||||
Block b = hopper.getBlock();
|
||||
// Check the hopper is still there
|
||||
if (b.getType().equals(Material.HOPPER)) {
|
||||
Hopper h = (Hopper)b.getState();
|
||||
addon.logger(3,"Hopper found!");
|
||||
// Check what is in the hopper
|
||||
if (h.getInventory().contains(Material.WATER_BUCKET)) {
|
||||
// Remove the water in the bucket
|
||||
// We cannot remove an itemstack the easy way because on acid island the bucket is changed to acid
|
||||
for (ItemStack item : h.getInventory().getContents()) {
|
||||
if (item != null && item.getType().equals(Material.WATER_BUCKET)) {
|
||||
// Remove one from this item stack
|
||||
// Water buckets in theory do no stack...
|
||||
ItemStack i = item.clone();
|
||||
i.setAmount(1);
|
||||
h.getInventory().removeItem(i);
|
||||
h.getInventory().addItem(new ItemStack(Material.BUCKET));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add to list
|
||||
snowGlobes.add(g);
|
||||
}
|
||||
} else {
|
||||
// Greenhouse is broken or no longer has a hopper when it should
|
||||
addon.getLogger().warning("Hopper missing from greenhouse at " + g.getRoofHopperLocation().getBlockX() + " "
|
||||
+ g.getRoofHopperLocation().getBlockY() + " " + g.getRoofHopperLocation().getBlockZ());
|
||||
addon.getLogger().warning("Removing greenhouse");
|
||||
toBeRemoved.add(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!snowGlobes.isEmpty()) {
|
||||
snowOn(snowGlobes);
|
||||
}
|
||||
// Remove any greenhouses that need it
|
||||
for (Greenhouse g : toBeRemoved) {
|
||||
//UUID owner = g.getOwner();
|
||||
addon.removeGreenhouse(g);
|
||||
//plugin.players.save(owner);
|
||||
}
|
||||
addon.saveGreenhouses();
|
||||
}, 0L, (Settings.snowSpeed * 20L)); // Every 30 seconds
|
||||
|
||||
}
|
||||
|
||||
protected void snowOn(List<Greenhouse> snowGlobes) {
|
||||
for (Greenhouse g : snowGlobes) {
|
||||
addon.logger(3,"snowing in a greenhouse");
|
||||
// Chance of snow
|
||||
if (Math.random()>Settings.snowChanceGlobal)
|
||||
return;
|
||||
g.snow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any greenhouses that are currently in the eco system
|
||||
* @param g
|
||||
*/
|
||||
public void remove(Greenhouse g) {
|
||||
if (snowGlobes.contains(g))
|
||||
snowGlobes.remove(g);
|
||||
}
|
||||
|
||||
}
|
@ -1,606 +0,0 @@
|
||||
package world.bentobox.greenhouses.greenhouse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.block.data.type.Snow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import world.bentobox.bentobox.util.Pair;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.Settings;
|
||||
|
||||
/**
|
||||
* Defines a greenhouse
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class Greenhouse {
|
||||
private Greenhouses plugin;
|
||||
private final Location pos1;
|
||||
private final Location pos2;
|
||||
private final World world;
|
||||
private UUID owner;
|
||||
private String playerName;
|
||||
private HashMap<String,Object> flags = new HashMap<String,Object>();
|
||||
private Biome originalBiome;
|
||||
private Biome greenhouseBiome;
|
||||
private Location roofHopperLocation;
|
||||
private int area;
|
||||
private int heightY;
|
||||
private int height;
|
||||
private int groundY;
|
||||
private BiomeRecipe biomeRecipe;
|
||||
|
||||
|
||||
public Greenhouse(Greenhouses plugin, Location pos1, Location pos2, UUID owner) {
|
||||
this.plugin = plugin;
|
||||
this.pos1 = pos1;
|
||||
this.pos2 = pos2;
|
||||
int minx = Math.min(pos1.getBlockX(), pos2.getBlockX());
|
||||
int maxx = Math.max(pos1.getBlockX(), pos2.getBlockX());
|
||||
int minz = Math.min(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
int maxz = Math.max(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
this.area = (maxx-minx - 1) * (maxz-minz -1);
|
||||
this.heightY = Math.max(pos1.getBlockY(), pos2.getBlockY()); // Should always be pos2 is higher, but just in case
|
||||
this.groundY = Math.min(pos1.getBlockY(), pos2.getBlockY());
|
||||
this.height = heightY - groundY;
|
||||
this.world = pos1.getWorld();
|
||||
if (pos1.getWorld() == null || pos2.getWorld() == null) {
|
||||
plugin.getLogger().severe("This greenhouse's world does not exist!");
|
||||
} else {
|
||||
if (!pos1.getWorld().equals(pos2.getWorld())) {
|
||||
plugin.getLogger().severe("Pos 1 and Pos 2 are not in the same world!");
|
||||
}
|
||||
}
|
||||
this.originalBiome = pos1.getBlock().getBiome();
|
||||
this.greenhouseBiome = pos2.getBlock().getBiome();
|
||||
this.owner = owner;
|
||||
this.playerName = "";
|
||||
flags.put("enterMessage", "");
|
||||
flags.put("farewellMessage", "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the originalBiome
|
||||
*/
|
||||
public Biome getOriginalBiome() {
|
||||
return originalBiome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the greenhouseBiome
|
||||
*/
|
||||
public Biome getBiome() {
|
||||
return greenhouseBiome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param winner.getType() the greenhouseBiome to set
|
||||
*/
|
||||
public void setBiomeRecipe(BiomeRecipe winner) {
|
||||
this.greenhouseBiome = winner.getBiome();
|
||||
this.biomeRecipe = winner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the greenhouse's biome recipe
|
||||
*/
|
||||
public BiomeRecipe getBiomeRecipe() {
|
||||
return biomeRecipe;
|
||||
}
|
||||
|
||||
public void setBiome(Biome greenhouseBiome2) {
|
||||
this.greenhouseBiome = greenhouseBiome2;
|
||||
}
|
||||
|
||||
|
||||
public boolean insideGreenhouse(Location loc) {
|
||||
if (loc.getWorld().equals(world)) {
|
||||
plugin.logger(4,"Checking intersection");
|
||||
Vector v = loc.toVector();
|
||||
plugin.logger(4,"Pos 1 = " + pos1.toString());
|
||||
plugin.logger(4,"Pos 2 = " + pos2.toString());
|
||||
plugin.logger(4,"V = " + v.toString());
|
||||
boolean i = v.isInAABB(Vector.getMinimum(pos1.toVector(), pos2.toVector()), Vector.getMaximum(pos1.toVector(), pos2.toVector()));
|
||||
return i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a location is above a greenhouse
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean aboveGreenhouse(Location loc) {
|
||||
if (loc.getWorld().equals(world)) {
|
||||
Vector v = loc.toVector();
|
||||
Vector p1 = new Vector(pos1.getBlockX(),heightY,pos1.getBlockZ());
|
||||
Vector p2 = new Vector(pos2.getBlockX(),world.getMaxHeight(),pos2.getBlockZ());
|
||||
boolean i = v.isInAABB(Vector.getMinimum(p1, p2), Vector.getMaximum(p1, p2));
|
||||
return i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this location is in a greenhouse wall
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean isAWall(Location loc) {
|
||||
plugin.logger(3,"wall check");
|
||||
if (loc.getBlockX() == pos1.getBlockX() || loc.getBlockX() == pos2.getBlockX()
|
||||
|| loc.getBlockZ() == pos1.getBlockZ() || loc.getBlockZ() == pos2.getBlockZ()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pos1
|
||||
*/
|
||||
public Location getPos1() {
|
||||
return new Location (world, pos1.getBlockX(), pos1.getBlockY(), pos1.getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pos2
|
||||
*/
|
||||
public Location getPos2() {
|
||||
return new Location (world, pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the owner
|
||||
*/
|
||||
public UUID getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the flags
|
||||
*/
|
||||
public HashMap<String, Object> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param flags the flags to set
|
||||
*/
|
||||
public void setFlags(HashMap<String, Object> flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param owner the owner to set
|
||||
*/
|
||||
public void setOwner(UUID owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the playerName
|
||||
*/
|
||||
public String getPlayerName() {
|
||||
return playerName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param playerName the playerName to set
|
||||
*/
|
||||
public void setPlayerName(String playerName) {
|
||||
//plugin.getLogger().info("DEBUG: setting name to " + playerName);
|
||||
this.playerName = playerName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the enterMessage
|
||||
*/
|
||||
public String getEnterMessage() {
|
||||
return (String)flags.get("enterMessage");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the farewallMessage
|
||||
*/
|
||||
public String getFarewellMessage() {
|
||||
return (String)flags.get("farewellMessage");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param enterMessage the enterMessage to set
|
||||
*/
|
||||
public void setEnterMessage(String enterMessage) {
|
||||
flags.put("enterMessage",enterMessage);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param farewallMessage the farewallMessage to set
|
||||
*/
|
||||
public void setFarewellMessage(String farewellMessage) {
|
||||
flags.put("farewellMessage",farewellMessage);
|
||||
}
|
||||
|
||||
|
||||
public void setOriginalBiome(Biome originalBiome) {
|
||||
this.originalBiome = originalBiome;
|
||||
}
|
||||
|
||||
|
||||
public void setRoofHopperLocation(Location roofHopperLoc) {
|
||||
this.roofHopperLocation = roofHopperLoc;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the world
|
||||
*/
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
public Location getRoofHopperLocation() {
|
||||
return roofHopperLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the area
|
||||
*/
|
||||
public int getArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the heightY
|
||||
*/
|
||||
public int getHeightY() {
|
||||
return heightY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the height
|
||||
*/
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reruns the recipe check to see if this greenhouse is still viable
|
||||
* @return true if okay, otherwise false
|
||||
*/
|
||||
public boolean checkEco() {
|
||||
plugin.logger(3,"Checking the ecology of the greenhouse.");
|
||||
if (biomeRecipe != null) {
|
||||
return this.biomeRecipe.checkRecipe(getPos1(), getPos2(), null);
|
||||
} else {
|
||||
plugin.logger(3,"BiomeRecipe is null! ");
|
||||
plugin.getLogger().warning("[Greenhouse info]");
|
||||
plugin.getLogger().warning("Owner: " + getOwner());
|
||||
plugin.getLogger().warning("Location :" + getPos1().toString() + " to " + getPos2().toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts the biome in the greenhouse
|
||||
* @param teleport - if true will teleport the player away and back to force the biome to change
|
||||
*/
|
||||
public void startBiome(boolean teleport) {
|
||||
setBiomeBlocks(greenhouseBiome, teleport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts the biome of the greenhouse to the original unless someone is in this greenhouse
|
||||
* @param to
|
||||
*/
|
||||
public void endBiome() {
|
||||
setBiomeBlocks(originalBiome, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Actually set blocks to a biome
|
||||
* The chunk refresh command has been deprecated and no longer works on 1.8+
|
||||
* so jumping through hoops to refresh mobs is no longer needed
|
||||
* If teleport is true, this biome starting is happening during a teleport
|
||||
* sequence, i.e, gh is being generated or removed
|
||||
* @param biome
|
||||
* @param teleport
|
||||
*/
|
||||
private void setBiomeBlocks(Biome biome, boolean teleport) {
|
||||
if (biome == null) {
|
||||
return;
|
||||
}
|
||||
plugin.logger(2,"Biome seting to " + biome.toString());
|
||||
Set<Pair<Integer, Integer>> chunkCoords = new HashSet<>();
|
||||
final Set<Chunk> chunks = new HashSet<Chunk>();
|
||||
for (int x = pos1.getBlockX();x<pos2.getBlockX();x++) {
|
||||
for (int z = pos1.getBlockZ();z<pos2.getBlockZ();z++) {
|
||||
Block b = world.getBlockAt(x, groundY, z);
|
||||
b.setBiome(biome);
|
||||
if (teleport) {
|
||||
chunks.add(b.getChunk());
|
||||
}
|
||||
if (plugin.getServer().getVersion().contains("(MC: 1.7")) {
|
||||
chunkCoords.add(new Pair<Integer, Integer>(b.getChunk().getX(), b.getChunk().getZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns friendly mobs according to the type of biome
|
||||
*/
|
||||
public void populateGreenhouse() {
|
||||
if (biomeRecipe == null) {
|
||||
return;
|
||||
}
|
||||
plugin.logger(3,"populating mobs in greenhouse");
|
||||
// Make sure no players are around
|
||||
/*
|
||||
if (plugin.players.getNumberInGreenhouse(this) > 0)
|
||||
return;
|
||||
*/
|
||||
// Quick check - see if any animal is going to spawn
|
||||
EntityType mob = biomeRecipe.getRandomMob();
|
||||
if (mob == null) {
|
||||
return;
|
||||
}
|
||||
plugin.logger(3,"Mob ready to spawn in location " + pos1.getBlockX() + "," + pos2.getBlockZ() + " in world " + world.getName());
|
||||
// Load greenhouse chunks
|
||||
int numberOfMobs = 0;
|
||||
Set<Pair> chunkSet = new HashSet<Pair>();
|
||||
for (int x = (pos1.getBlockX()-15); x < (pos2.getBlockX()+15); x += 16) {
|
||||
for (int z = (pos1.getBlockZ()-15); z < (pos2.getBlockZ()+15); z += 16) {
|
||||
Chunk chunk = world.getChunkAt(x/16, z/16);
|
||||
chunkSet.add(new Pair(x/16,z/16));
|
||||
chunk.load();
|
||||
plugin.logger(3, "Chunk = " + (x/16) + "," + (z/16) + " number of entities = " + chunk.getEntities().length);
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
plugin.logger(3,entity.getType().toString());
|
||||
if (mob.equals(entity.getType())) {
|
||||
numberOfMobs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
plugin.logger(3,"Mobs in area = " + numberOfMobs);
|
||||
plugin.logger(3,"Area of greenhouse = " + area);
|
||||
if (area - (numberOfMobs * biomeRecipe.getMobLimit()) <= 0) {
|
||||
plugin.logger(3,"Too many mobs already in this greenhouse");
|
||||
for (Pair pair: chunkSet) {
|
||||
world.unloadChunkRequest(pair.getLeft(), pair.getRight());
|
||||
}
|
||||
return;
|
||||
}
|
||||
Material type = biomeRecipe.getMobSpawnOn(mob);
|
||||
int minx = Math.min(pos1.getBlockX(), pos2.getBlockX());
|
||||
int maxx = Math.max(pos1.getBlockX(), pos2.getBlockX());
|
||||
int minz = Math.min(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
int maxz = Math.max(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
// Try 10 times
|
||||
for (int i = 0; i<10; i++) {
|
||||
int x = Greenhouses.randInt(minx,maxx);
|
||||
int z = Greenhouses.randInt(minz,maxz);
|
||||
Block h = getHighestBlockInGreenhouse(x,z);
|
||||
Block b = h.getRelative(BlockFace.DOWN);
|
||||
Block a = h.getRelative(BlockFace.UP);
|
||||
plugin.logger(3,"block found " + h.getType().toString());
|
||||
plugin.logger(3,"below found " + b.getType().toString());
|
||||
plugin.logger(3,"above found " + a.getType().toString());
|
||||
if ((b.getType().equals(type) && h.getType().equals(Material.AIR))
|
||||
|| (h.getType().equals(type) && a.getType().equals(Material.AIR)) ) {
|
||||
Location midBlock = new Location(world, h.getLocation().getX()+0.5D, h.getLocation().getY(), h.getLocation().getZ()+0.5D);
|
||||
Entity e = world.spawnEntity(midBlock, mob);
|
||||
if (e != null)
|
||||
plugin.logger(1,"Spawned a "+ Util.prettifyText(mob.toString()) + " on "+ Util.prettifyText(type.toString()) + " at "
|
||||
+ midBlock.getBlockX() + "," + midBlock.getBlockY() + "," + midBlock.getBlockZ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (Pair pair: chunkSet) {
|
||||
world.unloadChunkRequest(pair.getLeft(), pair.getRight());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lay down snow in the greenhouse
|
||||
*/
|
||||
public void snow() {
|
||||
// Lay down snow and ice
|
||||
List<Block> waterToIceBlocks = new ArrayList<Block>();
|
||||
long water = 0;
|
||||
int minx = Math.min(pos1.getBlockX(), pos2.getBlockX());
|
||||
int maxx = Math.max(pos1.getBlockX(), pos2.getBlockX());
|
||||
int minz = Math.min(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
int maxz = Math.max(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
for (int x = minx+1; x < maxx; x++) {
|
||||
for (int z = minz+1; z < maxz;z++) {
|
||||
Block b = getHighestBlockInGreenhouse(x,z);
|
||||
// Display snow particles in air above b and count water blocks
|
||||
for (int y = pos1.getBlockY(); y < heightY; y++) {
|
||||
Block airCheck = world.getBlockAt(x, y, z);
|
||||
if (airCheck.getType().equals(Material.AIR)) {
|
||||
//).display(0F,0F,0F, 0.1F, 5,
|
||||
//ParticleEffects.SNOWBALL.send(Bukkit.getOnlinePlayers(),airCheck.getLocation(),0D,0D,0D,1F,5,20);
|
||||
world.spawnParticle(Particle.SNOWBALL, airCheck.getLocation(), 5);
|
||||
} else if (airCheck.getType().equals(Material.WATER)) {
|
||||
water++;
|
||||
}
|
||||
}
|
||||
Block belowB = b.getRelative(BlockFace.DOWN);
|
||||
if (Math.random()<Settings.snowDensity) {
|
||||
if (belowB.getType().equals(Material.WATER)) {
|
||||
// If the recipe requires a certain amount of water, then we need to wait until later to make ice
|
||||
if (biomeRecipe.getWaterCoverage() > 0) {
|
||||
waterToIceBlocks.add(belowB);
|
||||
} else {
|
||||
belowB.setType(Material.ICE);
|
||||
}
|
||||
} else if (belowB.getType().equals(Material.SNOW)) {
|
||||
Snow snow = (Snow)belowB.getBlockData();
|
||||
// Increment snow layers
|
||||
snow.setLayers(Math.min(snow.getLayers() + 1, snow.getMaximumLayers()));
|
||||
} else if (b.getType().equals(Material.AIR)) {
|
||||
// Don't put snow on liquids or snow...
|
||||
if (!belowB.isLiquid() && !belowB.getType().equals(Material.SNOW))
|
||||
b.setType(Material.SNOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
plugin.logger(3,"water = " + water);
|
||||
if (biomeRecipe.getWaterCoverage() > 0 && water >0) {
|
||||
plugin.logger(3,"water coverage required = " + biomeRecipe.getWaterCoverage());
|
||||
// Check if ice can be made
|
||||
for (Block toIce: waterToIceBlocks) {
|
||||
plugin.logger(3,"water ratio = " + ((double)(water-1)/(double)area * 100));
|
||||
if (((double)(water-1)/(double)area * 100) > biomeRecipe.getWaterCoverage()) {
|
||||
toIce.setType(Material.ICE);
|
||||
water--;
|
||||
} else {
|
||||
plugin.logger(3,"no more ice allowed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void growFlowers() {
|
||||
if (biomeRecipe == null) {
|
||||
return;
|
||||
}
|
||||
Location hopper = roofHopperLocation;
|
||||
if (hopper != null) {
|
||||
plugin.logger(3,"Hopper location:" + hopper.toString());
|
||||
Block b = hopper.getBlock();
|
||||
// Check the hopper is still there
|
||||
if (b.getType().equals(Material.HOPPER)) {
|
||||
Hopper h = (Hopper)b.getState();
|
||||
plugin.logger(3,"Hopper found!");
|
||||
// Check what is in the hopper
|
||||
if (h.getInventory().contains(Material.BONE_MEAL)) {
|
||||
int total = h.getInventory().all(Material.BONE_MEAL).values().stream().mapToInt(ItemStack::getAmount).sum();
|
||||
// We need one bonemeal for each flower made
|
||||
if (total > 0) {
|
||||
/*
|
||||
ItemStack remBoneMeal = new ItemStack(Material.INK_SACK);
|
||||
remBoneMeal.setDurability((short)15);
|
||||
remBoneMeal.setAmount(1);
|
||||
*/
|
||||
// Rewrite to use on bonemeal per flower
|
||||
plugin.logger(3,"Bonemeal found! Amount = " + total);
|
||||
// Now go and grow stuff with the set probability
|
||||
int minx = Math.min(pos1.getBlockX(), pos2.getBlockX());
|
||||
int maxx = Math.max(pos1.getBlockX(), pos2.getBlockX());
|
||||
int minz = Math.min(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
int maxz = Math.max(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
for (int x = minx+1; x < maxx; x++) {
|
||||
for (int z = minz+1; z < maxz;z++) {
|
||||
Block bl = getHighestBlockInGreenhouse(x,z);
|
||||
//if (Math.random()<Settings.flowerChance) {
|
||||
plugin.logger(3,"Block is " + bl.getRelative(BlockFace.DOWN).getType().toString());
|
||||
if (total > 0 && biomeRecipe.growPlant(bl)) {
|
||||
total --;
|
||||
plugin.logger(3,"Grew plant, spraying bonemeal");
|
||||
// Spray the bonemeal
|
||||
for (int y = bl.getLocation().getBlockY(); y< heightY; y++) {
|
||||
Block airCheck = world.getBlockAt(x, y, z);
|
||||
if (airCheck.getType().equals(Material.AIR)) {
|
||||
world.spawnParticle(Particle.EXPLOSION_NORMAL, airCheck.getLocation(), 5);
|
||||
//ParticleEffects.EXPLOSION_NORMAL.send(Bukkit.getOnlinePlayers(),airCheck.getLocation(),0D,0D,0D,1F,5,20);
|
||||
//ParticleEffect.EXPLOSION_NORMAL.display(0F,0F,0F, 0.1F, 5, airCheck.getLocation(), 30D);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
plugin.logger(3,"Bonemeal left = " + total);
|
||||
// Remove the bonemeal from the hopper
|
||||
h.getInventory().remove(Material.BONE_MEAL);
|
||||
h.getInventory().addItem(new ItemStack(Material.BONE_MEAL, total));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Greenhouse is broken or no longer has a hopper when it should
|
||||
// TODO remove the greenhouse
|
||||
plugin.logger(3,"Hopper is not there anymore...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts blocks in the greenhouse over time at a random rate
|
||||
* Depends on the biome recipe
|
||||
*/
|
||||
public void convertBlocks() {
|
||||
if (biomeRecipe == null) {
|
||||
return;
|
||||
}
|
||||
if (biomeRecipe.getBlockConvert()) {
|
||||
// Check biome recipe
|
||||
int minx = Math.min(pos1.getBlockX(), pos2.getBlockX());
|
||||
int maxx = Math.max(pos1.getBlockX(), pos2.getBlockX());
|
||||
int minz = Math.min(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
int maxz = Math.max(pos1.getBlockZ(), pos2.getBlockZ());
|
||||
for (int x = minx+1; x < maxx; x++) {
|
||||
for (int z = minz+1; z < maxz;z++) {
|
||||
for (int y = groundY; y < heightY; y++) {
|
||||
biomeRecipe.convertBlock(world.getBlockAt(x,y,z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Replaces the getHighestBlock function by only looking within a greenhouse
|
||||
* @param x
|
||||
* @param z
|
||||
* @return Non-solid block just above the highest solid block at x,z - should always be AIR
|
||||
*/
|
||||
public Block getHighestBlockInGreenhouse(int x, int z) {
|
||||
Block bl = world.getBlockAt(x,heightY,z).getRelative(BlockFace.DOWN);
|
||||
while (bl.getLocation().getBlockY() >= groundY && bl.isEmpty()) {
|
||||
bl = bl.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
return bl.getRelative(BlockFace.UP);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package world.bentobox.greenhouses.greenhouse;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -9,27 +10,33 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
|
||||
/**
|
||||
* Contains the parameters of a greenhouse roof
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class Roof {
|
||||
private final Location location;
|
||||
private int minX;
|
||||
private int maxX;
|
||||
private int minZ;
|
||||
private int maxZ;
|
||||
private int height;
|
||||
private boolean roofFound;
|
||||
private final static List<String> ROOFBLOCKS = Arrays.asList("GLASS","STAINED_GLASS","HOPPER","TRAP_DOOR","IRON_TRAPDOOR","GLOWSTONE");
|
||||
|
||||
public final static List<Material> ROOFBLOCKS = Arrays.stream(Material.values())
|
||||
.filter(Material::isBlock) // Blocks only, no items
|
||||
.filter(m -> !m.name().contains("DOOR")) // No doors
|
||||
.filter(m -> m.name().contains("TRAPDOOR") // All trapdoors
|
||||
|| m.name().contains("GLASS") // All glass blocks
|
||||
|| m.equals(Material.HOPPER) // Hoppers
|
||||
|| m.equals(Material.GLOWSTONE)) // Glowstone
|
||||
.collect(Collectors.toList());
|
||||
/**
|
||||
* Finds a roof from a starting location under the roof and characterizes it
|
||||
* @param loc
|
||||
*/
|
||||
public Roof(Greenhouses plugin, Location loc) {
|
||||
public Roof(Location loc) {
|
||||
this.location = loc;
|
||||
World world = loc.getWorld();
|
||||
// This section tries to find a roof block
|
||||
// Try just going up - this covers every case except if the player is standing under a hole
|
||||
@ -47,14 +54,14 @@ public class Roof {
|
||||
&& (z > loc.getBlockZ() - radius && z < loc.getBlockZ() + radius))) {
|
||||
//player.sendBlockChange(new Location(world,x,roofY,z), Material.GLASS, (byte)(radius % 14));
|
||||
Block b = world.getBlockAt(x,roofY,z);
|
||||
plugin.logger(3,"Checking column " + x + " " + z );
|
||||
//plugin.logger(3,"Checking column " + x + " " + z );
|
||||
if (!Walls.isWallBlock(b.getType())) {
|
||||
// Look up
|
||||
for (int y = roofY; y < world.getMaxHeight(); y++) {
|
||||
if (ROOFBLOCKS.contains(world.getBlockAt(x,y,z).getType().name())) {
|
||||
if (ROOFBLOCKS.contains(world.getBlockAt(x,y,z).getType())) {
|
||||
roofFound = true;
|
||||
loc = new Location(world,x,y,z);
|
||||
plugin.logger(3,"Roof block found at " + x + " " + y + " " + z + " of type " + loc.getBlock().getType().toString());
|
||||
//plugin.logger(3,"Roof block found at " + x + " " + y + " " + z + " of type " + loc.getBlock().getType().toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -87,10 +94,10 @@ public class Roof {
|
||||
int maxz = maxZ;
|
||||
// Now we have some idea of the mins and maxes, check each block and see if it goes further
|
||||
do {
|
||||
plugin.logger(3, "Roof minx=" + minx);
|
||||
plugin.logger(3, "Roof maxx=" + maxx);
|
||||
plugin.logger(3, "Roof minz=" + minz);
|
||||
plugin.logger(3, "Roof maxz=" + maxz);
|
||||
//plugin.logger(3, "Roof minx=" + minx);
|
||||
//plugin.logger(3, "Roof maxx=" + maxx);
|
||||
//plugin.logger(3, "Roof minz=" + minz);
|
||||
//plugin.logger(3, "Roof maxz=" + maxz);
|
||||
minx = minX;
|
||||
maxx = maxX;
|
||||
minz = minZ;
|
||||
@ -118,7 +125,7 @@ public class Roof {
|
||||
Location maxz = height.clone();
|
||||
Location minz = height.clone();
|
||||
int limit = 0;
|
||||
while (ROOFBLOCKS.contains(maxx.getBlock().getType().name()) && limit < 100) {
|
||||
while (ROOFBLOCKS.contains(maxx.getBlock().getType()) && limit < 100) {
|
||||
limit++;
|
||||
maxx.add(new Vector(1,0,0));
|
||||
}
|
||||
@ -126,7 +133,7 @@ public class Roof {
|
||||
maxX = maxx.getBlockX()-1;
|
||||
}
|
||||
|
||||
while (ROOFBLOCKS.contains(minx.getBlock().getType().name()) && limit < 200) {
|
||||
while (ROOFBLOCKS.contains(minx.getBlock().getType()) && limit < 200) {
|
||||
limit++;
|
||||
minx.subtract(new Vector(1,0,0));
|
||||
}
|
||||
@ -134,7 +141,7 @@ public class Roof {
|
||||
minX = minx.getBlockX() + 1;
|
||||
}
|
||||
|
||||
while (ROOFBLOCKS.contains(maxz.getBlock().getType().name()) && limit < 300) {
|
||||
while (ROOFBLOCKS.contains(maxz.getBlock().getType()) && limit < 300) {
|
||||
limit++;
|
||||
maxz.add(new Vector(0,0,1));
|
||||
}
|
||||
@ -142,7 +149,7 @@ public class Roof {
|
||||
maxZ = maxz.getBlockZ() - 1;
|
||||
}
|
||||
|
||||
while (ROOFBLOCKS.contains(minz.getBlock().getType().name()) && limit < 400) {
|
||||
while (ROOFBLOCKS.contains(minz.getBlock().getType()) && limit < 400) {
|
||||
limit++;
|
||||
minz.subtract(new Vector(0,0,1));
|
||||
}
|
||||
@ -221,14 +228,19 @@ public class Roof {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if roof block
|
||||
* @param blockType
|
||||
* @return true if this is a roof block
|
||||
* @return the location
|
||||
*/
|
||||
public boolean isRoofBlock(Material blockType) {
|
||||
if (ROOFBLOCKS.contains(blockType.name())) {
|
||||
return true;
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Roof [location=" + location + ", minX=" + minX + ", maxX=" + maxX + ", minZ=" + minZ + ", maxZ=" + maxZ
|
||||
+ ", height=" + height + ", roofFound=" + roofFound + "]";
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,6 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
|
||||
public class Walls {
|
||||
private int minX;
|
||||
@ -22,8 +19,7 @@ public class Walls {
|
||||
private boolean useRoofMinX;
|
||||
private boolean useRoofMaxZ;
|
||||
private boolean useRoofMinZ;
|
||||
private Location roofBlock;
|
||||
Location roofHopperLoc = null;
|
||||
|
||||
public final static List<Material> WALL_BLOCKS = Arrays.stream(Material.values())
|
||||
.filter(Material::isBlock) // Blocks only, no items
|
||||
.filter(m -> !m.name().contains("TRAPDOOR")) // No trapdoors
|
||||
@ -33,11 +29,11 @@ public class Walls {
|
||||
|| m.equals(Material.GLOWSTONE)) // Glowstone
|
||||
.collect(Collectors.toList());
|
||||
|
||||
public Walls(Greenhouses addon, final Player player, Roof roof) {
|
||||
public Walls(Roof roof) {
|
||||
// The player is under the roof
|
||||
// Assume the player is inside the greenhouse they are trying to create
|
||||
Location loc = player.getLocation();
|
||||
World world = player.getWorld();
|
||||
Location loc = roof.getLocation();
|
||||
World world = roof.getLocation().getWorld();
|
||||
// Find the floor - defined as the last y under the roof where there are no wall blocks
|
||||
int wallBlockCount = 0;
|
||||
int y = roof.getHeight();
|
||||
@ -53,7 +49,7 @@ public class Walls {
|
||||
|
||||
} while( y-- > 0 && wallBlockCount > 0);
|
||||
floor = y + 1;
|
||||
addon.logger(3,"#1 Floor found at " + floor);
|
||||
//addon.logger(3,"#1 Floor found at " + floor);
|
||||
// Now start with the player's x and z location
|
||||
int radiusMinX = 0;
|
||||
int radiusMaxX = 0;
|
||||
@ -67,17 +63,7 @@ public class Walls {
|
||||
maxX = loc.getBlockX();
|
||||
minZ = loc.getBlockZ();
|
||||
maxZ = loc.getBlockZ();
|
||||
addon.logger(3,"Starting point = " + loc.getBlockX() + "," + loc.getBlockZ());
|
||||
addon.logger(3,"roof minX = " + roof.getMinX());
|
||||
addon.logger(3,"roof maxX = " + roof.getMaxX());
|
||||
addon.logger(3,"roof minZ = " + roof.getMinZ());
|
||||
addon.logger(3,"roof maxZ = " + roof.getMaxZ());
|
||||
do {
|
||||
addon.logger(3,"wall radiusminX = " + radiusMinX);
|
||||
addon.logger(3,"wall radius maxX = " + radiusMaxX);
|
||||
addon.logger(3,"wall radius minZ = " + radiusMinZ);
|
||||
addon.logger(3,"wall radius maxZ = " + radiusMaxZ);
|
||||
|
||||
// Look around player in an ever expanding cube
|
||||
minX = loc.getBlockX() - radiusMinX;
|
||||
maxX = loc.getBlockX() + radiusMaxX;
|
||||
@ -89,7 +75,6 @@ public class Walls {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
// Only look around outside edge
|
||||
if (!((x > minX && x < maxX) && (z > minZ && z < maxZ))) {
|
||||
addon.logger(3,"Checking block " + x + " " + y + " " + z);
|
||||
// Look at block faces
|
||||
for (BlockFace bf: BlockFace.values()) {
|
||||
switch (bf) {
|
||||
@ -97,28 +82,24 @@ public class Walls {
|
||||
// positive x
|
||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
||||
stopMaxX = true;
|
||||
addon.logger(3,"Wall found, stopping MaxX");
|
||||
}
|
||||
break;
|
||||
case WEST:
|
||||
// negative x
|
||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
||||
stopMinX = true;
|
||||
addon.logger(3,"Wall found, stopping minX");
|
||||
}
|
||||
break;
|
||||
case NORTH:
|
||||
// negative Z
|
||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
||||
stopMinZ = true;
|
||||
addon.logger(3,"Wall found, stopping minZ");
|
||||
}
|
||||
break;
|
||||
case SOUTH:
|
||||
// positive Z
|
||||
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
|
||||
stopMaxZ = true;
|
||||
addon.logger(3,"Wall found, stopping maxZ");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -130,19 +111,15 @@ public class Walls {
|
||||
}
|
||||
}
|
||||
if (minX < roof.getMinX()) {
|
||||
addon.logger(3,"minx is less that the roof minX");
|
||||
stopMinX = true;
|
||||
}
|
||||
if (maxX > roof.getMaxX()) {
|
||||
addon.logger(3,"maxx is > that the roof minX");
|
||||
stopMaxX = true;
|
||||
}
|
||||
if (minZ < roof.getMinZ()) {
|
||||
addon.logger(3,"minz is less that the roof minz");
|
||||
stopMinZ = true;
|
||||
}
|
||||
if (maxZ > roof.getMaxZ()) {
|
||||
addon.logger(3,"maxZ is >t the roof maxZ");
|
||||
stopMaxZ = true;
|
||||
}
|
||||
// Expand the edges
|
||||
@ -164,11 +141,6 @@ public class Walls {
|
||||
maxX++;
|
||||
minZ--;
|
||||
maxZ++;
|
||||
addon.logger(3,"wall minX = " + minX);
|
||||
addon.logger(3,"wall maxX = " + maxX);
|
||||
addon.logger(3,"wall minZ = " + minZ);
|
||||
addon.logger(3,"wall maxZ = " + maxZ);
|
||||
|
||||
// Find the floor again, only looking within the walls
|
||||
y = roof.getHeight();
|
||||
do {
|
||||
@ -183,8 +155,6 @@ public class Walls {
|
||||
|
||||
} while( y-- > 0 && wallBlockCount > 0);
|
||||
floor = y + 1;
|
||||
addon.logger(3,"#2 floor = " + floor);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,20 +217,6 @@ public class Walls {
|
||||
return (maxX - minX) * (maxZ - minZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roofBlock
|
||||
*/
|
||||
public Location getRoofBlock() {
|
||||
return roofBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roofHopperLoc
|
||||
*/
|
||||
public Location getRoofHopperLoc() {
|
||||
return roofHopperLoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the floor
|
||||
*/
|
||||
|
@ -1,15 +1,11 @@
|
||||
package world.bentobox.greenhouses.listeners;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -18,12 +14,12 @@ import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.Settings;
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
import world.bentobox.greenhouses.util.Util;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -31,7 +27,6 @@ import world.bentobox.greenhouses.util.Util;
|
||||
*/
|
||||
public class GreenhouseEvents implements Listener {
|
||||
private final Greenhouses plugin;
|
||||
private List<Location> blockedPistons = new ArrayList<Location>();
|
||||
|
||||
public GreenhouseEvents(final Greenhouses plugin) {
|
||||
this.plugin = plugin;
|
||||
@ -43,182 +38,83 @@ public class GreenhouseEvents implements Listener {
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled=true)
|
||||
public void onPlayerInteract(PlayerInteractEvent event){
|
||||
Player player = event.getPlayer();
|
||||
World world = player.getWorld();
|
||||
// Check we are in the right world
|
||||
if (!world.getEnvironment().equals(Environment.NETHER) || !Settings.worldName.contains(world.getName())) {
|
||||
public void onPlayerInteract(PlayerInteractEvent e) {
|
||||
if (!e.getPlayer().getWorld().getEnvironment().equals(World.Environment.NETHER)) {
|
||||
return;
|
||||
}
|
||||
if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
|
||||
Biome biome = event.getClickedBlock().getBiome();
|
||||
if (event.getItem() != null && biome != null) {
|
||||
// Allow pouring of water if biome is okay
|
||||
if (event.getItem().getType().equals(Material.WATER_BUCKET) && !biome.equals(Biome.NETHER)
|
||||
&& !biome.equals(Biome.DESERT) && !biome.equals(Biome.DESERT_HILLS)) {
|
||||
event.setCancelled(true);
|
||||
event.getClickedBlock().getRelative(event.getBlockFace()).setType(Material.WATER);
|
||||
}
|
||||
}
|
||||
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK) && e.getItem() != null && e.getItem().getType().equals(Material.WATER_BUCKET)) {
|
||||
e.setCancelled(true);
|
||||
e.getClickedBlock().getRelative(e.getBlockFace()).setType(Material.WATER);
|
||||
e.getItem().setType(Material.BUCKET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes water in the Nether if ice is broken and in a greenhouse
|
||||
* @param event
|
||||
* @param e - event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled=true)
|
||||
public void onIceBreak(BlockBreakEvent event){
|
||||
Player player = event.getPlayer();
|
||||
World world = player.getWorld();
|
||||
// Check we are in the right world
|
||||
if (!Settings.worldName.contains(world.getName())) {
|
||||
public void onIceBreak(BlockBreakEvent e) {
|
||||
if (!e.getBlock().getWorld().getEnvironment().equals(World.Environment.NETHER)
|
||||
|| (!e.getBlock().getType().equals(Material.ICE) && !e.getBlock().getType().equals(Material.BLUE_ICE))) {
|
||||
return;
|
||||
}
|
||||
Biome biome = event.getBlock().getBiome();
|
||||
// Set to water if the biome is okay.
|
||||
if(event.getBlock().getWorld().getEnvironment() == Environment.NETHER && event.getBlock().getType() == Material.ICE
|
||||
&& !biome.equals(Biome.NETHER) && !biome.equals(Biome.DESERT) && !biome.equals(Biome.DESERT_HILLS)) {
|
||||
event.setCancelled(true);
|
||||
event.getBlock().setType(Material.WATER);
|
||||
}
|
||||
if (plugin.getManager().getMap().getGreenhouse(e.getBlock().getLocation()).isPresent()) {
|
||||
e.setCancelled(true);
|
||||
e.getBlock().setType(Material.WATER);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks player movement
|
||||
* @param event
|
||||
* @param e - event
|
||||
*/
|
||||
/*
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
//plugin.logger(3,event.getEventName());
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
if (plugin.getPlayerGHouse(uuid) == null || plugin.getPlayerGHouse(uuid).isEmpty()) {
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerMove(PlayerMoveEvent e) {
|
||||
handleTransition(User.getInstance(e.getPlayer()), e.getTo(), e.getFrom());
|
||||
}
|
||||
|
||||
private void handleTransition(User user, Location toLoc, Location fromLoc) {
|
||||
Optional<Greenhouse> to = plugin.getManager().getMap().getGreenhouse(toLoc);
|
||||
Optional<Greenhouse> from = plugin.getManager().getMap().getGreenhouse(fromLoc);
|
||||
if (!to.isPresent() && !from.isPresent()) {
|
||||
return;
|
||||
}
|
||||
if (to.isPresent() && from.isPresent() && to.equals(from)) {
|
||||
// Same greenhouse
|
||||
return;
|
||||
}
|
||||
// to is a greenhouse
|
||||
if (to.isPresent() && from.isPresent() && !to.equals(from)) {
|
||||
// Leaving greenhouse, entering another
|
||||
user.sendRawMessage("Leaving " + to.get().getBiomeRecipe().getFriendlyName() + " greenhouse");
|
||||
user.sendRawMessage("Entering " + from.get().getBiomeRecipe().getFriendlyName() + " greenhouse");
|
||||
return;
|
||||
}
|
||||
// from is a greenhouse
|
||||
if (from.isPresent() && !to.isPresent()) {
|
||||
// Exiting
|
||||
user.sendRawMessage("Leaving " + to.get().getBiomeRecipe().getFriendlyName() + " greenhouse");
|
||||
return;
|
||||
}
|
||||
if (!from.isPresent() && to.isPresent()) {
|
||||
// Entering
|
||||
user.sendRawMessage("Entering " + from.get().getBiomeRecipe().getFriendlyName() + " greenhouse");
|
||||
return;
|
||||
}
|
||||
|
||||
World world = player.getWorld();
|
||||
// Check we are in the right world
|
||||
if (!Settings.worldName.contains(world.getName())) {
|
||||
plugin.logger(4,"Not in a Greenhouse world");
|
||||
return;
|
||||
}
|
||||
// Did we move a block?
|
||||
if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|
||||
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|
||||
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()) {
|
||||
boolean result = checkMove(player, event.getFrom(), event.getTo(), uuid);
|
||||
if (result) {
|
||||
Location newLoc = event.getFrom();
|
||||
newLoc.setX(newLoc.getBlockX() + 0.5);
|
||||
newLoc.setY(newLoc.getBlockY());
|
||||
newLoc.setZ(newLoc.getBlockZ() + 0.5);
|
||||
event.setTo(newLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent e) {
|
||||
// Strangely, sometimes these worlds can be null
|
||||
if (event.getFrom() == null || event.getTo() == null) {
|
||||
if (e.getFrom() == null || e.getTo() == null) {
|
||||
return;
|
||||
}
|
||||
// Check if they changed worlds
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
if (plugin.getPlayerGHouse(uuid) == null || plugin.getPlayerGHouse(uuid).isEmpty()) {
|
||||
return;
|
||||
handleTransition(User.getInstance(e.getPlayer()), e.getTo(), e.getFrom());
|
||||
}
|
||||
|
||||
World fromWorld = event.getFrom().getWorld();
|
||||
World toWorld = event.getTo().getWorld();
|
||||
// Check we are in the right world
|
||||
if (!Settings.worldName.contains(fromWorld.getName()) && !Settings.worldName.contains(toWorld.getName())) {
|
||||
return;
|
||||
}
|
||||
// Did we move a block?
|
||||
checkMove(event.getPlayer(), event.getFrom(), event.getTo(), uuid);
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* @param player
|
||||
* @param from
|
||||
* @param to
|
||||
* @return false if the player can move into that area, true if not allowed
|
||||
*/
|
||||
/*
|
||||
private boolean checkMove(Player player, Location from, Location to, UUID uuid) {
|
||||
Greenhouse fromGreenhouse = null;
|
||||
Greenhouse toGreenhouse= null;
|
||||
if (plugin.getGreenhouses().isEmpty()) {
|
||||
// No greenhouses yet
|
||||
return false;
|
||||
}
|
||||
plugin.logger(4,"Checking greenhouses");
|
||||
plugin.logger(4,"From : " + from.toString());
|
||||
plugin.logger(4,"From: " + from.getBlockX() + "," + from.getBlockZ());
|
||||
plugin.logger(4,"To: " + to.getBlockX() + "," + to.getBlockZ());
|
||||
for (Greenhouse d: plugin.getPlayerGHouse(uuid)) {
|
||||
plugin.logger(4,"Greenhouse (" + d.getPos1().getBlockX() + "," + d.getPos1().getBlockZ() + " : " + d.getPos2().getBlockX() + "," + d.getPos2().getBlockZ() + ")");
|
||||
if (d.insideGreenhouse(to)) {
|
||||
plugin.logger(4,"To intersects d!");
|
||||
toGreenhouse = d;
|
||||
}
|
||||
if (d.insideGreenhouse(from)) {
|
||||
plugin.logger(4,"From intersects d!");
|
||||
fromGreenhouse = d;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// No greenhouse interaction
|
||||
if (fromGreenhouse == null && toGreenhouse == null) {
|
||||
// Clear the greenhouse flag (the greenhouse may have been deleted while they were offline)
|
||||
plugin.players.setInGreenhouse(player, null);
|
||||
return false;
|
||||
} else if (fromGreenhouse == toGreenhouse) {
|
||||
// Set the greenhouse - needs to be done if the player teleports too (should be done on a teleport event)
|
||||
plugin.players.setInGreenhouse(player, toGreenhouse);
|
||||
return false;
|
||||
}
|
||||
if (fromGreenhouse != null && toGreenhouse == null) {
|
||||
// leaving a greenhouse
|
||||
if (!fromGreenhouse.getFarewellMessage().isEmpty()) {
|
||||
player.sendMessage(fromGreenhouse.getFarewellMessage());
|
||||
}
|
||||
plugin.players.setInGreenhouse(player, null);
|
||||
//if (plugin.players.getNumberInGreenhouse(fromGreenhouse) == 0) {
|
||||
// fromGreenhouse.ƒ();
|
||||
//}
|
||||
} else if (fromGreenhouse == null && toGreenhouse != null){
|
||||
// Going into a greenhouse
|
||||
if (!toGreenhouse.getEnterMessage().isEmpty()) {
|
||||
player.sendMessage(toGreenhouse.getEnterMessage());
|
||||
|
||||
//plugin.visualize(toGreenhouse, player);
|
||||
}
|
||||
toGreenhouse.startBiome(false);
|
||||
plugin.players.setInGreenhouse(player, toGreenhouse);
|
||||
|
||||
} else if (fromGreenhouse != null && toGreenhouse != null){
|
||||
// Leaving one greenhouse and entering another greenhouse immediately
|
||||
if (!fromGreenhouse.getFarewellMessage().isEmpty()) {
|
||||
player.sendMessage(fromGreenhouse.getFarewellMessage());
|
||||
}
|
||||
plugin.players.setInGreenhouse(player, toGreenhouse);
|
||||
//if (plugin.players.getNumberInGreenhouse(fromGreenhouse) == 0) {
|
||||
//fromGreenhouse.endBiome();
|
||||
//}
|
||||
toGreenhouse.startBiome(false);
|
||||
if (!toGreenhouse.getEnterMessage().isEmpty()) {
|
||||
player.sendMessage(toGreenhouse.getEnterMessage());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks is broken blocks cause the greenhouse to fail
|
||||
@ -226,25 +122,19 @@ public class GreenhouseEvents implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockBreak(final BlockBreakEvent e) {
|
||||
if (!Settings.worldName.contains(e.getPlayer().getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
plugin.logger(3,"block break");
|
||||
// Get the greenhouse that this block is in (if any)
|
||||
Greenhouse g = plugin.getInGreenhouse(e.getBlock().getLocation());
|
||||
|
||||
if (g == null) {
|
||||
// Not in a greenhouse
|
||||
plugin.logger(3,"not in greenhouse");
|
||||
return;
|
||||
}
|
||||
// Check to see if this causes the greenhouse to break
|
||||
if ((e.getBlock().getLocation().getBlockY() == g.getHeightY()) || (g.isAWall(e.getBlock().getLocation()))) {
|
||||
e.getPlayer().sendMessage(ChatColor.RED + Locale.eventbroke.replace("[biome]",Util.prettifyText(g.getOriginalBiome().toString())));
|
||||
e.getPlayer().sendMessage(ChatColor.RED + Locale.eventfix);
|
||||
plugin.removeGreenhouse(g);
|
||||
return;
|
||||
User user = User.getInstance(e.getPlayer());
|
||||
plugin.getManager().getMap().getGreenhouse(e.getBlock().getLocation()).ifPresent(g -> {
|
||||
// Check to see if wall or roof block broken
|
||||
if ((e.getBlock().getLocation().getBlockY() == g.getCeilingHeight())
|
||||
|| e.getBlock().getLocation().getBlockX() == g.getFootprint().getMinX()
|
||||
|| e.getBlock().getLocation().getBlockX() == g.getFootprint().getMaxX()
|
||||
|| e.getBlock().getLocation().getBlockZ() == g.getFootprint().getMinY()
|
||||
|| e.getBlock().getLocation().getBlockZ() == g.getFootprint().getMaxY()
|
||||
) {
|
||||
user.sendMessage("greenhouses.broken");
|
||||
plugin.getManager().getMap().removeGreenhouse(g);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,67 +143,28 @@ public class GreenhouseEvents implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true)
|
||||
public void onPlayerBlockPlace(final BlockPlaceEvent e) {
|
||||
if (!Settings.worldName.contains(e.getPlayer().getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
if (e.getPlayer().getWorld().getEnvironment().equals(Environment.NETHER)) {
|
||||
return;
|
||||
}
|
||||
// If the offending block is not above a greenhouse, forget it!
|
||||
Greenhouse g = plugin.aboveAGreenhouse(e.getBlock().getLocation());
|
||||
if (g == null) {
|
||||
return;
|
||||
}
|
||||
e.getPlayer().sendMessage(ChatColor.RED + Locale.eventcannotplace);
|
||||
e.getPlayer().sendMessage("Greenhouse is at " + g.getPos1() + " to " + g.getPos2());
|
||||
if (checkBlockHeight(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
User user = User.getInstance(e.getPlayer());
|
||||
user.sendMessage("greenhouses.error.cannot-place");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkBlockHeight(Block block) {
|
||||
return plugin.getManager().getMap().getGreenhouse(block.getLocation())
|
||||
.filter(g -> g.getCeilingHeight() < block.getY())
|
||||
.filter(g -> !block.getWorld().getEnvironment().equals(World.Environment.NETHER))
|
||||
.isPresent();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if anyone is sneaking a block over a greenhouse by using a piston
|
||||
* @param e
|
||||
*/
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true)
|
||||
public void onPistonPush(final BlockPistonExtendEvent e) {
|
||||
if (!Settings.worldName.contains(e.getBlock().getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
if (e.getBlock().getWorld().getEnvironment().equals(Environment.NETHER)) {
|
||||
return;
|
||||
}
|
||||
// Check if piston is already extended to avoid the double event effect
|
||||
|
||||
Location l = e.getBlock().getLocation();
|
||||
if (blockedPistons.contains(l)) {
|
||||
// Cancel the double call
|
||||
blockedPistons.remove(l);
|
||||
e.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
plugin.logger(3,"Direction: " + e.getDirection());
|
||||
plugin.logger(3,"Location of piston block:" + l);
|
||||
// Pistons can push up to 12 blocks - find the end block + 1
|
||||
for (int i = 0; i < 13; i++) {
|
||||
l = l.getBlock().getRelative(e.getDirection()).getLocation();
|
||||
if (!l.getBlock().getType().isSolid()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
plugin.logger(3,"Location of end block + 1:" + l);
|
||||
// The end block location is now l
|
||||
if (plugin.aboveAGreenhouse(l) == null) {
|
||||
return;
|
||||
}
|
||||
// Find out who is around the piston
|
||||
for (Player p : plugin.getServer().getOnlinePlayers()) {
|
||||
if (Settings.worldName.contains(p.getLocation().getWorld().getName())) {
|
||||
if (p.getLocation().distanceSquared(e.getBlock().getLocation()) <= 25) {
|
||||
p.sendMessage(ChatColor.RED + Locale.eventpistonerror);
|
||||
e.setCancelled(true);
|
||||
blockedPistons.add(e.getBlock().getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
e.setCancelled(e.getBlocks().stream().anyMatch(this::checkBlockHeight));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
package world.bentobox.greenhouses.listeners;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.Settings;
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
|
||||
public class GreenhouseGuard implements Listener {
|
||||
private final Greenhouses plugin;
|
||||
@ -20,32 +21,31 @@ public class GreenhouseGuard implements Listener {
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onFlow(final BlockFromToEvent e) {
|
||||
// Flow may be allowed anyway
|
||||
if (Settings.allowFlowIn && Settings.allowFlowOut) {
|
||||
if (plugin.getSettings().isAllowFlowIn() && plugin.getSettings().isAllowFlowOut()) {
|
||||
return;
|
||||
}
|
||||
if (!Settings.worldName.isEmpty() && !Settings.worldName.contains(e.getBlock().getWorld().getName())) {
|
||||
if (!plugin.getActiveWorlds().contains(e.getBlock().getWorld())) {
|
||||
return;
|
||||
}
|
||||
// Get To and From Districts
|
||||
Greenhouse to = plugin.getInGreenhouse(e.getToBlock().getLocation());
|
||||
Greenhouse from = plugin.getInGreenhouse(e.getBlock().getLocation());
|
||||
// Get To and From
|
||||
Optional<Greenhouse> to = plugin.getManager().getMap().getGreenhouse(e.getToBlock().getLocation());
|
||||
Optional<Greenhouse> from = plugin.getManager().getMap().getGreenhouse(e.getBlock().getLocation());
|
||||
// Scenarios
|
||||
// 1. inside district or outside - always ok
|
||||
// 2. inside to outside - allowFlowOut determines
|
||||
// 3. outside to inside - allowFlowIn determines
|
||||
if (to == null && from == null) {
|
||||
if (!to.isPresent() && !from.isPresent()) {
|
||||
return;
|
||||
}
|
||||
if (to !=null && from != null && to.equals(from)) {
|
||||
if (to.isPresent() && from.isPresent() && to.equals(from)) {
|
||||
return;
|
||||
}
|
||||
// to or from or both are districts, NOT the same and flow is across a boundary
|
||||
// if to is a district, flow in is allowed
|
||||
if (to != null && Settings.allowFlowIn) {
|
||||
// to is a greenhouse
|
||||
if (to.isPresent() && plugin.getSettings().isAllowFlowIn()) {
|
||||
return;
|
||||
}
|
||||
// if from is a district, flow may allowed
|
||||
if (from != null && Settings.allowFlowOut) {
|
||||
// from is a greenhouse
|
||||
if (from.isPresent() && plugin.getSettings().isAllowFlowOut()) {
|
||||
return;
|
||||
}
|
||||
// Otherwise cancel - the flow is not allowed
|
||||
|
@ -1,54 +0,0 @@
|
||||
package world.bentobox.greenhouses.listeners;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
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.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.PlayerCache;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
|
||||
public class JoinLeaveEvents implements Listener {
|
||||
private Greenhouses addon;
|
||||
private PlayerCache players;
|
||||
|
||||
public JoinLeaveEvents(Greenhouses greenhouses, PlayerCache onlinePlayers) {
|
||||
this.addon = greenhouses;
|
||||
this.players = onlinePlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPlayerJoin(final PlayerJoinEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
final UUID playerUUID = p.getUniqueId();
|
||||
// Add player to the cache, and clear any greenhouses over their permitted limit
|
||||
addon.players.addPlayer(p);
|
||||
addon.logger(3,"Cached " + p.getName());
|
||||
// Load any messages for the player
|
||||
final List<String> messages = addon.getMessages(playerUUID);
|
||||
if (!messages.isEmpty()) {
|
||||
addon.getServer().getScheduler().runTaskLater(addon.getPlugin(), () -> {
|
||||
event.getPlayer().sendMessage(ChatColor.AQUA + Locale.newsheadline);
|
||||
int i = 1;
|
||||
for (String message : messages) {
|
||||
event.getPlayer().sendMessage(i++ + ": " + message);
|
||||
}
|
||||
}, 40L);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPlayerQuit(final PlayerQuitEvent event) {
|
||||
players.removeOnlinePlayer(event.getPlayer());
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
package world.bentobox.greenhouses.listeners;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.block.data.type.Snow;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
|
||||
/**
|
||||
* Monitors the greenhouses and grows things, adds weather etc.
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class SnowTracker implements Listener {
|
||||
private final Greenhouses addon;
|
||||
private final static List<Biome> SNOWBIOMES = Arrays.stream(Biome.values()).filter(b -> b.name().contains("COLD") || b.name().contains("ICE") || b.name().contains("FROZEN")).collect(Collectors.toList());
|
||||
private Map<World, BukkitTask> snowTasks;
|
||||
|
||||
public SnowTracker(Greenhouses addon) {
|
||||
this.addon = addon;
|
||||
snowTasks = new HashMap<>();
|
||||
// Start snow if ongoing
|
||||
addon.getActiveWorlds().stream().filter(World::isThundering)
|
||||
.forEach(w -> snowTasks.putIfAbsent(w, Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> shakeGlobes(w), 0L, 100L)));
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWeatherChangeEvent(final WeatherChangeEvent e) {
|
||||
if (!addon.getActiveWorlds().contains(e.getWorld())) {
|
||||
return;
|
||||
}
|
||||
if (e.toWeatherState()) {
|
||||
// It's raining
|
||||
//addon.logger(3,"It's raining!");
|
||||
startSnow(e.getWorld());
|
||||
} else {
|
||||
// It's stopped raining!
|
||||
//addon.logger(3,"Stopped raining!");
|
||||
stopSnow(e.getWorld());
|
||||
}
|
||||
}
|
||||
|
||||
private void stopSnow(World world) {
|
||||
if (snowTasks.containsKey(world)) {
|
||||
snowTasks.get(world).cancel();
|
||||
snowTasks.remove(world);
|
||||
}
|
||||
}
|
||||
|
||||
private void startSnow(World world) {
|
||||
// Start timer
|
||||
snowTasks.putIfAbsent(world, Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> shakeGlobes(world), 0L, 100L)); // every 5 seconds
|
||||
}
|
||||
|
||||
private void shakeGlobes(World world) {
|
||||
addon.getManager().getMap().getGreenhouses().stream().filter(g -> SNOWBIOMES.contains(g.getBiomeRecipe().getBiome()))
|
||||
.filter(g -> g.getLocation().getWorld().equals(world))
|
||||
.filter(g -> !g.isBroken())
|
||||
.filter(g -> g.getRoofHopperLocation() != null)
|
||||
.filter(g -> g.getRoofHopperLocation().getBlock().getType().equals(Material.HOPPER))
|
||||
.filter(g -> ((Hopper)g.getRoofHopperLocation().getBlock()).getInventory().contains(Material.WATER_BUCKET))
|
||||
.forEach(this::removeWaterBucketAndShake);
|
||||
}
|
||||
|
||||
private void removeWaterBucketAndShake(Greenhouse g) {
|
||||
Hopper h = ((Hopper)g.getRoofHopperLocation().getBlock());
|
||||
h.getInventory().removeItem(new ItemStack(Material.WATER_BUCKET));
|
||||
h.getInventory().addItem(new ItemStack(Material.BUCKET));
|
||||
// Scatter snow
|
||||
getAirBlocks(g);
|
||||
}
|
||||
|
||||
private List<Block> getAirBlocks(Greenhouse gh) {
|
||||
List<Block> waterBlocks = new ArrayList<>();
|
||||
List<Block> result = new ArrayList<>();
|
||||
for (int x = (int)gh.getFootprint().getMinX() + 1; x < (int)gh.getFootprint().getMaxX(); x++) {
|
||||
for (int z = (int)gh.getFootprint().getMinY() + 1; z < (int)gh.getFootprint().getMaxY(); z++) {
|
||||
for (int y = gh.getCeilingHeight() - 1; y >= gh.getFloorHeight(); y--) {
|
||||
Block b = gh.getLocation().getWorld().getBlockAt(x, y, z);
|
||||
if (b.getType().equals(Material.AIR)) {
|
||||
b.getWorld().spawnParticle(Particle.SNOWBALL, b.getLocation(), 5);
|
||||
} else {
|
||||
// Add snow
|
||||
if (b.getType().equals(Material.WATER)) {
|
||||
waterBlocks.add(b);
|
||||
} else {
|
||||
// Not water
|
||||
if (Math.random() < addon.getSettings().getSnowDensity() && !b.isLiquid()) {
|
||||
addSnow(b);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if any water blocks can be turned to ice
|
||||
int maxSize = waterBlocks.size() - (gh.getArea() / gh.getBiomeRecipe().getWaterCoverage());
|
||||
if (maxSize > 0) {
|
||||
waterBlocks.stream().limit(maxSize).filter(b -> Math.random() < addon.getSettings().getSnowDensity()).forEach(b -> b.setType(Material.ICE));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addSnow(Block b) {
|
||||
Block above = b.getRelative(BlockFace.UP);
|
||||
if (above.getType().equals(Material.SNOW) || above.getType().equals(Material.AIR)) {
|
||||
above.setType(Material.SNOW);
|
||||
Snow snow = (Snow)above;
|
||||
snow.setLayers(Math.min(snow.getMaximumLayers(), snow.getLayers() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
package world.bentobox.greenhouses.managers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
|
||||
/**
|
||||
* Runs the ecosystem for a greenhouse
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class EcoSystemManager {
|
||||
|
||||
private Greenhouses addon;
|
||||
private GreenhouseManager g;
|
||||
private BukkitTask plantTask;
|
||||
private BukkitTask mobTask;
|
||||
private BukkitTask blockTask;
|
||||
private BukkitTask ecoTask;
|
||||
|
||||
public EcoSystemManager(Greenhouses addon, GreenhouseManager greenhouseManager) {
|
||||
this.addon = addon;
|
||||
this.g = greenhouseManager;
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
// Kick off flower growing
|
||||
long plantTick = addon.getSettings().getPlantTick() * 60 * 20; // In minutes
|
||||
if (plantTick > 0) {
|
||||
addon.log("Kicking off flower growing scheduler every " + addon.getSettings().getPlantTick() + " minutes");
|
||||
plantTask = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
|
||||
g.getMap().getGreenhouses().forEach(gh -> growPlants(gh));
|
||||
}, 80L, plantTick);
|
||||
|
||||
} else {
|
||||
addon.log("Flower growth disabled.");
|
||||
}
|
||||
|
||||
// Kick block conversion growing
|
||||
long blockTick = addon.getSettings().getBlockTick() * 60 * 20; // In minutes
|
||||
|
||||
if (blockTick > 0) {
|
||||
addon.log("Kicking off block conversion scheduler every " + addon.getSettings().getBlockTick() + " minutes");
|
||||
blockTask = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
|
||||
addon.log("Servicing greenhouse biome");
|
||||
|
||||
|
||||
}, 60L, blockTick);
|
||||
} else {
|
||||
addon.log("Block conversion disabled.");
|
||||
}
|
||||
// Kick off g/h verification
|
||||
long ecoTick = addon.getSettings().getEcoTick() * 60 * 20; // In minutes
|
||||
if (ecoTick > 0) {
|
||||
addon.log("Kicking off greenhouse verify scheduler every " + addon.getSettings().getEcoTick() + " minutes");
|
||||
ecoTask = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
|
||||
// Todo
|
||||
}, ecoTick, ecoTick);
|
||||
|
||||
} else {
|
||||
addon.log("Greenhouse verification disabled.");
|
||||
}
|
||||
// Kick off mob population
|
||||
long mobTick = addon.getSettings().getMobTick() * 60 * 20; // In minutes
|
||||
if (mobTick > 0) {
|
||||
addon.log("Kicking off mob populator scheduler every " + addon.getSettings().getMobTick() + " minutes");
|
||||
mobTask = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
|
||||
}, 120L, mobTick);
|
||||
|
||||
} else {
|
||||
addon.log("Mob disabled.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Growns plants in the greenhouse
|
||||
* @param gh - greenhouse
|
||||
*/
|
||||
private void growPlants(Greenhouse gh) {
|
||||
int bonemeal = getBoneMeal(gh);
|
||||
if (bonemeal > 0) {
|
||||
// Get a list of all available blocks
|
||||
setBoneMeal(gh, bonemeal - getAvailableBlocks(gh).stream().limit(bonemeal).mapToInt(bl -> gh.getBiomeRecipe().growPlant(bl) ? 1 : 0).sum());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a hopper's bone meal to this value
|
||||
* @param gh - greenhouse
|
||||
* @param value - value to set
|
||||
*/
|
||||
private void setBoneMeal(Greenhouse gh, int value) {
|
||||
Hopper hopper = getHopper(gh);
|
||||
if (hopper != null) {
|
||||
hopper.getInventory().remove(Material.BONE_MEAL);
|
||||
hopper.getInventory().addItem(new ItemStack(Material.BONE_MEAL, value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the highest block inside the greenhouse
|
||||
* @param gh - greenhouse
|
||||
* @return List of blocks
|
||||
*/
|
||||
private List<Block> getAvailableBlocks(Greenhouse gh) {
|
||||
List<Block> result = new ArrayList<>();
|
||||
for (int x = (int)gh.getFootprint().getMinX() + 1; x < (int)gh.getFootprint().getMaxX(); x++) {
|
||||
for (int z = (int)gh.getFootprint().getMinY() + 1; z < (int)gh.getFootprint().getMaxY(); z++) {
|
||||
for (int y = gh.getCeilingHeight() - 1; y >= gh.getFloorHeight(); y--) {
|
||||
Block b = gh.getLocation().getWorld().getBlockAt(x, y, z);
|
||||
if (!b.getType().equals(Material.AIR)) {
|
||||
result.add(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int getBoneMeal(Greenhouse gh) {
|
||||
Hopper hopper = getHopper(gh);
|
||||
if (hopper == null || !hopper.getInventory().contains(Material.BONE_MEAL)) {
|
||||
return 0;
|
||||
}
|
||||
return Arrays.stream(hopper.getInventory().getContents()).filter(Objects::nonNull)
|
||||
.filter(i -> i.getType().equals(Material.BONE_MEAL))
|
||||
.mapToInt(ItemStack::getAmount).sum();
|
||||
}
|
||||
|
||||
private Hopper getHopper(Greenhouse gh) {
|
||||
if (gh.getRoofHopperLocation() == null) {
|
||||
return null;
|
||||
}
|
||||
// Check if there are any bonemeal in the hopper
|
||||
if (gh.getRoofHopperLocation().getBlock().getType() != Material.HOPPER) {
|
||||
gh.setRoofHopperLocation(null);
|
||||
return null;
|
||||
}
|
||||
return (Hopper)gh.getRoofHopperLocation().getBlock().getBlockData();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
plantTask.cancel();
|
||||
mobTask.cancel();
|
||||
blockTask.cancel();
|
||||
ecoTask.cancel();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
package world.bentobox.greenhouses.managers;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
import world.bentobox.greenhouses.greenhouse.Roof;
|
||||
import world.bentobox.greenhouses.greenhouse.Walls;
|
||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
||||
|
||||
public class GreenhouseFinder {
|
||||
|
||||
private Greenhouse gh;
|
||||
private Set<Location> redGlass = new HashSet<Location>();
|
||||
|
||||
|
||||
public Set<GreenhouseResult> find(Location location) {
|
||||
Set<GreenhouseResult> result = new HashSet<>();
|
||||
redGlass.clear();
|
||||
|
||||
// Find the roof
|
||||
Roof roof = new Roof(location);
|
||||
if (!roof.isRoofFound()) {
|
||||
result.add(GreenhouseResult.FAIL_NO_ROOF);
|
||||
return result;
|
||||
}
|
||||
// Find the walls
|
||||
Walls walls = new Walls(roof);
|
||||
|
||||
// Make the initial greenhouse
|
||||
gh = new Greenhouse(location.getWorld(), new Rectangle(walls.getMinX(), walls.getMinZ(), walls.getMaxX(), walls.getMaxZ()), walls.getFloor(), roof.getHeight());
|
||||
// Set the original biome
|
||||
gh.setOriginalBiome(location.getBlock().getBiome());
|
||||
|
||||
// Now check again to see if the floor really is the floor and the walls follow the rules
|
||||
World world = roof.getLocation().getWorld();
|
||||
int minX = walls.getMinX();
|
||||
int minZ = walls.getMinZ();
|
||||
int maxX = walls.getMaxX();
|
||||
int maxZ = walls.getMaxZ();
|
||||
|
||||
// Counts
|
||||
int wallDoors = 0;
|
||||
// Hoppers
|
||||
int ghHopper = 0;
|
||||
// Air
|
||||
boolean airHoles = false;
|
||||
// Other blocks
|
||||
boolean otherBlocks = false;
|
||||
// Ceiling issue
|
||||
boolean inCeiling = false;
|
||||
// The y height where other blocks were found
|
||||
// If this is the bottom layer, the player has most likely uneven walls
|
||||
int otherBlockLayer = -1;
|
||||
int wallBlockCount = 0;
|
||||
|
||||
int y = 0;
|
||||
for (y = world.getMaxHeight() - 1; y >= walls.getFloor(); y--) {
|
||||
int doorCount = 0;
|
||||
int hopperCount = 0;
|
||||
boolean airHole = false;
|
||||
boolean otherBlock = false;
|
||||
wallBlockCount = 0;
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
Location thisBlock = new Location(world, x, y, z);
|
||||
Material blockType = world.getBlockAt(x, y, z).getType();
|
||||
// Checking above greenhouse - no blocks allowed
|
||||
if (y > roof.getHeight()) {
|
||||
// We are above the greenhouse
|
||||
if ((world.getEnvironment().equals(Environment.NORMAL) || world.getEnvironment().equals(Environment.THE_END))
|
||||
&& blockType != Material.AIR) {
|
||||
result.add(GreenhouseResult.FAIL_BLOCKS_ABOVE);
|
||||
redGlass.add(thisBlock);
|
||||
}
|
||||
} else {
|
||||
// Check just the walls
|
||||
if (y == roof.getHeight() || x == minX || x == maxX || z == minZ || z== maxZ) {
|
||||
//Greenhouses.addon.logDebug("DEBUG: Checking " + x + " " + y + " " + z);
|
||||
if ((y != roof.getHeight() && !Walls.WALL_BLOCKS.contains(blockType))
|
||||
|| (y == roof.getHeight() && !Roof.ROOFBLOCKS.contains(blockType))) {
|
||||
//logger(2,"DEBUG: bad block found at " + x + "," + y+ "," + z + " " + blockType);
|
||||
if (blockType == Material.AIR) {
|
||||
airHole = true;
|
||||
if (y == roof.getHeight()) {
|
||||
inCeiling = true;
|
||||
}
|
||||
} else {
|
||||
otherBlock = true;
|
||||
}
|
||||
redGlass.add(thisBlock);
|
||||
} else {
|
||||
wallBlockCount++;
|
||||
// A string comparison is used to capture 1.8+ door types without stopping pre-1.8
|
||||
// servers from working
|
||||
if (blockType.toString().contains("DOOR")) {
|
||||
doorCount++;
|
||||
// If we already have 8 doors add these blocks to the red list
|
||||
if (wallDoors == 8) {
|
||||
redGlass.add(thisBlock);
|
||||
}
|
||||
}
|
||||
if (blockType.equals(Material.HOPPER)) {
|
||||
hopperCount++;
|
||||
if (ghHopper > 0) {
|
||||
// Problem! Add extra hoppers to the red glass list
|
||||
redGlass.add(thisBlock);
|
||||
} else {
|
||||
// This is the first hopper
|
||||
gh.setRoofHopperLocation(thisBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wallBlockCount == 0 && y < roof.getHeight()) {
|
||||
// This is the floor
|
||||
break;
|
||||
} else {
|
||||
wallBlockCount = 0;
|
||||
wallDoors += doorCount;
|
||||
ghHopper += hopperCount;
|
||||
if (airHole) {
|
||||
airHoles = true;
|
||||
}
|
||||
if (otherBlock) {
|
||||
otherBlocks = true;
|
||||
if (otherBlockLayer < 0) {
|
||||
otherBlockLayer = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//addon.logDebug("Floor is at height y = " + y);
|
||||
// Check that the player is vertically in the greenhouse
|
||||
if (roof.getLocation().getBlockY() <= y) {
|
||||
result.add(GreenhouseResult.FAIL_BELOW);
|
||||
}
|
||||
// Show errors
|
||||
if (airHoles & !inCeiling) {
|
||||
result.add(GreenhouseResult.FAIL_HOLE_IN_WALL);
|
||||
} else if (airHoles & inCeiling) {
|
||||
result.add(GreenhouseResult.FAIL_HOLE_IN_ROOF);
|
||||
}
|
||||
//Greenhouses.addon.logDebug("DEBUG: otherBlockLayer = " + otherBlockLayer);
|
||||
if (otherBlocks && otherBlockLayer == y + 1) {
|
||||
// Walls must be even all the way around
|
||||
result.add(GreenhouseResult.FAIL_UNEVEN_WALLS);
|
||||
} else if (otherBlocks && otherBlockLayer == roof.getHeight()) {
|
||||
// Roof blocks must be glass, glowstone, doors or a hopper.
|
||||
result.add(GreenhouseResult.FAIL_BAD_ROOF_BLOCKS);
|
||||
} else if (otherBlocks) {
|
||||
// "Wall blocks must be glass, glowstone, doors or a hopper.
|
||||
result.add(GreenhouseResult.FAIL_BAD_WALL_BLOCKS);
|
||||
}
|
||||
if (wallDoors > 8) {
|
||||
result.add(GreenhouseResult.FAIL_TOO_MANY_DOORS);
|
||||
}
|
||||
if (ghHopper > 1) {
|
||||
result.add(GreenhouseResult.FAIL_TOO_MANY_HOPPERS);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the gh
|
||||
*/
|
||||
public Greenhouse getGh() {
|
||||
return gh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the redGlass
|
||||
*/
|
||||
public Set<Location> getRedGlass() {
|
||||
return redGlass;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
package world.bentobox.greenhouses.managers;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import world.bentobox.bentobox.database.Database;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
import world.bentobox.greenhouses.managers.GreenhouseMap.AddResult;
|
||||
|
||||
public class GreenhouseManager {
|
||||
|
||||
// No result = success
|
||||
public enum GreenhouseResult {
|
||||
FAIL_NO_ROOF,
|
||||
FAIL_BELOW,
|
||||
FAIL_BLOCKS_ABOVE,
|
||||
FAIL_HOLE_IN_WALL,
|
||||
FAIL_HOLE_IN_ROOF,
|
||||
FAIL_UNEVEN_WALLS,
|
||||
FAIL_BAD_ROOF_BLOCKS,
|
||||
FAIL_BAD_WALL_BLOCKS,
|
||||
FAIL_TOO_MANY_DOORS,
|
||||
FAIL_TOO_MANY_HOPPERS,
|
||||
FAIL_NO_WATER,
|
||||
FAIL_NO_LAVA,
|
||||
FAIL_NO_ICE,
|
||||
FAIL_INSUFFICIENT_WATER,
|
||||
FAIL_INSUFFICIENT_LAVA,
|
||||
FAIL_INSUFFICIENT_ICE
|
||||
}
|
||||
|
||||
private Greenhouses addon;
|
||||
// Greenhouses
|
||||
private GreenhouseMap map;
|
||||
private Database<Greenhouse> handler;
|
||||
|
||||
public GreenhouseManager(Greenhouses addon) {
|
||||
this.addon = addon;
|
||||
handler = new Database<>(addon, Greenhouse.class);
|
||||
map = new GreenhouseMap(addon);
|
||||
loadGreenhouses();
|
||||
// Start ecosystems
|
||||
new EcoSystemManager(addon, this);
|
||||
}
|
||||
|
||||
public GreenhouseMap getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all known greenhouses
|
||||
*/
|
||||
public void loadGreenhouses() {
|
||||
addon.log("Loading greenhouses...");
|
||||
handler.loadObjects().forEach(g -> {
|
||||
AddResult result = map.addGreenhouse(g);
|
||||
switch (result) {
|
||||
case FAIL_NO_ISLAND:
|
||||
case FAIL_OVERLAPPING:
|
||||
case NULL:
|
||||
addon.logError(result.name());
|
||||
break;
|
||||
case SUCCESS:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
addon.log("Loaded greenhouses.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all the greenhouses to database
|
||||
*/
|
||||
public void saveGreenhouses() {
|
||||
addon.log("Saving greenhouses...");
|
||||
map.getGreenhouses().forEach(handler::saveObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the greenhouse from the world and resets biomes
|
||||
* @param g
|
||||
*/
|
||||
public void removeGreenhouse(Greenhouse g) {
|
||||
map.removeGreenhouse(g);
|
||||
addon.log("Returning biome to original state: " + g.getOriginalBiome().toString());
|
||||
if (g.getOriginalBiome().equals(Biome.NETHER) || g.getOriginalBiome().equals(Biome.DESERT)
|
||||
|| g.getOriginalBiome().equals(Biome.DESERT_HILLS)) {
|
||||
for (int x = (int)g.getFootprint().getMinX(); x<= (int)g.getFootprint().getMaxX(); x++) {
|
||||
for (int z = (int)g.getFootprint().getMinY(); z<= (int)g.getFootprint().getMinY(); z++) {
|
||||
// Set back to the original biome
|
||||
g.getLocation().getWorld().setBiome(x, z, g.getOriginalBiome());
|
||||
for (int y = g.getFloorHeight(); y< g.getCeilingHeight(); y++) {
|
||||
Block b = g.getLocation().getWorld().getBlockAt(x, y, z);
|
||||
// Remove any water
|
||||
if (b.getType().equals(Material.WATER) || b.getType().equals(Material.BLUE_ICE)
|
||||
|| b.getType().equals(Material.FROSTED_ICE)
|
||||
|| b.getType().equals(Material.ICE) || b.getType().equals(Material.PACKED_ICE)
|
||||
|| b.getType().equals(Material.SNOW) || b.getType().equals(Material.SNOW_BLOCK)) {
|
||||
// Evaporate it
|
||||
b.setType(Material.AIR);
|
||||
b.getWorld().spawnParticle(Particle.SMOKE_LARGE, b.getLocation(), 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks that a greenhouse meets specs and makes it
|
||||
* If type is stated then only this specific type will be checked
|
||||
* @param user
|
||||
* @param greenhouseRecipe
|
||||
* @return
|
||||
*/
|
||||
public GhResult tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) {
|
||||
addon.log("Player location is " + location.getBlockX() + " " + location.getBlockY() + " " + location.getBlockZ());
|
||||
GreenhouseFinder finder = new GreenhouseFinder();
|
||||
Set<GreenhouseResult> resultSet = finder.find(location);
|
||||
if (!resultSet.isEmpty()) {
|
||||
// Failure!
|
||||
return new GhResult().setFinder(finder).setResults(resultSet);
|
||||
}
|
||||
// Check if the greenhouse meets the requested recipe
|
||||
if (greenhouseRecipe != null) {
|
||||
resultSet = greenhouseRecipe.checkRecipe(finder.getGh());
|
||||
if (resultSet.isEmpty()) {
|
||||
// Success - set recipe and add to map
|
||||
finder.getGh().setBiomeRecipe(greenhouseRecipe);
|
||||
map.addGreenhouse(finder.getGh());
|
||||
}
|
||||
return new GhResult().setFinder(finder).setResults(resultSet);
|
||||
}
|
||||
// Try ordered recipes
|
||||
addon.getRecipes().getBiomeRecipes().stream().sorted()
|
||||
.filter(r -> r.checkRecipe(finder.getGh()).isEmpty()).findFirst()
|
||||
.ifPresent(r -> {
|
||||
// Success - set recipe and add to map
|
||||
finder.getGh().setBiomeRecipe(r);
|
||||
map.addGreenhouse(finder.getGh());
|
||||
});
|
||||
return new GhResult().setFinder(finder).setResults(resultSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of the greenhouse make effort
|
||||
*
|
||||
*/
|
||||
public class GhResult {
|
||||
private Set<GreenhouseResult> results;
|
||||
private GreenhouseFinder finder;
|
||||
|
||||
/**
|
||||
* @return the results
|
||||
*/
|
||||
public Set<GreenhouseResult> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the finder
|
||||
*/
|
||||
public GreenhouseFinder getFinder() {
|
||||
return finder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param results the results to set
|
||||
*/
|
||||
public GhResult setResults(Set<GreenhouseResult> results) {
|
||||
this.results = results;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param finder the finder to set
|
||||
*/
|
||||
public GhResult setFinder(GreenhouseFinder finder) {
|
||||
this.finder = finder;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package world.bentobox.greenhouses.managers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
|
||||
public class GreenhouseMap {
|
||||
|
||||
public enum AddResult {
|
||||
SUCCESS,
|
||||
FAIL_OVERLAPPING,
|
||||
FAIL_NO_ISLAND,
|
||||
NULL
|
||||
}
|
||||
private Greenhouses addon;
|
||||
private Map<Island, List<Greenhouse>> greenhouses = new HashMap<>();
|
||||
|
||||
/**
|
||||
* @param addon - addon
|
||||
*/
|
||||
public GreenhouseMap(Greenhouses addon) {
|
||||
this.addon = addon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to add a greenhouse
|
||||
* @param greenhouse - greenhouse object
|
||||
* @return {@link AddResult#SUCCESS}, {@link AddResult#FAIL_NO_ISLAND} or {@link AddResult#FAIL_OVERLAPPING}
|
||||
*/
|
||||
public AddResult addGreenhouse(Greenhouse greenhouse) {
|
||||
if (greenhouse.getLocation() == null) {
|
||||
return AddResult.NULL;
|
||||
}
|
||||
return addon.getIslands().getIslandAt(greenhouse.getLocation()).map(i -> {
|
||||
greenhouses.putIfAbsent(i, new ArrayList<>());
|
||||
// Check if overlapping
|
||||
if (!isOverlapping(greenhouse)) {
|
||||
greenhouses.get(i).add(greenhouse);
|
||||
return AddResult.SUCCESS;
|
||||
} else {
|
||||
return AddResult.FAIL_OVERLAPPING;
|
||||
}
|
||||
}).orElse(AddResult.FAIL_NO_ISLAND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get greenhouse at location
|
||||
* @param location - location
|
||||
* @return Optional greenhouse or empty
|
||||
*/
|
||||
public Optional<Greenhouse> getGreenhouse(Location location) {
|
||||
return getXZGreenhouse(location).filter(g -> location.getBlockY() <= g.getCeilingHeight() && location.getBlockY() >= g.getFloorHeight());
|
||||
}
|
||||
|
||||
private Optional<Greenhouse> getXZGreenhouse(Location location) {
|
||||
return addon.getIslands().getIslandAt(location).map(i -> {
|
||||
greenhouses.putIfAbsent(i, new ArrayList<>());
|
||||
return greenhouses.get(i).stream().filter(g -> g.getFootprint().contains(location.getX(), location.getY())).findFirst();
|
||||
}).orElse(Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if location is inside a greenhouse
|
||||
* @param location - location
|
||||
* @return true if inside a greenhouse
|
||||
*/
|
||||
public boolean inGreenhouse(Location location) {
|
||||
return getGreenhouse(location).isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if location is above a greenhouse
|
||||
* @param location - location
|
||||
* @return true if above a known greenhouse
|
||||
*/
|
||||
public boolean isAboveGreenhouse(Location location) {
|
||||
return getXZGreenhouse(location).map(g -> location.getBlockY() > g.getCeilingHeight()).orElse(false);
|
||||
}
|
||||
|
||||
private boolean isOverlapping(Greenhouse greenhouse) {
|
||||
return addon.getIslands().getIslandAt(greenhouse.getLocation()).map(i -> {
|
||||
greenhouses.putIfAbsent(i, new ArrayList<>());
|
||||
return greenhouses.get(i).stream().anyMatch(g -> g.getFootprint().intersects(greenhouse.getFootprint()));
|
||||
}).orElse(false);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the greenhouse from the map
|
||||
* @param greenhouse - greenhouse
|
||||
*/
|
||||
public void removeGreenhouse(Greenhouse greenhouse) {
|
||||
addon.getIslands().getIslandAt(greenhouse.getLocation()).ifPresent(i -> {
|
||||
greenhouses.putIfAbsent(i, new ArrayList<>());
|
||||
greenhouses.get(i).remove(greenhouse);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of all the Greenhouses
|
||||
*/
|
||||
public List<Greenhouse> getGreenhouses() {
|
||||
return greenhouses.values().stream().flatMap(List::stream).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
package world.bentobox.greenhouses.managers;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
|
||||
public class RecipeManager {
|
||||
|
||||
private static final int MAXIMUM_INVENTORY_SIZE = 49;
|
||||
private Greenhouses addon;
|
||||
private List<BiomeRecipe> biomeRecipes = new ArrayList<>();
|
||||
|
||||
public RecipeManager(Greenhouses addon) {
|
||||
this.addon = addon;
|
||||
try {
|
||||
loadBiomeRecipes();
|
||||
} catch (Exception e) {
|
||||
addon.logError(e.getMessage());
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all the biome recipes from the file biomes.yml.
|
||||
* @throws InvalidConfigurationException
|
||||
* @throws IOException
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public void loadBiomeRecipes() throws FileNotFoundException, IOException, InvalidConfigurationException {
|
||||
biomeRecipes.clear();
|
||||
YamlConfiguration biomes = new YamlConfiguration();
|
||||
File biomeFile = new File(addon.getDataFolder(), "biomes.yml");
|
||||
if (!biomeFile.exists()) {
|
||||
addon.logError("No biomes.yml file!");
|
||||
addon.saveResource("biomes.yml", true);
|
||||
}
|
||||
biomes.load(biomeFile);
|
||||
ConfigurationSection biomeSection = biomes.getConfigurationSection("biomes");
|
||||
if (biomeSection == null) {
|
||||
addon.logError("biomes.yml file is missing, empty or corrupted. Delete and reload plugin again!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through all the entries
|
||||
for (String type: biomeSection.getValues(false).keySet()) {
|
||||
try {
|
||||
ConfigurationSection biomeRecipe = biomeSection.getConfigurationSection(type);
|
||||
Biome thisBiome = null;
|
||||
if (biomeRecipe.contains("biome")) {
|
||||
// Try and get the biome via the biome setting
|
||||
thisBiome = Biome.valueOf(biomeRecipe.getString("biome").toUpperCase());
|
||||
} else {
|
||||
// Old style, where type was the biome name
|
||||
thisBiome = Biome.valueOf(type);
|
||||
}
|
||||
if (thisBiome != null) {
|
||||
int priority = biomeRecipe.getInt("priority", 0);
|
||||
BiomeRecipe b = new BiomeRecipe(addon, thisBiome,priority);
|
||||
// Set the name
|
||||
b.setName(type);
|
||||
// Set the permission
|
||||
b.setPermission(biomeRecipe.getString("permission",""));
|
||||
// Set the icon
|
||||
b.setIcon(Material.valueOf(biomeRecipe.getString("icon", "SAPLING")));
|
||||
b.setFriendlyName(ChatColor.translateAlternateColorCodes('&', biomeRecipe.getString("friendlyname", "")));
|
||||
// A value of zero on these means that there must be NO coverage, e.g., desert. If the value is not present, then the default is -1
|
||||
b.setWatercoverage(biomeRecipe.getInt("watercoverage",-1));
|
||||
b.setLavacoverage(biomeRecipe.getInt("lavacoverage",-1));
|
||||
b.setIcecoverage(biomeRecipe.getInt("icecoverage",-1));
|
||||
b.setMobLimit(biomeRecipe.getInt("moblimit", 9));
|
||||
// Set the needed blocks
|
||||
ConfigurationSection reqContents = biomeRecipe.getConfigurationSection("contents");
|
||||
if (reqContents != null) {
|
||||
for (String rq : reqContents.getKeys(false)) {
|
||||
Material mat = Material.valueOf(rq.toUpperCase());
|
||||
if (mat != null) {
|
||||
b.addReqBlocks(mat, reqContents.getInt(rq));
|
||||
} else {
|
||||
addon.logError("Could not parse required block " + rq);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load plants
|
||||
// # Plant Material: Probability in %:Block Material on what they grow
|
||||
ConfigurationSection temp = biomes.getConfigurationSection("biomes." + type + ".plants");
|
||||
if (temp != null) {
|
||||
HashMap<String,Object> plants = (HashMap<String,Object>)temp.getValues(false);
|
||||
if (plants != null) {
|
||||
for (String s: plants.keySet()) {
|
||||
//logger(1, "Plant = " + s);
|
||||
Material plantMaterial = Material.valueOf(s);
|
||||
|
||||
//logger(1, "Plant = " + plantMaterial);
|
||||
String[] split = ((String)plants.get(s)).split(":");
|
||||
//logger(1, "Split length = " + split.length);
|
||||
int plantProbability = Integer.valueOf(split[0]);
|
||||
Material plantGrowOn = Material.valueOf(split[1]);
|
||||
|
||||
b.addPlants(plantMaterial, plantProbability, plantGrowOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load mobs!
|
||||
// Mob EntityType: Probability:Spawn on Material
|
||||
temp = biomes.getConfigurationSection("biomes." + type + ".mobs");
|
||||
if (temp != null) {
|
||||
HashMap<String,Object> mobs = (HashMap<String,Object>)temp.getValues(false);
|
||||
if (mobs != null) {
|
||||
for (String s: mobs.keySet()) {
|
||||
EntityType mobType = EntityType.valueOf(s);
|
||||
String[] split = ((String)mobs.get(s)).split(":");
|
||||
int mobProbability = Integer.valueOf(split[0]);
|
||||
Material mobSpawnOn = Material.valueOf(split[1]);
|
||||
b.addMobs(mobType, mobProbability, mobSpawnOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load block conversions
|
||||
ConfigurationSection conversionSec = biomeSection.getConfigurationSection(type + ".conversions");
|
||||
if (conversionSec != null) {
|
||||
for (String oldMat : conversionSec.getKeys(false)) {
|
||||
Material oldMaterial = Material.valueOf(oldMat);
|
||||
if (oldMaterial == null) {
|
||||
addon.logError("Could not parse " + oldMat);
|
||||
break;
|
||||
}
|
||||
String conversions = conversionSec.getString(oldMat);
|
||||
|
||||
//logger(3,"conversions = '" + conversions + "'");
|
||||
if (!conversions.isEmpty()) {
|
||||
String[] split = conversions.split(":");
|
||||
int convChance = Integer.valueOf(split[0]);
|
||||
Material newMaterial = Material.valueOf(split[1]);
|
||||
Material localMaterial = Material.valueOf(split[2]);
|
||||
b.addConvBlocks(oldMaterial, newMaterial, convChance, localMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add the recipe to the list
|
||||
biomeRecipes.add(b);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//logger(1,"Problem loading biome recipe - skipping!");
|
||||
String validBiomes = "";
|
||||
for (Biome biome : Biome.values()) {
|
||||
validBiomes = validBiomes + " " + biome.name();
|
||||
}
|
||||
//logger(1,"Valid biomes are " + validBiomes);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Check maximum number
|
||||
if (biomeRecipes.size() == MAXIMUM_INVENTORY_SIZE) {
|
||||
addon.logWarning("Cannot load any more biome recipies - limit is 49!");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
addon.log("Loaded " + biomeRecipes.size() + " biome recipes.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the biomeRecipes
|
||||
*/
|
||||
public List<BiomeRecipe> getBiomeRecipes() {
|
||||
return biomeRecipes;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,195 +0,0 @@
|
||||
package world.bentobox.greenhouses.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.util.Util;
|
||||
import world.bentobox.greenhouses.util.VaultHelper;
|
||||
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
* Provides a handy control panel
|
||||
*/
|
||||
public class ControlPanel implements Listener {
|
||||
|
||||
private Greenhouses plugin;
|
||||
|
||||
private HashMap<UUID, HashMap<Integer,BiomeRecipe>> biomePanels = new HashMap<UUID, HashMap<Integer,BiomeRecipe>>();
|
||||
/**
|
||||
* @param store
|
||||
*/
|
||||
public ControlPanel(Greenhouses plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
Player player = (Player) event.getWhoClicked(); // The player that clicked the item
|
||||
Inventory inventory = event.getInventory(); // The inventory that was clicked in
|
||||
int slot = event.getRawSlot();
|
||||
HashMap<Integer,BiomeRecipe> panel = biomePanels.get(player.getUniqueId());
|
||||
if (panel == null) {
|
||||
// No panel, so just return
|
||||
return;
|
||||
}
|
||||
// Check this is the Greenhouse Biome Panel
|
||||
if (inventory.getName().equals(ChatColor.translateAlternateColorCodes('&', Locale.controlpaneltitle))) {
|
||||
//String message = "";
|
||||
event.setCancelled(true); // Don't let them pick anything up
|
||||
if (slot < 0) {
|
||||
player.closeInventory();
|
||||
return;
|
||||
}
|
||||
if (slot == 0) {
|
||||
player.performCommand("greenhouse info");
|
||||
player.closeInventory();
|
||||
return;
|
||||
}
|
||||
if (panel.containsKey(slot)) {
|
||||
BiomeRecipe biomeRecipe = panel.get(slot);
|
||||
// Sets up a greenhouse
|
||||
Greenhouse oldg = plugin.players.getInGreenhouse(player);
|
||||
// Check ownership
|
||||
if (oldg != null && !oldg.getOwner().equals(player.getUniqueId())) {
|
||||
player.sendMessage(Locale.errornotyours);
|
||||
player.closeInventory();
|
||||
return;
|
||||
}
|
||||
if (oldg != null) {
|
||||
// Player wants to try and change biome
|
||||
//player.closeInventory(); // Closes the inventory
|
||||
// error.exists
|
||||
//player.sendMessage(ChatColor.RED + Locale.erroralreadyexists);
|
||||
//return;
|
||||
plugin.removeGreenhouse(oldg);
|
||||
}
|
||||
// Check if they are at their limit
|
||||
if (plugin.players.isAtLimit(player)) {
|
||||
player.sendMessage(ChatColor.translateAlternateColorCodes('&', Locale.infonomore));
|
||||
} else {
|
||||
// Make greenhouse
|
||||
Greenhouse g = plugin.tryToMakeGreenhouse(player, biomeRecipe);
|
||||
if (g == null) {
|
||||
player.closeInventory(); // Closes the inventory
|
||||
//error.norecipe
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return;
|
||||
}
|
||||
player.closeInventory(); // Closes the inventory
|
||||
}
|
||||
//player.performCommand("greenhouse make");
|
||||
//player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a player-specific biome panel based on permissions
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public Inventory getPanel(Player player) {
|
||||
HashMap<Integer, BiomeRecipe> store = new HashMap<Integer,BiomeRecipe>();
|
||||
// Index 0 is reserved for instructions
|
||||
int index = 1;
|
||||
// Run through biomes and add to the inventory if this player is allowed to use them
|
||||
for (BiomeRecipe br : plugin.getBiomeRecipes()) {
|
||||
// Gather the info
|
||||
if (br.getPermission().isEmpty() || VaultHelper.checkPerm(player, br.getPermission())) {
|
||||
// Add this biome recipe to the list
|
||||
store.put(index++, br);
|
||||
}
|
||||
}
|
||||
// Now create the panel
|
||||
//int panelSize = store.size() + 9 - 1;
|
||||
int panelSize = store.size() + 9;
|
||||
panelSize -= ( panelSize % 9);
|
||||
Inventory biomePanel = Bukkit.createInventory(player, panelSize, ChatColor.translateAlternateColorCodes('&', Locale.controlpaneltitle));
|
||||
// Add the instructions item
|
||||
ItemStack item = new ItemStack(Material.THIN_GLASS);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName(Locale.generalgreenhouses);
|
||||
List<String> lore = new ArrayList<String>();
|
||||
lore.addAll(new ArrayList<String>(Arrays.asList(Locale.infowelcome.split("\\|"))));
|
||||
if (plugin.players.isAtLimit(player)) {
|
||||
lore.add(ChatColor.translateAlternateColorCodes('&', Locale.infonomore));
|
||||
} else {
|
||||
if (plugin.players.getRemainingGreenhouses(player) > 0) {
|
||||
if (plugin.players.getRemainingGreenhouses(player) == 1) {
|
||||
lore.addAll(new ArrayList<String>(Arrays.asList(Locale.infoonemore.split("\\|"))));
|
||||
} else {
|
||||
String temp = Locale.infoyoucanbuild.replace("[number]", String.valueOf(plugin.players.getRemainingGreenhouses(player)));
|
||||
lore.addAll(new ArrayList<String>(Arrays.asList(temp.split("\\|"))));
|
||||
}
|
||||
} else {
|
||||
lore.addAll(new ArrayList<String>(Arrays.asList(Locale.infounlimited.split("\\|"))));
|
||||
}
|
||||
}
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
biomePanel.setItem(0, item);
|
||||
// Now add the biomes
|
||||
|
||||
index = 1;
|
||||
for (BiomeRecipe br : store.values()) {
|
||||
// Create an itemStack
|
||||
item = new ItemStack(br.getIcon());
|
||||
meta = item.getItemMeta();
|
||||
if (br.getFriendlyName().isEmpty()) {
|
||||
meta.setDisplayName(Util.prettifyText(br.getBiome().toString()));
|
||||
} else {
|
||||
meta.setDisplayName(br.getFriendlyName());
|
||||
}
|
||||
lore.clear();
|
||||
List<String> reqBlocks = br.getRecipeBlocks();
|
||||
if (reqBlocks.size() > 0) {
|
||||
lore.add(ChatColor.YELLOW + Locale.recipeminimumblockstitle);
|
||||
int i = 1;
|
||||
for (String list : reqBlocks) {
|
||||
lore.add(Locale.lineColor + (i++) + ": " + list);
|
||||
}
|
||||
} else {
|
||||
lore.add(ChatColor.YELLOW + Locale.recipenootherblocks);
|
||||
}
|
||||
if (br.getWaterCoverage() == 0) {
|
||||
lore.add(Locale.recipenowater);
|
||||
} else if (br.getWaterCoverage() > 0) {
|
||||
lore.add(Locale.recipewatermustbe.replace("[coverage]", String.valueOf(br.getWaterCoverage())));
|
||||
}
|
||||
if (br.getIceCoverage() == 0) {
|
||||
lore.add(Locale.recipenoice);
|
||||
} else if (br.getIceCoverage() > 0) {
|
||||
lore.add(Locale.recipeicemustbe.replace("[coverage]", String.valueOf(br.getIceCoverage())));
|
||||
}
|
||||
if (br.getLavaCoverage() == 0) {
|
||||
lore.add(Locale.recipenolava);
|
||||
} else if (br.getLavaCoverage() > 0) {
|
||||
lore.add(Locale.recipelavamustbe.replace("[coverage]", String.valueOf(br.getLavaCoverage())));
|
||||
}
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
biomePanel.setItem(index++,item);
|
||||
}
|
||||
// Stash the panel for later use when clicked
|
||||
biomePanels.put(player.getUniqueId(), store);
|
||||
return biomePanel;
|
||||
}
|
||||
}
|
@ -1,248 +0,0 @@
|
||||
|
||||
package world.bentobox.greenhouses.ui;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.PlayerCache;
|
||||
import world.bentobox.greenhouses.Settings;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.util.Util;
|
||||
import world.bentobox.greenhouses.util.VaultHelper;
|
||||
|
||||
public class GreenhouseCmd implements CommandExecutor {
|
||||
public boolean busyFlag = true;
|
||||
private Greenhouses plugin;
|
||||
private PlayerCache players;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param plugin
|
||||
* @param players
|
||||
*/
|
||||
public GreenhouseCmd(Greenhouses plugin, PlayerCache players) {
|
||||
|
||||
// Plugin instance
|
||||
this.plugin = plugin;
|
||||
this.players = players;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.bukkit.command.CommandExecutor#onCommand(org.bukkit.command.CommandSender
|
||||
* , org.bukkit.command.Command, java.lang.String, java.lang.String[])
|
||||
*/
|
||||
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] split) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return false;
|
||||
}
|
||||
final Player player = (Player) sender;
|
||||
// Check we are in the right world
|
||||
if (!Settings.worldName.contains(player.getWorld().getName())) {
|
||||
// notavailable
|
||||
player.sendMessage(ChatColor.RED + Locale.generalnotavailable);
|
||||
return true;
|
||||
}
|
||||
// Basic permissions check to even use /greenhouse
|
||||
if (!VaultHelper.checkPerm(player, "greenhouses.player")) {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornoPermission);
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* Grab data for this player - may be null or empty
|
||||
* playerUUID is the unique ID of the player who issued the command
|
||||
*/
|
||||
final UUID playerUUID = player.getUniqueId();
|
||||
|
||||
switch (split.length) {
|
||||
// /greenhouse command by itself
|
||||
case 0:
|
||||
final Greenhouse greenhouseInNow = players.getInGreenhouse(player);
|
||||
if (greenhouseInNow==null || greenhouseInNow.getOwner().equals(playerUUID)) {
|
||||
player.openInventory(plugin.getRecipeInv(player));
|
||||
return true;
|
||||
} else {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornotowner);
|
||||
return true;
|
||||
}
|
||||
case 1:
|
||||
// /greenhouse <command>
|
||||
if (split[0].equalsIgnoreCase("help")) {
|
||||
player.sendMessage(ChatColor.GREEN + Locale.generalgreenhouses +" " + plugin.getDescription().getVersion() + " " + Locale.helphelp + ":");
|
||||
player.sendMessage(ChatColor.YELLOW + "/" + label + " : " + ChatColor.WHITE + Locale.helpopengui);
|
||||
player.sendMessage(ChatColor.YELLOW + "/" + label + " make: " + ChatColor.WHITE + Locale.helpmake);
|
||||
player.sendMessage(ChatColor.YELLOW + "/" + label + " remove: " + ChatColor.WHITE + Locale.helpremove);
|
||||
player.sendMessage(ChatColor.YELLOW + "/" + label + " info: " + ChatColor.WHITE + Locale.helpinfo);
|
||||
player.sendMessage(ChatColor.YELLOW + "/" + label + " list: " + ChatColor.WHITE + Locale.helplist);
|
||||
player.sendMessage(ChatColor.YELLOW + "/" + label + " recipe <number>: " + ChatColor.WHITE + Locale.helprecipe);
|
||||
return true;
|
||||
} else if (split[0].equalsIgnoreCase("list")) {
|
||||
// List all the biomes that can be made
|
||||
player.sendMessage(ChatColor.GREEN + Locale.listtitle);
|
||||
player.sendMessage(Locale.listinfo);
|
||||
int index = 0;
|
||||
for (BiomeRecipe br : plugin.getBiomeRecipes()) {
|
||||
if (br.getFriendlyName().isEmpty()) {
|
||||
player.sendMessage(ChatColor.YELLOW + Integer.toString(index++) + ": " + Util.prettifyText(br.getBiome().toString()));
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + Integer.toString(index++) + ": " + br.getFriendlyName());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (split[0].equalsIgnoreCase("remove")) {
|
||||
final Greenhouse greenhouseNow = players.getInGreenhouse(player);
|
||||
if (greenhouseNow != null) {
|
||||
if (greenhouseNow.getOwner().equals(playerUUID)) {
|
||||
player.sendMessage(ChatColor.RED + Locale.errorremoving);
|
||||
plugin.removeGreenhouse(greenhouseNow);
|
||||
return true;
|
||||
}
|
||||
player.sendMessage(ChatColor.RED + Locale.errornotyours);
|
||||
} else {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornotinside);
|
||||
}
|
||||
return true;
|
||||
} else if (split[0].equalsIgnoreCase("make")) {
|
||||
// Sets up a greenhouse
|
||||
final Greenhouse greenhouseN = players.getInGreenhouse(player);
|
||||
if (greenhouseN != null) {
|
||||
// alreadyexists
|
||||
player.sendMessage(ChatColor.RED + Locale.erroralreadyexists);
|
||||
return true;
|
||||
}
|
||||
// Check if they are at their limit
|
||||
if (plugin.players.isAtLimit(player)) {
|
||||
player.sendMessage(ChatColor.translateAlternateColorCodes('&', Locale.infonomore));
|
||||
} else {
|
||||
// Try to make greenhouse
|
||||
Greenhouse g = plugin.tryToMakeGreenhouse(player);
|
||||
if (g == null) {
|
||||
// norecipe
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return true;
|
||||
}
|
||||
// Greenhouse is made
|
||||
}
|
||||
return true;
|
||||
} else if (split[0].equalsIgnoreCase("info")) {
|
||||
// Show some instructions on how to make greenhouses
|
||||
player.sendMessage(ChatColor.GREEN + ChatColor.translateAlternateColorCodes('&', Locale.infotitle));
|
||||
for (String instructions : Locale.infoinstructions) {
|
||||
player.sendMessage(ChatColor.GREEN + ChatColor.translateAlternateColorCodes('&', instructions));
|
||||
}
|
||||
final Greenhouse greenhouseIn = players.getInGreenhouse(player);
|
||||
if (greenhouseIn != null) {
|
||||
player.sendMessage(ChatColor.GOLD + Locale.infoinfo);
|
||||
// general.biome
|
||||
player.sendMessage(ChatColor.GREEN + Locale.generalbiome + ": " + Util.prettifyText(greenhouseIn.getBiome().toString()));
|
||||
if (greenhouseIn.getOwner() != null) {
|
||||
Player owner = plugin.getServer().getPlayer(greenhouseIn.getOwner());
|
||||
if (owner != null) {
|
||||
player.sendMessage(ChatColor.YELLOW + Locale.generalowner + ": " + owner.getDisplayName() + " (" + owner.getName() + ")");
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + Locale.generalowner + ": " + greenhouseIn.getPlayerName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (split[0].equalsIgnoreCase("make")) {
|
||||
// Sets up a greenhouse for a specific biome
|
||||
if (players.getInGreenhouse(player) != null) {
|
||||
// alreadyexists
|
||||
player.sendMessage(ChatColor.RED + Locale.erroralreadyexists);
|
||||
return true;
|
||||
}
|
||||
// Check if they are at their limit
|
||||
if (plugin.players.isAtLimit(player)) {
|
||||
player.sendMessage(ChatColor.translateAlternateColorCodes('&', Locale.infonomore));
|
||||
} else {
|
||||
// Check we are in a greenhouse
|
||||
try {
|
||||
if (NumberUtils.isNumber(split[1])) {
|
||||
int recipeNum = Integer.valueOf(split[1]);
|
||||
List<BiomeRecipe> recipeList = plugin.getBiomeRecipes();
|
||||
if (recipeNum < 1 || recipeNum > recipeList.size()) {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return true;
|
||||
}
|
||||
if (plugin.tryToMakeGreenhouse(player,recipeList.get(recipeNum)) == null) {
|
||||
// Failed for some reason - maybe permissions
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (split[0].equalsIgnoreCase("recipe")) {
|
||||
int recipeNumber = 0;
|
||||
try {
|
||||
recipeNumber = Integer.valueOf(split[1]);
|
||||
} catch (Exception e) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipehint);
|
||||
return true;
|
||||
}
|
||||
List<BiomeRecipe> recipeList = plugin.getBiomeRecipes();
|
||||
if (recipeNumber <1 || recipeNumber > recipeList.size()) {
|
||||
player.sendMessage(ChatColor.RED + Locale.recipewrongnumber.replace("[size]", String.valueOf(recipeList.size())));
|
||||
return true;
|
||||
}
|
||||
BiomeRecipe br = recipeList.get(recipeNumber-1);
|
||||
if (br.getFriendlyName().isEmpty()) {
|
||||
player.sendMessage(ChatColor.GREEN + "[" + Util.prettifyText(br.getBiome().toString()) + " recipe]");
|
||||
} else {
|
||||
player.sendMessage(ChatColor.GREEN + "[" + br.getFriendlyName() + " recipe]");
|
||||
}
|
||||
player.sendMessage(ChatColor.YELLOW + "Biome: " + Util.prettifyText(br.getBiome().toString()));
|
||||
if (br.getWaterCoverage() == 0) {
|
||||
player.sendMessage(Locale.recipenowater);
|
||||
} else if (br.getWaterCoverage() > 0) {
|
||||
player.sendMessage(Locale.recipewatermustbe.replace("[coverage]", String.valueOf(br.getWaterCoverage())));
|
||||
}
|
||||
if (br.getIceCoverage() == 0) {
|
||||
player.sendMessage(Locale.recipenoice);
|
||||
} else if (br.getIceCoverage() > 0) {
|
||||
player.sendMessage(Locale.recipeicemustbe.replace("[coverage]", String.valueOf(br.getIceCoverage())));
|
||||
}
|
||||
if (br.getLavaCoverage() == 0) {
|
||||
player.sendMessage(Locale.recipenolava);
|
||||
} else if (br.getLavaCoverage() > 0) {
|
||||
player.sendMessage(Locale.recipelavamustbe.replace("[coverage]", String.valueOf(br.getLavaCoverage())));
|
||||
}
|
||||
List<String> reqBlocks = br.getRecipeBlocks();
|
||||
if (reqBlocks.size() > 0) {
|
||||
player.sendMessage(ChatColor.YELLOW + Locale.recipeminimumblockstitle);
|
||||
int index = 1;
|
||||
for (String list : reqBlocks) {
|
||||
player.sendMessage(Locale.lineColor + (index++) + ": " + list);
|
||||
}
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + Locale.recipenootherblocks);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -5,14 +5,8 @@ package world.bentobox.greenhouses.ui.user;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
import world.bentobox.greenhouses.util.Util;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -44,6 +38,7 @@ public class ListCommand extends CompositeCommand {
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
/*
|
||||
// List all the biomes that can be made
|
||||
user.sendMessage(ChatColor.GREEN + Locale.listtitle);
|
||||
user.sendMessage(Locale.listinfo);
|
||||
@ -54,7 +49,7 @@ public class ListCommand extends CompositeCommand {
|
||||
} else {
|
||||
user.sendMessage(ChatColor.YELLOW + Integer.toString(index++) + ": " + br.getFriendlyName());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@ -5,14 +5,16 @@ package world.bentobox.greenhouses.ui.user;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GhResult;
|
||||
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -27,7 +29,6 @@ public class MakeCommand extends CompositeCommand {
|
||||
*/
|
||||
public MakeCommand(CompositeCommand parent) {
|
||||
super(parent, "make");
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -44,62 +45,75 @@ public class MakeCommand extends CompositeCommand {
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
// Sets up a greenhouse
|
||||
final Greenhouse greenhouseN = players.getInGreenhouse(player);
|
||||
if (greenhouseN != null) {
|
||||
// alreadyexists
|
||||
player.sendMessage(ChatColor.RED + Locale.erroralreadyexists);
|
||||
return true;
|
||||
}
|
||||
// Check if they are at their limit
|
||||
if (plugin.players.isAtLimit(player)) {
|
||||
player.sendMessage(ChatColor.translateAlternateColorCodes('&', Locale.infonomore));
|
||||
} else {
|
||||
// Try to make greenhouse
|
||||
Greenhouse g = plugin.tryToMakeGreenhouse(player);
|
||||
if (g == null) {
|
||||
// norecipe
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return true;
|
||||
}
|
||||
// Greenhouse is made
|
||||
}
|
||||
return true;
|
||||
|
||||
// Second arg
|
||||
case 2:
|
||||
if (split[0].equalsIgnoreCase("make")) {
|
||||
// Sets up a greenhouse for a specific biome
|
||||
if (players.getInGreenhouse(player) != null) {
|
||||
// alreadyexists
|
||||
player.sendMessage(ChatColor.RED + Locale.erroralreadyexists);
|
||||
// TODO Check permission
|
||||
// Find the physical the greenhouse
|
||||
Location location = user.getLocation().add(new Vector(0,1,0));
|
||||
// Check if there's a gh here already
|
||||
if (((Greenhouses)this.getAddon()).getManager().getMap().getGreenhouse(location).isPresent()) {
|
||||
user.sendRawMessage("You are in a greenhouse already!" );
|
||||
return true;
|
||||
}
|
||||
// Check if they are at their limit
|
||||
if (plugin.players.isAtLimit(player)) {
|
||||
player.sendMessage(ChatColor.translateAlternateColorCodes('&', Locale.infonomore));
|
||||
} else {
|
||||
// Check we are in a greenhouse
|
||||
try {
|
||||
if (NumberUtils.isNumber(split[1])) {
|
||||
int recipeNum = Integer.valueOf(split[1]);
|
||||
List<BiomeRecipe> recipeList = plugin.getBiomeRecipes();
|
||||
if (recipeNum < 1 || recipeNum > recipeList.size()) {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return true;
|
||||
}
|
||||
if (plugin.tryToMakeGreenhouse(player,recipeList.get(recipeNum)) == null) {
|
||||
// Failed for some reason - maybe permissions
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornorecipe);
|
||||
GhResult result = ((Greenhouses)this.getAddon()).getManager().tryToMakeGreenhouse(location, null);
|
||||
|
||||
if (result.getResults().isEmpty()) {
|
||||
// Success
|
||||
user.sendMessage("general.success");
|
||||
user.sendRawMessage(result.getFinder().getGh().getBiomeRecipe().getFriendlyName());
|
||||
return true;
|
||||
}
|
||||
result.getResults().forEach(r -> sendErrorMessage(user, r));
|
||||
if (!result.getFinder().getRedGlass().isEmpty()) {
|
||||
// Show red glass
|
||||
result.getFinder().getRedGlass().forEach(rg -> {
|
||||
user.getPlayer().sendBlockChange(rg, Material.RED_STAINED_GLASS.createBlockData());
|
||||
});
|
||||
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> {
|
||||
result.getFinder().getRedGlass().forEach(rg -> {
|
||||
user.getPlayer().sendBlockChange(rg, rg.getBlock().getBlockData());
|
||||
});
|
||||
}, 120L);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendErrorMessage(User user, GreenhouseResult r) {
|
||||
user.sendRawMessage(r.name());
|
||||
switch (r) {
|
||||
case FAIL_BAD_ROOF_BLOCKS:
|
||||
break;
|
||||
case FAIL_BAD_WALL_BLOCKS:
|
||||
break;
|
||||
case FAIL_BELOW:
|
||||
break;
|
||||
case FAIL_BLOCKS_ABOVE:
|
||||
break;
|
||||
case FAIL_HOLE_IN_ROOF:
|
||||
break;
|
||||
case FAIL_HOLE_IN_WALL:
|
||||
break;
|
||||
case FAIL_NO_ROOF:
|
||||
break;
|
||||
case FAIL_TOO_MANY_DOORS:
|
||||
break;
|
||||
case FAIL_TOO_MANY_HOPPERS:
|
||||
break;
|
||||
case FAIL_UNEVEN_WALLS:
|
||||
break;
|
||||
case FAIL_INSUFFICIENT_ICE:
|
||||
break;
|
||||
case FAIL_INSUFFICIENT_LAVA:
|
||||
break;
|
||||
case FAIL_INSUFFICIENT_WATER:
|
||||
break;
|
||||
case FAIL_NO_ICE:
|
||||
break;
|
||||
case FAIL_NO_LAVA:
|
||||
break;
|
||||
case FAIL_NO_WATER:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,8 @@ package world.bentobox.greenhouses.ui.user;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
import world.bentobox.greenhouses.util.Util;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -43,7 +38,7 @@ public class RecipeCommand extends CompositeCommand {
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
|
||||
/*
|
||||
// Second arg
|
||||
int recipeNumber = 0;
|
||||
try {
|
||||
@ -88,7 +83,7 @@ public class RecipeCommand extends CompositeCommand {
|
||||
}
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + Locale.recipenootherblocks);
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,8 @@ package world.bentobox.greenhouses.ui.user;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -43,6 +38,7 @@ public class RemoveCommand extends CompositeCommand {
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
/*
|
||||
final Greenhouse greenhouseNow = ((Greenhouses)getAddon()).getInGreenhouse(user);
|
||||
if (greenhouseNow != null) {
|
||||
if (greenhouseNow.getOwner().equals(user.getUniqueId())) {
|
||||
@ -53,7 +49,7 @@ public class RemoveCommand extends CompositeCommand {
|
||||
user.sendMessage(ChatColor.RED + Locale.errornotyours);
|
||||
} else {
|
||||
user.sendMessage(ChatColor.RED + Locale.errornotinside);
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@ -5,26 +5,24 @@ package world.bentobox.greenhouses.ui.user;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.greenhouses.greenhouse.Greenhouse;
|
||||
import world.bentobox.greenhouses.ui.Locale;
|
||||
import world.bentobox.greenhouses.Greenhouses;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class GhCommand extends CompositeCommand {
|
||||
public class UserCommand extends CompositeCommand {
|
||||
|
||||
/**
|
||||
* @param gh
|
||||
* @param parent
|
||||
* @param label
|
||||
* @param aliases
|
||||
*/
|
||||
public GhCommand(CompositeCommand parent) {
|
||||
super(parent, "greenhouse", "gh");
|
||||
public UserCommand(Greenhouses gh, CompositeCommand parent) {
|
||||
super(gh, parent, "greenhouse", "gh");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -37,11 +35,11 @@ public class GhCommand extends CompositeCommand {
|
||||
this.setParametersHelp("greenhouses.command.parameters");
|
||||
this.setDescription("greenhouses.command.description");
|
||||
|
||||
new InfoCommand(this);
|
||||
new ListCommand(this);
|
||||
//new InfoCommand(this);
|
||||
//new ListCommand(this);
|
||||
new MakeCommand(this);
|
||||
new RecipeCommand(this);
|
||||
new RemoveCommand(this);
|
||||
//new RecipeCommand(this);
|
||||
//new RemoveCommand(this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -49,14 +47,8 @@ public class GhCommand extends CompositeCommand {
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
final Greenhouse greenhouseInNow = players.getInGreenhouse(player);
|
||||
if (greenhouseInNow==null || greenhouseInNow.getOwner().equals(playerUUID)) {
|
||||
player.openInventory(plugin.getRecipeInv(player));
|
||||
this.showHelp(this, user);
|
||||
return true;
|
||||
} else {
|
||||
player.sendMessage(ChatColor.RED + Locale.errornotowner);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
name: WelcomeWarps
|
||||
main: world.bentobox.warps.Warp
|
||||
name: Greenhouses
|
||||
main: world.bentobox.greenhouses.Greenhouses
|
||||
version: ${version}
|
||||
|
||||
authors: tastybento
|
||||
@ -7,16 +7,6 @@ authors: tastybento
|
||||
softdepend: AcidIsland, BSkyBlock
|
||||
|
||||
permissions:
|
||||
bskyblock.island.warp:
|
||||
description: Player can use warp or warps commands
|
||||
greenhouses.make:
|
||||
description: Player can make a greenhouse
|
||||
default: true
|
||||
bskyblock.island.addwarp:
|
||||
description: Player can create a welcome warp sign
|
||||
default: true
|
||||
acidisland.island.warp:
|
||||
description: Player can use warp or warps commands
|
||||
default: true
|
||||
acidisland.island.addwarp:
|
||||
description: Player can create a welcome warp sign
|
||||
default: true
|
||||
|
||||
|
@ -5,16 +5,16 @@ biomes:
|
||||
# The name of the icon. Can use & for color codes, e.g. &c
|
||||
friendlyname: "Beach"
|
||||
# The biome of the recipe. Allows multiple recipes for the same biome.
|
||||
biome: BEACHES
|
||||
biome: BEACH
|
||||
# The icon is shown in the panel. It must be a Bukkit Material
|
||||
icon: SAND
|
||||
# Priority is used if the greenhouse can be more than one biome. The highest
|
||||
# priority wins
|
||||
priority: 0
|
||||
# Contents - The minimum requirement for this biome.
|
||||
# Format is Material:Type/Durability (optional):Number of blocks
|
||||
# So SAND:1:1 would require 1 block of red sand (durability of 1 = red sand)
|
||||
contents: SAND:1
|
||||
# Format is Material: Number of blocks
|
||||
contents:
|
||||
SAND: 1
|
||||
# The number of blocks in the greenhouse that must be water, ice or lava
|
||||
# Floor area * this % = number of blocks required
|
||||
watercoverage: 50
|
||||
@ -34,7 +34,7 @@ biomes:
|
||||
# Format:
|
||||
# Entity name: % chance:Block on which the mob will spawn
|
||||
mobs:
|
||||
SQUID: 10:STATIONARY_WATER
|
||||
SQUID: 10:WATER
|
||||
# The minimum number of blocks each mob requires.
|
||||
# Mobs will not spawn if there is more than 1 per this number of
|
||||
# blocks in the greenhouse. e.g., in this case only 2 mobs will spawn if the
|
||||
@ -42,45 +42,51 @@ biomes:
|
||||
moblimit: 9
|
||||
Snowy_beach:
|
||||
friendlyname: "Snowy beach"
|
||||
biome: COLD_BEACH
|
||||
biome: SNOWY_BEACH
|
||||
icon: SNOW_BLOCK
|
||||
priority: 21
|
||||
contents: SAND:1
|
||||
contents:
|
||||
SAND: 1
|
||||
watercoverage: 50
|
||||
icecoverage: 10
|
||||
ThreeWolfMoon:
|
||||
friendlyname: "Three Wolf Moon Forest"
|
||||
# Could do with more wolves, but the magic works with 3.
|
||||
# If you are using 1.8 or earlier, this biome should be COLD_TAIGA
|
||||
biome: TAIGA_COLD
|
||||
icon: SAPLING
|
||||
biome: TAIGA
|
||||
icon: SPRUCE_SAPLING
|
||||
priority: 20
|
||||
contents: LOG:3 LEAVES:3 GRASS:3
|
||||
contents:
|
||||
SPRUCE_LOG: 3
|
||||
SPRUCE_LEAVES: 3
|
||||
GRASS: 3
|
||||
icecoverage: 10
|
||||
plants:
|
||||
LONG_GRASS:1: 10:GRASS
|
||||
TALL_GRASS: 10:GRASS
|
||||
mobs:
|
||||
WOLF: 10:SNOW
|
||||
moblimit: 9
|
||||
Cold_Rabbit:
|
||||
friendlyname: "Cold Taiga Forest"
|
||||
# If you are using 1.8 or earlier, this biome should be COLD_TAIGA
|
||||
biome: TAIGA_COLD
|
||||
icon: SAPLING
|
||||
biome: TAIGA_HILLS
|
||||
icon: SPRUCE_SAPLING
|
||||
priority: 20
|
||||
contents: LOG:3 LEAVES:3 GRASS:3
|
||||
contents:
|
||||
SPRUCE_LOG: 3
|
||||
SPRUCE_LEAVES: 3
|
||||
GRASS: 3
|
||||
icecoverage: 10
|
||||
plants:
|
||||
LONG_GRASS:1: 10:GRASS
|
||||
TALL_GRASS: 10:GRASS
|
||||
mobs:
|
||||
RABBIT: 10:SNOW
|
||||
moblimit: 9
|
||||
DESERT:
|
||||
friendlyname: "Desert"
|
||||
biome: "Desert"
|
||||
biome: DESERT
|
||||
icon: DEAD_BUSH
|
||||
priority: 3
|
||||
contents: SAND:1
|
||||
contents:
|
||||
SAND: 1
|
||||
# No water allowed
|
||||
watercoverage: 0
|
||||
# No ice allowed
|
||||
@ -88,27 +94,33 @@ biomes:
|
||||
plants:
|
||||
DEAD_BUSH: 10:SAND
|
||||
CACTUS: 10:SAND
|
||||
# Conversions (see below for another variation)
|
||||
# Conversions
|
||||
# Format is:
|
||||
# Original Block Material:Durability:Chance of change:New Block Material:Durability
|
||||
# So, for below, regular dirt (durability 0) has a 30% chance of changing into regular sand.
|
||||
conversions: DIRT:0:30:SAND:0
|
||||
# Original Block: % chance:New Block:Adjacent Block
|
||||
# So, for below, dirt has a 30% chance of changing into SAND if it is next to SAND!
|
||||
conversions:
|
||||
DIRT: 30:SAND:SAND
|
||||
FOREST:
|
||||
friendlyname: "Flowery forest"
|
||||
biome: FOREST
|
||||
icon: RED_ROSE
|
||||
icon: ROSE_RED
|
||||
priority: 4
|
||||
contents: LOG:3 LEAVES:4 GRASS:4
|
||||
contents:
|
||||
OAK_LOG: 3
|
||||
OAK_LEAVES: 4
|
||||
GRASS: 4
|
||||
plants:
|
||||
RED_ROSE:8: 2:GRASS
|
||||
DOUBLE_PLANT:5: 4:GRASS
|
||||
LONG_GRASS:1: 20:GRASS
|
||||
HELL:
|
||||
PINK_TULIP: 2:GRASS
|
||||
ORANGE_TULIP: 2:GRASS
|
||||
SUNFLOWER: 4:GRASS
|
||||
TALL_GRASS: 20:GRASS
|
||||
NETHER:
|
||||
friendlyname: "&cNether"
|
||||
biome: HELL
|
||||
biome: NETHER
|
||||
icon: LAVA_BUCKET
|
||||
priority: 5
|
||||
contents: NETHERRACK:1
|
||||
contents:
|
||||
NETHERRACK: 1
|
||||
# Lava required, no ice or water allowed
|
||||
lavacoverage: 21
|
||||
icecoverage: 0
|
||||
@ -121,26 +133,30 @@ biomes:
|
||||
biome: JUNGLE
|
||||
icon: VINE
|
||||
priority: 6
|
||||
contents: GRASS:4 LOG:3:3 LEAVES:3:4
|
||||
contents:
|
||||
GRASS: 4
|
||||
JUNGLE_LOG: 3
|
||||
JUNGLE_LEAVES: 4
|
||||
plants:
|
||||
YELLOW_FLOWER: 20:GRASS
|
||||
MELON_BLOCK: 10:GRASS
|
||||
RED_ROSE: 20:GRASS
|
||||
DOUBLE_PLANT:3: 20:GRASS
|
||||
LONG_GRASS:2: 20:GRASS
|
||||
MUSHROOM_ISLAND:
|
||||
friendlyname: "Mushroom Island"
|
||||
biome: MUSHROOM_ISLAND
|
||||
DANDELION: 20:GRASS
|
||||
MELON: 10:GRASS
|
||||
ROSE_BUSH: 20:GRASS
|
||||
FERN: 20:GRASS
|
||||
TALL_GRASS: 20:GRASS
|
||||
MUSHROOM_FIELDS:
|
||||
friendlyname: "Mushroom Fields"
|
||||
biome: MUSHROOM_FIELDS
|
||||
icon: RED_MUSHROOM
|
||||
priority: 11
|
||||
contents: MYCEL:2
|
||||
contents:
|
||||
MYCELIUM: 2
|
||||
# Water required at 30%
|
||||
watercoverage: 30
|
||||
plants:
|
||||
BROWN_MUSHROOM: 10:MYCEL
|
||||
RED_MUSHROOM: 10:MYCEL
|
||||
BROWN_MUSHROOM: 10:MYCELIUM
|
||||
RED_MUSHROOM: 10:MYCELIUM
|
||||
mobs:
|
||||
MUSHROOM_COW: 10:MYCEL
|
||||
MUSHROOM_COW: 10:MYCELIUM
|
||||
moblimit: 9
|
||||
OCEAN:
|
||||
biome: OCEAN
|
||||
@ -149,16 +165,17 @@ biomes:
|
||||
# Lots of water required!
|
||||
watercoverage: 95
|
||||
mobs:
|
||||
SQUID: 10:STATIONARY_WATER
|
||||
SQUID: 10:WATER
|
||||
moblimit: 9
|
||||
PLAINS:
|
||||
friendlyname: "Horse Plains"
|
||||
biome: PLAINS
|
||||
icon: GRASS
|
||||
priority: 1
|
||||
contents: GRASS:3
|
||||
contents:
|
||||
GRASS: 3
|
||||
plants:
|
||||
LONG_GRASS:1: 10:GRASS
|
||||
TALL_GRASS: 10:GRASS
|
||||
mobs:
|
||||
HORSE: 10:GRASS
|
||||
moblimit: 9
|
||||
@ -167,32 +184,41 @@ biomes:
|
||||
biome: RIVER
|
||||
icon: CLAY
|
||||
priority: 10
|
||||
contents: SAND:1
|
||||
contents:
|
||||
SAND: 1
|
||||
# 50% water required
|
||||
watercoverage: 50
|
||||
# Conversions - in this case, an adjacent block is required to convert
|
||||
# Format is:
|
||||
# Original Block:Durability:% chance:New Block:Durability:Adjacent Block:Durability
|
||||
# Original Block: % chance:New Block:Adjacent Block
|
||||
# So, for below, dirt has a 50% chance of changing into clay if it is next to water!
|
||||
conversions: DIRT:0:50:CLAY:0:STATIONARY_WATER:0
|
||||
conversions:
|
||||
DIRT: 50:CLAY:WATER
|
||||
SAVANNA:
|
||||
biome: SAVANNA
|
||||
icon: LEAVES
|
||||
icon: ACACIA_LEAVES
|
||||
priority: 11
|
||||
contents: LOG_2:3 LEAVES_2:4 GRASS:4
|
||||
contents:
|
||||
ACACIA_LOG: 3
|
||||
ACACIA_LEAVES: 4
|
||||
GRASS: 4
|
||||
plants:
|
||||
DOUBLE_PLANT:2: 10:GRASS
|
||||
SWAMPLAND:
|
||||
TALL_GRASS: 10:GRASS
|
||||
SWAMP:
|
||||
friendlyname: "&2Slimy Swamp"
|
||||
icon: WATER_LILY
|
||||
biome: SWAMP
|
||||
icon: LILY_PAD
|
||||
priority: 13
|
||||
contents: GRASS:4 LOG:3 LEAVES:4
|
||||
contents:
|
||||
GRASS: 4
|
||||
OAK_LOG: 3
|
||||
OAK_LEAVES: 4
|
||||
# 50% water coverage required
|
||||
watercoverage: 50
|
||||
plants:
|
||||
RED_MUSHROOM: 20:GRASS
|
||||
BROWN_MUSHROOM: 20:GRASS
|
||||
WATER_LILY: 5:STATIONARY_WATER
|
||||
LILY_PAD: 5:WATER
|
||||
mobs:
|
||||
SLIME: 5:STATIONARY_WATER
|
||||
SLIME: 5:WATER
|
||||
moblimit: 3
|
||||
|
Loading…
Reference in New Issue
Block a user