Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
package com.untamedears.realisticbiomes.growth;

import com.untamedears.realisticbiomes.PlantManager;
import com.untamedears.realisticbiomes.RealisticBiomes;
import com.untamedears.realisticbiomes.model.Plant;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.Sapling;
import java.util.Random;

public class TreeGrower extends AgeableGrower {

private static boolean adjacentSaplingCheck(Material mat, Block northwest) {
for (Block block : new Block[]{northwest, northwest.getRelative(1, 0, 0), northwest.getRelative(0, 0, 1),
northwest.getRelative(1, 0, 1)}) {
if (block == null) {
return false;
}
if (block.getType() != mat) {
return false;
}
}
return true;
}
private final Random random = new Random();

private static boolean canBeBig(Material mat) {
switch (mat) {
Expand All @@ -45,73 +34,40 @@ private static boolean canBeBig(Material mat) {
}

/**
* Checks whether the block is part of a valid 2x2 grid
* checks whether this sapling is the NW sapling of a valid 2x2 sapling setup
*
* @param block Block to check for
* @param mat Sapling material
* @return True if the block is part of a 2x2 sapling grid and could grow large,
* false otherwise
* @param mat the material the saplings must share
* @param northwest the sapling to check for
* @return true iff this is a valid 2x2 setup
*/
private static boolean canGrowBig(Block block, Material mat) {
return adjacentSaplingCheck(mat, block.getRelative(-1, 0, -1))
|| adjacentSaplingCheck(mat, block.getRelative(0, 0, -1))
|| adjacentSaplingCheck(mat, block.getRelative(-1, 0, 0)) || adjacentSaplingCheck(mat, block);
private static boolean adjacentSaplingCheck(Material mat, Block northwest) {
for (int i = 0; i < 4; i++) {
Block block = northwest.getRelative(i % 2, 0, i / 2);
if (block.getType() != mat) {
return false;
}
}

return true;
}

/**
* Checks whether the block is part of a 2x2 grid and returns the north west block
* Checks whether the block is part of a 2x2 grid and returns the north west block.
* The block is tested as the northwest, northeast, southwest, and southeast sapling,
* in that order.
*
* @param block to check for
* @param mat Sapling material
* @return North west block; null if the block is not part of a 2x2 sapling grid
*/
private static Block findNWSapling(Block block, Material mat) {
Block northwest = null;
for (Block nwCandidate : new Block[]{block, block.getRelative(1, 0, 1), block.getRelative(0, 0, 1),
block.getRelative(1, 0, 0)}) {
private static Block find2x2NWSapling(Block block, Material mat) {
for (int i = 0; i < 4; i++) {
Block nwCandidate = block.getRelative(-(i % 2), 0, -(i / 2));
if (adjacentSaplingCheck(mat, nwCandidate)) {
northwest = nwCandidate;
break;
return nwCandidate;
}
}
if (northwest == null) {
return null;
}
return northwest;
}

private static void removeSapling(Block block) {
PlantManager manager = RealisticBiomes.getInstance().getPlantManager();
Plant plant = manager.getPlant(block);
if (plant == null) {
return;
}
manager.deletePlant(plant);
block.setType(Material.AIR);
}

/**
* Remove a 2x2 saplings grid if the block is part of one
*
* @param block to check for
* @param mat Sapling material
*/
private static void clearBigTreeSaplings(Block block, Material mat) {
Block northwest = null;
Block northeast, southwest, southeast;
northwest = findNWSapling(block, mat);
if (northwest == null) {
return;
}

northeast = northwest.getRelative(BlockFace.EAST);
southwest = northwest.getRelative(BlockFace.SOUTH);
southeast = northeast.getRelative(BlockFace.SOUTH);

removeSapling(northwest);
removeSapling(northeast);
removeSapling(southeast);
removeSapling(southwest);
return null;
}

private static TreeType remapSaplingToTree(Material mat, boolean big) {
Expand Down Expand Up @@ -157,6 +113,49 @@ public int getStage(Plant plant) {
return 0;
}

/**
* Set the saplings of the tree to a given material
*
* @param northwest northwestern sapling of the base
* @param isBig whether to set a 2x2 or 1x1 shape
* @param mat the material to change to
*/
public void setSaplings(Block northwest, boolean isBig, Material mat) {
northwest.setType(mat);

if (!isBig) {
return;
}

Block northeast, southwest, southeast;
northeast = northwest.getRelative(BlockFace.EAST);
southwest = northwest.getRelative(BlockFace.SOUTH);
southeast = northeast.getRelative(BlockFace.SOUTH);

northeast.setType(mat);
southwest.setType(mat);
southeast.setType(mat);
}

/**
* Attempts to grow a tree at the provided position.
* It will do 10 grow attempts.
*
* @param location The position to grow the tree at. NW sapling for 2x2 trees.
* @param type The type of tree to grow at the position.
* @return True if the tree grew successfully
*/
public boolean tryGrowTree(Location location, TreeType type) {
World world = location.getWorld();
for (int i = 0; i < 10; i++) {
if (world.generateTree(location, random, type)) {
return true;
}
}

return false;
}

@Override
public boolean setStage(Plant plant, int stage) {
if (stage < 1) {
Expand All @@ -170,20 +169,22 @@ public boolean setStage(Plant plant, int stage) {
Material mat = block.getType();
boolean canBeBig = canBeBig(mat);
if (canBeBig) {
canBeBig = canGrowBig(block, mat);
Block found = find2x2NWSapling(block, mat);
canBeBig = found != null;

if (canBeBig) {
block = found;
}
}

TreeType type = remapSaplingToTree(mat, canBeBig);
if (type == null) {
return true;
}
if (canBeBig) {
clearBigTreeSaplings(block, mat);
} else {
block.setType(Material.AIR);
}
if (!block.getLocation().getWorld().generateTree(block.getLocation(), type)) {
//failed, so restore sapling, TODO restore 2x2
block.setType(mat);

setSaplings(block, canBeBig, Material.AIR);
if (!tryGrowTree(block.getLocation(), type)) {
setSaplings(block, canBeBig, mat);
}
return true;
}
Expand Down