package Hexel.blocks;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import Hexel.blocks.types.Block;
import Hexel.blocks.types.BlockDebug;
import Hexel.blocks.types.BlockDirt;
import Hexel.blocks.types.BlockEmpty;
import Hexel.blocks.types.BlockGlass;
import Hexel.blocks.types.BlockLeaf;
import Hexel.blocks.types.BlockSeed;
import Hexel.blocks.types.BlockStone;
import Hexel.blocks.types.BlockTransparent;
import Hexel.blocks.types.BlockWater;
import Hexel.blocks.types.BlockWood;
import Hexel.blocks.types.BlockWoodData;
import Hexel.math.HexGeometry;
import Hexel.math.Vector3i;
public class BlockTools {
public static void pointFloodSearch(Vector3i start,
PointFloodSearchMatcher matcher) {
pointFloodSearch(start, false, matcher);
}
public static void pointFloodSearch(Vector3i start, boolean runOnStart, PointFloodSearchMatcher matcher) {
Queue<Vector3i> toMatch = new LinkedList<Vector3i>();
toMatch.add(start);
HashSet<Vector3i> seen = new HashSet<Vector3i>();
if (runOnStart){
if (!matcher.matches(start))
return;
}
while (!toMatch.isEmpty()) {
Vector3i curr = toMatch.poll();
if (!seen.contains(curr)) {
seen.add(curr);
Vector3i[] neighbors = HexGeometry.getAllNeighbors(curr.x);
for (Vector3i n : neighbors) {
Vector3i next = new Vector3i();
next.x = curr.x + n.x;
next.y = curr.y + n.y;
next.z = curr.z + n.z;
if (!seen.contains(next)) {
if (matcher.matches(next)) {
toMatch.add(next);
} else {
seen.add(next);
}
}
}
}
}
}
public interface PointFloodSearchMatcher {
public boolean matches(Vector3i p);
}
public static Block updateHealth(Block b, int newHealth){
if (b instanceof BlockDebug){
return BlockDebug.Make(newHealth);
}
else if (b instanceof BlockDirt){
return BlockDirt.Make(newHealth, ((BlockDirt)b).hasGrass);
}
else if (b instanceof BlockGlass){
return BlockGlass.Make(((BlockGlass)b).naturalLightLevel, newHealth);
}
else if (b instanceof BlockLeaf){
return BlockLeaf.Make(((BlockLeaf)b).naturalLightLevel, newHealth);
}
else if (b instanceof BlockSeed){
return BlockSeed.Make(((BlockSeed)b).maxHeight, newHealth);
}
else if (b instanceof BlockStone){
return BlockStone.Make(newHealth);
}
else if (b instanceof BlockWood){
BlockWood bw = (BlockWood)b;
return BlockWood.Make(new BlockWoodData(newHealth, bw.data.level, bw.data.branchLevel, bw.data.branches, bw.data.alive));
}
else{
try {
throw new Exception("can't update health, unknown block type");
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return null;
}
}
public static BlockTransparent updateLightLevel(BlockTransparent b, int newLightLevel){
if (b instanceof BlockEmpty){
return BlockEmpty.Make(newLightLevel);
}
else if (b instanceof BlockGlass){
return BlockGlass.Make(newLightLevel, b.getHealth());
}
else if (b instanceof BlockLeaf){
return BlockLeaf.Make(newLightLevel, b.getHealth());
}
else if (b instanceof BlockWater){
return BlockWater.Make(newLightLevel, ((BlockWater)b).getBottom(), ((BlockWater)b).getTop());
}
else{
try {
throw new Exception("can't update light level, unknown block type");
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return null;
}
}
}