diff --git a/changelog b/changelog index 2f3e642c2..732031cdd 100644 --- a/changelog +++ b/changelog @@ -6,6 +6,18 @@ * Aircraft carriers can spawn naval mines, which behave like landmines * New weapon mods * The laser rifle now has a shotgun barrel, extended capacitor and automatic receiver +* Compact compressor + * Only a third as tall as the regular compressor with a footprint less than twice as wide + * Comes with a frame that allows for stacking of multiple compressors without it looking ugly + * Otherwise identical to the regular compressor +* Pneumatic tubes + * Allows instant item transport without laggy entities + * Requires compressed air to work, air compression determines the max range (10 - 1,000m) + * Has various filter and order options + * Muffler compatible +* Air intake + * Simple machine that uses 100HE/t to produce 1B of compressed air + * Also looks really cool to have on the roof of factories ## Changed * .75 bolts now work as advertised @@ -26,6 +38,8 @@ * Placing conveyor belts now creates a draggable ghost that will automatically attempt to pathfind towards the destination * Lifts and chutes are placed automatically, meaning they no longer need crafting recipes * Changed the optimized receiver generic gun mod to +15% damage +* The xenon chemical plant recipes as well as biogas now require compressed air instead of no fluid at all +* Removed old unused radar configs ## Fixed * Fixed taint destroying bedrock @@ -38,4 +52,5 @@ * Fixed dupe regarding the toolbox * Fixed dummies with no OC components taking up a ton of component slots * Fixed infested glyphids spawning maggots also on the clientside, creating unkillable ghosts -* Fixed top left column not being selectable in the RBMK console \ No newline at end of file +* Fixed top left column not being selectable in the RBMK console +* Fixed CIWS hitrate config being read wrong diff --git a/src/main/java/api/hbm/energymk2/IEnergyReceiverMK2.java b/src/main/java/api/hbm/energymk2/IEnergyReceiverMK2.java index e1752dd5b..8978d64d4 100644 --- a/src/main/java/api/hbm/energymk2/IEnergyReceiverMK2.java +++ b/src/main/java/api/hbm/energymk2/IEnergyReceiverMK2.java @@ -4,6 +4,7 @@ import com.hbm.handler.threading.PacketThreading; import com.hbm.interfaces.NotableComments; import com.hbm.packet.toclient.AuxParticlePacketNT; import com.hbm.util.Compat; +import com.hbm.util.fauxpointtwelve.DirPos; import api.hbm.energymk2.Nodespace.PowerNode; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @@ -31,6 +32,8 @@ public interface IEnergyReceiverMK2 extends IEnergyHandlerMK2 { return this.getMaxPower(); } + public default void trySubscribe(World world, DirPos pos) { trySubscribe(world, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); } + public default void trySubscribe(World world, int x, int y, int z, ForgeDirection dir) { TileEntity te = Compat.getTileStandard(world, x, y, z); diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index 7a1cb4f90..ef0259e43 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -7,20 +7,12 @@ import com.hbm.blocks.gas.*; import com.hbm.blocks.generic.*; import com.hbm.blocks.generic.BlockHazard.ExtDisplayEffect; import com.hbm.blocks.machine.*; -import com.hbm.blocks.machine.albion.BlockPABeamline; -import com.hbm.blocks.machine.albion.BlockPADetector; -import com.hbm.blocks.machine.albion.BlockPADipole; -import com.hbm.blocks.machine.albion.BlockPAQuadrupole; -import com.hbm.blocks.machine.albion.BlockPARFC; -import com.hbm.blocks.machine.albion.BlockPASource; +import com.hbm.blocks.machine.albion.*; import com.hbm.blocks.machine.pile.*; import com.hbm.blocks.machine.rbmk.*; import com.hbm.blocks.network.*; import com.hbm.blocks.rail.*; -import com.hbm.blocks.test.TestCharge; -import com.hbm.blocks.test.TestCore; -import com.hbm.blocks.test.TestEventTester; -import com.hbm.blocks.test.TestObjTester; +import com.hbm.blocks.test.*; import com.hbm.blocks.turret.*; import com.hbm.items.block.*; import com.hbm.items.bomb.ItemPrototypeBlock; @@ -990,6 +982,7 @@ public class ModBlocks { public static Block machine_liquefactor; public static Block machine_solidifier; + public static Block machine_intake; public static Block machine_compressor; public static Block machine_compressor_compact; @@ -2266,6 +2259,7 @@ public class ModBlocks { machine_liquefactor = new MachineLiquefactor().setBlockName("machine_liquefactor").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine"); machine_solidifier = new MachineSolidifier().setBlockName("machine_solidifier").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine"); + machine_intake = new MachineIntake().setBlockName("machine_intake").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine"); machine_compressor = new MachineCompressor().setBlockName("machine_compressor").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine"); machine_compressor_compact = new MachineCompressorCompact().setBlockName("machine_compressor_compact").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine"); @@ -3291,6 +3285,7 @@ public class ModBlocks { GameRegistry.registerBlock(machine_deuterium_tower, machine_deuterium_tower.getUnlocalizedName()); GameRegistry.registerBlock(machine_liquefactor, ItemBlockBase.class, machine_liquefactor.getUnlocalizedName()); GameRegistry.registerBlock(machine_solidifier, ItemBlockBase.class, machine_solidifier.getUnlocalizedName()); + register(machine_intake); register(machine_compressor); register(machine_compressor_compact); GameRegistry.registerBlock(machine_electrolyser, machine_electrolyser.getUnlocalizedName()); diff --git a/src/main/java/com/hbm/blocks/machine/MachineIntake.java b/src/main/java/com/hbm/blocks/machine/MachineIntake.java new file mode 100644 index 000000000..6090eb7f1 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/MachineIntake.java @@ -0,0 +1,50 @@ +package com.hbm.blocks.machine; + +import java.util.ArrayList; +import java.util.List; + +import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ILookOverlay; +import com.hbm.tileentity.TileEntityProxyCombo; +import com.hbm.tileentity.machine.TileEntityMachineIntake; +import com.hbm.util.BobMathUtil; +import com.hbm.util.I18nUtil; + +import net.minecraft.block.material.Material; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre; + +public class MachineIntake extends BlockDummyable implements ILookOverlay { + + public MachineIntake() { + super(Material.iron); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + if(meta >= 12) return new TileEntityMachineIntake(); + return new TileEntityProxyCombo().power().fluid(); + } + + @Override public int[] getDimensions() { return new int[] {0, 0, 1, 0, 1, 0}; } + @Override public int getOffset() { return 0; } + + @Override + public void printHook(Pre event, World world, int x, int y, int z) { + + int[] pos = this.findCore(world, x, y, z); + if(pos == null) return; + TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]); + if(!(te instanceof TileEntityMachineIntake)) return; + + TileEntityMachineIntake intake = (TileEntityMachineIntake) te; + + List text = new ArrayList(); + text.add((intake.power < intake.getMaxPower() / 20 ? EnumChatFormatting.RED : EnumChatFormatting.GREEN) + "Power: " + BobMathUtil.getShortNumber(intake.power) + "HE"); + text.add(EnumChatFormatting.RED + "<- " + EnumChatFormatting.RESET + intake.compair.getTankType().getLocalizedName() + ": " + intake.compair.getFill() + "/" + intake.compair.getMaxFill() + "mB"); + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); + } +} diff --git a/src/main/java/com/hbm/blocks/network/PneumoTube.java b/src/main/java/com/hbm/blocks/network/PneumoTube.java index 3f5e4baa2..5d04f0e22 100644 --- a/src/main/java/com/hbm/blocks/network/PneumoTube.java +++ b/src/main/java/com/hbm/blocks/network/PneumoTube.java @@ -3,6 +3,7 @@ package com.hbm.blocks.network; import java.util.ArrayList; import java.util.List; +import com.hbm.blocks.ITooltipProvider; import com.hbm.inventory.fluid.FluidType; import com.hbm.inventory.fluid.Fluids; import com.hbm.lib.Library; @@ -23,6 +24,7 @@ import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.IIcon; @@ -31,7 +33,7 @@ import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.util.ForgeDirection; -public class PneumoTube extends BlockContainer implements IToolable, IFluidConnectorBlockMK2 { +public class PneumoTube extends BlockContainer implements IToolable, IFluidConnectorBlockMK2, ITooltipProvider { @SideOnly(Side.CLIENT) public IIcon baseIcon; @SideOnly(Side.CLIENT) public IIcon iconIn; @@ -222,4 +224,9 @@ public class PneumoTube extends BlockContainer implements IToolable, IFluidConne TileEntityPneumoTube tube = (TileEntityPneumoTube) world.getTileEntity(x, y, z); return tube != null && tube.isCompressor(); } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + addStandardInfo(stack, player, list, ext); + } } diff --git a/src/main/java/com/hbm/config/WeaponConfig.java b/src/main/java/com/hbm/config/WeaponConfig.java index 290641f86..fd370a20c 100644 --- a/src/main/java/com/hbm/config/WeaponConfig.java +++ b/src/main/java/com/hbm/config/WeaponConfig.java @@ -5,9 +5,6 @@ import net.minecraftforge.common.config.Property; public class WeaponConfig { - public static int radarRange = 1000; - public static int radarBuffer = 30; - public static int radarAltitude = 55; public static int ciwsHitrate = 50; public static boolean dropCell = true; @@ -21,18 +18,9 @@ public class WeaponConfig { public static void loadFromConfig(Configuration config) { final String CATEGORY_MISSILE = CommonConfig.CATEGORY_MISSILE; - Property propRadarRange = config.get(CATEGORY_MISSILE, "7.00_radarRange", 1000); - propRadarRange.comment = "Range of the radar, 50 will result in 100x100 block area covered"; - radarRange = propRadarRange.getInt(); - Property propRadarBuffer = config.get(CATEGORY_MISSILE, "7.01_radarBuffer", 30); - propRadarBuffer.comment = "How high entities have to be above the radar to be detected"; - radarBuffer = propRadarBuffer.getInt(); - Property propRadarAltitude = config.get(CATEGORY_MISSILE, "7.02_radarAltitude", 55); - propRadarAltitude.comment = "Y height required for the radar to work"; - radarAltitude = propRadarAltitude.getInt(); Property propCiwsHitrate = config.get(CATEGORY_MISSILE, "7.03_ciwsAccuracy", 50); propCiwsHitrate.comment = "Additional modifier for CIWS accuracy"; - ciwsHitrate = propRadarAltitude.getInt(); + ciwsHitrate = propCiwsHitrate.getInt(); final String CATEGORY_DROPS = CommonConfig.CATEGORY_DROPS; dropCell = CommonConfig.createConfigBool(config, CATEGORY_DROPS, "10.00_dropCell", "Whether antimatter cells should explode when dropped", true); diff --git a/src/main/java/com/hbm/inventory/gui/GUIPneumoTube.java b/src/main/java/com/hbm/inventory/gui/GUIPneumoTube.java index 02299ee1c..e1737e9cf 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIPneumoTube.java +++ b/src/main/java/com/hbm/inventory/gui/GUIPneumoTube.java @@ -42,7 +42,7 @@ public class GUIPneumoTube extends GuiInfoContainer { tube.compair.renderTankInfo(this, x, y, guiLeft + 7, guiTop + 16, 18, 18); this.drawCustomInfoStat(x, y, guiLeft + 7, guiTop + 52, 18, 18, x, y, (tube.redstone ? (EnumChatFormatting.GREEN + "ON ") : (EnumChatFormatting.RED + "OFF ")) + EnumChatFormatting.RESET + "with Redstone"); - this.drawCustomInfoStat(x, y, guiLeft + 6, guiTop + 36, 20, 8, x, y, "Compressor: " + tube.compair.getPressure() + " PU"); + this.drawCustomInfoStat(x, y, guiLeft + 6, guiTop + 36, 20, 8, x, y, "Compressor: " + tube.compair.getPressure() + " PU", "Max range: " + tube.getRangeFromPressure(tube.compair.getPressure()) + "m"); this.drawCustomInfoStat(x, y, guiLeft + 151, guiTop + 16, 18, 18, x, y, EnumChatFormatting.YELLOW + "Receiver order:", tube.receiveOrder == PneumaticNetwork.RECEIVE_ROBIN ? "Round robin" : "Random"); this.drawCustomInfoStat(x, y, guiLeft + 151, guiTop + 52, 18, 18, x, y, EnumChatFormatting.YELLOW + "Provider slot order:", tube.sendOrder == PneumaticNetwork.SEND_FIRST ? "First to last" : tube.sendOrder == PneumaticNetwork.SEND_LAST ? "Last to first" : "Random"); diff --git a/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java b/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java index a84a03f30..a86d7930f 100644 --- a/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java @@ -219,10 +219,12 @@ public class ChemplantRecipes extends SerializableRecipe { new FluidStack(Fluids.HYDROGEN, 400), new FluidStack(Fluids.OXYGEN, 400))); recipes.add(new ChemRecipe(59, "XENON", 300) - .inputFluids(new FluidStack(Fluids.NONE, 0)) + .inputFluids(new FluidStack(Fluids.AIR, 16_000)) .outputFluids(new FluidStack(Fluids.XENON, 50))); recipes.add(new ChemRecipe(60, "XENON_OXY", 20) - .inputFluids(new FluidStack(Fluids.OXYGEN, 250)) + .inputFluids( + new FluidStack(Fluids.AIR, 8_000), + new FluidStack(Fluids.OXYGEN, 250)) .outputFluids(new FluidStack(Fluids.XENON, 50))); recipes.add(new ChemRecipe(62, "BALEFIRE", 100) .inputItems(new ComparableStack(ModItems.egg_balefire_shard)) @@ -327,7 +329,7 @@ public class ChemplantRecipes extends SerializableRecipe { new ComparableStack(ModItems.nugget_bismuth, 4)) .inputFluids(new FluidStack(Fluids.PEROXIDE, 1000, 5)) .outputFluids(new FluidStack(Fluids.DEATH, 1000, 0))); - //one bucket of ethanol equals 275_000 TU using the diesel baseline0 + //one bucket of ethanol equals 275_000 TU using the diesel baseline //the coal baseline is 400_000 per piece //if we assume a burntime of 1.5 ops (300 ticks) for sugar at 100 TU/t that would equal a total of 30_000 TU recipes.add(new ChemRecipe(75, "ETHANOL", 50) @@ -399,6 +401,7 @@ public class ChemplantRecipes extends SerializableRecipe { public static void registerOtherOil() { recipes.add(new ChemRecipe(31, "BP_BIOGAS", 60) .inputItems(new ComparableStack(ModItems.biomass, 16)) //if we assume 1B BF = 500k and translate that to 2B BG = 500k, then each biomass is worth ~31k or roughly 1.5 furnace operations + .inputFluids(new FluidStack(Fluids.AIR, 4000)) .outputFluids(new FluidStack(2000, Fluids.BIOGAS))); recipes.add(new ChemRecipe(32, "BP_BIOFUEL", 60) .inputFluids(new FluidStack(1500, Fluids.BIOGAS), new FluidStack(250, Fluids.ETHANOL)) diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index cab7ef80d..896b90f58 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -308,6 +308,7 @@ public class ClientProxy extends ServerProxy { ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineCatalyticCracker.class, new RenderCatalyticCracker()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineLiquefactor.class, new RenderLiquefactor()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineSolidifier.class, new RenderSolidifier()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineIntake.class, new RenderIntake()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineCompressor.class, new RenderCompressor()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineCompressorCompact.class, new RenderCompressorCompact()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineDrain.class, new RenderDrain()); diff --git a/src/main/java/com/hbm/main/CraftingManager.java b/src/main/java/com/hbm/main/CraftingManager.java index c7ea4bb42..3ffb5c2f1 100644 --- a/src/main/java/com/hbm/main/CraftingManager.java +++ b/src/main/java/com/hbm/main/CraftingManager.java @@ -1001,6 +1001,7 @@ public class CraftingManager { addShapelessAuto(new ItemStack(ModItems.ingot_firebrick, 4), new Object[] { ModBlocks.brick_fire }); addRecipeAuto(new ItemStack(ModBlocks.machine_drain), new Object[] { "PPP", "T ", "PPP", 'P', STEEL.plateCast(), 'T', ModItems.tank_steel }); + addRecipeAuto(new ItemStack(ModBlocks.machine_intake), new Object[] { "GGG", "PMP", "PTP", 'G', ModBlocks.steel_grate, 'P', STEEL.plate(), 'M', ModItems.motor, 'T', ModItems.tank_steel }); addRecipeAuto(new ItemStack(ModBlocks.filing_cabinet, 1, DecoCabinetEnum.STEEL.ordinal()), new Object[] { " P ", "PIP", " P ", 'P', STEEL.plate(), 'I', ModItems.plate_polymer }); diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 02d752143..9743bf5c5 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -112,6 +112,9 @@ public class ResourceManager { //Cooling Tower public static final IModelCustom tower_small = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/tower_small.obj")).asVBO(); public static final IModelCustom tower_large = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/tower_large.obj")).asVBO(); + + //Air stuff + public static final IModelCustom intake = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/intake.obj")).asVBO(); public static final IModelCustom condenser = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/condenser.obj")).asVBO(); //Wood burner @@ -493,6 +496,7 @@ public class ResourceManager { public static final ResourceLocation hydrotreater_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/hydrotreater.png"); public static final ResourceLocation liquefactor_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/liquefactor.png"); public static final ResourceLocation solidifier_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/solidifier.png"); + public static final ResourceLocation intake_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/intake.png"); public static final ResourceLocation compressor_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/compressor.png"); public static final ResourceLocation compressor_compact_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/compressor_compact.png"); public static final ResourceLocation coker_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/coker.png"); diff --git a/src/main/java/com/hbm/render/tileentity/RenderIntake.java b/src/main/java/com/hbm/render/tileentity/RenderIntake.java new file mode 100644 index 000000000..034915190 --- /dev/null +++ b/src/main/java/com/hbm/render/tileentity/RenderIntake.java @@ -0,0 +1,68 @@ +package com.hbm.render.tileentity; + +import org.lwjgl.opengl.GL11; + +import com.hbm.blocks.ModBlocks; +import com.hbm.main.ResourceManager; +import com.hbm.render.item.ItemRenderBase; +import com.hbm.tileentity.machine.TileEntityMachineIntake; + +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.item.Item; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.client.IItemRenderer; + +public class RenderIntake extends TileEntitySpecialRenderer implements IItemRendererProvider { + + @Override + public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f) { + + GL11.glPushMatrix(); + GL11.glTranslated(x + 0.5D, y, z + 0.5D); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_CULL_FACE); + + switch(tileEntity.getBlockMetadata() - 10) { + case 2: GL11.glRotatef(90, 0F, 1F, 0F); break; + case 4: GL11.glRotatef(180, 0F, 1F, 0F); break; + case 3: GL11.glRotatef(270, 0F, 1F, 0F); break; + case 5: GL11.glRotatef(0, 0F, 1F, 0F); break; + } + + GL11.glTranslated(-0.5, 0, 0.5); + + TileEntityMachineIntake compressor = (TileEntityMachineIntake) tileEntity; + + bindTexture(ResourceManager.intake_tex); + ResourceManager.intake.renderPart("Base"); + + float rot = compressor.prevFan + (compressor.fan - compressor.prevFan) * f; + + GL11.glPushMatrix(); + GL11.glTranslated(0, 0, 0); + GL11.glRotatef(-rot, 0, 1, 0); + GL11.glTranslated(0, 0, 0); + ResourceManager.intake.renderPart("Fan"); + GL11.glPopMatrix(); + + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glPopMatrix(); + } + + @Override + public Item getItemForRenderer() { + return Item.getItemFromBlock(ModBlocks.machine_intake); + } + + @Override + public IItemRenderer getRenderer() { + return new ItemRenderBase( ) { + public void renderInventory() { + GL11.glScaled(5, 5, 5); + } + public void renderCommon() { + bindTexture(ResourceManager.intake_tex); ResourceManager.intake.renderAll(); + } + }; + } +} diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index 77ca0b97f..b4f3ffa3b 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -330,6 +330,7 @@ public class TileMappings { put(TileEntityDeuteriumTower.class, "tileentity_deuterium_tower"); put(TileEntityMachineLiquefactor.class, "tileentity_liquefactor"); put(TileEntityMachineSolidifier.class, "tileentity_solidifier"); + put(TileEntityMachineIntake.class, "tileentity_intake"); put(TileEntityMachineCompressor.class, "tileentity_compressor"); put(TileEntityMachineCompressorCompact.class, "tileentity_compressor_compact"); put(TileEntityElectrolyser.class, "tileentity_electrolyser"); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineCompressorCompact.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineCompressorCompact.java index 3fe48d961..386c3f538 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineCompressorCompact.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineCompressorCompact.java @@ -19,7 +19,7 @@ public class TileEntityMachineCompressorCompact extends TileEntityMachineCompres this.prevFanSpin = this.fanSpin; if(this.isOn) { - this.fanSpin += 15; + this.fanSpin += 45; if(this.fanSpin >= 360) { this.prevFanSpin -= 360; diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineIntake.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineIntake.java new file mode 100644 index 000000000..1507c1b1f --- /dev/null +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineIntake.java @@ -0,0 +1,141 @@ +package com.hbm.tileentity.machine; + +import com.hbm.inventory.fluid.FluidType; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.tileentity.TileEntityLoadedBase; +import com.hbm.util.fauxpointtwelve.DirPos; + +import api.hbm.energymk2.IEnergyReceiverMK2; +import api.hbm.fluidmk2.IFluidStandardSenderMK2; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraftforge.common.util.ForgeDirection; + +public class TileEntityMachineIntake extends TileEntityLoadedBase implements IEnergyReceiverMK2, IFluidStandardSenderMK2 { + + public FluidTank compair; + public long power; + public float fan = 0; + public float prevFan = 0; + + public TileEntityMachineIntake() { + this.compair = new FluidTank(Fluids.AIR, 1_000); + } + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + + if(this.power >= this.getMaxPower() / 20) { + this.compair.setFill(this.compair.getMaxFill()); + this.power -= this.getMaxPower() / 20; + } + + for(DirPos pos : getConPos()) { + if(this.compair.getFill() > 0) this.tryProvide(compair, worldObj, pos); + this.trySubscribe(worldObj, pos); + } + + this.networkPackNT(50); + + } else { + + this.prevFan = this.fan; + + if(this.power >= this.getMaxPower() / 20) { + this.fan += 45; + + if(this.fan >= 360) { + this.fan -= 360; + this.prevFan -= 360; + } + } + } + } + + public DirPos[] getConPos() { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + return new DirPos[] { + new DirPos(xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ, dir), + new DirPos(xCoord + dir.offsetX + rot.offsetX, yCoord, zCoord + dir.offsetZ + rot.offsetZ, dir), + + new DirPos(xCoord - dir.offsetX * 2, yCoord, zCoord - dir.offsetZ * 2, dir.getOpposite()), + new DirPos(xCoord - dir.offsetX * 2 + rot.offsetX, yCoord, zCoord - dir.offsetZ * 2 + rot.offsetZ, dir.getOpposite()), + + new DirPos(xCoord + rot.offsetX * 2, yCoord, zCoord + rot.offsetZ * 2, rot), + new DirPos(xCoord + rot.offsetX * 2 - dir.offsetX, yCoord, zCoord + rot.offsetZ * 2 - dir.offsetZ, rot), + + new DirPos(xCoord - rot.offsetX, yCoord, zCoord - rot.offsetZ, rot.getOpposite()), + new DirPos(xCoord - rot.offsetX - dir.offsetX, yCoord, zCoord - rot.offsetZ - dir.offsetZ, rot.getOpposite()) + }; + } + + @Override + public void serialize(ByteBuf buf) { + super.serialize(buf); + buf.writeLong(power); + compair.serialize(buf); + } + + @Override + public void deserialize(ByteBuf buf) { + super.deserialize(buf); + this.power = buf.readLong(); + compair.deserialize(buf); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.power = nbt.getLong("power"); + compair.readFromNBT(nbt, "compair"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setLong("power", power); + compair.writeToNBT(nbt, "compair"); + } + + @Override public boolean canConnect(ForgeDirection dir) { return dir != ForgeDirection.UP && dir != ForgeDirection.DOWN; } + @Override public boolean canConnect(FluidType type, ForgeDirection dir) { return type == Fluids.AIR && dir != ForgeDirection.UP && dir != ForgeDirection.DOWN; } + + @Override public void setPower(long i) { power = i; } + @Override public long getPower() { return power; } + @Override public long getMaxPower() { return 2_000; } + + @Override public FluidTank[] getAllTanks() { return new FluidTank[] {compair}; } + @Override public FluidTank[] getSendingTanks() { return new FluidTank[] {compair}; } + + AxisAlignedBB bb = null; + + @Override + public AxisAlignedBB getRenderBoundingBox() { + + if(bb == null) { + bb = AxisAlignedBB.getBoundingBox( + xCoord - 1, + yCoord, + zCoord - 1, + xCoord + 2, + yCoord + 1, + zCoord + 2 + ); + } + + return bb; + } + + @Override + @SideOnly(Side.CLIENT) + public double getMaxRenderDistanceSquared() { + return 65536.0D; + } +} diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java b/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java index 6584109ec..02202ff90 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityPneumoTube.java @@ -216,7 +216,7 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP NBTTagCompound nbt = pkt.func_148857_g(); this.insertionDir = EnumUtil.grabEnumSafely(ForgeDirection.class, nbt.getByte("insertionDir")); this.ejectionDir = EnumUtil.grabEnumSafely(ForgeDirection.class, nbt.getByte("ejectionDir")); - worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); // that's right, we're gonna cheat } @Override diff --git a/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java b/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java index 9a4dcbf62..c51e0aa74 100644 --- a/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java +++ b/src/main/java/com/hbm/uninos/networkproviders/PneumaticNetwork.java @@ -32,8 +32,11 @@ public class PneumaticNetwork extends NodeNet { public Random rand = new Random(); public int nextReceiver = 0; - protected static int timeout = 1_000; + protected static final int timeout = 1_000; + public static final int ITEMS_PER_TRANSFER = 64; + // while the system has parts that expects IInventires to be TileEntities to work properly (mostly range checks), + // it can actually handle non-TileEntities just fine. public HashMap> receivers = new HashMap(); public void addReceiver(IInventory inventory, ForgeDirection pipeDir) { @@ -42,6 +45,9 @@ public class PneumaticNetwork extends NodeNet { @Override public void update() { + // weeds out invalid targets + // technically not necessary since that step is taken during the send operation, + // but we still want to reap garbage data that would otherwise accumulate long timestamp = System.currentTimeMillis(); receivers.entrySet().removeIf(x -> { return (timestamp - x.getValue().getValue() > timeout) || NodeNet.isBadLink(x.getKey()); }); } @@ -61,6 +67,7 @@ public class PneumaticNetwork extends NodeNet { if(sendOrder == SEND_LAST) BobMathUtil.reverseIntArray(sourceSlotAccess); if(sendOrder == SEND_RANDOM) BobMathUtil.shuffleIntArray(sourceSlotAccess); + // for round robin, receivers are ordered by proximity to the source ReceiverComparator comparator = new ReceiverComparator(tube); List>> receiverList = new ArrayList(receivers.size()); receiverList.addAll(receivers.entrySet()); @@ -81,7 +88,8 @@ public class PneumaticNetwork extends NodeNet { TileEntity tile1 = source instanceof TileEntity ? (TileEntity) source : null; TileEntity tile2 = dest instanceof TileEntity ? (TileEntity) dest : null; - if(source != null && dest != null) { + // range check for our compression level, skip if either source or dest aren't tile entities + if(tile1 != null && tile2 != null) { int sq = (tile1.xCoord - tile2.xCoord) * (tile1.xCoord - tile2.xCoord) + (tile1.yCoord - tile2.yCoord) * (tile1.yCoord - tile2.yCoord) + (tile1.zCoord - tile2.zCoord) * (tile1.zCoord - tile2.zCoord); if(sq > maxRange * maxRange) { nextReceiver++; @@ -91,7 +99,7 @@ public class PneumaticNetwork extends NodeNet { int destSide = chosenReceiverEntry.getValue().getKey().getOpposite().ordinal(); int[] destSlotAccess = getSlotAccess(dest, destSide); - int itemsLeftToSend = 64; + int itemsLeftToSend = ITEMS_PER_TRANSFER; // not actually individual items, but rather the total "mass", based on max stack size boolean didSomething = false; for(int sourceIndex : sourceSlotAccess) { @@ -100,8 +108,10 @@ public class PneumaticNetwork extends NodeNet { if(sidedSource != null && !sidedSource.canExtractItem(sourceIndex, sourceStack, sourceSide)) continue; boolean match = tube.matchesFilter(sourceStack); if((match && !tube.whitelist) || (!match && tube.whitelist)) continue; + // the "mass" of an item. something that only stacks to 4 has a "mass" of 16. max transfer mass is 64, i.e. one standard stack, or one single unstackable item int proportionalValue = MathHelper.clamp_int(64 / sourceStack.getMaxStackSize(), 1, 64); + // try to fill partial stacks first for(int destIndex : destSlotAccess) { ItemStack destStack = dest.getStackInSlot(destIndex); if(destStack == null) continue; @@ -119,6 +129,7 @@ public class PneumaticNetwork extends NodeNet { if(itemsLeftToSend <= 0) break; } + // if there's stuff left to send, occupy empty slots if(itemsLeftToSend > 0 && sourceStack.stackSize > 0) for(int destIndex : destSlotAccess) { if(dest.getStackInSlot(destIndex) != null) continue; if(!dest.isItemValidForSlot(destIndex, sourceStack)) continue; @@ -139,6 +150,7 @@ public class PneumaticNetwork extends NodeNet { if(itemsLeftToSend <= 0) break; } + // make sure both parties are saved to disk and increment the counter for round robin if(didSomething) { nextReceiver++; source.markDirty(); @@ -148,6 +160,7 @@ public class PneumaticNetwork extends NodeNet { return didSomething; } + /** Returns an array of accessible slots from the given side of an IInventory. If it's an ISidedInventory, uses the sided restrictions instead. */ public static int[] getSlotAccess(IInventory inventory, int dir) { if(inventory instanceof ISidedInventory) { @@ -160,6 +173,7 @@ public class PneumaticNetwork extends NodeNet { } } + /** Compares IInventory by distance, going off the assumption that they are TileEntities. Uses positional data for tie-breaking if the distance is the same. */ public static class ReceiverComparator implements Comparator>> { private TileEntityPneumoTube origin; @@ -174,21 +188,21 @@ public class PneumaticNetwork extends NodeNet { TileEntity tile1 = o1.getKey() instanceof TileEntity ? (TileEntity) o1.getKey() : null; TileEntity tile2 = o2.getKey() instanceof TileEntity ? (TileEntity) o2.getKey() : null; - //prioritize actual TileEntities + // prioritize actual TileEntities if(tile1 == null && tile2 != null) return 1; if(tile1 != null && tile2 == null) return -1; if(tile1 == null && tile2 == null) return 0; - //calculate distances from origin + // calculate distances from origin int dist1 = (tile1.xCoord - origin.xCoord) * (tile1.xCoord - origin.xCoord) + (tile1.yCoord - origin.yCoord) * (tile1.yCoord - origin.yCoord) + (tile1.zCoord - origin.zCoord) * (tile1.zCoord - origin.zCoord); int dist2 = (tile2.xCoord - origin.xCoord) * (tile2.xCoord - origin.xCoord) + (tile2.yCoord - origin.yCoord) * (tile2.yCoord - origin.yCoord) + (tile2.zCoord - origin.zCoord) * (tile2.zCoord - origin.zCoord); - //tier-breaker: use hash value instead + // tier-breaker: use hash value instead if(dist1 == dist2) { return TileEntityPneumoTube.getIdentifier(tile1.xCoord, tile1.yCoord, tile1.zCoord) - TileEntityPneumoTube.getIdentifier(tile2.xCoord, tile2.yCoord, tile2.zCoord); } - //no tie? return difference of the distances + // no tie? return difference of the distances return dist1 - dist2; } } diff --git a/src/main/java/com/hbm/util/DamageResistanceHandler.java b/src/main/java/com/hbm/util/DamageResistanceHandler.java index c8f6deb5c..ed678991e 100644 --- a/src/main/java/com/hbm/util/DamageResistanceHandler.java +++ b/src/main/java/com/hbm/util/DamageResistanceHandler.java @@ -66,7 +66,7 @@ public class DamageResistanceHandler { if(!config.exists()) { initDefaults(); - writeDefault(template); + //writeDefault(template); } else { /// } diff --git a/src/main/resources/assets/hbm/lang/de_DE.lang b/src/main/resources/assets/hbm/lang/de_DE.lang index 724b02f75..149ec4a7b 100644 --- a/src/main/resources/assets/hbm/lang/de_DE.lang +++ b/src/main/resources/assets/hbm/lang/de_DE.lang @@ -4526,6 +4526,7 @@ tile.machine_icf_press.name=ICF-Brennstoffpellet-Fabrikant tile.machine_industrial_boiler.name=Industrieller Boiler tile.machine_industrial_boiler.desc=Großer Boiler zum Verdampfen von Wasser oder$Erhitzen von Öl. Benötigt externe Hitzequelle.$Wärmestransferrate: ΔT*0.01 TU/t$Überdrucksicher tile.machine_industrial_generator.name=Industrieller Generator +tile.machine_intake.name=Lufteinlass tile.machine_keyforge.name=Schlossertisch tile.machine_large_turbine.name=Industrielle Dampfturbine tile.machine_large_turbine.desc=Effizienz: 100%% @@ -4758,6 +4759,7 @@ tile.plasma.name=Plasma tile.plasma_heater.name=Plasmaerhitzer tile.plushie.name=%s Plüschfigur tile.pneumatic_tube.name=Rohrpost +tile.pneumatic_tube.desc=Sendted Items mit Druckluft.$Rechtsklick mit Schraubenzieher aktiviert den Eingang.$Shift-Rechtskick mit Schrabuenzieher aktiviert den Ausgang.$Eingänge können konfiguriert und mit Druckluft verbunden werden.$Sendet bis zu einem Stack, vier Mal pro Sekunde. tile.pole_satellite_receiver.name=Satellitenschüssel tile.pole_top.name=Antennenspitze tile.press_preheater.name=Presse-Vorheizer diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index 0a4423320..41f0f81d7 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -5660,6 +5660,7 @@ tile.machine_icf_press.desc=Fills ICF Fuel pellets$Left fuel slot is accepted by tile.machine_industrial_boiler.name=Industrial Boiler tile.machine_industrial_boiler.desc=Large boiler that can boil water or heat up oil.$Requires external heat source.$Heat transfer rate: ΔT*0.01 TU/t$Cannot explode tile.machine_industrial_generator.name=Industrial Generator +tile.machine_intake.name=Air Intake tile.machine_keyforge.name=Locksmith Table tile.machine_large_turbine.name=Industrial Steam Turbine tile.machine_large_turbine.desc=Efficiency: 100%% @@ -5904,6 +5905,7 @@ tile.plasma.name=Plasma tile.plasma_heater.name=Plasma Heater tile.plushie.name=%s Plushie tile.pneumatic_tube.name=Pneumatic Tube +tile.pneumatic_tube.desc=Sends items using compressed air.$Right-click with screwdriver to toggle an input.$Shift right-click with screwdriver to toggle an output.$Inputs can be configured, and connected to compressed air.$Sends up to one stack, four times per second. tile.pole_satellite_receiver.name=Satellite Dish tile.pole_top.name=Antenna Top tile.press_preheater.name=Burner Press Preheater diff --git a/src/main/resources/assets/hbm/models/machines/intake.obj b/src/main/resources/assets/hbm/models/machines/intake.obj new file mode 100644 index 000000000..2fd36b9cd --- /dev/null +++ b/src/main/resources/assets/hbm/models/machines/intake.obj @@ -0,0 +1,230 @@ +# Blender v2.79 (sub 0) OBJ File: 'intake.blend' +# www.blender.org +o Fan +v 0.000000 0.750000 -0.125000 +v -0.108253 0.750000 -0.062500 +v -0.108253 0.750000 0.062500 +v 0.000000 0.750000 0.125000 +v 0.108253 0.750000 0.062500 +v 0.108253 0.750000 -0.062500 +v 0.000000 0.875000 -0.125000 +v -0.108253 0.875000 -0.062500 +v -0.108253 0.875000 0.062500 +v 0.000000 0.875000 0.125000 +v 0.108253 0.875000 0.062500 +v 0.108253 0.875000 -0.062500 +v -0.108253 0.828676 -0.060370 +v -0.108253 0.796324 0.060370 +v -0.541266 0.873161 -0.226389 +v -0.541266 0.751839 0.226389 +v 0.001844 0.828676 0.123935 +v 0.106409 0.796324 0.063565 +v 0.074575 0.873161 0.581944 +v 0.466691 0.751839 0.355556 +v 0.106409 0.828676 -0.063565 +v 0.001844 0.796324 -0.123935 +v 0.466691 0.873161 -0.355556 +v 0.074574 0.751839 -0.581944 +vt 0.869565 -0.000000 +vt 0.826087 0.025641 +vt 0.826087 -0.000000 +vt 0.739130 -0.000000 +vt 0.695652 0.025641 +vt 0.695652 -0.000000 +vt 0.913043 -0.000000 +vt 0.869565 0.025641 +vt 0.782609 0.025641 +vt 0.782609 -0.000000 +vt 0.739130 0.025641 +vt 0.956522 -0.000000 +vt 0.913043 0.025641 +vt 0.761043 0.028899 +vt 0.782956 0.051282 +vt 0.717218 0.073665 +vt 0.956522 0.128205 +vt 0.847826 0.025641 +vt 0.891304 0.025641 +vt 0.891304 0.025641 +vt 0.782609 0.128205 +vt 0.847826 0.025641 +vt 0.891304 0.025641 +vt 0.782609 0.128205 +vt 0.847826 0.025641 +vt 0.956522 0.025641 +vt 0.761043 0.073665 +vt 0.695305 0.051282 +vt 0.717218 0.028899 +vt 0.782609 0.128205 +vt 0.956522 0.128205 +vt 0.956522 0.128205 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn -0.5000 0.0000 0.8660 +vn -0.5000 0.0000 -0.8660 +vn 0.5000 0.0000 -0.8660 +vn 0.5000 0.0000 0.8660 +vn 0.0000 1.0000 -0.0000 +vn -0.0000 0.9659 0.2588 +vn 0.2241 0.9659 -0.1294 +vn -0.2241 0.9659 -0.1294 +s off +f 3/1/1 8/2/1 2/3/1 +f 6/4/2 11/5/2 5/6/2 +f 4/7/3 9/8/3 3/1/3 +f 2/3/4 7/9/4 1/10/4 +f 1/10/5 12/11/5 6/4/5 +f 5/12/6 10/13/6 4/7/6 +f 12/14/7 7/15/7 9/16/7 +f 15/17/8 14/18/8 13/19/8 +f 17/20/9 20/21/9 18/22/9 +f 21/23/10 24/24/10 22/25/10 +f 3/1/1 9/8/1 8/2/1 +f 6/4/2 12/11/2 11/5/2 +f 4/7/3 10/13/3 9/8/3 +f 2/3/4 8/2/4 7/9/4 +f 1/10/5 7/9/5 12/11/5 +f 5/12/6 11/26/6 10/13/6 +f 7/15/7 8/27/7 9/16/7 +f 9/16/7 10/28/7 11/29/7 +f 11/29/7 12/14/7 9/16/7 +f 15/17/8 16/30/8 14/18/8 +f 17/20/9 19/31/9 20/21/9 +f 21/23/10 23/32/10 24/24/10 +o Base +v -1.000000 0.000000 1.000000 +v 1.000000 0.000000 1.000000 +v -1.000000 0.000000 -1.000000 +v 1.000000 0.000000 -1.000000 +v -0.875000 0.750000 0.875000 +v 0.875000 0.750000 0.875000 +v -0.875000 0.750000 -0.875000 +v 0.875000 0.750000 -0.875000 +v -1.000000 0.750000 -1.000000 +v -1.000000 0.750000 1.000000 +v 1.000000 0.750000 1.000000 +v 1.000000 0.750000 -1.000000 +v -0.625000 1.000000 -0.625000 +v -0.625000 1.000000 0.625000 +v 0.625000 1.000000 0.625000 +v 0.625000 1.000000 -0.625000 +v -0.875000 1.000000 -0.875000 +v -0.875000 1.000000 0.875000 +v 0.875000 1.000000 0.875000 +v 0.875000 1.000000 -0.875000 +v -0.625000 0.750000 -0.625000 +v -0.625000 0.750000 0.625000 +v 0.625000 0.750000 0.625000 +v 0.625000 0.750000 -0.625000 +v -0.625000 1.000000 -0.625000 +v -0.625000 1.000000 0.625000 +v 0.625000 1.000000 0.625000 +v 0.625000 1.000000 -0.625000 +vt 0.695652 -0.000000 +vt -0.000000 0.410256 +vt -0.000000 -0.000000 +vt 0.652174 0.589744 +vt 0.043478 0.641026 +vt 0.043478 0.589744 +vt 0.695652 0.410256 +vt -0.000000 0.564103 +vt -0.000000 0.410256 +vt 0.695652 0.410256 +vt -0.000000 0.564103 +vt -0.000000 0.410256 +vt 0.695652 0.410256 +vt 0.000000 0.564103 +vt 0.000000 0.410256 +vt 0.695652 0.410256 +vt -0.000000 0.564103 +vt 0.043478 0.589744 +vt 0.695652 0.564103 +vt 0.652174 0.589744 +vt 0.043478 0.589744 +vt 0.695652 0.564103 +vt 0.652174 0.589744 +vt 0.695652 0.564103 +vt 0.043478 0.589744 +vt 0.695652 0.564103 +vt 0.652174 0.589744 +vt 0.565217 0.692308 +vt 0.130435 0.743590 +vt 0.130435 0.692308 +vt 0.043478 0.641026 +vt 0.043478 0.641026 +vt 0.043478 0.641026 +vt 0.130435 0.692308 +vt 0.652174 0.641026 +vt 0.565217 0.692308 +vt 0.130435 0.692308 +vt 0.652174 0.641026 +vt 0.565217 0.692308 +vt 0.652174 0.641026 +vt 0.130435 0.692308 +vt 0.652174 0.641026 +vt 0.565217 0.692308 +vt 0.565217 1.000000 +vt 0.130435 1.000000 +vt 0.130435 0.743590 +vt 0.130435 0.743590 +vt 0.130435 0.743590 +vt 0.565217 0.743590 +vt 1.000000 1.000000 +vt 0.565217 1.000000 +vt 0.565217 0.743590 +vt 0.565217 0.743590 +vt 0.565217 0.743590 +vt 0.565217 0.743590 +vt 1.000000 0.743590 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 1.0000 0.0000 +s off +f 27/33/11 26/34/11 25/35/11 +f 32/36/12 43/37/12 30/38/12 +f 25/39/13 33/40/13 27/41/13 +f 27/42/14 36/43/14 28/44/14 +f 26/45/15 34/46/15 25/47/15 +f 28/48/12 35/49/12 26/34/12 +f 31/50/16 34/51/16 29/52/16 +f 29/53/16 35/54/16 30/55/16 +f 30/38/16 36/56/16 32/36/16 +f 32/57/16 33/58/16 31/59/16 +f 40/60/13 47/61/13 39/62/13 +f 29/52/13 41/63/13 31/50/13 +f 31/59/14 44/64/14 32/57/14 +f 30/55/15 42/65/15 29/53/15 +f 37/66/16 42/67/16 38/68/16 +f 38/69/16 43/70/16 39/71/16 +f 39/62/16 44/72/16 40/60/16 +f 40/73/16 41/74/16 37/75/16 +f 47/61/16 45/76/16 46/77/16 +f 38/68/12 45/78/12 37/66/12 +f 37/75/15 48/79/15 40/73/15 +f 39/71/14 46/80/14 38/69/14 +f 51/81/16 49/82/16 50/83/16 +f 27/33/11 28/48/11 26/34/11 +f 32/36/12 44/72/12 43/37/12 +f 25/39/13 34/51/13 33/40/13 +f 27/42/14 33/58/14 36/43/14 +f 26/45/15 35/54/15 34/46/15 +f 28/48/12 36/56/12 35/49/12 +f 31/50/16 33/40/16 34/51/16 +f 29/53/16 34/46/16 35/54/16 +f 30/38/16 35/49/16 36/56/16 +f 32/57/16 36/43/16 33/58/16 +f 40/60/13 48/84/13 47/61/13 +f 29/52/13 42/67/13 41/63/13 +f 31/59/14 41/74/14 44/64/14 +f 30/55/15 43/70/15 42/65/15 +f 37/66/16 41/63/16 42/67/16 +f 38/69/16 42/65/16 43/70/16 +f 39/62/16 43/37/16 44/72/16 +f 40/73/16 44/64/16 41/74/16 +f 47/61/16 48/84/16 45/76/16 +f 38/68/12 46/85/12 45/78/12 +f 37/75/15 45/86/15 48/79/15 +f 39/71/14 47/87/14 46/80/14 +f 51/81/16 52/88/16 49/82/16 diff --git a/src/main/resources/assets/hbm/textures/models/machines/intake.png b/src/main/resources/assets/hbm/textures/models/machines/intake.png new file mode 100644 index 000000000..49b34854d Binary files /dev/null and b/src/main/resources/assets/hbm/textures/models/machines/intake.png differ