package com.rwtema.funkylocomotion.blocks; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.HashSet; import javax.annotation.Nonnull; import com.rwtema.funkylocomotion.description.Describer; import com.rwtema.funkylocomotion.fakes.FakeWorldClient; import com.rwtema.funkylocomotion.rendering.ChunkRerenderer; import com.rwtema.funkylocomotion.rendering.PassHandler; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class TileMovingClient extends TileMovingBase { public static final HashMap<BlockPos, WeakReference<TileEntity>> cachedTiles = new HashMap<>(); public static final HashSet<Class<?>> renderBlackList = new HashSet<>(); public static final HashSet<Class<?>> renderErrorList = new HashSet<>(); public final boolean[] skipPass = new boolean[2]; public Block block = Blocks.AIR; public int meta = 0; public TileEntity tile = null; public boolean render; public boolean error = false; public boolean rawTile = false; public boolean init = false; public TileMovingClient() { super(Side.CLIENT); } @Override public void update() { if (time < maxTime) { super.update(); } } @Override public void invalidate() { super.invalidate(); if (rawTile && tile != null) tile.invalidate(); } @Override public void handleUpdateTag(NBTTagCompound tag) { block = Block.getBlockById(tag.getInteger("Block")); meta = tag.getInteger("Meta"); time = tag.getInteger("Time"); maxTime = tag.getInteger("MaxTime"); lightLevel = tag.getInteger("Light"); lightOpacity = tag.getShort("Opacity"); isAir = block == Blocks.AIR; if (tag.hasKey("Collisions", 9)) { collisions = AxisTags(tag.getTagList("Collisions", 10)); } // BlockHelper.postUpdateBlock(worldObj, pos); dir = tag.getByte("Dir"); TileEntity tile = null; if (this.dir >= 0 && this.dir < 8 && this.dir != 6) { EnumFacing d = getDir(); WeakReference<TileEntity> ref = cachedTiles.remove(d != null ? pos.offset(d, -1) : pos); // if (ref != null) // tile = ref.get(); } if (tile != null && FakeWorldClient.isValid(getWorld()) && tile.getWorld() == this.getWorld()) { rawTile = true; tile.setPos(pos.toImmutable()); tile.setWorld(FakeWorldClient.getFakeWorldWrapper(this.getWorld())); tile.updateContainingBlockInfo(); this.tile = tile; render = true; } else { render = !tag.getBoolean("DNR"); if (render) { this.tile = Describer.recreateTileEntity(tag, getState(), pos, FakeWorldClient.getFakeWorldWrapper(this.getWorld())); } } if (checkClass(this.block) || checkClass(this.tile)) this.tile = null; if (render && !init) ChunkRerenderer.markBlock(pos); init = true; getWorld().markBlockRangeForRenderUpdate(pos, pos); } public boolean checkClass(Object o) { if (o == null) return false; if (renderBlackList.contains(o.getClass())) { this.render = false; return true; } if (renderErrorList.contains(o.getClass())) { this.render = false; this.error = true; return true; } return false; } @Nonnull @SideOnly(Side.CLIENT) public AxisAlignedBB getRenderBoundingBox() { AxisAlignedBB other; if (tile != null) other = tile.getRenderBoundingBox(); else other = getState().getCollisionBoundingBox(FakeWorldClient.getFakeWorldWrapper(getWorld()), pos); if (other == null) other = Block.FULL_BLOCK_AABB; else other = other.union(Block.FULL_BLOCK_AABB); other = other.addCoord(pos.getX(), pos.getY(), pos.getZ()); double h = offset(true); EnumFacing d = getDir(); return h != 0 && d != null ? other.offset(h * d.getFrontOffsetX(), h * d.getFrontOffsetY(), h * d.getFrontOffsetZ()) : other; } @Override public boolean shouldRenderInPass(int pass) { if (maxTime == 0) return false; if (!render || error) return pass == 0; IBlockState state = getState(); if (block == Blocks.AIR || (tile == null && state.getRenderType() == EnumBlockRenderType.INVISIBLE)) return false; if (tile != null) { if (tile.shouldRenderInPass(pass)) return true; } for (BlockRenderLayer layer : PassHandler.getHandler(pass).layers) { if (block.canRenderInLayer(state, layer)) { return true; } } return false; } @SuppressWarnings("deprecation") public IBlockState getState() { return block.getStateFromMeta(meta); } }