From 07a2e4eea36ebfef8c6d52486df46c68268e8edd Mon Sep 17 00:00:00 2001 From: Boblet Date: Mon, 8 Sep 2025 16:54:05 +0200 Subject: [PATCH] tragic yuri --- changelog | 4 +- src/main/java/com/hbm/blocks/ModBlocks.java | 3 + .../machine/MachineAssemblyFactory.java | 88 ++++ .../ContainerMachineAssemblyFactory.java | 86 ++++ .../container/ContainerPADetector.java | 6 +- .../gui/GUIMachineAssemblyFactory.java | 140 ++++++ .../gui/GUIMachineChemicalFactory.java | 3 +- src/main/java/com/hbm/main/ClientProxy.java | 1 + .../java/com/hbm/main/ResourceManager.java | 2 + .../tileentity/RenderAssemblyFactory.java | 61 +++ .../java/com/hbm/tileentity/TileMappings.java | 1 + .../TileEntityMachineAssemblyFactory.java | 407 ++++++++++++++++++ .../machine/TileEntityMachineAssemfac.java | 1 + .../TileEntityMachineChemicalFactory.java | 9 +- .../machine/albion/TileEntityPADetector.java | 10 + .../java/com/hbm/util/AchievementHandler.java | 1 + .../gui/processing/gui_assembly_factory.png | Bin 0 -> 4662 bytes .../models/machines/assembly_factory.png | Bin 3677 -> 4916 bytes 18 files changed, 810 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/hbm/blocks/machine/MachineAssemblyFactory.java create mode 100644 src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyFactory.java create mode 100644 src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyFactory.java create mode 100644 src/main/java/com/hbm/render/tileentity/RenderAssemblyFactory.java create mode 100644 src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyFactory.java create mode 100644 src/main/resources/assets/hbm/textures/gui/processing/gui_assembly_factory.png diff --git a/changelog b/changelog index 84d70e20e..de0dc79c4 100644 --- a/changelog +++ b/changelog @@ -7,4 +7,6 @@ ## Fixed * Fixed fusion reactor item IO being broken -* Fixed issue with the chemical factory where the declogging feature would be triggered by a recipe processor that doesn't even own the reported slot \ No newline at end of file +* Fixed issue with the chemical factory where the declogging feature would be triggered by a recipe processor that doesn't even own the reported slot +* Fixed the new PA not triggering the omega-12 achievement + * In addition to granting the achievement to nearby players on recipe completion, it is also granted when taking it out of the output slot \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index d30f6b619..74d743a47 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -1007,6 +1007,7 @@ public class ModBlocks { @Deprecated public static Block machine_assembler; public static Block machine_assembly_machine; @Deprecated public static Block machine_assemfac; + public static Block machine_assembly_factory; public static Block machine_arc_welder; public static Block machine_soldering_station; public static Block machine_arc_furnace; @@ -2240,6 +2241,7 @@ public class ModBlocks { machine_assembler = new MachineAssembler(Material.iron).setBlockName("machine_assembler").setHardness(5.0F).setResistance(30.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":machine_assembler"); machine_assembly_machine = new MachineAssemblyMachine(Material.iron).setBlockName("machine_assembly_machine").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); machine_assemfac = new MachineAssemfac(Material.iron).setBlockName("machine_assemfac").setHardness(5.0F).setResistance(30.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":block_steel"); + machine_assembly_factory = new MachineAssemblyFactory(Material.iron).setBlockName("machine_assembly_factory").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); machine_arc_welder = new MachineArcWelder(Material.iron).setBlockName("machine_arc_welder").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); machine_soldering_station = new MachineSolderingStation(Material.iron).setBlockName("machine_soldering_station").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); machine_chemplant = new MachineChemplant(Material.iron).setBlockName("machine_chemplant").setHardness(5.0F).setResistance(30.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":block_steel"); @@ -3298,6 +3300,7 @@ public class ModBlocks { GameRegistry.registerBlock(machine_assembler, machine_assembler.getUnlocalizedName()); register(machine_assembly_machine); GameRegistry.registerBlock(machine_assemfac, machine_assemfac.getUnlocalizedName()); + register(machine_assembly_factory); GameRegistry.registerBlock(machine_chemplant, machine_chemplant.getUnlocalizedName()); register(machine_chemical_plant); register(machine_chemfac); diff --git a/src/main/java/com/hbm/blocks/machine/MachineAssemblyFactory.java b/src/main/java/com/hbm/blocks/machine/MachineAssemblyFactory.java new file mode 100644 index 000000000..409be9874 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/MachineAssemblyFactory.java @@ -0,0 +1,88 @@ +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.blocks.ITooltipProvider; +import com.hbm.tileentity.TileEntityProxyDyn; +import com.hbm.tileentity.machine.TileEntityMachineAssemblyFactory; +import com.hbm.util.fauxpointtwelve.DirPos; +import com.hbm.util.i18n.I18nUtil; + +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.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre; +import net.minecraftforge.common.util.ForgeDirection; + +public class MachineAssemblyFactory extends BlockDummyable implements ITooltipProvider, ILookOverlay { + + public MachineAssemblyFactory(Material mat) { + super(mat); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + if(meta >= 12) return new TileEntityMachineAssemblyFactory(); + if(meta >= 6) return new TileEntityProxyDyn().inventory().power().fluid(); + return null; + } + + @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[] {2, 0, 2, 2, 2, 2}; } + @Override public int getOffset() { return 2; } + + @Override + public void fillSpace(World world, int x, int y, int z, ForgeDirection dir, int o) { + super.fillSpace(world, x, y, z, dir, o); + + x -= dir.offsetX * 2; + z -= dir.offsetZ * 2; + + for(int i = -2; i <= 2; i++) for(int j = -2; j <= 2; j++) { + if(Math.abs(i) == 2 || Math.abs(j) == 2) this.makeExtra(world, x + i, y, z + j); + } + + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + for(int i = -2; i <= 2; i++) { + this.makeExtra(world, x + dir.offsetX * i + rot.offsetX * 2, y + 2, z + dir.offsetZ * i + rot.offsetZ * 2); + this.makeExtra(world, x + dir.offsetX * i - rot.offsetX * 2, y + 2, z + dir.offsetZ * i - rot.offsetZ * 2); + } + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + this.addStandardInfo(stack, player, list, ext); + } + + @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 TileEntityMachineAssemblyFactory)) return; + TileEntityMachineAssemblyFactory assemfac = (TileEntityMachineAssemblyFactory) te; + + DirPos[] cool = assemfac.getCoolPos(); + + for(DirPos dirPos : cool) if(dirPos.compare(x + dirPos.getDir().offsetX, y, z + dirPos.getDir().offsetZ)) { + List text = new ArrayList(); + + text.add(EnumChatFormatting.GREEN + "-> " + EnumChatFormatting.RESET + assemfac.water.getTankType().getLocalizedName()); + text.add(EnumChatFormatting.RED + "<- " + EnumChatFormatting.RESET + assemfac.lps.getTankType().getLocalizedName()); + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); + break; + } + } +} diff --git a/src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyFactory.java b/src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyFactory.java new file mode 100644 index 000000000..01f094c4a --- /dev/null +++ b/src/main/java/com/hbm/inventory/container/ContainerMachineAssemblyFactory.java @@ -0,0 +1,86 @@ +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.ItemBlueprints; +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 ContainerMachineAssemblyFactory extends ContainerBase { + + public ContainerMachineAssemblyFactory(InventoryPlayer invPlayer, IInventory assemFac) { + super(invPlayer, assemFac); + + // Battery + this.addSlotToContainer(new SlotNonRetarded(assemFac, 0, 234, 112)); + // Upgrades + this.addSlots(assemFac, 1, 214, 149, 3, 1); + + for(int i = 0; i < 4; i++) { + // Template + this.addSlots(assemFac, 4 + i * 14, 25 + (i % 2) * 109, 54 + (i / 2) * 56, 1, 1); + // Solid Input + this.addSlots(assemFac, 5 + i * 14, 7 + (i % 2) * 109, 20 + (i / 2) * 56, 2, 6, 16); + // Solid Output + this.addOutputSlots(invPlayer.player, assemFac, 17 + i * 14, 87 + (i % 2) * 109, 54 + (i / 2) * 56, 1, 1); + } + + this.playerInv(invPlayer, 33, 158); + } + + @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 ItemBlueprints) { + if(!this.mergeItemStack(slotStack, 4, 5, false)) return null; + } else if(slotOriginal.getItem() instanceof ItemBlueprints) { + if(!this.mergeItemStack(slotStack, 18, 19, false)) return null; + } else if(slotOriginal.getItem() instanceof ItemBlueprints) { + if(!this.mergeItemStack(slotStack, 32, 33, false)) return null; + } else if(slotOriginal.getItem() instanceof ItemBlueprints) { + if(!this.mergeItemStack(slotStack, 44, 45, false)) return null; + } else if(slotOriginal.getItem() instanceof ItemMachineUpgrade) { + if(!this.mergeItemStack(slotStack, 1, 4, false)) return null; + } else { + if(!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 5, 17, false) && + !InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 19, 31, false) && + !InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 33, 46, false) && + !InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 47, 59, 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/container/ContainerPADetector.java b/src/main/java/com/hbm/inventory/container/ContainerPADetector.java index 08e8f9e81..d9a927f8d 100644 --- a/src/main/java/com/hbm/inventory/container/ContainerPADetector.java +++ b/src/main/java/com/hbm/inventory/container/ContainerPADetector.java @@ -1,6 +1,6 @@ package com.hbm.inventory.container; -import com.hbm.inventory.SlotTakeOnly; +import com.hbm.inventory.SlotCraftingOutput; import com.hbm.items.ModItems; import com.hbm.tileentity.machine.albion.TileEntityPADetector; @@ -24,8 +24,8 @@ public class ContainerPADetector extends Container { this.addSlotToContainer(new Slot(tile, 1, 62, 18)); this.addSlotToContainer(new Slot(tile, 2, 80, 18)); //Outputs - this.addSlotToContainer(new SlotTakeOnly(tile, 3, 62, 45)); - this.addSlotToContainer(new SlotTakeOnly(tile, 4, 80, 45)); + this.addSlotToContainer(new SlotCraftingOutput(playerInv.player, tile, 3, 62, 45)); + this.addSlotToContainer(new SlotCraftingOutput(playerInv.player, tile, 4, 80, 45)); for(int i = 0; i < 3; i++) { for(int j = 0; j < 9; j++) { diff --git a/src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyFactory.java b/src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyFactory.java new file mode 100644 index 000000000..583b57bce --- /dev/null +++ b/src/main/java/com/hbm/inventory/gui/GUIMachineAssemblyFactory.java @@ -0,0 +1,140 @@ +package com.hbm.inventory.gui; + +import org.lwjgl.opengl.GL11; + +import com.hbm.inventory.container.ContainerMachineAssemblyFactory; +import com.hbm.inventory.recipes.AssemblyMachineRecipes; +import com.hbm.inventory.recipes.loader.GenericRecipe; +import com.hbm.items.machine.ItemBlueprints; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.machine.TileEntityMachineAssemblyFactory; +import com.hbm.util.i18n.I18nUtil; + +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 GUIMachineAssemblyFactory extends GuiInfoContainer { + + private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/processing/gui_assembly_factory.png"); + private TileEntityMachineAssemblyFactory assembler; + + public GUIMachineAssemblyFactory(InventoryPlayer invPlayer, TileEntityMachineAssemblyFactory tedf) { + super(new ContainerMachineAssemblyFactory(invPlayer, tedf)); + assembler = tedf; + + this.xSize = 256; + this.ySize = 240; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float f) { + super.drawScreen(mouseX, mouseY, f); + + for(int j = 0; j < 4; j++) { + assembler.inputTanks[j].renderTankInfo(this, mouseX, mouseY, guiLeft + 105 + (j % 2) * 109, guiTop + 20 + (j / 2) * 56, 3, 16); + assembler.outputTanks[j].renderTankInfo(this, mouseX, mouseY, guiLeft + 105 + (j % 2) * 109, guiTop + 54 + (j / 2) * 56, 3, 16); + } + + assembler.water.renderTankInfo(this, mouseX, mouseY, guiLeft + 232, guiTop + 149, 7, 52); + assembler.lps.renderTankInfo(this, mouseX, mouseY, guiLeft + 241, guiTop + 149, 7, 52); + + this.drawElectricityInfo(this, mouseX, mouseY, guiLeft + 234, guiTop + 18, 16, 92, assembler.power, assembler.maxPower); + + for(int i = 0; i < 4; i++) if(guiLeft + 6 + (i % 2) * 109 <= mouseX && guiLeft + 6 + (i % 2) * 109 + 18 > mouseX && guiTop + 53 + (i / 2) * 56 < mouseY && guiTop + 53 + (i / 2) * 56 + 18 >= mouseY) { + if(this.assembler.assemblerModule[i].recipe != null && AssemblyMachineRecipes.INSTANCE.recipeNameMap.containsKey(this.assembler.assemblerModule[i].recipe)) { + GenericRecipe recipe = (GenericRecipe) AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(this.assembler.assemblerModule[i].recipe); + this.func_146283_a(recipe.print(), mouseX, mouseY); + } else { + this.drawCreativeTabHoveringText(EnumChatFormatting.YELLOW + I18nUtil.resolveKey("gui.recipe.setRecipe"), mouseX, mouseY); + } + } + } + + @Override + protected void mouseClicked(int x, int y, int button) { + super.mouseClicked(x, y, button); + + for(int i = 0; i < 4; i++) if(this.checkClick(x, y, 6 + (i % 2) * 109, 53 + (i / 2) * 56, 18, 18)) GUIScreenRecipeSelector.openSelector(AssemblyMachineRecipes.INSTANCE, assembler, assembler.assemblerModule[i].recipe, i, ItemBlueprints.grabPool(assembler.slots[4 + i * 14]), 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, 113 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752); + this.fontRendererObj.drawString(I18n.format("container.inventory"), 33, 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, 256, 140); + drawTexturedModalRect(guiLeft + 25, guiTop + 140, 25, 140, 231, 100); + + int p = (int) (assembler.power * 92 / assembler.maxPower); + drawTexturedModalRect(guiLeft + 234, guiTop + 110 - p, 0, 232 - p, 16, p); + + for(int i = 0; i < 4; i++) if(assembler.assemblerModule[i].progress > 0) { + int j = (int) Math.ceil(37 * assembler.assemblerModule[i].progress); + drawTexturedModalRect(guiLeft + 45 + (i % 2) * 109, guiTop + 63 + (i / 2) * 56, 0, 240, j, 6); + } + + for(int g = 0; g < 4; g++) { + GenericRecipe recipe = AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(assembler.assemblerModule[g].recipe); + + /// LEFT LED + if(assembler.didProcess[g]) { + drawTexturedModalRect(guiLeft + 45 + (g % 2) * 109, guiTop + 55 + (g / 2) * 56, 4, 236, 4, 4); + } else if(recipe != null) { + drawTexturedModalRect(guiLeft + 45 + (g % 2) * 109, guiTop + 55 + (g / 2) * 56, 0, 236, 4, 4); + } + + /// RIGHT LED + if(assembler.didProcess[g]) { + drawTexturedModalRect(guiLeft + 53 + (g % 2) * 109, guiTop + 55 + (g / 2) * 56, 4, 236, 4, 4); + } else if(recipe != null && assembler.power >= recipe.power && assembler.canCool()) { + drawTexturedModalRect(guiLeft + 53 + (g % 2) * 109, guiTop + 55 + (g / 2) * 56, 0, 236, 4, 4); + } + } + + for(int g = 0; g < 4; g++) { + GenericRecipe recipe = AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(assembler.assemblerModule[g].recipe); + + this.renderItem(recipe != null ? recipe.getIcon() : TEMPLATE_FOLDER, 7 + (g % 2) * 109, 54 + (g / 2) * 56); + + if(recipe != null && recipe.inputItem != null) { + for(int i = 0; i < recipe.inputItem.length; i++) { + Slot slot = (Slot) this.inventorySlots.inventorySlots.get(assembler.assemblerModule[g].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[g].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); + } + } + + for(int j = 0; j < 4; j++) { + assembler.inputTanks[j].renderTank(guiLeft + 105 + (j % 2) * 109, guiTop + 52 + (j / 2) * 56, this.zLevel, 5, 32); + assembler.outputTanks[j].renderTank(guiLeft + 105 + (j % 2) * 109, guiTop + 70 + (j / 2) * 56, this.zLevel, 5, 16); + } + + assembler.water.renderTank(guiLeft + 232, guiTop + 201, this.zLevel, 7, 52); + assembler.lps.renderTank(guiLeft + 241, guiTop + 201, this.zLevel, 7, 52); + } +} diff --git a/src/main/java/com/hbm/inventory/gui/GUIMachineChemicalFactory.java b/src/main/java/com/hbm/inventory/gui/GUIMachineChemicalFactory.java index 567b2e256..c153a949f 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIMachineChemicalFactory.java +++ b/src/main/java/com/hbm/inventory/gui/GUIMachineChemicalFactory.java @@ -8,6 +8,7 @@ import com.hbm.inventory.recipes.loader.GenericRecipe; import com.hbm.items.machine.ItemBlueprints; import com.hbm.lib.RefStrings; import com.hbm.tileentity.machine.TileEntityMachineChemicalFactory; +import com.hbm.util.i18n.I18nUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; @@ -49,7 +50,7 @@ public class GUIMachineChemicalFactory extends GuiInfoContainer { GenericRecipe recipe = (GenericRecipe) ChemicalPlantRecipes.INSTANCE.recipeNameMap.get(this.chemplant.chemplantModule[i].recipe); this.func_146283_a(recipe.print(), mouseX, mouseY); } else { - this.drawCreativeTabHoveringText(EnumChatFormatting.YELLOW + "Click to set recipe", mouseX, mouseY); + this.drawCreativeTabHoveringText(EnumChatFormatting.YELLOW + I18nUtil.resolveKey("gui.recipe.setRecipe"), mouseX, mouseY); } } } diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 6a2a2a439..1dfd9d2ff 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -271,6 +271,7 @@ public class ClientProxy extends ServerProxy { ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineAssembler.class, new RenderAssembler()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineAssemblyMachine.class, new RenderAssemblyMachine()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineAssemfac.class, new RenderAssemfac()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineAssemblyFactory.class, new RenderAssemblyFactory()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemplant.class, new RenderChemplant()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemicalPlant.class, new RenderChemicalPlant()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemfac.class, new RenderChemfac()); diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 8f51419f4..4eb451c2b 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -142,6 +142,7 @@ public class ResourceManager { 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")).asVBO(); public static final IModelCustom assemfac = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/assemfac.obj")).asVBO(); + public static final IModelCustom assembly_factory = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/assembly_factory.obj")).asVBO(); //Chemplant public static final IModelCustom chemplant_body = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/chemplant_new_body.obj")).asVBO(); @@ -578,6 +579,7 @@ public class ResourceManager { 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"); + public static final ResourceLocation assembly_factory_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/assembly_factory.png"); //Chemplant public static final ResourceLocation chemplant_body_tex = new ResourceLocation(RefStrings.MODID, "textures/models/chemplant_base_new.png"); diff --git a/src/main/java/com/hbm/render/tileentity/RenderAssemblyFactory.java b/src/main/java/com/hbm/render/tileentity/RenderAssemblyFactory.java new file mode 100644 index 000000000..8c6b0d750 --- /dev/null +++ b/src/main/java/com/hbm/render/tileentity/RenderAssemblyFactory.java @@ -0,0 +1,61 @@ +package com.hbm.render.tileentity; + +import org.lwjgl.opengl.GL11; + +import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ModBlocks; +import com.hbm.main.ResourceManager; +import com.hbm.render.item.ItemRenderBase; + +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.client.IItemRenderer; + +public class RenderAssemblyFactory extends TileEntitySpecialRenderer implements IItemRendererProvider { + + @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; + } + + bindTexture(ResourceManager.assembly_factory_tex); + ResourceManager.assembly_factory.renderAll(); + + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glPopMatrix(); + } + + @Override + public Item getItemForRenderer() { + return Item.getItemFromBlock(ModBlocks.machine_assembly_factory); + } + + @Override + public IItemRenderer getRenderer() { + + return new ItemRenderBase() { + + public void renderInventory() { + GL11.glTranslated(0, -1.5, 0); + GL11.glScaled(3, 3, 3); + } + public void renderCommonWithStack(ItemStack item) { + GL11.glScaled(0.75, 0.75, 0.75); + GL11.glShadeModel(GL11.GL_SMOOTH); + bindTexture(ResourceManager.assembly_factory_tex); + ResourceManager.assembly_factory.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 250305afe..500069e74 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -352,6 +352,7 @@ public class TileMappings { put(TileEntityMachineAssembler.class, "tileentity_assembly_machine"); put(TileEntityMachineAssemblyMachine.class, "tileentity_assemblymachine"); put(TileEntityMachineAssemfac.class, "tileentity_assemfac"); + put(TileEntityMachineAssemblyFactory.class, "tileentity_assemblyfactory"); put(TileEntityMachineChemplant.class, "tileentity_chemical_plant"); put(TileEntityMachineChemicalPlant.class, "tileentity_chemicalplant"); put(TileEntityMachineChemfac.class, "tileentity_chemfac"); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyFactory.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyFactory.java new file mode 100644 index 000000000..e16572586 --- /dev/null +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemblyFactory.java @@ -0,0 +1,407 @@ +package com.hbm.tileentity.machine; + +import java.util.HashMap; +import java.util.List; + +import com.hbm.blocks.ModBlocks; +import com.hbm.interfaces.IControlReceiver; +import com.hbm.interfaces.NotableComments; +import com.hbm.inventory.UpgradeManagerNT; +import com.hbm.inventory.container.ContainerMachineAssemblyFactory; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.inventory.gui.GUIMachineAssemblyFactory; +import com.hbm.inventory.recipes.AssemblyMachineRecipes; +import com.hbm.inventory.recipes.loader.GenericRecipe; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemMachineUpgrade; +import com.hbm.items.machine.ItemMachineUpgrade.UpgradeType; +import com.hbm.lib.Library; +import com.hbm.main.MainRegistry; +import com.hbm.module.machine.ModuleMachineAssembler; +import com.hbm.sound.AudioWrapper; +import com.hbm.tileentity.IGUIProvider; +import com.hbm.tileentity.IUpgradeInfoProvider; +import com.hbm.tileentity.TileEntityMachineBase; +import com.hbm.tileentity.TileEntityProxyDyn.IProxyDelegateProvider; +import com.hbm.util.BobMathUtil; +import com.hbm.util.fauxpointtwelve.DirPos; +import com.hbm.util.i18n.I18nUtil; + +import api.hbm.energymk2.IEnergyReceiverMK2; +import api.hbm.fluidmk2.IFluidStandardTransceiverMK2; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +// TODO: make a base class because 90% of this is just copy pasted from the chemfac +@NotableComments +public class TileEntityMachineAssemblyFactory extends TileEntityMachineBase implements IEnergyReceiverMK2, IFluidStandardTransceiverMK2, IUpgradeInfoProvider, IControlReceiver, IGUIProvider, IProxyDelegateProvider { + + public FluidTank[] allTanks; + public FluidTank[] inputTanks; + public FluidTank[] outputTanks; + + public FluidTank water; + public FluidTank lps; + + public long power; + public long maxPower = 1_000_000; + public boolean[] didProcess = new boolean[4]; + + public boolean frame = false; + private AudioWrapper audio; + + public ModuleMachineAssembler[] assemblerModule; + public UpgradeManagerNT upgradeManager = new UpgradeManagerNT(this); + + protected DelegateAssemblyFactoy delegate = new DelegateAssemblyFactoy(); + + public TileEntityMachineAssemblyFactory() { + super(60); + + this.inputTanks = new FluidTank[4]; + this.outputTanks = new FluidTank[4]; + for(int i = 0; i < 4; i++) { + this.inputTanks[i] = new FluidTank(Fluids.NONE, 4_000); + this.outputTanks[i] = new FluidTank(Fluids.NONE, 4_000); + } + + this.water = new FluidTank(Fluids.WATER, 4_000); + this.lps = new FluidTank(Fluids.SPENTSTEAM, 4_000); + + this.allTanks = new FluidTank[this.inputTanks.length + this.outputTanks.length + 2]; + for(int i = 0; i < inputTanks.length; i++) this.allTanks[i] = this.inputTanks[i]; + for(int i = 0; i < outputTanks.length; i++) this.allTanks[i + this.inputTanks.length] = this.outputTanks[i]; + + this.allTanks[this.allTanks.length - 2] = this.water; + this.allTanks[this.allTanks.length - 1] = this.lps; + + this.assemblerModule = new ModuleMachineAssembler[4]; + for(int i = 0; i < 4; i++) this.assemblerModule[i] = new ModuleMachineAssembler(i, this, slots) + .itemInput(5 + i * 14).itemOutput(17 + i * 14) + .fluidInput(inputTanks[i]).fluidOutput(outputTanks[i]); + } + + @Override + public boolean canExtractItem(int i, ItemStack itemStack, int j) { + for(int k = 0; k < 4; k++) if(i == 17 + k * 14) return true; + for(int k = 0; k < 4; k++) if(this.assemblerModule[k].isSlotClogged(i)) return true; + return false; + } + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + if(slot == 0) return true; // battery + for(int i = 0; i < 4; i++) if(slot == 4 + i * 14 && stack.getItem() == ModItems.blueprints) return true; + if(slot >= 1 && slot <= 3 && stack.getItem() instanceof ItemMachineUpgrade) return true; // upgrades + for(int i = 0; i < 4; i++) if(this.assemblerModule[i].isItemValid(slot, stack)) return true; // recipe input crap + return false; + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return new int[] { + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 + }; // ho boy, a big fucking array of hand-written values, surely this isn't gonna bite me in the ass some day + } + + @Override + public String getName() { + return "container.machineAssemblyFactory"; + } + + @Override + public void updateEntity() { + + if(maxPower <= 0) this.maxPower = 10_000_000; + + if(!worldObj.isRemote) { + + long nextMaxPower = 0; + for(int i = 0; i < 4; i++) { + GenericRecipe recipe = AssemblyMachineRecipes.INSTANCE.recipeNameMap.get(assemblerModule[i].recipe); + if(recipe != null) { + nextMaxPower += recipe.power * 100; + } + } + this.maxPower = nextMaxPower; + this.maxPower = BobMathUtil.max(this.power, this.maxPower, 1_000_000); + + this.power = Library.chargeTEFromItems(slots, 0, power, maxPower); + upgradeManager.checkSlots(slots, 1, 3); + + for(DirPos pos : getConPos()) { + this.trySubscribe(worldObj, pos); + for(FluidTank tank : inputTanks) if(tank.getTankType() != Fluids.NONE) this.trySubscribe(tank.getTankType(), worldObj, pos); + for(FluidTank tank : outputTanks) if(tank.getFill() > 0) this.tryProvide(tank, worldObj, pos); + } + + for(DirPos pos : getCoolPos()) { + delegate.trySubscribe(worldObj, pos); + delegate.trySubscribe(water.getTankType(), worldObj, pos); + delegate.tryProvide(lps, worldObj, pos); + } + + double speed = 1D; + double pow = 1D; + + speed += Math.min(upgradeManager.getLevel(UpgradeType.SPEED), 3) / 3D; + speed += Math.min(upgradeManager.getLevel(UpgradeType.OVERDRIVE), 3); + + pow -= Math.min(upgradeManager.getLevel(UpgradeType.POWER), 3) * 0.25D; + pow += Math.min(upgradeManager.getLevel(UpgradeType.SPEED), 3) * 1D; + pow += Math.min(upgradeManager.getLevel(UpgradeType.OVERDRIVE), 3) * 10D / 3D; + boolean markDirty = false; + + for(int i = 0; i < 4; i++) { + this.assemblerModule[i].update(speed * 2D, pow * 2D, canCool(), slots[4 + i * 7]); + this.didProcess[i] = this.assemblerModule[i].didProcess; + markDirty |= this.assemblerModule[i].markDirty; + + if(this.assemblerModule[i].didProcess) { + this.water.setFill(this.water.getFill() - 100); + this.lps.setFill(this.lps.getFill() + 100); + } + } + + if(markDirty) this.markDirty(); + + this.networkPackNT(100); + } else { + + } + } + + @Override public AudioWrapper createAudioLoop() { + return MainRegistry.proxy.getLoopedSound("hbm:block.motor", xCoord, yCoord, zCoord, 0.5F, 15F, 0.75F, 20); + } + + @Override public void onChunkUnload() { + if(audio != null) { audio.stopSound(); audio = null; } + } + + @Override public void invalidate() { + super.invalidate(); + if(audio != null) { audio.stopSound(); audio = null; } + } + + public boolean canCool() { + return water.getFill() >= 100 && lps.getFill() <= lps.getMaxFill() - 100; + } + + public DirPos[] getConPos() { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + return new DirPos[] { + new DirPos(xCoord + 3, yCoord, zCoord - 2, Library.POS_X), + new DirPos(xCoord + 3, yCoord, zCoord + 0, Library.POS_X), + new DirPos(xCoord + 3, yCoord, zCoord + 2, Library.POS_X), + new DirPos(xCoord - 3, yCoord, zCoord - 2, Library.NEG_X), + new DirPos(xCoord - 3, yCoord, zCoord + 0, Library.NEG_X), + new DirPos(xCoord - 3, yCoord, zCoord + 2, Library.NEG_X), + new DirPos(xCoord - 2, yCoord, zCoord + 3, Library.POS_Z), + new DirPos(xCoord + 0, yCoord, zCoord + 3, Library.POS_Z), + new DirPos(xCoord + 2, yCoord, zCoord + 3, Library.POS_Z), + new DirPos(xCoord - 2, yCoord, zCoord - 3, Library.NEG_Z), + new DirPos(xCoord + 0, yCoord, zCoord - 3, Library.NEG_Z), + new DirPos(xCoord + 2, yCoord, zCoord - 3, Library.NEG_Z), + + new DirPos(xCoord + dir.offsetX * 2 + rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 2 + rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord + dir.offsetX * 1 + rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 1 + rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord + dir.offsetX * 0 + rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 0 + rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord - dir.offsetX * 1 + rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 1 + rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord - dir.offsetX * 2 + rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 2 + rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord + dir.offsetX * 2 - rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 2 - rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord + dir.offsetX * 1 - rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 1 - rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord + dir.offsetX * 0 - rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 0 - rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord - dir.offsetX * 1 - rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 1 - rot.offsetZ * 2, Library.POS_Y), + new DirPos(xCoord - dir.offsetX * 2 - rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 2 - rot.offsetZ * 2, Library.POS_Y), + + new DirPos(xCoord + dir.offsetX + rot.offsetX * 3, yCoord, zCoord + dir.offsetZ + rot.offsetZ * 3, rot), + new DirPos(xCoord - dir.offsetX + rot.offsetX * 3, yCoord, zCoord - dir.offsetZ + rot.offsetZ * 3, rot), + new DirPos(xCoord + dir.offsetX - rot.offsetX * 3, yCoord, zCoord + dir.offsetZ - rot.offsetZ * 3, rot.getOpposite()), + new DirPos(xCoord - dir.offsetX - rot.offsetX * 3, yCoord, zCoord - dir.offsetZ - rot.offsetZ * 3, rot.getOpposite()), + }; + } + + + public DirPos[] getCoolPos() { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + return new DirPos[] { + new DirPos(xCoord + rot.offsetX + dir.offsetX * 3, yCoord, zCoord + rot.offsetZ + dir.offsetZ * 3, dir), + new DirPos(xCoord - rot.offsetX + dir.offsetX * 3, yCoord, zCoord - rot.offsetZ + dir.offsetZ * 3, dir), + new DirPos(xCoord + rot.offsetX - dir.offsetX * 3, yCoord, zCoord + rot.offsetZ - dir.offsetZ * 3, dir.getOpposite()), + new DirPos(xCoord - rot.offsetX - dir.offsetX * 3, yCoord, zCoord - rot.offsetZ - dir.offsetZ * 3, dir.getOpposite()), + }; + } + + @Override + public void serialize(ByteBuf buf) { + super.serialize(buf); + for(FluidTank tank : inputTanks) tank.serialize(buf); + for(FluidTank tank : outputTanks) tank.serialize(buf); + water.serialize(buf); + lps.serialize(buf); + buf.writeLong(power); + buf.writeLong(maxPower); + for(boolean b : didProcess) buf.writeBoolean(b); + for(int i = 0; i < 4; i++) this.assemblerModule[i].serialize(buf); + } + + @Override + public void deserialize(ByteBuf buf) { + super.deserialize(buf); + for(FluidTank tank : inputTanks) tank.deserialize(buf); + for(FluidTank tank : outputTanks) tank.deserialize(buf); + water.deserialize(buf); + lps.deserialize(buf); + this.power = buf.readLong(); + this.maxPower = buf.readLong(); + for(int i = 0; i < 4; i++) this.didProcess[i] = buf.readBoolean(); + for(int i = 0; i < 4; i++) this.assemblerModule[i].deserialize(buf); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + + for(int i = 0; i < inputTanks.length; i++) this.inputTanks[i].readFromNBT(nbt, "i" + i); + for(int i = 0; i < outputTanks.length; i++) this.outputTanks[i].readFromNBT(nbt, "i" + i); + + this.water.readFromNBT(nbt, "w"); + this.lps.readFromNBT(nbt, "s"); + + this.power = nbt.getLong("power"); + this.maxPower = nbt.getLong("maxPower"); + for(int i = 0; i < 4; i++) this.assemblerModule[i].readFromNBT(nbt); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + + for(int i = 0; i < inputTanks.length; i++) this.inputTanks[i].writeToNBT(nbt, "i" + i); + for(int i = 0; i < outputTanks.length; i++) this.outputTanks[i].writeToNBT(nbt, "i" + i); + + this.water.writeToNBT(nbt, "w"); + this.lps.writeToNBT(nbt, "s"); + + nbt.setLong("power", power); + nbt.setLong("maxPower", maxPower); + for(int i = 0; i < 4; i++) this.assemblerModule[i].writeToNBT(nbt); + } + + @Override public long getPower() { return power; } + @Override public void setPower(long power) { this.power = power; } + @Override public long getMaxPower() { return maxPower; } + + @Override public FluidTank[] getReceivingTanks() { return inputTanks; } + @Override public FluidTank[] getSendingTanks() { return outputTanks; } + @Override public FluidTank[] getAllTanks() { return allTanks; } + + @Override public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { return new ContainerMachineAssemblyFactory(player.inventory, this); } + @Override @SideOnly(Side.CLIENT) public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { return new GUIMachineAssemblyFactory(player.inventory, this); } + + @Override public boolean hasPermission(EntityPlayer player) { return this.isUseableByPlayer(player); } + + @Override + public void receiveControl(NBTTagCompound data) { + if(data.hasKey("index") && data.hasKey("selection")) { + int index = data.getInteger("index"); + String selection = data.getString("selection"); + if(index >= 0 && index < 4) { + this.assemblerModule[index].recipe = selection; + this.markChanged(); + } + } + } + + AxisAlignedBB bb = null; + + @Override + public AxisAlignedBB getRenderBoundingBox() { + if(bb == null) bb = AxisAlignedBB.getBoundingBox(xCoord - 2, yCoord, zCoord - 2, xCoord + 3, yCoord + 3, zCoord + 3); + return bb; + } + + @Override + @SideOnly(Side.CLIENT) + public double getMaxRenderDistanceSquared() { + return 65536.0D; + } + + @Override + public boolean canProvideInfo(UpgradeType type, int level, boolean extendedInfo) { + return type == UpgradeType.SPEED || type == UpgradeType.POWER || type == UpgradeType.OVERDRIVE; + } + + @Override + public void provideInfo(UpgradeType type, int level, List info, boolean extendedInfo) { + info.add(IUpgradeInfoProvider.getStandardLabel(ModBlocks.machine_chemical_factory)); + if(type == UpgradeType.SPEED) { + info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_SPEED, "+" + (level * 100 / 3) + "%")); + info.add(EnumChatFormatting.RED + I18nUtil.resolveKey(KEY_CONSUMPTION, "+" + (level * 50) + "%")); + } + if(type == UpgradeType.POWER) { + info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_CONSUMPTION, "-" + (level * 25) + "%")); + } + if(type == UpgradeType.OVERDRIVE) { + info.add((BobMathUtil.getBlink() ? EnumChatFormatting.RED : EnumChatFormatting.DARK_GRAY) + "YES"); + } + } + + @Override + public HashMap getValidUpgrades() { + HashMap upgrades = new HashMap<>(); + upgrades.put(UpgradeType.SPEED, 3); + upgrades.put(UpgradeType.POWER, 3); + upgrades.put(UpgradeType.OVERDRIVE, 3); + return upgrades; + } + + public DirPos[] coolantLine; + + @Override // carelessly copy pasted from TileEntityMachineChemicalFactory + public Object getDelegateForPosition(int x, int y, int z) { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + if(coolantLine == null) coolantLine = new DirPos[] { + new DirPos(xCoord + rot.offsetX + dir.offsetX * 2, yCoord, zCoord + rot.offsetZ + dir.offsetZ * 2, dir), + new DirPos(xCoord - rot.offsetX + dir.offsetX * 2, yCoord, zCoord - rot.offsetZ + dir.offsetZ * 2, dir), + new DirPos(xCoord + rot.offsetX - dir.offsetX * 2, yCoord, zCoord + rot.offsetZ - dir.offsetZ * 2, dir.getOpposite()), + new DirPos(xCoord - rot.offsetX - dir.offsetX * 2, yCoord, zCoord - rot.offsetZ - dir.offsetZ * 2, dir.getOpposite()), + }; + + for(DirPos pos : coolantLine) if(pos.compare(x, y, z)) return this.delegate; // this actually fucking works + + return null; + } + + public class DelegateAssemblyFactoy implements IEnergyReceiverMK2, IFluidStandardTransceiverMK2 { // scumware + + @Override public long getPower() { return TileEntityMachineAssemblyFactory.this.getPower(); } + @Override public void setPower(long power) { TileEntityMachineAssemblyFactory.this.setPower(power); } + @Override public long getMaxPower() { return TileEntityMachineAssemblyFactory.this.getMaxPower(); } + @Override public boolean isLoaded() { return TileEntityMachineAssemblyFactory.this.isLoaded(); } + + @Override public FluidTank[] getReceivingTanks() { return new FluidTank[] {TileEntityMachineAssemblyFactory.this.water}; } + @Override public FluidTank[] getSendingTanks() { return new FluidTank[] {TileEntityMachineAssemblyFactory.this.lps}; } + + @Override public FluidTank[] getAllTanks() { return TileEntityMachineAssemblyFactory.this.getAllTanks(); } + } +} diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemfac.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemfac.java index 61e8d0a92..034b98163 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemfac.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAssemfac.java @@ -31,6 +31,7 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; +@Deprecated public class TileEntityMachineAssemfac extends TileEntityMachineAssemblerBase implements IFluidStandardTransceiver, IUpgradeInfoProvider, IFluidCopiable { public AssemblerArm[] arms; diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineChemicalFactory.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineChemicalFactory.java index 09141b42b..32c2adf2e 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineChemicalFactory.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineChemicalFactory.java @@ -145,14 +145,6 @@ public class TileEntityMachineChemicalFactory extends TileEntityMachineBase impl this.power = Library.chargeTEFromItems(slots, 0, power, maxPower); upgradeManager.checkSlots(slots, 1, 3); - - inputTanks[0].loadTank(10, 13, slots); - inputTanks[1].loadTank(11, 14, slots); - inputTanks[2].loadTank(12, 15, slots); - - outputTanks[0].unloadTank(16, 19, slots); - outputTanks[1].unloadTank(17, 20, slots); - outputTanks[2].unloadTank(18, 21, slots); for(DirPos pos : getConPos()) { this.trySubscribe(worldObj, pos); @@ -188,6 +180,7 @@ public class TileEntityMachineChemicalFactory extends TileEntityMachineBase impl } } + // internal fluid sharing logic for(FluidTank in : inputTanks) if(in.getTankType() != Fluids.NONE) for(FluidTank out : outputTanks) { // up to 144 iterations, but most of them are NOP anyway if(out.getTankType() == Fluids.NONE) continue; if(out.getTankType() != in.getTankType()) continue; diff --git a/src/main/java/com/hbm/tileentity/machine/albion/TileEntityPADetector.java b/src/main/java/com/hbm/tileentity/machine/albion/TileEntityPADetector.java index e5bb48c88..bf796c407 100644 --- a/src/main/java/com/hbm/tileentity/machine/albion/TileEntityPADetector.java +++ b/src/main/java/com/hbm/tileentity/machine/albion/TileEntityPADetector.java @@ -1,10 +1,14 @@ package com.hbm.tileentity.machine.albion; +import java.util.List; + import com.hbm.inventory.container.ContainerPADetector; import com.hbm.inventory.gui.GUIPADetector; import com.hbm.inventory.recipes.ParticleAcceleratorRecipes; import com.hbm.inventory.recipes.ParticleAcceleratorRecipes.ParticleAcceleratorRecipe; +import com.hbm.items.ModItems; import com.hbm.lib.Library; +import com.hbm.main.MainRegistry; import com.hbm.tileentity.IGUIProvider; import com.hbm.tileentity.machine.albion.TileEntityPASource.PAState; import com.hbm.tileentity.machine.albion.TileEntityPASource.Particle; @@ -142,6 +146,12 @@ public class TileEntityPADetector extends TileEntityCooledBase implements IGUIPr } } } + + if((recipe.output1 != null && recipe.output1.getItem() == ModItems.particle_digamma) || (recipe.output2 != null && recipe.output2.getItem() == ModItems.particle_digamma)) { + List players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5).expand(100, 50, 100)); + for(EntityPlayer player : players) player.triggerAchievement(MainRegistry.achOmega12); + } + particle.crash(PAState.SUCCESS); return; } diff --git a/src/main/java/com/hbm/util/AchievementHandler.java b/src/main/java/com/hbm/util/AchievementHandler.java index 8ffbb48e8..8c36ef859 100644 --- a/src/main/java/com/hbm/util/AchievementHandler.java +++ b/src/main/java/com/hbm/util/AchievementHandler.java @@ -49,6 +49,7 @@ public class AchievementHandler { craftingAchievements.put(new ComparableStack(ModBlocks.machine_difurnace_off), MainRegistry.achBlastFurnace); craftingAchievements.put(new ComparableStack(ModBlocks.machine_assembly_machine), MainRegistry.achAssembly); craftingAchievements.put(new ComparableStack(ModItems.billet_pu_mix), MainRegistry.achChicagoPile); + craftingAchievements.put(new ComparableStack(ModItems.particle_digamma), MainRegistry.achOmega12); } public static void fire(EntityPlayer player, ItemStack stack) { diff --git a/src/main/resources/assets/hbm/textures/gui/processing/gui_assembly_factory.png b/src/main/resources/assets/hbm/textures/gui/processing/gui_assembly_factory.png new file mode 100644 index 0000000000000000000000000000000000000000..73a306fdb3039b2a7186a7ebbcc787ec6f13dc1d GIT binary patch literal 4662 zcmc&&XH*nhm%U8}$vi}nr0{5MkYocA8d@ZXl2oGP90WyTlN$p;qBJ=x0!oG!1f-!6 z1c3%Yo3=%&2vreA+HQDMH^Ifs-hA)~sr9p*)`MiZ+b4z7k zmboaiyTIvY+h5NosnuD@&9E8m^WxQJt748Pq@IVh6D;n%yeYD;S7jBN(uRkvb;l#9 z&>8;J?XKBzgiYDL<>gaR<+K8Bm=nqu%jyFD>obwngD83VdyT8oQ!})gyDR;c&r2Nr zi{VWXpD~ISjjKBQlb>djzH!n18X4ZZC3p2|e1{#oW{a*BC`md}`vC)p%&aD_^?D>Ao=(*%tTGl&R?g6&`w9SqmN0Jil_G8){^8`p zg`?n**{8C+?7aZ+F+4_xwM=!|uF+dMC}C-Up1^%x^o!u8CZB}D0BYe{2H^Ul%7_wL zoS}jlpf6uztzc*Ub(>=ebdJ*sB=mvhaf10lOfHHm#i*5Z#s0%V$GPC5PE)S=;7g`cMToQ-_H~A{TuhhBlfqqS3gH_S#_%&<_!ktNGZvxLslu6jd z_!x9wT;Ry8t=8}q&%Hy5u5lNX%NE6HS4}7J6n@MulDvOwfd-44$f{2hQksgi4nR7F zuo+VL7j|M2w0;g4cEjS;z87WOjxaqy?oj-IVP3Cdr2N+VMV#6Px?#jD`Lw6F38wC0 z%cnF%1%ozR=HUakZ#-y!#twh1kF*>unl$pVjtk8~6dY;C85g1)lFBJ^gAA_FOL}T} zZgWYxf?BWF;R~3A)P<=n9x!~J3m2_I^6LA3%8L14F-XAIm#G=A9YAsdig|vDk*?{s z>XegbSI$x|A={&A{%ww;?_oou9|Xy?AKV(b>@IT9+7vv|ee~H4>?_w_a>OeSA_C>J zI-QV324Qgy__V--orf+d`1igV77e>no&n_qf&%;ZhRXFblEpm+Br_2n3X%i<-ZSyj zr}CseN|*&JpJ9y7Id|$YdjBYRmaH9V31_^%*Ae$*#MCo}f4MC1`9lx&J%X-MVpLag z^~8CHS*M7!TZ3kem@{GQVK1q!RUAsuZ+Gnl&WdDJ%J3>HD!yAUUm@*{wew$YGW*-z zgbj|vK6*y~*lNYt>?H%f^Gno~o;EU{r*xhcsfdgqvV2XmsWjFv)(g2|pGo^?TtLZ+ zmI`UHKmADUo(rg|YKN@HrZp-@YR~bX3doHvo(5+n@2k%nQM8diy%V5A7`zdnoAC|b zBg^2(7q;6HWvY`jBTPJh@3Zz(p;{t;xnDKw(b_pU`e?FP-(KyB$`*2%t&25bn-_s; zBmNlgjlUgXBFAl$-0nvyaHmXVxIx&=XnmxbDZLHXN{TK>wZGj5B1#M|;^tkD+%Y9S z2G#cLHZ^HAsre?BbjUM|@^$b2N`9|&5GY-2j3%XjQzsR<hW}(;oX_ixRBf4Px+8iso|D0+iyjEh?YnmC7> z*vutA{6O*0j5dBS-AzS}bo#_R0Uokmxw(;`RSxI4ff1&M3 zLhJyow&FJhPV5yr>M!5Vh0R%D)3vXCK#XAu#F>Ph`E_lwwo|30Xo*5r8&&?m;EJZa z%qG=Hp4>r{{t)L?r73IO+qOl1;U;$dJb3jv(98D^f0TSR0H-O2+j)pSy?pqaD4>Ip zP45(HEk~u}n(u5(q)Ymf4*r&BWch%D=m|k1*V z!@~`atFz>q4tDcqQ$$)zGKFnwj74X5cWVa*z2v(^M>~Y9%&Z>^7%QAMdh@YlePcQr zzgF9B)_su!znC5|TwpOE+%hGBcN}z~jPLm)>eH)x&-Sk)$ch*JzT3JvhS(V9q!_`{ z6O&Mn zVQglnp`SoC+TAsGzt;(lC z`?spYW_Ij0hH-Pt;?q{_62&SnP^3CzsI4zbMh@FaEgb!FvpeA>OwAzBW-k+zGZ-G{ z_H*c$NijejO`WuU`Vd*e?k=CjZ8?1@!B@Mgr+SJ^CU-WCCKvcTyL6XXvbbH1WTRb1 zc~S5m8q~jLJlJZVH95yb_J}YEa%(Rst6u^G+}Nlt5kDV)i(c;sq|1uK%NNm6z z9}{vqo0~%!e}+t!u(@CB?nYzX)*_YDv}Pubr5lA$_Fv~@1@*bm=rkFcE`hH`Og^fw zWgAYeZH^W;dDZZ+Io-`%=!YLIt(|1pLNJT z=&kXAjGf!#CK&+_>UoD|T1;ev_8%?buxPGN@Lfm*q#;QGireDl4@b@ST@;gZP$6O$ zF32*o%BRBZ!XZfuxaZn8Dsg8B~;GU)PukG!R5MQjBK}Bv4e7hAD+7Kqd zH^F7^i<^&dKg(JnHg?8!-;V>gMp)nh*FmoJBbsuXt32FCt5Pk4fy~gus25C*w8{H+ z;zT?4U&U(}TOV1!*o`i193QI4yzTh7F*7q$k9k&KY<|plqSRc+lsk*ESAxE_smXF_ zhhI5Z6b^?cUYASia$b*Zl;{8P;ys^0q#QukHCyTJ-NbhAsND4ggEQZ}-)>RodUuyn zTCuY_>8Ei9Ip>!Fq!cY$me0w|U)0j!YQ@_rCl6-yCn14~m@0pY4#u3F+Q@=c>Rei2 zoG4w)pR?;1m*Mn)7oY&KsKMl@NQ5SXz=hRB6N_fXf){v0tN13KdIPNEv^Q)aI%j8B zxO?mrkrhm zvNS<3o^A<%>RPVcr$IL=u zdH8dNI=qjCzjWX^)K=l^$Q8!xa$}+zOR;FbolSWA4rFPmnZ#0$2Z~{r&I7DREf>%u zm4EqN9Yw1HD&6R;dM|C=H=9Spz62o<9;t(~tOsz07=&+>gvqponzso2PIZJsajxZxTBI zq3SwD0O|iYxfnuQdk&G|ZG?Wx&jSm&Ov%50z2UwKM z-*aBT;fFOh@TFpSY-Rg}I3uS9p?vvs*Q%OH)5On*%bcl-g>=x~Y=OR6dDU6KkBY1a zO?2*+uRE7|DM8T!FE6hed98M!Te-{}XEc~Uz}0I`n5U8b?u5+wqNeH(mAb7%Q&xw2WW2*~Uw?<*r)nBNqrV1VZ z2u$GPhtmzTfXF)su*~HC&`@SiB`VD3kJ~F!(__|`!aa(T$^B(S?K_q1di|>viT&Lk z_40Bne}@ReLYebuf!7%nl>ZP1>ko-Ah{znqAmOXc6ao}?;4AJX5vtV z=lEPkd6OZyb&RUL*YP3}4PTSYLl;gcdDSU_*O1O8zpSCsnHjE=;}a3xt1E5~cW6Je z`<{HT(s)p&^ebn*I4MVWwqMwyaByks)yBq#&e0>-ivQ&u@aoBvCp1x%%fs9BXto!; zdlTO{j`>dIo9j)!UchqFvwmQTwd_9P{;bpE0^@bl4HQ9K<3k2rFDHs#lRLfMX9{&f`=Gz7U literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/models/machines/assembly_factory.png b/src/main/resources/assets/hbm/textures/models/machines/assembly_factory.png index b98f8d14af08a10852b1d035ab44b0bf18b82637..908603da4f24926c33802da5dc5e7934b3206de7 100644 GIT binary patch delta 4910 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 a4|#17LiP&fdo^5~V|d*RReII=?*9Nv)ieqK