package net.glowstone.generator.decorators.overworld;
import net.glowstone.generator.decorators.BlockDecorator;
import net.glowstone.generator.objects.trees.GenericTree;
import net.glowstone.util.BlockStateDelegate;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class TreeDecorator extends BlockDecorator {
private List<TreeDecoration> trees;
public final void setTrees(TreeDecoration... trees) {
this.trees = Arrays.asList(trees);
}
@Override
public void populate(World world, Random random, Chunk chunk) {
int treeAmount = amount;
if (random.nextInt(10) == 0) {
treeAmount++;
}
for (int i = 0; i < treeAmount; i++) {
decorate(world, random, chunk);
}
}
@Override
public void decorate(World world, Random random, Chunk source) {
int sourceX = (source.getX() << 4) + random.nextInt(16);
int sourceZ = (source.getZ() << 4) + random.nextInt(16);
final Block sourceBlock = world.getBlockAt(sourceX, world.getHighestBlockYAt(sourceX, sourceZ), sourceZ);
final Class<? extends GenericTree> clazz = getRandomTree(random, trees);
if (clazz != null) {
final BlockStateDelegate delegate = new BlockStateDelegate();
GenericTree tree;
try {
final Constructor<? extends GenericTree> c = clazz.getConstructor(Random.class, Location.class, BlockStateDelegate.class);
tree = c.newInstance(random, sourceBlock.getLocation(), delegate);
} catch (Exception ex) {
tree = new GenericTree(random, sourceBlock.getLocation(), delegate);
}
if (tree.generate()) {
delegate.updateBlockStates();
}
}
}
private Class<? extends GenericTree> getRandomTree(Random random, List<TreeDecoration> decorations) {
int totalWeight = 0;
for (TreeDecoration decoration : decorations) {
totalWeight += decoration.getWeigth();
}
int weight = random.nextInt(totalWeight);
for (TreeDecoration decoration : decorations) {
weight -= decoration.getWeigth();
if (weight < 0) {
return decoration.getTree();
}
}
return null;
}
public static class TreeDecoration {
private final Class<? extends GenericTree> tree;
private final int weight;
public TreeDecoration(Class<? extends GenericTree> tree, int weight) {
this.tree = tree;
this.weight = weight;
}
public Class<? extends GenericTree> getTree() {
return tree;
}
public int getWeigth() {
return weight;
}
}
}