Greenhouses/src/main/java/world/bentobox/greenhouses/managers/GreenhouseManager.java

256 lines
8.1 KiB
Java
Raw Normal View History

2019-01-22 00:44:01 +01:00
package world.bentobox.greenhouses.managers;
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.event.EventHandler;
import org.bukkit.event.Listener;
2019-01-22 00:44:01 +01:00
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
2019-01-22 00:44:01 +01:00
import world.bentobox.bentobox.database.Database;
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;
import world.bentobox.greenhouses.listeners.GreenhouseEvents;
import world.bentobox.greenhouses.listeners.GreenhouseGuard;
import world.bentobox.greenhouses.listeners.IslandChangeEvents;
import world.bentobox.greenhouses.listeners.SnowTracker;
2019-01-22 00:44:01 +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,
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);
}
@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);
ecoMgr.setup();
// Register listeners
addon.registerListener(new SnowTracker(addon));
addon.registerListener(new GreenhouseEvents(addon));
addon.registerListener(new GreenhouseGuard(addon));
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...");
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:
// 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:
activateGreenhouse(g);
2019-01-22 00:44:01 +01:00
break;
default:
break;
}
});
addon.log("Loaded " + map.getSize() + " greenhouses.");
// 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...");
2020-06-11 06:35:38 +02:00
map.getGreenhouses().forEach(handler::saveObjectAsync);
2019-01-22 00:44:01 +01:00
}
/**
* 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());
for (int x = (int)g.getBoundingBox().getMinX(); x<= (int)g.getBoundingBox().getMaxX(); x+=4) {
for (int z = (int)g.getBoundingBox().getMinZ(); z<= (int)g.getBoundingBox().getMaxZ(); z+=4) {
for (int y = (int)g.getBoundingBox().getMinY(); y<= (int)g.getBoundingBox().getMaxY(); y+=4) {
// Set back to the original biome
g.getLocation().getWorld().setBiome(x, y, z, g.getOriginalBiome());
2019-01-22 00:44:01 +01:00
}
}
}
}
/**
* 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);
resultSet.add(map.addGreenhouse(finder.getGh()));
activateGreenhouse(finder.getGh());
2020-06-11 06:35:38 +02:00
handler.saveObjectAsync(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);
activateGreenhouse(finder.getGh());
2020-06-11 06:35:38 +02:00
handler.saveObjectAsync(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);
}
private void activateGreenhouse(Greenhouse gh) {
for (int x = (int)gh.getBoundingBox().getMinX(); x < gh.getBoundingBox().getMaxX(); x+=4) {
for (int z = (int)gh.getBoundingBox().getMinZ(); z < gh.getBoundingBox().getMaxZ(); z+=4) {
for (int y = (int)gh.getBoundingBox().getMinY(); y < gh.getBoundingBox().getMaxY(); y+=4) {
gh.getWorld().setBiome(x, y, 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;
}
/* (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;
}
/**
* 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
}