From 0cf9d88e36f0a7209a840419ce1f3cbf277e3a9a Mon Sep 17 00:00:00 2001 From: Boblet Date: Tue, 8 Jul 2025 16:46:41 +0200 Subject: [PATCH] needle punch fuck machine --- .../ContainerMachineAssemblyMachine.java | 74 +++++++ .../gui/GUIMachineAssemblyMachine.java | 121 +++++++++++ .../recipes/AssemblyMachineRecipes.java | 56 +++++ .../inventory/recipes/anvil/AnvilRecipes.java | 5 +- .../recipes/loader/SerializableRecipe.java | 1 + src/main/java/com/hbm/main/ClientProxy.java | 1 + .../java/com/hbm/main/ResourceManager.java | 2 + .../machine/ModuleMachineAssembler.java | 3 +- .../tileentity/RenderAssemblyMachine.java | 157 ++++++++++++++ .../java/com/hbm/tileentity/TileMappings.java | 1 + .../machine/TileEntityMachineAssembler.java | 1 + .../TileEntityMachineAssemblerBase.java | 1 + .../TileEntityMachineAssemblyMachine.java | 192 +++++++++++++++++- .../textures/gui/processing/gui_assembler.png | Bin 3517 -> 3445 bytes 14 files changed, 607 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyMachine.java create mode 100644 src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyMachine.java create mode 100644 src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java create mode 100644 src/main/java/com/hbm/render/tileentity/RenderAssemblyMachine.java diff --git a/src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyMachine.java b/src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyMachine.java new file mode 100644 index 000000000..f7bc0d499 --- /dev/null +++ b/src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyMachine.java @@ -0,0 +1,74 @@ +package com.hbm.inventory.container; + +import com.hbm.inventory.SlotCraftingOutput; +import com.hbm.inventory.SlotNonRetarded; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemAssemblyTemplate; +import com.hbm.items.machine.ItemMachineUpgrade; +import com.hbm.util.InventoryUtil; + +import api.hbm.energymk2.IBatteryItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class ContainerMachineAssemblyMachine extends ContainerBase { + + public ContainerMachineAssemblyMachine(InventoryPlayer invPlayer, IInventory assembler) { + super(invPlayer, assembler); + + // Battery + this.addSlotToContainer(new SlotNonRetarded(assembler, 0, 152, 81)); + // Schematic + this.addSlotToContainer(new SlotNonRetarded(assembler, 1, 35, 126)); + // Upgrades + this.addSlots(assembler, 2, 152, 108, 2, 1); + // Input + this.addSlots(assembler, 4, 8, 18, 4, 3); + // Output + this.addSlotToContainer(new SlotCraftingOutput(invPlayer.player, assembler, 16, 98, 45)); + + this.playerInv(invPlayer, 8, 174); + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int index) { + ItemStack slotOriginal = null; + Slot slot = (Slot) this.inventorySlots.get(index); + + if(slot != null && slot.getHasStack()) { + ItemStack slotStack = slot.getStack(); + slotOriginal = slotStack.copy(); + + if(index <= tile.getSizeInventory() - 1) { + SlotCraftingOutput.checkAchievements(player, slotStack); + if(!this.mergeItemStack(slotStack, tile.getSizeInventory(), this.inventorySlots.size(), true)) { + return null; + } + } else { + + if(slotOriginal.getItem() instanceof IBatteryItem || slotOriginal.getItem() == ModItems.battery_creative) { + if(!this.mergeItemStack(slotStack, 0, 1, false)) return null; + } else if(slotOriginal.getItem() instanceof ItemAssemblyTemplate) { + if(!this.mergeItemStack(slotStack, 1, 2, false)) return null; + } else if(slotOriginal.getItem() instanceof ItemMachineUpgrade) { + if(!this.mergeItemStack(slotStack, 2, 4, false)) return null; + } else { + if(!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 4, 7, false)) return null; + } + } + + if(slotStack.stackSize == 0) { + slot.putStack(null); + } else { + slot.onSlotChanged(); + } + + slot.onPickupFromSlot(player, slotStack); + } + + return slotOriginal; + } +} diff --git a/src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyMachine.java b/src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyMachine.java new file mode 100644 index 000000000..8218c4057 --- /dev/null +++ b/src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyMachine.java @@ -0,0 +1,121 @@ +package com.hbm.inventory.gui; + +import org.lwjgl.opengl.GL11; + +import com.hbm.inventory.container.ContainerMachineAssemblyMachine; +import com.hbm.inventory.recipes.AssemblyMachineRecipes; +import com.hbm.inventory.recipes.loader.GenericRecipe; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.machine.TileEntityMachineAssemblyMachine; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; + +public class GUIMachineAssemblyMachine extends GuiInfoContainer { + + private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/processing/gui_assembler.png"); + private TileEntityMachineAssemblyMachine assembler; + + public GUIMachineAssemblyMachine(InventoryPlayer invPlayer, TileEntityMachineAssemblyMachine tedf) { + super(new ContainerMachineAssemblyMachine(invPlayer, tedf)); + assembler = tedf; + + this.xSize = 176; + this.ySize = 256; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float f) { + super.drawScreen(mouseX, mouseY, f); + + assembler.inputTank.renderTankInfo(this, mouseX, mouseY, guiLeft + 8, guiTop + 115, 34, 16); + assembler.outputTank.renderTankInfo(this, mouseX, mouseY, guiLeft + 80, guiTop + 115, 34, 16); + + this.drawElectricityInfo(this, mouseX, mouseY, guiLeft + 152, guiTop + 18, 16, 61, assembler.power, assembler.maxPower); + + if(guiLeft + 7 <= mouseX && guiLeft + 7 + 18 > mouseX && guiTop + 125 < mouseY && guiTop + 125 + 18 >= mouseY) { + if(this.assembler.assemblerModule.recipe != null && AssemblyMachineRecipes.INSTANCE.recipeNameMap.containsKey(this.assembler.assemblerModule.recipe)) { + GenericRecipe recipe = (GenericRecipe) AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(this.assembler.assemblerModule.recipe); + this.func_146283_a(recipe.print(), mouseX, mouseY); + } else { + this.drawCreativeTabHoveringText(EnumChatFormatting.YELLOW + "Click to set recipe", mouseX, mouseY); + } + } + } + + @Override + protected void mouseClicked(int x, int y, int button) { + super.mouseClicked(x, y, button); + + if(this.checkClick(x, y, 7, 125, 18, 18)) GUIScreenRecipeSelector.openSelector(AssemblyMachineRecipes.INSTANCE, assembler, assembler.assemblerModule.recipe, 0, this); + } + + @Override + protected void drawGuiContainerForegroundLayer(int i, int j) { + String name = this.assembler.hasCustomInventoryName() ? this.assembler.getInventoryName() : I18n.format(this.assembler.getInventoryName()); + + this.fontRendererObj.drawString(name, 70 - 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 p_146976_1_, int p_146976_2_, int p_146976_3_) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); + + int p = (int) (assembler.power * 61 / assembler.maxPower); + drawTexturedModalRect(guiLeft + 152, guiTop + 79 - p, 176, 61 - p, 16, p); + + if(assembler.assemblerModule.progress > 0) { + int j = (int) Math.ceil(70 * assembler.assemblerModule.progress); + drawTexturedModalRect(guiLeft + 62, guiTop + 126, 176, 61, j, 16); + } + + GenericRecipe recipe = AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(assembler.assemblerModule.recipe); + + /// LEFT LED + if(assembler.didProcess) { + drawTexturedModalRect(guiLeft + 51, guiTop + 121, 195, 0, 3, 6); + } else if(recipe != null) { + drawTexturedModalRect(guiLeft + 51, guiTop + 121, 192, 0, 3, 6); + } + + /// RIGHT LED + if(assembler.didProcess) { + drawTexturedModalRect(guiLeft + 56, guiTop + 121, 195, 0, 3, 6); + } else if(recipe != null && assembler.power >= recipe.power) { + drawTexturedModalRect(guiLeft + 56, guiTop + 121, 192, 0, 3, 6); + } + + this.renderItem(recipe != null ? recipe.getIcon() : TEMPLATE_FOLDER, 8, 126); + + if(recipe != null && recipe.inputItem != null) { + for(int i = 0; i < recipe.inputItem.length; i++) { + Slot slot = (Slot) this.inventorySlots.inventorySlots.get(assembler.assemblerModule.inputSlots[i]); + if(!slot.getHasStack()) this.renderItem(recipe.inputItem[i].extractForCyclingDisplay(20), slot.xDisplayPosition, slot.yDisplayPosition, 10F); + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + OpenGlHelper.glBlendFunc(770, 771, 1, 0); + GL11.glColor4f(1F, 1F, 1F, 0.5F); + GL11.glEnable(GL11.GL_BLEND); + this.zLevel = 300F; + for(int i = 0; i < recipe.inputItem.length; i++) { + Slot slot = (Slot) this.inventorySlots.inventorySlots.get(assembler.assemblerModule.inputSlots[i]); + if(!slot.getHasStack()) drawTexturedModalRect(guiLeft + slot.xDisplayPosition, guiTop + slot.yDisplayPosition, slot.xDisplayPosition, slot.yDisplayPosition, 16, 16); + } + this.zLevel = 0F; + GL11.glColor4f(1F, 1F, 1F, 1F); + GL11.glDisable(GL11.GL_BLEND); + } + + assembler.inputTank.renderTank(guiLeft + 8, guiTop + 115, this.zLevel, 34, 16, 1); + assembler.outputTank.renderTank(guiLeft + 80, guiTop + 115, this.zLevel, 34, 16, 1); + } +} diff --git a/src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java b/src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java new file mode 100644 index 000000000..c018e55c9 --- /dev/null +++ b/src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java @@ -0,0 +1,56 @@ +package com.hbm.inventory.recipes; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import static com.hbm.inventory.OreDictManager.*; +import static com.hbm.inventory.material.Mats.*; + +import com.hbm.inventory.FluidStack; +import com.hbm.inventory.RecipesCommon.AStack; +import com.hbm.inventory.RecipesCommon.ComparableStack; +import com.hbm.inventory.RecipesCommon.OreDictStack; +import com.hbm.inventory.recipes.loader.GenericRecipe; +import com.hbm.inventory.recipes.loader.GenericRecipes; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemFluidIcon; + +import net.minecraft.item.ItemStack; + +public class AssemblyMachineRecipes extends GenericRecipes { + + public static final AssemblyMachineRecipes INSTANCE = new AssemblyMachineRecipes(); + + @Override public int inputItemLimit() { return 12; } + @Override public int inputFluidLimit() { return 1; } + @Override public int outputItemLimit() { return 1; } + @Override public int outputFluidLimit() { return 1; } + + @Override public String getFileName() { return "hbmAsemblyMachine.json"; } + @Override public GenericRecipe instantiateRecipe(String name) { return new GenericRecipe(name); } + + @Override + public void registerDefaults() { + + this.register(new GenericRecipe("ass.test").setup(100, 1_000) + .inputItems(new OreDictStack(STEEL.ingot(), 5)) + .outputItems(new ItemStack(ModItems.plate_welded, 1, MAT_STEEL.id))); + } + + public static HashMap getRecipes() { + HashMap recipes = new HashMap(); + + for(GenericRecipe recipe : INSTANCE.recipeOrderedList) { + List input = new ArrayList(); + if(recipe.inputItem != null) for(AStack stack : recipe.inputItem) input.add(stack); + if(recipe.inputFluid != null) for(FluidStack stack : recipe.inputFluid) input.add(ItemFluidIcon.make(stack)); + List output = new ArrayList(); + if(recipe.outputItem != null) for(IOutput stack : recipe.outputItem) output.add(stack.getAllPossibilities()); + if(recipe.outputFluid != null) for(FluidStack stack : recipe.outputFluid) output.add(ItemFluidIcon.make(stack)); + recipes.put(input.toArray(), output.toArray()); + } + + return recipes; + } +} diff --git a/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java b/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java index fca1efb87..a98931abb 100644 --- a/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java @@ -229,12 +229,11 @@ public class AnvilRecipes extends SerializableRecipe { int ukModifier = 1; constructionRecipes.add(new AnvilConstructionRecipe( new AStack[] { - new OreDictStack(KEY_CLEARGLASS, 4 * ukModifier), new OreDictStack(STEEL.ingot(), 8 * ukModifier), - new OreDictStack(CU.ingot(), 8 * ukModifier), + new OreDictStack(CU.plate(), 4 * ukModifier), new ComparableStack(ModItems.motor, 2 * ukModifier), new ComparableStack(ModItems.circuit, 4 * ukModifier, EnumCircuitType.VACUUM_TUBE.ordinal()) - }, new AnvilOutput(new ItemStack(ModBlocks.machine_assembler))).setTier(2)); + }, new AnvilOutput(new ItemStack(ModBlocks.machine_assembly_machine))).setTier(2)); constructionRecipes.add(new AnvilConstructionRecipe( new AStack[] { diff --git a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java index ec30b16b3..f633298f1 100644 --- a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java +++ b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java @@ -83,6 +83,7 @@ public abstract class SerializableRecipe { recipeHandlers.add(new PedestalRecipes()); //GENERIC + recipeHandlers.add(AssemblyMachineRecipes.INSTANCE); recipeHandlers.add(ChemicalPlantRecipes.INSTANCE); recipeHandlers.add(new MatDistribution()); diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 128a8f8b4..1d934e87d 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -267,6 +267,7 @@ public class ClientProxy extends ServerProxy { ClientRegistry.bindTileEntitySpecialRenderer(TileEntityChimneyIndustrial.class, new RenderChimneyIndustrial()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineMiningLaser.class, new RenderLaserMiner()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineAssembler.class, new RenderAssembler()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineAssemblyMachine.class, new RenderAssemblyMachine()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineAssemfac.class, new RenderAssemfac()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemplant.class, new RenderChemplant()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemicalPlant.class, new RenderChemicalPlant()); diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 5ec3d90fc..a1fee2c2c 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -140,6 +140,7 @@ public class ResourceManager { public static final IModelCustom assembler_cog = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/assembler_new_cog.obj")); public static final IModelCustom assembler_slider = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/assembler_new_slider.obj")); public static final IModelCustom assembler_arm = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/assembler_new_arm.obj")); + public static final IModelCustom assembly_machine = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/assembly_machine.obj")); public static final IModelCustom assemfac = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/assemfac.obj")); //Chemplant @@ -574,6 +575,7 @@ public class ResourceManager { public static final ResourceLocation assembler_cog_tex = new ResourceLocation(RefStrings.MODID, "textures/models/assembler_cog_new.png"); public static final ResourceLocation assembler_slider_tex = new ResourceLocation(RefStrings.MODID, "textures/models/assembler_slider_new.png"); public static final ResourceLocation assembler_arm_tex = new ResourceLocation(RefStrings.MODID, "textures/models/assembler_arm_new.png"); + public static final ResourceLocation assembly_machine_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/assembly_machine.png"); public static final ResourceLocation assemfac_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/assemfac.png"); //Chemplant diff --git a/src/main/java/com/hbm/module/machine/ModuleMachineAssembler.java b/src/main/java/com/hbm/module/machine/ModuleMachineAssembler.java index 2188b306a..1823b540b 100644 --- a/src/main/java/com/hbm/module/machine/ModuleMachineAssembler.java +++ b/src/main/java/com/hbm/module/machine/ModuleMachineAssembler.java @@ -1,6 +1,7 @@ package com.hbm.module.machine; import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.inventory.recipes.AssemblyMachineRecipes; import com.hbm.inventory.recipes.loader.GenericRecipe; import api.hbm.energymk2.IEnergyHandlerMK2; @@ -18,7 +19,7 @@ public class ModuleMachineAssembler extends ModuleMachineBase { @Override public GenericRecipe getRecipe() { - return null; + return AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(this.recipe); } public ModuleMachineAssembler itemInput(int from) { for(int i = 0; i < inputSlots.length; i++) inputSlots[i] = from + i; return this; } diff --git a/src/main/java/com/hbm/render/tileentity/RenderAssemblyMachine.java b/src/main/java/com/hbm/render/tileentity/RenderAssemblyMachine.java new file mode 100644 index 000000000..6bb9a7f21 --- /dev/null +++ b/src/main/java/com/hbm/render/tileentity/RenderAssemblyMachine.java @@ -0,0 +1,157 @@ +package com.hbm.render.tileentity; + +import org.lwjgl.opengl.GL11; + +import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ModBlocks; +import com.hbm.inventory.recipes.AssemblyMachineRecipes; +import com.hbm.inventory.recipes.loader.GenericRecipe; +import com.hbm.main.MainRegistry; +import com.hbm.main.ResourceManager; +import com.hbm.render.item.ItemRenderBase; +import com.hbm.tileentity.machine.TileEntityMachineAssemblyMachine; +import com.hbm.util.BobMathUtil; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.client.IItemRenderer; + +public class RenderAssemblyMachine extends TileEntitySpecialRenderer implements IItemRendererProvider { + + public static EntityItem dummy; + + @Override + public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float interp) { + GL11.glPushMatrix(); + GL11.glTranslated(x + 0.5, y, z + 0.5); + GL11.glRotated(90, 0, 1, 0); + GL11.glShadeModel(GL11.GL_SMOOTH); + + switch(tileEntity.getBlockMetadata() - BlockDummyable.offset) { + case 2: GL11.glRotatef(0, 0F, 1F, 0F); break; + case 4: GL11.glRotatef(90, 0F, 1F, 0F); break; + case 3: GL11.glRotatef(180, 0F, 1F, 0F); break; + case 5: GL11.glRotatef(270, 0F, 1F, 0F); break; + } + + TileEntityMachineAssemblyMachine assembler = (TileEntityMachineAssemblyMachine) tileEntity; + + bindTexture(ResourceManager.assembly_machine_tex); + ResourceManager.assembly_machine.renderPart("Base"); + if(assembler.frame) ResourceManager.assembly_machine.renderPart("Frame"); + + GL11.glPushMatrix(); + + double spin = BobMathUtil.interp(assembler.prevRing, assembler.ring, interp); + double[] arm1 = assembler.arms[0].getPositions(interp); + double[] arm2 = assembler.arms[1].getPositions(interp); + + // arm1 = arm2 = new double[] {60, -15, 15, -0.25}; // heart + + GL11.glRotated(spin, 0, 1, 0); + ResourceManager.assembly_machine.renderPart("Ring"); + + GL11.glPushMatrix(); { + GL11.glTranslated(0, 1.625, 0.9375); + GL11.glRotated(arm1[0], 1, 0, 0); + GL11.glTranslated(0, -1.625, -0.9375); + ResourceManager.assembly_machine.renderPart("ArmLower1"); + + GL11.glTranslated(0, 2.375, 0.9375); + GL11.glRotated(arm1[1], 1, 0, 0); + GL11.glTranslated(0, -2.375, -0.9375); + ResourceManager.assembly_machine.renderPart("ArmUpper1"); + + GL11.glTranslated(0, 2.375, 0.4375); + GL11.glRotated(arm1[2], 1, 0, 0); + GL11.glTranslated(0, -2.375, -0.4375); + ResourceManager.assembly_machine.renderPart("Head1"); + GL11.glTranslated(0, arm1[3], 0); + ResourceManager.assembly_machine.renderPart("Spike1"); + } GL11.glPopMatrix(); + + GL11.glPushMatrix(); { + GL11.glTranslated(0, 1.625, -0.9375); + GL11.glRotated(-arm2[0], 1, 0, 0); + GL11.glTranslated(0, -1.625, 0.9375); + ResourceManager.assembly_machine.renderPart("ArmLower2"); + + GL11.glTranslated(0, 2.375, -0.9375); + GL11.glRotated(-arm2[1], 1, 0, 0); + GL11.glTranslated(0, -2.375, 0.9375); + ResourceManager.assembly_machine.renderPart("ArmUpper2"); + + GL11.glTranslated(0, 2.375, -0.4375); + GL11.glRotated(-arm2[2], 1, 0, 0); + GL11.glTranslated(0, -2.375, 0.4375); + ResourceManager.assembly_machine.renderPart("Head2"); + GL11.glTranslated(0, arm2[3], 0); + ResourceManager.assembly_machine.renderPart("Spike2"); + } GL11.glPopMatrix(); + + GL11.glPopMatrix(); + + GL11.glShadeModel(GL11.GL_FLAT); + + GenericRecipe recipe = AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(assembler.assemblerModule.recipe); + if(recipe != null && MainRegistry.proxy.me().getDistanceSq(tileEntity.xCoord + 0.5, tileEntity.yCoord + 1, tileEntity.zCoord + 0.5) < 35 * 35) { + + GL11.glRotated(90, 0, 1, 0); + GL11.glTranslated(0, 1.0625, 0); + + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + ItemStack stack = recipe.getIcon(); + + if(!(stack.getItemSpriteNumber() == 0 && stack.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d(Block.getBlockFromItem(stack.getItem()).getRenderType()))) { + GL11.glRotated(-90, 1, 0, 0); + GL11.glTranslated(0, -0.25, 0); + } + + GL11.glScaled(1.25, 1.25, 1.25); + + if(dummy == null || dummy.worldObj != tileEntity.getWorldObj()) dummy = new EntityItem(tileEntity.getWorldObj(), 0, 0, 0, stack); + dummy.setEntityItemStack(stack); + dummy.hoverStart = 0.0F; + + RenderItem.renderInFrame = true; + RenderManager.instance.renderEntityWithPosYaw(dummy, 0.0D, 0.0D, 0.0D, 0.0F, 0.0F); + RenderItem.renderInFrame = false; + } + + GL11.glPopMatrix(); + } + + @Override + public Item getItemForRenderer() { + return Item.getItemFromBlock(ModBlocks.machine_assembly_machine); + } + + @Override + public IItemRenderer getRenderer() { + + return new ItemRenderBase() { + + public void renderInventory() { + GL11.glTranslated(0, -2.75, 0); + GL11.glScaled(4.5, 4.5, 4.5); + } + public void renderCommonWithStack(ItemStack item) { + GL11.glRotated(90, 0, 1, 0); + GL11.glScaled(0.75, 0.75, 0.75); + GL11.glShadeModel(GL11.GL_SMOOTH); + bindTexture(ResourceManager.assembly_machine_tex); + ResourceManager.assembly_machine.renderAll(); + GL11.glShadeModel(GL11.GL_FLAT); + }}; + } +} diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index 20e51d5fc..ca3281bd1 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -340,6 +340,7 @@ public class TileMappings { put(TileEntityMachineCombustionEngine.class, "tileentity_combustion_engine"); put(TileEntityMachineAssembler.class, "tileentity_assembly_machine"); + put(TileEntityMachineAssemblyMachine.class, "tileentity_assemblymachine"); put(TileEntityMachineAssemfac.class, "tileentity_assemfac"); put(TileEntityMachineChemplant.class, "tileentity_chemical_plant"); put(TileEntityMachineChemicalPlant.class, "tileentity_chemicalplant"); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssembler.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssembler.java index 53b47d04b..1117d6674 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssembler.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssembler.java @@ -31,6 +31,7 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; +@Deprecated public class TileEntityMachineAssembler extends TileEntityMachineAssemblerBase implements IUpgradeInfoProvider { public int recipe = -1; diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblerBase.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblerBase.java index d0d58dfb4..bcf3172d1 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblerBase.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblerBase.java @@ -22,6 +22,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +@Deprecated public abstract class TileEntityMachineAssemblerBase extends TileEntityMachineBase implements IEnergyReceiverMK2, IGUIProvider { public long power; diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyMachine.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyMachine.java index 3a057c184..7007e54e5 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyMachine.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyMachine.java @@ -2,14 +2,15 @@ package com.hbm.tileentity.machine; import java.util.HashMap; import java.util.List; +import java.util.Random; import com.hbm.blocks.ModBlocks; import com.hbm.interfaces.IControlReceiver; import com.hbm.inventory.UpgradeManagerNT; -import com.hbm.inventory.container.ContainerMachineChemicalPlant; +import com.hbm.inventory.container.ContainerMachineAssemblyMachine; import com.hbm.inventory.fluid.Fluids; import com.hbm.inventory.fluid.tank.FluidTank; -import com.hbm.inventory.gui.GUIMachineChemicalPlant; +import com.hbm.inventory.gui.GUIMachineAssemblyMachine; import com.hbm.items.ModItems; import com.hbm.items.machine.ItemMachineUpgrade; import com.hbm.items.machine.ItemMachineUpgrade.UpgradeType; @@ -33,7 +34,6 @@ 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.util.EnumChatFormatting; import net.minecraft.world.World; @@ -51,6 +51,13 @@ public class TileEntityMachineAssemblyMachine extends TileEntityMachineBase impl private AudioWrapper audio; public ModuleMachineAssembler assemblerModule; + + public AssemblerArm[] arms = new AssemblerArm[2]; + public double prevRing; + public double ring; + public double ringSpeed; + public double ringTarget; + public int ringDelay; public UpgradeManagerNT upgradeManager = new UpgradeManagerNT(this); @@ -59,6 +66,8 @@ public class TileEntityMachineAssemblyMachine extends TileEntityMachineBase impl this.inputTank = new FluidTank(Fluids.NONE, 32_000); this.outputTank = new FluidTank(Fluids.NONE, 32_000); + for(int i = 0; i < this.arms.length; i++) this.arms[i] = new AssemblerArm(); + this.assemblerModule = new ModuleMachineAssembler(0, this, slots) .itemInput(4).itemOutput(16) .fluidInput(inputTank).fluidOutput(outputTank); @@ -128,11 +137,50 @@ public class TileEntityMachineAssemblyMachine extends TileEntityMachineBase impl audio = null; } } + + for(AssemblerArm arm : arms) { + arm.updateInterp(); + if(didProcess) { + arm.updateArm(); + } else{ + arm.returnToNullPos(); + } + } + + this.prevRing = this.ring; + + if(didProcess) { + if(this.ring != this.ringTarget) { + double ringDelta = Math.abs(this.ringTarget - this.ring); + if(ringDelta <= this.ringSpeed) this.ring = this.ringTarget; + if(this.ringTarget > this.ring) this.ring += this.ringSpeed; + if(this.ringTarget < this.ring) this.ring -= this.ringSpeed; + if(this.ringTarget == this.ring) { + if(ringTarget >= 360) { + this.ringTarget -= 360D; + this.ring -= 360D; + this.prevRing -= 360D; + } + if(ringTarget <= -360) { + this.ringTarget += 360D; + this.ring += 360D; + this.prevRing += 360D; + } + this.ringDelay = 20 + worldObj.rand.nextInt(21); + } + } else { + if(this.ringDelay > 0) this.ringDelay--; + if(this.ringDelay <= 0) { + this.ringTarget += (worldObj.rand.nextDouble() * 2 - 1) * 135; + this.ringSpeed = 10D + worldObj.rand.nextDouble() * 5D; + } + } + } } } @Override public AudioWrapper createAudioLoop() { - return MainRegistry.proxy.getLoopedSound("hbm:block.assembler", xCoord, yCoord, zCoord, 1F, 15F, 1.0F, 20); + return MainRegistry.proxy.getLoopedSound("hbm:block.chemicalPlant", xCoord, yCoord, zCoord, 1F, 15F, 1.0F, 20); } @Override public void onChunkUnload() { @@ -216,6 +264,11 @@ public class TileEntityMachineAssemblyMachine extends TileEntityMachineBase impl return i == 16; } + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return new int[] {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + } + @Override public long getPower() { return power; } @Override public void setPower(long power) { this.power = power; } @Override public long getMaxPower() { return maxPower; } @@ -283,4 +336,135 @@ public class TileEntityMachineAssemblyMachine extends TileEntityMachineBase impl upgrades.put(UpgradeType.OVERDRIVE, 3); return upgrades; } + + public static class AssemblerArm { + + public double[] angles = new double[4]; + public double[] prevAngles = new double[4]; + public double[] targetAngles = new double[4]; + public double[] speed = new double[4]; + + Random rand = new Random(); + ArmActionState state = ArmActionState.ASSUME_POSITION; + int actionDelay = 0; + + public static enum ArmActionState { + ASSUME_POSITION, + EXTEND_STRIKER, + RETRACT_STRIKER + } + + public AssemblerArm() { + this.resetSpeed(); + } + + private void updateInterp() { + for(int i = 0; i < angles.length; i++) { + prevAngles[i] = angles[i]; + } + } + + private void returnToNullPos() { + for(int i = 0; i < 4; i++) this.targetAngles[i] = 0; + for(int i = 0; i < 3; i++) this.speed[i] = 3; + this.speed[3] = 0.25; + this.state = ArmActionState.RETRACT_STRIKER; + + this.move(); + } + + private void resetSpeed() { + speed[0] = 15; //Pivot + speed[1] = 15; //Arm + speed[2] = 15; //Piston + speed[3] = 0.5; //Striker + } + + public void updateArm() { + resetSpeed(); + + if(actionDelay > 0) { + actionDelay--; + return; + } + + switch(state) { + // Move. If done moving, set a delay and progress to EXTEND + case ASSUME_POSITION: + if(move()) { + actionDelay = 2; + state = ArmActionState.EXTEND_STRIKER; + targetAngles[3] = -0.75D; + } + break; + case EXTEND_STRIKER: + if(move()) { + state = ArmActionState.RETRACT_STRIKER; + targetAngles[3] = 0D; + } + break; + case RETRACT_STRIKER: + if(move()) { + actionDelay = 2 + rand.nextInt(5); + chooseNewArmPoistion(); + state = ArmActionState.ASSUME_POSITION; + } + break; + + } + } + + private double[][] pos = new double[][] { // possible positions for the arms + {45, -15, -5}, + {15, 15, -15}, + {25, 10, -15}, + {30, 0, -10}, + {70, -10, -25}, + }; // sure it's not truly random like with the old assemfac, but at least now the striker always hits the center and doesn't clip through the board + + public void chooseNewArmPoistion() { + int chosen = rand.nextInt(pos.length); + this.targetAngles[0] = pos[chosen][0]; + this.targetAngles[1] = pos[chosen][1]; + this.targetAngles[2] = pos[chosen][2]; + } + + private boolean move() { + boolean didMove = false; + + for(int i = 0; i < angles.length; i++) { + if(angles[i] == targetAngles[i]) + continue; + + didMove = true; + + double angle = angles[i]; + double target = targetAngles[i]; + double turn = speed[i]; + double delta = Math.abs(angle - target); + + if(delta <= turn) { + angles[i] = targetAngles[i]; + continue; + } + + if(angle < target) { + angles[i] += turn; + } else { + angles[i] -= turn; + } + } + + return !didMove; + } + + public double[] getPositions(float interp) { + return new double[] { + BobMathUtil.interp(this.prevAngles[0], this.angles[0], interp), + BobMathUtil.interp(this.prevAngles[1], this.angles[1], interp), + BobMathUtil.interp(this.prevAngles[2], this.angles[2], interp), + BobMathUtil.interp(this.prevAngles[3], this.angles[3], interp) + }; + } + } } diff --git a/src/main/resources/assets/hbm/textures/gui/processing/gui_assembler.png b/src/main/resources/assets/hbm/textures/gui/processing/gui_assembler.png index 19221af066c73104c8d5226f6e1e33f50c46a3d1..dc9f7034bfa3723926a9e3a087278070caec4777 100644 GIT binary patch literal 3445 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 LjP>(Q6Yu{E9d9*S literal 3517 zcmb_ec|6ox8$YvTCSgnz8Osn#*4s^t!A!X5D$xyPC$6 zhbqo{*yqH)ZM*rY)q*T`dRi_2jhq0|2!2hR51!<0AXXYLZkn@r#wgaM&#lqtU;&{L z9XEGMKVrGO2NC7igV7gKAR+%?Fc=j=Cer%h zmHHVnBi}^BgQIYMq>Y^L>P?={+MDN}Gd^M^Nc_5lEAprqlXJ3N-V8D9z{p72WM^iK z++qGme*vlubbxl-Smvcwn0nntVLXHC>LE7LvB6z&Kl)$~2kEAt8Ai%@?J8SSQ&VcM z*3|U^HNO&BMB11mNnxJF9QCF*)8&@Rp5V^UPNQV%H|qImktJuJkucZD&5VHOjJ1Wg z#21b+%83g*d$oQ$VPxc{^RRE0ppAhg0?5jM}HVH{ST& zrW_mCTZZM0e;eZ#Vq6fHz(q6&VzSw1tP4J@2YlFhY_b3}LmS+VK2T6cSliwbo7;?! zO=w}z_?&`G8-yDKU&L7NIEL?;4q{a0HTM68$wG}r4;m_5VS#pWdW#)RcR)Gs8Ubka zSL=hf`UG9uNF#dB=G!p6_WUqSJkO4&^MR zN9B7R#%Jiut3w_eE#I9aO}^SozOHhFBEtgAIt=*+0oYW*=F^JQ)9V|Dhfh|$3eSI< zKHAI~Q-2oq{q5M(Muf@3^^W0u|mCE$ugcg=sFGeSiLKVoywPFFDa|zdFU9O*uk`EJ6Yb zO_qxD#?%^X4MTo#%=vD5(GQRSd?#sW>>OZT{|3$MfjX=oR?EVCZyio!4|u%}d;sw67Mt)u!)2 zs2<%XBKnEbo`l55H{ZatWr1#7=IgR|Q+E@aP|@IGppT#5+~aSNmpj%Tcq%^;Y>QqV z`!uKH6>gi@B&G-(8t)sPm@u1kxSahk{75PzO!lNTLiy8bT%F>5)M}oy9(g$6&Xub& z8i}DziDcDy1N^$~ZYPe-*H!)MFyfM?q14=yom(xE)Lmme*Ry~04cE;GFJ!LVI-}%s z&?6EX4GQ!0PPGU1JkT{vQ}r>WIo&u;wt0q_H~pl^eWV$I?SoZj^XbMnGacwHF&|fd zI*S^O`@6?p;8}~A^e@K--QPXR*!ZbZU@C5qb+$+FmnQ$5llD8decIKl`cY+8^iLfq z2IO7s>8V%M{14Rx7SpF-m5-LYeBS(3K%1Kk@SWu++P&=V^xm0&OEj11!)7WxcdS*@ zY`gop-Oi9fmmeX^XR}tB-_y1LzYp%kUH0*_Xk)M#ox+fXIPaotH#9rH375g>e3gHmKL#9U)pd5XU3s%J4sUUYngj)rujtIgmP7jp1mLBu6yxyb;^x%dVc8%?~ze=%m zQ~b5Q`Vvp`c5$Q(c1Kuu{)CvEbx^9wJT|hNu2xTiwwtbu2jl3VQdo-9;{IC<#nd=r?6J!fub%ZcueWL zVt1UIrBtO7qT83 zbXC80E$JRTkkV$2&yqp{+f-j3)*uT9&BQd>ZEmGP2#H9odk8Y?{kvs0sBTOoPa#tx zbjJC}zi1V9Sqo8>-@rgL76OL^&f+j2ZVa-l&ZTin_o5rs`(RnY=UAXi9}XU7HL}Q{ z0T+UNudW5gv@#{*6#WE^H^y=F7T>Rr(pT)Rr!LGgIwwf=8^OvWlauvZ?l}cJ^JUok zY+#@X4ME@b2RP`(VFvfdfFp?@k1E{IB@Fgp;o`f?c177sEHXc^nhR4A4yUo;f<5En z68Ff3gB%g3Eg2{NbdE0X7c6kdqwvvJ#I?EoVw&^gs`aHAF;2fCveYCZgT4H=9(GPv zb@qsOqF@#j`ibZXH|~ATeOn);0SlA zs3HC+SRIOFzPkHTgllyORO^d)5z7>UHujp0fhiw`6YMwNW?5f+rKhM!{%U`@5GU>ef&wOoua5k8%J2xK{Z2nMYFlKn|PSHb)#6rI+6 zm!l8owAqkG4sN5Gu@0 zk6IwCojf!&q?U+^Q%N(s61eEe7$mVkv_ddi_$Ki6@iz0HN+qBg)Mey8dGMaH!2RZ~ z@^dVrr$P;d{NDGd$np9n+mEkbbq7|x(UHC*TJ)+oA4hh+94HYf?|W%Dws|DMyyntW z>S5aRxAig-B)vMLm%ud5rh$+t2)l;Y8u zVJS4xt2Vi@G7_qWnhr#e$C+ZIV~y8Qi{A!*Y=4wKI5Dqg6)6t?kGlRrbpP$|+1UuN zeGdvFtsN=S{z!7_$nM)30*2UuIz4S7+%hpb5X$R^>FKett&jt&)^WxszoCr?%nqn= zMBYOHf&JiLDDQt=h9I*gITH;sf0f1ilSuzRrJ0|lq5$n9Hjg0iPc~Kw-JRqRrDS4A zXmg0_mW1L0-LFBI!5IFXt^Zf(->Dr4oVRgqw{#NXx!5?fg=*khF|z;YDK^=&r28fN z<#M_`MIG(!Evl$LSYn)mxXUx<7-ZhHoejUrD{FikKS*VI@&s2&>SHQ5REj4Iwo~o+ MPv%C22F}<10u