package buildcraft.transport;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.render.ITextureStates;
import buildcraft.api.transport.IPipe;
import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.pluggable.IFacadePluggable;
import buildcraft.api.transport.pluggable.IPipePluggableRenderer;
import buildcraft.api.transport.pluggable.PipePluggable;
import buildcraft.core.lib.utils.MatrixTranformations;
import buildcraft.transport.render.FacadeRenderHelper;
public class FacadePluggable extends PipePluggable implements IFacadePluggable {
public static final class FacadePluggableRenderer implements IPipePluggableRenderer {
public static final IPipePluggableRenderer INSTANCE = new FacadePluggableRenderer();
private FacadePluggableRenderer() {
}
@Override
public void renderPluggable(RenderBlocks renderblocks, IPipe pipe, ForgeDirection side, PipePluggable pipePluggable, ITextureStates blockStateMachine, int renderPass, int x, int y, int z) {
FacadeRenderHelper.pipeFacadeRenderer(renderblocks, blockStateMachine, pipe.getTile(), renderPass, x, y, z, side, (IFacadePluggable) pipePluggable);
}
}
public ItemFacade.FacadeState[] states;
private ItemFacade.FacadeState activeState;
private IPipeTile pipe;
// Client sync
private Block block;
private int meta;
private boolean transparent, renderAsHollow;
public FacadePluggable(ItemFacade.FacadeState[] states) {
this.states = states;
prepareStates();
}
public FacadePluggable() {
}
@Override
public void invalidate() {
this.pipe = null;
}
@Override
public void validate(IPipeTile pipe, ForgeDirection direction) {
this.pipe = pipe;
}
@Override
public boolean requiresRenderUpdate(PipePluggable o) {
FacadePluggable other = (FacadePluggable) o;
return other.block != block || other.meta != meta || other.transparent != transparent || other.renderAsHollow != renderAsHollow;
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
if (states != null) {
nbt.setTag("states", ItemFacade.FacadeState.writeArray(states));
}
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
if (nbt.hasKey("states")) {
states = ItemFacade.FacadeState.readArray(nbt.getTagList("states", Constants.NBT.TAG_COMPOUND));
}
}
@Override
public ItemStack[] getDropItems(IPipeTile pipe) {
if (states != null) {
return new ItemStack[]{ItemFacade.getFacade(states)};
} else {
return new ItemStack[]{ItemFacade.getFacade(new ItemFacade.FacadeState(getCurrentBlock(), getCurrentMetadata(), null, isHollow()))};
}
}
@Override
public boolean isBlocking(IPipeTile pipe, ForgeDirection direction) {
return !isHollow();
}
@Override
public Block getCurrentBlock() {
prepareStates();
return activeState == null ? block : activeState.block;
}
@Override
public int getCurrentMetadata() {
prepareStates();
return activeState == null ? meta : activeState.metadata;
}
@Override
public boolean isTransparent() {
prepareStates();
return activeState == null ? transparent : activeState.transparent;
}
public boolean isHollow() {
prepareStates();
return activeState == null ? renderAsHollow : activeState.hollow;
}
@Override
public AxisAlignedBB getBoundingBox(ForgeDirection side) {
float[][] bounds = new float[3][2];
// X START - END
bounds[0][0] = 0.0F;
bounds[0][1] = 1.0F;
// Y START - END
bounds[1][0] = 0.0F;
bounds[1][1] = TransportConstants.FACADE_THICKNESS;
// Z START - END
bounds[2][0] = 0.0F;
bounds[2][1] = 1.0F;
MatrixTranformations.transform(bounds, side);
return AxisAlignedBB.getBoundingBox(bounds[0][0], bounds[1][0], bounds[2][0], bounds[0][1], bounds[1][1], bounds[2][1]);
}
@Override
public boolean isSolidOnSide(IPipeTile pipe, ForgeDirection direction) {
return !isHollow();
}
@Override
public IPipePluggableRenderer getRenderer() {
return FacadePluggableRenderer.INSTANCE;
}
@Override
public void writeData(ByteBuf data) {
prepareStates();
if (activeState == null || activeState.block == null) {
data.writeShort(0);
} else {
data.writeShort(Block.getIdFromBlock(activeState.block));
}
data.writeByte((activeState != null && activeState.transparent ? 128 : 0) |
(activeState != null && activeState.hollow ? 64 : 0) |
(activeState == null ? 0 : activeState.metadata));
}
@Override
public void readData(ByteBuf data) {
int blockId = data.readUnsignedShort();
if (blockId > 0) {
block = Block.getBlockById(blockId);
} else {
block = null;
}
int flags = data.readUnsignedByte();
meta = flags & 0x0F;
transparent = (flags & 0x80) != 0;
renderAsHollow = (flags & 0x40) != 0;
}
private void prepareStates() {
if (states != null && states.length > 1) {
if (pipe == null || pipe.getPipe() == null) {
activeState = states[0];
return;
}
IPipe p = pipe.getPipe();
int defaultStateId = -1;
int activeStateId = -1;
for (int i = 0; i < states.length; i++) {
ItemFacade.FacadeState state = states[i];
if (state.wire == null) {
defaultStateId = i;
continue;
}
if (p.isWireActive(state.wire)) {
activeStateId = i;
break;
}
}
activeState = activeStateId < 0 ? (defaultStateId < 0 ? states[0] : states[defaultStateId]) : states[activeStateId];
} else if (activeState == null) {
activeState = states != null && states.length > 0 ? states[0] : null;
}
}
}