package blusunrize.immersiveengineering.common.blocks.metal.conveyors; import blusunrize.immersiveengineering.api.tool.ConveyorHandler.ConveyorDirection; import blusunrize.immersiveengineering.client.ClientUtils; import blusunrize.immersiveengineering.common.IEContent; import blusunrize.immersiveengineering.common.blocks.metal.BlockTypes_MetalDecoration1; import blusunrize.immersiveengineering.common.blocks.wooden.BlockTypes_WoodenDecoration; import blusunrize.immersiveengineering.common.util.Utils; import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4; import com.google.common.collect.Lists; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing.Axis; import net.minecraft.util.EnumHand; import net.minecraft.util.math.AxisAlignedBB; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.oredict.OreDictionary; import org.lwjgl.util.vector.Vector3f; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.function.Function; /** * @author BluSunrize - 29.03.2017 */ public class ConveyorCovered extends ConveyorBasic { public static ArrayList<com.google.common.base.Function<ItemStack, Boolean>> validCoveyorCovers = new ArrayList(); static { final ArrayList<ItemStack> scaffolds = Lists.newArrayList( new ItemStack(IEContent.blockWoodenDecoration, 1, BlockTypes_WoodenDecoration.SCAFFOLDING.getMeta()), new ItemStack(IEContent.blockMetalDecoration1, 1, BlockTypes_MetalDecoration1.STEEL_SCAFFOLDING_1.getMeta()), new ItemStack(IEContent.blockMetalDecoration1, 1, BlockTypes_MetalDecoration1.STEEL_SCAFFOLDING_2.getMeta()), new ItemStack(IEContent.blockMetalDecoration1, 1, BlockTypes_MetalDecoration1.ALUMINUM_SCAFFOLDING_0.getMeta()), new ItemStack(IEContent.blockMetalDecoration1, 1, BlockTypes_MetalDecoration1.ALUMINUM_SCAFFOLDING_1.getMeta()), new ItemStack(IEContent.blockMetalDecoration1, 1, BlockTypes_MetalDecoration1.ALUMINUM_SCAFFOLDING_2.getMeta())); validCoveyorCovers.add(new com.google.common.base.Function<ItemStack, Boolean>() { @Nullable @Override public Boolean apply(@Nullable ItemStack input) { if(input==null) return Boolean.FALSE; for(ItemStack stack : scaffolds) if(OreDictionary.itemMatches(stack, input, false)) return Boolean.TRUE; return Boolean.FALSE; } }); validCoveyorCovers.add(input -> input==null?Boolean.FALSE: Utils.compareToOreName(input, "blockGlass")); } public ItemStack cover = null; @Override public void onEntityCollision(TileEntity tile, Entity entity, EnumFacing facing) { super.onEntityCollision(tile, entity, facing); if(entity instanceof EntityItem) ((EntityItem) entity).setPickupDelay(10); } @Override public String getModelCacheKey(TileEntity tile, EnumFacing facing) { String key = super.getModelCacheKey(tile, facing); if(cover!=null) key += "s"+cover.getItem().getRegistryName()+cover.getMetadata(); return key; } static final ItemStack defaultCover = new ItemStack(IEContent.blockMetalDecoration1,1, BlockTypes_MetalDecoration1.STEEL_SCAFFOLDING_0.getMeta()); @Override @SideOnly(Side.CLIENT) public List<BakedQuad> modifyQuads(List<BakedQuad> baseModel, @Nullable TileEntity tile, EnumFacing facing) { ItemStack cover = this.cover!=null?this.cover:defaultCover; Block b = Block.getBlockFromItem(cover.getItem()); IBlockState state = b != null ? b.getStateFromMeta(cover.getMetadata()) : Blocks.STONE.getDefaultState(); IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelForState(state); if(model != null) { TextureAtlasSprite sprite = model.getParticleTexture(); HashMap<EnumFacing,TextureAtlasSprite> sprites = new HashMap<>(); ConveyorDirection conDir = this.getConveyorDirection(); for(EnumFacing f : EnumFacing.VALUES) for(BakedQuad q : model.getQuads(state, f, 0)) if(q!=null&&q.getSprite()!=null) sprites.put(f, q.getSprite()); for(BakedQuad q : model.getQuads(state, null, 0)) if(q!=null&&q.getSprite()!=null&&q.getFace()!=null) sprites.put(q.getFace(), q.getSprite()); Function<EnumFacing, TextureAtlasSprite> getSprite = f -> sprites.containsKey(f)?sprites.get(f):sprite; Function<EnumFacing, TextureAtlasSprite> getSpriteHorizontal = f -> f.getAxis()==Axis.Y?null:sprites.containsKey(f)?sprites.get(f):sprite; float[] colour = {1, 1, 1, 1}; Matrix4 matrix = new Matrix4(facing); boolean wallLeft = tile==null||this.renderWall(tile, facing, 0); boolean wallRight = tile==null||this.renderWall(tile, facing, 1); Function<Vector3f[],Vector3f[]> vertexTransformer = conDir==ConveyorDirection.HORIZONTAL?vertices->vertices: vertices -> { Vector3f[] ret = new Vector3f[vertices.length]; for(int i=0; i<ret.length; i++) ret[i] = new Vector3f(vertices[i].x,vertices[i].y+(vertices[i].z==(conDir==ConveyorDirection.UP?0:1)?1:0),vertices[i].z); return ret; }; baseModel.addAll(ClientUtils.createBakedBox(new Vector3f(0, .75f, 0),new Vector3f(1, 1, 1),matrix, facing, vertexTransformer, getSprite, colour)); if(wallLeft) baseModel.addAll(ClientUtils.createBakedBox(new Vector3f(0, .1875f, 0),new Vector3f(.0625f, .75f, 1),matrix, facing, vertexTransformer, getSpriteHorizontal, colour)); else { baseModel.addAll(ClientUtils.createBakedBox(new Vector3f(0, .1875f, 0),new Vector3f(.0625f, .75f, .0625f),matrix, facing, getSpriteHorizontal, colour)); baseModel.addAll(ClientUtils.createBakedBox(new Vector3f(0, .1875f, .9375f),new Vector3f(.0625f, .75f, 1),matrix, facing, getSpriteHorizontal, colour)); } if(wallRight) baseModel.addAll(ClientUtils.createBakedBox(new Vector3f(.9375f, .1875f, 0),new Vector3f(1, .75f, 1),matrix, facing, vertexTransformer, getSpriteHorizontal, colour)); else { baseModel.addAll(ClientUtils.createBakedBox(new Vector3f(.9375f, .1875f, 0),new Vector3f(1, .75f, .0625f),matrix, facing, getSpriteHorizontal, colour)); baseModel.addAll(ClientUtils.createBakedBox(new Vector3f(.9375f, .1875f, .9375f),new Vector3f(1, .75f, 1),matrix, facing, getSpriteHorizontal, colour)); } } return baseModel; } @Override public boolean playerInteraction(TileEntity tile, EntityPlayer player, EnumHand hand, ItemStack heldItem, float hitX, float hitY, float hitZ, EnumFacing side) { if(heldItem == null && player.isSneaking() && cover != null) { if(!tile.getWorld().isRemote && tile.getWorld().getGameRules().getBoolean("doTileDrops")) { EntityItem entityitem = player.dropItem(cover.copy(), false); if(entityitem != null) entityitem.setNoPickupDelay(); } cover = null; return true; } else if(heldItem != null && !player.isSneaking()) for(com.google.common.base.Function<ItemStack, Boolean> func : validCoveyorCovers) if(func.apply(heldItem) == Boolean.TRUE) { if(!OreDictionary.itemMatches(cover, heldItem, true)) { if(!tile.getWorld().isRemote && cover!=null && tile.getWorld().getGameRules().getBoolean("doTileDrops")) { EntityItem entityitem = player.dropItem(cover.copy(), false); if(entityitem != null) entityitem.setNoPickupDelay(); } cover = Utils.copyStackWithAmount(heldItem, 1); if((--heldItem.stackSize) <= 0) player.setHeldItem(hand, heldItem); return true; } } return false; } static final AxisAlignedBB topBox = new AxisAlignedBB(0,.75,0, 1,1,1); @Override public List<AxisAlignedBB> getColisionBoxes(TileEntity tile, EnumFacing facing) { List<AxisAlignedBB> list = Lists.newArrayList(conveyorBounds); if(getConveyorDirection()==ConveyorDirection.HORIZONTAL) list.add(topBox); else { boolean up = getConveyorDirection()==ConveyorDirection.UP; list.add(new AxisAlignedBB((facing==EnumFacing.WEST&&!up)||(facing==EnumFacing.EAST&&up)?.5:0,1.75,(facing==EnumFacing.NORTH&&!up)||(facing==EnumFacing.SOUTH&&up)?.5:0, (facing==EnumFacing.WEST&&up)||(facing==EnumFacing.EAST&&!up)?.5:1,2,(facing==EnumFacing.NORTH&&up)||(facing==EnumFacing.SOUTH&&!up)?.5:1)); list.add(new AxisAlignedBB((facing==EnumFacing.WEST&&up)||(facing==EnumFacing.EAST&&!up)?.5:0,1.25,(facing==EnumFacing.NORTH&&up)||(facing==EnumFacing.SOUTH&&!up)?.5:0, (facing==EnumFacing.WEST&&!up)||(facing==EnumFacing.EAST&&up)?.5:1,1.5,(facing==EnumFacing.NORTH&&!up)||(facing==EnumFacing.SOUTH&&up)?.5:1)); } return list; } @Override public List<AxisAlignedBB> getSelectionBoxes(TileEntity tile, EnumFacing facing) { if(getConveyorDirection()==ConveyorDirection.HORIZONTAL) return Lists.newArrayList(Block.FULL_BLOCK_AABB); else { boolean up = getConveyorDirection()==ConveyorDirection.UP; List<AxisAlignedBB> list = Lists.newArrayList( new AxisAlignedBB((facing==EnumFacing.WEST&&!up)||(facing==EnumFacing.EAST&&up)?.5:0,.5,(facing==EnumFacing.NORTH&&!up)||(facing==EnumFacing.SOUTH&&up)?.5:0, (facing==EnumFacing.WEST&&up)||(facing==EnumFacing.EAST&&!up)?.5:1,2,(facing==EnumFacing.NORTH&&up)||(facing==EnumFacing.SOUTH&&!up)?.5:1), new AxisAlignedBB((facing==EnumFacing.WEST&&up)||(facing==EnumFacing.EAST&&!up)?.5:0,0,(facing==EnumFacing.NORTH&&up)||(facing==EnumFacing.SOUTH&&!up)?.5:0, (facing==EnumFacing.WEST&&!up)||(facing==EnumFacing.EAST&&up)?.5:1,1.5,(facing==EnumFacing.NORTH&&!up)||(facing==EnumFacing.SOUTH&&up)?.5:1)); return list; } } @Override public NBTTagCompound writeConveyorNBT() { NBTTagCompound nbt = super.writeConveyorNBT(); if(cover != null) nbt.setTag("cover", cover.writeToNBT(new NBTTagCompound())); return nbt; } @Override public void readConveyorNBT(NBTTagCompound nbt) { super.readConveyorNBT(nbt); cover = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("cover")); } }