From 71b40de7a713a2e0b63b50ed9e3bcad2647596e8 Mon Sep 17 00:00:00 2001 From: Boblet Date: Thu, 20 Nov 2025 15:59:34 +0100 Subject: [PATCH] the smooth taste of NEO, wake up and taste the PAIN --- changelog | 3 + .../machine/fusion/MachineFusionBoiler.java | 53 +++++- .../machine/fusion/MachineFusionBreeder.java | 11 +- .../fusion/MachineFusionCollector.java | 12 +- .../machine/fusion/MachineFusionKlystron.java | 11 +- .../machine/fusion/MachineFusionMHDT.java | 53 +++++- .../machine/fusion/MachineFusionTorus.java | 11 +- .../hbm/handler/nei/ConstructionHandler.java | 51 ++++-- .../hbm/handler/nei/FusionBreederHandler.java | 16 ++ .../hbm/handler/nei/NEIUniversalHandler.java | 16 +- .../com/hbm/handler/nei/OutgasserHandler.java | 4 +- .../recipes/FluidBreederRecipes.java | 72 ++++++++ .../recipes/loader/SerializableRecipe.java | 1 + src/main/java/com/hbm/main/NEIRegistry.java | 1 + .../render/tileentity/RenderFusionMHDT.java | 7 +- .../fusion/TileEntityFusionBoiler.java | 139 ++++++++++++++- .../fusion/TileEntityFusionBreeder.java | 36 +++- .../fusion/TileEntityFusionKlystron.java | 1 + .../machine/fusion/TileEntityFusionMHDT.java | 163 +++++++++++++++++- src/main/java/com/hbm/util/BobMathUtil.java | 3 + src/main/java/com/hbm/util/ItemStackUtil.java | 16 ++ src/main/resources/assets/hbm/lang/de_DE.lang | 15 ++ src/main/resources/assets/hbm/lang/en_US.lang | 16 +- .../hbm/textures/models/fusion/boiler.png | Bin 6699 -> 6806 bytes .../hbm/textures/models/fusion/mhdt.png | Bin 9318 -> 16649 bytes 25 files changed, 681 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/hbm/handler/nei/FusionBreederHandler.java create mode 100644 src/main/java/com/hbm/inventory/recipes/FluidBreederRecipes.java diff --git a/changelog b/changelog index 3c93a2fc6..07f7d6f3a 100644 --- a/changelog +++ b/changelog @@ -50,6 +50,8 @@ * Re-solidifcation of bedrock ore crumbs now requires ore slop instead of nitric acid * Due to ore slop being only obtainable from processing raw bedrock ore, this places a hard cap on how many times a single ore can be re-solidified out of crumbs * This approach means that crumb yields don't have to be nerfed, and prevents that issue from popping up again should there ever be a new, more efficient processing path +* Rewrote the ore layer generator (hematite, bauxite) to be way more performant during worldgen +* The mining laser can now be stopped by applying a redstone signal to one of the ports ## Fixed * Fixed arc furnace only allowing electrodes to be inserted when the lid is down instead of up @@ -65,3 +67,4 @@ * Fixed bismuth armor not having a valid repair material * Fixed compressors needing at least one mB of fluid more to process a recipe than necessary * Fixed many NTM structure spawn conditions being hardcoded (again) preventing them from spawning in modded biomes that would otherwise be a fit +* Fixed spawn offset for some structures which caused them to float in the air diff --git a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBoiler.java b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBoiler.java index e3273ad79..7e61a254d 100644 --- a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBoiler.java +++ b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBoiler.java @@ -1,15 +1,27 @@ package com.hbm.blocks.machine.fusion; +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.inventory.fluid.tank.FluidTank; import com.hbm.tileentity.TileEntityProxyCombo; import com.hbm.tileentity.machine.fusion.TileEntityFusionBoiler; +import com.hbm.util.BobMathUtil; +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 MachineFusionBoiler extends BlockDummyable { +public class MachineFusionBoiler extends BlockDummyable implements ILookOverlay, ITooltipProvider { public MachineFusionBoiler() { super(Material.iron); @@ -18,7 +30,7 @@ public class MachineFusionBoiler extends BlockDummyable { @Override public TileEntity createNewTileEntity(World world, int meta) { if(meta >= 12) return new TileEntityFusionBoiler(); - if(meta >= 6) return new TileEntityProxyCombo().power().fluid(); + if(meta >= 6) return new TileEntityProxyCombo().fluid(); return null; } @@ -40,5 +52,42 @@ public class MachineFusionBoiler extends BlockDummyable { @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 * o; + z += dir.offsetZ * o; + + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + //this.makeExtra(world, x + dir.offsetX * 4, y + 2, z + dir.offsetZ * 4); + this.makeExtra(world, x - dir.offsetX * 1 + rot.offsetX, y, z - dir.offsetZ * 1 + rot.offsetZ); + this.makeExtra(world, x - dir.offsetX * 1 - rot.offsetX, y, z - dir.offsetZ * 1 - rot.offsetZ); + this.makeExtra(world, x + dir.offsetX * 2 + rot.offsetX, y, z + dir.offsetZ * 2 + rot.offsetZ); + this.makeExtra(world, x + dir.offsetX * 2 - rot.offsetX, y, z + dir.offsetZ * 2 - rot.offsetZ); + } + + @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 TileEntityFusionBoiler)) return; + TileEntityFusionBoiler boiler = (TileEntityFusionBoiler) te; + + List text = new ArrayList(); + text.add(EnumChatFormatting.GREEN + "-> " + EnumChatFormatting.RESET + BobMathUtil.format(boiler.plasmaEnergy) + " TU"); + + for(int i = 0; i < boiler.getAllTanks().length; i++) { + FluidTank tank = boiler.getAllTanks()[i]; + text.add((i == 0 ? (EnumChatFormatting.GREEN + "-> ") : (EnumChatFormatting.RED + "<- ")) + EnumChatFormatting.RESET + tank.getTankType().getLocalizedName() + ": " + tank.getFill() + "/" + tank.getMaxFill() + "mB"); + } + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + addStandardInfo(stack, player, list, ext); } } diff --git a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBreeder.java b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBreeder.java index ede4e3fe1..d86c1f6bd 100644 --- a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBreeder.java +++ b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionBreeder.java @@ -1,16 +1,20 @@ package com.hbm.blocks.machine.fusion; +import java.util.List; + import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ITooltipProvider; import com.hbm.tileentity.TileEntityProxyCombo; import com.hbm.tileentity.machine.fusion.TileEntityFusionBreeder; 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; import net.minecraftforge.common.util.ForgeDirection; -public class MachineFusionBreeder extends BlockDummyable { +public class MachineFusionBreeder extends BlockDummyable implements ITooltipProvider { public MachineFusionBreeder() { super(Material.iron); @@ -58,4 +62,9 @@ public class MachineFusionBreeder extends BlockDummyable { this.makeExtra(world, x + dir.offsetX - rot.offsetX, y, z + dir.offsetZ - rot.offsetZ); this.makeExtra(world, x + dir.offsetX * 2, y + 2, z + dir.offsetZ * 2); } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + addStandardInfo(stack, player, list, ext); + } } diff --git a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionCollector.java b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionCollector.java index 39383ceb4..2c7b92ebc 100644 --- a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionCollector.java +++ b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionCollector.java @@ -1,14 +1,19 @@ package com.hbm.blocks.machine.fusion; +import java.util.List; + import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ITooltipProvider; import com.hbm.tileentity.machine.fusion.TileEntityFusionCollector; 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; import net.minecraftforge.common.util.ForgeDirection; -public class MachineFusionCollector extends BlockDummyable { +public class MachineFusionCollector extends BlockDummyable implements ITooltipProvider { public MachineFusionCollector() { super(Material.iron); @@ -39,4 +44,9 @@ public class MachineFusionCollector extends BlockDummyable { public void fillSpace(World world, int x, int y, int z, ForgeDirection dir, int o) { super.fillSpace(world, x, y, z, dir, o); } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + addStandardInfo(stack, player, list, ext); + } } diff --git a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionKlystron.java b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionKlystron.java index b68a23f07..d95b48f53 100644 --- a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionKlystron.java +++ b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionKlystron.java @@ -1,17 +1,21 @@ package com.hbm.blocks.machine.fusion; +import java.util.List; + import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ITooltipProvider; import com.hbm.handler.MultiblockHandlerXR; import com.hbm.tileentity.TileEntityProxyCombo; import com.hbm.tileentity.machine.fusion.TileEntityFusionKlystron; 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; import net.minecraftforge.common.util.ForgeDirection; -public class MachineFusionKlystron extends BlockDummyable { +public class MachineFusionKlystron extends BlockDummyable implements ITooltipProvider { public MachineFusionKlystron() { super(Material.iron); @@ -60,4 +64,9 @@ public class MachineFusionKlystron extends BlockDummyable { this.makeExtra(world, x + rot.offsetX * 2, y, z + rot.offsetZ * 2); this.makeExtra(world, x - rot.offsetX * 2, y, z - rot.offsetZ * 2); } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + addStandardInfo(stack, player, list, ext); + } } diff --git a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionMHDT.java b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionMHDT.java index ebb77998a..208859bfb 100644 --- a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionMHDT.java +++ b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionMHDT.java @@ -1,16 +1,28 @@ package com.hbm.blocks.machine.fusion; +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.handler.MultiblockHandlerXR; +import com.hbm.inventory.fluid.tank.FluidTank; import com.hbm.tileentity.TileEntityProxyCombo; import com.hbm.tileentity.machine.fusion.TileEntityFusionMHDT; +import com.hbm.util.BobMathUtil; +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 MachineFusionMHDT extends BlockDummyable { +public class MachineFusionMHDT extends BlockDummyable implements ILookOverlay, ITooltipProvider { public MachineFusionMHDT() { super(Material.iron); @@ -52,5 +64,44 @@ public class MachineFusionMHDT extends BlockDummyable { MultiblockHandlerXR.fillSpace(world, x + dir.offsetX * o, y, z + dir.offsetZ * o, new int[] {3, -2, -3, 5, 2, 2}, this, dir); MultiblockHandlerXR.fillSpace(world, x + dir.offsetX * o, y, z + dir.offsetZ * o, new int[] {4, -3, -3, 5, 1, 1}, this, dir); MultiblockHandlerXR.fillSpace(world, x + dir.offsetX * (o + 3), y, z + dir.offsetZ * (o + 3), new int[] {1, 0, 0, 1, 3, 3}, this, dir); + + x += dir.offsetX * o; + z += dir.offsetZ * o; + + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + this.makeExtra(world, x + dir.offsetX * 4 + rot.offsetX * 3, y, z + dir.offsetZ * 4 + rot.offsetZ * 3); + this.makeExtra(world, x + dir.offsetX * 4 - rot.offsetX * 3, y, z + dir.offsetZ * 4 - rot.offsetZ * 3); + this.makeExtra(world, x + dir.offsetX * 7, y + 1, z + dir.offsetZ * 7); + } + + @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 TileEntityFusionMHDT)) return; + TileEntityFusionMHDT turbine = (TileEntityFusionMHDT) te; + + boolean isCool = turbine.isCool(); + + List text = new ArrayList(); + text.add(EnumChatFormatting.GREEN + "-> " + EnumChatFormatting.RESET + BobMathUtil.getShortNumber(turbine.plasmaEnergy) + " TU/t"); + text.add(EnumChatFormatting.RED + "<- " + EnumChatFormatting.RESET + BobMathUtil.getShortNumber(!isCool ? 0 : (long) Math.floor(turbine.plasmaEnergy * turbine.PLASMA_EFFICIENCY)) + "HE/t"); + + for(int i = 0; i < turbine.getAllTanks().length; i++) { + FluidTank tank = turbine.getAllTanks()[i]; + text.add((i == 0 ? (EnumChatFormatting.GREEN + "-> ") : (EnumChatFormatting.RED + "<- ")) + EnumChatFormatting.RESET + tank.getTankType().getLocalizedName() + ": " + tank.getFill() + "/" + tank.getMaxFill() + "mB"); + } + + if(!isCool) text.add("&[" + (BobMathUtil.getBlink() ? 0xff0000 : 0xffff00) + "&]! ! ! INSUFFICIENT COOLING ! ! !"); + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + addStandardInfo(stack, player, list, ext); } } diff --git a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionTorus.java b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionTorus.java index 988fbaa6d..26e111207 100644 --- a/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionTorus.java +++ b/src/main/java/com/hbm/blocks/machine/fusion/MachineFusionTorus.java @@ -1,16 +1,20 @@ package com.hbm.blocks.machine.fusion; +import java.util.List; + import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.ITooltipProvider; import com.hbm.tileentity.TileEntityProxyCombo; import com.hbm.tileentity.machine.fusion.TileEntityFusionTorus; 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; import net.minecraftforge.common.util.ForgeDirection; -public class MachineFusionTorus extends BlockDummyable { +public class MachineFusionTorus extends BlockDummyable implements ITooltipProvider { public static final int[][][] layout = new int[][][] { @@ -193,4 +197,9 @@ public class MachineFusionTorus extends BlockDummyable { this.makeExtra(world, x - 2, y, z - 6); this.makeExtra(world, x - 2, y + 4, z - 6); } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + addStandardInfo(stack, player, list, ext); + } } diff --git a/src/main/java/com/hbm/handler/nei/ConstructionHandler.java b/src/main/java/com/hbm/handler/nei/ConstructionHandler.java index 05105f579..30391fa2c 100644 --- a/src/main/java/com/hbm/handler/nei/ConstructionHandler.java +++ b/src/main/java/com/hbm/handler/nei/ConstructionHandler.java @@ -1,14 +1,16 @@ package com.hbm.handler.nei; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import com.hbm.blocks.ModBlocks; +import com.hbm.blocks.machine.fusion.MachineFusionTorus; import com.hbm.inventory.material.Mats; import com.hbm.items.ModItems; import com.hbm.util.ItemStackUtil; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; public class ConstructionHandler extends NEIUniversalHandler { @@ -54,9 +56,9 @@ public class ConstructionHandler extends NEIUniversalHandler { /* ITER */ ItemStack[] iter = new ItemStack[] { new ItemStack(ModBlocks.fusion_conductor, 36), - ItemStackUtil.addTooltipToStack(new ItemStack(ModBlocks.fusion_conductor, 256), EnumChatFormatting.RED + "4x64"), + ItemStackUtil.addStackSizeLabel(new ItemStack(ModBlocks.fusion_conductor, 256)), new ItemStack(ModItems.plate_cast, 36, Mats.MAT_STEEL.id), - ItemStackUtil.addTooltipToStack(new ItemStack(ModItems.plate_cast, 256, Mats.MAT_STEEL.id), EnumChatFormatting.RED + "4x64"), + ItemStackUtil.addStackSizeLabel(new ItemStack(ModItems.plate_cast, 256, Mats.MAT_STEEL.id)), new ItemStack(ModBlocks.fusion_center, 64), new ItemStack(ModBlocks.fusion_motor, 4), new ItemStack(ModBlocks.reinforced_glass, 8), @@ -92,11 +94,11 @@ public class ConstructionHandler extends NEIUniversalHandler { /* SOYUZ LAUNCHER */ ItemStack[] soysauce = new ItemStack[] { new ItemStack(ModBlocks.struct_launcher, 30), - ItemStackUtil.addTooltipToStack(new ItemStack(ModBlocks.struct_launcher, 384), EnumChatFormatting.RED + "6x64"), + ItemStackUtil.addStackSizeLabel(new ItemStack(ModBlocks.struct_launcher, 384)), new ItemStack(ModBlocks.struct_scaffold, 63), - ItemStackUtil.addTooltipToStack(new ItemStack(ModBlocks.struct_scaffold, 384), EnumChatFormatting.RED + "6x64"), + ItemStackUtil.addStackSizeLabel(new ItemStack(ModBlocks.struct_scaffold, 384)), new ItemStack(ModBlocks.concrete_smooth, 38), - ItemStackUtil.addTooltipToStack(new ItemStack(ModBlocks.concrete_smooth, 320), EnumChatFormatting.RED + "5x64"),}; + ItemStackUtil.addStackSizeLabel(new ItemStack(ModBlocks.concrete_smooth, 320))}; bufferedRecipes.put(soysauce, new ItemStack(ModBlocks.soyuz_launcher)); bufferedTools.put(soysauce, new ItemStack(ModBlocks.struct_soyuz_core)); @@ -104,17 +106,44 @@ public class ConstructionHandler extends NEIUniversalHandler { /* ICF */ ItemStack[] icf = new ItemStack[] { new ItemStack(ModBlocks.icf_component, 50, 0), - ItemStackUtil.addTooltipToStack(new ItemStack(ModBlocks.icf_component, 240, 3), EnumChatFormatting.RED + "3x64 + 48"), - ItemStackUtil.addTooltipToStack(Mats.MAT_DURA.make(ModItems.bolt, 960), EnumChatFormatting.RED + "15x64"), - ItemStackUtil.addTooltipToStack(Mats.MAT_STEEL.make(ModItems.plate_cast, 240), EnumChatFormatting.RED + "3x64 + 48"), - ItemStackUtil.addTooltipToStack(new ItemStack(ModBlocks.icf_component, 117, 1), EnumChatFormatting.RED + "64 + 53"), - ItemStackUtil.addTooltipToStack(Mats.MAT_BBRONZE.make(ModItems.plate_cast, 117), EnumChatFormatting.RED + "64 + 53"), + ItemStackUtil.addStackSizeLabel(new ItemStack(ModBlocks.icf_component, 240, 3)), + ItemStackUtil.addStackSizeLabel(Mats.MAT_DURA.make(ModItems.bolt, 960)), + ItemStackUtil.addStackSizeLabel(Mats.MAT_STEEL.make(ModItems.plate_cast, 240)), + ItemStackUtil.addStackSizeLabel(new ItemStack(ModBlocks.icf_component, 117, 1)), + ItemStackUtil.addStackSizeLabel(Mats.MAT_BBRONZE.make(ModItems.plate_cast, 117)), new ItemStack(ModItems.blowtorch), new ItemStack(ModItems.boltgun) }; bufferedRecipes.put(icf, new ItemStack(ModBlocks.icf)); bufferedTools.put(icf, new ItemStack(ModBlocks.struct_icf_core)); + /* FUSION TORUS */ + int wallCount = 0; + int blanketCount = 0; + int pipeCount = -1; // one block is replaced by the core + + for(int iy = 0; iy < 5; iy++) { + int l = iy > 2 ? 4 - iy : iy; + int[][] layer = MachineFusionTorus.layout[l]; + for(int ix = 0; ix < layer.length; ix++) for(int iz = 0; iz < layer.length; iz++) { + int meta = layer[ix][iz]; + if(meta == 1) wallCount++; + if(meta == 2) blanketCount++; + if(meta == 3) pipeCount++; + } + } + + List torusItems = new ArrayList(); + while(wallCount > 0) { int a = Math.min(wallCount, 256); torusItems.add(new ItemStack(ModBlocks.fusion_component, a, 1)); wallCount -= a; } + while(blanketCount > 0) { int a = Math.min(blanketCount, 256); torusItems.add(new ItemStack(ModBlocks.fusion_component, a, 2)); blanketCount -= a; } + while(pipeCount > 0) { int a = Math.min(pipeCount, 256); torusItems.add(new ItemStack(ModBlocks.fusion_component, a, 3)); pipeCount -= a; } + torusItems.add(new ItemStack(ModItems.blowtorch)); + for(ItemStack stack : torusItems) ItemStackUtil.addStackSizeLabel(stack); + ItemStack[] torus = torusItems.toArray(new ItemStack[0]); + + bufferedRecipes.put(torus, new ItemStack(ModBlocks.fusion_torus)); + bufferedTools.put(torus, new ItemStack(ModBlocks.struct_torus_core)); + return recipes ? bufferedRecipes : bufferedTools; } } diff --git a/src/main/java/com/hbm/handler/nei/FusionBreederHandler.java b/src/main/java/com/hbm/handler/nei/FusionBreederHandler.java new file mode 100644 index 000000000..69a4c6a05 --- /dev/null +++ b/src/main/java/com/hbm/handler/nei/FusionBreederHandler.java @@ -0,0 +1,16 @@ +package com.hbm.handler.nei; + +import com.hbm.blocks.ModBlocks; +import com.hbm.inventory.recipes.FluidBreederRecipes; + +public class FusionBreederHandler extends NEIUniversalHandler { + + public FusionBreederHandler() { + super(ModBlocks.fusion_breeder.getLocalizedName(), ModBlocks.fusion_breeder, FluidBreederRecipes.getRecipes()); + } + + @Override + public String getKey() { + return "ntmFluidBreeder"; + } +} diff --git a/src/main/java/com/hbm/handler/nei/NEIUniversalHandler.java b/src/main/java/com/hbm/handler/nei/NEIUniversalHandler.java index 31274e626..3fb477547 100644 --- a/src/main/java/com/hbm/handler/nei/NEIUniversalHandler.java +++ b/src/main/java/com/hbm/handler/nei/NEIUniversalHandler.java @@ -210,7 +210,13 @@ public abstract class NEIUniversalHandler extends TemplateRecipeHandler implemen }; } - return new int[count][2]; + int[][] slots = new int[count][2]; + + for(int i = 0; i < count; i++) { + slots[i] = new int[] {i % 4 * 18, i / 4 * 18}; + } + + return slots; } public static int[][] getOutputCoords(int count) { @@ -258,7 +264,13 @@ public abstract class NEIUniversalHandler extends TemplateRecipeHandler implemen }; } - return new int[count][2]; + int[][] slots = new int[count][2]; + + for(int i = 0; i < count; i++) { + slots[i] = new int[] {i % 4 * 18, i / 4 * 18}; + } + + return slots; } @Override diff --git a/src/main/java/com/hbm/handler/nei/OutgasserHandler.java b/src/main/java/com/hbm/handler/nei/OutgasserHandler.java index 6a7575609..0e7a79f35 100644 --- a/src/main/java/com/hbm/handler/nei/OutgasserHandler.java +++ b/src/main/java/com/hbm/handler/nei/OutgasserHandler.java @@ -6,10 +6,12 @@ import com.hbm.blocks.ModBlocks; import com.hbm.inventory.gui.GUIRBMKOutgasser; import com.hbm.inventory.recipes.OutgasserRecipes; +import net.minecraft.item.ItemStack; + public class OutgasserHandler extends NEIUniversalHandler { public OutgasserHandler() { - super(ModBlocks.rbmk_outgasser.getLocalizedName(), ModBlocks.rbmk_outgasser, OutgasserRecipes.getRecipes()); + super(ModBlocks.rbmk_outgasser.getLocalizedName(), new ItemStack[] {new ItemStack(ModBlocks.rbmk_outgasser), new ItemStack(ModBlocks.fusion_breeder)}, OutgasserRecipes.getRecipes()); } @Override diff --git a/src/main/java/com/hbm/inventory/recipes/FluidBreederRecipes.java b/src/main/java/com/hbm/inventory/recipes/FluidBreederRecipes.java new file mode 100644 index 000000000..36e960b25 --- /dev/null +++ b/src/main/java/com/hbm/inventory/recipes/FluidBreederRecipes.java @@ -0,0 +1,72 @@ +package com.hbm.inventory.recipes; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.stream.JsonWriter; +import com.hbm.inventory.FluidStack; +import com.hbm.inventory.fluid.FluidType; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.recipes.loader.SerializableRecipe; +import com.hbm.items.machine.ItemFluidIcon; +import com.hbm.util.Tuple.Pair; + +// i'm gonna be honest, i got so carried away with the new fusion reactor stuff that i forgot what fluid irradiation was even supposed to be for +public class FluidBreederRecipes extends SerializableRecipe { + + public static Map> recipes = new HashMap(); + + @Override + public void registerDefaults() { + + register(new FluidStack(Fluids.GAS, 1_000), new FluidStack(Fluids.SYNGAS, 1_000)); + register(new FluidStack(Fluids.LIGHTOIL, 1_000), new FluidStack(Fluids.REFORMGAS, 1_000)); + register(new FluidStack(Fluids.LIGHTOIL_CRACK, 1_000), new FluidStack(Fluids.REFORMGAS, 1_000)); + } + + public static void register(FluidStack input, FluidStack output) { + recipes.put(input.type, new Pair(input.fill, output)); + } + + public static Pair getOutput(FluidType type) { + return recipes.get(type); + } + + public static HashMap getRecipes() { + + HashMap recipes = new HashMap(); + + for(Entry> entry : FluidBreederRecipes.recipes.entrySet()) { + recipes.put(ItemFluidIcon.make(entry.getKey(), entry.getValue().getKey()), ItemFluidIcon.make(entry.getValue().getValue())); + } + + return recipes; + } + + @Override + public void readRecipe(JsonElement recipe) { + JsonObject obj = (JsonObject) recipe; + + FluidStack input = this.readFluidStack(obj.get("input").getAsJsonArray()); + FluidStack output = this.readFluidStack(obj.get("output").getAsJsonArray()); + this.recipes.put(input.type, new Pair(input.fill, output)); + } + + @Override + public void writeRecipe(Object recipe, JsonWriter writer) throws IOException { + Entry> rec = (Entry>) recipe; + + writer.name("input"); + this.writeFluidStack(new FluidStack(rec.getKey(), rec.getValue().getKey()), writer); + writer.name("output"); + this.writeFluidStack(rec.getValue().getValue(), writer); + } + + @Override public String getFileName() { return "hbmIrradiationFluids.json"; } + @Override public Object getRecipeObject() { return recipes; } + @Override public void deleteRecipes() { recipes.clear(); } +} 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 659b52948..e2ba5cf28 100644 --- a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java +++ b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java @@ -73,6 +73,7 @@ public abstract class SerializableRecipe { recipeHandlers.add(new FuelPoolRecipes()); recipeHandlers.add(new MixerRecipes()); recipeHandlers.add(new OutgasserRecipes()); + recipeHandlers.add(new FluidBreederRecipes()); recipeHandlers.add(new CompressorRecipes()); recipeHandlers.add(new ElectrolyserFluidRecipes()); recipeHandlers.add(new ElectrolyserMetalRecipes()); diff --git a/src/main/java/com/hbm/main/NEIRegistry.java b/src/main/java/com/hbm/main/NEIRegistry.java index 14cd7f7e7..31671e8df 100644 --- a/src/main/java/com/hbm/main/NEIRegistry.java +++ b/src/main/java/com/hbm/main/NEIRegistry.java @@ -63,6 +63,7 @@ public class NEIRegistry { handlers.add(new SawmillHandler()); handlers.add(new MixerHandler()); handlers.add(new OutgasserHandler()); + handlers.add(new FusionBreederHandler()); handlers.add(new ElectrolyserFluidHandler()); handlers.add(new ElectrolyserMetalHandler()); handlers.add(new AshpitHandler()); diff --git a/src/main/java/com/hbm/render/tileentity/RenderFusionMHDT.java b/src/main/java/com/hbm/render/tileentity/RenderFusionMHDT.java index 72bd59ca2..157dc29a3 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderFusionMHDT.java +++ b/src/main/java/com/hbm/render/tileentity/RenderFusionMHDT.java @@ -6,6 +6,7 @@ import com.hbm.blocks.BlockDummyable; import com.hbm.blocks.ModBlocks; import com.hbm.main.ResourceManager; import com.hbm.render.item.ItemRenderBase; +import com.hbm.tileentity.machine.fusion.TileEntityFusionMHDT; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.item.Item; @@ -32,8 +33,10 @@ public class RenderFusionMHDT extends TileEntitySpecialRenderer implements IItem bindTexture(ResourceManager.fusion_mhdt_tex); ResourceManager.fusion_mhdt.renderPart("Turbine"); + TileEntityFusionMHDT turbine = (TileEntityFusionMHDT) tile; + GL11.glPushMatrix(); - double rot = (System.currentTimeMillis() / 10) % 30D; + float rot = (turbine.prevRotor + (turbine.rotor - turbine.prevRotor) * interp) % 30; rot -= 15; GL11.glTranslated(0, 1.5, 0); GL11.glRotated(rot, 1, 0, 0); @@ -64,7 +67,7 @@ public class RenderFusionMHDT extends TileEntitySpecialRenderer implements IItem GL11.glShadeModel(GL11.GL_SMOOTH); bindTexture(ResourceManager.fusion_mhdt_tex); ResourceManager.fusion_mhdt.renderPart("Turbine"); - double rot = (System.currentTimeMillis() / 10) % 30D; + double rot = (System.currentTimeMillis() / 5) % 30D; rot -= 15; GL11.glTranslated(0, 1.5, 0); GL11.glRotated(rot, 1, 0, 0); diff --git a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBoiler.java b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBoiler.java index 4692184b2..7d7404f1d 100644 --- a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBoiler.java +++ b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBoiler.java @@ -1,11 +1,146 @@ package com.hbm.tileentity.machine.fusion; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.inventory.fluid.trait.FT_Heatable; +import com.hbm.tileentity.TileEntityLoadedBase; +import com.hbm.uninos.GenNode; +import com.hbm.uninos.UniNodespace; +import com.hbm.uninos.networkproviders.PlasmaNetworkProvider; +import com.hbm.util.fauxpointtwelve.BlockPos; +import com.hbm.util.fauxpointtwelve.DirPos; + +import api.hbm.fluidmk2.IFluidStandardTransceiverMK2; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.tileentity.TileEntity; +import io.netty.buffer.ByteBuf; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; +import net.minecraftforge.common.util.ForgeDirection; -public class TileEntityFusionBoiler extends TileEntity { +public class TileEntityFusionBoiler extends TileEntityLoadedBase implements IFluidStandardTransceiverMK2, IFusionPowerReceiver { + + protected GenNode plasmaNode; + + public long plasmaEnergy; + public long plasmaEnergySync; + public FluidTank[] tanks; + + public TileEntityFusionBoiler() { + this.tanks = new FluidTank[2]; + this.tanks[0] = new FluidTank(Fluids.WATER, 32_000); + this.tanks[1] = new FluidTank(Fluids.SUPERHOTSTEAM, 32_000); + } + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + + this.plasmaEnergySync = this.plasmaEnergy; + this.plasmaEnergy = 0; + + for(DirPos pos : getConPos()) { + if(tanks[0].getTankType() != Fluids.NONE) this.trySubscribe(tanks[0].getTankType(), worldObj, pos); + if(tanks[1].getFill() > 0) this.tryProvide(tanks[1], worldObj, pos); + } + + if(plasmaNode == null || plasmaNode.expired) { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10).getOpposite(); + plasmaNode = UniNodespace.getNode(worldObj, xCoord + dir.offsetX * 4, yCoord + 2, zCoord + dir.offsetZ * 4, PlasmaNetworkProvider.THE_PROVIDER); + + if(plasmaNode == null) { + plasmaNode = new GenNode(PlasmaNetworkProvider.THE_PROVIDER, + new BlockPos(xCoord + dir.offsetX * 4, yCoord + 2, zCoord + dir.offsetZ * 4)) + .setConnections(new DirPos(xCoord + dir.offsetX * 5, yCoord + 2, zCoord + dir.offsetZ * 5, dir)); + + UniNodespace.createNode(worldObj, plasmaNode); + } + } + + if(plasmaNode != null && plasmaNode.hasValidNet()) plasmaNode.net.addReceiver(this); + + this.networkPackNT(50); + } + } + + public DirPos[] getConPos() { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + return new DirPos[] { + //new DirPos(xCoord + dir.offsetX * 5, yCoord + 2, zCoord + dir.offsetZ * 5, dir), + new DirPos(xCoord - dir.offsetX * 1 + rot.offsetX * 3, yCoord, zCoord - dir.offsetZ * 1 + rot.offsetZ * 3, rot), + new DirPos(xCoord - dir.offsetX * 1 - rot.offsetX * 3, yCoord, zCoord - dir.offsetZ * 1 - rot.offsetZ * 3, rot.getOpposite()), + new DirPos(xCoord + dir.offsetX * 2 + rot.offsetX * 3, yCoord, zCoord + dir.offsetZ * 2 + rot.offsetZ * 3, rot), + new DirPos(xCoord + dir.offsetX * 2 - rot.offsetX * 3, yCoord, zCoord + dir.offsetZ * 2 - rot.offsetZ * 3, rot.getOpposite()) + }; + } + + @Override public boolean receivesFusionPower() { return true; } + + @Override + public void receiveFusionPower(long fusionPower, double neutronPower) { + this.plasmaEnergy = fusionPower; + + int waterCycles = Math.min(tanks[0].getFill(), tanks[1].getMaxFill() - tanks[1].getFill()); + int steamCycles = (int) (Math.min(fusionPower / tanks[0].getTankType().getTrait(FT_Heatable.class).getFirstStep().heatReq, waterCycles)); + // the Math.min call was mushed into the steam cycles call instead of doing it afterwards as usual + // in order to prevent issues when casting, should the fusion reactor output truly absurd amounts of power + // due to the water cycles being effectively capped via the buffer size + + if(steamCycles > 0) { + tanks[0].setFill(tanks[0].getFill() - steamCycles); + tanks[1].setFill(tanks[1].getFill() - steamCycles); + } + } + + @Override + public void serialize(ByteBuf buf) { + super.serialize(buf); + buf.writeLong(plasmaEnergySync); + + this.tanks[0].serialize(buf); + this.tanks[1].serialize(buf); + } + + @Override + public void deserialize(ByteBuf buf) { + super.deserialize(buf); + this.plasmaEnergy = buf.readLong(); + + this.tanks[0].deserialize(buf); + this.tanks[1].deserialize(buf); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + + this.tanks[0].readFromNBT(nbt, "t0"); + this.tanks[1].readFromNBT(nbt, "t1"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + + this.tanks[0].writeToNBT(nbt, "t0"); + this.tanks[1].writeToNBT(nbt, "t1"); + } + + @Override + public void invalidate() { + super.invalidate(); + + if(!worldObj.isRemote) { + if(this.plasmaNode != null) UniNodespace.destroyNode(worldObj, plasmaNode); + } + } + + @Override public FluidTank[] getAllTanks() { return tanks; } + @Override public FluidTank[] getReceivingTanks() { return new FluidTank[] {tanks[0]}; } + @Override public FluidTank[] getSendingTanks() { return new FluidTank[] {tanks[1]}; } AxisAlignedBB bb = null; diff --git a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBreeder.java b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBreeder.java index 2cd045441..e03305267 100644 --- a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBreeder.java +++ b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionBreeder.java @@ -5,6 +5,7 @@ import com.hbm.inventory.container.ContainerFusionBreeder; import com.hbm.inventory.fluid.Fluids; import com.hbm.inventory.fluid.tank.FluidTank; import com.hbm.inventory.gui.GUIFusionBreeder; +import com.hbm.inventory.recipes.FluidBreederRecipes; import com.hbm.inventory.recipes.OutgasserRecipes; import com.hbm.items.machine.IItemFluidIdentifier; import com.hbm.tileentity.IGUIProvider; @@ -57,7 +58,7 @@ public class TileEntityFusionBreeder extends TileEntityMachineBase implements IF if(!worldObj.isRemote) { - if(!canProcessSolid()) { + if(!canProcessSolid() && !canProcessLiquid()) { this.progress = 0; } @@ -111,6 +112,21 @@ public class TileEntityFusionBreeder extends TileEntityMachineBase implements IF return slots[2].getItem() == out.getItem() && slots[2].getItemDamage() == out.getItemDamage() && slots[2].stackSize + out.stackSize <= slots[2].getMaxStackSize(); } + public boolean canProcessLiquid() { + + Pair output = FluidBreederRecipes.getOutput(tanks[0].getTankType()); + if(output == null) return false; + if(tanks[0].getFill() < output.getKey()) return false; + + FluidStack fluid = output.getValue(); + + if(tanks[1].getTankType() != fluid.type && tanks[1].getFill() > 0) return false; + tanks[1].setTankType(fluid.type); + if(tanks[1].getFill() + fluid.fill > tanks[1].getMaxFill()) return false; + + return true; + } + private void processSolid() { Pair output = OutgasserRecipes.getOutput(slots[1]); @@ -131,6 +147,13 @@ public class TileEntityFusionBreeder extends TileEntityMachineBase implements IF } } } + + private void processLiquid() { + + Pair output = FluidBreederRecipes.getOutput(tanks[0].getTankType()); + tanks[0].setFill(tanks[0].getFill() - output.getKey()); + tanks[1].setFill(tanks[1].getFill() + output.getValue().fill); + } public void doProgress() { @@ -141,6 +164,15 @@ public class TileEntityFusionBreeder extends TileEntityMachineBase implements IF progress = 0; this.markDirty(); } + } else if(canProcessLiquid()) { + this.progress += this.neutronEnergy; + if(progress > capacity) { + processLiquid(); + progress = 0; + this.markDirty(); + } + } else { + progress = 0; } } @@ -160,7 +192,7 @@ public class TileEntityFusionBreeder extends TileEntityMachineBase implements IF new DirPos(xCoord + rot.offsetX * 3, yCoord, zCoord + rot.offsetZ * 3, rot), new DirPos(xCoord - rot.offsetX * 3, yCoord, zCoord - rot.offsetZ * 3, rot.getOpposite()), new DirPos(xCoord + dir.offsetX + rot.offsetX * 3, yCoord, zCoord + dir.offsetX + rot.offsetZ * 3, rot), - new DirPos(xCoord - dir.offsetX - rot.offsetX * 3, yCoord, zCoord - dir.offsetX - rot.offsetZ * 3, rot.getOpposite()) + new DirPos(xCoord + dir.offsetX - rot.offsetX * 3, yCoord, zCoord + dir.offsetX - rot.offsetZ * 3, rot.getOpposite()) }; } diff --git a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionKlystron.java b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionKlystron.java index e1853bb2d..812946dd9 100644 --- a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionKlystron.java +++ b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionKlystron.java @@ -123,6 +123,7 @@ public class TileEntityFusionKlystron extends TileEntityMachineBase implements I } this.networkPackNT(100); + } else { double mult = TileEntityFusionTorus.getSpeedScaled(outputTarget, output); diff --git a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionMHDT.java b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionMHDT.java index b242dd7e7..1a40e8465 100644 --- a/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionMHDT.java +++ b/src/main/java/com/hbm/tileentity/machine/fusion/TileEntityFusionMHDT.java @@ -1,11 +1,170 @@ package com.hbm.tileentity.machine.fusion; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.tileentity.TileEntityLoadedBase; +import com.hbm.uninos.GenNode; +import com.hbm.uninos.UniNodespace; +import com.hbm.uninos.networkproviders.PlasmaNetworkProvider; +import com.hbm.util.fauxpointtwelve.BlockPos; +import com.hbm.util.fauxpointtwelve.DirPos; + +import api.hbm.energymk2.IEnergyProviderMK2; +import api.hbm.fluidmk2.IFluidStandardTransceiverMK2; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.tileentity.TileEntity; +import io.netty.buffer.ByteBuf; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MathHelper; +import net.minecraftforge.common.util.ForgeDirection; -public class TileEntityFusionMHDT extends TileEntity { +public class TileEntityFusionMHDT extends TileEntityLoadedBase implements IEnergyProviderMK2, IFluidStandardTransceiverMK2, IFusionPowerReceiver { + + protected GenNode plasmaNode; + + public long plasmaEnergy; + public long plasmaEnergySync; + public long power; + + public float rotor; + public float prevRotor; + public float rotorSpeed; + public static final float ROTOR_ACCELERATION = 0.125F; + + public static final double PLASMA_EFFICIENCY = 1.35D; + public static final int COOLANT_USE = 50; + + public FluidTank[] tanks; + + public TileEntityFusionMHDT() { + this.tanks = new FluidTank[2]; + this.tanks[0] = new FluidTank(Fluids.PERFLUOROMETHYL_COLD, 4_000); + this.tanks[1] = new FluidTank(Fluids.PERFLUOROMETHYL, 4_000); + } + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + + this.plasmaEnergySync = this.plasmaEnergy; + + if(isCool()) { + this.power = (long) Math.floor(this.plasmaEnergy * PLASMA_EFFICIENCY); + tanks[0].setFill(tanks[0].getFill() - COOLANT_USE); + tanks[1].setFill(tanks[1].getFill() + COOLANT_USE); + } + + for(DirPos pos : getConPos()) { + this.tryProvide(worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); + if(tanks[0].getTankType() != Fluids.NONE) this.trySubscribe(tanks[0].getTankType(), worldObj, pos); + if(tanks[1].getFill() > 0) this.tryProvide(tanks[1], worldObj, pos); + } + + if(plasmaNode == null || plasmaNode.expired) { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10).getOpposite(); + plasmaNode = UniNodespace.getNode(worldObj, xCoord + dir.offsetX * 6, yCoord + 2, zCoord + dir.offsetZ * 6, PlasmaNetworkProvider.THE_PROVIDER); + + if(plasmaNode == null) { + plasmaNode = new GenNode(PlasmaNetworkProvider.THE_PROVIDER, + new BlockPos(xCoord + dir.offsetX * 6, yCoord + 2, zCoord + dir.offsetZ * 6)) + .setConnections(new DirPos(xCoord + dir.offsetX * 7, yCoord + 2, zCoord + dir.offsetZ * 7, dir)); + + UniNodespace.createNode(worldObj, plasmaNode); + } + } + + if(plasmaNode != null && plasmaNode.hasValidNet()) plasmaNode.net.addReceiver(this); + + this.networkPackNT(150); + this.plasmaEnergy = 0; + + } else { + + if(this.plasmaEnergy > 0 && isCool()) this.rotorSpeed += ROTOR_ACCELERATION; + else this.rotorSpeed -= ROTOR_ACCELERATION; + + this.rotorSpeed = MathHelper.clamp_float(this.rotorSpeed, 0F, 15F); + + this.prevRotor = this.rotor; + this.rotor += this.rotorSpeed; + + if(this.rotor >= 360F) { + this.rotor -= 360F; + this.prevRotor -= 360F; + } + } + } + + public boolean isCool() { + return tanks[0].getFill() >= COOLANT_USE && tanks[1].getFill() + COOLANT_USE <= tanks[1].getMaxFill(); + } + + public DirPos[] getConPos() { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + return new DirPos[] { + new DirPos(xCoord + dir.offsetX * 4 + rot.offsetX * 4, yCoord, zCoord + dir.offsetZ * 4 + rot.offsetZ * 4, rot), + new DirPos(xCoord + dir.offsetX * 4 - rot.offsetX * 4, yCoord, zCoord + dir.offsetZ * 4 - rot.offsetZ * 4, rot.getOpposite()), + new DirPos(xCoord + dir.offsetX * 8, yCoord + 1, zCoord + dir.offsetZ * 8, dir) + }; + } + + @Override public boolean receivesFusionPower() { return true; } + @Override public void receiveFusionPower(long fusionPower, double neutronPower) { this.plasmaEnergy = fusionPower; } + + @Override + public void serialize(ByteBuf buf) { + super.serialize(buf); + buf.writeLong(plasmaEnergySync); + + this.tanks[0].serialize(buf); + this.tanks[1].serialize(buf); + } + + @Override + public void deserialize(ByteBuf buf) { + super.deserialize(buf); + this.plasmaEnergy = buf.readLong(); + + this.tanks[0].deserialize(buf); + this.tanks[1].deserialize(buf); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + + this.tanks[0].readFromNBT(nbt, "t0"); + this.tanks[1].readFromNBT(nbt, "t1"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + + this.tanks[0].writeToNBT(nbt, "t0"); + this.tanks[1].writeToNBT(nbt, "t1"); + } + + @Override + public void invalidate() { + super.invalidate(); + + if(!worldObj.isRemote) { + if(this.plasmaNode != null) UniNodespace.destroyNode(worldObj, plasmaNode); + } + } + + @Override public long getPower() { return power; } + @Override public void setPower(long power) { this.power = power; } + @Override public long getMaxPower() { return power; } + + @Override public FluidTank[] getAllTanks() { return tanks; } + @Override public FluidTank[] getReceivingTanks() { return new FluidTank[] {tanks[0]}; } + @Override public FluidTank[] getSendingTanks() { return new FluidTank[] {tanks[1]}; } AxisAlignedBB bb = null; diff --git a/src/main/java/com/hbm/util/BobMathUtil.java b/src/main/java/com/hbm/util/BobMathUtil.java index 0c46100be..ad8b8ee0e 100644 --- a/src/main/java/com/hbm/util/BobMathUtil.java +++ b/src/main/java/com/hbm/util/BobMathUtil.java @@ -187,6 +187,9 @@ public class BobMathUtil { public static String format(int amount) { return String.format(Locale.US, "%,d", amount); } + public static String format(long amount) { + return String.format(Locale.US, "%,d", amount); + } public static boolean getBlink() { return System.currentTimeMillis() % 1000 < 500; diff --git a/src/main/java/com/hbm/util/ItemStackUtil.java b/src/main/java/com/hbm/util/ItemStackUtil.java index a3bc8a822..02b4551f2 100644 --- a/src/main/java/com/hbm/util/ItemStackUtil.java +++ b/src/main/java/com/hbm/util/ItemStackUtil.java @@ -107,6 +107,22 @@ public class ItemStackUtil { return stack; } + + /** + * Automatically adds multistack labels for displays that use a ton of items (like construction recipe handlers). + * @param stack + * @return + */ + public static ItemStack addStackSizeLabel(ItemStack stack) { + + if(stack.stackSize > 64) { + int stacks = stack.stackSize / 64; + int items = stack.stackSize % 64; + addTooltipToStack(stack, EnumChatFormatting.RED + "" + stacks + "x64" + (items > 0 ? (" + " + items) : "")); + } + + return stack; + } public static void addStacksToNBT(ItemStack stack, ItemStack... stacks) { diff --git a/src/main/resources/assets/hbm/lang/de_DE.lang b/src/main/resources/assets/hbm/lang/de_DE.lang index dd8ba0192..a44f9eda1 100644 --- a/src/main/resources/assets/hbm/lang/de_DE.lang +++ b/src/main/resources/assets/hbm/lang/de_DE.lang @@ -366,7 +366,10 @@ container.furnaceBrick=Ziegelofen container.furnaceCombination=Kombinationsofen container.furnaceIron=Eiserner Ofen container.furnaceSteel=Stahlofen +container.fusionBreeder=Brutkammer +container.fusionKlystron=Klystron container.fusionMultiblock=Großer Fusionsreaktor +container.fusionTorus=Fusionsreaktor-Plasmagefäß container.fusionaryWatzPlant=Fusionares Watzwerk container.gasCentrifuge=Gaszentrifuge container.gasFlare=Abfackelturm @@ -4281,13 +4284,25 @@ tile.furnace_iron.name=Eiserner Ofen tile.furnace_iron.desc=Größerer und effizienterer Ofen,$verschwended keinen Brennstoff im Leerlauf. tile.furnace_steel.name=Stahlofen tile.furnace_steel.desc=Sehr großer Ofen mit Produktionsboni.$Benötigt externe Hitzequelle.$Wärmetransferrate: ΔT*0.05 TU/t$(Δ heißt Differenz, T heißt Temparatur) +tile.fusion_boiler.name=Fusionsreaktor-Boiler +tile.fusion_boiler.desc=Nutzt Plasmaenergie aus einem Fusionsreaktor$um Wasser zu superverdichtetem Dampf zu machen. +tile.fusion_breeder.name=Fusionsreaktor-Brutkammer +tile.fusion_breeder.desc=Verwendet Neutronenflux von einem$Fusionsreaktor um Materialien zu verarbeiten.$Nützlich für Tritiumbrennstoff. tile.fusion_center.name=Zentralmagnetstück +tile.fusion_collector.name=Fusionsreaktor-Kollektor +tile.fusion_collector.desc=Erhöht Nebenprodukt-Produktion$von einem Fusionsreaktor. tile.fusion_conductor.name=Supraleiter-Magnet tile.fusion_conductor_welded.name=Supraleiter-Magnet (Verschweißt) tile.fusion_core.name=Fusionsreaktorsteuerung tile.fusion_hatch.name=Fusionsreaktorzugriffsluke tile.fusion_heater.name=Plasmaerhitzer-Komponente +tile.fusion_klystron.name=Klystron +tile.fusion_klystron.desc=Energiequelle für einen Fusionsreaktor.$Benötigt Kühlung mittles Druckluft. +tile.fusion_mhdt.name=MHD-Turbine +tile.fusion_mhdt.desc=Wandelt Plasmaenergie in verwendbare$elektrische Energie um. Effizienter als ein$konventioneller Boiler.$Benötigt Kühlung! tile.fusion_motor.name=Magnetmotorstück +tile.fusion_torus.name=Fusionsreaktor-Plasmagefäß +tile.fusion_torus.desc=Hauptkomponente des Reaktors.$Benötigt Energie von einem Klystron zur Zündung,$erzeugt Plasmaenergie und Neutronenflux.$Benötigt Kühlung! tile.fwatz_computer.name=Watzwerkrechenmatrix tile.fwatz_conductor.name=4000K Supraleiter-Magnet tile.fwatz_cooler.name=Kühlmitteltankhülle diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index ffbb75370..1ade44d00 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -772,8 +772,10 @@ container.furnaceBrick=Bricked Furnace container.furnaceCombination=Combination Oven container.furnaceIron=Iron Furnace container.furnaceSteel=Steel Furnace +container.fusionBreeder=Fusion Reactor Breeder +container.fusionKlystron=Klystron container.fusionMultiblock=Big Fusion Reactor -container.fusionaryWatzPlant=Fusionary Watz Plant +container.fusionTorus=Fusion Reactor Vessel container.gasCentrifuge=Gas Centrifuge container.gasFlare=Flare Stack container.generator=Nuclear Reactor @@ -5537,13 +5539,25 @@ tile.furnace_iron.name=Iron Furnace tile.furnace_iron.desc=Larger and more efficient furnace,$does not waste fuel when idle. tile.furnace_steel.name=Steel Furnace tile.furnace_steel.desc=Very large furnace that can provide bonus items$when smelting ores. Requires external heat source.$Heat transfer rate: ΔT*0.05 TU/t$(Δ means difference and T means temperature) +tile.fusion_boiler.name=Fusion Reactor Boiler +tile.fusion_boiler.desc=Uses plasma energy from a fusion reactor$to boil water into super dense steam. +tile.fusion_breeder.name=Fusion Reactor Breeding Chamber +tile.fusion_breeder.desc=Uses output neutron flux from$a fusion reactor to process materials.$Useful for making tritium fuel. tile.fusion_center.name=Central Magnet Piece +tile.fusion_collector.name=Fusion Reactor Collector Chamber +tile.fusion_collector.desc=Can be connected to the main vessel$to increase byproduct yield. tile.fusion_conductor.name=Superconducting Magnet tile.fusion_conductor_welded.name=Superconducting Magnet (Welded) tile.fusion_core.name=Fusion Reactor Control tile.fusion_hatch.name=Duct Deco Block tile.fusion_heater.name=Plasma Heater Component +tile.fusion_klystron.name=Klystron +tile.fusion_klystron.desc=Power source for fusion reactors.$Requires cooling via compressed air. +tile.fusion_mhdt.name=MHD Turbine +tile.fusion_mhdt.desc=Turns plasma energy into usable$electricity directly. More efficient$than a conventional boiler.$Requires cooling! tile.fusion_motor.name=Magnet Motor Piece +tile.fusion_torus.name=Fusion Reactor Vessel +tile.fusion_torus.desc=Fusion reactor main component.$Requires klystron input energy to ignite plasma,$produces plasma energy and neutron flux.$Requires cooling! tile.fwatz_computer.name=Fusionary Watz Reactor Calculation Matrix tile.fwatz_conductor.name=4000K Superconducting Magnet tile.fwatz_cooler.name=Regenerative Coolant Fluid Tank Shell diff --git a/src/main/resources/assets/hbm/textures/models/fusion/boiler.png b/src/main/resources/assets/hbm/textures/models/fusion/boiler.png index 4a62137d5e1156a20256d8e54f43ba32fdba84e3..85ddf504692a423b03ec66088653d357643a162e 100644 GIT binary patch literal 6806 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 JQln%S{y*LqUCRIf literal 6699 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 diff --git a/src/main/resources/assets/hbm/textures/models/fusion/mhdt.png b/src/main/resources/assets/hbm/textures/models/fusion/mhdt.png index 0836580c2d67513040dc70a11b074e3568a4931a..b6312886191290c08725c3eafd5ddfa8f674cb2f 100644 GIT binary patch literal 16649 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 L_0=${b`k#vn%NFK