diff --git a/src/main/java/com/raoulvdberge/refinedstorage/RSItems.java b/src/main/java/com/raoulvdberge/refinedstorage/RSItems.java index c2844c43f..af50bad0e 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/RSItems.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/RSItems.java @@ -21,4 +21,5 @@ public final class RSItems { public static final ItemFluidStoragePart FLUID_STORAGE_PART = new ItemFluidStoragePart(); public static final ItemSecurityCard SECURITY_CARD = new ItemSecurityCard(); public static final ItemCuttingTool CUTTING_TOOL = new ItemCuttingTool(); + public static final ItemCover COVER = new ItemCover(); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/ICoverable.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/ICoverable.java new file mode 100644 index 000000000..51d5edc76 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/ICoverable.java @@ -0,0 +1,7 @@ +package com.raoulvdberge.refinedstorage.apiimpl.network.node; + +import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager; + +public interface ICoverable { + CoverManager getCoverManager(); +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCable.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCable.java index 88cf7b604..627dc00a6 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCable.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCable.java @@ -1,12 +1,22 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.node; import com.raoulvdberge.refinedstorage.RS; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.items.IItemHandler; -public class NetworkNodeCable extends NetworkNode { +import javax.annotation.Nullable; + +public class NetworkNodeCable extends NetworkNode implements ICoverable { public static final String ID = "cable"; + private static final String NBT_COVERS = "Covers"; + + private CoverManager coverManager = new CoverManager(this); + public NetworkNodeCable(World world, BlockPos pos) { super(world, pos); } @@ -20,4 +30,33 @@ public class NetworkNodeCable extends NetworkNode { public String getId() { return ID; } + + @Override + public CoverManager getCoverManager() { + return coverManager; + } + + @Override + public NBTTagCompound write(NBTTagCompound tag) { + super.write(tag); + + tag.setTag(NBT_COVERS, coverManager.writeToNbt()); + + return tag; + } + + @Override + public void read(NBTTagCompound tag) { + super.read(tag); + + if (tag.hasKey(NBT_COVERS)) { + coverManager.readFromNbt(tag.getTagList(NBT_COVERS, Constants.NBT.TAG_COMPOUND)); + } + } + + @Nullable + @Override + public IItemHandler getDrops() { + return coverManager.getAsInventory(); + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/cover/CoverManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/cover/CoverManager.java new file mode 100644 index 000000000..a41562e15 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/cover/CoverManager.java @@ -0,0 +1,141 @@ +package com.raoulvdberge.refinedstorage.apiimpl.network.node.cover; + +import com.raoulvdberge.refinedstorage.RSItems; +import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; +import com.raoulvdberge.refinedstorage.item.ItemCover; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemStackHandler; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + +public class CoverManager { + private static final String NBT_DIRECTION = "Direction"; + private static final String NBT_ITEM = "Item"; + + private Map covers = new HashMap<>(); + private INetworkNode node; + + public CoverManager(INetworkNode node) { + this.node = node; + } + + @Nullable + public ItemStack getCover(EnumFacing facing) { + return covers.get(facing); + } + + public boolean setCover(EnumFacing cover, ItemStack stack) { + if (isValidCover(stack) && !covers.containsKey(cover)) { + covers.put(cover, stack); + + node.markDirty(); + + return true; + } + + return false; + } + + public void readFromNbt(NBTTagList list) { + for (int i = 0; i < list.tagCount(); ++i) { + NBTTagCompound tag = list.getCompoundTagAt(i); + + if (tag.hasKey(NBT_DIRECTION) && tag.hasKey(NBT_ITEM)) { + EnumFacing direction = EnumFacing.getFront(tag.getInteger(NBT_DIRECTION)); + ItemStack item = new ItemStack(tag.getCompoundTag(NBT_ITEM)); + + if (isValidCover(item)) { + covers.put(direction, item); + } + } + } + } + + public NBTTagList writeToNbt() { + NBTTagList list = new NBTTagList(); + + for (Map.Entry entry : covers.entrySet()) { + NBTTagCompound tag = new NBTTagCompound(); + + tag.setInteger(NBT_DIRECTION, entry.getKey().ordinal()); + tag.setTag(NBT_ITEM, entry.getValue().serializeNBT()); + + list.appendTag(tag); + } + + return list; + } + + public IItemHandler getAsInventory() { + ItemStackHandler handler = new ItemStackHandler(covers.size()); + + int i = 0; + + for (Map.Entry entry : covers.entrySet()) { + ItemStack cover = new ItemStack(RSItems.COVER); + + ItemCover.setItem(cover, entry.getValue()); + + handler.setStackInSlot(i++, cover); + } + + return handler; + } + + public static boolean isValidCover(ItemStack item) { + if (item.isEmpty()) { + return false; + } + + Block block = getBlock(item); + + IBlockState state = getBlockState(item); + + return block != null && state != null && isModelSupported(state) && block.isTopSolid(state) && !block.getTickRandomly() && !block.hasTileEntity(state); + } + + private static boolean isModelSupported(IBlockState state) { + if (state.getRenderType() != EnumBlockRenderType.MODEL || state instanceof IExtendedBlockState) { + return false; + } + + return state.isFullCube(); + } + + @Nullable + public static Block getBlock(@Nullable ItemStack item) { + if (item == null) { + return null; + } + + Block block = Block.getBlockFromItem(item.getItem()); + + if (block == Blocks.AIR) { + return null; + } + + return block; + } + + @Nullable + public static IBlockState getBlockState(@Nullable ItemStack item) { + Block block = getBlock(item); + + if (block == null) { + return null; + } + + return block.getStateFromMeta(item.getItem().getMetadata(item)); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockCable.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockCable.java index 451475f78..18c4de40b 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockCable.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockCable.java @@ -1,5 +1,7 @@ package com.raoulvdberge.refinedstorage.block; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager; import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy; import com.raoulvdberge.refinedstorage.tile.TileBase; import com.raoulvdberge.refinedstorage.tile.TileCable; @@ -11,6 +13,7 @@ import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; @@ -20,13 +23,27 @@ import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.common.property.IExtendedBlockState; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class BlockCable extends BlockNode { + public static final PropertyObject COVER_NORTH = new PropertyObject<>("cover_north", ItemStack.class); + public static final PropertyObject COVER_EAST = new PropertyObject<>("cover_east", ItemStack.class); + public static final PropertyObject COVER_SOUTH = new PropertyObject<>("cover_south", ItemStack.class); + public static final PropertyObject COVER_WEST = new PropertyObject<>("cover_west", ItemStack.class); + public static final PropertyObject COVER_UP = new PropertyObject<>("cover_up", ItemStack.class); + public static final PropertyObject COVER_DOWN = new PropertyObject<>("cover_down", ItemStack.class); + + public static final AxisAlignedBB HOLDER_NORTH_AABB = RenderUtils.getBounds(7, 7, 2, 9, 9, 6); + public static final AxisAlignedBB HOLDER_EAST_AABB = RenderUtils.getBounds(10, 7, 7, 14, 9, 9); + public static final AxisAlignedBB HOLDER_SOUTH_AABB = RenderUtils.getBounds(7, 7, 10, 9, 9, 14); + public static final AxisAlignedBB HOLDER_WEST_AABB = RenderUtils.getBounds(2, 7, 7, 6, 9, 9); + public static final AxisAlignedBB HOLDER_UP_AABB = RenderUtils.getBounds(7, 10, 7, 9, 14, 9); + public static final AxisAlignedBB HOLDER_DOWN_AABB = RenderUtils.getBounds(7, 2, 7, 9, 6, 9); + public static final AxisAlignedBB CORE_AABB = RenderUtils.getBounds(6, 6, 6, 10, 10, 10); private static final AxisAlignedBB NORTH_AABB = RenderUtils.getBounds(6, 6, 0, 10, 10, 6); private static final AxisAlignedBB EAST_AABB = RenderUtils.getBounds(10, 6, 6, 16, 10, 10); @@ -68,6 +85,12 @@ public class BlockCable extends BlockNode { .add(WEST) .add(UP) .add(DOWN) + .add(COVER_NORTH) + .add(COVER_EAST) + .add(COVER_SOUTH) + .add(COVER_WEST) + .add(COVER_UP) + .add(COVER_DOWN) .build(); } @@ -87,6 +110,24 @@ public class BlockCable extends BlockNode { return state; } + @Override + public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) { + IBlockState s = super.getExtendedState(state, world, pos); + + TileEntity tile = world.getTileEntity(pos); + + if (tile instanceof TileNode && ((TileNode) tile).getNode() instanceof ICoverable) { + s = ((IExtendedBlockState) s).withProperty(COVER_NORTH, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.NORTH)); + s = ((IExtendedBlockState) s).withProperty(COVER_EAST, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.EAST)); + s = ((IExtendedBlockState) s).withProperty(COVER_SOUTH, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.SOUTH)); + s = ((IExtendedBlockState) s).withProperty(COVER_WEST, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.WEST)); + s = ((IExtendedBlockState) s).withProperty(COVER_UP, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.UP)); + s = ((IExtendedBlockState) s).withProperty(COVER_DOWN, ((ICoverable) ((TileNode) tile).getNode()).getCoverManager().getCover(EnumFacing.DOWN)); + } + + return s; + } + private static boolean hasConnectionWith(IBlockAccess world, BlockPos pos, BlockBase block, TileEntity tile, EnumFacing direction) { if (!(tile instanceof TileNode)) { return false; @@ -119,7 +160,7 @@ public class BlockCable extends BlockNode { (state.getValue(DOWN) && RenderUtils.isInBounds(DOWN_AABB, hitX, hitY, hitZ)); } - public List getUnionizedCollisionBoxes(IBlockState state) { + public List getCombinedCollisionBoxes(IBlockState state) { List boxes = new ArrayList<>(); boxes.add(CORE_AABB); @@ -151,15 +192,81 @@ public class BlockCable extends BlockNode { return boxes; } - public List getNonUnionizedCollisionBoxes(IBlockState state) { - return Collections.emptyList(); - } - - public List getCollisionBoxes(IBlockState state) { + public List getCollisionBoxes(TileEntity tile, IBlockState state) { List boxes = new ArrayList<>(); - boxes.addAll(getUnionizedCollisionBoxes(state)); - boxes.addAll(getNonUnionizedCollisionBoxes(state)); + if (tile instanceof TileNode && ((TileNode) tile).getNode() instanceof ICoverable) { + CoverManager coverManager = ((ICoverable) ((TileNode) tile).getNode()).getCoverManager(); + + boolean hasUp = coverManager.getCover(EnumFacing.UP) != null; + boolean hasDown = coverManager.getCover(EnumFacing.DOWN) != null; + + boolean hasEast = coverManager.getCover(EnumFacing.EAST) != null; + boolean hasWest = coverManager.getCover(EnumFacing.WEST) != null; + + if (coverManager.getCover(EnumFacing.NORTH) != null) { + boxes.add(RenderUtils.getBounds( + hasWest ? 2 : 0, hasDown ? 2 : 0, 0, + hasEast ? 14 : 16, hasUp ? 14 : 16, 2 + )); + + boxes.add(HOLDER_NORTH_AABB); + } + + if (hasEast) { + boxes.add(RenderUtils.getBounds( + 14, hasDown ? 2 : 0, 0, + 16, hasUp ? 14 : 16, 16 + )); + + boxes.add(HOLDER_EAST_AABB); + } + + if (coverManager.getCover(EnumFacing.SOUTH) != null) { + boxes.add(RenderUtils.getBounds( + hasEast ? 14 : 16, hasDown ? 2 : 0, 16, + hasWest ? 2 : 0, hasUp ? 14 : 16, 14 + )); + + boxes.add(HOLDER_SOUTH_AABB); + } + + if (hasWest) { + boxes.add(RenderUtils.getBounds( + 0, hasDown ? 2 : 0, 0, + 2, hasUp ? 14 : 16, 16 + )); + + boxes.add(HOLDER_WEST_AABB); + } + + if (hasUp) { + boxes.add(RenderUtils.getBounds( + 0, 14, 0, + 16, 16, 16 + )); + + boxes.add(HOLDER_UP_AABB); + } + + if (hasDown) { + boxes.add(RenderUtils.getBounds( + 0, 0, 0, + 16, 2, 16 + )); + + boxes.add(HOLDER_DOWN_AABB); + } + } + + return boxes; + } + + private List getAllCollisionBoxes(TileEntity tile, IBlockState state) { + List boxes = new ArrayList<>(); + + boxes.addAll(getCombinedCollisionBoxes(state)); + boxes.addAll(getCollisionBoxes(tile, state)); return boxes; } @@ -167,7 +274,7 @@ public class BlockCable extends BlockNode { @Override @SuppressWarnings("deprecation") public void addCollisionBoxToList(IBlockState state, World world, BlockPos pos, AxisAlignedBB entityBox, List collidingBoxes, Entity entityIn, boolean p_185477_7_) { - for (AxisAlignedBB aabb : getCollisionBoxes(this.getActualState(state, world, pos))) { + for (AxisAlignedBB aabb : getAllCollisionBoxes(world.getTileEntity(pos), this.getActualState(state, world, pos))) { addCollisionBoxToList(pos, entityBox, collidingBoxes, aabb); } } @@ -175,7 +282,7 @@ public class BlockCable extends BlockNode { @Override @SuppressWarnings("deprecation") public RayTraceResult collisionRayTrace(IBlockState state, World world, BlockPos pos, Vec3d start, Vec3d end) { - RenderUtils.AdvancedRayTraceResult result = RenderUtils.collisionRayTrace(pos, start, end, getCollisionBoxes(this.getActualState(state, world, pos))); + RenderUtils.AdvancedRayTraceResult result = RenderUtils.collisionRayTrace(pos, start, end, getAllCollisionBoxes(world.getTileEntity(pos), this.getActualState(state, world, pos))); return result != null ? result.hit : null; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockConstructor.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockConstructor.java index 1fc1c1115..ee6e5beb2 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockConstructor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockConstructor.java @@ -17,13 +17,6 @@ import java.util.ArrayList; import java.util.List; public class BlockConstructor extends BlockCable { - public static final AxisAlignedBB HOLDER_NORTH_AABB = RenderUtils.getBounds(7, 7, 2, 9, 9, 6); - public static final AxisAlignedBB HOLDER_EAST_AABB = RenderUtils.getBounds(10, 7, 7, 14, 9, 9); - public static final AxisAlignedBB HOLDER_SOUTH_AABB = RenderUtils.getBounds(7, 7, 10, 9, 9, 14); - public static final AxisAlignedBB HOLDER_WEST_AABB = RenderUtils.getBounds(2, 7, 7, 6, 9, 9); - public static final AxisAlignedBB HOLDER_UP_AABB = RenderUtils.getBounds(7, 10, 7, 9, 14, 9); - public static final AxisAlignedBB HOLDER_DOWN_AABB = RenderUtils.getBounds(7, 2, 7, 9, 6, 9); - public static final AxisAlignedBB HEAD_NORTH_AABB = RenderUtils.getBounds(0, 0, 0, 16, 16, 2); public static final AxisAlignedBB HEAD_EAST_AABB = RenderUtils.getBounds(14, 0, 0, 16, 16, 16); public static final AxisAlignedBB HEAD_SOUTH_AABB = RenderUtils.getBounds(0, 0, 14, 16, 16, 16); @@ -36,7 +29,7 @@ public class BlockConstructor extends BlockCable { } @Override - public List getNonUnionizedCollisionBoxes(IBlockState state) { + public List getCollisionBoxes(TileEntity tile, IBlockState state) { List boxes = new ArrayList<>(); switch (state.getValue(getDirection().getProperty())) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockDestructor.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockDestructor.java index d10aad164..ec27d78e6 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockDestructor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockDestructor.java @@ -26,8 +26,8 @@ public class BlockDestructor extends BlockCable { } @Override - public List getNonUnionizedCollisionBoxes(IBlockState state) { - return RSBlocks.CONSTRUCTOR.getNonUnionizedCollisionBoxes(state); + public List getCollisionBoxes(TileEntity tile, IBlockState state) { + return RSBlocks.CONSTRUCTOR.getCollisionBoxes(tile, state); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExporter.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExporter.java index f9720d20d..cda493a41 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExporter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExporter.java @@ -41,7 +41,7 @@ public class BlockExporter extends BlockCable { } @Override - public List getNonUnionizedCollisionBoxes(IBlockState state) { + public List getCollisionBoxes(TileEntity tile, IBlockState state) { List boxes = new ArrayList<>(); switch (state.getValue(getDirection().getProperty())) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExternalStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExternalStorage.java index 7e49ccb60..c3f5525b9 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExternalStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockExternalStorage.java @@ -31,32 +31,32 @@ public class BlockExternalStorage extends BlockCable { } @Override - public List getNonUnionizedCollisionBoxes(IBlockState state) { + public List getCollisionBoxes(TileEntity tile, IBlockState state) { List boxes = new ArrayList<>(); switch (state.getValue(getDirection().getProperty())) { case NORTH: - boxes.add(BlockConstructor.HOLDER_NORTH_AABB); + boxes.add(HOLDER_NORTH_AABB); boxes.add(HEAD_NORTH_AABB); break; case EAST: - boxes.add(BlockConstructor.HOLDER_EAST_AABB); + boxes.add(HOLDER_EAST_AABB); boxes.add(HEAD_EAST_AABB); break; case SOUTH: - boxes.add(BlockConstructor.HOLDER_SOUTH_AABB); + boxes.add(HOLDER_SOUTH_AABB); boxes.add(HEAD_SOUTH_AABB); break; case WEST: - boxes.add(BlockConstructor.HOLDER_WEST_AABB); + boxes.add(HOLDER_WEST_AABB); boxes.add(HEAD_WEST_AABB); break; case UP: - boxes.add(BlockConstructor.HOLDER_UP_AABB); + boxes.add(HOLDER_UP_AABB); boxes.add(HEAD_UP_AABB); break; case DOWN: - boxes.add(BlockConstructor.HOLDER_DOWN_AABB); + boxes.add(HOLDER_DOWN_AABB); boxes.add(HEAD_DOWN_AABB); break; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockImporter.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockImporter.java index 8e473359a..fe3d68c69 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockImporter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockImporter.java @@ -41,7 +41,7 @@ public class BlockImporter extends BlockCable { } @Override - public List getNonUnionizedCollisionBoxes(IBlockState state) { + public List getCollisionBoxes(TileEntity tile, IBlockState state) { List boxes = new ArrayList<>(); switch (state.getValue(getDirection().getProperty())) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockReader.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockReader.java index 7b1514883..38efd1506 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockReader.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockReader.java @@ -24,8 +24,8 @@ public class BlockReader extends BlockCable { } @Override - public List getNonUnionizedCollisionBoxes(IBlockState state) { - return RSBlocks.CONSTRUCTOR.getNonUnionizedCollisionBoxes(state); + public List getCollisionBoxes(TileEntity tile, IBlockState state) { + return RSBlocks.CONSTRUCTOR.getCollisionBoxes(tile, state); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockWriter.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockWriter.java index f5d0eca71..053c3848f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockWriter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockWriter.java @@ -25,8 +25,8 @@ public class BlockWriter extends BlockCable { } @Override - public List getNonUnionizedCollisionBoxes(IBlockState state) { - return RSBlocks.CONSTRUCTOR.getNonUnionizedCollisionBoxes(state); + public List getCollisionBoxes(TileEntity tile, IBlockState state) { + return RSBlocks.CONSTRUCTOR.getCollisionBoxes(tile, state); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemCover.java b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemCover.java new file mode 100644 index 000000000..bccd2425c --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemCover.java @@ -0,0 +1,101 @@ +package com.raoulvdberge.refinedstorage.item; + +import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; +import com.raoulvdberge.refinedstorage.api.network.security.Permission; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable; +import com.raoulvdberge.refinedstorage.tile.TileNode; +import com.raoulvdberge.refinedstorage.util.WorldUtils; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class ItemCover extends ItemBase { + private static final String NBT_ITEM = "Item"; + + public ItemCover() { + super("cover"); + } + + public static void setItem(ItemStack cover, ItemStack item) { + if (!cover.hasTagCompound()) { + cover.setTagCompound(new NBTTagCompound()); + } + + cover.getTagCompound().setTag(NBT_ITEM, item.serializeNBT()); + } + + @Nonnull + public static ItemStack getItem(ItemStack cover) { + if (!cover.hasTagCompound() || !cover.getTagCompound().hasKey(NBT_ITEM)) { + return ItemStack.EMPTY; + } + + return new ItemStack(cover.getTagCompound().getCompoundTag(NBT_ITEM)); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + super.addInformation(stack, world, tooltip, flag); + + ItemStack item = getItem(stack); + + if (!item.isEmpty()) { + tooltip.add(item.getItem().getItemStackDisplayName(item)); + } + } + + @Override + public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + ItemStack stack = player.getHeldItem(hand); + + TileEntity tile = world.getTileEntity(pos); + + // Support placing on the bottom side without too much hassle. + if (!canPlaceOn(tile)) { + pos = pos.up(); + + facing = EnumFacing.DOWN; + + tile = world.getTileEntity(pos); + } + + if (canPlaceOn(tile)) { + if (world.isRemote) { + return EnumActionResult.SUCCESS; + } + + INetworkNode node = ((TileNode) tile).getNode(); + + if (node.getNetwork() != null && !node.getNetwork().getSecurityManager().hasPermission(Permission.BUILD, player)) { + return EnumActionResult.FAIL; + } + + if (((ICoverable) node).getCoverManager().setCover(facing, getItem(stack))) { + player.getHeldItem(hand).shrink(1); + + WorldUtils.updateBlock(world, pos); + + return EnumActionResult.SUCCESS; + } + + return EnumActionResult.FAIL; + } + + return EnumActionResult.PASS; + } + + private boolean canPlaceOn(TileEntity tile) { + return tile instanceof TileNode && ((TileNode) tile).getNode() instanceof ICoverable; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java index 1392ef1f4..fe83ea842 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java @@ -15,7 +15,14 @@ import com.raoulvdberge.refinedstorage.gui.grid.GuiCraftingStart; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase; import com.raoulvdberge.refinedstorage.item.*; import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreviewResponse; -import com.raoulvdberge.refinedstorage.render.*; +import com.raoulvdberge.refinedstorage.render.model.ModelDiskDrive; +import com.raoulvdberge.refinedstorage.render.model.ModelDiskManipulator; +import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelCableCover; +import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelCover; +import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelPattern; +import com.raoulvdberge.refinedstorage.render.model.loader.CustomModelLoaderDefault; +import com.raoulvdberge.refinedstorage.render.statemapper.StateMapperCTM; +import com.raoulvdberge.refinedstorage.render.tesr.TileEntitySpecialRendererStorageMonitor; import com.raoulvdberge.refinedstorage.tile.TileController; import com.raoulvdberge.refinedstorage.tile.TileStorageMonitor; import com.raoulvdberge.refinedstorage.tile.grid.portable.IPortableGrid; @@ -76,7 +83,7 @@ public class ProxyClient extends ProxyCommon { itemColors.registerItemColorHandler((stack, tintIndex) -> { CraftingPattern pattern = ItemPattern.getPatternFromCache(Minecraft.getMinecraft().world, stack); - if (BakedModelPattern.canDisplayPatternOutput(stack, pattern)) { + if (BakedModelPattern.canDisplayOutput(stack, pattern)) { int color = itemColors.colorMultiplier(pattern.getOutputs().get(0), tintIndex); if (color != -1) { @@ -121,13 +128,13 @@ public class ProxyClient extends ProxyCommon { ); ModelBakery.registerItemVariants(RSItems.PROCESSOR, - new ResourceLocation("refinedstorage:basic_printed_processor"), - new ResourceLocation("refinedstorage:improved_printed_processor"), - new ResourceLocation("refinedstorage:advanced_printed_processor"), + new ResourceLocation("refinedstorage:cut_basic_processor"), + new ResourceLocation("refinedstorage:cut_improved_processor"), + new ResourceLocation("refinedstorage:cut_advanced_processor"), new ResourceLocation("refinedstorage:basic_processor"), new ResourceLocation("refinedstorage:improved_processor"), new ResourceLocation("refinedstorage:advanced_processor"), - new ResourceLocation("refinedstorage:printed_silicon") + new ResourceLocation("refinedstorage:cut_silicon") ); ModelBakery.registerItemVariants(RSItems.CORE, @@ -223,6 +230,7 @@ public class ProxyClient extends ProxyCommon { ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RSBlocks.DISK_MANIPULATOR), 0, new ModelResourceLocation("refinedstorage:disk_manipulator", "inventory")); ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RSBlocks.QUARTZ_ENRICHED_IRON), 0, new ModelResourceLocation("refinedstorage:quartz_enriched_iron_block", "inventory")); ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RSBlocks.STORAGE_MONITOR), 0, new ModelResourceLocation("refinedstorage:storage_monitor", "connected=false,direction=north")); + ModelLoader.setCustomModelResourceLocation(RSItems.COVER, 0, new ModelResourceLocation("refinedstorage:cover", "inventory")); ModelLoaderRegistry.registerLoader(new CustomModelLoaderDefault(new ResourceLocation(RS.ID, "disk_drive"), ModelDiskDrive::new)); ModelLoaderRegistry.registerLoader(new CustomModelLoaderDefault(new ResourceLocation(RS.ID, "disk_manipulator"), ModelDiskManipulator::new)); @@ -364,6 +372,10 @@ public class ProxyClient extends ProxyCommon { if (model.getResourceDomain().equals(RS.ID)) { if (model.getResourcePath().equals("pattern")) { e.getModelRegistry().putObject(model, new BakedModelPattern(e.getModelRegistry().getObject(model))); + } else if (model.getResourcePath().equals("cable")) { + e.getModelRegistry().putObject(model, new BakedModelCableCover(e.getModelRegistry().getObject(model))); + } else if (model.getResourcePath().equals("cover")) { + e.getModelRegistry().putObject(model, new BakedModelCover(e.getModelRegistry().getObject(model), null)); } } } @@ -393,8 +405,8 @@ public class ProxyClient extends ProxyCommon { return; } - List unionized = cable.getUnionizedCollisionBoxes(state); - List nonUnionized = cable.getNonUnionizedCollisionBoxes(state); + List combinedBoxes = cable.getCombinedCollisionBoxes(state); + List boxes = cable.getCollisionBoxes(player.world.getTileEntity(pos), state); e.setCanceled(true); @@ -409,15 +421,15 @@ public class ProxyClient extends ProxyCommon { double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) e.getPartialTicks(); double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) e.getPartialTicks(); - AxisAlignedBB unionizedAabb = unionized.get(0); + AxisAlignedBB combinedAabb = combinedBoxes.get(0); - for (int i = 1; i < unionized.size(); ++i) { - unionizedAabb = unionizedAabb.union(unionized.get(i)); + for (int i = 1; i < combinedBoxes.size(); ++i) { + combinedAabb = combinedAabb.union(combinedBoxes.get(i)); } - drawSelectionBoundingBox(unionizedAabb.expand(0.0020000000949949026D, 0.0020000000949949026D, 0.0020000000949949026D).offset(-d0, -d1, -d2).offset(pos.getX(), pos.getY(), pos.getZ())); + drawSelectionBoundingBox(combinedAabb.expand(0.0020000000949949026D, 0.0020000000949949026D, 0.0020000000949949026D).offset(-d0, -d1, -d2).offset(pos.getX(), pos.getY(), pos.getZ())); - for (AxisAlignedBB aabb : nonUnionized) { + for (AxisAlignedBB aabb : boxes) { drawSelectionBoundingBox(aabb.expand(0.0020000000949949026D, 0.0020000000949949026D, 0.0020000000949949026D).offset(-d0, -d1, -d2).offset(pos.getX(), pos.getY(), pos.getZ())); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java index 23ed2b485..2cd9d0bfd 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java @@ -42,6 +42,7 @@ import com.raoulvdberge.refinedstorage.integration.oc.DriverNetwork; import com.raoulvdberge.refinedstorage.integration.oc.IntegrationOC; import com.raoulvdberge.refinedstorage.item.ItemProcessor; import com.raoulvdberge.refinedstorage.network.*; +import com.raoulvdberge.refinedstorage.recipe.RecipeCover; import com.raoulvdberge.refinedstorage.tile.*; import com.raoulvdberge.refinedstorage.tile.craftingmonitor.TileCraftingMonitor; import com.raoulvdberge.refinedstorage.tile.data.TileDataManager; @@ -59,6 +60,7 @@ import net.minecraft.inventory.Container; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; @@ -260,6 +262,7 @@ public class ProxyCommon { registerItem(RSItems.FILTER); registerItem(RSItems.NETWORK_CARD); registerItem(RSItems.SECURITY_CARD); + registerItem(RSItems.COVER); IntegrationInventorySorter.register(); } @@ -304,6 +307,11 @@ public class ProxyCommon { itemsToRegister.forEach(e.getRegistry()::register); } + @SubscribeEvent + public void registerRecipes(RegistryEvent.Register e) { + e.getRegistry().register(new RecipeCover().setRegistryName(new ResourceLocation(RS.ID, "cover"))); + } + @SubscribeEvent public void onHarvestCheck(PlayerEvent.HarvestCheck e) { if (e.getTargetBlock().getBlock() instanceof BlockBase) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/recipe/RecipeCover.java b/src/main/java/com/raoulvdberge/refinedstorage/recipe/RecipeCover.java new file mode 100644 index 000000000..a5772317a --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/recipe/RecipeCover.java @@ -0,0 +1,72 @@ +package com.raoulvdberge.refinedstorage.recipe; + +import com.raoulvdberge.refinedstorage.RSItems; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager; +import com.raoulvdberge.refinedstorage.item.ItemCover; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.world.World; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.registries.IForgeRegistryEntry; + +public class RecipeCover extends IForgeRegistryEntry.Impl implements IRecipe { + @Override + public boolean matches(InventoryCrafting inv, World world) { + boolean hadCuttingTool = false; + boolean hadItem = false; + + for (int i = 0; i < inv.getSizeInventory(); ++i) { + ItemStack slot = inv.getStackInSlot(i); + + if (!slot.isEmpty() && hadCuttingTool && hadItem) { + return false; + } + + if (slot.getItem() == RSItems.CUTTING_TOOL) { + if (hadCuttingTool) { + return false; + } + + hadCuttingTool = true; + } + + if (CoverManager.isValidCover(slot)) { + if (hadItem) { + return false; + } + + hadItem = true; + } + } + + return hadCuttingTool && hadItem; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + for (int i = 0; i < inv.getSizeInventory(); ++i) { + ItemStack slot = inv.getStackInSlot(i); + + if (CoverManager.isValidCover(slot)) { + ItemStack cover = new ItemStack(RSItems.COVER, 6); + + ItemCover.setItem(cover, ItemHandlerHelper.copyStackWithSize(slot, 1)); + + return cover; + } + } + + return ItemStack.EMPTY; + } + + @Override + public boolean canFit(int width, int height) { + return true; + } + + @Override + public ItemStack getRecipeOutput() { + return ItemStack.EMPTY; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/QuadBuilder.java b/src/main/java/com/raoulvdberge/refinedstorage/render/QuadBuilder.java new file mode 100644 index 000000000..f1e9b90ba --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/QuadBuilder.java @@ -0,0 +1,518 @@ +package com.raoulvdberge.refinedstorage.render; + +import com.google.common.collect.Maps; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; +import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; + +import javax.vecmath.Vector4f; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @link https://github.com/ArekkuusuJerii/Solar + */ +public class QuadBuilder { + private final Map facingMap = Maps.newEnumMap(EnumFacing.class); + private final VertexFormat format; + private boolean hasBrightness; + private Vector3 from; + private Vector3 to; + private EnumFacing last; + + private QuadBuilder(VertexFormat format) { + this.format = format; + } + + public static QuadBuilder withFormat(VertexFormat format) { + return new QuadBuilder(format); + } + + public QuadBuilder setFrom(double x, double y, double z) { + this.from = Vector3.create(x, y, z); + return this; + } + + public QuadBuilder setTo(double x, double y, double z) { + this.to = Vector3.create(x, y, z); + return this; + } + + public QuadBuilder setHasBrightness(boolean hasBrightness) { + this.hasBrightness = hasBrightness; + return this; + } + + public QuadBuilder addAll(TextureAtlasSprite sprite) { + for (EnumFacing facing : EnumFacing.values()) { + addFace(facing, 0F, 16F, 0F, 16F, sprite); + } + return this; + } + + public QuadBuilder addAll(float uMin, float uMax, float vMin, float vMax, TextureAtlasSprite sprite) { + for (EnumFacing facing : EnumFacing.values()) { + addFace(facing, uMin, uMax, vMin, vMax, sprite); + } + return this; + } + + public QuadBuilder addFace(EnumFacing facing, float uMin, float uMax, float vMin, float vMax, TextureAtlasSprite sprite) { + QuadHolder holder = new QuadHolder(); + + holder.uv = new Vector4f(uMin, uMax, vMin, vMax); + + Vector3 a = Vector3.create(0, 0, 0); + Vector3 b = Vector3.create(0, 0, 0); + Vector3 c = Vector3.create(0, 0, 0); + Vector3 d = Vector3.create(0, 0, 0); + + holder.sprite = sprite; + + switch (facing) { + case DOWN: + a.x = to.x; + a.y = from.y; + a.z = from.z; + + b.x = to.x; + b.y = from.y; + b.z = to.z; + + c.x = from.x; + c.y = from.y; + c.z = to.z; + + d.x = from.x; + d.y = from.y; + d.z = from.z; + break; + case UP: + a.x = from.x; + a.y = to.y; + a.z = from.z; + + b.x = from.x; + b.y = to.y; + b.z = to.z; + + c.x = to.x; + c.y = to.y; + c.z = to.z; + + d.x = to.x; + d.y = to.y; + d.z = from.z; + break; + case NORTH: + a.x = to.x; + a.y = from.y; + a.z = to.z; + + b.x = to.x; + b.y = to.y; + b.z = to.z; + + c.x = from.x; + c.y = to.y; + c.z = to.z; + + d.x = from.x; + d.y = from.y; + d.z = to.z; + break; + case SOUTH: + a.x = from.x; + a.y = from.y; + a.z = from.z; + + b.x = from.x; + b.y = to.y; + b.z = from.z; + + c.x = to.x; + c.y = to.y; + c.z = from.z; + + d.x = to.x; + d.y = from.y; + d.z = from.z; + break; + case WEST: + a.x = from.x; + a.y = from.y; + a.z = to.z; + + b.x = from.x; + b.y = to.y; + b.z = to.z; + + c.x = from.x; + c.y = to.y; + c.z = from.z; + + d.x = from.x; + d.y = from.y; + d.z = from.z; + break; + case EAST: + a.x = to.x; + a.y = from.y; + a.z = from.z; + + b.x = to.x; + b.y = to.y; + b.z = from.z; + + c.x = to.x; + c.y = to.y; + c.z = to.z; + + d.x = to.x; + d.y = from.y; + d.z = to.z; + break; + } + + holder.a = a.divide(16D); + holder.b = b.divide(16D); + holder.c = c.divide(16D); + holder.d = d.divide(16D); + + facingMap.put(facing, holder); + last = facing; + + return this; + } + + public QuadBuilder mirror() { + if (facingMap.containsKey(last)) { + Stream stream = Arrays.stream(facingMap.get(last).getVectors()); + switch (last) { + case DOWN: + case UP: + stream.forEach(vec -> vec.subtract(0.5D).rotate(EnumFacing.Axis.Y, 180).add(0.5D)); + break; + case NORTH: + case SOUTH: + stream.forEach(vec -> vec.subtract(0.5D).rotate(EnumFacing.Axis.X, 180).add(0.5D)); + break; + case EAST: + case WEST: + stream.forEach(vec -> vec.subtract(0.5D).rotate(EnumFacing.Axis.Z, 180).add(0.5D)); + break; + } + } + + return this; + } + + public QuadBuilder clear() { + facingMap.clear(); + + return this; + } + + public QuadBuilder rotate(EnumFacing facing, EnumFacing... exclude) { + if (exclude == null || !Arrays.asList(exclude).contains(facing)) { + switch (facing) { + case DOWN: + rotate(EnumFacing.Axis.X, 180F); + break; + case UP: + rotate(EnumFacing.Axis.X, 180F); + break; + default: + rotate(EnumFacing.Axis.X, 90F); + rotate(EnumFacing.Axis.Y, -facing.getHorizontalAngle()); + rotate(EnumFacing.Axis.Y, -90F); + } + } + + return this; + } + + public QuadBuilder rotate(EnumFacing.Axis axis, float angle) { + facingMap.values().forEach(holder -> { + Arrays.stream(holder.getVectors()).forEach(vec -> { + vec.subtract(0.5D).rotate(axis, angle).add(0.5D); + }); + }); + + return this; + } + + public List bake() { + return facingMap.entrySet().stream().map(e -> createQuad(e.getValue(), e.getKey())).collect(Collectors.toList()); + } + + private BakedQuad createQuad(QuadHolder holder, EnumFacing facing) { + Vector4f uv = holder.uv; + + Vector3 a = holder.a; + Vector3 b = holder.b; + Vector3 c = holder.c; + Vector3 d = holder.d; + + Vector3 normal = c.copy().subtract(b).cross(a.copy().subtract(b)).normalize(); + + UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format); + + putVertex(builder, normal, a.x, a.y, a.z, holder.sprite, uv.y, uv.w, hasBrightness); + putVertex(builder, normal, b.x, b.y, b.z, holder.sprite, uv.y, uv.z, hasBrightness); + putVertex(builder, normal, c.x, c.y, c.z, holder.sprite, uv.x, uv.z, hasBrightness); + putVertex(builder, normal, d.x, d.y, d.z, holder.sprite, uv.x, uv.w, hasBrightness); + + builder.setQuadOrientation(facing); + builder.setTexture(holder.sprite); + + return builder.build(); + } + + private void putVertex(UnpackedBakedQuad.Builder builder, Vector3 normal, double x, double y, double z, TextureAtlasSprite sprite, float u, float v, boolean hasBrightness) { + for (int e = 0; e < format.getElementCount(); e++) { + switch (format.getElement(e).getUsage()) { + case POSITION: + builder.put(e, (float) x, (float) y, (float) z, 1F); + break; + case COLOR: + builder.put(e, 1F, 1F, 1F, 1F); + break; + case UV: + if (format.getElement(e).getIndex() == 1) { + if (hasBrightness) { + builder.put(e, 1F, 1F); + } else { + builder.put(e, 0F, 0F); + } + break; + } else if (format.getElement(e).getIndex() == 0) { + u = sprite.getInterpolatedU(u); + v = sprite.getInterpolatedV(v); + builder.put(e, u, v, 0F, 1F); + break; + } + case NORMAL: + if (hasBrightness) { + builder.put(e, 0F, 1F, 0F); + } else { + builder.put(e, (float) normal.x, (float) normal.y, (float) normal.z); + } + break; + default: + builder.put(e); + break; + } + } + } + + private class QuadHolder { + private TextureAtlasSprite sprite; + + private Vector3 a; + private Vector3 b; + private Vector3 c; + private Vector3 d; + + private Vector4f uv; + + public Vector3[] getVectors() { + return new Vector3[]{a, b, c, d}; + } + } + + private static class Vector3 { + private double x; + private double y; + private double z; + + public static Vector3 create(double x, double y, double z) { + return new Vector3(x, y, z); + } + + public static Vector3 create(Vec3d vec) { + return new Vector3(vec.x, vec.y, vec.z); + } + + private Vector3(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3 setVec(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + + return this; + } + + public Vector3 subtract(Vector3 vec) { + return subtract(vec.x, vec.y, vec.z); + } + + public Vector3 subtract(Vec3d vec) { + return subtract(vec.x, vec.y, vec.z); + } + + public Vector3 subtract(Vec3i vec) { + return subtract(vec.getX(), vec.getY(), vec.getZ()); + } + + public Vector3 subtract(double amount) { + return subtract(amount, amount, amount); + } + + public Vector3 subtract(double x, double y, double z) { + return add(-x, -y, -z); + } + + public Vector3 add(Vector3 vec) { + return add(vec.x, vec.y, vec.z); + } + + public Vector3 add(Vec3d vec) { + return add(vec.x, vec.y, vec.z); + } + + public Vector3 add(Vec3i vec) { + return add(vec.getX(), vec.getY(), vec.getZ()); + } + + public Vector3 add(double amount) { + return add(amount, amount, amount); + } + + public Vector3 add(double x, double y, double z) { + return setVec(this.x + x, this.y + y, this.z + z); + } + + public Vector3 multiply(Vector3 vec) { + return multiply(vec.x, vec.y, vec.z); + } + + public Vector3 multiply(double m) { + return multiply(m, m, m); + } + + public Vector3 multiply(double x, double y, double z) { + return setVec(this.x * x, this.y * y, this.z * z); + } + + public Vector3 divide(Vector3 vec) { + return divide(vec.x, vec.y, vec.z); + } + + public Vector3 divide(double m) { + return divide(m, m, m); + } + + public Vector3 divide(double x, double y, double z) { + return setVec(this.x / x, this.y / y, this.z / z); + } + + public Vector3 rotate(EnumFacing.Axis axis, float degrees) { + float radians = degrees * (float) (Math.PI / 180D); + switch (axis) { + case X: + rotatePitchX(radians); + break; + case Y: + rotateYaw(radians); + break; + case Z: + rotatePitchZ(radians); + break; + } + + return this; + } + + public Vector3 rotateYaw(float radians) { + float cos = MathHelper.cos(radians); + float sin = MathHelper.sin(radians); + double x = this.x * cos + this.z * sin; + double z = this.z * cos - this.x * sin; + return setVec(x, y, z); + } + + public Vector3 rotatePitchZ(float radians) { + float cos = MathHelper.cos(radians); + float sin = MathHelper.sin(radians); + double y = this.y * cos + this.z * sin; + double z = this.z * cos - this.y * sin; + return setVec(x, y, z); + } + + public Vector3 rotatePitchX(float radians) { + float cos = MathHelper.cos(radians); + float sin = MathHelper.sin(radians); + double y = this.y * cos + this.x * sin; + double x = this.x * cos - this.y * sin; + return setVec(x, y, z); + } + + public Vector3 rotate(Rotation rotation) { + switch (rotation) { + case NONE: + default: + return this; + case CLOCKWISE_90: + return setVec(-z, y, x); + case CLOCKWISE_180: + return setVec(-x, y, -z); + case COUNTERCLOCKWISE_90: + return setVec(z, y, -x); + } + } + + public Vector3 offset(EnumFacing facing, float amount) { + return setVec(x + facing.getFrontOffsetX() * amount, y + facing.getFrontOffsetY() * amount, z + facing.getFrontOffsetZ() * amount); + } + + public Vector3 normalize() { + double root = MathHelper.sqrt(x * x + y * y + z * z); + + return root < 1.0E-4D ? setVec(0, 0, 0) : setVec(x / root, y / root, z / root); + } + + public Vector3 cross(Vector3 vec) { + double x = this.y * vec.z - this.z * vec.y; + double y = this.z * vec.x - this.x * vec.z; + double z = this.x * vec.y - this.y * vec.x; + + return setVec(x, y, z); + } + + public double distanceTo(Vector3 vec) { + double xDiff = x - vec.x; + double yDiff = y - vec.y; + double zDiff = z - vec.z; + + return MathHelper.sqrt(xDiff * xDiff + yDiff * yDiff + zDiff * zDiff); + } + + public Vector3 limit(double max) { + double x = this.x > max ? max : this.x < -max ? -max : this.x; + double y = this.y > max ? max : this.y < -max ? -max : this.y; + double z = this.z > max ? max : this.z < -max ? -max : this.z; + + return setVec(x, y, z); + } + + public Vector3 copy() { + return new Vector3(x, y, z); + } + } +} + diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/ModelDiskDrive.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/ModelDiskDrive.java old mode 100755 new mode 100644 similarity index 95% rename from src/main/java/com/raoulvdberge/refinedstorage/render/ModelDiskDrive.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/model/ModelDiskDrive.java index 13e232c29..7aa686166 --- a/src/main/java/com/raoulvdberge/refinedstorage/render/ModelDiskDrive.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/ModelDiskDrive.java @@ -1,5 +1,6 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.model; +import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelDiskDrive; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/ModelDiskManipulator.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/ModelDiskManipulator.java old mode 100755 new mode 100644 similarity index 96% rename from src/main/java/com/raoulvdberge/refinedstorage/render/ModelDiskManipulator.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/model/ModelDiskManipulator.java index 18fa8c53f..3dc667cab --- a/src/main/java/com/raoulvdberge/refinedstorage/render/ModelDiskManipulator.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/ModelDiskManipulator.java @@ -1,5 +1,6 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.model; +import com.raoulvdberge.refinedstorage.render.model.baked.BakedModelDiskManipulator; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelCableCover.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelCableCover.java new file mode 100644 index 000000000..c230b2155 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelCableCover.java @@ -0,0 +1,284 @@ +package com.raoulvdberge.refinedstorage.render.model.baked; + +import com.raoulvdberge.refinedstorage.RS; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager; +import com.raoulvdberge.refinedstorage.block.BlockCable; +import com.raoulvdberge.refinedstorage.render.QuadBuilder; +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.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.common.property.IExtendedBlockState; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.Nullable; +import javax.vecmath.Matrix4f; +import java.util.ArrayList; +import java.util.List; + +public class BakedModelCableCover implements IBakedModel { + private IBakedModel base; + private TextureAtlasSprite genericGreyTexture; + + public BakedModelCableCover(IBakedModel base) { + this.base = base; + } + + @Override + public List getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) { + List quads = new ArrayList<>(base.getQuads(state, side, rand)); + + if (state != null) { + IExtendedBlockState s = (IExtendedBlockState) state; + + addCover(quads, s.getValue(BlockCable.COVER_NORTH), EnumFacing.NORTH, side, rand, s); + addCover(quads, s.getValue(BlockCable.COVER_SOUTH), EnumFacing.SOUTH, side, rand, s); + addCover(quads, s.getValue(BlockCable.COVER_EAST), EnumFacing.EAST, side, rand, s); + addCover(quads, s.getValue(BlockCable.COVER_WEST), EnumFacing.WEST, side, rand, s); + addCover(quads, s.getValue(BlockCable.COVER_DOWN), EnumFacing.DOWN, side, rand, s); + addCover(quads, s.getValue(BlockCable.COVER_UP), EnumFacing.UP, side, rand, s); + } + + return quads; + } + + private void addCover(List quads, @Nullable ItemStack coverStack, EnumFacing coverSide, EnumFacing side, long rand, IExtendedBlockState state) { + if (coverStack == null) { + return; + } + + IBlockState coverState = CoverManager.getBlockState(coverStack); + + if (coverState == null) { + return; + } + + IBakedModel coverModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(coverState); + + TextureAtlasSprite sprite = getSprite(coverModel, coverState, side, rand); + + boolean hasUp = CoverManager.getBlockState(state.getValue(BlockCable.COVER_UP)) != null; + boolean hasDown = CoverManager.getBlockState(state.getValue(BlockCable.COVER_DOWN)) != null; + + boolean hasEast = CoverManager.getBlockState(state.getValue(BlockCable.COVER_EAST)) != null; + boolean hasWest = CoverManager.getBlockState(state.getValue(BlockCable.COVER_WEST)) != null; + + float handleAngle = 0; + EnumFacing.Axis handleAxis = EnumFacing.Axis.Y; + + if (coverSide == EnumFacing.NORTH) { + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(hasWest ? 2 : 0, hasDown ? 2 : 0, 0) + .setTo(hasEast ? 14 : 16, hasUp ? 14 : 16, 2) + + .addFace(EnumFacing.UP, 16, 0, 2, 0, sprite) + .addFace(EnumFacing.DOWN, 0, 16, 14, 16, sprite) + .addFace(EnumFacing.EAST, 14, 16, 0, 16, sprite) + .addFace(EnumFacing.WEST, 0, 2, 0, 16, sprite) + + .addFace(EnumFacing.NORTH, hasEast ? 2 : 0, hasWest ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + .addFace(EnumFacing.SOUTH, hasEast ? 2 : 0, hasWest ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + + .bake() + ); + } else if (coverSide == EnumFacing.SOUTH) { + handleAngle = 180; + + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(hasEast ? 14 : 16, hasDown ? 2 : 0, 16) + .setTo(hasWest ? 2 : 0, hasUp ? 14 : 16, 14) + + .addFace(EnumFacing.UP, 0, 16, 14, 16, sprite) + .addFace(EnumFacing.DOWN, 16, 0, 2, 0, sprite) + .addFace(EnumFacing.EAST, 14, 16, 0, 16, sprite) + .addFace(EnumFacing.WEST, 0, 2, 0, 16, sprite) + + .addFace(EnumFacing.NORTH, hasWest ? 2 : 0, hasEast ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + .addFace(EnumFacing.SOUTH, hasWest ? 2 : 0, hasEast ? 14 : 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + + .bake() + ); + } else if (coverSide == EnumFacing.EAST) { + handleAngle = 270; + + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(14, hasDown ? 2 : 0, 0) + .setTo(16, hasUp ? 14 : 16, 16) + + .addFace(EnumFacing.UP, 16, 14, 16, 0, sprite) + .addFace(EnumFacing.DOWN, 14, 16, 0, 16, sprite) + .addFace(EnumFacing.NORTH, 14, 16, 0, 16, sprite) + .addFace(EnumFacing.SOUTH, 0, 2, 0, 16, sprite) + + .addFace(EnumFacing.EAST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + .addFace(EnumFacing.WEST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + + .bake() + ); + } else if (coverSide == EnumFacing.WEST) { + handleAngle = 90; + + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(0, hasDown ? 2 : 0, 0) + .setTo(2, hasUp ? 14 : 16, 16) + + .addFace(EnumFacing.UP, 2, 0, 16, 0, sprite) + .addFace(EnumFacing.DOWN, 0, 2, 0, 16, sprite) + .addFace(EnumFacing.NORTH, 0, 2, 0, 16, sprite) + .addFace(EnumFacing.SOUTH, 14, 16, 0, 16, sprite) + + .addFace(EnumFacing.EAST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + .addFace(EnumFacing.WEST, 0, 16, hasUp ? 2 : 0, hasDown ? 14 : 16, sprite) + + .bake() + ); + } else if (coverSide == EnumFacing.DOWN) { + handleAxis = EnumFacing.Axis.Z; + handleAngle = 90; + + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(0, 0, 0) + .setTo(16, 2, 16) + + .addFace(EnumFacing.NORTH, 0, 16, 14, 16, sprite) + .addFace(EnumFacing.SOUTH, 0, 16, 14, 16, sprite) + .addFace(EnumFacing.EAST, 0, 16, 14, 16, sprite) + .addFace(EnumFacing.WEST, 0, 16, 14, 16, sprite) + + .addFace(EnumFacing.UP, 16, 0, 16, 0, sprite) + .addFace(EnumFacing.DOWN, 0, 16, 0, 16, sprite) + + .bake() + ); + } else if (coverSide == EnumFacing.UP) { + handleAxis = EnumFacing.Axis.Z; + handleAngle = 270; + + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(0, 14, 0) + .setTo(16, 16, 16) + + .addFace(EnumFacing.NORTH, 0, 16, 0, 2, sprite) + .addFace(EnumFacing.SOUTH, 0, 16, 0, 2, sprite) + .addFace(EnumFacing.EAST, 0, 16, 0, 2, sprite) + .addFace(EnumFacing.WEST, 0, 16, 0, 2, sprite) + + .addFace(EnumFacing.UP, 16, 0, 16, 0, sprite) + .addFace(EnumFacing.DOWN, 0, 16, 0, 16, sprite) + + .bake() + ); + } + + if (this.genericGreyTexture == null) { + this.genericGreyTexture = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(RS.ID + ":blocks/generic_grey"); + } + + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(7, 7, 2) + .setTo(9, 9, 6) + .addFace(EnumFacing.NORTH, 0, 0, 4, 4, genericGreyTexture) + .addFace(EnumFacing.EAST, 0, 0, 2, 4, genericGreyTexture) + .addFace(EnumFacing.SOUTH, 0, 0, 4, 4, genericGreyTexture) + .addFace(EnumFacing.WEST, 0, 0, 2, 4, genericGreyTexture) + .addFace(EnumFacing.UP, 0, 0, 4, 2, genericGreyTexture) + .addFace(EnumFacing.DOWN, 0, 0, 4, 2, genericGreyTexture) + .rotate(handleAxis, handleAngle) + .bake() + ); + } + + public static TextureAtlasSprite getSprite(IBakedModel coverModel, IBlockState coverState, EnumFacing facing, long rand) { + TextureAtlasSprite sprite = null; + + BlockRenderLayer originalLayer = MinecraftForgeClient.getRenderLayer(); + + try { + for (BlockRenderLayer layer : BlockRenderLayer.values()) { + ForgeHooksClient.setRenderLayer(layer); + + for (BakedQuad bakedQuad : coverModel.getQuads(coverState, facing, rand)) { + return bakedQuad.getSprite(); + } + + for (BakedQuad bakedQuad : coverModel.getQuads(coverState, null, rand)) { + if (sprite == null) { + sprite = bakedQuad.getSprite(); + } + + if (bakedQuad.getFace() == facing) { + return bakedQuad.getSprite(); + } + } + } + } catch (Exception e) { + // NO OP + } finally { + ForgeHooksClient.setRenderLayer(originalLayer); + } + + if (sprite == null) { + try { + sprite = coverModel.getParticleTexture(); + } catch (Exception e) { + // NO OP + } + } + + if (sprite == null) { + sprite = Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite(); + } + + return sprite; + } + + @Override + @SuppressWarnings("deprecation") + public ItemCameraTransforms getItemCameraTransforms() { + return base.getItemCameraTransforms(); + } + + @Override + public ItemOverrideList getOverrides() { + return base.getOverrides(); + } + + @Override + public boolean isAmbientOcclusion(IBlockState state) { + return base.isAmbientOcclusion(state); + } + + @Override + public Pair handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) { + return base.handlePerspective(cameraTransformType); + } + + @Override + public boolean isAmbientOcclusion() { + return base.isAmbientOcclusion(); + } + + @Override + public boolean isGui3d() { + return base.isGui3d(); + } + + @Override + public boolean isBuiltInRenderer() { + return base.isBuiltInRenderer(); + } + + @Override + public TextureAtlasSprite getParticleTexture() { + return base.getParticleTexture(); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelCover.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelCover.java new file mode 100644 index 000000000..6af75d692 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelCover.java @@ -0,0 +1,126 @@ +package com.raoulvdberge.refinedstorage.render.model.baked; + +import com.raoulvdberge.refinedstorage.apiimpl.network.node.cover.CoverManager; +import com.raoulvdberge.refinedstorage.item.ItemCover; +import com.raoulvdberge.refinedstorage.render.QuadBuilder; +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.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraftforge.client.ForgeHooksClient; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.Nullable; +import javax.vecmath.Matrix4f; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class BakedModelCover implements IBakedModel { + @Nullable + private ItemStack stack; + private IBakedModel base; + + public BakedModelCover(IBakedModel base, @Nullable ItemStack stack) { + this.base = base; + this.stack = stack; + } + + @Override + public List getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) { + List quads = new ArrayList<>(base.getQuads(state, side, rand)); + + TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite(); + + if (stack != null) { + ItemStack item = ItemCover.getItem(stack); + + if (!item.isEmpty()) { + IBlockState coverState = CoverManager.getBlockState(item); + + if (coverState != null) { + IBakedModel coverModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(coverState); + + sprite = BakedModelCableCover.getSprite(coverModel, coverState, side, rand); + } + } + } + + quads.addAll(QuadBuilder.withFormat(DefaultVertexFormats.ITEM) + .setFrom(0, 0, 0) + .setTo(16, 16, 2) + + .addFace(EnumFacing.UP, 16, 0, 2, 0, sprite) + .addFace(EnumFacing.DOWN, 0, 16, 14, 16, sprite) + .addFace(EnumFacing.EAST, 14, 16, 0, 16, sprite) + .addFace(EnumFacing.WEST, 0, 2, 0, 16, sprite) + + .addFace(EnumFacing.NORTH, 0, 16, 0, 16, sprite) + .addFace(EnumFacing.SOUTH, 0, 16, 0, 16, sprite) + + .bake() + ); + + return quads; + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() { + return base.getItemCameraTransforms(); + } + + @Override + public ItemOverrideList getOverrides() { + if (stack != null) { + return base.getOverrides(); + } + + return new ItemOverrideList(Collections.emptyList()) { + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity) { + return new BakedModelCover(base, stack); + } + }; + } + + @Override + public boolean isAmbientOcclusion(IBlockState state) { + return base.isAmbientOcclusion(state); + } + + @Override + public Pair handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) { + Pair matrix = base.handlePerspective(cameraTransformType); + Pair bakedModel = ForgeHooksClient.handlePerspective(this, cameraTransformType); + + return Pair.of(bakedModel.getKey(), matrix.getRight()); + } + + @Override + public boolean isAmbientOcclusion() { + return base.isAmbientOcclusion(); + } + + @Override + public boolean isGui3d() { + return base.isGui3d(); + } + + @Override + public boolean isBuiltInRenderer() { + return base.isBuiltInRenderer(); + } + + @Override + public TextureAtlasSprite getParticleTexture() { + return base.getParticleTexture(); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelDiskDrive.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelDiskDrive.java old mode 100755 new mode 100644 similarity index 99% rename from src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelDiskDrive.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelDiskDrive.java index 2feb8637b..8fde9a4a6 --- a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelDiskDrive.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelDiskDrive.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.model.baked; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelDiskManipulator.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelDiskManipulator.java old mode 100755 new mode 100644 similarity index 99% rename from src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelDiskManipulator.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelDiskManipulator.java index 7bab45e85..3395a3183 --- a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelDiskManipulator.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelDiskManipulator.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.model.baked; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelPattern.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelPattern.java old mode 100755 new mode 100644 similarity index 94% rename from src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelPattern.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelPattern.java index b221e2b0d..126d60e2f --- a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelPattern.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelPattern.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.model.baked; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternRenderHandler; import com.raoulvdberge.refinedstorage.apiimpl.API; @@ -75,7 +75,7 @@ public class BakedModelPattern implements IBakedModel { public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { CraftingPattern pattern = ItemPattern.getPatternFromCache(world, stack); - if (canDisplayPatternOutput(stack, pattern)) { + if (canDisplayOutput(stack, pattern)) { return Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides(pattern.getOutputs().get(0), world, entity); } @@ -84,7 +84,7 @@ public class BakedModelPattern implements IBakedModel { }; } - public static boolean canDisplayPatternOutput(ItemStack patternStack, CraftingPattern pattern) { + public static boolean canDisplayOutput(ItemStack patternStack, CraftingPattern pattern) { if (pattern.isValid() && pattern.getOutputs().size() == 1) { for (ICraftingPatternRenderHandler renderHandler : API.instance().getPatternRenderHandlers()) { if (renderHandler.canRenderOutput(patternStack)) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelTRSR.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelTRSR.java old mode 100755 new mode 100644 similarity index 99% rename from src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelTRSR.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelTRSR.java index 35366a45b..500b2e3ec --- a/src/main/java/com/raoulvdberge/refinedstorage/render/BakedModelTRSR.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/baked/BakedModelTRSR.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.model.baked; import com.google.common.collect.ImmutableList; import net.minecraft.block.state.IBlockState; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/CustomModelLoaderDefault.java b/src/main/java/com/raoulvdberge/refinedstorage/render/model/loader/CustomModelLoaderDefault.java similarity index 93% rename from src/main/java/com/raoulvdberge/refinedstorage/render/CustomModelLoaderDefault.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/model/loader/CustomModelLoaderDefault.java index 89496a465..5f946d08a 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/render/CustomModelLoaderDefault.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/model/loader/CustomModelLoaderDefault.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.model.loader; import net.minecraft.client.resources.IResourceManager; import net.minecraft.util.ResourceLocation; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/StateMapperCTM.java b/src/main/java/com/raoulvdberge/refinedstorage/render/statemapper/StateMapperCTM.java similarity index 92% rename from src/main/java/com/raoulvdberge/refinedstorage/render/StateMapperCTM.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/statemapper/StateMapperCTM.java index 0c4eb570f..661e577ec 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/render/StateMapperCTM.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/statemapper/StateMapperCTM.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.statemapper; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.block.model.ModelResourceLocation; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/render/TileEntitySpecialRendererStorageMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/render/tesr/TileEntitySpecialRendererStorageMonitor.java similarity index 99% rename from src/main/java/com/raoulvdberge/refinedstorage/render/TileEntitySpecialRendererStorageMonitor.java rename to src/main/java/com/raoulvdberge/refinedstorage/render/tesr/TileEntitySpecialRendererStorageMonitor.java index 40d22b8bd..9a0cd966e 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/render/TileEntitySpecialRendererStorageMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/render/tesr/TileEntitySpecialRendererStorageMonitor.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.render; +package com.raoulvdberge.refinedstorage.render.tesr; import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.tile.TileStorageMonitor; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java index af24abb7b..5ab33c2e3 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java @@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeManager; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy; import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.ICoverable; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode; import com.raoulvdberge.refinedstorage.apiimpl.util.OneSixMigrationHelper; import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy; @@ -15,6 +16,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.Constants; import net.minecraftforge.items.IItemHandler; import javax.annotation.Nonnull; @@ -24,6 +26,7 @@ public abstract class TileNode extends TileBase implement public static final TileDataParameter REDSTONE_MODE = RedstoneMode.createParameter(); protected static final String NBT_ACTIVE = "Active"; + private static final String NBT_COVERS = "Cover"; private N clientNode; @@ -46,6 +49,10 @@ public abstract class TileNode extends TileBase implement public NBTTagCompound writeUpdate(NBTTagCompound tag) { super.writeUpdate(tag); + if (getNode() instanceof ICoverable) { + tag.setTag(NBT_COVERS, ((ICoverable) getNode()).getCoverManager().writeToNbt()); + } + tag.setBoolean(NBT_ACTIVE, getNode().getNetwork() != null && getNode().canUpdate()); return tag; @@ -54,6 +61,10 @@ public abstract class TileNode extends TileBase implement public void readUpdate(NBTTagCompound tag) { super.readUpdate(tag); + if (getNode() instanceof ICoverable && tag.hasKey(NBT_COVERS)) { + ((ICoverable) getNode()).getCoverManager().readFromNbt(tag.getTagList(NBT_COVERS, Constants.NBT.TAG_COMPOUND)); + } + getNode().setActive(tag.getBoolean(NBT_ACTIVE)); } diff --git a/src/main/resources/assets/refinedstorage/blockstates/cover.json b/src/main/resources/assets/refinedstorage/blockstates/cover.json new file mode 100644 index 000000000..3608d114f --- /dev/null +++ b/src/main/resources/assets/refinedstorage/blockstates/cover.json @@ -0,0 +1,19 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "cable": "refinedstorage:blocks/cable", + "line": "refinedstorage:blocks/generic_grey" + }, + "model": "refinedstorage:cable_core", + "uvlock": true + }, + "variants": { + "inventory": [ + { + "model": "refinedstorage:cover", + "transform": "forge:default-block" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/refinedstorage/lang/en_us.lang b/src/main/resources/assets/refinedstorage/lang/en_us.lang index 53b357a1a..be08a4a1f 100644 --- a/src/main/resources/assets/refinedstorage/lang/en_us.lang +++ b/src/main/resources/assets/refinedstorage/lang/en_us.lang @@ -290,6 +290,7 @@ item.refinedstorage:network_card.name=Network Card2 item.refinedstorage:security_card.name=Security Card item.refinedstorage:security_card.owner=Bound to: %s item.refinedstorage:cutting_tool.name=Cutting Tool +item.refinedstorage:cover.name=Cover commands.refinedstorage.createdisk.usage=/createdisk commands.refinedstorage.createdisk.error.notADisk=The given disk item is not a disk. diff --git a/src/main/resources/assets/refinedstorage/models/block/cover.json b/src/main/resources/assets/refinedstorage/models/block/cover.json new file mode 100644 index 000000000..b2f72e6de --- /dev/null +++ b/src/main/resources/assets/refinedstorage/models/block/cover.json @@ -0,0 +1,143 @@ +{ + "__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)", + "elements": [ + { + "name": "Line1", + "from": [ + 7.0, + 7.0, + 2.0 + ], + "to": [ + 9.0, + 9.0, + 6.0 + ], + "faces": { + "north": { + "texture": "#line", + "uv": [ + 0.0, + 0.0, + 4.0, + 4.0 + ] + }, + "east": { + "texture": "#line", + "uv": [ + 0.0, + 0.0, + 2.0, + 4.0 + ] + }, + "south": { + "texture": "#line", + "uv": [ + 0.0, + 0.0, + 4.0, + 4.0 + ] + }, + "west": { + "texture": "#line", + "uv": [ + 0.0, + 0.0, + 2.0, + 4.0 + ] + }, + "up": { + "texture": "#line", + "uv": [ + 0.0, + 0.0, + 4.0, + 2.0 + ] + }, + "down": { + "texture": "#line", + "uv": [ + 0.0, + 0.0, + 4.0, + 2.0 + ] + } + } + }, + { + "name": "Core", + "from": [ + 6.0, + 6.0, + 6.0 + ], + "to": [ + 10.0, + 10.0, + 10.0 + ], + "faces": { + "north": { + "texture": "#cable", + "uv": [ + 6.0, + 6.0, + 10.0, + 10.0 + ] + }, + "east": { + "texture": "#cable", + "uv": [ + 6.0, + 6.0, + 10.0, + 10.0 + ] + }, + "south": { + "texture": "#cable", + "uv": [ + 6.0, + 6.0, + 10.0, + 10.0 + ] + }, + "west": { + "texture": "#cable", + "uv": [ + 6.0, + 6.0, + 10.0, + 10.0 + ] + }, + "up": { + "texture": "#cable", + "uv": [ + 6.0, + 6.0, + 10.0, + 10.0 + ] + }, + "down": { + "texture": "#cable", + "uv": [ + 6.0, + 6.0, + 10.0, + 10.0 + ] + } + } + } + ] +}