package pneumaticCraft.common.thirdparty.fmp; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import net.minecraft.block.Block; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import pneumaticCraft.api.block.IPneumaticWrenchable; import pneumaticCraft.api.tileentity.IAirHandler; import pneumaticCraft.client.model.ModelPressureTube; import pneumaticCraft.common.block.BlockPressureTube; import pneumaticCraft.common.block.Blockss; import pneumaticCraft.common.block.tubes.IPneumaticPosProvider; import pneumaticCraft.common.block.tubes.TubeModule; import pneumaticCraft.common.block.tubes.TubeModuleRedstoneEmitting; import pneumaticCraft.common.config.Config; import pneumaticCraft.common.tileentity.TileEntityPressureTube; import pneumaticCraft.lib.BBConstants; import pneumaticCraft.lib.Log; import codechicken.lib.data.MCDataInput; import codechicken.lib.data.MCDataOutput; import codechicken.lib.raytracer.IndexedCuboid6; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Vector3; import codechicken.microblock.ISidedHollowConnect; import codechicken.multipart.IRedstonePart; import codechicken.multipart.JNormalOcclusion; import codechicken.multipart.NormalOcclusionTest; import codechicken.multipart.NormallyOccludedPart; import codechicken.multipart.PartMap; import codechicken.multipart.TMultiPart; import codechicken.multipart.TSlottedPart; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class PartPressureTube extends TMultiPart implements IPneumaticPosProvider, IPneumaticWrenchable, TSlottedPart, JNormalOcclusion, ISidedHollowConnect, IRedstonePart{ private TileEntityPressureTube tube = getNewTube().setPart(this); private static final Cuboid6[] boundingBoxes = new Cuboid6[7]; static { boundingBoxes[0] = new Cuboid6(BBConstants.PRESSURE_PIPE_MIN_POS, 0.0F, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MAX_POS); boundingBoxes[1] = new Cuboid6(BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MAX_POS, 1.0F, BBConstants.PRESSURE_PIPE_MAX_POS); boundingBoxes[2] = new Cuboid6(BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MIN_POS, 0.0F, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MIN_POS); boundingBoxes[3] = new Cuboid6(BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MAX_POS, 1.0F); boundingBoxes[4] = new Cuboid6(0.0F, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MAX_POS); boundingBoxes[5] = new Cuboid6(BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MIN_POS, 1.0F, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MAX_POS); boundingBoxes[6] = new Cuboid6(BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MIN_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MAX_POS, BBConstants.PRESSURE_PIPE_MAX_POS); } public PartPressureTube(){} public PartPressureTube(TileEntityPressureTube tube){ this.tube = tube.setPart(this); } @Override public IAirHandler getAirHandler(){ return tube.getAirHandler(); } @Override public void load(NBTTagCompound nbt){ if(nbt.hasKey("tube")) {//TODO remove legacy nbt = nbt.getCompoundTag("tube"); } tube.readFromNBTI(nbt); } @Override public void save(NBTTagCompound nbt){ NBTTagCompound tag = new NBTTagCompound(); tube.writeToNBTI(tag); nbt.setTag("tube", tag); } protected TileEntityPressureTube getNewTube(){ return new TileEntityPressureTube(); } @Override public void update(){ //Log.info("sides connected " + world().isRemote + ": " + Arrays.toString(sidesConnected)); if(Config.convertMultipartsToBlocks && !world().isRemote) { Log.info("Converting Pressure Tube part to Pressure Tube block at " + x() + ", " + y() + ", " + z()); Block pressureTube = Block.getBlockFromItem(getItem().getItem()); world().setBlock(x(), y(), z(), pressureTube); TileEntityPressureTube t = (TileEntityPressureTube)world().getTileEntity(x(), y(), z()); NBTTagCompound tag = new NBTTagCompound(); tube.writeToNBTI(tag); t.readFromNBT(tag); world().notifyBlocksOfNeighborChange(x(), y(), z(), pressureTube); return; } tube.updateEntityI(); } @Override public boolean isConnectedTo(ForgeDirection side){ return tube.isConnectedTo(side); } public boolean passesOcclusionTest(ForgeDirection side){ TubeModule[] modules = tube.modules; tube.modules = new TubeModule[6]; boolean result = tile() != null && tile().canAddPart(new NormallyOccludedPart(boundingBoxes[side.ordinal()])); tube.modules = modules; return result; } public TileEntityPressureTube getTube(){ return tube; } @Override public void onWorldJoin(){ tube.setWorldObj(world()); tube.xCoord = x(); tube.yCoord = y(); tube.zCoord = z(); } @Override public void onPartChanged(TMultiPart part){ onNeighborChanged(); } @Override public void onNeighborChanged(){ if(!world().isRemote) { tube.onNeighborTileUpdate(); tube.onNeighborChange(); tube.onNeighborBlockUpdate(); sendDescriptionPacket(); } } @Override public boolean activate(EntityPlayer player, MovingObjectPosition hit, ItemStack item){ boolean result = Blockss.pressureTube.onBlockActivated(player.worldObj, x(), y(), z(), player, hit.sideHit, (float)hit.hitVec.xCoord, (float)hit.hitVec.yCoord, (float)hit.hitVec.zCoord); if(result) onNeighborChanged(); return result ? true : super.activate(player, hit, item); } @Override public Cuboid6 getRenderBounds(){ return Cuboid6.full; } @Override public String getType(){ return "tile.pressureTube"; } @Override public int getHollowSize(int side){ if(tube.modules[side] != null) { return Math.min(12, (int)(tube.modules[side].getWidth() * 16)); } return 4; } @Override public Iterable<ItemStack> getDrops(){ List<ItemStack> drops = BlockPressureTube.getModuleDrops(getTube()); drops.add(getItem()); return drops; } @Override public ItemStack pickItem(MovingObjectPosition hit){ return getItem(); } public ItemStack getItem(){ return new ItemStack(Blockss.pressureTube); } @Override public Iterable<Cuboid6> getOcclusionBoxes(){ List<Cuboid6> boxes = new ArrayList<Cuboid6>(); boxes.add(boundingBoxes[6]); for(int i = 0; i < 6; i++) { if(tube.modules[i] != null) boxes.add(boundingBoxes[i]);//The full bounding box of modules is too big for hollow covers. } return boxes; } @Override public boolean occlusionTest(TMultiPart npart){ return NormalOcclusionTest.apply(this, npart); } @Override public Iterable<Cuboid6> getCollisionBoxes(){ List<Cuboid6> boxes = new ArrayList<Cuboid6>(); boxes.add(boundingBoxes[6]); for(int i = 0; i < 6; i++) { if(tube.sidesConnected[i]) boxes.add(boundingBoxes[i]); if(tube.modules[i] != null) boxes.add(new Cuboid6(tube.modules[i].boundingBoxes[i])); } return boxes; } @Override public Iterable<IndexedCuboid6> getSubParts(){ Iterable<Cuboid6> boxList = getCollisionBoxes(); LinkedList<IndexedCuboid6> partList = new LinkedList<IndexedCuboid6>(); for(Cuboid6 c : boxList) partList.add(new IndexedCuboid6(0, c)); return partList; } @Override public int getSlotMask(){ return PartMap.CENTER.mask; } @SideOnly(Side.CLIENT) private static ModelPressureTube tubeModel; @SideOnly(Side.CLIENT) @Override public void renderDynamic(Vector3 pos, float partialTicks, int renderPass){ if(renderPass == 0) { /* GL11.glPushMatrix(); // start // GL11.glDisable(GL11.GL_TEXTURE_2D); // GL11.glEnable(GL11.GL_BLEND); // GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); FMLClientHandler.instance().getClient().getTextureManager().bindTexture(getTexture()); // GL11.glColor4f(0.82F, 0.56F, 0.09F, 1.0F); GL11.glTranslatef((float)pos.x + 0.5F, (float)pos.y + 1.5F, (float)pos.z + 0.5F); // size GL11.glRotatef(0, 0.0F, 1.0F, 0.0F); GL11.glScalef(1.0F, -1F, -1F); if(tubeModel == null) tubeModel = new ModelPressureTube(); tubeModel.renderModel(0.0625F, tube.sidesConnected); GL11.glPopMatrix();*/ TileEntityRendererDispatcher.instance.getSpecialRenderer(tube).renderTileEntityAt(tube, pos.x, pos.y, pos.z, partialTicks); } } private void sendDescriptionPacket(){ sendDescUpdate(); } @Override public void writeDesc(MCDataOutput packet){ for(int i = 0; i < 6; i++) { packet.writeBoolean(tube.sidesConnected[i]); } NBTTagCompound tag = new NBTTagCompound(); tube.writeToNBT(tag); packet.writeNBTTagCompound(tag); } @Override public void readDesc(MCDataInput packet){ for(int i = 0; i < 6; i++) { tube.sidesConnected[i] = packet.readBoolean(); } tube.readFromNBT(packet.readNBTTagCompound()); } @Override public boolean canConnectRedstone(int side){ side = side ^ 1; for(int i = 0; i < 6; i++) { if(tube.modules[i] != null) { if((side ^ 1) == i || i != side && tube.modules[i].isInline()) {//if we are on the same side, or when we have an 'in line' module that is not on the opposite side. if(tube.modules[i] instanceof TubeModuleRedstoneEmitting) return true; } } } return false; } @Override public int strongPowerLevel(int side){ return 0; } @Override public int weakPowerLevel(int side){ side = side ^ 1; int redstoneLevel = 0; for(int i = 0; i < 6; i++) { if(tube.modules[i] != null) { if((side ^ 1) == i || i != side && tube.modules[i].isInline()) {//if we are on the same side, or when we have an 'in line' module that is not on the opposite side. redstoneLevel = Math.max(redstoneLevel, tube.modules[i].getRedstoneLevel()); } } } return redstoneLevel; } @Override public boolean rotateBlock(World world, EntityPlayer player, int x, int y, int z, ForgeDirection side){ return ((IPneumaticWrenchable)Blockss.pressureTube).rotateBlock(world, player, x, y, z, side); } }