package buildcraft.transport.gates; import java.util.Set; import io.netty.buffer.ByteBuf; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; 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.gates.GateExpansions; import buildcraft.api.gates.IGateExpansion; import buildcraft.api.transport.IPipe; import buildcraft.api.transport.IPipeTile; import buildcraft.api.transport.pluggable.IPipePluggableDynamicRenderer; import buildcraft.api.transport.pluggable.IPipePluggableRenderer; import buildcraft.api.transport.pluggable.PipePluggable; import buildcraft.core.CoreConstants; import buildcraft.core.lib.utils.MatrixTranformations; import buildcraft.transport.Gate; import buildcraft.transport.TileGenericPipe; import buildcraft.transport.render.PipeRendererTESR; public class GatePluggable extends PipePluggable { private static final class GatePluggableRenderer implements IPipePluggableRenderer, IPipePluggableDynamicRenderer { public static final GatePluggableRenderer INSTANCE = new GatePluggableRenderer(); private GatePluggableRenderer() { } @Override public void renderPluggable(IPipe pipe, ForgeDirection side, PipePluggable pipePluggable, double x, double y, double z) { PipeRendererTESR.renderGate(x, y, z, (GatePluggable) pipePluggable, side); } @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) { PipeRendererTESR.renderGateStatic(renderblocks, side, (GatePluggable) pipePluggable, blockStateMachine, x, y, z); } } } public GateDefinition.GateMaterial material; public GateDefinition.GateLogic logic; public IGateExpansion[] expansions; public boolean isLit, isPulsing; public Gate realGate, instantiatedGate; private float pulseStage; public GatePluggable() { } public GatePluggable(Gate gate) { instantiatedGate = gate; initFromGate(gate); } private void initFromGate(Gate gate) { this.material = gate.material; this.logic = gate.logic; Set<IGateExpansion> gateExpansions = gate.expansions.keySet(); this.expansions = gateExpansions.toArray(new IGateExpansion[gateExpansions.size()]); } @Override public void writeToNBT(NBTTagCompound nbt) { nbt.setByte(ItemGate.NBT_TAG_MAT, (byte) material.ordinal()); nbt.setByte(ItemGate.NBT_TAG_LOGIC, (byte) logic.ordinal()); NBTTagList expansionsList = nbt.getTagList(ItemGate.NBT_TAG_EX, Constants.NBT.TAG_STRING); for (IGateExpansion expansion : expansions) { expansionsList.appendTag(new NBTTagString(expansion.getUniqueIdentifier())); } nbt.setTag(ItemGate.NBT_TAG_EX, expansionsList); } @Override public void readFromNBT(NBTTagCompound nbt) { material = GateDefinition.GateMaterial.fromOrdinal(nbt.getByte(ItemGate.NBT_TAG_MAT)); logic = GateDefinition.GateLogic.fromOrdinal(nbt.getByte(ItemGate.NBT_TAG_LOGIC)); NBTTagList expansionsList = nbt.getTagList(ItemGate.NBT_TAG_EX, Constants.NBT.TAG_STRING); final int expansionsSize = expansionsList.tagCount(); expansions = new IGateExpansion[expansionsSize]; for (int i = 0; i < expansionsSize; i++) { expansions[i] = GateExpansions.getExpansion(expansionsList.getStringTagAt(i)); } } @Override public void writeData(ByteBuf buf) { buf.writeByte(material.ordinal()); buf.writeByte(logic.ordinal()); buf.writeBoolean(realGate != null ? realGate.isGateActive() : false); buf.writeBoolean(realGate != null ? realGate.isGatePulsing() : false); final int expansionsSize = expansions.length; buf.writeShort(expansionsSize); for (IGateExpansion expansion : expansions) { buf.writeShort(GateExpansions.getExpansionID(expansion)); } } @Override public void readData(ByteBuf buf) { material = GateDefinition.GateMaterial.fromOrdinal(buf.readByte()); logic = GateDefinition.GateLogic.fromOrdinal(buf.readByte()); isLit = buf.readBoolean(); isPulsing = buf.readBoolean(); final int expansionsSize = buf.readUnsignedShort(); expansions = new IGateExpansion[expansionsSize]; for (int i = 0; i < expansionsSize; i++) { expansions[i] = GateExpansions.getExpansionByID(buf.readUnsignedShort()); } } @Override public boolean requiresRenderUpdate(PipePluggable o) { // rendered by TESR return false; } @Override public ItemStack[] getDropItems(IPipeTile pipe) { ItemStack gate = ItemGate.makeGateItem(material, logic); for (IGateExpansion expansion : expansions) { ItemGate.addGateExpansion(gate, expansion); } return new ItemStack[]{gate}; } @Override public void update(IPipeTile pipe, ForgeDirection direction) { if (isPulsing || pulseStage > 0.11F) { // if it is moving, or is still in a moved state, then complete // the current movement pulseStage = (pulseStage + 0.01F) % 1F; } else { pulseStage = 0; } } @Override public void onAttachedPipe(IPipeTile pipe, ForgeDirection direction) { TileGenericPipe pipeReal = (TileGenericPipe) pipe; if (!pipeReal.getWorld().isRemote) { if (instantiatedGate != null) { pipeReal.pipe.gates[direction.ordinal()] = instantiatedGate; } else { Gate gate = pipeReal.pipe.gates[direction.ordinal()]; if (gate == null || gate.material != material || gate.logic != logic) { pipeReal.pipe.gates[direction.ordinal()] = GateFactory.makeGate(pipeReal.pipe, material, logic, direction); for (IGateExpansion expansion : expansions) { pipeReal.pipe.gates[direction.ordinal()].addGateExpansion(expansion); } pipeReal.scheduleRenderUpdate(); } } realGate = pipeReal.pipe.gates[direction.ordinal()]; } } @Override public void onDetachedPipe(IPipeTile pipe, ForgeDirection direction) { TileGenericPipe pipeReal = (TileGenericPipe) pipe; if (!pipeReal.getWorld().isRemote) { Gate gate = pipeReal.pipe.gates[direction.ordinal()]; if (gate != null) { gate.resetGate(); pipeReal.pipe.gates[direction.ordinal()] = null; } pipeReal.scheduleRenderUpdate(); } } @Override public boolean isBlocking(IPipeTile pipe, ForgeDirection direction) { return true; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof GatePluggable)) { return false; } GatePluggable o = (GatePluggable) obj; if (o.material.ordinal() != material.ordinal()) { return false; } if (o.logic.ordinal() != logic.ordinal()) { return false; } if (o.expansions.length != expansions.length) { return false; } for (int i = 0; i < expansions.length; i++) { if (o.expansions[i] != expansions[i]) { return false; } } return true; } @Override public AxisAlignedBB getBoundingBox(ForgeDirection side) { float min = CoreConstants.PIPE_MIN_POS + 0.05F; float max = CoreConstants.PIPE_MAX_POS - 0.05F; float[][] bounds = new float[3][2]; // X START - END bounds[0][0] = min; bounds[0][1] = max; // Y START - END bounds[1][0] = CoreConstants.PIPE_MIN_POS - 0.10F; bounds[1][1] = CoreConstants.PIPE_MIN_POS; // Z START - END bounds[2][0] = min; bounds[2][1] = max; 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 IPipePluggableRenderer getRenderer() { return GatePluggableRenderer.INSTANCE; } @Override public IPipePluggableDynamicRenderer getDynamicRenderer() { return GatePluggableRenderer.INSTANCE; } public float getPulseStage() { return pulseStage; } public GateDefinition.GateMaterial getMaterial() { return material; } public GateDefinition.GateLogic getLogic() { return logic; } public IGateExpansion[] getExpansions() { return expansions; } }