2019-01-22 00:44:01 +01:00
|
|
|
package world.bentobox.greenhouses.managers;
|
|
|
|
|
2019-08-01 22:29:25 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
2019-01-22 00:44:01 +01:00
|
|
|
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;
|
2019-01-23 05:54:43 +01:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.Listener;
|
2019-01-22 00:44:01 +01:00
|
|
|
|
2019-01-23 05:54:43 +01:00
|
|
|
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
|
2019-01-22 00:44:01 +01:00
|
|
|
import world.bentobox.bentobox.database.Database;
|
2019-07-08 16:53:03 +02:00
|
|
|
import world.bentobox.bentobox.database.objects.Island;
|
2019-01-22 00:44:01 +01:00
|
|
|
import world.bentobox.greenhouses.Greenhouses;
|
|
|
|
import world.bentobox.greenhouses.data.Greenhouse;
|
|
|
|
import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
|
2019-01-23 05:54:43 +01:00
|
|
|
import world.bentobox.greenhouses.listeners.GreenhouseEvents;
|
|
|
|
import world.bentobox.greenhouses.listeners.GreenhouseGuard;
|
2019-07-08 16:53:03 +02:00
|
|
|
import world.bentobox.greenhouses.listeners.IslandChangeEvents;
|
2019-01-23 05:54:43 +01:00
|
|
|
import world.bentobox.greenhouses.listeners.SnowTracker;
|
2019-01-22 00:44:01 +01:00
|
|
|
|
2019-01-23 05:54:43 +01:00
|
|
|
public class GreenhouseManager implements Listener {
|
2019-01-22 00:44:01 +01:00
|
|
|
|
2019-01-22 02:53:34 +01:00
|
|
|
/**
|
|
|
|
* Result of greenhouse making
|
|
|
|
*
|
|
|
|
*/
|
2019-01-22 00:44:01 +01:00
|
|
|
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,
|
2019-01-22 02:53:34 +01:00
|
|
|
FAIL_INSUFFICIENT_ICE,
|
|
|
|
FAIL_NO_ISLAND,
|
|
|
|
FAIL_OVERLAPPING,
|
|
|
|
NULL,
|
|
|
|
SUCCESS,
|
2019-10-12 03:52:32 +02:00
|
|
|
FAIL_NO_RECIPE_FOUND,
|
|
|
|
FAIL_INSUFFICIENT_BLOCKS
|
2019-01-22 00:44:01 +01:00
|
|
|
}
|
|
|
|
|
2019-01-26 17:38:13 +01:00
|
|
|
private final Greenhouses addon;
|
2019-01-22 00:44:01 +01:00
|
|
|
// Greenhouses
|
2019-01-26 17:38:13 +01:00
|
|
|
private final GreenhouseMap map;
|
|
|
|
private final Database<Greenhouse> handler;
|
2019-07-08 00:45:47 +02:00
|
|
|
private EcoSystemManager ecoMgr;
|
2019-01-22 00:44:01 +01:00
|
|
|
|
|
|
|
public GreenhouseManager(Greenhouses addon) {
|
|
|
|
this.addon = addon;
|
|
|
|
handler = new Database<>(addon, Greenhouse.class);
|
|
|
|
map = new GreenhouseMap(addon);
|
2019-01-23 05:54:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler
|
|
|
|
public void startManager(BentoBoxReadyEvent e) {
|
2019-01-22 00:44:01 +01:00
|
|
|
loadGreenhouses();
|
|
|
|
// Start ecosystems
|
2019-07-08 00:45:47 +02:00
|
|
|
ecoMgr = new EcoSystemManager(addon, this);
|
2019-01-23 05:54:43 +01:00
|
|
|
// Register listeners
|
|
|
|
addon.registerListener(new SnowTracker(addon));
|
|
|
|
addon.registerListener(new GreenhouseEvents(addon));
|
|
|
|
addon.registerListener(new GreenhouseGuard(addon));
|
2019-07-08 16:53:03 +02:00
|
|
|
addon.registerListener(new IslandChangeEvents(addon));
|
2019-01-22 00:44:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public GreenhouseMap getMap() {
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load all known greenhouses
|
|
|
|
*/
|
2019-01-26 17:38:13 +01:00
|
|
|
private void loadGreenhouses() {
|
2019-07-08 00:45:47 +02:00
|
|
|
map.clear();
|
2019-01-22 00:44:01 +01:00
|
|
|
addon.log("Loading greenhouses...");
|
2019-08-01 22:29:25 +02:00
|
|
|
List<Greenhouse> toBeRemoved = new ArrayList<>();
|
2019-01-22 00:44:01 +01:00
|
|
|
handler.loadObjects().forEach(g -> {
|
2019-01-22 02:53:34 +01:00
|
|
|
GreenhouseResult result = map.addGreenhouse(g);
|
2019-01-22 00:44:01 +01:00
|
|
|
switch (result) {
|
|
|
|
case FAIL_NO_ISLAND:
|
2019-08-01 22:29:25 +02:00
|
|
|
// Delete the failed greenhouse
|
|
|
|
toBeRemoved.add(g);
|
2019-11-01 05:36:05 +01:00
|
|
|
break;
|
2019-01-22 00:44:01 +01:00
|
|
|
case FAIL_OVERLAPPING:
|
|
|
|
case NULL:
|
|
|
|
addon.logError(result.name());
|
|
|
|
break;
|
|
|
|
case SUCCESS:
|
2019-01-23 05:54:43 +01:00
|
|
|
activateGreenhouse(g);
|
2019-01-22 00:44:01 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
2019-01-23 05:54:43 +01:00
|
|
|
addon.log("Loaded " + map.getSize() + " greenhouses.");
|
2019-08-01 22:29:25 +02:00
|
|
|
// Remove the old or outdated greenhouses
|
|
|
|
toBeRemoved.forEach(handler::deleteObject);
|
2019-01-22 00:44:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
2019-01-26 17:38:13 +01:00
|
|
|
* @param g - greenhouse
|
2019-01-22 00:44:01 +01:00
|
|
|
*/
|
|
|
|
public void removeGreenhouse(Greenhouse g) {
|
2019-07-08 00:45:47 +02:00
|
|
|
handler.deleteObject(g);
|
2019-01-22 00:44:01 +01:00
|
|
|
map.removeGreenhouse(g);
|
|
|
|
addon.log("Returning biome to original state: " + g.getOriginalBiome().toString());
|
2019-08-01 22:29:25 +02:00
|
|
|
for (int x = (int)g.getBoundingBox().getMinX(); x<= (int)g.getBoundingBox().getMaxX(); x++) {
|
|
|
|
for (int z = (int)g.getBoundingBox().getMinZ(); z<= (int)g.getBoundingBox().getMaxZ(); z++) {
|
|
|
|
// Set back to the original biome
|
|
|
|
g.getLocation().getWorld().setBiome(x, z, g.getOriginalBiome());
|
|
|
|
if (g.getOriginalBiome().equals(Biome.NETHER) || g.getOriginalBiome().equals(Biome.DESERT)
|
|
|
|
|| g.getOriginalBiome().equals(Biome.DESERT_HILLS)) {
|
2019-01-22 00:44:01 +01:00
|
|
|
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
|
2019-01-26 17:38:13 +01:00
|
|
|
* @param location - location to start search from
|
|
|
|
* @param greenhouseRecipe - recipe requested, or null for a best-effort search
|
|
|
|
* @return - greenhouse result {@link GhResult}
|
2019-01-22 00:44:01 +01:00
|
|
|
*/
|
|
|
|
public GhResult tryToMakeGreenhouse(Location location, BiomeRecipe greenhouseRecipe) {
|
|
|
|
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);
|
2019-05-09 00:21:11 +02:00
|
|
|
resultSet.add(map.addGreenhouse(finder.getGh()));
|
2019-01-23 05:54:43 +01:00
|
|
|
activateGreenhouse(finder.getGh());
|
2019-07-08 00:45:47 +02:00
|
|
|
handler.saveObject(finder.getGh());
|
2019-01-22 00:44:01 +01:00
|
|
|
}
|
|
|
|
return new GhResult().setFinder(finder).setResults(resultSet);
|
|
|
|
}
|
2019-01-22 02:53:34 +01:00
|
|
|
|
2019-01-22 00:44:01 +01:00
|
|
|
// Try ordered recipes
|
2019-01-22 02:53:34 +01:00
|
|
|
resultSet.add(addon.getRecipes().getBiomeRecipes().stream().sorted()
|
|
|
|
.filter(r -> r.checkRecipe(finder.getGh()).isEmpty()).findFirst()
|
|
|
|
.map(r -> {
|
|
|
|
// Success - set recipe and add to map
|
|
|
|
finder.getGh().setBiomeRecipe(r);
|
2019-01-23 05:54:43 +01:00
|
|
|
activateGreenhouse(finder.getGh());
|
2019-07-08 00:45:47 +02:00
|
|
|
handler.saveObject(finder.getGh());
|
2019-01-22 02:53:34 +01:00
|
|
|
return map.addGreenhouse(finder.getGh());
|
|
|
|
}).orElse(GreenhouseResult.FAIL_NO_RECIPE_FOUND));
|
2019-01-22 00:44:01 +01:00
|
|
|
return new GhResult().setFinder(finder).setResults(resultSet);
|
|
|
|
}
|
|
|
|
|
2019-01-23 05:54:43 +01:00
|
|
|
private void activateGreenhouse(Greenhouse gh) {
|
2019-05-09 00:21:11 +02:00
|
|
|
for (int x = (int)gh.getBoundingBox().getMinX(); x < gh.getBoundingBox().getMaxX(); x++) {
|
|
|
|
for (int z = (int)gh.getBoundingBox().getMinZ(); z < gh.getBoundingBox().getMaxZ(); z++) {
|
2019-01-23 05:54:43 +01:00
|
|
|
gh.getWorld().setBiome(x, z, gh.getBiomeRecipe().getBiome());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-01-22 00:44:01 +01:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2019-01-26 17:38:13 +01:00
|
|
|
GhResult setResults(Set<GreenhouseResult> results) {
|
2019-01-22 00:44:01 +01:00
|
|
|
this.results = results;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param finder the finder to set
|
|
|
|
*/
|
2019-01-26 17:38:13 +01:00
|
|
|
GhResult setFinder(GreenhouseFinder finder) {
|
2019-01-22 00:44:01 +01:00
|
|
|
this.finder = finder;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2019-05-09 00:21:11 +02:00
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see java.lang.Object#toString()
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "GhResult [results=" + results + ", finder=" + finder + "]";
|
|
|
|
}
|
|
|
|
|
2019-01-22 00:44:01 +01:00
|
|
|
|
|
|
|
}
|
2019-07-08 00:45:47 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the ecoMgr
|
|
|
|
*/
|
|
|
|
public EcoSystemManager getEcoMgr() {
|
|
|
|
return ecoMgr;
|
|
|
|
}
|
2019-07-08 16:53:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes all greenhouses on island
|
|
|
|
* @param island - island
|
|
|
|
*/
|
|
|
|
public void removeGreenhouses(Island island) {
|
|
|
|
map.getGreenhouses(island).forEach(handler::deleteObject);
|
|
|
|
map.removeGreenhouses(island);
|
|
|
|
|
|
|
|
}
|
2019-01-22 00:44:01 +01:00
|
|
|
}
|