package com.austinv11.collectiveframework.minecraft.utils; import net.minecraft.block.Block; import java.util.HashMap; /** * A utility to aid in creating world gen structures */ public class StructureCreator { private HashMap<Location, Block> blocks = new HashMap<Location,Block>(); private HashMap<Block, Integer> metas = new HashMap<Block,Integer>(); private HashMap<Location, ICheckBlockValidity> errorCheckers = new HashMap<Location,ICheckBlockValidity>(); /** * Adds a block to the structure with the default implementation of {@link com.austinv11.collectiveframework.minecraft.utils.StructureCreator.ICheckBlockValidity} * @param location The location of the block * @param block The block */ public void addBlock(Location location, Block block) { addBlock(location, block, 0); } /** * Adds a block to the structure with the default implementation of {@link com.austinv11.collectiveframework.minecraft.utils.StructureCreator.ICheckBlockValidity} * @param location The location of the block * @param block The block * @param meta The meta for the block */ public void addBlock(Location location, Block block, int meta) { addBlock(location, block, meta, new DefaultValidityChecker()); } /** * Adds a block to the structure with a custom implementation of {@link com.austinv11.collectiveframework.minecraft.utils.StructureCreator.ICheckBlockValidity} * @param location The location of the block * @param block The block * @param meta The meta for the block * @param validityChecker The {@link com.austinv11.collectiveframework.minecraft.utils.StructureCreator.ICheckBlockValidity} to use */ public void addBlock(Location location, Block block, int meta, ICheckBlockValidity validityChecker) { if (!blocks.containsKey(location)) { blocks.put(location, block); errorCheckers.put(location, validityChecker); metas.put(block, meta); } } /** * Checks if the structure is valid for spawning * @return True if the structure can be generated, false if otherwise */ public boolean isStructureValid() { for (Location l : blocks.keySet()) { if (!errorCheckers.get(l).canStructureGenerate(blocks.get(l), metas.get(blocks.get(l)), l)) return false; } return true; } /** * Generates the structure, it won't generate if {@link #isStructureValid()} is false */ public void generateStructure() { generateStructure(false); } /** * Generates the structure with the set flags, it won't generate if {@link #isStructureValid()} is false * @param forceOptionalBlocks If true, blocks which don't need to be generated for the structure to spawn will spawn */ public void generateStructure(boolean forceOptionalBlocks) { generateStructure(forceOptionalBlocks, false); } /** * Generates the structure with the set flags * @param forceOptionalBlocks If true, blocks which don't need to be generated for the structure to spawn will spawn * @param forceNonOptionalBlocks If true, the structure will generate regardless of the results of {@link #isStructureValid()} */ public void generateStructure(boolean forceOptionalBlocks, boolean forceNonOptionalBlocks) { if (!forceNonOptionalBlocks && !isStructureValid()) return; for (Location l : blocks.keySet()) { if (errorCheckers.get(l).isBlockValid(blocks.get(l), metas.get(blocks.get(l)), l) || forceOptionalBlocks) l.getWorld().setBlock(l.getRoundedX(), l.getRoundedY(), l.getRoundedZ(), blocks.get(l), metas.get(blocks.get(l)), 2); } } public static class DefaultValidityChecker implements ICheckBlockValidity { @Override public boolean isBlockValid(Block block, int meta, Location location) { return location.getWorld().isAirBlock(location.getRoundedX(), location.getRoundedY(), location.getRoundedZ()) || location.getWorld().getBlock(location.getRoundedX(), location.getRoundedY(), location.getRoundedZ()).getMaterial().isReplaceable(); } @Override public boolean canStructureGenerate(Block block, int meta, Location location) { return isBlockValid(block, meta, location); } } /** * Implement this if you want to check for custom conditions */ public static interface ICheckBlockValidity { /** * Checks if the block can be generated in the desired location * @param block The block * @param meta The metadata for the block * @param location The location * @return True if valid */ public boolean isBlockValid(Block block, int meta, Location location); /** * Same as {@link #isBlockValid(Block, int, Location)} except if false, the whole structure is prevented from generating. * Most times you just want this method to consist of: * {@code return this.isBlockValid(block, location);} */ public boolean canStructureGenerate(Block block, int meta, Location location); } }