From a050ce51da6c34798f8a535b1b07eed8ffe326d5 Mon Sep 17 00:00:00 2001 From: MartinTheDragon Date: Sat, 26 Aug 2023 15:31:02 +0200 Subject: [PATCH] Make conveyor crane I/O sides configurable Right click with a screwdriver to change output direction, shift-right-click to change input direction. The ton of textures were made by 70k Co-authored-by: 70000hp <105080577+70000hp@users.noreply.github.com> --- .../hbm/blocks/network/BlockCraneBase.java | 196 +++++++++++++++++- .../com/hbm/blocks/network/CraneBoxer.java | 43 ++-- .../hbm/blocks/network/CraneExtractor.java | 44 +++- .../com/hbm/blocks/network/CraneGrabber.java | 36 ++-- .../com/hbm/blocks/network/CraneInserter.java | 48 ++--- .../com/hbm/blocks/network/CraneUnboxer.java | 58 ++++-- .../network/TileEntityCraneBase.java | 94 +++++++++ .../network/TileEntityCraneBoxer.java | 26 ++- .../network/TileEntityCraneExtractor.java | 29 ++- .../network/TileEntityCraneGrabber.java | 27 ++- .../network/TileEntityCraneInserter.java | 16 +- .../network/TileEntityCraneUnboxer.java | 16 +- .../crane_boxer_side_down_turn_left.png | Bin 0 -> 518 bytes .../crane_boxer_side_down_turn_right.png | Bin 0 -> 504 bytes .../crane_boxer_side_left_turn_down.png | Bin 0 -> 514 bytes .../blocks/crane_boxer_side_left_turn_up.png | Bin 0 -> 511 bytes .../crane_boxer_side_right_turn_down.png | Bin 0 -> 514 bytes .../blocks/crane_boxer_side_right_turn_up.png | Bin 0 -> 522 bytes .../blocks/crane_boxer_side_up_turn_left.png | Bin 0 -> 519 bytes .../blocks/crane_boxer_side_up_turn_right.png | Bin 0 -> 514 bytes .../textures/blocks/crane_boxer_top_left.png | Bin 0 -> 462 bytes .../textures/blocks/crane_boxer_top_right.png | Bin 0 -> 472 bytes .../crane_grabber_side_down_turn_left.png | Bin 0 -> 521 bytes .../crane_grabber_side_down_turn_right.png | Bin 0 -> 518 bytes .../crane_grabber_side_left_turn_down.png | Bin 0 -> 504 bytes .../crane_grabber_side_left_turn_up.png | Bin 0 -> 473 bytes .../crane_grabber_side_right_turn_down.png | Bin 0 -> 500 bytes .../crane_grabber_side_right_turn_up.png | Bin 0 -> 510 bytes .../crane_grabber_side_up_turn_left.png | Bin 0 -> 506 bytes .../crane_grabber_side_up_turn_right.png | Bin 0 -> 526 bytes .../blocks/crane_grabber_top_left.png | Bin 0 -> 768 bytes .../blocks/crane_grabber_top_right.png | Bin 0 -> 770 bytes .../assets/hbm/textures/blocks/crane_in.png | Bin 305 -> 252 bytes .../blocks/crane_in_side_down_turn_left.png | Bin 0 -> 496 bytes .../blocks/crane_in_side_down_turn_right.png | Bin 0 -> 524 bytes .../blocks/crane_in_side_left_turn_down.png | Bin 0 -> 524 bytes .../blocks/crane_in_side_left_turn_up.png | Bin 0 -> 490 bytes .../blocks/crane_in_side_right_turn_down.png | Bin 0 -> 530 bytes .../blocks/crane_in_side_right_turn_up.png | Bin 0 -> 508 bytes .../blocks/crane_in_side_up_turn_left.png | Bin 0 -> 507 bytes .../blocks/crane_in_side_up_turn_right.png | Bin 0 -> 526 bytes .../hbm/textures/blocks/crane_in_top_left.png | Bin 0 -> 776 bytes .../textures/blocks/crane_in_top_right.png | Bin 0 -> 772 bytes .../assets/hbm/textures/blocks/crane_out.png | Bin 252 -> 305 bytes .../blocks/crane_out_side_down_turn_left.png | Bin 0 -> 513 bytes .../blocks/crane_out_side_down_turn_right.png | Bin 0 -> 519 bytes .../blocks/crane_out_side_left_turn_down.png | Bin 0 -> 519 bytes .../blocks/crane_out_side_left_turn_up.png | Bin 0 -> 500 bytes .../blocks/crane_out_side_right_turn_down.png | Bin 0 -> 515 bytes .../blocks/crane_out_side_right_turn_up.png | Bin 0 -> 502 bytes .../blocks/crane_out_side_up_turn_left.png | Bin 0 -> 500 bytes .../blocks/crane_out_side_up_turn_right.png | Bin 0 -> 525 bytes .../textures/blocks/crane_out_top_left.png | Bin 0 -> 763 bytes .../textures/blocks/crane_out_top_right.png | Bin 0 -> 763 bytes .../hbm/textures/blocks/crane_side_in.png | Bin 358 -> 325 bytes .../hbm/textures/blocks/crane_side_out.png | Bin 325 -> 358 bytes .../crane_unboxer_side_down_turn_left.png | Bin 0 -> 488 bytes .../crane_unboxer_side_down_turn_right.png | Bin 0 -> 506 bytes .../crane_unboxer_side_left_turn_down.png | Bin 0 -> 507 bytes .../crane_unboxer_side_left_turn_up.png | Bin 0 -> 508 bytes .../crane_unboxer_side_right_turn_down.png | Bin 0 -> 516 bytes .../crane_unboxer_side_right_turn_up.png | Bin 0 -> 516 bytes .../crane_unboxer_side_up_turn_left.png | Bin 0 -> 491 bytes .../crane_unboxer_side_up_turn_right.png | Bin 0 -> 509 bytes .../blocks/crane_unboxer_top_left.png | Bin 0 -> 456 bytes .../blocks/crane_unboxer_top_right.png | Bin 0 -> 458 bytes 66 files changed, 473 insertions(+), 160 deletions(-) create mode 100644 src/main/java/com/hbm/tileentity/network/TileEntityCraneBase.java create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_down_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_down_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_left_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_left_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_right_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_right_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_up_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_up_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_top_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_boxer_top_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_down_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_down_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_left_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_left_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_right_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_right_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_up_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_up_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_top_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_grabber_top_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_down_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_down_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_left_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_left_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_right_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_right_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_up_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_side_up_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_top_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_in_top_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_down_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_down_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_left_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_left_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_right_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_right_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_up_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_side_up_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_top_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_out_top_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_down_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_down_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_left_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_left_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_right_turn_down.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_right_turn_up.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_up_turn_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_up_turn_right.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_top_left.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/crane_unboxer_top_right.png diff --git a/src/main/java/com/hbm/blocks/network/BlockCraneBase.java b/src/main/java/com/hbm/blocks/network/BlockCraneBase.java index 932381c24..3cdd1f8e5 100644 --- a/src/main/java/com/hbm/blocks/network/BlockCraneBase.java +++ b/src/main/java/com/hbm/blocks/network/BlockCraneBase.java @@ -1,11 +1,12 @@ package com.hbm.blocks.network; -import java.util.Random; - +import api.hbm.block.IToolable; import com.hbm.blocks.IBlockSideRotation; +import com.hbm.items.tool.ItemTooling; import com.hbm.lib.RefStrings; import com.hbm.main.MainRegistry; - +import com.hbm.tileentity.network.TileEntityCraneBase; +import com.hbm.util.ChatBuilder; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.common.network.internal.FMLNetworkHandler; import cpw.mods.fml.relauncher.Side; @@ -21,11 +22,16 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -public abstract class BlockCraneBase extends BlockContainer implements IBlockSideRotation { +import java.util.Random; + +public abstract class BlockCraneBase extends BlockContainer implements IBlockSideRotation, IToolable { @SideOnly(Side.CLIENT) protected IIcon iconSide; @SideOnly(Side.CLIENT) protected IIcon iconIn; @@ -37,10 +43,24 @@ public abstract class BlockCraneBase extends BlockContainer implements IBlockSid @SideOnly(Side.CLIENT) protected IIcon iconDirectionalUp; @SideOnly(Side.CLIENT) protected IIcon iconDirectionalDown; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalTurnLeft; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalTurnRight; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideLeftTurnUp; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideRightTurnUp; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideLeftTurnDown; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideRightTurnDown; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideUpTurnLeft; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideUpTurnRight; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideDownTurnLeft; + @SideOnly(Side.CLIENT) protected IIcon iconDirectionalSideDownTurnRight; + public BlockCraneBase(Material mat) { super(mat); } - + + @Override + public abstract TileEntityCraneBase createNewTileEntity(World p_149915_1_, int p_149915_2_); + @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { @@ -54,7 +74,9 @@ public abstract class BlockCraneBase extends BlockContainer implements IBlockSid @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { - if(world.isRemote) { + if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemTooling) { + return false; + } else if(world.isRemote) { return true; } else if(!player.isSneaking()) { FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z); @@ -70,9 +92,149 @@ public abstract class BlockCraneBase extends BlockContainer implements IBlockSid world.setBlockMetadataWithNotify(x, y, z, l, 2); } + protected boolean hasReversedIO() { + return false; + } + + @Override + public boolean onScrew(World world, EntityPlayer player, int x, int y, int z, int side, float fX, float fY, float fZ, ToolType tool) { + if (tool != ToolType.SCREWDRIVER) return false; + + TileEntity te = world.getTileEntity(x, y, z); + if (!(te instanceof TileEntityCraneBase)) return false; + + TileEntityCraneBase craneTileEntity = (TileEntityCraneBase) te; + + // some cranes like the ejector have reversed input and output sides + // so this bit of logic is to hide that away from the player + boolean actuallyCycleInput = player.isSneaking() != hasReversedIO(); + ForgeDirection newDirection; + + if (actuallyCycleInput) { // cycle input + // it's in reverse because players are more likely to want to turn the output from DOWN to UP + int newValue = Math.floorMod(world.getBlockMetadata(x, y, z) - 1, 6); + newDirection = ForgeDirection.getOrientation(newValue); + + world.setBlockMetadataWithNotify(x, y, z, newValue, 3); + craneTileEntity.ensureOutputOverrideValid(); + } else { // cycle output + newDirection = craneTileEntity.cycleOutputOverride(); + } + + if (!world.isRemote) { + ChatBuilder message = player.isSneaking() + ? ChatBuilder.start("Input: ").color(EnumChatFormatting.GREEN) + : ChatBuilder.start("Output: ").color(EnumChatFormatting.RED); + message.next(newDirection.name()).color(EnumChatFormatting.WHITE); + player.addChatComponentMessage(message.flush()); + } + + return true; + } + + public ForgeDirection getInputSide(IBlockAccess world, int x, int y, int z) { + return ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z)); + } + + /** + * Returns the player-overridden output direction, or {@link ForgeDirection#UNKNOWN} if unset. + * A return value of {@link ForgeDirection#UNKNOWN} suggests use of default meta behavior. + * Should never return the current input direction. + */ + protected final ForgeDirection getOutputSideOverride(IBlockAccess world, int x, int y, int z) { + TileEntity te = world.getTileEntity(x, y, z); + if (!(te instanceof TileEntityCraneBase)) return ForgeDirection.UNKNOWN; + TileEntityCraneBase craneTileEntity = (TileEntityCraneBase) te; + + return craneTileEntity.getOutputOverride(); + } + + public ForgeDirection getOutputSide(IBlockAccess world, int x, int y, int z) { + TileEntity te = world.getTileEntity(x, y, z); + if (!(te instanceof TileEntityCraneBase)) return ForgeDirection.UNKNOWN; + TileEntityCraneBase craneTileEntity = (TileEntityCraneBase) te; + + return craneTileEntity.getOutputSide(); + } + + @Override + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + ForgeDirection inputSide = getInputSide(world, x, y, z); + ForgeDirection outputOverride = getOutputSideOverride(world, x, y, z); + boolean outputSideOverridden = outputOverride != ForgeDirection.UNKNOWN && outputOverride.getOpposite() != inputSide; + ForgeDirection outputSide = outputSideOverridden ? outputOverride : inputSide.getOpposite(); + + // take your left hand, make your thumb the input side and the index finger the output side + // angle your middle finger to make your hand look like coordinate axes + // the direction your middle finger is pointing towards will be the direction returned from this function + ForgeDirection leftHandRotation = outputSide.getRotation(inputSide); + + if(side == 0 || side == 1) { + if(side == outputSide.ordinal()) { + return this.iconOut; + } + if(side == inputSide.ordinal()) { + return this.iconIn; + } + + if (side == 1) { + if (outputSideOverridden) { + if (leftHandRotation == ForgeDirection.UP) { + return this.iconDirectionalTurnLeft; + } + if (leftHandRotation == ForgeDirection.DOWN) { + return this.iconDirectionalTurnRight; + } + } else return iconDirectional; + } + + return this.blockIcon; + } + + if(side == outputSide.ordinal()) { + return this.iconSideOut; + } + if(side == inputSide.ordinal()) { + return this.iconSideIn; + } + + if (outputSideOverridden) { + if (leftHandRotation.ordinal() == side) { + if (outputSide == ForgeDirection.UP) + return this.iconDirectionalSideLeftTurnUp; + if (outputSide == ForgeDirection.DOWN) + return this.iconDirectionalSideRightTurnDown; + if (inputSide == ForgeDirection.UP) + return this.iconDirectionalSideUpTurnRight; + if (inputSide == ForgeDirection.DOWN) + return this.iconDirectionalSideDownTurnLeft; + } + if (leftHandRotation.getOpposite().ordinal() == side) { + if (outputSide == ForgeDirection.UP) + return this.iconDirectionalSideRightTurnUp; + if (outputSide == ForgeDirection.DOWN) + return this.iconDirectionalSideLeftTurnDown; + if (inputSide == ForgeDirection.UP) + return this.iconDirectionalSideUpTurnLeft; + if (inputSide == ForgeDirection.DOWN) + return this.iconDirectionalSideDownTurnRight; + } + } else { + if(outputSide == ForgeDirection.UP) { + return this.iconDirectionalUp; + } + if(outputSide == ForgeDirection.DOWN) { + return this.iconDirectionalDown; + } + } + + return this.iconSide; + } + + // kept for inventory rendering @Override public IIcon getIcon(int side, int metadata) { - + if(side == 0 || side == 1) { if(side == metadata) { return this.iconOut; @@ -80,10 +242,10 @@ public abstract class BlockCraneBase extends BlockContainer implements IBlockSid if(side == ForgeDirection.getOrientation(metadata).getOpposite().ordinal()) { return this.iconIn; } - + return side == 1 ? this.iconDirectional : this.blockIcon; } - + if(side == metadata) { return this.iconSideOut; } @@ -97,9 +259,23 @@ public abstract class BlockCraneBase extends BlockContainer implements IBlockSid if(metadata == 1) { return this.iconDirectionalDown; } - + return this.iconSide; } + + @Override + public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { + int meta = world.getBlockMetadata(x, y, z); + + if(meta > 1 && side == 1) { + if(meta == 2) return 3; + if(meta == 3) return 0; + if(meta == 4) return 1; + if(meta == 5) return 2; + } + + return 0; + } public static int renderIDClassic = RenderingRegistry.getNextAvailableRenderId(); diff --git a/src/main/java/com/hbm/blocks/network/CraneBoxer.java b/src/main/java/com/hbm/blocks/network/CraneBoxer.java index b884bd62f..2498e734c 100644 --- a/src/main/java/com/hbm/blocks/network/CraneBoxer.java +++ b/src/main/java/com/hbm/blocks/network/CraneBoxer.java @@ -1,11 +1,11 @@ package com.hbm.blocks.network; -import com.hbm.lib.RefStrings; -import com.hbm.tileentity.network.TileEntityCraneBoxer; - import api.hbm.conveyor.IConveyorItem; import api.hbm.conveyor.IConveyorPackage; import api.hbm.conveyor.IEnterableBlock; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.network.TileEntityCraneBase; +import com.hbm.tileentity.network.TileEntityCraneBoxer; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -14,8 +14,6 @@ import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.item.EntityItem; import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; @@ -26,7 +24,7 @@ public class CraneBoxer extends BlockCraneBase implements IEnterableBlock { } @Override - public TileEntity createNewTileEntity(World world, int meta) { + public TileEntityCraneBase createNewTileEntity(World world, int meta) { return new TileEntityCraneBoxer(); } @@ -34,31 +32,26 @@ public class CraneBoxer extends BlockCraneBase implements IEnterableBlock { @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { super.registerBlockIcons(iconRegister); - this.iconIn = iconRegister.registerIcon(RefStrings.MODID + ":crane_box"); - this.iconSideIn = iconRegister.registerIcon(RefStrings.MODID + ":crane_side_box"); + this.iconOut = iconRegister.registerIcon(RefStrings.MODID + ":crane_box"); + this.iconSideOut = iconRegister.registerIcon(RefStrings.MODID + ":crane_side_box"); this.iconDirectional = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_top"); this.iconDirectionalUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_up"); this.iconDirectionalDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_down"); + this.iconDirectionalTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_top_left"); + this.iconDirectionalTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_top_right"); + this.iconDirectionalSideLeftTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_left_turn_up"); + this.iconDirectionalSideRightTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_right_turn_up"); + this.iconDirectionalSideLeftTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_left_turn_down"); + this.iconDirectionalSideRightTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_right_turn_down"); + this.iconDirectionalSideUpTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_up_turn_left"); + this.iconDirectionalSideUpTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_up_turn_right"); + this.iconDirectionalSideDownTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_down_turn_left"); + this.iconDirectionalSideDownTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_boxer_side_down_turn_right"); } - @Override - public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { - int meta = world.getBlockMetadata(x, y, z); - - if(meta > 1 && side == 1) { - if(meta == 2) return 3; - if(meta == 3) return 0; - if(meta == 4) return 1; - if(meta == 5) return 2; - } - - return 0; - } - - @Override + @Override public boolean canItemEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorItem entity) { - ForgeDirection orientation = ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z)); - return orientation == dir; + return getInputSide(world, x, y, z) == dir; } @Override diff --git a/src/main/java/com/hbm/blocks/network/CraneExtractor.java b/src/main/java/com/hbm/blocks/network/CraneExtractor.java index 51d754aa4..7b142bb70 100644 --- a/src/main/java/com/hbm/blocks/network/CraneExtractor.java +++ b/src/main/java/com/hbm/blocks/network/CraneExtractor.java @@ -1,16 +1,16 @@ package com.hbm.blocks.network; import com.hbm.lib.RefStrings; +import com.hbm.tileentity.network.TileEntityCraneBase; import com.hbm.tileentity.network.TileEntityCraneExtractor; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.tileentity.TileEntity; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; public class CraneExtractor extends BlockCraneBase { @@ -19,7 +19,7 @@ public class CraneExtractor extends BlockCraneBase { } @Override - public TileEntity createNewTileEntity(World world, int meta) { + public TileEntityCraneBase createNewTileEntity(World world, int meta) { return new TileEntityCraneExtractor(); } @@ -30,19 +30,53 @@ public class CraneExtractor extends BlockCraneBase { this.iconDirectional = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_top"); this.iconDirectionalUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_down"); this.iconDirectionalDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_up"); + this.iconDirectionalTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_top_right"); + this.iconDirectionalTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_top_left"); + this.iconDirectionalSideLeftTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_up_turn_left"); + this.iconDirectionalSideRightTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_up_turn_right"); + this.iconDirectionalSideLeftTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_down_turn_left"); + this.iconDirectionalSideRightTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_down_turn_right"); + this.iconDirectionalSideUpTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_left_turn_up"); + this.iconDirectionalSideUpTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_right_turn_up"); + this.iconDirectionalSideDownTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_left_turn_down"); + this.iconDirectionalSideDownTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_out_side_right_turn_down"); + } + + @Override + protected boolean hasReversedIO() { + return true; } @Override public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { int meta = world.getBlockMetadata(x, y, z); - + if(meta > 1 && side == 1) { + // ok so i've been sitting around for 4-5 hours trying to come up with a + // more elegant way to implement this and i have seriously no clue what + // the guys at mojang did, but the uv rotation makes absolutely no sense + // it's 2:30 am, please just accept this + // - martin + ForgeDirection leftHandDirection = getOutputSide(world, x, y, z).getRotation(getInputSide(world, x, y, z)); + if (leftHandDirection == ForgeDirection.UP) { + if (meta == 2) return 2; + if (meta == 3) return 1; + if (meta == 4) return 3; + if (meta == 5) return 0; + } + if (leftHandDirection == ForgeDirection.DOWN) { + if (meta == 2) return 1; + if (meta == 3) return 2; + if (meta == 4) return 0; + if (meta == 5) return 3; + } + if(meta == 2) return 0; if(meta == 3) return 3; if(meta == 4) return 2; if(meta == 5) return 1; } - + return 0; } diff --git a/src/main/java/com/hbm/blocks/network/CraneGrabber.java b/src/main/java/com/hbm/blocks/network/CraneGrabber.java index 5c0ee4bb1..fcda1d05a 100644 --- a/src/main/java/com/hbm/blocks/network/CraneGrabber.java +++ b/src/main/java/com/hbm/blocks/network/CraneGrabber.java @@ -1,15 +1,13 @@ package com.hbm.blocks.network; import com.hbm.lib.RefStrings; +import com.hbm.tileentity.network.TileEntityCraneBase; import com.hbm.tileentity.network.TileEntityCraneGrabber; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; public class CraneGrabber extends BlockCraneBase { @@ -19,7 +17,7 @@ public class CraneGrabber extends BlockCraneBase { } @Override - public TileEntity createNewTileEntity(World world, int meta) { + public TileEntityCraneBase createNewTileEntity(World world, int meta) { return new TileEntityCraneGrabber(); } @@ -27,28 +25,24 @@ public class CraneGrabber extends BlockCraneBase { @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { super.registerBlockIcons(iconRegister); + this.iconIn = iconRegister.registerIcon(RefStrings.MODID + ":crane_pull"); + this.iconSideIn = iconRegister.registerIcon(RefStrings.MODID + ":crane_side_pull"); this.iconDirectional = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_top"); this.iconDirectionalUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_up"); this.iconDirectionalDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_down"); - this.iconOut = iconRegister.registerIcon(RefStrings.MODID + ":crane_pull"); - this.iconSideOut = iconRegister.registerIcon(RefStrings.MODID + ":crane_side_pull"); + this.iconDirectionalTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_top_left"); + this.iconDirectionalTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_top_right"); + this.iconDirectionalSideLeftTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_left_turn_up"); + this.iconDirectionalSideRightTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_right_turn_up"); + this.iconDirectionalSideLeftTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_left_turn_down"); + this.iconDirectionalSideRightTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_right_turn_down"); + this.iconDirectionalSideUpTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_up_turn_left"); + this.iconDirectionalSideUpTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_up_turn_right"); + this.iconDirectionalSideDownTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_down_turn_left"); + this.iconDirectionalSideDownTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_grabber_side_down_turn_right"); } - @Override - public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { - int meta = world.getBlockMetadata(x, y, z); - - if(meta > 1 && side == 1) { - if(meta == 2) return 3; - if(meta == 3) return 0; - if(meta == 4) return 1; - if(meta == 5) return 2; - } - - return 0; - } - - @Override + @Override public void breakBlock(World world, int x, int y, int z, Block block, int meta) { this.dropContents(world, x, y, z, block, meta, 9, 11); super.breakBlock(world, x, y, z, block, meta); diff --git a/src/main/java/com/hbm/blocks/network/CraneInserter.java b/src/main/java/com/hbm/blocks/network/CraneInserter.java index cf3917af4..97347dc3c 100644 --- a/src/main/java/com/hbm/blocks/network/CraneInserter.java +++ b/src/main/java/com/hbm/blocks/network/CraneInserter.java @@ -1,11 +1,11 @@ package com.hbm.blocks.network; -import com.hbm.lib.RefStrings; -import com.hbm.tileentity.network.TileEntityCraneInserter; - import api.hbm.conveyor.IConveyorItem; import api.hbm.conveyor.IConveyorPackage; import api.hbm.conveyor.IEnterableBlock; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.network.TileEntityCraneBase; +import com.hbm.tileentity.network.TileEntityCraneInserter; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -18,7 +18,6 @@ import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; @@ -29,7 +28,7 @@ public class CraneInserter extends BlockCraneBase implements IEnterableBlock { } @Override - public TileEntity createNewTileEntity(World world, int meta) { + public TileEntityCraneBase createNewTileEntity(World world, int meta) { return new TileEntityCraneInserter(); } @@ -40,6 +39,16 @@ public class CraneInserter extends BlockCraneBase implements IEnterableBlock { this.iconDirectional = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_top"); this.iconDirectionalUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_up"); this.iconDirectionalDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_down"); + this.iconDirectionalTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_top_left"); + this.iconDirectionalTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_top_right"); + this.iconDirectionalSideLeftTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_left_turn_up"); + this.iconDirectionalSideRightTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_right_turn_up"); + this.iconDirectionalSideLeftTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_left_turn_down"); + this.iconDirectionalSideRightTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_right_turn_down"); + this.iconDirectionalSideUpTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_up_turn_left"); + this.iconDirectionalSideUpTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_up_turn_right"); + this.iconDirectionalSideDownTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_down_turn_left"); + this.iconDirectionalSideDownTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_in_side_down_turn_right"); } @Override @@ -50,7 +59,8 @@ public class CraneInserter extends BlockCraneBase implements IEnterableBlock { @Override public void onItemEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorItem entity) { - TileEntity te = world.getTileEntity(x - dir.offsetX, y - dir.offsetY, z - dir.offsetZ); + ForgeDirection outputDirection = getOutputSide(world, x, y, z); + TileEntity te = world.getTileEntity(x + outputDirection.offsetX, y + outputDirection.offsetY, z + outputDirection.offsetZ); if(entity == null || entity.getItemStack() == null || entity.getItemStack().stackSize <= 0) { return; @@ -62,19 +72,19 @@ public class CraneInserter extends BlockCraneBase implements IEnterableBlock { if(te instanceof ISidedInventory) { ISidedInventory sided = (ISidedInventory) te; - access = masquerade(sided, dir.ordinal()); + access = masquerade(sided, outputDirection.getOpposite().ordinal()); } if(te instanceof IInventory) { IInventory inv = (IInventory) te; - addToInventory(inv, access, toAdd, dir.ordinal()); + addToInventory(inv, access, toAdd, outputDirection.getOpposite().ordinal()); } - if(toAdd != null && toAdd.stackSize > 0) { - addToInventory((TileEntityCraneInserter) world.getTileEntity(x, y, z), null, toAdd, dir.ordinal()); + if(toAdd.stackSize > 0) { + addToInventory((TileEntityCraneInserter) world.getTileEntity(x, y, z), null, toAdd, outputDirection.getOpposite().ordinal()); } - if(toAdd != null && toAdd.stackSize > 0) { + if(toAdd.stackSize > 0) { EntityItem drop = new EntityItem(world, x + 0.5, y + 0.5, z + 0.5, toAdd.copy()); world.spawnEntityInWorld(drop); } @@ -147,21 +157,7 @@ public class CraneInserter extends BlockCraneBase implements IEnterableBlock { @Override public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { } - @Override - public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { - int meta = world.getBlockMetadata(x, y, z); - - if(meta > 1 && side == 1) { - if(meta == 2) return 3; - if(meta == 3) return 0; - if(meta == 4) return 1; - if(meta == 5) return 2; - } - - return 0; - } - - @Override + @Override public boolean hasComparatorInputOverride() { return true; } diff --git a/src/main/java/com/hbm/blocks/network/CraneUnboxer.java b/src/main/java/com/hbm/blocks/network/CraneUnboxer.java index 558de5654..109be9ac7 100644 --- a/src/main/java/com/hbm/blocks/network/CraneUnboxer.java +++ b/src/main/java/com/hbm/blocks/network/CraneUnboxer.java @@ -1,11 +1,11 @@ package com.hbm.blocks.network; -import com.hbm.lib.RefStrings; -import com.hbm.tileentity.network.TileEntityCraneUnboxer; - import api.hbm.conveyor.IConveyorItem; import api.hbm.conveyor.IConveyorPackage; import api.hbm.conveyor.IEnterableBlock; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.network.TileEntityCraneBase; +import com.hbm.tileentity.network.TileEntityCraneUnboxer; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -14,7 +14,6 @@ import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.item.EntityItem; import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; @@ -26,7 +25,7 @@ public class CraneUnboxer extends BlockCraneBase implements IEnterableBlock { } @Override - public TileEntity createNewTileEntity(World world, int meta) { + public TileEntityCraneBase createNewTileEntity(World world, int meta) { return new TileEntityCraneUnboxer(); } @@ -34,24 +33,58 @@ public class CraneUnboxer extends BlockCraneBase implements IEnterableBlock { @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { super.registerBlockIcons(iconRegister); - this.iconIn = iconRegister.registerIcon(RefStrings.MODID + ":crane_box"); - this.iconSideIn = iconRegister.registerIcon(RefStrings.MODID + ":crane_side_box"); + this.iconOut = iconRegister.registerIcon(RefStrings.MODID + ":crane_box"); + this.iconSideOut = iconRegister.registerIcon(RefStrings.MODID + ":crane_side_box"); this.iconDirectional = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_top"); this.iconDirectionalUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_down"); this.iconDirectionalDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_up"); + this.iconDirectionalTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_top_right"); + this.iconDirectionalTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_top_left"); + this.iconDirectionalSideLeftTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_up_turn_left"); + this.iconDirectionalSideRightTurnUp = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_up_turn_right"); + this.iconDirectionalSideLeftTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_down_turn_left"); + this.iconDirectionalSideRightTurnDown = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_down_turn_right"); + this.iconDirectionalSideUpTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_left_turn_up"); + this.iconDirectionalSideUpTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_right_turn_up"); + this.iconDirectionalSideDownTurnLeft = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_left_turn_down"); + this.iconDirectionalSideDownTurnRight = iconRegister.registerIcon(RefStrings.MODID + ":crane_unboxer_side_right_turn_down"); + } + + @Override + protected boolean hasReversedIO() { + return true; } @Override public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { int meta = world.getBlockMetadata(x, y, z); - + if(meta > 1 && side == 1) { + // ok so i've been sitting around for 4-5 hours trying to come up with a + // more elegant way to implement this and i have seriously no clue what + // the guys at mojang did, but the uv rotation makes absolutely no sense + // it's 2:30 am, please just accept this + // - martin + ForgeDirection leftHandDirection = getOutputSide(world, x, y, z).getRotation(getInputSide(world, x, y, z)); + if (leftHandDirection == ForgeDirection.UP) { + if (meta == 2) return 2; + if (meta == 3) return 1; + if (meta == 4) return 3; + if (meta == 5) return 0; + } + if (leftHandDirection == ForgeDirection.DOWN) { + if (meta == 2) return 1; + if (meta == 3) return 2; + if (meta == 4) return 0; + if (meta == 5) return 3; + } + if(meta == 2) return 0; if(meta == 3) return 3; if(meta == 4) return 2; if(meta == 5) return 1; } - + return 0; } @@ -71,15 +104,16 @@ public class CraneUnboxer extends BlockCraneBase implements IEnterableBlock { @Override public boolean canPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { - return true; + return getOutputSide(world, x, y, z) == dir; } @Override public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { TileEntityCraneUnboxer unboxer = (TileEntityCraneUnboxer) world.getTileEntity(x, y, z); - + ForgeDirection accessedSide = getOutputSide(world, x, y, z).getOpposite(); + for(ItemStack stack : entity.getItemStacks()) { - ItemStack remainder = CraneInserter.addToInventory(unboxer, unboxer.getAccessibleSlotsFromSide(dir.ordinal()), stack, dir.ordinal()); + ItemStack remainder = CraneInserter.addToInventory(unboxer, unboxer.getAccessibleSlotsFromSide(accessedSide.ordinal()), stack, accessedSide.ordinal()); if(remainder != null && remainder.stackSize > 0) { EntityItem drop = new EntityItem(world, x + 0.5, y + 0.5, z + 0.5, remainder.copy()); diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCraneBase.java b/src/main/java/com/hbm/tileentity/network/TileEntityCraneBase.java new file mode 100644 index 000000000..28daa73f7 --- /dev/null +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCraneBase.java @@ -0,0 +1,94 @@ +package com.hbm.tileentity.network; + +import com.hbm.tileentity.TileEntityMachineBase; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.common.util.ForgeDirection; + +public abstract class TileEntityCraneBase extends TileEntityMachineBase { + public TileEntityCraneBase(int scount) { + super(scount); + } + + // extension to the meta system + // for compatibility purposes, normal meta values are still used by default + private ForgeDirection outputOverride = ForgeDirection.UNKNOWN; + + // for extra stability in case the screwdriver action doesn't get synced to other clients + @SideOnly(Side.CLIENT) + private ForgeDirection cachedOutputOverride = ForgeDirection.UNKNOWN; + + @Override + public void updateEntity() { + if (hasWorldObj() && worldObj.isRemote) { + if (cachedOutputOverride != outputOverride) { + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + cachedOutputOverride = outputOverride; + } + } + } + + public ForgeDirection getInputSide() { + return ForgeDirection.getOrientation(getBlockMetadata()); + } + + public ForgeDirection getOutputSide() { + ForgeDirection override = getOutputOverride(); + return override != ForgeDirection.UNKNOWN ? override : ForgeDirection.getOrientation(getBlockMetadata()).getOpposite(); + } + + public ForgeDirection getOutputOverride() { + return outputOverride; + } + + public ForgeDirection cycleOutputOverride() { + do { + outputOverride = ForgeDirection.getOrientation(Math.floorMod(outputOverride.ordinal() - 1, 7)); + } while (outputOverride.ordinal() == getBlockMetadata()); + + onBlockChanged(); + return outputOverride; + } + + public void ensureOutputOverrideValid() { + if (outputOverride.ordinal() == getBlockMetadata()) + cycleOutputOverride(); + } + + protected void onBlockChanged() { + if (!hasWorldObj()) return; + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + worldObj.notifyBlockChange(xCoord, yCoord, zCoord, getBlockType()); + markDirty(); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + writeToNBT(nbt); + return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, nbt); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + readFromNBT(pkt.func_148857_g()); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + if (nbt.hasKey("CraneOutputOverride", Constants.NBT.TAG_BYTE)) + outputOverride = ForgeDirection.getOrientation(nbt.getByte("CraneOutputOverride")); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setByte("CraneOutputOverride", (byte) outputOverride.ordinal()); + } +} diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCraneBoxer.java b/src/main/java/com/hbm/tileentity/network/TileEntityCraneBoxer.java index bca0a3f22..2996d102a 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityCraneBoxer.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCraneBoxer.java @@ -1,13 +1,11 @@ package com.hbm.tileentity.network; +import api.hbm.conveyor.IConveyorBelt; import com.hbm.entity.item.EntityMovingPackage; import com.hbm.interfaces.IControlReceiver; import com.hbm.inventory.container.ContainerCraneBoxer; import com.hbm.inventory.gui.GUICraneBoxer; import com.hbm.tileentity.IGUIProvider; -import com.hbm.tileentity.TileEntityMachineBase; - -import api.hbm.conveyor.IConveyorBelt; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -20,7 +18,7 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -public class TileEntityCraneBoxer extends TileEntityMachineBase implements IGUIProvider, IControlReceiver { +public class TileEntityCraneBoxer extends TileEntityCraneBase implements IGUIProvider, IControlReceiver { public byte mode = 0; public static final byte MODE_4 = 0; @@ -42,15 +40,15 @@ public class TileEntityCraneBoxer extends TileEntityMachineBase implements IGUIP @Override public void updateEntity() { - + super.updateEntity(); if(!worldObj.isRemote) { boolean redstone = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); if(mode == MODE_REDSTONE && redstone && !lastRedstone) { - ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()).getOpposite(); - Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); + ForgeDirection outputSide = getOutputSide(); + Block b = worldObj.getBlock(xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ); IConveyorBelt belt = null; if(b instanceof IConveyorBelt) { @@ -58,7 +56,7 @@ public class TileEntityCraneBoxer extends TileEntityMachineBase implements IGUIP } int pack = 0; - + for(int i = 0; i < slots.length; i++) { if(slots[i] != null) { pack++; @@ -79,8 +77,8 @@ public class TileEntityCraneBoxer extends TileEntityMachineBase implements IGUIP } EntityMovingPackage moving = new EntityMovingPackage(worldObj); - Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + dir.offsetX * 0.55, yCoord + 0.5 + dir.offsetY * 0.55, zCoord + 0.5 + dir.offsetZ * 0.55); - Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, pos); + Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + outputSide.offsetX * 0.55, yCoord + 0.5 + outputSide.offsetY * 0.55, zCoord + 0.5 + outputSide.offsetZ * 0.55); + Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ, pos); moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); moving.setItemStacks(box); worldObj.spawnEntityInWorld(moving); @@ -116,8 +114,8 @@ public class TileEntityCraneBoxer extends TileEntityMachineBase implements IGUIP } } - ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()).getOpposite(); - Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); + ForgeDirection outputSide = getOutputSide(); + Block b = worldObj.getBlock(xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ); IConveyorBelt belt = null; if(b instanceof IConveyorBelt) { @@ -138,8 +136,8 @@ public class TileEntityCraneBoxer extends TileEntityMachineBase implements IGUIP } EntityMovingPackage moving = new EntityMovingPackage(worldObj); - Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + dir.offsetX * 0.55, yCoord + 0.5 + dir.offsetY * 0.55, zCoord + 0.5 + dir.offsetZ * 0.55); - Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, pos); + Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + outputSide.offsetX * 0.55, yCoord + 0.5 + outputSide.offsetY * 0.55, zCoord + 0.5 + outputSide.offsetZ * 0.55); + Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ, pos); moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); moving.setItemStacks(box); worldObj.spawnEntityInWorld(moving); diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCraneExtractor.java b/src/main/java/com/hbm/tileentity/network/TileEntityCraneExtractor.java index 1da88ce44..d947f9922 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityCraneExtractor.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCraneExtractor.java @@ -1,5 +1,6 @@ package com.hbm.tileentity.network; +import api.hbm.conveyor.IConveyorBelt; import com.hbm.entity.item.EntityMovingItem; import com.hbm.interfaces.IControlReceiver; import com.hbm.inventory.container.ContainerCraneExtractor; @@ -7,9 +8,6 @@ import com.hbm.inventory.gui.GUICraneExtractor; import com.hbm.items.ModItems; import com.hbm.module.ModulePatternMatcher; import com.hbm.tileentity.IGUIProvider; -import com.hbm.tileentity.TileEntityMachineBase; - -import api.hbm.conveyor.IConveyorBelt; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -26,7 +24,7 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -public class TileEntityCraneExtractor extends TileEntityMachineBase implements IGUIProvider, IControlReceiver { +public class TileEntityCraneExtractor extends TileEntityCraneBase implements IGUIProvider, IControlReceiver { public boolean isWhitelist = false; public ModulePatternMatcher matcher; @@ -55,7 +53,7 @@ public class TileEntityCraneExtractor extends TileEntityMachineBase implements I @Override public void updateEntity() { - + super.updateEntity(); if(!worldObj.isRemote) { int delay = 20; @@ -78,10 +76,11 @@ public class TileEntityCraneExtractor extends TileEntityMachineBase implements I case 2: amount = 64; break; } } - - ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()); - TileEntity te = worldObj.getTileEntity(xCoord - dir.offsetX, yCoord - dir.offsetY, zCoord - dir.offsetZ); - Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); + + ForgeDirection inputSide = getOutputSide(); // note the switcheroo! + ForgeDirection outputSide = getInputSide(); + TileEntity te = worldObj.getTileEntity(xCoord + inputSide.offsetX, yCoord + inputSide.offsetY, zCoord + inputSide.offsetZ); + Block b = worldObj.getBlock(xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ); int[] access = null; ISidedInventory sided = null; @@ -89,7 +88,7 @@ public class TileEntityCraneExtractor extends TileEntityMachineBase implements I if(te instanceof ISidedInventory) { sided = (ISidedInventory) te; //access = sided.getAccessibleSlotsFromSide(dir.ordinal()); - access = masquerade(sided, dir.ordinal()); + access = masquerade(sided, inputSide.getOpposite().ordinal()); } boolean hasSent = false; @@ -108,7 +107,7 @@ public class TileEntityCraneExtractor extends TileEntityMachineBase implements I int index = access == null ? i : access[i]; ItemStack stack = inv.getStackInSlot(index); - if(stack != null && (sided == null || sided.canExtractItem(index, stack, dir.ordinal()))){ + if(stack != null && (sided == null || sided.canExtractItem(index, stack, inputSide.getOpposite().ordinal()))){ boolean match = this.matchesFilter(stack); @@ -119,8 +118,8 @@ public class TileEntityCraneExtractor extends TileEntityMachineBase implements I stack.stackSize = toSend; EntityMovingItem moving = new EntityMovingItem(worldObj); - Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + dir.offsetX * 0.55, yCoord + 0.5 + dir.offsetY * 0.55, zCoord + 0.5 + dir.offsetZ * 0.55); - Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, pos); + Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + outputSide.offsetX * 0.55, yCoord + 0.5 + outputSide.offsetY * 0.55, zCoord + 0.5 + outputSide.offsetZ * 0.55); + Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ, pos); moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); moving.setItemStack(stack); worldObj.spawnEntityInWorld(moving); @@ -144,8 +143,8 @@ public class TileEntityCraneExtractor extends TileEntityMachineBase implements I stack.stackSize = toSend; EntityMovingItem moving = new EntityMovingItem(worldObj); - Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + dir.offsetX * 0.55, yCoord + 0.5 + dir.offsetY * 0.55, zCoord + 0.5 + dir.offsetZ * 0.55); - Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, pos); + Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + outputSide.offsetX * 0.55, yCoord + 0.5 + outputSide.offsetY * 0.55, zCoord + 0.5 + outputSide.offsetZ * 0.55); + Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ, pos); moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); moving.setItemStack(stack); worldObj.spawnEntityInWorld(moving); diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCraneGrabber.java b/src/main/java/com/hbm/tileentity/network/TileEntityCraneGrabber.java index ba50abcea..e6dc6b48b 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityCraneGrabber.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCraneGrabber.java @@ -1,7 +1,5 @@ package com.hbm.tileentity.network; -import java.util.List; - import com.hbm.blocks.ModBlocks; import com.hbm.blocks.network.CraneInserter; import com.hbm.entity.item.EntityMovingItem; @@ -11,8 +9,6 @@ import com.hbm.inventory.gui.GUICraneGrabber; import com.hbm.items.ModItems; import com.hbm.module.ModulePatternMatcher; import com.hbm.tileentity.IGUIProvider; -import com.hbm.tileentity.TileEntityMachineBase; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -29,7 +25,9 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -public class TileEntityCraneGrabber extends TileEntityMachineBase implements IGUIProvider, IControlReceiver { +import java.util.List; + +public class TileEntityCraneGrabber extends TileEntityCraneBase implements IGUIProvider, IControlReceiver { public boolean isWhitelist = false; public ModulePatternMatcher matcher; @@ -50,7 +48,7 @@ public class TileEntityCraneGrabber extends TileEntityMachineBase implements IGU @Override public void updateEntity() { - + super.updateEntity(); if(!worldObj.isRemote) { int delay = 20; @@ -74,15 +72,16 @@ public class TileEntityCraneGrabber extends TileEntityMachineBase implements IGU } } - ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()); - TileEntity te = worldObj.getTileEntity(xCoord - dir.offsetX, yCoord - dir.offsetY, zCoord - dir.offsetZ); + ForgeDirection inputSide = getInputSide(); + ForgeDirection outputSide = getOutputSide(); + TileEntity te = worldObj.getTileEntity(xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ); int[] access = null; ISidedInventory sided = null; if(te instanceof ISidedInventory) { sided = (ISidedInventory) te; - access = CraneInserter.masquerade(sided, dir.ordinal()); + access = CraneInserter.masquerade(sided, outputSide.getOpposite().ordinal()); } if(te instanceof IInventory) { @@ -95,14 +94,14 @@ public class TileEntityCraneGrabber extends TileEntityMachineBase implements IGU */ double reach = 1D; if(this.getBlockMetadata() > 1) { //ignore if pointing up or down - Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); + Block b = worldObj.getBlock(xCoord + inputSide.offsetX, yCoord + inputSide.offsetY, zCoord + inputSide.offsetZ); if(b == ModBlocks.conveyor_double) reach = 0.5D; if(b == ModBlocks.conveyor_triple) reach = 0.33D; } - double x = xCoord + dir.offsetX * reach; - double y = yCoord + dir.offsetY * reach; - double z = zCoord + dir.offsetZ * reach; + double x = xCoord + inputSide.offsetX * reach; + double y = yCoord + inputSide.offsetY * reach; + double z = zCoord + inputSide.offsetZ * reach; List items = worldObj.getEntitiesWithinAABB(EntityMovingItem.class, AxisAlignedBB.getBoundingBox(x + 0.1875D, y + 0.1875D, z + 0.1875D, x + 0.8125D, y + 0.8125D, z + 0.8125D)); for(EntityMovingItem item : items) { @@ -113,7 +112,7 @@ public class TileEntityCraneGrabber extends TileEntityMachineBase implements IGU ItemStack copy = stack.copy(); int toAdd = Math.min(stack.stackSize, amount); copy.stackSize = toAdd; - ItemStack ret = CraneInserter.addToInventory((IInventory) te, access, copy, dir.ordinal()); + ItemStack ret = CraneInserter.addToInventory((IInventory) te, access, copy, outputSide.getOpposite().ordinal()); int didAdd = toAdd - (ret != null ? ret.stackSize : 0); stack.stackSize -= didAdd; diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java b/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java index 205fe3115..9de4fb7fc 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java @@ -4,8 +4,6 @@ import com.hbm.blocks.network.CraneInserter; import com.hbm.inventory.container.ContainerCraneInserter; import com.hbm.inventory.gui.GUICraneInserter; import com.hbm.tileentity.IGUIProvider; -import com.hbm.tileentity.TileEntityMachineBase; - import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.gui.GuiScreen; @@ -18,7 +16,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -public class TileEntityCraneInserter extends TileEntityMachineBase implements IGUIProvider { +public class TileEntityCraneInserter extends TileEntityCraneBase implements IGUIProvider { public static final int[] access = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; @@ -33,18 +31,18 @@ public class TileEntityCraneInserter extends TileEntityMachineBase implements IG @Override public void updateEntity() { - + super.updateEntity(); if(!worldObj.isRemote) { - ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()); - TileEntity te = worldObj.getTileEntity(xCoord - dir.offsetX, yCoord - dir.offsetY, zCoord - dir.offsetZ); + ForgeDirection outputSide = getOutputSide(); + TileEntity te = worldObj.getTileEntity(xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ); int[] access = null; if(te instanceof ISidedInventory) { ISidedInventory sided = (ISidedInventory) te; //access = sided.getAccessibleSlotsFromSide(dir.ordinal()); - access = CraneInserter.masquerade(sided, dir.ordinal()); + access = CraneInserter.masquerade(sided, outputSide.getOpposite().ordinal()); } if(te instanceof IInventory) { @@ -53,7 +51,7 @@ public class TileEntityCraneInserter extends TileEntityMachineBase implements IG ItemStack stack = slots[i]; if(stack != null) { - ItemStack ret = CraneInserter.addToInventory((IInventory) te, access, stack.copy(), dir.ordinal()); + ItemStack ret = CraneInserter.addToInventory((IInventory) te, access, stack.copy(), outputSide.getOpposite().ordinal()); if(ret == null || ret.stackSize != stack.stackSize) { slots[i] = ret; @@ -72,7 +70,7 @@ public class TileEntityCraneInserter extends TileEntityMachineBase implements IG if(stack != null) { stack = stack.copy(); stack.stackSize = 1; - ItemStack ret = CraneInserter.addToInventory((IInventory) te, access, stack.copy(), dir.ordinal()); + ItemStack ret = CraneInserter.addToInventory((IInventory) te, access, stack.copy(), outputSide.getOpposite().ordinal()); if(ret == null || ret.stackSize != stack.stackSize) { this.decrStackSize(i, 1); diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCraneUnboxer.java b/src/main/java/com/hbm/tileentity/network/TileEntityCraneUnboxer.java index 3cd1aa7da..31dd46c1e 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityCraneUnboxer.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCraneUnboxer.java @@ -1,13 +1,11 @@ package com.hbm.tileentity.network; +import api.hbm.conveyor.IConveyorBelt; import com.hbm.entity.item.EntityMovingItem; import com.hbm.inventory.container.ContainerCraneUnboxer; import com.hbm.inventory.gui.GUICraneUnboxer; import com.hbm.items.ModItems; import com.hbm.tileentity.IGUIProvider; -import com.hbm.tileentity.TileEntityMachineBase; - -import api.hbm.conveyor.IConveyorBelt; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -19,7 +17,7 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -public class TileEntityCraneUnboxer extends TileEntityMachineBase implements IGUIProvider { +public class TileEntityCraneUnboxer extends TileEntityCraneBase implements IGUIProvider { public TileEntityCraneUnboxer() { super(23); @@ -32,7 +30,7 @@ public class TileEntityCraneUnboxer extends TileEntityMachineBase implements IGU @Override public void updateEntity() { - + super.updateEntity(); if(!worldObj.isRemote) { int delay = 20; @@ -65,8 +63,8 @@ public class TileEntityCraneUnboxer extends TileEntityMachineBase implements IGU } } - ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()); - Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); + ForgeDirection outputSide = getInputSide(); // note the switcheroo! + Block b = worldObj.getBlock(xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ); if(b instanceof IConveyorBelt) { @@ -82,8 +80,8 @@ public class TileEntityCraneUnboxer extends TileEntityMachineBase implements IGU stack.stackSize = toSend; EntityMovingItem moving = new EntityMovingItem(worldObj); - Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + dir.offsetX * 0.55, yCoord + 0.5 + dir.offsetY * 0.55, zCoord + 0.5 + dir.offsetZ * 0.55); - Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, pos); + Vec3 pos = Vec3.createVectorHelper(xCoord + 0.5 + outputSide.offsetX * 0.55, yCoord + 0.5 + outputSide.offsetY * 0.55, zCoord + 0.5 + outputSide.offsetZ * 0.55); + Vec3 snap = belt.getClosestSnappingPosition(worldObj, xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ, pos); moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); moving.setItemStack(stack); worldObj.spawnEntityInWorld(moving); diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_down_turn_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_down_turn_left.png new file mode 100644 index 0000000000000000000000000000000000000000..5bdc5d132487da1bac043cc9c01c65961c5d1c3a GIT binary patch literal 518 zcmV+h0{Q)kP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TugK~y+Tl~KJ) z!%!H#X^Kr7oq~(vpj|9tl?*}!2f@YJmk_#j^939V7Q{Y+4i0?-7nh1d(SlMO8(L~( zQ?vJWbO+fAAGSk|cBqmSv@&3xWU*$8q}ozW@G! zm6^1#h%1VM0RRISjs@5onyY#p>E79F5@lXo-6?g0f>_&MA+j3lyJe(z+YhO8)Si7NIGu)9{>OV07*qo IM6N<$g0!&Bi~s-t literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_down_turn_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_down_turn_right.png new file mode 100644 index 0000000000000000000000000000000000000000..0c3c43bd97255ded4bba009e6a365a7df1b48513 GIT binary patch literal 504 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0gXvSK~y+Tl~O%V z!cY`_twajwMC#yXmRwpi2S0D zAdX4U0)ilbSQ-eb%FBcO?IUC7FJ90F;8l?*_!xUO$(I^GxUhZ6b1 zG+oz4R~qEi1W;n=RgWd2QmLT(dk2!@HGDr@^-y`$Zaabz&omdV zD>@v~fW47*UEivmO{dfIRtsZXcRDzn9*_XBx?C>F1Ast{cLV{j%X~h^bv8s%~s u{|g!k$Ou53MncAT+<+xKun_zO#=ZevV_jE7xuik>0000E literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_left_turn_down.png b/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_left_turn_down.png new file mode 100644 index 0000000000000000000000000000000000000000..e2590058df1a211b8e0d00bf2a9dab23d55d98c5 GIT binary patch literal 514 zcmV+d0{#7oP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0hdWcK~y+Tl~O%R z!%!5xsYTP)K%r!D5FCr3l0mGS;NtARXa^yJ|G}kHYJY~aiy$sV1#1hH;v@yJBx#Ga zv7~95cwTOZ-NeJ==G>3-?tSk?(siBw10m2fE%JzhAYdDlFiespnWow6^&&yP-{&F* z7e!7GpqeAyZg;6rC}c93`F!rWuIG6OeJ)@$8p*PZEW@_#1a!Xd!+|vn!#D1+b%7 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_left_turn_up.png b/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_left_turn_up.png new file mode 100644 index 0000000000000000000000000000000000000000..3c3f8f4691dd8237ac3419c001020161dc404054 GIT binary patch literal 511 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TK1iKYQC4-<_!Nu97TgA0o2geR|vU~qS7iSkiM5rjJ6_ny6gkWjX z&lpM?TjP1T;n__*gqw5j$Gi8wr<6)1`VT~buIrH^3W9*GB%zxWMX@Za-EPNOce`Cq z0y>?}S+!~q-PY@dVZeiIPMb_7G5j3If%SbK+B8jMhf&(i=ToT^oDy(~kusSK1PXBW z#JqtwnOuM!kA2vU+%futAYnKhiVoi)zCu9mY_H_>wS&Fv;r^D4PN!2?NKxQ<9z>yB zKB?7k_VSWuyPt3(1UZ|{5M>(`@UE*w_yAQ^=W75?09@CNMuIr4RE`P-o?F(ioX2km z5KYry&o7@Z8m+6x_xt7tBu^qCZYiBks+;Uj$b-1vjth?pY8D-WI2?AtQ31#3#A)5OJ#^ z3IL^8EMf<|B98<}0x;*1VEg^PD1ZwW947n)q90nZNEpLAPm%xt002ovPDHLkV1f_6 B)35*l literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_right_turn_down.png b/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_right_turn_down.png new file mode 100644 index 0000000000000000000000000000000000000000..3e47bb1b0efc80be90c2345b23cc1e6418c10b15 GIT binary patch literal 514 zcmV+d0{#7oP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0hdWcK~y+Tl~O%V z!cY{wMWO|CB3&Fz9EpjV4o2KaT%7#_%&;-IGP_}r9e;qci-~a|Y9d0SAxwtEl-L3h zX-Fxh^}KhR%4R%yxt#lP-o5t~rBo`>e;@?9u7@5`5Cm)^BEzI8ifNktem@ip1_Lf) za8c+40jfFD>-AQ$*=#D6S}Yc>>l%gu<<}C%VgOj5j1eG>UBI0#^9RY4(tQhx9yuo=dStw z)H2|XMx*(B&M822KsD}$)iliv4$o>e1ThA1QK?v#g_K-S?l7Cp@FQBtCeWN03ZjigP)Px#1ZP1_K>z@;j|==^1poj5$xuvGMRIa-q@<*yqoa+Djf{+pp`oFmprDJ3i;$3z zkB^Uzj*fPAcK-kX;Q#=rsHlpHiiwGdYinzkmX>jGahjT%f`WpBgM*Zml!u3haBy&G zR5Np4IhB=_fq{X0dwY_Sl7)qZZfVGd007EKL_t(2 zQ)SF;Z-Ouo!0}TQ721^!LDsIw6wz9I;PyN>pT7Tx+KpEx`zM!Ne#ssDuS0daUa#-_ zet+->!%^UcjNge!2q6LPhfy3e#`!o&)0AN1We-Yet<$&R3QoS|?JMB$}}*bO2eFELBNDCoR-9LHjh=v{2N>1a0}sZXL*?*qI%*U*uH- z4)FQq^$p)Y5I?^V58r@4v>%T&C&cpsL0+!b+K_6REyVOgx|^K)1vq>f!pgrrMF0Q* M07*qoM6N<$g2)=;f&c&j literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_up_turn_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_boxer_side_up_turn_left.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5c0762aea97e3c925c878cf2a92df412c96a96 GIT binary patch literal 519 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%LhM0X`wFMMXtRmMmGkcyWJ!e{XMZPfyRng$oxfSkT?wJz>IxzP`S)va*K^ z4F4GzR;*aj)z#J6*_oZ4J#E^w#>U3N!oq@rf|iz++}zxzrl#iR<|$LAloyH8t_^@$K#HZEbC> zt*s>`B@GP?rKP1n*Ku-k{=doj{{|xv{JYNZ=PJXmD-1s_F+4fQuyzu||C{Vz&NF;E z%kb(LLtR~6MMXsi&+kHzwgQjHVg?4j!ywFfJby(BQ1G~?i(`mJaO#=p;6nxiZ4X^1 z+%hxl<<3&wD5j2ZF^dq1ap=dO89{pMTjPye>}>XtfLqgJ{P=p_bES3j3^ HP6Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0hdWcK~y+Tl~KV; z!$1(-)S_uIrxFkkg6*jYDme&x6TEo#Gji)^1kA;LM0@BTco9MHAX-pF=qU}9Hf`F* zP?9t@zR8rOH}SFAyqPz%J2R^^8V&Iu6!95`!3L0J*?2r&tyUnqu48Avq9~)$XfPO1 z0)QZBjNx!-TGoLO?N-Zi9C#4TVR0N6@C$+fdy*u}<H>Y-Y# z!ay9(j@?Ii%jIqCiv?wF?VY1G5CqI-Gr9p4OTauk-M=&ruP^F1S0^y;+Pn&<(q$Rz=i0L-~0?05}IfC~f81O9>#zj44uc!c5mTmS$707*qoM6N<$ Eg66WPx#1ZP1_K>z@;j|==^1poj5pHNIxMRIa-q@<*yqobmtqM@OoprD|Oi;IwukdKd# zj*gCvjg5?qjEahiiHV78YipL4mWPLjY;0_Tf`WsCgOrq%fq{W(R5Np4IhB=_dwYA5 zl9GLWeg6OepM*`ckXpQ$Vw01Te}8{@d3kzzdUtns;Q#=9e0+9xc3)p#hK7cPg@u=w zmw00009a7bBm000ic000ic0Tn1p zfB*mhxJg7oR47wr%-a&dFcgL1jkZxu>rhElLMsQNLY?0K*=*&)jQ{eRH4FY5V8h`k zisCqqk~ffXI?1vup*f|r0GN_|Ht$=MWr?t4Y|gn5oUa(G5Y`eD-)!reH#?~jXrYwY zq6i|5MaWaF$qnywmsY**4hKsb!T`Y6#gggUlx-W2d&Wl@Bjb+07*qoM6N<$ Ef+x(xzyJUM literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_boxer_top_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_boxer_top_right.png new file mode 100644 index 0000000000000000000000000000000000000000..05881e5958b335e58d45f15d44ac680b65624f62 GIT binary patch literal 472 zcmV;}0Vn>6P)Px#1ZP1_K>z@;j|==^1poj5qEJj!MRIa-q@<*yqobmtqM@OoprD|Oi;IwukdKd# zj*gCvjg5?qjEahiiHV78YipL4mWPLjY;0_Tf`WsCgOrq%X;d?FUO9n*fqQ# zdUSMjYHDhelaqCIb%cb3e}8{zX=#3bet39zadB}j3u> O0000fag7k{ zeO$3IqGH~370+4AR$tB98@D}b?R%*S8y9MD$>>b?juB&-|9G$Q5;ueMpLI^VFg)mr zZ*I7HPC}4DF2QK#ndika2YW;d-z~iU`eEK>6aN!SpLFj(r#D-~vd(^MuCyw{ikZeM zj)g4lmC_Cn7G#*pxO2nIvuVnoC%vh4Y5R6{L-9d5rQ?My9A-uf9!)IM``U1rdHI*S z2M!46oMv+FY)gC)*?&g7$Mt$?!IcK}Y0DH3c;}@EG<7;DmMV4pG-+m@vGw-bCybv$ z>=XPycCE|s4xMLfc;7PRU!m{zexDUJx6jQNRqlHKGrOWB{Nsl<-iBwp^0wc0O%GzY zAmCuJd~N(BUXF#9sz110?Eecy)<3-Q^Eoh*_);T0(|mmyw18|5AO?X;!IMFhr>mdK II;Vst035N>cmMzZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_down_turn_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_down_turn_right.png new file mode 100644 index 0000000000000000000000000000000000000000..f1f7fb7d3cc50933c4c1554235a264e89cca1bfc GIT binary patch literal 518 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXL!+mQV~BCAUBz@M7 z2WzLuzJDOSU{B-v2e*1VxfiQRJ#J$4p9>-hU~CIY32Hkta*?^&k5o2%)! z{dVa8Mu}T*%O+|r-MX#N-6ztrPnhLkg^eE1=9_1_bk?l!*y5I}efZ&pr|MlwNwb!{ z{yJ;N%^Zd1gAG5JPaK)>{AbzjSiR|USNfH! za4Fqx{^t0tQL2lcc?WJ6KcywW%*iHn*{#^(z}yJa4e`0@6PARnR`oZD+Npj?w>~*? zs%_wM{X_izt-rUw`WM-8={@_+)rnq5`#-&@_!98pfgjI-mnBv)#{W6KnRy?bsG~D| zTUy#VH8!u94T67Im+oT-JRg%^eDBJCU<~o4MtG+A`Z8z%*&IL&0+)g(gD6i|KbLh* G2~7Y*K8a!PbLoEEK2A%afoFH)LO4G`DIV`sqy9?TU zDXd}gwiV5vSKEB;7n@yEx_%RT;6f!i7cQsU6SfI>O=>eK{I>j~2H)GVeRpTRc{kna zZr=2N%w}7nbgczNT^DXtnWT2Su;#ve|M4`ACI?q8(VGi37F;`%VY2FhI*+re7oK|bh-nl@`?uDZL{92GB&u-vLbGMv~R=AT=t0@ zstPKO`nXy3`w3RZ)f>(9nEUZI>w`^vc{yO)y#7cDOL7vnc6RGsW+o~2E+dT34 zUzVH;x1WkJedXDf_iOj|UpZ%|v+X+`wN`BJf=MBLJLc?9)?OvI*y-hjoz;i_{GKNl zKQrLt#<_br56`Z9=6~|A`s07h(hSQlzkKlSqu9qB&6`GCPpyQM{;}scaEa?Q?RWUX rY!z=C(|1Qm7Z@jesS%!OzP=1vKsE;ugTSTW$so$p)z4*}Q$iB}J|oWr literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_left_turn_up.png b/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_left_turn_up.png new file mode 100644 index 0000000000000000000000000000000000000000..959d1982bb839af2efd96af9ff0bf0deadd9cd2b GIT binary patch literal 473 zcmV;~0Ve*5P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940d7e|K~y+Tl~F-T z!%z^Ngn+g?TWILgr375`Hr~LRU2*5y8;HF@@8L#pAu3qJg-Ai#G>}L`(#A9~zWMY0 zwr<2nI(>iUz4?=gH5d%&KVUVG9+H%y$o&zg^MI0~4yB zcgnG1MClzrh9|e0hu3TXEZ_IB8GL;7R;8^S2$y*fd1){pg#|0YUm*Gd70y6LCS+88 P00000NkvXXu0mjfdRfX9 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_right_turn_down.png b/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_right_turn_down.png new file mode 100644 index 0000000000000000000000000000000000000000..5345e832c76dc6e571d1623d40956b997ff77853 GIT binary patch literal 500 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufG}g$wN6f;hI~&K#}Etuse!)UhaCjwUTN4iZ%NbJi;Fqr zeii>=omO$`>gN9ow*F)K%QkA!eDB&q*sh7AoyFV9PptCT+7=UFIyMEV06k z5j9-5-fnxn%R}!v!}HSE>#MJ>((x`hV!)%`K7Gpn0H?)&ck7(K;NsnJhmq~*GV3dI zZU0@nx@wic+JzciXPMTpxmdlrvp~AcQBFByDsPP*W6%zEGlmSOE3dy!*pixTFweHx zgClF6+=PkeJ_jGUcu=Bt$+;UP3@^X`KD?gWdT+(CbD<)xi?(cNQ%h>w{4&5cz&t%* zgJb^mXpSq!H+RXszxV3itbCrD&WZ(pSf?&3J@WLI>~f{=5~5nm&y@SksK0;tv9_?0 z{Ozl=4Hmtbxxa0>|Fq-$ISexAKkvG$7bjTleNxVCVT`-eob%6f9Js`Fn)W+<;g)~z owlLn-BM=xLe5nzhX}-P;T0k}j5QD&_;K?A$)78&qol`;+00+{|V*mgE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_right_turn_up.png b/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_right_turn_up.png new file mode 100644 index 0000000000000000000000000000000000000000..e0214f3d4562fa7f232c4366ed2c92e4e70217e5 GIT binary patch literal 510 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940eMM8K~y+Tl~O@U z!%z^N)QUEcLMb#2uG}dF7rlkvz@1BLTote24aDBSL%4GzxDXXB;<6w%386xWZ461{ zn?FCPJMocD-=BH!&!3+d!{Lzr12**geZ3+oib7&VRGJLK2!dcbooYiEhNvwT3#DX; zT40){*d~)n4S!J-A*N}%Eb*ZLDLCSH3CP%hY@X*z$w1%H_W7uH+39qoDoB!KWe{L9 z&+{Oq`6r%1eq4F7EJM@=Se1V1`@UA2E%CTthqi5_Bu9X_jvvpZfZAYug3QQ1gXhA$ z0!PnE6UVVW5*8r1JI8TAbca&?8*C7_tXD8wr{R9L+ttew+8|NDX|+A~QF)$E0n0VK zHOsQVFcyx4ajtO04G(U?DCtE9H8_It%tRPUie=?nAC zJ?8H>boa!BinonytQb-Jz)!`ad(DGeHUNg}y6tuw--SMXIg&s)w^cWZ6S4s*T(A=S z1)?99N>-RnqM-2r000hUSV?A0O#mtY000O800000007cclK=n!07*qoM6N<$f}S_m A)c^nh literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_up_turn_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_up_turn_left.png new file mode 100644 index 0000000000000000000000000000000000000000..7c0e16cb9ba3893e93a89b706706c0a93ef1b431 GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXL#d~WV~BZyikSAaY`5#2 z^UoFbGZ~qg_y%7${bX}K_WIV|>hqt?X7|4T?I@5?$KlAUg-GC(tbt*$D2-$2A$KtP8{78 zxBhtgWa+ys@~?wkE?Fkz|GD+pg3)=hisWS%sU4*WJ7eCJS+C@}<~?5%rhTV#1>?^wc4qbFg9`NrgIwQxt^M9;_LVnmdj1*z^)svazkE5> za_ju$SFwhRa*myETz+1bU;ZXT#D)CkWsUtb0-Ae#e-LEuvGWDw=)>gTe~DWM4fJ)p!* literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_up_turn_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_grabber_side_up_turn_right.png new file mode 100644 index 0000000000000000000000000000000000000000..cda6ec6871a12199e3ecb2fa447b8d5c069397c3 GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Lg50X`wFMMXtRmMmGkc=4h|ixw_ixM0D8?(Xgh6DIWc_xJVn_4fAm^z?Lf zb#-=jW@l$ln>MYzy}h-yH8V4_rKP30xw)ySY08u-H8nL1Q~uZ1);2aaR##U~nly=_ z;VwhhyZZY2%F4>Bs;ctx@{W#{FrU@?DM(v^M`SSr z1K)lSX0%`pRsjm0^mK6y(FjiM$qsHd5OBTD72@p>G07o_Q`KxqYHjq|{{R2?$1IPx zdVF)QarOE3*8edE-A7X=Ey``-tbUenzArlXyZ}7 z-c4m^ADJD#r?`vnYJ!=L%fjmCRdOba(*y5h>g}1EXMUR@AT-SQ&g;oDmR&otVs6+g zl~*UDmQLwQv;7s@uqpG~@5BznS!Ht+8SdKK*j@b0eet#Q#fP#ln%_U3_}TMIse;Di z?ceK8pZUyJ_rqQC9LGa(w*?Y;x1aR30zJi-8sVAd>&u`8WOD#92wV!D45B<;{an^L HB{Ts56rSDK literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_grabber_top_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_grabber_top_left.png new file mode 100644 index 0000000000000000000000000000000000000000..8877112aa3e2e29e38fb1e00713fd2884ce0e383 GIT binary patch literal 768 zcmV+b1ONPqP))=wP)CztrNlaTIZ9|eG#Z_=|5FA7o zzXtz-u7azAASi-}o4a3&NIcgH710}R&cl1}dpLOmp@ePbz1mU87koE05!YsB=d{Qp z^|TXZgihV`oUvpw!N2S6ni^HF`c$v~@BO(N7cI|(ntI_O({X)anTEu&?C`xcR8KAYgN+|-=G?q+k8mt+m(1^Z)R#o9!t|8X zcG(?xq?jO%hCzuXY<&8p79_L3ef?j)Ns8hzPj1i|}$5PTd!_zq4BRew=(8h#ahqpHPrp?MXK&#IcS z1t)9JcI)V_{w0NFhcX#>I)bKIXt{)j`ASyb=N#TZdPRQG1#Is?x7=@D_ykeoXfMH= zVGd00B5jL_t(2&y`X;Zi7G&Wf7HApa^_`q$L%% zN=xfHH!zM*kQ^b$Nr4m)3s^$Pe9R|rchDG<#(5HGX7t|7?AsMV5E%b~h0phW&ZlXj zKL=D7LZoRL$FW6umSxidEGB?Wm9}k_pe#%3(KOAnz0l~o&NNM4K}F*@4#QB_^+h9! zBBapteGfJf0BUD)PQBy!=l$soyHbUK7-FiZl^_KbIoQXSqj5f=2o14a*To+*uL4@y zw(Xs*+2<36C@$j7`H|uJHA(1-LKF yU5UY?bU8!`z{a9W>fg7>PAWm3=P>xr=lu&$N<0Z;1?Has0000)=wP)CztrNlaTIZ9|eG#Z_=|5FA7o zzXtz-u7azAASi-}o4a3&NIcgH710}R&cl1}dpLOmp@ePbz1mU87koE05!YsB=d{Qp z^|TXZgihV`oUvpw!N2S6ni^HF`c$v~@BO(N7cI|(ntI_O({X)anTEu&?C`xcR8KAYgN+|-=G?q+k8mt+m(1^Z)R#o9!t|8X zcG(?xq?jO%hCzuXY<&8p79_L3ef?j)Ns8hzPj1i|}$5PTd!_zq4BRew=(8h#ahqpHPrp?MXK&#IcS z1t)9JcI)V_{w0NFhcX#>I)bKIXt{)j`ASyb=N#TZdPRQG1#Is?x7=@D_ykeoXfMH= zVGd00BBlL_t(2&y`Y3PJ}=dq+wt&J7pGZb<2)h z>5@Bm19WcS6+DSIfbbFMgb?Ht!0LXaX>sFJLg)3P>V2DqVQAcf6TTn_)O}r7I+a0w z##m7lX_}tsUY6ymL5T@qlV=zPA!wQg=QxhbvK+!61b~STym_8+5)Z#kQ}~l4VG@f( z-}k$K&`Eqt#BqFmc!7p8Ow&a9g#c0#*tU&kz9guCtN(^ZEz6>~+muwTS(YKH(Q)H^ zC+IMw=IQgV4n;#fE{i~<~R05AWs0{j7xG=H;6L_t(Ijir+@4ul{OMIVOJyO?+v&tUI0JfpRViH)IymU;*m7J`9S8wrM|NjA5E4#&O&Y0Q$by3C=mnvb@x7+v2_7 z4VGomK+2W&-hYn}LeRi43;JkLLOxZ?v#ERer8wIS000000< KMNUMnLSTZ~a$p+( delta 261 zcmV+g0s8*@0kHy*G=JzxL_t(Ijir-Ij)fo)MGqZjvYNLJhpxmGxjPf169b8WKo4G^ zQQxn-?*ysTJ*f*Q`o2&6LlWS2yB&%trLxxFSwaY=X<{75I{;vw=VGXhH7KQo5Tewr zwRga}t^f?f@X^>^*Bv9o7zrT&ptXK!R!R|L#5s2a#28D{Gk%Ct3V?mzOTPrzw(XGl z5hR-dLI?%$1zZj-%NT<(=2Fl7TI-((f0fL{M{1hpb3lE+aLjyGedy9!%Xx}d<_qAr z=CcaGdr#Z8muYgmTsyxR3E;iQId?JEs(-2&W7$i9Wm(=n;b-~=@_xsC)EPx#1ZP1_K>z@;j|==^1poj532;bRa{vGizW@LZzX3P}QzQTY0fk9KK~y+Tm65+n z!%!5)Z<2yWEFId}St%&=EgThn2X0-E;1_Myu6Q|A96%8jXCVRGOv|3zDUkVHmFKI*yYYhQpzV1R{bY zNkT*o$n^VtlaJ?lL{h%*kH_O)uNMSC6h+hNG>&89WHR~6fJ__MW;UCJVaR5V^ZB}e zL}`+!fd~Lw{1^nN-@C_T03JZ!@(U-Ce2Et;dsixztAms9P0a#D5%LggNhODSwOWl9 z#Gosn1`tsrB7%a50C32>B^IO6X#1?Qys8yD=k2Z2wq{Dz>vbW5Ulj&}!DhE(ujn6e zJUAJVUe9513FUGbMwgalG1iTzU9QD6O*lO;VmY)-@>c~R#bhK|+?qf$+qQ!{zaRDsOx)8RQj?IKW0oR|5iT*_il3TUTOm{n$2dlTIFQY04N9$ muFK9RsSTt!TqgJnN__+6R$*}{Z8A#$00003d4O{4$r>%y)1oO z#M`pj|Cr58X8TSS)Lg2vu2XMvYNVq8PrGw6$Ke1MCc&95nk$xGdjCE5k4s?7jMSS& zJ6&SdhAHfgB4fFJ z!`sUaZfWT#R-4TEZS~cxj)2GB3-!diLK}EJ5*(U15-b?Xm9iZ6-MV$4^YyNi%6wjL zneEor95o8H2}?hJW;_4P-{vLXkF;F59rkaLWZ<6z=V!TpZ)4w{!>}f7b!+x9d#38w zs>YKXEaX>LAIr&c;1plOTHp9Wn)gkdp;}7TVPHJ*rABzB`T8NS%Lg50X`wFMMXtRmMmGkc=4h|ixw_ixM0D8?(Xgh6DIWc_xJVn_4fAm^z?Lf zb#-=jW@l$ln>MYnu`x3EIvNo=RZSRTU$#@OG86LNl8g*X(`YZoSdBhZ*u;>!3YHZ zt~30(%JAz7!;ec0PYyDyoy73}Ci|E344=+2ygJ5ES65e2QBhb}$mMm>2BfpVBeIx* zf$tCqGm2_>H2?*Vd%8G=XauL8$;>}wz|)Y}|5d`|ZPCO@Y+i0s3+^4=Sorq;|Mfc` zonEqclIrV;IX~_*n@ZWLdCpqqY3A_HWS)rY#Ep{-!x(Lz|D3_CX!+brlgaX8aH5Yb z$9$nPMz=d|NxZyMb5UqRkZH4k&a`<8Y6^P=N|Y)uuVZSsmRFJJqyAoC@$Bw%SLVjt zKj^map~|IWOYgI-Saa86tC&&N-ERU6@%Qi9e<*I>VXq*!pJ9Kd{oIUm9n+PaO7~X2 z4-dJY|FFF-~=2TmaYT}|C9{wiM3b6R1ja_oKDp{u(D`QH|#J)5($ zIDgK;1cm>NhF_}oS_x~O4qB`l8Yy$Ub5Vxf{OfHubC%^wajo8bVv`P!^Ykp4s?4gaBrE5+pW1k2k;WyHzh+M=*X=!;)cEVKYuDB}?CxvB zx_7ze9yrBNwC-p^X#QI+7XRIM!%Q9SJUE}=y8QA@>2E6&4i{V4wdzmz&Rf%@;`wT7 z2bYbDE#sOn?JELT)UHp>VVYrXDYx>MdYyEM>)KVboVP4(c&)@+8!L3Z)N=3bx2HC| z|83{`%`r=V0o&&I%{OE28|jvQUwv8a$I?WdNq4396({_--5PUOQt9dAvVQ@F6Q3OW zqtm}WTP{|Lxu8kmLF$hmXVyhY=P!u)t~ks6utO*NI+l9JC)~~xy*6GsA`$?M1-{e> d&op0O1}z|)1BgN3Qt)ID<>~6@vd$@?2>>l(%l7~P literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_in_side_right_turn_down.png b/src/main/resources/assets/hbm/textures/blocks/crane_in_side_right_turn_down.png new file mode 100644 index 0000000000000000000000000000000000000000..fb2fca3ffb5f0a2a91f5716068b47d41691d52c0 GIT binary patch literal 530 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~8hSll978Pprv}=39}W=N>)9-|Fm~4zv0Ysp ze0Tq_>+v=1-YwYvZ(3G;TXXZ|=I#dyS{jQKB1EGu@q2m9o}pGb@Ao_7zDEo1%&UI4 zbLabg>058-{^H-U@M_k~9uG~`jS5j}r#IEyfB*gWvP2W9PEQ53$r`NNHTK4xKNc^* z(y>VCT-xSv-s`2Z#~XiqWiB}P+2;Hv9Z#WxBL@>clw8qWdx`tvyGV5&XP${dO8ySb z3uf?{PdIDorRf{&vgD4y@r^4OqD>y$+x;RzY9EuV`vfiX4{=fx3iuyQQ`{QGyGT>J z_3=#E9Ud+3Yv+_KF4uZF@A6#djtJ&m5)Jn`6~0#OeJQ)c*O-yz-NS+vbJ># z>&9&R=$_rXp5w_e%zX+CYg@v#r=L!U;NIR>v@|HvD*krW?fHJoJsOWDDSEpH9+}?3 zKI?v>OV0YwbN+BfPu$$drOJOM+-zoj+@-I!!a?Uxzg(Q=@=*6bm)sqRckzYH36=B0 z*M@!U+Qb)Q1Zd*k~5G4tKnmaC<-bV`9@$!wj|Tulc)+XzSKO-~Z)I4Ro6x9Z+N|H@#lZ;^#NwHW|4j8lyOr| z^5y5BCIQo)mL2Vyc);eW>+-vKi}y#Z-DZ5@5101TQ@>c>?kHJsz0E>&>P`QX(y#YA zUwdb3yKj?%=`G*;Ta~)z{S1Eb;pB@4jm!;CE%@&7{o}h4t^d*4g<(;uih>FVdQ&MBb@0IHJIRsaA1 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_in_side_up_turn_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_in_side_up_turn_left.png new file mode 100644 index 0000000000000000000000000000000000000000..763c68afcb43742678492bca845eddfc1f256d05 GIT binary patch literal 507 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXLz$EqdRZE-$5`UbVupYNS}6Lh#V z_80#R0|}llT`O{ z7r*UJtZ(Sy-Fs!+Cl^+&FUEiAVt0M8}0t*3=v+S}m!X+I{x3@k2Z0RPzTs~p)!i0GncAd0jk`-i} zkSbX&@VaWR-G0e?*3%_kKFT}c#Cm4g%tQN_XRQmb22Wb_i4++&S zp{WX;f-Di=3T96Vs(QCMLZ?7|5!;j1rEGCCmd)IsuzFMZs&CSZeQIZ4y(;~AvGKEu z%(i=t7JmD@p)R~fqx#wM$1goT|Cq?z@X(?!HS&jhLVoBacOj1F+p^N;^zwQNS%Lg50X`wFMMXtRmMmGkc=4h|ixw_ixM0D8?(Xgh6DIWc_xJVn_4fAm^z?Lf zb#-=jW@l$ln>MYzy}h-yH8V4_rKP30xw)ySY08u-H8nLp{~2m)Ya1IItE;OgO`7Cz zox%AbLw$XHWo2bmRaJR;c}GV_Sy@?pe0*D5TU}jUNl8gVLqln4DbOLDoSgq}a{j-; z2n7GGGyJ*A@aqc0k4p?s4l=Br#PI(n`t~@QBhb}m?JRp4MG07o_Q`KxqYHjq|{{R2?$1IPx zdVF)QarOE3*8edE-A7X=Ey``-tbUenzArlXyZ}7 z-c4m^ADJD#r?`vnYJ!=L%fjmCRdOba(*y5h>g}1EXMUR@AT-SQ&g;oDmR&otVs6+g zl~*UDmQLwQv;7s@uqpG~@5BznS!Ht+8SdKK*j@b0eet#Q#fP#ln%_U3_}TMIse;Di z?ceK8pZUyJ_rqQC9LGa(w*?Y;x1aR30zJi-8sVAd>&u`8WOD#92wV!D45B<;{an^L HB{Ts5D+Jw3 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_in_top_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_in_top_left.png new file mode 100644 index 0000000000000000000000000000000000000000..23721ae91edb5e07364485d2f68c0ea931f537a4 GIT binary patch literal 776 zcmV+j1NZ!iP))=wP)CztrNlaTIZ9|eG#Z_=|5FA7o zzXtz-u7azAASi-}o4a3&NIcgH710}R&cl1}dpLOmp@ePbz1mU87koE05!YsB=d{Qp z^|TXZgihV`oUvpw!N2S6ni^HF`c$v~@BO(N7cI|(ntI_O({X)anTEu&?C`xcR8KAYgN+|-=G?q+k8mt+m(1^Z)R#o9!t|8X zcG(?xq?jO%hCzuXY<&8p79_L3ef?j)Ns8hzPj1i|}$5PTd!_zq4BRew=(8h#ahqpHPrp?MXK&#IcS z1t)9JcI)V_{w0NFhcX#>I)bKIXt{)j`ASyb=N#TZdPRQG1#Is?x7=@D_ykeoXfMH= zVGd00BTrL_t(2&y`Y3PJ}=ZZIG2QA%Qy>6L#Ff zr4uiq?pPU5-~ncw%sDi1<=Q*Uaxg;pEeIJt3iz5gX&c>WC3LEa_v&v1K_LDk7Czti zl|7ClU!~A*7)FvLQ50FUvn(4mQRHD5@EViA)3&W7lx4{nP1ES%;UPya$;1a&-}iN0 ze@qgFAxuC&Cm{gBaHg^uJBr@7w`tIB;Y<({vmM3UYoE zShQ{1uXmezC;GiW5((OiqhoP;f91L^F;!I^N@ABp1B4f%l%GwLT@=OQX?1cYy_YY` zi^nAqp6AULhtaCR$8miAuzJ3}p-xWMb!Y%h<304CreRrDnx^2SSxQ|EaCRE{Y9TlQ z<>C6c<{1I|Vn&_JO*8q705l5Kp}%iYO;Qr_Jja0lc-~(^zCrx56djlV0000)=wP)CztrNlaTIZ9|eG#Z_=|5FA7o zzXtz-u7azAASi-}o4a3&NIcgH710}R&cl1}dpLOmp@ePbz1mU87koE05!YsB=d{Qp z^|TXZgihV`oUvpw!N2S6ni^HF`c$v~@BO(N7cI|(ntI_O({X)anTEu&?C`xcR8KAYgN+|-=G?q+k8mt+m(1^Z)R#o9!t|8X zcG(?xq?jO%hCzuXY<&8p79_L3ef?j)Ns8hzPj1i|}$5PTd!_zq4BRew=(8h#ahqpHPrp?MXK&#IcS z1t)9JcI)V_{w0NFhcX#>I)bKIXt{)j`ASyb=N#TZdPRQG1#Is?x7=@D_ykeoXfMH= zVGd00BHnL_t(2&y`X;PK8hu5|Mfj$=d} z&We65*f1_%LZduCS(XJtUDr!W%-(UFEgJ?k@XNZjZCfNB-u=f9AI8m{u#2K#8`hK% z0B2d2u(ZU)YWoGoc5&z_Dxx zw+PT?@OEP6DI2;9z{Xx|slRtoc2WrPJV%57xZXdpAW<$8SW%7u0000^*Bv9o7zrT&ptXK!R!R|L#5s2a#28D{Gk%Ct3V?mzOTPrzw(XGl z5hR-dLI?%$1zZj-%NT<(=2Fl7TI-((f0fL{M{1hpb3lE+aLjyGedy9!%Xx}d<_qAr z=CcaGdr#Z8muYgmTsyxR3E;iQId?JEs(-2&W7$i9Wm(=n;b-~=@_xsC)E05AWs0{j7xG=H;6L_t(Ijir+@4ul{OMIVOJyO?+v&tUI0JfpRViH)IymU;*m7J`9S8wrM|NjA5E4#&O&Y0Q$by3C=mnvb@x7+v2_7 z4VGomK+2W&-hYn}LeRi43;JkLLOxZ?v#ERer8wIS000000< KMNUMnLSTZ~a$p+( diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_out_side_down_turn_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_out_side_down_turn_left.png new file mode 100644 index 0000000000000000000000000000000000000000..760f1c1f34839998da3280ee8aed12bad08caa87 GIT binary patch literal 513 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXLyf14V~B*!iEVY8B!&#Yyvjt_p)ZAl@DwUZxn9iL zD%F3yP)6Nz)6JZ1w{!Q#{lCX(WcH-8ul;LPZ_2*^rG_$#OqwF6EzQ(oV$iJPWm>_0 zSWt<<=0J*3q~7$3CQ0>2HqN{6y1jE-ocO&;-o^0Z#!nnO-;~Whs}{v@!8kmi`Qw7A zQtAPMf(%O;w-!X|h+SV-y-LKqulT7&*QCr@PAt`;7d{>+^}oVwVN-DGj;P7)ZPs)7 zB&KzoJ#;f`>$1z5N)PsMvGVjvKKuMLj#cr;BBebP0l+XkKI&jA- literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_out_side_down_turn_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_out_side_down_turn_right.png new file mode 100644 index 0000000000000000000000000000000000000000..e9bd8e35259c231abea4f7d047508565d1d2a61d GIT binary patch literal 519 zcmV+i0{H!jP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGizW@LZzX3P}QzQTY0fI?HK~y+Tm6FX) z!cY)}rv;+8gbgd#nkFuID`dyY2dVZ!T)S{%;=-tj#<(B>Q^Jn~l0qs!rS+S8D;PG$ z6FQukduHy;v`(wllK(&x>h*f=iDX%3?UtCZIF2(Kjr#q5o-iJdt;oWPawp4B+eo+D zb@_{;2)kOXmdhn}ya^7fEt5wu=F`v)%1~XXZ zdETBH`yoP{p{*uQAREUh71zFh#EG6$Ya&h>D1~5g8@y_%%$%SheKxj zouD(&BA2pF^?z1gsZ@AV)Ux+80AL?3E89l52kZp3&9o&D0CjoF<#PN)XAAdK+e_a# zmZGQX)r<1OGv(o}+&?Rk?EN5lHB4mwsJ|_b9&$dq(*)o&n@wimi=ehS+I?`qa=q5{ z%*Hf<5DPYfzaa7rDTGmpUaP#;0000EWmrjOO-%qQ00008000000002eQ*~8k#&^978Pprv@5&9}W=MXTlnsIjtl^{dv~| zffxNPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940dGk}K~y+Tm66R# z!%z@~C!tj9w$Rdzdnvf+WB4X%z(rR+f)7y5^SBXQhzg3ha8Z%|WKn2H+nA=t@7@Ww z>P9@Y!?`o(%$+;&27`h82gcCr^{SIdS(X|dv1#!sXaIL~G?8lyfSD{?5(55so5t!hBB#@}qjf?7Wa$eczIo{QlS z&YksoT?J{HRwEGstLSt(5WNAQR)SiIF}MTU;Kj6uGZ>&Zfc!S-h?=Fndj=T=TnDM? zb~*UIuOpoYLATo_IiJswl2nfx%olAm8moJ{W&V-9?HRw+j79QC!}pI3f4`EO2ScQM z*(;tb6G`vP&++88;_1|89_W|WP50N2_ffNh2g1;d01?LPqk=GVM q_y7O^4rN$LW=%~1DgXcg2mk;800000(o>TF0000DH-?{LzWQ}`DPhhkV=j6v0fg-+Y!nY0PpWo`S(Dj-j+f^ya{^O#59$Bd^C_1@63II9C@aa{H~>X`_N0FH5S#+Sm&^^qLerg*r00riorypmB9;m1b&5rRrzf|l|BHC7=v&5i@ z>CVyBS6`PJta-XiuPSTntGjuH`hxshs+wG)ER*Iw;&q=?-ouls zf9AXYjQabR{u&D#$yfheZLsLc#Ql?w^G|axzr$d$@4dMc@18|@OjB3_&TT5%*?qK0 zTHp|?_rZ9DUyPh_7AC2e7=(e*!*~8VWsK978Pprv{$(I_w~_SD0n(ZHHMU597G> zK1nvo2L;EJJZ%^GtoWD7yoo!|QBYh@%W3k362VIXmrXw2**W>v+zO5D>F?$g%L|*% z^m$>Q(ER@QGnXsd)*g|)m>J}y>bWUGrzde|OqYj(QgKG~3RUCz=XL+2Mz%$ShF*N= z%$%|}PPwkUp@-M^a?bW>7sg+4?GJq=tooFBZz1H72(zU+r=; zVT;(huk*1)>q0xXX)jt{7;*giYqu_iMWr%xNr1Gq2Ybr;Ljv<|mT>7wN-%_&C_A3Y zTWWKjc_LrKith*6Rvg{H&r@b7w|iaoIoTe^MGP_59H!X3U*5Qwt0}=iq9NBzx~C=k z^rjD+4nGt)c{Qu`dArE^7THTCPyKJa{@SHJMQd$v?0eqmi;S;VRwdSz9Q*Tn+PnEP z1Af;<{ZA`KNb$ o^Ik{gGy-FUFEzq5&DWPf3&`dGVi33#JQ+lJy85}Sb4q9e072r)ng9R* literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_out_side_up_turn_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_out_side_up_turn_left.png new file mode 100644 index 0000000000000000000000000000000000000000..3a5c6636e786a5ef655616f16d07fe3025796a38 GIT binary patch literal 500 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXL%yerV~B3O6#lnNx zjxifPIj*V|n17(RlY6n6RO!K{WeytloW8+aBCpKLXKgYxoVVrhPUGiyW>$A!fB*fd zeSq`w%PYf_QX`|*bb5C`uPl`DSDSpwVE%dE6obI68s1l?N%FPx)=g4T%-eqZY?`wS z58H(JMjzhx!-@OvZ$7t4hv)Eag^ooTd*k}u7JsZb^Nqt{-g9^61_Oy#0&1Hgbn==W zSaEy^(Cs>8qP{0WatiapA3~Pmj_xK~Zohq5a*8AE0$-UCm$={Dog7(7OcR!^EHikW zwRP9mzj^DAdwk#behOFG>KTVOGW$+HttzKo@VX(fZ1>z$o~Z|w4jlgG5*|7sg@ySv z+xAS&<=5>t-|VqAG~KX1OuFP^j@jn$ZKtHC=k51DRdgxr>$ljSH>ZAj;W+Q!6px>^ zQ8gB7llHv`{`_R;qmPTF8m_-Bi(V`CpW|EE(pMgAk8fQ&d*Tc{r~^~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_out_side_up_turn_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_out_side_up_turn_right.png new file mode 100644 index 0000000000000000000000000000000000000000..18271a72f6260f0ab2f4adb1a9a405d9f40c7cc7 GIT binary patch literal 525 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXLx-n}V~BV3!Yz!&awCu(9QuNTvVX=U4J_*R$INx1yaoUR>>b5$8&*j&5SK zY_8fEks#s8+R7Ms{p%~a3k#*^Y)a};NMJ6Kn6SdkavytwdaC@-?4^yuI*EVV+zOx0 z*_|41v24}JS5KOE79PA)z2teh+LU_v<@37)UDyAaVpF48@!<%YL-zLDU#n!fk8Qsi zSg6`qkhePR*xefqLSk!J>Kk9M->ZmkvbVj?4U8zh)CkWsUtb0-Ae#e-LEuvGWDw=) L>gTe~DWM4fz|_%A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_out_top_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_out_top_left.png new file mode 100644 index 0000000000000000000000000000000000000000..d2ffff31e885d294c7227355b112bb9d6451bcdb GIT binary patch literal 763 zcmV)=wP)CztrNlaTIZ9|eG#Z_=|5FA7o zzXtz-u7azAASi-}o4a3&NIcgH710}R&cl1}dpLOmp@ePbz1mU87koE05!YsB=d{Qp z^|TXZgihV`oUvpw!N2S6ni^HF`c$v~@BO(N7cI|(ntI_O({X)anTEu&?C`xcR8KAYgN+|-=G?q+k8mt+m(1^Z)R#o9!t|8X zcG(?xq?jO%hCzuXY<&8p79_L3ef?j)Ns8hzPj1i|}$5PTd!_zq4BRew=(8h#ahqpHPrp?MXK&#IcS z1t)9JcI)V_{w0NFhcX#>I)bKIXt{)j`ASyb=N#TZdPRQG1#Is?x7=@D_ykeoXfMH= zVGd00A>eL_t(2&y`X;ZiO%qG!|7F3TS9jN223a zuceBT3*-P0l5-?&F7t|j_!S5}@h4+1+4zwr8Ohe}dd9onwG~B?_z!HXFbvt>wvBc+ zC~jF+Q50F0+2mJMwHaVB0c?s4!=MCh+tM9<-<#K48q+kfU@vK1*JWA8al{#1?3Cvd{Z8g@z&o*z-J7L}frFpuz_`eR(}=5;Vm2JP$jv{RpUN$8jDW z75gFtk_c_w2=R0}xvoo`uIu)asLJy<>7wsu!-V7vP1C$5$(@dV#PM4k6C((MD*;-| zea!RxIZ1By0c>cXM04#_jY3W8@4v{MRD!y$(cnLR?=QBrE#VHJQ;7fo002ovPDHLkV1gQyS(g9+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_out_top_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_out_top_right.png new file mode 100644 index 0000000000000000000000000000000000000000..78f357645e1e02bbafde513763b0bc871fc15f52 GIT binary patch literal 763 zcmV)=wP)CztrNlaTIZ9|eG#Z_=|5FA7o zzXtz-u7azAASi-}o4a3&NIcgH710}R&cl1}dpLOmp@ePbz1mU87koE05!YsB=d{Qp z^|TXZgihV`oUvpw!N2S6ni^HF`c$v~@BO(N7cI|(ntI_O({X)anTEu&?C`xcR8KAYgN+|-=G?q+k8mt+m(1^Z)R#o9!t|8X zcG(?xq?jO%hCzuXY<&8p79_L3ef?j)Ns8hzPj1i|}$5PTd!_zq4BRew=(8h#ahqpHPrp?MXK&#IcS z1t)9JcI)V_{w0NFhcX#>I)bKIXt{)j`ASyb=N#TZdPRQG1#Is?x7=@D_ykeoXfMH= zVGd00A>eL_t(2&y`X;ZiO%qwBbSVS{ka0vbD0RlCwwG?Uib*e*h`E>nq(v_dzo49&YDM2#QuW|zAy~+dD}Kx^@ie{ z^Rg_nEW6OTs;bR^78Agx$T*Ht&~+WwX`0q`J*7Vh01F>@%d%i49)4SvjHhYJ6;_2| z7!Cp9uJEOhB*}9eLqj*r^Gx?k0i+~w90$#ODo_Ehag0W7+ors`OS;xP&yn@c*j2Hy z`B0jt+s*Sl5cuK5Gk*a5Nkl6Nur9P5N^N@AWhSYO%a(_-=CnAqG=lH zx^@BpWm(P#wAMsXw8*n8!x-ZP`o5n7K9;yK=G=m{b`Dfk1%E)2B#V3)1^|L}i z`zObbdpNv1U*!8vPM-)k)345a-oKoA^Nbw#&R2P!OB~0H<9IQP>$&)!%36zv&~=@A h%5B^J>2WQ70Td@Hz&nXJY*PRL002ovPDHLkV1n+Uidz5x delta 316 zcmV-C0mJ^q0_FmcGk*acNkl$npw~1Afp+e@B0bx04#^kJ5c1Ff9Es zEcaZ!AJ6$KvNhWddlf~IgkebAwu}4k%KfRVwTK91Sq?)iisI%KzN8;&3D_U|V|^R| O0000$npw~1Afp+e@B0bx04#^kJ5c1Ff9Es zEcaZ!AJ6$KvNhWddlf~IgkebAwu}4k%KfRVwTK91Sq?)iisI%KzN8;&3D_U|V|^R| O0000uK5Gk*a5Nkl6Nur9P5N^N@AWhSYO%a(_-=CnAqG=lH zx^@BpWm(P#wAMsXw8*n8!x-ZP`o5n7K9;yK=G=m{b`Dfk1%E)2B#V3)1^|L}i z`zObbdpNv1U*!8vPM-)k)345a-oKoA^Nbw#&R2P!OB~0H<9IQP>$&)!%36zv&~=@A h%5B^J>2WQ70Td@Hz&nXJY*PRL002ovPDHLkV1n+Uidz5x diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_down_turn_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_down_turn_left.png new file mode 100644 index 0000000000000000000000000000000000000000..1d6cfc0b0c3e67f7eddf1d568d80327a5fcc997c GIT binary patch literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%LiR0X`wFMMXtRmMmGkc=5u83l}U{(B0iVVZwy|{{FtczTV#6o}QkruCC6` z&g|^$Y15_^7Z(>67UtySG&eU-nKGrdwKX%uxH!&o`t<3Ijg8gS)srSo^7+rOXGYTG z$&+hqYbz@&w@ipCFE4j~$S}Xfx2&uzK0dy^y}hlit)!%+p`oF^zP_}y6zCRCPR{=~ zIse~a1cHCp8U9>l_;rQh$0dd*2N~8*V)%cP{mXfVPiGlk9b>4gtE;G}IMF-h4@g^q zM`SSr1K&XqX529``z=s#m#2$kh(>VgnVWn~1_G@Q0~s5;l9qCWwKkO|-!YH5_kX9% zgJVbZXQq6Lm-%sBDR)<2qJ->buCVK6G1pBa`wgElep%c2o|lZ&dYfn>!q8%|I=71wnXFFgUfBp c>ofkcD(Q;NS%Lfm0X`wFMMXu$#l=gOELpsG@qz^l7A{=a-Q7K5!i4_*{=UAx-rnAxo}R9* zuFlTR?Ck7m)20;`7UtyS#K*@sH#bk2G9@#_xH!&o`t<3Ijg8gS)srSo%FoZA-{QMv zLe!oaNzM-$YHMpND=TwzbIZ%iJ32ai{xg)7m9@9Gx3#skwzgJPRh5*KG&D5S*VmVp zmI58c$;tWuCg=Yfj6m@3I>Vo<48N{0{J6yM>%N?bAyTVfD9(QGyDcJn?=EHvt6*h|V^c%u|-Onp| t*U@j>^!xYnDYGUni)?b2)~i4K)4sn@!eCCcCnz!*JYD@<);T3K0RTWV+KK=G literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_left_turn_down.png b/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_left_turn_down.png new file mode 100644 index 0000000000000000000000000000000000000000..99d98ea56f04b78c71d815d914b0341be1d376e4 GIT binary patch literal 507 zcmVPx#1ZP1_K>z@;j|==^1poj5y--Y4MRIa-b8~Z~q@<&xqoAOmp`oFRi;IwukdKd# zj*gCvjg5?qjEahiiHV78YipL4mT_@$Y;0^_UtfcRgOrq%X;d?FUOAVSmw|zSdwYA5 zl9HclaqaYeR+9#O#c9SdU|(vcZi6HL*W2+c6Nt{hlYlRg@uK5baa4# zfNE-Lb#-+B000RI3IEv%|JVTm0RjHk0Q}Ve`qTjU(g5Va0IiY$|Jeuh&j9kx0P4m7 zetv#sR6;-y_^>NH9Ci*j6BFA;*KS*5G5N=;|uvIPYCUT?Ov`yu+>6CI8~ xCw`yLd@e-S13_@RYpv(3ZI=-8jsX8bd;o1C7upqD@>Bo-002ovPDHLkV1iOE*R%it literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_left_turn_up.png b/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_left_turn_up.png new file mode 100644 index 0000000000000000000000000000000000000000..bbf523a73ba7a4bb36c943ca83252a27e68252c8 GIT binary patch literal 508 zcmVPx#1ZP1_K>z@;j|==^1poj5z)(z7MRIa-q@<*yqoa+Djf{+pp`oFmprDJ3i;$3z zkB^Uzj*fPAc1-^OL*W3ZsHlpHiiwGdYinzkmX>pKb8&HTY;0^_UtfcRgOrq%X;d?F zUOAVSmw|zSdwYA5l9F$4Z=Zxsw2)eplaqaYeR+9#yqIElcXx=0h=+%VhK7cPg@tr< zbbx?>e}8{0OY{{t&#x$*$4E`0P@WM z>c#+metvj(c&qU5{r~^~32;bRa{vGi!vFvd!vV){sAK>D0L4i}K~yMHWz5@df} z;ZfvJ*mc3e(xs?SaTP?yb3OO{-^#&wVbU*|Wb!97@Lz{?yGGBnEX%ap;C#4-$9P}( zLWlrh;CzN5W1L4aj$;a6MyOQ6c%syII;1eN$12Mi&olKiDJTe^wRk>F9IYw%Gyat2 ziK{&cFrPPx#1ZP1_K>z@;j|==^1poj5!%$3AMRIa-b8~Z~q@<&xqoAOmp`oFRi;IwukdKd# zj*gCvjg5?qjEahiiHV78YipL4mT_@$Y;0^_UtfcRgOrq%X;d?FUOAVSmw|zSdwYA5 zl9F$4Z=Zxsw2)f7m|~NYlYM=Cd3kwlZEZv00D5|QcXxM)h=@%80CskEhlhuThK7ZO zg>-aufPjE%YHD?LbpQYW2?+`R*$MyH0RaI4{?`Ef)d2d`0Qk}X5FBXYRSRt`&F`9%X(I()c_oDvwi=- z&o9K?9`W!E_(SjGkfZGL literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_right_turn_up.png b/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_right_turn_up.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc53b86ee98abf10d84932e6f527db036d07971 GIT binary patch literal 516 zcmV+f0{i`mP)Px#1ZP1_K>z@;j|==^1poj5#!yUDMRIa-q@<*yqoa+Djf{+pp`oFmprDJ3i;$3z zkB^Uzj*fPAc1-^OL*W3ZsHlpHiiwGdYinzkmX>pKb8&HTY;0^_UtfcRgOrq%X;d?F zUOAVSmw|zSdwYA5l9F$4Z=Zxsw2)f7m|~NYlYM=Cd3kwlZEbpbdUtnsh=_=XhlhrS zhJ}TNbaZrpfPjC0e|2?r000092?_t%3IEsu0RaL2*8u$00Q%Gb_|gF6!2qq20RPzs z^v?kD%>e4g0DgXcczAde1cD*}000SaNLh0L01m?d01m?e$8V@)0002TNkljBzei9LE&;R-|>pc%t(S83{9xt3!V3c|Wxrc3fU$;t*4;A*|u z;%<+4I3k|TfEU`^mgWob`-Bkw{2F6?(liT*=trpjQR)wEEEo6FP^C@)0000NS%LiR0X`wFMMXu$#l=gOELpsG@qz^l7A{=a-Q7K5!i4_*{=UAx-rnAxo}R9* zuFlTR?Ck7m)20;`7UtyS#K*@sH#bk2GNrY(H8aGxIL^}NKZEl_hUwF%H#Rm_S65G( zG--Z|@0JNslP6EEt*x!BtlTprsl2?rtgNiPy}hlit)!%+p`oF^zP_}y6zCRCPR{=~ zIse~a1cHCp8U9>l_;rQh$0dd*2N~8*V)%cP{mXfVPiGlk9b>4gtE;G}cw}yV5u~la zBeIx*f$tCqGm2_>H2?+odb&7SBAkgq|tB>(X9wAll(;B+lKmYvj@BG!E z*e_=f82#trj=z>K#e2zQdhTuA<1E|Xme$-akC<*K#_%OZo98#1xKn_H%d{zli;^_k zUv?adP%%0!JT<+@NLORS6X&O!Z(N<_6keNJ`R1i1djyATe40yDE9cX6&58R3re?m9 z%sYNjv|XWV+RI66mMvby#<$~MPWcXd1v&qY=iCpb-rFuc*ZR@p9s!&9sMnS&UvoL# f68vC4XFubwtzt7xI_6vjdW6B#)z4*}Q$iB}-sjG^ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_up_turn_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_side_up_turn_right.png new file mode 100644 index 0000000000000000000000000000000000000000..51827914cd045fec627c2eb9d630cfb281e01af4 GIT binary patch literal 509 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Lfm0X`wFMMXu$#l=gOELpsG@qz^l7A{=a-Q7K5!i4_*{=UAx-rnAxo}R9* zuFlTR?Ck7m)20;`7UtyS`21&Ze#j6XAK%>EJY~w1%n;+^ILqnNr#Ch>R##U~nlvdt zKYxCU@0JNsduAln*49>5R_5mBmY0`zbaa%Jm9@9Gx3#skwzgJPRh5*KG&D5S*VmVp zmI58c$;tWuCg=Yfj6m@3I>Vo<48N{0{J6yMNo6SGe-WP2YP-2nzRvoA^ zb=svPg=Ze73Mi_1sduc;JeK&RuW*uftjLPxs_cSiCe7`Hf zS)D_-EnKCdpV|>8{z}Vtuiv+{aJECc;+AKBvpai=jpxGg=hw~u=5%b^@3PzWLgW48 w%JYRUR=NxP`x~7tz9utF;A7u~JBH7g)Y`>oetGotHPA;4p00i_>zopr0Q1q^VgLXD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_top_left.png b/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_top_left.png new file mode 100644 index 0000000000000000000000000000000000000000..4d042062a00672ffd329dedb4aac3642c5c6dcee GIT binary patch literal 456 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Lid0X`wFMMXtRmMmGkc=4h|ixw_ixM0D8?(Xgh6DIWc_xJVn_4fAm^z?Lf zb#-=jW@l$ln>MYzy}hlit+lnarKP30xw)ySY08u-#l^*ig@rjeIgO2t)z#ILCQZr= zF)og?oIH7QZEbC3Wu?!5hCMTqs;a8W%geV+h$<^9i;s_Ye#kJt#kZuSq@kf<`t<2j zr%o*`Ev>Jw&&6PHiO%M$h3XeTXVY!&0y|k~FtAzg)T1&hc@Do1{ZdozXMavtK3n@{=8J0bS4F>FVdQ&MBb@0OiEI=>Px# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_top_right.png b/src/main/resources/assets/hbm/textures/blocks/crane_unboxer_top_right.png new file mode 100644 index 0000000000000000000000000000000000000000..5f1aeb266e428c2ae456f7945a33217e6cc40a8f GIT binary patch literal 458 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Lhe0X`wFMMXtRmMmGkc=4h|ixw_ixM0D8?(Xgh6DIWc_xJVn_4fAm^z?Lf zb#-=jW@l$ln>MYuxVW&eFefJ`K0dy=xp~TzDVZV0#c`I?r%!KeY^<)Xo-}Dvet!P^ z7T+xsqV~*4a(>8ATU%RMS(%%gTV7t?(b3`apP{U*ti8Rxt*x!KwY8z4Vd~VWlP6Cu zEiG+nX{oQT&&bLkOMw?%vOY