/*
* Copyright (c) CovertJaguar, 2014 http://railcraft.info
*
* This code is the property of CovertJaguar
* and may only be used with explicit written
* permission unless otherwise specified on the
* license page at http://railcraft.info/wiki/info:license.
*/
package mods.railcraft.common.items.firestone;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import mods.railcraft.api.core.WorldCoordinate;
import mods.railcraft.common.blocks.RailcraftTileEntity;
import mods.railcraft.common.fluids.FluidHelper;
import mods.railcraft.common.fluids.Fluids;
import mods.railcraft.common.plugins.forge.WorldPlugin;
import mods.railcraft.common.util.effects.EffectManager;
import mods.railcraft.common.util.misc.Game;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
/**
*
* @author CovertJaguar <http://www.railcraft.info/>
*/
public class TileFirestoneRecharge extends RailcraftTileEntity {
public static final int[] REBUILD_DELAY = new int[8];
public int charge = 0;
public long rotationYaw, preRotationYaw;
public float yOffset = -2, preYOffset = -2;
private final Deque<WorldCoordinate> queue = new LinkedList<WorldCoordinate>();
private final Set<WorldCoordinate> visitedBlocks = new HashSet<WorldCoordinate>();
private Deque<WorldCoordinate> lavaFound = new LinkedList<WorldCoordinate>();
private int rebuildDelay;
private String itemName;
static {
REBUILD_DELAY[0] = 128;
REBUILD_DELAY[1] = 256;
REBUILD_DELAY[2] = 512;
REBUILD_DELAY[3] = 1024;
REBUILD_DELAY[4] = 2048;
REBUILD_DELAY[5] = 4096;
REBUILD_DELAY[6] = 8192;
REBUILD_DELAY[7] = 16384;
}
@Override
public void updateEntity() {
super.updateEntity();
if (Game.isNotHost(worldObj)) {
preRotationYaw = rotationYaw;
rotationYaw += 5;
if (rotationYaw >= 360) {
rotationYaw = 0;
preRotationYaw = rotationYaw;
}
preYOffset = yOffset;
if (yOffset < 0)
yOffset += 0.0625F;
return;
}
if (charge >= ItemFirestoneRefined.item.getMaxDamage())
return;
// if (clock % 4 == 0) {
if (clock % REBUILD_DELAY[rebuildDelay] == 0) {
rebuildDelay++;
if (rebuildDelay >= REBUILD_DELAY.length)
rebuildDelay = REBUILD_DELAY.length - 1;
rebuildQueue();
}
WorldCoordinate index = getNextLavaBlock(true);
if (index != null && coolLava(index.x, index.y, index.z)) {
charge++;
rebuildDelay = 0;
}
// }
}
private boolean coolLava(int x, int y, int z) {
Block block = WorldPlugin.getBlock(worldObj, x, y, z);
if (Fluids.LAVA.is(FluidHelper.getFluid(block))) {
boolean placed = WorldPlugin.setBlock(worldObj, x, y, z, Blocks.obsidian);
if (placed) {
EffectManager.instance.fireSparkEffect(worldObj, x + 0.5, y + 0.5, z + 0.5, xCoord + 0.5, yCoord + 0.8, zCoord + 0.5);
queueAdjacent(x, y, z);
expandQueue();
return true;
}
}
return false;
}
private WorldCoordinate getNextLavaBlock(boolean remove) {
if (queue.isEmpty())
return null;
if (remove) {
WorldCoordinate index = queue.pollFirst();
return index;
}
return queue.peekFirst();
}
/**
* Nasty expensive function, don't call if you don't have to.
*/
void rebuildQueue() {
queue.clear();
visitedBlocks.clear();
lavaFound.clear();
queueAdjacent(xCoord, yCoord, zCoord);
expandQueue();
}
private void expandQueue() {
while (!lavaFound.isEmpty()) {
Deque<WorldCoordinate> blocksToExpand = lavaFound;
lavaFound = new LinkedList<WorldCoordinate>();
for (WorldCoordinate index : blocksToExpand) {
queueAdjacent(index.x, index.y, index.z);
}
}
}
public void queueAdjacent(int x, int y, int z) {
queueForFilling(x + 1, y, z);
queueForFilling(x - 1, y, z);
queueForFilling(x, y, z + 1);
queueForFilling(x, y, z - 1);
queueForFilling(x, y + 1, z);
queueForFilling(x, y - 1, z);
}
public void queueForFilling(int x, int y, int z) {
WorldCoordinate index = new WorldCoordinate(0, x, y, z);
if (visitedBlocks.add(index)) {
if ((x - xCoord) * (x - xCoord) + (z - zCoord) * (z - zCoord) > 64 * 64)
return;
Block block = WorldPlugin.getBlock(worldObj, x, y, z);
if (block == Blocks.obsidian || Fluids.LAVA.is(FluidHelper.getFluid(block))) {
lavaFound.add(index);
if (FluidHelper.isFullFluidBlock(block, worldObj, x, y, z))
queue.addLast(index);
}
}
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemName() {
return itemName;
}
@Override
public void writeToNBT(NBTTagCompound data) {
super.writeToNBT(data);
data.setShort("charge", (short) charge);
data.setByte("rebuildDelay", (byte) rebuildDelay);
if (itemName != null)
data.setString("itemName", itemName);
}
@Override
public void readFromNBT(NBTTagCompound data) {
super.readFromNBT(data);
charge = data.getShort("charge");
rebuildDelay = data.getByte("rebuildDelay");
if (data.hasKey(itemName))
itemName = data.getString("itemName");
}
@Override
public void writePacketData(DataOutputStream data) throws IOException {
super.writePacketData(data);
}
@Override
public void readPacketData(DataInputStream data) throws IOException {
super.readPacketData(data);
}
@Override
public String getName() {
return "";
}
@Override
public short getId() {
return 222;
}
}