package buildcraft.robotics;
import java.util.List;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.ForgeDirection;
import cofh.api.energy.IEnergyReceiver;
import buildcraft.BuildCraftRobotics;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.render.ITextureStates;
import buildcraft.api.robots.DockingStation;
import buildcraft.api.robots.IDockingStationProvider;
import buildcraft.api.robots.RobotManager;
import buildcraft.api.tiles.IDebuggable;
import buildcraft.api.transport.IPipe;
import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.pluggable.IPipePluggableItem;
import buildcraft.api.transport.pluggable.IPipePluggableRenderer;
import buildcraft.api.transport.pluggable.PipePluggable;
import buildcraft.core.lib.utils.MatrixTranformations;
import buildcraft.transport.PipeIconProvider;
public class RobotStationPluggable extends PipePluggable implements IPipePluggableItem, IEnergyReceiver, IDebuggable,
IDockingStationProvider {
public class RobotStationPluggableRenderer implements IPipePluggableRenderer {
private float zFightOffset = 1 / 4096.0F;
@Override
public void renderPluggable(RenderBlocks renderblocks, IPipe pipe, ForgeDirection side, PipePluggable pipePluggable, ITextureStates blockStateMachine, int renderPass, int x, int y, int z) {
if (renderPass != 0) {
return;
}
RobotStationState state = ((RobotStationPluggable) pipePluggable).getRenderState();
switch (state) {
case None:
case Available:
blockStateMachine.getTextureState().set(BuildCraftTransport.instance.pipeIconProvider
.getIcon(PipeIconProvider.TYPE.PipeRobotStation.ordinal()));
break;
case Reserved:
blockStateMachine.getTextureState().set(BuildCraftTransport.instance.pipeIconProvider
.getIcon(PipeIconProvider.TYPE.PipeRobotStationReserved.ordinal()));
break;
case Linked:
blockStateMachine.getTextureState().set(BuildCraftTransport.instance.pipeIconProvider
.getIcon(PipeIconProvider.TYPE.PipeRobotStationLinked.ordinal()));
break;
}
float[][] zeroState = new float[3][2];
// X START - END
zeroState[0][0] = 0.4325F;
zeroState[0][1] = 0.5675F;
// Y START - END
zeroState[1][0] = 0F;
zeroState[1][1] = 0.1875F + zFightOffset;
// Z START - END
zeroState[2][0] = 0.4325F;
zeroState[2][1] = 0.5675F;
float[][] rotated = MatrixTranformations.deepClone(zeroState);
MatrixTranformations.transform(rotated, side);
renderblocks.setRenderBounds(rotated[0][0], rotated[1][0],
rotated[2][0], rotated[0][1], rotated[1][1],
rotated[2][1]);
renderblocks.renderStandardBlock(blockStateMachine.getBlock(), x, y, z);
// X START - END
zeroState[0][0] = 0.25F;
zeroState[0][1] = 0.75F;
// Y START - END
zeroState[1][0] = 0.1875F;
zeroState[1][1] = 0.25F + zFightOffset;
// Z START - END
zeroState[2][0] = 0.25F;
zeroState[2][1] = 0.75F;
rotated = MatrixTranformations.deepClone(zeroState);
MatrixTranformations.transform(rotated, side);
renderblocks.setRenderBounds(rotated[0][0], rotated[1][0],
rotated[2][0], rotated[0][1], rotated[1][1],
rotated[2][1]);
renderblocks.renderStandardBlock(blockStateMachine.getBlock(), x, y, z);
}
}
public enum RobotStationState {
None,
Available,
Reserved,
Linked
}
private RobotStationState renderState;
private DockingStationPipe station;
private boolean isValid = false;
public RobotStationPluggable() {
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
}
@Override
public ItemStack[] getDropItems(IPipeTile pipe) {
return new ItemStack[]{new ItemStack(BuildCraftRobotics.robotStationItem)};
}
@Override
public DockingStation getStation() {
return station;
}
@Override
public boolean isBlocking(IPipeTile pipe, ForgeDirection direction) {
return true;
}
@Override
public void invalidate() {
if (station != null
&& station.getPipe() != null
&& !station.getPipe().getWorld().isRemote) {
RobotManager.registryProvider.getRegistry(station.world).removeStation(station);
isValid = false;
}
}
@Override
public void validate(IPipeTile pipe, ForgeDirection direction) {
if (!isValid && !pipe.getWorld().isRemote) {
station = (DockingStationPipe)
RobotManager.registryProvider.getRegistry(pipe.getWorld()).getStation(
pipe.x(),
pipe.y(),
pipe.z(),
direction);
if (station == null) {
station = new DockingStationPipe(pipe, direction);
RobotManager.registryProvider.getRegistry(pipe.getWorld()).registerStation(station);
}
isValid = true;
}
}
@Override
public AxisAlignedBB getBoundingBox(ForgeDirection side) {
float[][] bounds = new float[3][2];
// X START - END
bounds[0][0] = 0.25F;
bounds[0][1] = 0.75F;
// Y START - END
bounds[1][0] = 0.125F;
bounds[1][1] = 0.251F;
// Z START - END
bounds[2][0] = 0.25F;
bounds[2][1] = 0.75F;
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]);
}
private void refreshRenderState() {
this.renderState = station.isTaken()
? (station.isMainStation() ? RobotStationState.Linked : RobotStationState.Reserved)
: RobotStationState.Available;
}
public RobotStationState getRenderState() {
if (renderState == null) {
renderState = RobotStationState.None;
}
return renderState;
}
@Override
public IPipePluggableRenderer getRenderer() {
return new RobotStationPluggableRenderer();
}
@Override
public void writeData(ByteBuf data) {
refreshRenderState();
data.writeByte(getRenderState().ordinal());
}
@Override
public boolean requiresRenderUpdate(PipePluggable o) {
return getRenderState() != ((RobotStationPluggable) o).getRenderState();
}
@Override
public void readData(ByteBuf data) {
try {
this.renderState = RobotStationState.values()[data.readUnsignedByte()];
} catch (ArrayIndexOutOfBoundsException e) {
this.renderState = RobotStationState.None;
}
}
@Override
public PipePluggable createPipePluggable(IPipe pipe, ForgeDirection side, ItemStack stack) {
return new RobotStationPluggable();
}
@Override
public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) {
if (station != null && station.robotTaking() != null && station.robotTaking().getBattery() != null
&& station.robotTaking().getDockingStation() == station) {
return ((EntityRobot) station.robotTaking()).receiveEnergy(maxReceive, simulate);
}
return 0;
}
@Override
public int getEnergyStored(ForgeDirection from) {
return 0;
}
@Override
public int getMaxEnergyStored(ForgeDirection from) {
return 0;
}
@Override
public boolean canConnectEnergy(ForgeDirection from) {
return true;
}
@Override
public void getDebugInfo(List<String> info, ForgeDirection side, ItemStack debugger, EntityPlayer player) {
if (station == null) {
info.add("RobotStationPluggable: No station found!");
} else {
refreshRenderState();
info.add("Docking Station (side " + side.name() + ", " + getRenderState().name() + ")");
if (station.robotTaking() != null && station.robotTaking() instanceof IDebuggable) {
((IDebuggable) station.robotTaking()).getDebugInfo(info, ForgeDirection.UNKNOWN, debugger, player);
}
}
}
}