mirror of
https://github.com/BentoBoxWorld/Greenhouses.git
synced 2024-11-25 20:16:22 +01:00
Perform block conversions in 3D.
Fixes https://github.com/BentoBoxWorld/Greenhouses/issues/59
This commit is contained in:
parent
ad82941452
commit
9d85e37e1b
@ -223,5 +223,4 @@ public class Greenhouse implements DataObject {
|
||||
public Map<Material, Integer> getMissingBlocks() {
|
||||
return missingBlocks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
||||
private String name;
|
||||
private String friendlyName;
|
||||
|
||||
private final List<BlockFace> adjBlocks = Arrays.asList( BlockFace.DOWN, BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.UP, BlockFace.WEST);
|
||||
private static final List<BlockFace> ADJ_BLOCKS = Arrays.asList( BlockFace.DOWN, BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.UP, BlockFace.WEST);
|
||||
|
||||
// Content requirements
|
||||
// Material, Type, Qty. There can be more than one type of material required
|
||||
@ -221,7 +221,7 @@ public class BiomeRecipe implements Comparable<BiomeRecipe> {
|
||||
.filter(bc -> random.nextDouble() < bc.getProbability())
|
||||
.forEach(bc -> {
|
||||
// Check if the block is in the right area, up, down, n,s,e,w
|
||||
if (adjBlocks.stream().map(b::getRelative).map(Block::getType).anyMatch(m -> bc.getLocalMaterial() == null || m == bc.getLocalMaterial())) {
|
||||
if (ADJ_BLOCKS.stream().map(b::getRelative).map(Block::getType).anyMatch(m -> bc.getLocalMaterial() == null || m == bc.getLocalMaterial())) {
|
||||
// Convert!
|
||||
b.setType(bc.getNewMaterial());
|
||||
}
|
||||
|
@ -37,10 +37,12 @@ public class EcoSystemManager {
|
||||
public EcoSystemManager(Greenhouses addon, GreenhouseManager greenhouseManager) {
|
||||
this.addon = addon;
|
||||
this.g = greenhouseManager;
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
/**
|
||||
* Kick off schedulers
|
||||
*/
|
||||
void setup() {
|
||||
// Kick off flower growing
|
||||
long plantTick = addon.getSettings().getPlantTick() * 60 * 20L; // In minutes
|
||||
if (plantTick > 0) {
|
||||
@ -81,10 +83,16 @@ public class EcoSystemManager {
|
||||
|
||||
private void convertBlocks(Greenhouse gh) {
|
||||
if(!gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMaxX()) >> 4, ((int) gh.getBoundingBox().getMaxZ()) >> 4) || !gh.getLocation().getWorld().isChunkLoaded(((int) gh.getBoundingBox().getMinX()) >> 4, ((int) gh.getBoundingBox().getMinZ()) >> 4)){
|
||||
//addon.log("Skipping convertblock for unloaded greenhouse at " + gh.getLocation());
|
||||
return;
|
||||
}
|
||||
getAvailableBlocks(gh).stream().map(b -> b.getRelative(BlockFace.DOWN)).forEach(gh.getBiomeRecipe()::convertBlock);
|
||||
for (int x = (int)gh.getBoundingBox().getMinX() + 1; x < (int)gh.getBoundingBox().getMaxX(); x++) {
|
||||
for (int z = (int)gh.getBoundingBox().getMinZ() + 1; z < (int)gh.getBoundingBox().getMaxZ(); z++) {
|
||||
for (int y = (int)gh.getBoundingBox().getMaxY() - 2; y >= (int)gh.getBoundingBox().getMinY() && y > 0; y--) {
|
||||
Block b = gh.getWorld().getBlockAt(x, y, z).getRelative(BlockFace.DOWN);
|
||||
if (!b.isEmpty()) gh.getBiomeRecipe().convertBlock(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verify(Greenhouse gh) {
|
||||
@ -121,7 +129,7 @@ public class EcoSystemManager {
|
||||
.filter(e -> gh.getBiomeRecipe().getMobTypes().contains(e.getType()))
|
||||
.filter(e -> gh.contains(e.getLocation())).count();
|
||||
// Get the blocks in the greenhouse where spawning could occur
|
||||
List<Block> list = new ArrayList<>(getAvailableBlocks(gh));
|
||||
List<Block> list = new ArrayList<>(getAvailableBlocks(gh, false));
|
||||
Collections.shuffle(list, new Random(System.currentTimeMillis()));
|
||||
Iterator<Block> it = list.iterator();
|
||||
// Check if the greenhouse is full
|
||||
@ -146,7 +154,7 @@ public class EcoSystemManager {
|
||||
int bonemeal = getBoneMeal(gh);
|
||||
if (bonemeal > 0) {
|
||||
// Get a list of all available blocks
|
||||
int plantsGrown = getAvailableBlocks(gh).stream().limit(bonemeal).mapToInt(bl -> gh.getBiomeRecipe().growPlant(bl) ? 1 : 0).sum();
|
||||
int plantsGrown = getAvailableBlocks(gh, false).stream().limit(bonemeal).mapToInt(bl -> gh.getBiomeRecipe().growPlant(bl) ? 1 : 0).sum();
|
||||
if (plantsGrown > 0) {
|
||||
setBoneMeal(gh, bonemeal - (int)Math.ceil((double)plantsGrown / PLANTS_PER_BONEMEAL ));
|
||||
}
|
||||
@ -170,17 +178,21 @@ public class EcoSystemManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the lowest level air blocks inside the greenhouse
|
||||
* Get a list of the lowest level blocks inside the greenhouse. May be air, liquid or plants.
|
||||
* These blocks sit just above solid blocks
|
||||
* @param gh - greenhouse
|
||||
* @param ignoreliquid - true if liquid blocks should be treated like air blocks
|
||||
* @return List of blocks
|
||||
*/
|
||||
private List<Block> getAvailableBlocks(Greenhouse gh) {
|
||||
List<Block> getAvailableBlocks(Greenhouse gh, boolean ignoreLiquid) {
|
||||
List<Block> result = new ArrayList<>();
|
||||
for (int x = (int)gh.getBoundingBox().getMinX() + 1; x < (int)gh.getBoundingBox().getMaxX(); x++) {
|
||||
for (int z = (int)gh.getBoundingBox().getMinZ() + 1; z < (int)gh.getBoundingBox().getMaxZ(); z++) {
|
||||
for (int y = (int)gh.getBoundingBox().getMaxY() - 2; y >= (int)gh.getBoundingBox().getMinY(); y--) {
|
||||
Block b = gh.getLocation().getWorld().getBlockAt(x, y, z);
|
||||
if ((!b.isEmpty() && !b.isPassable()) && (b.getRelative(BlockFace.UP).isEmpty() || b.getRelative(BlockFace.UP).isPassable())) {
|
||||
Block b = gh.getWorld().getBlockAt(x, y, z);
|
||||
if ((!b.isEmpty() && !b.isPassable())
|
||||
&& (b.getRelative(BlockFace.UP).isEmpty() || b.getRelative(BlockFace.UP).isPassable()
|
||||
|| (ignoreLiquid && b.getRelative(BlockFace.UP).isLiquid()))) {
|
||||
result.add(b.getRelative(BlockFace.UP));
|
||||
break;
|
||||
}
|
||||
@ -212,6 +224,9 @@ public class EcoSystemManager {
|
||||
return (Hopper)gh.getRoofHopperLocation().getBlock().getState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel all the scheduled tasks
|
||||
*/
|
||||
public void cancel() {
|
||||
plantTask.cancel();
|
||||
mobTask.cancel();
|
||||
|
@ -67,6 +67,7 @@ public class GreenhouseManager implements Listener {
|
||||
loadGreenhouses();
|
||||
// Start ecosystems
|
||||
ecoMgr = new EcoSystemManager(addon, this);
|
||||
ecoMgr.setup();
|
||||
// Register listeners
|
||||
addon.registerListener(new SnowTracker(addon));
|
||||
addon.registerListener(new GreenhouseEvents(addon));
|
||||
|
@ -0,0 +1,169 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package world.bentobox.greenhouses.managers;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyDouble;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.greenhouses.data.Greenhouse;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Bukkit.class, BentoBox.class})
|
||||
public class EcoSystemManagerTest {
|
||||
|
||||
@Mock
|
||||
private Greenhouse gh;
|
||||
@Mock
|
||||
private World world;
|
||||
@Mock
|
||||
private Block block;
|
||||
@Mock
|
||||
private Block air;
|
||||
@Mock
|
||||
private Block liquid;
|
||||
@Mock
|
||||
private Block plant;
|
||||
|
||||
// CUT
|
||||
private EcoSystemManager eco;
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// 4x4x4 greenhouse
|
||||
BoundingBox bb = BoundingBox.of(new Vector(0,0,0), new Vector(5,5,5));
|
||||
when(gh.getBoundingBox()).thenReturn(bb);
|
||||
// World
|
||||
when(gh.getWorld()).thenReturn(world);
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
|
||||
// Block
|
||||
// Air
|
||||
when(air.isEmpty()).thenReturn(true);
|
||||
when(air.isPassable()).thenReturn(true);
|
||||
when(air.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
||||
// Plant
|
||||
when(plant.isPassable()).thenReturn(true);
|
||||
when(plant.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
||||
// Liquid
|
||||
when(liquid.isLiquid()).thenReturn(true);
|
||||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
||||
// Default for block
|
||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(air);
|
||||
|
||||
eco = new EcoSystemManager(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksAirAboveBlock() {
|
||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
||||
assertEquals(16, result.size());
|
||||
assertEquals(air, result.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksPlantAboveBlock() {
|
||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(plant);
|
||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
||||
assertEquals(16, result.size());
|
||||
assertEquals(plant, result.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksAllAir() {
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(air);
|
||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksAllLiquid() {
|
||||
when(liquid.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(liquid);
|
||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksAllPlant() {
|
||||
when(plant.getRelative(eq(BlockFace.UP))).thenReturn(plant);
|
||||
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(plant);
|
||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksLiquidAboveBlockIgnoreLiquids() {
|
||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||
List<Block> result = eco.getAvailableBlocks(gh, true);
|
||||
assertEquals(16, result.size());
|
||||
assertEquals(liquid, result.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.greenhouses.managers.EcoSystemManager#getAvailableBlocks(world.bentobox.greenhouses.data.Greenhouse)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAvailableBlocksLiquidAboveBlock() {
|
||||
when(block.getRelative(eq(BlockFace.UP))).thenReturn(liquid);
|
||||
List<Block> result = eco.getAvailableBlocks(gh, false);
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user