From 0b6d45752543d9f1188ccbf03e8aa1937e09b8e8 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 8 Dec 2022 22:56:20 +0100 Subject: [PATCH] combination oven --- src/main/java/com/hbm/blocks/ModBlocks.java | 3 + .../blocks/machine/FurnaceCombination.java | 48 ++++ .../hbm/entity/projectile/EntityChemical.java | 2 + .../hbm/handler/nei/CombinationHandler.java | 16 ++ .../container/ContainerFurnaceCombo.java | 72 +++++ .../hbm/inventory/fluid/tank/FluidTank.java | 8 +- .../java/com/hbm/inventory/gui/GUIAnvil.java | 18 +- .../hbm/inventory/gui/GUIFurnaceCombo.java | 59 ++++ .../inventory/recipes/CombinationRecipes.java | 88 ++++++ src/main/java/com/hbm/main/ClientProxy.java | 1 + src/main/java/com/hbm/main/MainRegistry.java | 1 + src/main/java/com/hbm/main/NEIConfig.java | 1 + .../java/com/hbm/main/ResourceManager.java | 2 + .../com/hbm/particle/ParticleRBMKFlame.java | 2 +- .../tileentity/RenderFurnaceCombination.java | 107 +++++++ .../render/tileentity/RenderTurretBase.java | 2 +- .../java/com/hbm/tileentity/TileMappings.java | 1 + .../machine/TileEntityFurnaceCombination.java | 250 ++++++++++++++++ .../tileentity/machine/TileEntitySawmill.java | 6 +- .../TileEntityMachineCatalyticCracker.java | 12 +- .../hbm/models/machines/combination_oven.obj | 266 ++++++++++++++++++ .../hbm/textures/gui/processing/gui_anvil.png | Bin 3521 -> 3494 bytes .../processing/gui_furnace_combination.png | Bin 0 -> 6228 bytes 23 files changed, 946 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/hbm/blocks/machine/FurnaceCombination.java create mode 100644 src/main/java/com/hbm/handler/nei/CombinationHandler.java create mode 100644 src/main/java/com/hbm/inventory/container/ContainerFurnaceCombo.java create mode 100644 src/main/java/com/hbm/inventory/gui/GUIFurnaceCombo.java create mode 100644 src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java create mode 100644 src/main/java/com/hbm/render/tileentity/RenderFurnaceCombination.java create mode 100644 src/main/java/com/hbm/tileentity/machine/TileEntityFurnaceCombination.java create mode 100644 src/main/resources/assets/hbm/models/machines/combination_oven.obj create mode 100644 src/main/resources/assets/hbm/textures/gui/processing/gui_furnace_combination.png diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index 8e831c82f..9a24ffaab 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -658,6 +658,7 @@ public class ModBlocks { public static Block furnace_iron; public static Block furnace_steel; + public static Block furnace_combination; public static Block machine_stirling; public static Block machine_stirling_steel; public static Block machine_sawmill; @@ -1853,6 +1854,7 @@ public class ModBlocks { furnace_iron = new FurnaceIron().setBlockName("furnace_iron").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_aluminium"); furnace_steel = new FurnaceSteel().setBlockName("furnace_steel").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); + furnace_combination = new FurnaceCombination().setBlockName("furnace_combination").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":brick_light_alt"); machine_stirling = new MachineStirling().setBlockName("machine_stirling").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); machine_stirling_steel = new MachineStirling().setBlockName("machine_stirling_steel").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); machine_sawmill = new MachineSawmill().setBlockName("machine_sawmill").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); @@ -3047,6 +3049,7 @@ public class ModBlocks { register(heater_heatex); register(furnace_iron); register(furnace_steel); + register(furnace_combination); register(machine_stirling); register(machine_stirling_steel); register(machine_sawmill); diff --git a/src/main/java/com/hbm/blocks/machine/FurnaceCombination.java b/src/main/java/com/hbm/blocks/machine/FurnaceCombination.java new file mode 100644 index 000000000..83e4b5ce9 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/FurnaceCombination.java @@ -0,0 +1,48 @@ +package com.hbm.blocks.machine; + +import java.util.List; + +import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ITooltipProvider; +import com.hbm.tileentity.TileEntityProxyCombo; +import com.hbm.tileentity.machine.TileEntityFurnaceCombination; + +import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public class FurnaceCombination extends BlockDummyable implements ITooltipProvider { + + public FurnaceCombination() { + super(Material.rock); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + if(meta >= 12) + return new TileEntityFurnaceCombination(); + return new TileEntityProxyCombo().inventory().fluid(); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + return this.standardOpenBehavior(world, x, y, z, player, 0); + } + + @Override + public int[] getDimensions() { + return new int[] {1, 0, 1, 1, 1, 1}; + } + + @Override + public int getOffset() { + return 1; + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + this.addStandardInfo(stack, player, list, ext); + } +} diff --git a/src/main/java/com/hbm/entity/projectile/EntityChemical.java b/src/main/java/com/hbm/entity/projectile/EntityChemical.java index ea7f07050..586d73fe6 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityChemical.java +++ b/src/main/java/com/hbm/entity/projectile/EntityChemical.java @@ -57,11 +57,13 @@ public class EntityChemical extends EntityThrowableNT { public EntityChemical(World world) { super(world); this.ignoreFrustumCheck = true; + this.isImmuneToFire = true; } public EntityChemical(World world, EntityLivingBase thrower) { super(world, thrower); this.ignoreFrustumCheck = true; + this.isImmuneToFire = true; } @Override diff --git a/src/main/java/com/hbm/handler/nei/CombinationHandler.java b/src/main/java/com/hbm/handler/nei/CombinationHandler.java new file mode 100644 index 000000000..8537c12b0 --- /dev/null +++ b/src/main/java/com/hbm/handler/nei/CombinationHandler.java @@ -0,0 +1,16 @@ +package com.hbm.handler.nei; + +import com.hbm.blocks.ModBlocks; +import com.hbm.inventory.recipes.CombinationRecipes; + +public class CombinationHandler extends NEIUniversalHandler { + + public CombinationHandler() { + super("Combination Furnace", ModBlocks.furnace_combination, CombinationRecipes.getRecipes()); + } + + @Override + public String getKey() { + return "ntmCombination"; + } +} diff --git a/src/main/java/com/hbm/inventory/container/ContainerFurnaceCombo.java b/src/main/java/com/hbm/inventory/container/ContainerFurnaceCombo.java new file mode 100644 index 000000000..51f7a2d47 --- /dev/null +++ b/src/main/java/com/hbm/inventory/container/ContainerFurnaceCombo.java @@ -0,0 +1,72 @@ +package com.hbm.inventory.container; + +import com.hbm.inventory.SlotMachineOutput; +import com.hbm.inventory.SlotSmelting; +import com.hbm.tileentity.machine.TileEntityFurnaceCombination; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class ContainerFurnaceCombo extends Container { + + protected TileEntityFurnaceCombination furnace; + + public ContainerFurnaceCombo(InventoryPlayer invPlayer, TileEntityFurnaceCombination furnace) { + this.furnace = furnace; + + //input + this.addSlotToContainer(new Slot(furnace, 0, 26, 36)); + //output + this.addSlotToContainer(new SlotSmelting(invPlayer.player, furnace, 1, 89, 36)); + this.addSlotToContainer(new Slot(furnace, 2, 136, 18)); + this.addSlotToContainer(new SlotMachineOutput(furnace, 3, 136, 54)); + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 9; j++) { + this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j * 18, 104 + i * 18)); + } + } + + for(int i = 0; i < 9; i++) { + this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 162)); + } + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int index) { + ItemStack stack = null; + Slot slot = (Slot) this.inventorySlots.get(index); + + if(slot != null && slot.getHasStack()) { + ItemStack originalStack = slot.getStack(); + stack = originalStack.copy(); + + if(index <= 3) { + if(!this.mergeItemStack(originalStack, 4, this.inventorySlots.size(), true)) { + return null; + } + + slot.onSlotChange(originalStack, stack); + + } else if(!this.mergeItemStack(originalStack, 0, 1, false)) { + return null; + } + + if(originalStack.stackSize == 0) { + slot.putStack((ItemStack) null); + } else { + slot.onSlotChanged(); + } + } + + return stack; + } + + @Override + public boolean canInteractWith(EntityPlayer player) { + return furnace.isUseableByPlayer(player); + } +} diff --git a/src/main/java/com/hbm/inventory/fluid/tank/FluidTank.java b/src/main/java/com/hbm/inventory/fluid/tank/FluidTank.java index 074dfdd5e..0d3f855d2 100644 --- a/src/main/java/com/hbm/inventory/fluid/tank/FluidTank.java +++ b/src/main/java/com/hbm/inventory/fluid/tank/FluidTank.java @@ -33,8 +33,14 @@ public class FluidTank { FluidType type; int fluid; int maxFluid; - public int index; + public int index = 0; + public FluidTank(FluidType type, int maxFluid) { + this.type = type; + this.maxFluid = maxFluid; + } + + @Deprecated // indices are no longer needed public FluidTank(FluidType type, int maxFluid, int index) { this.type = type; this.maxFluid = maxFluid; diff --git a/src/main/java/com/hbm/inventory/gui/GUIAnvil.java b/src/main/java/com/hbm/inventory/gui/GUIAnvil.java index 35eb676a1..f184282ad 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIAnvil.java +++ b/src/main/java/com/hbm/inventory/gui/GUIAnvil.java @@ -146,11 +146,11 @@ public class GUIAnvil extends GuiContainer { return; } - if(guiLeft + 97 <= x && guiLeft + 97 + 18 > x && guiTop + 107 < y && guiTop + 107 + 18 >= y) { + /*if(guiLeft + 97 <= x && guiLeft + 97 + 18 > x && guiTop + 107 < y && guiTop + 107 + 18 >= y) { mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F)); search(this.search.getText()); return; - } + }*/ for(int i = index * 2; i < index * 2 + 10; i++) { @@ -322,9 +322,9 @@ public class GUIAnvil extends GuiContainer { if(guiLeft + 52 <= mX && guiLeft + 52 + 18 > mX && guiTop + 53 < mY && guiTop + 53 + 18 >= mY) { drawTexturedModalRect(guiLeft + 52, guiTop + 53, 176, 150, 18, 18); } - if(guiLeft + 97 <= mX && guiLeft + 97 + 18 > mX && guiTop + 107 < mY && guiTop + 107 + 18 >= mY) { + /*if(guiLeft + 97 <= mX && guiLeft + 97 + 18 > mX && guiTop + 107 < mY && guiTop + 107 + 18 >= mY) { drawTexturedModalRect(guiLeft + 97, guiTop + 107, 176, 168, 18, 18); - } + }*/ for(int i = index * 2; i < index * 2 + 10; i++) { if(i >= recipes.size()) @@ -363,13 +363,9 @@ public class GUIAnvil extends GuiContainer { @Override protected void keyTyped(char c, int key) { - if(!this.search.textboxKeyTyped(c, key)) { - - if(key == 28) { - this.search.setFocused(false); - search(this.search.getText()); - } - + if(this.search.textboxKeyTyped(c, key)) { + search(this.search.getText()); + } else { super.keyTyped(c, key); } } diff --git a/src/main/java/com/hbm/inventory/gui/GUIFurnaceCombo.java b/src/main/java/com/hbm/inventory/gui/GUIFurnaceCombo.java new file mode 100644 index 000000000..118c83f60 --- /dev/null +++ b/src/main/java/com/hbm/inventory/gui/GUIFurnaceCombo.java @@ -0,0 +1,59 @@ +package com.hbm.inventory.gui; + +import org.lwjgl.opengl.GL11; + +import com.hbm.inventory.container.ContainerFurnaceCombo; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.machine.TileEntityFurnaceCombination; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.ResourceLocation; + +public class GUIFurnaceCombo extends GuiInfoContainer { + + private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/processing/gui_furnace_combination.png"); + private TileEntityFurnaceCombination furnace; + + public GUIFurnaceCombo(InventoryPlayer invPlayer, TileEntityFurnaceCombination tedf) { + super(new ContainerFurnaceCombo(invPlayer, tedf)); + furnace = tedf; + + this.xSize = 176; + this.ySize = 186; + } + + @Override + public void drawScreen(int x, int y, float interp) { + super.drawScreen(x, y, interp); + + furnace.tank.renderTankInfo(this, x, y, guiLeft + 118, guiTop + 18, 16, 52); + + this.drawCustomInfoStat(x, y, guiLeft + 44, guiTop + 36, 39, 7, x, y, new String[] { String.format("%,d", furnace.progress) + " / " + String.format("%,d", furnace.processTime) + "TU" }); + this.drawCustomInfoStat(x, y, guiLeft + 44, guiTop + 45, 39, 7, x, y, new String[] { String.format("%,d", furnace.heat) + " / " + String.format("%,d", furnace.maxHeat) + "TU" }); + } + + @Override + protected void drawGuiContainerForegroundLayer(int i, int j) { + String name = this.furnace.hasCustomInventoryName() ? this.furnace.getInventoryName() : I18n.format(this.furnace.getInventoryName()); + + this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752); + this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float interp, int x, int y) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); + + int p = furnace.progress * 38 / furnace.processTime; + drawTexturedModalRect(guiLeft + 45, guiTop + 37, 176, 0, p, 5); + + int h = furnace.heat * 37 / furnace.maxHeat; + drawTexturedModalRect(guiLeft + 45, guiTop + 46, 176, 5, h, 5); + + furnace.tank.renderTank(guiLeft + 118, guiTop + 70, this.zLevel, 16, 52); + } +} diff --git a/src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java b/src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java new file mode 100644 index 000000000..acf183200 --- /dev/null +++ b/src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java @@ -0,0 +1,88 @@ +package com.hbm.inventory.recipes; + +import java.util.HashMap; +import java.util.Map.Entry; + +import static com.hbm.inventory.OreDictManager.*; + +import com.hbm.inventory.FluidStack; +import com.hbm.inventory.OreDictManager.DictFrame; +import com.hbm.inventory.RecipesCommon.ComparableStack; +import com.hbm.inventory.RecipesCommon.OreDictStack; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.items.ItemEnums.EnumCokeType; +import com.hbm.items.ItemEnums.EnumTarType; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemFluidIcon; +import com.hbm.util.Tuple.Pair; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +public class CombinationRecipes { + + private static HashMap> recipes = new HashMap(); + + public static void register() { + recipes.put(COAL.gem(), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.COAL), new FluidStack(Fluids.COALOIL, 50))); + recipes.put(COAL.dust(), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.COAL), new FluidStack(Fluids.COALOIL, 50))); + + recipes.put(LIGNITE.gem(), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.LIGNITE), new FluidStack(Fluids.COALOIL, 50))); + recipes.put(LIGNITE.dust(), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.LIGNITE), new FluidStack(Fluids.COALOIL, 50))); + recipes.put(new ComparableStack(ModItems.briquette_lignite), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.LIGNITE), new FluidStack(Fluids.COALOIL, 50))); + + recipes.put(CINNABAR.crystal(), new Pair(new ItemStack(ModItems.sulfur), new FluidStack(Fluids.MERCURY, 100))); + + recipes.put(KEY_LOG, new Pair(new ItemStack(Items.coal, 1 ,1), new FluidStack(Fluids.HEATINGOIL, 10))); + + recipes.put(DictFrame.fromOne(ModItems.oil_tar, EnumTarType.CRUDE), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.PETROLEUM), null)); + recipes.put(DictFrame.fromOne(ModItems.oil_tar, EnumTarType.CRACK), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.PETROLEUM), null)); + recipes.put(DictFrame.fromOne(ModItems.oil_tar, EnumTarType.COAL), new Pair(DictFrame.fromOne(ModItems.coke, EnumCokeType.COAL), null)); + } + + public static Pair getOutput(ItemStack stack) { + + if(stack == null || stack.getItem() == null) + return null; + + ComparableStack comp = new ComparableStack(stack.getItem(), 1, stack.getItemDamage()); + + if(recipes.containsKey(comp)) { + Pair out = recipes.get(comp); + return new Pair(out.getKey() == null ? null : out.getKey().copy(), out.getValue()); + } + + String[] dictKeys = comp.getDictKeys(); + + for(String key : dictKeys) { + + if(recipes.containsKey(key)) { + Pair out = recipes.get(key); + return new Pair(out.getKey() == null ? null : out.getKey().copy(), out.getValue()); + } + } + + return null; + } + + public static HashMap getRecipes() { + + HashMap recipes = new HashMap(); + + for(Entry> entry : CombinationRecipes.recipes.entrySet()) { + Object key = entry.getKey(); + Pair val = entry.getValue(); + Object o = key instanceof String ? new OreDictStack((String) key) : key; + + if(val.getKey() != null && val.getValue() != null) { + recipes.put(o, new ItemStack[] {val.getKey(), ItemFluidIcon.make(val.getValue())}); + } else if(val.getKey() != null) { + recipes.put(o, new ItemStack[] {val.getKey()}); + } else if(val.getValue() != null) { + recipes.put(o, new ItemStack[] {ItemFluidIcon.make(val.getValue())}); + } + } + + return recipes; + } +} diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 06c83ca4c..a49bd214a 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -248,6 +248,7 @@ public class ClientProxy extends ServerProxy { ClientRegistry.bindTileEntitySpecialRenderer(TileEntityElectrolyser.class, new RenderElectrolyser()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityFurnaceIron.class, new RenderFurnaceIron()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityFurnaceSteel.class, new RenderFurnaceSteel()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityFurnaceCombination.class, new RenderFurnaceCombination()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityHeaterFirebox.class, new RenderFirebox()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityHeaterOven.class, new RenderHeatingOven()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityHeaterOilburner.class, new RenderOilburner()); diff --git a/src/main/java/com/hbm/main/MainRegistry.java b/src/main/java/com/hbm/main/MainRegistry.java index 14c1a1a25..ee288b7a3 100644 --- a/src/main/java/com/hbm/main/MainRegistry.java +++ b/src/main/java/com/hbm/main/MainRegistry.java @@ -783,6 +783,7 @@ public class MainRegistry { RefineryRecipes.registerCracking(); RadiolysisRecipes.registerRadiolysis(); GasCentrifugeRecipes.register(); + CombinationRecipes.register(); //the good stuff SerializableRecipe.registerAllHandlers(); diff --git a/src/main/java/com/hbm/main/NEIConfig.java b/src/main/java/com/hbm/main/NEIConfig.java index 04d1a8920..31c8a9776 100644 --- a/src/main/java/com/hbm/main/NEIConfig.java +++ b/src/main/java/com/hbm/main/NEIConfig.java @@ -63,6 +63,7 @@ public class NEIConfig implements IConfigureNEI { registerHandler(new CrackingHandler()); registerHandler(new FractioningHandler()); registerHandler(new BoilingHandler()); + registerHandler(new CombinationHandler()); //Some things are even beyond my control...or are they? API.hideItem(ItemBattery.getEmptyBattery(ModItems.memory)); diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 02b8fbf83..98c503ec3 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -74,6 +74,7 @@ public class ResourceManager { //Furnaces public static final IModelCustom furnace_iron = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/machines/furnace_iron.obj")); public static final IModelCustom furnace_steel = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/machines/furnace_steel.obj")); + public static final IModelCustom combination_oven = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/machines/combination_oven.obj")); //Landmines public static final IModelCustom mine_ap = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/mine_ap.obj")); @@ -407,6 +408,7 @@ public class ResourceManager { //Furnaces public static final ResourceLocation furnace_iron_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/furnace_iron.png"); public static final ResourceLocation furnace_steel_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/furnace_steel.png"); + public static final ResourceLocation combination_oven_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/combination_oven.png"); //Oil Pumps public static final ResourceLocation derrick_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/derrick.png"); diff --git a/src/main/java/com/hbm/particle/ParticleRBMKFlame.java b/src/main/java/com/hbm/particle/ParticleRBMKFlame.java index 696896552..262e407cc 100644 --- a/src/main/java/com/hbm/particle/ParticleRBMKFlame.java +++ b/src/main/java/com/hbm/particle/ParticleRBMKFlame.java @@ -17,7 +17,7 @@ import net.minecraft.world.World; @SideOnly(Side.CLIENT) public class ParticleRBMKFlame extends EntityFX { - private static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/particle/rbmk_fire.png"); + public static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/particle/rbmk_fire.png"); private TextureManager theRenderEngine; public ParticleRBMKFlame(TextureManager texman, World world, double x, double y, double z, int maxAge) { diff --git a/src/main/java/com/hbm/render/tileentity/RenderFurnaceCombination.java b/src/main/java/com/hbm/render/tileentity/RenderFurnaceCombination.java new file mode 100644 index 000000000..058581763 --- /dev/null +++ b/src/main/java/com/hbm/render/tileentity/RenderFurnaceCombination.java @@ -0,0 +1,107 @@ +package com.hbm.render.tileentity; + +import org.lwjgl.opengl.GL11; + +import com.hbm.blocks.ModBlocks; +import com.hbm.lib.RefStrings; +import com.hbm.main.ResourceManager; +import com.hbm.render.item.ItemRenderBase; +import com.hbm.tileentity.machine.TileEntityFurnaceCombination; + +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.item.Item; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.IItemRenderer; + +public class RenderFurnaceCombination extends TileEntitySpecialRenderer implements IItemRendererProvider { + + public static final ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/particle/rbmk_fire.png"); + + @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.glEnable(GL11.GL_CULL_FACE); + + bindTexture(ResourceManager.combination_oven_tex); + ResourceManager.combination_oven.renderAll(); + + TileEntityFurnaceCombination furnace = (TileEntityFurnaceCombination) tileEntity; + + if(furnace.wasOn) { + + bindTexture(texture); + + GL11.glPushMatrix(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GL11.glAlphaFunc(GL11.GL_GEQUAL, 0); + GL11.glDepthMask(false); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + RenderHelper.disableStandardItemLighting(); + + int texIndex = (int) (furnace.getWorldObj().getTotalWorldTime() / 2 % 14); + float f0 = 1F / 14F; + + float uMin = texIndex % 5 * f0; + float uMax = uMin + f0; + float vMin = 0; + float vMax = 1; + + Tessellator tess = Tessellator.instance; + tess.startDrawingQuads(); + + tess.setNormal(0.0F, 1.0F, 0.0F); + tess.setBrightness(240); + tess.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F); + + GL11.glTranslated(0, 1.75, 0); + GL11.glRotatef(-RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F); + + double scaleH = 1; + double scaleV = 3; + + tess.addVertexWithUV(-scaleH, 0, 0, uMax, vMax); + tess.addVertexWithUV(-scaleH, scaleV, 0, uMax, vMin); + tess.addVertexWithUV(scaleH, scaleV, 0, uMin, vMin); + tess.addVertexWithUV(scaleH, 0, 0, uMin, vMax); + + tess.draw(); + + //GL11.glPolygonOffset(0.0F, 0.0F); + GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); + GL11.glDepthFunc(GL11.GL_LEQUAL); + GL11.glDepthMask(true); + GL11.glPopMatrix(); + RenderHelper.enableStandardItemLighting(); + } + + GL11.glPopMatrix(); + } + + @Override + public Item getItemForRenderer() { + return Item.getItemFromBlock(ModBlocks.furnace_combination); + } + + @Override + public IItemRenderer getRenderer() { + return new ItemRenderBase( ) { + public void renderInventory() { + GL11.glTranslated(0, -1.5, 0); + GL11.glScaled(3.25, 3.25, 3.25); + } + public void renderCommon() { + bindTexture(ResourceManager.combination_oven_tex); + ResourceManager.combination_oven.renderAll(); + }}; + } +} diff --git a/src/main/java/com/hbm/render/tileentity/RenderTurretBase.java b/src/main/java/com/hbm/render/tileentity/RenderTurretBase.java index a76e0d09b..99536327f 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderTurretBase.java +++ b/src/main/java/com/hbm/render/tileentity/RenderTurretBase.java @@ -37,7 +37,7 @@ public abstract class RenderTurretBase extends TileEntitySpecialRenderer { private void checkPlug(World world, int x, int y, int z, boolean power, boolean fluid, FluidType type, int ox, int oz, int rot, ForgeDirection dir) { - if((power && Library.canConnect(world, x, y, z, dir)) || (fluid && Library.checkFluidConnectables(world, x, y, z, type))) { + if((power && Library.canConnect(world, x, y, z, dir)) || (fluid && Library.checkFluidConnectables(world, x, y, z, type)) || (fluid && Library.canConnectFluid(world, x, y, z, dir, type))) { GL11.glPushMatrix(); GL11.glRotated(rot, 0, 1, 0); diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index 75e4249f7..2ade0da60 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -241,6 +241,7 @@ public class TileMappings { put(TileEntityHeaterHeatex.class, "tileentity_heater_heatex"); put(TileEntityFurnaceIron.class, "tileentity_furnace_iron"); put(TileEntityFurnaceSteel.class, "tileentity_furnace_steel"); + put(TileEntityFurnaceCombination.class, "tileentity_combination_oven"); put(TileEntityStirling.class, "tileentity_stirling"); put(TileEntitySawmill.class, "tileentity_sawmill"); put(TileEntityCrucible.class, "tileentity_crucible"); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityFurnaceCombination.java b/src/main/java/com/hbm/tileentity/machine/TileEntityFurnaceCombination.java new file mode 100644 index 000000000..8fb1e879b --- /dev/null +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityFurnaceCombination.java @@ -0,0 +1,250 @@ +package com.hbm.tileentity.machine; + +import com.hbm.inventory.FluidStack; +import com.hbm.inventory.container.ContainerFurnaceCombo; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.inventory.gui.GUIFurnaceCombo; +import com.hbm.inventory.recipes.CombinationRecipes; +import com.hbm.tileentity.IGUIProvider; +import com.hbm.tileentity.TileEntityMachineBase; +import com.hbm.util.Tuple.Pair; + +import api.hbm.fluid.IFluidStandardSender; +import api.hbm.tile.IHeatSource; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class TileEntityFurnaceCombination extends TileEntityMachineBase implements IFluidStandardSender, IGUIProvider { + + public boolean wasOn; + public int progress; + public static int processTime = 20_000; + + public int heat; + public static int maxHeat = 100_000; + public static double diffusion = 0.25D; + + public FluidTank tank; + + public TileEntityFurnaceCombination() { + super(4); + this.tank = new FluidTank(Fluids.NONE, 24_000); + } + + @Override + public String getName() { + return "container.furnaceCombination"; + } + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + this.tryPullHeat(); + + if(this.worldObj.getTotalWorldTime() % 20 == 0) { + for(int i = 2; i < 6; i++) { + ForgeDirection dir = ForgeDirection.getOrientation(i); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + for(int y = yCoord; y <= yCoord + 1; y++) { + for(int j = -1; j <= 1; j++) { + if(tank.getFill() > 0) this.sendFluid(tank.getTankType(), worldObj, xCoord + dir.offsetX * 2 + rot.offsetX * j, y, zCoord + dir.offsetZ * 2 + rot.offsetZ * j, dir); + } + } + } + + for(int x = xCoord - 1; x <= xCoord + 1; x++) { + for(int z = zCoord - 1; z <= zCoord + 1; z++) { + if(tank.getFill() > 0) this.sendFluid(tank.getTankType(), worldObj, x, yCoord + 2, z, ForgeDirection.UP); + } + } + } + + this.wasOn = false; + + tank.unloadTank(2, 3, slots); + + if(canSmelt()) { + int burn = heat / 100; + + if(burn > 0) { + this.wasOn = true; + this.progress += burn; + this.heat -= burn; + + if(progress >= processTime) { + this.markChanged(); + progress -= this.processTime; + + Pair pair = CombinationRecipes.getOutput(slots[0]); + ItemStack out = pair.getKey(); + FluidStack fluid = pair.getValue(); + + if(out != null) { + if(slots[1] == null) { + slots[1] = out.copy(); + } else { + slots[1].stackSize += out.stackSize; + } + } + + if(fluid != null) { + if(tank.getTankType() != fluid.type) { + tank.setTankType(fluid.type); + } + + tank.setFill(tank.getFill() + fluid.fill); + } + + this.decrStackSize(0, 1); + } + } + } else { + this.progress = 0; + } + + NBTTagCompound data = new NBTTagCompound(); + data.setBoolean("wasOn", this.wasOn); + data.setInteger("heat", this.heat); + data.setInteger("progress", this.progress); + tank.writeToNBT(data, "t"); + this.networkPack(data, 50); + } else { + + if(this.wasOn && worldObj.rand.nextInt(15) == 0) { + worldObj.spawnParticle("lava", xCoord + 0.5 + worldObj.rand.nextGaussian() * 0.5, yCoord + 2, zCoord + 0.5 + worldObj.rand.nextGaussian() * 0.5, 0, 0, 0); + } + } + } + + public boolean canSmelt() { + if(slots[0] == null) return false; + Pair pair = CombinationRecipes.getOutput(slots[0]); + + if(pair == null) return false; + + ItemStack out = pair.getKey(); + FluidStack fluid = pair.getValue(); + + if(out != null) { + if(slots[1] != null) { + if(!out.isItemEqual(slots[1])) return false; + if(out.stackSize + slots[1].stackSize > slots[1].getMaxStackSize()) return false; + } + } + + if(fluid != null) { + if(tank.getTankType() != fluid.type && tank.getFill() > 0) return false; + if(tank.getTankType() == fluid.type && tank.getFill() + fluid.fill > tank.getMaxFill()) return false; + } + + return true; + } + + @Override + public void networkUnpack(NBTTagCompound nbt) { + this.wasOn = nbt.getBoolean("wasOn"); + this.heat = nbt.getInteger("heat"); + this.progress = nbt.getInteger("progress"); + this.tank.readFromNBT(nbt, "t"); + } + + protected void tryPullHeat() { + + if(this.heat >= this.maxHeat) return; + + TileEntity con = worldObj.getTileEntity(xCoord, yCoord - 1, zCoord); + + if(con instanceof IHeatSource) { + IHeatSource source = (IHeatSource) con; + int diff = source.getHeatStored() - this.heat; + + if(diff == 0) { + return; + } + + if(diff > 0) { + diff = (int) Math.ceil(diff * diffusion); + source.useUpHeat(diff); + this.heat += diff; + if(this.heat > this.maxHeat) + this.heat = this.maxHeat; + return; + } + } + + this.heat = Math.max(this.heat - Math.max(this.heat / 1000, 1), 0); + } + + @Override + public int[] getAccessibleSlotsFromSide(int meta) { + return new int[] { 0, 1 }; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemStack) { + return i == 0 && CombinationRecipes.getOutput(itemStack) != null; + } + + @Override + public boolean canExtractItem(int i, ItemStack itemStack, int j) { + return i == 1; + } + + @Override + public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new ContainerFurnaceCombo(player.inventory, this); + } + + @Override + @SideOnly(Side.CLIENT) + public GuiScreen provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new GUIFurnaceCombo(player.inventory, this); + } + + AxisAlignedBB bb = null; + + @Override + public AxisAlignedBB getRenderBoundingBox() { + + if(bb == null) { + bb = AxisAlignedBB.getBoundingBox( + xCoord - 1, + yCoord, + zCoord - 1, + xCoord + 2, + yCoord + 2.125, + zCoord + 2 + ); + } + + return bb; + } + + @Override + @SideOnly(Side.CLIENT) + public double getMaxRenderDistanceSquared() { + return 65536.0D; + } + + @Override + public FluidTank[] getAllTanks() { + return new FluidTank[] {tank}; + } + + @Override + public FluidTank[] getSendingTanks() { + return new FluidTank[] {tank}; + } +} diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntitySawmill.java b/src/main/java/com/hbm/tileentity/machine/TileEntitySawmill.java index a82b519f2..7bd6d6e10 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntitySawmill.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntitySawmill.java @@ -69,7 +69,7 @@ public class TileEntitySawmill extends TileEntityMachineBase { slots[1] = result; if(result.getItem() != ModItems.powder_sawdust) { - float chance = result.getItem() == Items.stick ? 0.05F : 0.5F; + float chance = result.getItem() == Items.stick ? 0.1F : 0.5F; if(worldObj.rand.nextFloat() < chance) { slots[2] = new ItemStack(ModItems.powder_sawdust); } @@ -258,6 +258,10 @@ public class TileEntitySawmill extends TileEntityMachineBase { return new ItemStack(Items.stick, 4); } + if(names.contains("treeSapling")) { + return new ItemStack(Items.stick, 1); + } + return null; } diff --git a/src/main/java/com/hbm/tileentity/machine/oil/TileEntityMachineCatalyticCracker.java b/src/main/java/com/hbm/tileentity/machine/oil/TileEntityMachineCatalyticCracker.java index 77554db0c..b1770cbd2 100644 --- a/src/main/java/com/hbm/tileentity/machine/oil/TileEntityMachineCatalyticCracker.java +++ b/src/main/java/com/hbm/tileentity/machine/oil/TileEntityMachineCatalyticCracker.java @@ -21,7 +21,6 @@ import api.hbm.fluid.IFluidStandardTransceiver; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraftforge.common.util.ForgeDirection; @@ -45,13 +44,17 @@ public class TileEntityMachineCatalyticCracker extends TileEntityLoadedBase impl public void updateEntity() { if(!worldObj.isRemote) { - + + this.worldObj.theProfiler.startSection("catalyticCracker_setup_tanks"); setupTanks(); + this.worldObj.theProfiler.endStartSection("catalyticCracker_update_connections"); updateConnections(); - + + this.worldObj.theProfiler.endStartSection("catalyticCracker_do_recipe"); if(worldObj.getTotalWorldTime() % 20 == 0) crack(); - + + this.worldObj.theProfiler.endStartSection("catalyticCracker_send_fluid"); if(worldObj.getTotalWorldTime() % 10 == 0) { fillFluidInit(tanks[2].getTankType()); fillFluidInit(tanks[3].getTankType()); @@ -70,6 +73,7 @@ public class TileEntityMachineCatalyticCracker extends TileEntityLoadedBase impl INBTPacketReceiver.networkPack(this, data, 50); } + this.worldObj.theProfiler.endSection(); } } diff --git a/src/main/resources/assets/hbm/models/machines/combination_oven.obj b/src/main/resources/assets/hbm/models/machines/combination_oven.obj new file mode 100644 index 000000000..952f8233d --- /dev/null +++ b/src/main/resources/assets/hbm/models/machines/combination_oven.obj @@ -0,0 +1,266 @@ +# Blender v2.79 (sub 0) OBJ File: 'combination_oven.blend' +# www.blender.org +o Plane +v 0.750000 2.125000 -0.750000 +v 0.750000 2.125000 0.750000 +v -0.750000 2.125000 0.750000 +v -0.750000 2.125000 -0.750000 +v -1.500000 0.000000 1.500000 +v 1.500000 0.000000 1.500000 +v -1.500000 0.000000 -1.500000 +v 1.500000 0.000000 -1.500000 +v -1.500000 0.125000 -1.500000 +v -1.500000 0.125000 1.500000 +v 1.500000 0.125000 1.500000 +v 1.500000 0.125000 -1.500000 +v -1.375000 0.125000 -1.375000 +v -1.375000 0.125000 1.375000 +v 1.375000 0.125000 1.375000 +v 1.375000 0.125000 -1.375000 +v -1.375000 0.875000 -1.375000 +v -1.375000 0.875000 1.375000 +v 1.375000 0.875000 1.375000 +v 1.375000 0.875000 -1.375000 +v -1.000000 1.625000 -1.000000 +v -1.000000 1.625000 1.000000 +v 1.000000 1.625000 1.000000 +v 1.000000 1.625000 -1.000000 +v -1.000000 2.125000 -1.000000 +v -1.000000 2.125000 1.000000 +v 1.000000 2.125000 1.000000 +v 1.000000 2.125000 -1.000000 +v 0.750000 1.625000 -0.750000 +v -0.750000 1.625000 -0.750000 +v 0.750000 1.625000 0.750000 +v -0.750000 1.625000 0.750000 +v -0.500000 0.000000 0.500000 +v 0.500000 0.000000 0.500000 +v -0.500000 0.000000 -0.500000 +v 0.500000 0.000000 -0.500000 +v -0.500000 0.062500 -0.500000 +v -0.500000 0.062500 0.500000 +v 0.500000 0.062500 0.500000 +v 0.500000 0.062500 -0.500000 +v -0.437500 0.062500 -0.437500 +v -0.437500 0.062500 0.437500 +v 0.437500 0.062500 0.437500 +v 0.437500 0.062500 -0.437500 +v -0.437500 0.000000 -0.437500 +v -0.437500 0.000000 0.437500 +v 0.437500 0.000000 0.437500 +v 0.437500 0.000000 -0.437500 +vt 0.000000 0.489796 +vt 0.347826 0.326531 +vt 0.521739 0.489796 +vt 0.521739 1.000000 +vt 0.500000 0.530612 +vt 0.521739 0.510204 +vt 0.000000 0.510204 +vt 0.521739 0.489796 +vt 0.000000 0.510204 +vt 0.000000 0.489796 +vt 0.521739 0.489796 +vt 0.000000 0.510204 +vt 0.000000 0.489796 +vt 0.521739 0.489796 +vt 0.000000 0.510204 +vt 0.000000 0.489796 +vt 1.000000 0.000000 +vt 0.521739 0.122449 +vt 0.521739 0.000000 +vt 0.021739 0.979592 +vt 0.000000 1.000000 +vt 0.021739 0.530612 +vt 0.500000 0.979592 +vt 1.000000 0.122449 +vt 0.586957 0.244898 +vt 0.521739 0.122449 +vt 1.000000 -0.000000 +vt 0.521739 -0.000000 +vt 1.000000 0.000000 +vt 0.521739 0.122449 +vt 0.521739 0.000000 +vt 1.000000 0.000000 +vt 0.521739 0.122449 +vt 0.521739 0.000000 +vt 0.934783 0.244898 +vt 0.586957 0.326531 +vt 0.586957 0.244898 +vt 1.000000 0.122449 +vt 0.586957 0.244898 +vt 1.000000 0.122449 +vt 1.000000 0.122449 +vt 0.586957 0.244898 +vt 0.934783 0.326531 +vt 0.630435 0.367347 +vt 0.586957 0.326531 +vt 0.934783 0.244898 +vt 0.586957 0.326531 +vt 0.934783 0.244898 +vt 0.934783 0.244898 +vt 0.586957 0.326531 +vt 0.891304 0.653061 +vt 0.630435 0.734694 +vt 0.630435 0.653061 +vt 0.586957 0.653061 +vt 0.891304 0.612245 +vt 0.934783 0.653061 +vt 0.891304 0.367347 +vt 0.630435 0.612245 +vt 0.630435 0.979592 +vt 0.891304 0.734694 +vt 0.891304 0.979592 +vt 0.891304 0.653061 +vt 0.630435 0.734694 +vt 0.630435 0.653061 +vt 0.891304 0.653061 +vt 0.630435 0.734694 +vt 0.630435 0.653061 +vt 0.891304 0.653061 +vt 0.630435 0.734694 +vt 0.630435 0.653061 +vt 0.369565 0.714286 +vt 0.358696 0.551020 +vt 0.369565 0.551020 +vt 0.000000 0.000000 +vt 0.173913 0.326531 +vt 0.521739 0.000000 +vt 0.173913 0.163265 +vt 0.347826 0.163265 +vt 0.163043 0.551020 +vt 0.173913 0.704082 +vt 0.163043 0.714286 +vt 0.152174 0.551020 +vt 0.152174 0.714286 +vt 0.173913 0.734694 +vt 0.347826 0.724490 +vt 0.347826 0.734694 +vt 0.347826 0.530612 +vt 0.173913 0.540816 +vt 0.173913 0.530612 +vt 0.184783 0.714286 +vt 0.336957 0.704082 +vt 0.336957 0.714286 +vt 0.173913 0.724490 +vt 0.347826 0.540816 +vt 0.184783 0.551020 +vt 0.358696 0.714286 +vt 0.347826 0.561224 +vt 0.336957 0.561224 +vt 0.184783 0.704082 +vt 0.184783 0.561224 +vt 0.336957 0.551020 +vt 0.347826 0.704082 +vt 0.173913 0.561224 +vt 0.521739 0.510204 +vt 0.521739 0.510204 +vt 0.521739 0.510204 +vt 0.934783 0.326531 +vt 0.934783 0.326531 +vt 0.934783 0.326531 +vt 0.891304 0.734694 +vt 0.891304 0.734694 +vt 0.891304 0.734694 +vn 0.0000 -1.0000 0.0000 +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.8944 0.4472 0.0000 +vn -0.8944 0.4472 0.0000 +vn 0.0000 0.4472 -0.8944 +vn 0.0000 0.4472 0.8944 +s off +f 6/1/1 36/2/1 8/3/1 +f 9/4/2 16/5/2 12/6/2 +f 8/3/3 11/7/3 6/1/3 +f 5/8/4 9/9/4 7/10/4 +f 7/11/5 12/12/5 8/13/5 +f 6/14/6 10/15/6 5/16/6 +f 15/17/6 18/18/6 14/19/6 +f 11/7/2 14/20/2 10/21/2 +f 12/6/2 15/22/2 11/7/2 +f 10/21/2 13/23/2 9/4/2 +f 20/24/7 23/25/7 19/26/7 +f 16/27/3 19/26/3 15/28/3 +f 14/29/4 17/30/4 13/31/4 +f 13/32/5 20/33/5 16/34/5 +f 21/35/5 28/36/5 24/37/5 +f 18/38/8 21/39/8 17/30/8 +f 17/40/9 24/37/9 20/33/9 +f 19/41/10 22/42/10 18/18/10 +f 28/43/2 2/44/2 27/45/2 +f 23/46/6 26/47/6 22/42/6 +f 24/48/3 27/45/3 23/25/3 +f 22/49/4 25/50/4 21/39/4 +f 2/51/5 32/52/5 3/53/5 +f 26/54/2 4/55/2 25/56/2 +f 25/56/2 1/57/2 28/43/2 +f 27/45/2 3/58/2 26/54/2 +f 32/59/2 29/60/2 30/61/2 +f 4/62/6 29/63/6 1/64/6 +f 3/65/3 30/66/3 4/67/3 +f 1/68/4 31/69/4 2/70/4 +f 36/71/6 37/72/6 35/73/6 +f 5/74/1 34/75/1 6/1/1 +f 7/76/1 33/77/1 5/74/1 +f 8/3/1 35/78/1 7/76/1 +f 38/79/1 43/80/1 39/81/1 +f 33/82/5 39/81/5 34/83/5 +f 34/84/4 40/85/4 36/86/4 +f 35/87/3 38/88/3 33/89/3 +f 43/90/3 48/91/3 44/92/3 +f 39/93/1 44/92/1 40/85/1 +f 37/94/1 42/95/1 38/88/1 +f 40/96/1 41/97/1 37/72/1 +f 45/98/1 47/99/1 46/100/1 +f 41/101/4 46/100/4 42/95/4 +f 44/102/5 45/98/5 41/97/5 +f 42/103/6 47/99/6 43/80/6 +f 6/1/1 34/75/1 36/2/1 +f 9/4/2 13/23/2 16/5/2 +f 8/3/3 12/6/3 11/7/3 +f 5/8/4 10/104/4 9/9/4 +f 7/11/5 9/105/5 12/12/5 +f 6/14/6 11/106/6 10/15/6 +f 15/17/6 19/41/6 18/18/6 +f 11/7/2 15/22/2 14/20/2 +f 12/6/2 16/5/2 15/22/2 +f 10/21/2 14/20/2 13/23/2 +f 20/24/7 24/48/7 23/25/7 +f 16/27/3 20/24/3 19/26/3 +f 14/29/4 18/38/4 17/30/4 +f 13/32/5 17/40/5 20/33/5 +f 21/35/5 25/107/5 28/36/5 +f 18/38/8 22/49/8 21/39/8 +f 17/40/9 21/35/9 24/37/9 +f 19/41/10 23/46/10 22/42/10 +f 28/43/2 1/57/2 2/44/2 +f 23/46/6 27/108/6 26/47/6 +f 24/48/3 28/43/3 27/45/3 +f 22/49/4 26/109/4 25/50/4 +f 2/51/5 31/110/5 32/52/5 +f 26/54/2 3/58/2 4/55/2 +f 25/56/2 4/55/2 1/57/2 +f 27/45/2 2/44/2 3/58/2 +f 32/59/2 31/69/2 29/60/2 +f 4/62/6 30/111/6 29/63/6 +f 3/65/3 32/112/3 30/66/3 +f 1/68/4 29/60/4 31/69/4 +f 36/71/6 40/96/6 37/72/6 +f 5/74/1 33/77/1 34/75/1 +f 7/76/1 35/78/1 33/77/1 +f 8/3/1 36/2/1 35/78/1 +f 38/79/1 42/103/1 43/80/1 +f 33/82/5 38/79/5 39/81/5 +f 34/84/4 39/93/4 40/85/4 +f 35/87/3 37/94/3 38/88/3 +f 43/90/3 47/99/3 48/91/3 +f 39/93/1 43/90/1 44/92/1 +f 37/94/1 41/101/1 42/95/1 +f 40/96/1 44/102/1 41/97/1 +f 45/98/1 48/91/1 47/99/1 +f 41/101/4 45/98/4 46/100/4 +f 44/102/5 48/91/5 45/98/5 +f 42/103/6 46/100/6 47/99/6 diff --git a/src/main/resources/assets/hbm/textures/gui/processing/gui_anvil.png b/src/main/resources/assets/hbm/textures/gui/processing/gui_anvil.png index 7fb48fbdbdc0bd4f50cc75626397aa2f84c8cd76..09fcb0e038c69db7b6c364a58f0bfc2c483c4f90 100755 GIT binary patch literal 3494 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 F{U1xlB(eYi literal 3521 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 L&isL?ck+J${YN>j diff --git a/src/main/resources/assets/hbm/textures/gui/processing/gui_furnace_combination.png b/src/main/resources/assets/hbm/textures/gui/processing/gui_furnace_combination.png new file mode 100644 index 0000000000000000000000000000000000000000..3645fbfd5cb8309eabd11e95781fdb756c18118c GIT binary patch literal 6228 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