diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/BlockItemViewerHopping.java b/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/BlockItemViewerHopping.java new file mode 100644 index 000000000..e24388db2 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/BlockItemViewerHopping.java @@ -0,0 +1,130 @@ +/* + * This file ("BlockItemInterfaceHopping.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.blocks; + +import com.google.common.base.Predicate; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityItemViewerHopping; +import net.minecraft.block.properties.PropertyDirection; +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.tileentity.TileEntity; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.List; + +//Most of this is just copied from BlockHopper, no credit taken. Or clue what it is. +public class BlockItemViewerHopping extends BlockItemViewer{ + + public static final PropertyDirection FACING = PropertyDirection.create("facing", new Predicate(){ + @Override + public boolean apply(EnumFacing facing){ + return facing != EnumFacing.UP; + } + }); + + private static final AxisAlignedBB BASE_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.625D, 1.0D); + private static final AxisAlignedBB SOUTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D); + private static final AxisAlignedBB NORTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.875D, 1.0D, 1.0D, 1.0D); + private static final AxisAlignedBB WEST_AABB = new AxisAlignedBB(0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); + private static final AxisAlignedBB EAST_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D); + + public BlockItemViewerHopping(String name){ + super(name); + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ + return FULL_BLOCK_AABB; + } + + @Override + public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List collidingBoxes, Entity entityIn){ + addCollisionBoxToList(pos, entityBox, collidingBoxes, BASE_AABB); + addCollisionBoxToList(pos, entityBox, collidingBoxes, EAST_AABB); + addCollisionBoxToList(pos, entityBox, collidingBoxes, WEST_AABB); + addCollisionBoxToList(pos, entityBox, collidingBoxes, SOUTH_AABB); + addCollisionBoxToList(pos, entityBox, collidingBoxes, NORTH_AABB); + } + + @Override + public TileEntity createNewTileEntity(World worldIn, int meta){ + return new TileEntityItemViewerHopping(); + } + + @Override + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer){ + EnumFacing opp = facing.getOpposite(); + return this.getDefaultState().withProperty(FACING, opp == EnumFacing.UP ? EnumFacing.DOWN : opp); + } + + @Override + public boolean isFullyOpaque(IBlockState state){ + return true; + } + + @Override + public boolean isFullCube(IBlockState state){ + return false; + } + + @Override + public boolean isOpaqueCube(IBlockState state){ + return false; + } + + @Override + @SideOnly(Side.CLIENT) + public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side){ + return true; + } + + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getBlockLayer(){ + return BlockRenderLayer.CUTOUT_MIPPED; + } + + @Override + public IBlockState getStateFromMeta(int meta){ + return this.getDefaultState().withProperty(FACING, EnumFacing.getFront(meta)); + } + + @Override + public int getMetaFromState(IBlockState state){ + return state.getValue(FACING).getIndex(); + } + + @Override + protected BlockStateContainer createBlockState(){ + return new BlockStateContainer(this, FACING); + } + + @Override + public IBlockState withRotation(IBlockState state, Rotation rot){ + return state.withProperty(FACING, rot.rotate(state.getValue(FACING))); + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirror){ + return this.withRotation(state, mirror.toRotation(state.getValue(FACING))); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java b/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java index 9e4ae0b65..9ffec2737 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/blocks/InitBlocks.java @@ -86,6 +86,7 @@ public final class InitBlocks{ public static Block blockLaserRelayItem; public static Block blockLaserRelayItemWhitelist; public static Block blockItemViewer; + public static Block blockItemViewerHopping; public static Block blockBlackLotus; public static Block blockCrystal; public static Block blockCrystalEmpowered; @@ -112,6 +113,7 @@ public final class InitBlocks{ public static void init(){ ModUtil.LOGGER.info("Initializing Blocks..."); + blockItemViewerHopping = new BlockItemViewerHopping("block_item_viewer_hopping"); blockFarmer = new BlockFarmer("block_farmer"); blockBioReactor = new BlockBioReactor("block_bio_reactor"); blockDistributorItem = new BlockDistributorItem("block_distributor_item"); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java b/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java index dbcc741cc..29bb2da14 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/creative/CreativeTab.java @@ -66,6 +66,7 @@ public class CreativeTab extends CreativeTabs{ this.add(InitBlocks.blockLaserRelayItem); this.add(InitBlocks.blockLaserRelayItemWhitelist); this.add(InitBlocks.blockItemViewer); + this.add(InitBlocks.blockItemViewerHopping); this.add(InitBlocks.blockAtomicReconstructor); this.add(InitBlocks.blockEmpowerer); this.add(InitBlocks.blockPhantomface); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java index da6f7182d..5b3b395e1 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityBase.java @@ -119,6 +119,7 @@ public abstract class TileEntityBase extends TileEntity implements ITickable{ register(TileEntityDistributorItem.class); register(TileEntityBioReactor.class); register(TileEntityFarmer.class); + register(TileEntityItemViewerHopping.class); } private static void register(Class tileClass){ diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityInputter.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityInputter.java index 1f6e84c8b..6128a35a5 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityInputter.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityInputter.java @@ -80,7 +80,7 @@ public class TileEntityInputter extends TileEntityInventoryBase implements IButt if(cap != null){ for(int i = Math.max(this.slotToPullStart, 0); i < Math.min(this.slotToPullEnd, cap.getSlots()); i++){ if(this.checkBothFilters(cap.getStackInSlot(i), false)){ - if(WorldUtil.doItemInteraction(i, 0, this.placeToPull, this, side, null)){ + if(WorldUtil.doItemInteraction(i, 0, cap, this.slots, Integer.MAX_VALUE)){ return true; } } @@ -102,7 +102,7 @@ public class TileEntityInputter extends TileEntityInventoryBase implements IButt IItemHandler cap = this.placeToPut.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side); if(cap != null){ for(int i = Math.max(this.slotToPutStart, 0); i < Math.min(this.slotToPutEnd, cap.getSlots()); i++){ - if(WorldUtil.doItemInteraction(0, i, this, this.placeToPut, null, side)){ + if(WorldUtil.doItemInteraction(0, i, this.slots, cap, Integer.MAX_VALUE)){ return true; } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemViewer.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemViewer.java index 24ef03335..5215294da 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemViewer.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemViewer.java @@ -31,10 +31,10 @@ public class TileEntityItemViewer extends TileEntityBase{ private Network oldNetwork; private int lastNetworkChangeAmount = -1; - private final IItemHandler itemHandler; + protected final IItemHandler itemHandler; - public TileEntityItemViewer(){ - super("itemViewer"); + public TileEntityItemViewer(String name){ + super(name); this.itemHandler = new IItemHandler(){ @Override @@ -102,6 +102,10 @@ public class TileEntityItemViewer extends TileEntityBase{ }; } + public TileEntityItemViewer(){ + this("itemViewer"); + } + @Override public IItemHandler getItemHandler(EnumFacing facing){ return this.itemHandler; diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemViewerHopping.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemViewerHopping.java new file mode 100644 index 000000000..444774c9b --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemViewerHopping.java @@ -0,0 +1,104 @@ +/* + * This file ("TileEntityItemViewerHopping.java") is part of the Actually Additions mod for Minecraft. + * It is created and owned by Ellpeck and distributed + * under the Actually Additions License to be found at + * http://ellpeck.de/actaddlicense + * View the source code at https://github.com/Ellpeck/ActuallyAdditions + * + * © 2015-2016 Ellpeck + */ + +package de.ellpeck.actuallyadditions.mod.tile; + +import de.ellpeck.actuallyadditions.mod.util.ItemStackHandlerCustom; +import de.ellpeck.actuallyadditions.mod.util.StackUtil; +import de.ellpeck.actuallyadditions.mod.util.WorldUtil; +import net.minecraft.block.BlockHopper; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; + +import java.util.List; + +public class TileEntityItemViewerHopping extends TileEntityItemViewer{ + + private IItemHandler handlerToPullFrom; + private IItemHandler handlerToPushTo; + + public TileEntityItemViewerHopping(){ + super("itemViewerHopping"); + } + + @Override + public void updateEntity(){ + super.updateEntity(); + + if(!this.world.isRemote && this.world.getTotalWorldTime()%10 == 0){ + if(this.handlerToPullFrom != null){ + outer : for(int i = 0; i < this.handlerToPullFrom.getSlots(); i++){ + if(StackUtil.isValid(this.handlerToPullFrom.getStackInSlot(i))){ + for(int j = 0; j < this.itemHandler.getSlots(); j++){ + if(WorldUtil.doItemInteraction(i, j, this.handlerToPullFrom, this.itemHandler, 4)){ + break outer; + } + } + } + } + } + + if(this.handlerToPushTo != null){ + outer : for(int i = 0; i < this.itemHandler.getSlots(); i++){ + if(StackUtil.isValid(this.itemHandler.getStackInSlot(i))){ + for(int j = 0; j < this.handlerToPushTo.getSlots(); j++){ + if(WorldUtil.doItemInteraction(i, j, this.itemHandler, this.handlerToPushTo, 4)){ + break outer; + } + } + } + } + } + + if(this.world.getTotalWorldTime()%20 == 0){ + List items = this.world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(this.pos.getX(), this.pos.getY()+0.5, this.pos.getZ(), this.pos.getX()+1, this.pos.getY()+2, this.pos.getZ()+1)); + if(items != null && !items.isEmpty()){ + for(EntityItem item : items){ + if(item != null && !item.isDead){ + for(int i = 0; i < this.itemHandler.getSlots(); i++){ + ItemStack left = this.itemHandler.insertItem(i, item.getEntityItem(), false); + item.setEntityItemStack(left); + + if(!StackUtil.isValid(left)){ + item.setDead(); + break; + } + } + } + } + } + } + } + } + + @Override + public void saveDataOnChangeOrWorldStart(){ + super.saveDataOnChangeOrWorldStart(); + + TileEntity from = this.world.getTileEntity(this.pos.offset(EnumFacing.UP)); + if(from != null && !(from instanceof TileEntityItemViewer) && from.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN)){ + this.handlerToPullFrom = from.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN); + } + + IBlockState state = this.world.getBlockState(this.pos); + EnumFacing facing = state.getValue(BlockHopper.FACING); + + TileEntity to = this.world.getTileEntity(this.pos.offset(facing)); + if(to != null && !(to instanceof TileEntityItemViewer) && to.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite())){ + this.handlerToPushTo = to.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()); + } + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java b/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java index e901c62ab..1b48d0790 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java @@ -27,7 +27,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.play.client.CPacketPlayerDigging; import net.minecraft.network.play.server.SPacketBlockChange; 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; @@ -46,7 +45,6 @@ import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import java.util.ArrayList; @@ -54,19 +52,14 @@ import java.util.List; public final class WorldUtil{ - public static boolean doItemInteraction(int slotExtract, int slotInsert, TileEntity extract, TileEntity insert, EnumFacing extractSide, EnumFacing insertSide){ - if(extract.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, extractSide) && insert.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, insertSide)){ - IItemHandler extractCap = extract.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, extractSide); - IItemHandler insertCap = insert.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, insertSide); - - ItemStack theoreticalExtract = extractCap.extractItem(slotExtract, Integer.MAX_VALUE, true); - if(StackUtil.isValid(theoreticalExtract)){ - ItemStack remaining = insertCap.insertItem(slotInsert, theoreticalExtract, false); - if(!ItemStack.areItemStacksEqual(remaining, theoreticalExtract)){ - int toExtract = !StackUtil.isValid(remaining) ? StackUtil.getStackSize(theoreticalExtract) : StackUtil.getStackSize(theoreticalExtract)-StackUtil.getStackSize(remaining); - extractCap.extractItem(slotExtract, toExtract, false); - return true; - } + public static boolean doItemInteraction(int slotExtract, int slotInsert, IItemHandler extract, IItemHandler insert, int maxExtract){ + ItemStack theoreticalExtract = extract.extractItem(slotExtract, maxExtract, true); + if(StackUtil.isValid(theoreticalExtract)){ + ItemStack remaining = insert.insertItem(slotInsert, theoreticalExtract, false); + if(!ItemStack.areItemStacksEqual(remaining, theoreticalExtract)){ + int toExtract = !StackUtil.isValid(remaining) ? StackUtil.getStackSize(theoreticalExtract) : StackUtil.getStackSize(theoreticalExtract)-StackUtil.getStackSize(remaining); + extract.extractItem(slotExtract, toExtract, false); + return true; } } return false; diff --git a/src/main/resources/assets/actuallyadditions/blockstates/block_item_viewer_hopping.json b/src/main/resources/assets/actuallyadditions/blockstates/block_item_viewer_hopping.json new file mode 100644 index 000000000..eba7c0b80 --- /dev/null +++ b/src/main/resources/assets/actuallyadditions/blockstates/block_item_viewer_hopping.json @@ -0,0 +1,19 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "actuallyadditions:item_viewer_hopping_down", + "textures": { + "all": "actuallyadditions:blocks/block_item_viewer" + }, + "transform": "forge:default-block" + }, + "variants": { + "normal": [{}], + "inventory": [{}], + "facing=down": { "model": "actuallyadditions:item_viewer_hopping_down" }, + "facing=north": { "model": "actuallyadditions:item_viewer_hopping_side" }, + "facing=south": { "model": "actuallyadditions:item_viewer_hopping_side", "y": 180 }, + "facing=west": { "model": "actuallyadditions:item_viewer_hopping_side", "y": 270 }, + "facing=east": { "model": "actuallyadditions:item_viewer_hopping_side", "y": 90 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/actuallyadditions/lang/en_US.lang b/src/main/resources/assets/actuallyadditions/lang/en_US.lang index acbe113fc..c83c47dca 100644 --- a/src/main/resources/assets/actuallyadditions/lang/en_US.lang +++ b/src/main/resources/assets/actuallyadditions/lang/en_US.lang @@ -228,6 +228,7 @@ tile.actuallyadditions.block_pillar_quartz_slab.name=Black Quartz Pillar Slab tile.actuallyadditions.block_laser_relay_item.name=Item Laser Relay tile.actuallyadditions.block_laser_relay_item_whitelist.name=Advanced Item Laser Relay tile.actuallyadditions.block_item_viewer.name=Item Interface +tile.actuallyadditions.block_item_viewer_hopping.name=Hopping Item Interface tile.actuallyadditions.block_impure_iron.name=Impure Iron tile.actuallyadditions.block_booklet_stand.name=Wall-Mount Manual tile.actuallyadditions.block_display_stand.name=Display Stand diff --git a/src/main/resources/assets/actuallyadditions/models/block/item_viewer_hopping_down.json b/src/main/resources/assets/actuallyadditions/models/block/item_viewer_hopping_down.json new file mode 100644 index 000000000..62a3cdee8 --- /dev/null +++ b/src/main/resources/assets/actuallyadditions/models/block/item_viewer_hopping_down.json @@ -0,0 +1,88 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "actuallyadditions:blocks/block_item_viewer_hopping_outside", + "top": "actuallyadditions:blocks/block_item_viewer_hopping_top", + "side": "actuallyadditions:blocks/block_item_viewer_hopping_outside", + "inside": "actuallyadditions:blocks/block_item_viewer_hopping_inside" + }, + "elements": [ + { "from": [ 0, 10, 0 ], + "to": [ 16, 11, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#inside" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 0, 11, 0 ], + "to": [ 2, 16, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 14, 11, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 2, 11, 0 ], + "to": [ 14, 16, 2 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 2, 11, 14 ], + "to": [ 14, 16, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 4, 4, 4 ], + "to": [ 12, 10, 12 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#side" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 6, 0, 6 ], + "to": [ 10, 4, 10 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#side" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + } + ] +} diff --git a/src/main/resources/assets/actuallyadditions/models/block/item_viewer_hopping_side.json b/src/main/resources/assets/actuallyadditions/models/block/item_viewer_hopping_side.json new file mode 100644 index 000000000..b95eb1418 --- /dev/null +++ b/src/main/resources/assets/actuallyadditions/models/block/item_viewer_hopping_side.json @@ -0,0 +1,88 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "actuallyadditions:blocks/block_item_viewer_hopping_outside", + "top": "actuallyadditions:blocks/block_item_viewer_hopping_top", + "side": "actuallyadditions:blocks/block_item_viewer_hopping_outside", + "inside": "actuallyadditions:blocks/block_item_viewer_hopping_inside" + }, + "elements": [ + { "from": [ 0, 10, 0 ], + "to": [ 16, 11, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#inside" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 0, 11, 0 ], + "to": [ 2, 16, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 14, 11, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 2, 11, 0 ], + "to": [ 14, 16, 2 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 2, 11, 14 ], + "to": [ 14, 16, 16 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 4, 4, 4 ], + "to": [ 12, 10, 12 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#side" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 6, 4, 0 ], + "to": [ 10, 8, 4 ], + "faces": { + "down": { "texture": "#side" }, + "up": { "texture": "#side" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + } + ] +} diff --git a/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_inside.png b/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_inside.png new file mode 100644 index 000000000..deca6b0f2 Binary files /dev/null and b/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_inside.png differ diff --git a/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_outside.png b/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_outside.png new file mode 100644 index 000000000..ee095e558 Binary files /dev/null and b/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_outside.png differ diff --git a/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_top.png b/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_top.png new file mode 100644 index 000000000..5c914cfa6 Binary files /dev/null and b/src/main/resources/assets/actuallyadditions/textures/blocks/block_item_viewer_hopping_top.png differ