From 81a035298647df0a895e3aa1e20c3864d165b5ee Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 31 Mar 2025 22:19:21 +0200 Subject: [PATCH] fuck --- changelog | 25 +- src/main/java/com/hbm/blocks/ModBlocks.java | 40 ++ .../java/com/hbm/blocks/bomb/NukeMk3.java | 184 +++++ .../hbm/blocks/machine/BlockGenericVVER.java | 22 + .../hbm/blocks/machine/BlockPillarVVER.java | 21 + .../com/hbm/blocks/machine/BlockVVER.java | 341 ++++++++++ .../blocks/machine/MachineVVERController.java | 222 ++++++ .../java/com/hbm/crafting/RodRecipes.java | 18 + .../inventory/container/ContainerNukeMk3.java | 77 +++ .../inventory/container/ContainerVVER.java | 75 +++ .../com/hbm/inventory/gui/GUINukeMk3.java | 77 +++ .../java/com/hbm/inventory/gui/GUIVVER.java | 199 ++++++ src/main/java/com/hbm/items/ModItems.java | 14 + .../com/hbm/items/machine/ItemVVERFuel.java | 64 ++ .../hbm/items/weapon/sedna/ItemGunBaseNT.java | 3 +- .../weapon/sedna/factory/GunFactory.java | 4 +- src/main/java/com/hbm/main/ClientProxy.java | 1 + .../java/com/hbm/main/CraftingManager.java | 11 + .../java/com/hbm/main/ResourceManager.java | 1 + .../hbm/render/tileentity/RenderNukeMk3.java | 65 ++ .../java/com/hbm/tileentity/TileMappings.java | 4 + .../tileentity/bomb/TileEntityNukeMk3.java | 254 +++++++ .../machine/TileEntityVVERController.java | 631 ++++++++++++++++++ src/main/resources/assets/hbm/lang/en_US.lang | 68 ++ .../assets/hbm/textures/blocks/mk3.png | Bin 0 -> 441 bytes .../assets/hbm/textures/blocks/vver_block.png | Bin 0 -> 344 bytes .../hbm/textures/blocks/vver_block_ct.png | Bin 0 -> 864 bytes .../hbm/textures/blocks/vver_block_ct_alt.png | Bin 0 -> 899 bytes .../hbm/textures/blocks/vver_casing.png | Bin 0 -> 562 bytes .../hbm/textures/blocks/vver_casing_blank.png | Bin 0 -> 515 bytes .../hbm/textures/blocks/vver_casing_port.png | Bin 0 -> 300 bytes .../textures/blocks/vver_casing_port_ct.png | Bin 0 -> 916 bytes .../hbm/textures/blocks/vver_channel_side.png | Bin 0 -> 174 bytes .../hbm/textures/blocks/vver_channel_top.png | Bin 0 -> 169 bytes .../textures/blocks/vver_concrete_flat.png | Bin 0 -> 522 bytes .../hbm/textures/blocks/vver_control_side.png | Bin 0 -> 242 bytes .../hbm/textures/blocks/vver_control_top.png | Bin 0 -> 288 bytes .../hbm/textures/blocks/vver_controller.png | Bin 0 -> 544 bytes .../hbm/textures/blocks/vver_fuel_side.png | Bin 0 -> 211 bytes .../hbm/textures/blocks/vver_fuel_top.png | Bin 0 -> 294 bytes .../hbm/textures/blocks/vver_heatex.png | Bin 0 -> 374 bytes .../hbm/textures/blocks/vver_heatsink.png | Bin 0 -> 323 bytes .../textures/blocks/vver_neutron_source.png | Bin 0 -> 537 bytes .../assets/hbm/textures/blocks/vver_port.png | Bin 0 -> 588 bytes .../hbm/textures/blocks/vver_reflector.png | Bin 0 -> 496 bytes .../assets/hbm/textures/models/mk3.png | Bin 0 -> 5320 bytes 46 files changed, 2400 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/hbm/blocks/bomb/NukeMk3.java create mode 100644 src/main/java/com/hbm/blocks/machine/BlockGenericVVER.java create mode 100644 src/main/java/com/hbm/blocks/machine/BlockPillarVVER.java create mode 100644 src/main/java/com/hbm/blocks/machine/BlockVVER.java create mode 100644 src/main/java/com/hbm/blocks/machine/MachineVVERController.java create mode 100644 src/main/java/com/hbm/inventory/container/ContainerNukeMk3.java create mode 100644 src/main/java/com/hbm/inventory/container/ContainerVVER.java create mode 100644 src/main/java/com/hbm/inventory/gui/GUINukeMk3.java create mode 100644 src/main/java/com/hbm/inventory/gui/GUIVVER.java create mode 100644 src/main/java/com/hbm/items/machine/ItemVVERFuel.java create mode 100644 src/main/java/com/hbm/render/tileentity/RenderNukeMk3.java create mode 100644 src/main/java/com/hbm/tileentity/bomb/TileEntityNukeMk3.java create mode 100644 src/main/java/com/hbm/tileentity/machine/TileEntityVVERController.java create mode 100644 src/main/resources/assets/hbm/textures/blocks/mk3.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_block.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_block_ct.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_block_ct_alt.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_casing.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_casing_blank.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_casing_port.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_casing_port_ct.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_channel_side.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_channel_top.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_concrete_flat.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_control_side.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_control_top.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_controller.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_fuel_side.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_fuel_top.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_heatex.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_heatsink.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_neutron_source.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_port.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/vver_reflector.png create mode 100644 src/main/resources/assets/hbm/textures/models/mk3.png diff --git a/changelog b/changelog index 671756e10..05f81516f 100644 --- a/changelog +++ b/changelog @@ -1,18 +1,9 @@ -## Changed -* .75 bolts now work as advertised -* Updated lead pipe texture -* Removed recipes from a few ancient melee weapons, as well as the creative tab listing -* Removed flat magnets -* Taint should now also affect non-solid blocks that are full cubes -* Reduced the AoE size of 7.62mm, .50 BMG and 10 gauge explosive projectiles -* Removed the old gun mechanism items, turrets now use the new cast parts -* A secret weapon and its variant have become craftable -* NEI now shows RBMK fuel rod recycling and cooling -* Removed most of the old unused siege mobs +## Added +* VVER! + * New reactor + * Totally different from the PWR, not similar in the slightest +* Mark 3 nuclear bomb + * New bobm -## Fixed -* Fixed taint destroying bedrock -* Fixed ferrouranium plate not being castable -* Fixed bayonet not rendering properly in third person -* Fixed xenon poison gauge in the RBMK control panel not showing up on colums (oops) -* Fixed hitscan projectiles colliding with dead mobs \ No newline at end of file +## Changed +* all secret weapons are now obtainable in creative, overstimulate yourselves all you want you little gremlins \ 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 bf6821881..dc28db453 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -634,6 +634,7 @@ public class ModBlocks { public static Block nuke_gadget; public static Block nuke_boy; public static Block nuke_man; + public static Block nuke_mk3; public static Block nuke_mike; public static Block nuke_tsar; public static Block nuke_fleija; @@ -895,6 +896,18 @@ public class ModBlocks { public static Block pwr_controller; public static Block pwr_block; + public static Block vver_fuel; + public static Block vver_control; + public static Block vver_channel; + public static Block vver_heatex; + public static Block vver_heatsink; + public static Block vver_neutron_source; + public static Block vver_reflector; + public static Block vver_casing; + public static Block vver_port; + public static Block vver_controller; + public static Block vver_block; + public static Block fusion_conductor; public static Block fusion_center; public static Block fusion_motor; @@ -1712,6 +1725,7 @@ public class ModBlocks { nuke_gadget = new NukeGadget(Material.iron).setBlockName("nuke_gadget").setCreativeTab(MainRegistry.nukeTab).setHardness(5.0F).setResistance(200.0F).setBlockTextureName(RefStrings.MODID + ":theGadget"); nuke_boy = new NukeBoy(Material.iron).setBlockName("nuke_boy").setCreativeTab(MainRegistry.nukeTab).setHardness(5.0F).setResistance(200.0F).setBlockTextureName(RefStrings.MODID + ":lilBoy"); nuke_man = new NukeMan(Material.iron).setBlockName("nuke_man").setCreativeTab(MainRegistry.nukeTab).setHardness(5.0F).setResistance(200.0F).setBlockTextureName(RefStrings.MODID + ":fatMan"); + nuke_mk3 = new NukeMk3(Material.iron).setBlockName("nuke_mk3").setCreativeTab(MainRegistry.nukeTab).setHardness(5.0F).setResistance(200.0F).setBlockTextureName(RefStrings.MODID + ":mk3"); nuke_mike = new NukeMike(Material.iron).setBlockName("nuke_mike").setCreativeTab(MainRegistry.nukeTab).setHardness(5.0F).setResistance(200.0F).setBlockTextureName(RefStrings.MODID + ":ivyMike"); nuke_tsar = new NukeTsar(Material.iron).setBlockName("nuke_tsar").setCreativeTab(MainRegistry.nukeTab).setHardness(5.0F).setResistance(200.0F).setBlockTextureName(RefStrings.MODID + ":tsarBomba"); nuke_fleija = new NukeFleija(Material.iron).setBlockName("nuke_fleija").setCreativeTab(MainRegistry.nukeTab).setHardness(5.0F).setResistance(200.0F).setBlockTextureName(RefStrings.MODID + ":fleija"); @@ -2014,6 +2028,18 @@ public class ModBlocks { pwr_controller = new MachinePWRController(Material.iron).setBlockName("pwr_controller").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":pwr_casing_blank"); pwr_block = new BlockPWR(Material.iron).setBlockName("pwr_block").setHardness(5.0F).setResistance(10.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":pwr_block"); + vver_fuel = new BlockPillarVVER(Material.iron, RefStrings.MODID + ":vver_fuel_top").setBlockName("vver_fuel").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_fuel_side"); + vver_control = new BlockPillarVVER(Material.iron, RefStrings.MODID + ":vver_control_top").setBlockName("vver_control").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_control_side"); + vver_channel = new BlockPillarVVER(Material.iron, RefStrings.MODID + ":vver_channel_top").setBlockName("vver_channel").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_channel_side"); + vver_heatex = new BlockGenericVVER(Material.iron).setBlockName("vver_heatex").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_heatex"); + vver_heatsink = new BlockGenericVVER(Material.iron).setBlockName("vver_heatsink").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_heatsink"); + vver_neutron_source = new BlockGenericVVER(Material.iron).setBlockName("vver_neutron_source").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_neutron_source"); + vver_reflector = new BlockGenericVVER(Material.iron).setBlockName("vver_reflector").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_reflector"); + vver_casing = new BlockGenericVVER(Material.iron).setBlockName("vver_casing").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_casing"); + vver_port = new BlockGenericVVER(Material.iron).setBlockName("vver_port").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_port"); + vver_controller = new MachineVVERController(Material.iron).setBlockName("vver_controller").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vver_casing_blank"); + vver_block = new BlockVVER(Material.iron).setBlockName("vver_block").setHardness(5.0F).setResistance(10.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":vver_block"); + fusion_conductor = new BlockToolConversionPillar(Material.iron).addVariant("_welded").setBlockName("fusion_conductor").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":fusion_conductor"); fusion_center = new BlockPillar(Material.iron, RefStrings.MODID + ":fusion_center_top_alt").setBlockName("fusion_center").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":fusion_center_side_alt"); fusion_motor = new BlockPillar(Material.iron, RefStrings.MODID + ":fusion_motor_top_alt").setBlockName("fusion_motor").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":fusion_motor_side_alt"); @@ -2857,6 +2883,7 @@ public class ModBlocks { GameRegistry.registerBlock(nuke_gadget, nuke_gadget.getUnlocalizedName()); GameRegistry.registerBlock(nuke_boy, nuke_boy.getUnlocalizedName()); GameRegistry.registerBlock(nuke_man, nuke_man.getUnlocalizedName()); + GameRegistry.registerBlock(nuke_mk3, nuke_mk3.getUnlocalizedName()); GameRegistry.registerBlock(nuke_mike, nuke_mike.getUnlocalizedName()); GameRegistry.registerBlock(nuke_tsar, nuke_tsar.getUnlocalizedName()); GameRegistry.registerBlock(nuke_prototype, ItemPrototypeBlock.class, nuke_prototype.getUnlocalizedName()); @@ -3354,6 +3381,19 @@ public class ModBlocks { register(pwr_controller); register(pwr_block); + //VVER!!! + register(vver_fuel); + register(vver_control); + register(vver_channel); + register(vver_heatex); + register(vver_heatsink); + register(vver_neutron_source); + register(vver_reflector); + register(vver_casing); + register(vver_port); + register(vver_controller); + register(vver_block); + //Multiblock Generators register(fusion_conductor); GameRegistry.registerBlock(fusion_center, fusion_center.getUnlocalizedName()); diff --git a/src/main/java/com/hbm/blocks/bomb/NukeMk3.java b/src/main/java/com/hbm/blocks/bomb/NukeMk3.java new file mode 100644 index 000000000..ed0c22cb6 --- /dev/null +++ b/src/main/java/com/hbm/blocks/bomb/NukeMk3.java @@ -0,0 +1,184 @@ +package com.hbm.blocks.bomb; + +import java.util.Random; + +import com.hbm.blocks.ModBlocks; +import com.hbm.config.BombConfig; +import com.hbm.entity.effect.EntityNukeTorex; +import com.hbm.entity.logic.EntityNukeExplosionMK5; +import com.hbm.interfaces.IBomb; +import com.hbm.main.MainRegistry; +import com.hbm.tileentity.bomb.TileEntityNukeMk3; + +import cpw.mods.fml.common.network.internal.FMLNetworkHandler; +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +public class NukeMk3 extends BlockContainer implements IBomb { + + public TileEntityNukeMk3 tetn = new TileEntityNukeMk3(); + + private final Random field_149933_a = new Random(); + private static boolean keepInventory = false; + + public NukeMk3(Material p_i45386_1_) { + super(p_i45386_1_); + } + + @Override + public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) { + return new TileEntityNukeMk3(); + + } + + @Override + public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) { + return Item.getItemFromBlock(ModBlocks.nuke_man); + } + + @Override + public void breakBlock(World p_149749_1_, int p_149749_2_, int p_149749_3_, int p_149749_4_, Block p_149749_5_, int p_149749_6_) { + if(!keepInventory) { + TileEntityNukeMk3 tileentityfurnace = (TileEntityNukeMk3) p_149749_1_.getTileEntity(p_149749_2_, p_149749_3_, p_149749_4_); + + if(tileentityfurnace != null) { + for(int i1 = 0; i1 < tileentityfurnace.getSizeInventory(); ++i1) { + ItemStack itemstack = tileentityfurnace.getStackInSlot(i1); + + if(itemstack != null) { + float f = this.field_149933_a.nextFloat() * 0.8F + 0.1F; + float f1 = this.field_149933_a.nextFloat() * 0.8F + 0.1F; + float f2 = this.field_149933_a.nextFloat() * 0.8F + 0.1F; + + while(itemstack.stackSize > 0) { + int j1 = this.field_149933_a.nextInt(21) + 10; + + if(j1 > itemstack.stackSize) { + j1 = itemstack.stackSize; + } + + itemstack.stackSize -= j1; + EntityItem entityitem = new EntityItem(p_149749_1_, p_149749_2_ + f, p_149749_3_ + f1, p_149749_4_ + f2, new ItemStack(itemstack.getItem(), j1, itemstack.getItemDamage())); + + if(itemstack.hasTagCompound()) { + entityitem.getEntityItem().setTagCompound((NBTTagCompound) itemstack.getTagCompound().copy()); + } + + float f3 = 0.05F; + entityitem.motionX = (float) this.field_149933_a.nextGaussian() * f3; + entityitem.motionY = (float) this.field_149933_a.nextGaussian() * f3 + 0.2F; + entityitem.motionZ = (float) this.field_149933_a.nextGaussian() * f3; + p_149749_1_.spawnEntityInWorld(entityitem); + } + } + } + + p_149749_1_.func_147453_f(p_149749_2_, p_149749_3_, p_149749_4_, p_149749_5_); + } + } + + super.breakBlock(p_149749_1_, p_149749_2_, p_149749_3_, p_149749_4_, p_149749_5_, p_149749_6_); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + if(world.isRemote) { + return true; + } else if(!player.isSneaking()) { + TileEntityNukeMk3 entity = (TileEntityNukeMk3) world.getTileEntity(x, y, z); + if(entity != null) { + FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z); + } + return true; + } else { + return false; + } + } + + @Override + public void onNeighborBlockChange(World p_149695_1_, int x, int y, int z, Block p_149695_5_) { + TileEntityNukeMk3 entity = (TileEntityNukeMk3) p_149695_1_.getTileEntity(x, y, z); + if(p_149695_1_.isBlockIndirectlyGettingPowered(x, y, z) && !p_149695_1_.isRemote) { + if(entity.isReady()) { + this.onBlockDestroyedByPlayer(p_149695_1_, x, y, z, 1); + entity.clearSlots(); + p_149695_1_.setBlockToAir(x, y, z); + igniteTestBomb(p_149695_1_, x, y, z); + } + } + } + + public boolean igniteTestBomb(World world, int x, int y, int z) { + if(!world.isRemote) { + tetn.clearSlots(); + world.playSoundEffect(x, y, z, "random.explode", 1.0f, world.rand.nextFloat() * 0.1F + 0.9F); + + world.spawnEntityInWorld(EntityNukeExplosionMK5.statFac(world, BombConfig.manRadius, x + 0.5, y + 0.5, z + 0.5)); + EntityNukeTorex.statFac(world, x + 0.5, y + 0.5, z + 0.5, BombConfig.manRadius); + } + + return false; + } + + @Override + public int getRenderType() { + return -1; + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public boolean renderAsNormalBlock() { + return false; + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { + int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; + + if(i == 0) { + world.setBlockMetadataWithNotify(x, y, z, 5, 2); + } + if(i == 1) { + world.setBlockMetadataWithNotify(x, y, z, 3, 2); + } + if(i == 2) { + world.setBlockMetadataWithNotify(x, y, z, 4, 2); + } + if(i == 3) { + world.setBlockMetadataWithNotify(x, y, z, 2, 2); + } + } + + @Override + public BombReturnCode explode(World world, int x, int y, int z) { + + if(!world.isRemote) { + TileEntityNukeMk3 entity = (TileEntityNukeMk3) world.getTileEntity(x, y, z); + if(entity.isReady()) { + this.onBlockDestroyedByPlayer(world, x, y, z, 1); + entity.clearSlots(); + world.setBlockToAir(x, y, z); + igniteTestBomb(world, x, y, z); + return BombReturnCode.DETONATED; + } + + return BombReturnCode.ERROR_MISSING_COMPONENT; + } + + return BombReturnCode.UNDEFINED; + } +} diff --git a/src/main/java/com/hbm/blocks/machine/BlockGenericVVER.java b/src/main/java/com/hbm/blocks/machine/BlockGenericVVER.java new file mode 100644 index 000000000..afcf97409 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/BlockGenericVVER.java @@ -0,0 +1,22 @@ +package com.hbm.blocks.machine; + +import java.util.List; + +import com.hbm.blocks.ITooltipProvider; +import com.hbm.blocks.generic.BlockGeneric; + +import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public class BlockGenericVVER extends BlockGeneric implements ITooltipProvider { + + public BlockGenericVVER(Material material) { + super(material); + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + this.addStandardInfo(stack, player, list, ext); + } +} diff --git a/src/main/java/com/hbm/blocks/machine/BlockPillarVVER.java b/src/main/java/com/hbm/blocks/machine/BlockPillarVVER.java new file mode 100644 index 000000000..02f809ebc --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/BlockPillarVVER.java @@ -0,0 +1,21 @@ +package com.hbm.blocks.machine; + +import java.util.List; + +import com.hbm.blocks.ITooltipProvider; + +import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public class BlockPillarVVER extends BlockPillar implements ITooltipProvider { + + public BlockPillarVVER(Material mat, String top) { + super(mat, top); + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + this.addStandardInfo(stack, player, list, ext); + } +} diff --git a/src/main/java/com/hbm/blocks/machine/BlockVVER.java b/src/main/java/com/hbm/blocks/machine/BlockVVER.java new file mode 100644 index 000000000..1af4aa73d --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/BlockVVER.java @@ -0,0 +1,341 @@ +package com.hbm.blocks.machine; + +import java.util.Random; + +import com.hbm.blocks.ModBlocks; +import com.hbm.inventory.fluid.FluidType; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.lib.RefStrings; +import com.hbm.render.block.ct.CT; +import com.hbm.render.block.ct.CTStitchReceiver; +import com.hbm.render.block.ct.IBlockCT; +import com.hbm.tileentity.machine.TileEntityVVERController; + +import api.hbm.fluidmk2.IFluidReceiverMK2; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class BlockVVER extends BlockContainer implements IBlockCT { + + @SideOnly(Side.CLIENT) protected IIcon iconPort; + + public BlockVVER(Material mat) { + super(mat); + } + + @Override + public int getRenderType() { + return CT.renderID; + } + + @Override + public Item getItemDropped(int i, Random rand, int j) { + return null; + } + + @SideOnly(Side.CLIENT) public CTStitchReceiver rec; + @SideOnly(Side.CLIENT) public CTStitchReceiver recPort; + + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister reg) { + super.registerBlockIcons(reg); + this.iconPort = reg.registerIcon(RefStrings.MODID + ":vver_casing_port"); + this.rec = IBlockCT.primeReceiver(reg, this.blockIcon.getIconName(), this.blockIcon); + this.recPort = IBlockCT.primeReceiver(reg, this.iconPort.getIconName(), this.iconPort); + } + + @Override + public IIcon[] getFragments(IBlockAccess world, int x, int y, int z) { + int meta = world.getBlockMetadata(x, y, z); + if(meta == 1) return recPort.fragCache; + return rec.fragCache; + } + + @Override + public boolean canConnect(IBlockAccess world, int x, int y, int z, Block block) { + return block == ModBlocks.vver_block || block == ModBlocks.vver_controller; + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityBlockVVER(); + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + + TileEntity tile = world.getTileEntity(x, y, z); + + if(tile instanceof TileEntityBlockVVER) { + TileEntityBlockVVER vver = (TileEntityBlockVVER) tile; + world.removeTileEntity(x, y, z); + if(vver.block != null) { + world.setBlock(x, y, z, vver.block); + TileEntity controller = world.getTileEntity(vver.coreX, vver.coreY, vver.coreZ); + + if(controller instanceof TileEntityVVERController) { + ((TileEntityVVERController) controller).assembled = false; + } + } + } else { + world.removeTileEntity(x, y, z); + } + super.breakBlock(world, x, y, z, block, meta); + } + + public static class TileEntityBlockVVER extends TileEntity implements IFluidReceiverMK2, ISidedInventory { + + public Block block; + public int coreX; + public int coreY; + public int coreZ; + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + + if(worldObj.getTotalWorldTime() % 20 == 0 && block != null) { + + TileEntityVVERController controller = getCore(); + + if(controller != null) { + if(!controller.assembled) { + this.getBlockType().breakBlock(worldObj, xCoord, yCoord, zCoord, this.getBlockType(), this.getBlockMetadata()); + } + } else if(worldObj.getChunkProvider().chunkExists(coreX >> 4, coreZ >> 4)) { + this.getBlockType().breakBlock(worldObj, xCoord, yCoord, zCoord, this.getBlockType(), this.getBlockMetadata()); + } + } + } + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + + block = Block.getBlockById(nbt.getInteger("block")); + if(block != Blocks.air) { + coreX = nbt.getInteger("cX"); + coreY = nbt.getInteger("cY"); + coreZ = nbt.getInteger("cZ"); + } else { + block = null; + } + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + + if(block != null) { + nbt.setInteger("block", Block.getIdFromBlock(block)); + nbt.setInteger("cX", coreX); + nbt.setInteger("cY", coreY); + nbt.setInteger("cZ", coreZ); + } + } + + @Override + public void markDirty() { + if(this.worldObj != null) { + this.worldObj.markTileEntityChunkModified(this.xCoord, this.yCoord, this.zCoord, this); + } + } + + public TileEntityVVERController cachedCore; + + protected TileEntityVVERController getCore() { + + if(cachedCore != null && !cachedCore.isInvalid()) return cachedCore; + + if(worldObj.getChunkProvider().chunkExists(coreX >> 4, coreZ >> 4)) { + + TileEntity tile = worldObj.getTileEntity(coreX, coreY, coreZ); + if(tile instanceof TileEntityVVERController) { + TileEntityVVERController controller = (TileEntityVVERController) tile; + cachedCore = controller; + return controller; + } + } + + return null; + } + + @Override + public long transferFluid(FluidType type, int pressure, long fluid) { + + if(this.getBlockMetadata() != 1) return fluid; + if(block == null) return fluid; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.transferFluid(type, pressure, fluid); + + return fluid; + } + + @Override + public long getDemand(FluidType type, int pressure) { + if(this.getBlockMetadata() != 1) return 0; + if(block == null) return 0; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.getDemand(type, pressure); + return 0; + } + + @Override + public FluidTank[] getAllTanks() { + if(this.getBlockMetadata() != 1) return FluidTank.EMPTY_ARRAY; + if(block == null) return FluidTank.EMPTY_ARRAY; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.getAllTanks(); + return FluidTank.EMPTY_ARRAY; + } + + @Override + public boolean canConnect(FluidType type, ForgeDirection dir) { + return this.getBlockMetadata() == 1; + } + + @Override + public int getSizeInventory() { + + if(this.getBlockMetadata() != 1) return 0; + if(block == null) return 0; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.getSizeInventory(); + + return 0; + } + + @Override + public ItemStack getStackInSlot(int slot) { + + if(this.getBlockMetadata() != 1) return null; + if(block == null) return null; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.getStackInSlot(slot); + + return null; + } + + @Override + public ItemStack decrStackSize(int slot, int amount) { + + if(this.getBlockMetadata() != 1) return null; + if(block == null) return null; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.decrStackSize(slot, amount); + + return null; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + + if(this.getBlockMetadata() != 1) return null; + if(block == null) return null; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.getStackInSlotOnClosing(slot); + + return null; + } + + @Override + public void setInventorySlotContents(int slot, ItemStack stack) { + + if(this.getBlockMetadata() != 1) return; + if(block == null) return; + TileEntityVVERController controller = this.getCore(); + if(controller != null) controller.setInventorySlotContents(slot, stack); + } + + @Override + public int getInventoryStackLimit() { + + if(this.getBlockMetadata() != 1) return 0; + if(block == null) return 0; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.getInventoryStackLimit(); + + return 0; + } + + @Override public boolean isUseableByPlayer(EntityPlayer player) { return false; } + @Override public void openInventory() { } + @Override public void closeInventory() { } + @Override public String getInventoryName() { return ""; } + @Override public boolean hasCustomInventoryName() { return false; } + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + + if(this.getBlockMetadata() != 1) return false; + if(block == null) return false; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.isItemValidForSlot(slot, stack); + + return false; + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + + if(this.getBlockMetadata() != 1) return new int[0]; + if(block == null) return new int[0]; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.getAccessibleSlotsFromSide(side); + + return new int[0]; + } + + @Override + public boolean canInsertItem(int slot, ItemStack stack, int side) { + + if(this.getBlockMetadata() != 1) return false; + if(block == null) return false; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.canInsertItem(slot, stack, side); + + return false; + } + + @Override + public boolean canExtractItem(int slot, ItemStack stack, int side) { + + if(this.getBlockMetadata() != 1) return false; + if(block == null) return false; + TileEntityVVERController controller = this.getCore(); + if(controller != null) return controller.canExtractItem(slot, stack, side); + + return false; + } + + public boolean isLoaded = true; + + @Override + public boolean isLoaded() { + return isLoaded; + } + + @Override + public void onChunkUnload() { + super.onChunkUnload(); + this.isLoaded = false; + } + } +} diff --git a/src/main/java/com/hbm/blocks/machine/MachineVVERController.java b/src/main/java/com/hbm/blocks/machine/MachineVVERController.java new file mode 100644 index 000000000..2ba88f511 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/MachineVVERController.java @@ -0,0 +1,222 @@ +package com.hbm.blocks.machine; + +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import com.hbm.blocks.ITooltipProvider; +import com.hbm.blocks.ModBlocks; +import com.hbm.blocks.machine.BlockVVER.TileEntityBlockVVER; +import com.hbm.handler.threading.PacketThreading; +import com.hbm.lib.RefStrings; +import com.hbm.main.MainRegistry; +import com.hbm.packet.toclient.AuxParticlePacketNT; +import com.hbm.tileentity.machine.TileEntityVVERController; +import com.hbm.util.fauxpointtwelve.BlockPos; + +import cpw.mods.fml.common.network.internal.FMLNetworkHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class MachineVVERController extends BlockContainer implements ITooltipProvider { + + @SideOnly(Side.CLIENT) + private IIcon iconFront; + + public MachineVVERController(Material mat) { + super(mat); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityVVERController(); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister iconRegister) { + super.registerBlockIcons(iconRegister); + this.iconFront = iconRegister.registerIcon(RefStrings.MODID + ":vver_controller"); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int metadata) { + return metadata == 0 && side == 3 ? this.iconFront : (side == metadata ? this.iconFront : this.blockIcon); + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { + int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; + + if(i == 0) world.setBlockMetadataWithNotify(x, y, z, 2, 2); + if(i == 1) world.setBlockMetadataWithNotify(x, y, z, 5, 2); + if(i == 2) world.setBlockMetadataWithNotify(x, y, z, 3, 2); + if(i == 3) world.setBlockMetadataWithNotify(x, y, z, 4, 2); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + + if(world.isRemote) { + return true; + } else if(!player.isSneaking()) { + + TileEntityVVERController controller = (TileEntityVVERController) world.getTileEntity(x, y, z); + + if(!controller.assembled) { + assemble(world, x, y, z, player); + } else { + FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z); + } + + return true; + } else { + return false; + } + } + + private static HashMap assembly = new HashMap(); + private static HashMap fuelRods = new HashMap(); + private static HashMap sources = new HashMap(); + private static boolean errored; + private static final int maxSize = 4096; + + public void assemble(World world, int x, int y, int z, EntityPlayer player) { + assembly.clear(); + fuelRods.clear(); + sources.clear(); + assembly.put(new BlockPos(x, y, z), this); + + ForgeDirection dir = ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z)).getOpposite(); + + errored = false; + floodFill(world, x + dir.offsetX, y, z + dir.offsetZ, player); + + if(fuelRods.size() == 0){ + sendError(world, x, y, z, "Fuel rods required", player); + errored = true; + } + + if(sources.size() == 0) { + sendError(world, x, y, z, "Neutron sources required", player); + errored = true; + } + + TileEntityVVERController controller = (TileEntityVVERController) world.getTileEntity(x, y, z); + + if(!errored) { + for(Entry entry : assembly.entrySet()) { + + BlockPos pos = entry.getKey(); + Block block = entry.getValue(); + + if(block != ModBlocks.vver_controller) { + + if(block == ModBlocks.vver_port) { + world.setBlock(pos.getX(), pos.getY(), pos.getZ(), ModBlocks.vver_block, 1, 3); + } else { + world.setBlock(pos.getX(), pos.getY(), pos.getZ(), ModBlocks.vver_block, 0, 3); + } + + TileEntityBlockVVER vver = (TileEntityBlockVVER) world.getTileEntity(pos.getX(), pos.getY(), pos.getZ()); + vver.block = block; + vver.coreX = x; + vver.coreY = y; + vver.coreZ = z; + vver.markDirty(); + } + } + + controller.setup(assembly, fuelRods); + } + controller.assembled = !errored; + + assembly.clear(); + fuelRods.clear(); + sources.clear(); + } + + private void floodFill(World world, int x, int y, int z, EntityPlayer player) { + + BlockPos pos = new BlockPos(x, y, z); + + if(assembly.containsKey(pos)) return; + if(assembly.size() >= maxSize) { + errored = true; + sendError(world, x, y, z, "Max size exceeded", player); + return; + } + + Block block = world.getBlock(x, y, z); + + if(isValidCasing(block)) { + assembly.put(pos, block); + return; + } + + if(isValidCore(block)) { + assembly.put(pos, block); + if(block == ModBlocks.vver_fuel) fuelRods.put(pos, block); + if(block == ModBlocks.vver_neutron_source) sources.put(pos, block); + floodFill(world, x + 1, y, z, player); + floodFill(world, x - 1, y, z, player); + floodFill(world, x, y + 1, z, player); + floodFill(world, x, y - 1, z, player); + floodFill(world, x, y, z + 1, player); + floodFill(world, x, y, z - 1, player); + return; + } + + sendError(world, x, y, z, "Non-reactor block", player); + errored = true; + } + + private void sendError(World world, int x, int y, int z, String message, EntityPlayer player) { + + if(player instanceof EntityPlayerMP) { + NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "marker"); + data.setInteger("color", 0xff0000); + data.setInteger("expires", 5_000); + data.setDouble("dist", 128D); + if(message != null) data.setString("label", message); + PacketThreading.createSendToThreadedPacket(new AuxParticlePacketNT(data, x, y, z), (EntityPlayerMP) player); + } + } + + private boolean isValidCore(Block block) { + if(block == ModBlocks.vver_fuel || + block == ModBlocks.vver_control || + block == ModBlocks.vver_channel || + block == ModBlocks.vver_heatex || + block == ModBlocks.vver_heatsink || + block == ModBlocks.vver_neutron_source) + return true; + return false; + } + + private boolean isValidCasing(Block block) { + if(block == ModBlocks.vver_casing || block == ModBlocks.vver_reflector || block == ModBlocks.vver_port) return true; + return false; + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + this.addStandardInfo(stack, player, list, ext); + } +} diff --git a/src/main/java/com/hbm/crafting/RodRecipes.java b/src/main/java/com/hbm/crafting/RodRecipes.java index bd15c0322..a1c09e3e9 100644 --- a/src/main/java/com/hbm/crafting/RodRecipes.java +++ b/src/main/java/com/hbm/crafting/RodRecipes.java @@ -5,6 +5,7 @@ import com.hbm.items.ModItems; import com.hbm.items.machine.ItemBreedingRod.*; import com.hbm.items.machine.ItemCircuit.EnumCircuitType; import com.hbm.items.machine.ItemPWRFuel.EnumPWRFuel; +import com.hbm.items.machine.ItemVVERFuel.EnumVVERFuel; import com.hbm.items.machine.ItemWatzPellet.EnumWatzType; import com.hbm.items.machine.ItemZirnoxRod.EnumZirnoxType; import com.hbm.main.CraftingManager; @@ -155,6 +156,23 @@ public class RodRecipes { CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.pwr_fuel, EnumPWRFuel.HES327), new Object[] { "F", "I", "F", 'F', SA327.billet(), 'I', ModItems.plate_polymer }); CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.pwr_fuel, EnumPWRFuel.BFB_AM_MIX), new Object[] { "NFN", "NIN", "NBN", 'F', ModItems.billet_am_mix, 'I', ModItems.plate_polymer, 'B', BI.billet(), 'N', ModItems.nugget_plutonium_fuel }); CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.pwr_fuel, EnumPWRFuel.BFB_PU241), new Object[] { "NFN", "NIN", "NBN", 'F', PU241.billet(), 'I', ModItems.plate_polymer, 'B', BI.billet(), 'N', ModItems.nugget_uranium_fuel }); + + //VVER fuel!!! + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.MEU), new Object[] { "F", "I", "F", 'F', ModItems.billet_uranium_fuel, 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HEU233), new Object[] { "F", "I", "F", 'F', U233.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HEU235), new Object[] { "F", "I", "F", 'F', U235.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.MEN), new Object[] { "F", "I", "F", 'F', ModItems.billet_neptunium_fuel, 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HEN237), new Object[] { "F", "I", "F", 'F', NP237.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.MOX), new Object[] { "F", "I", "F", 'F', ModItems.billet_mox_fuel, 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.MEP), new Object[] { "F", "I", "F", 'F', ModItems.billet_pu_mix, 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HEP239), new Object[] { "F", "I", "F", 'F', PU239.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HEP241), new Object[] { "F", "I", "F", 'F', PU241.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.MEA), new Object[] { "F", "I", "F", 'F', ModItems.billet_am_mix, 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HEA242), new Object[] { "F", "I", "F", 'F', AM242.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HES326), new Object[] { "F", "I", "F", 'F', SA326.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.HES327), new Object[] { "F", "I", "F", 'F', SA327.billet(), 'I', IRON.plate() }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.BFB_AM_MIX), new Object[] { "NFN", "NIN", "NBN", 'F', ModItems.billet_am_mix, 'I', IRON.plate(), 'B', BI.billet(), 'N', ModItems.nugget_plutonium_fuel }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.vver_fuel, EnumVVERFuel.BFB_PU241), new Object[] { "NFN", "NIN", "NBN", 'F', PU241.billet(), 'I', IRON.plate(), 'B', BI.billet(), 'N', ModItems.nugget_uranium_fuel }); CraftingManager.addRecipeAuto(new ItemStack(ModItems.icf_pellet_empty), new Object[] { "ZLZ", "L L", "ZLZ", 'Z', ZR.wireFine(), 'L', PB.wireFine() }); } diff --git a/src/main/java/com/hbm/inventory/container/ContainerNukeMk3.java b/src/main/java/com/hbm/inventory/container/ContainerNukeMk3.java new file mode 100644 index 000000000..e89dae1f5 --- /dev/null +++ b/src/main/java/com/hbm/inventory/container/ContainerNukeMk3.java @@ -0,0 +1,77 @@ +package com.hbm.inventory.container; + +import com.hbm.tileentity.bomb.TileEntityNukeMk3; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class ContainerNukeMk3 extends Container { + +private TileEntityNukeMk3 nukeMan; + + public ContainerNukeMk3(InventoryPlayer invPlayer, TileEntityNukeMk3 tedf) { + + nukeMan = tedf; + + this.addSlotToContainer(new Slot(tedf, 0, 26, 35)); + this.addSlotToContainer(new Slot(tedf, 1, 8, 17)); + this.addSlotToContainer(new Slot(tedf, 2, 44, 17)); + this.addSlotToContainer(new Slot(tedf, 3, 8, 53)); + this.addSlotToContainer(new Slot(tedf, 4, 44, 53)); + this.addSlotToContainer(new Slot(tedf, 5, 98, 35)); + + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 9; j++) + { + this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for(int i = 0; i < 9; i++) + { + this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 142)); + } + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int par2) + { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) + { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 <= 5) { + if (!this.mergeItemStack(var5, 6, this.inventorySlots.size(), true)) + { + return null; + } + } else { + return null; + } + + if (var5.stackSize == 0) + { + var4.putStack((ItemStack) null); + } + else + { + var4.onSlotChanged(); + } + } + + return var3; + } + + @Override + public boolean canInteractWith(EntityPlayer player) { + return nukeMan.isUseableByPlayer(player); + } +} diff --git a/src/main/java/com/hbm/inventory/container/ContainerVVER.java b/src/main/java/com/hbm/inventory/container/ContainerVVER.java new file mode 100644 index 000000000..682792d0e --- /dev/null +++ b/src/main/java/com/hbm/inventory/container/ContainerVVER.java @@ -0,0 +1,75 @@ +package com.hbm.inventory.container; + +import com.hbm.inventory.SlotCraftingOutput; +import com.hbm.items.machine.IItemFluidIdentifier; +import com.hbm.tileentity.machine.TileEntityVVERController; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class ContainerVVER extends Container { + + TileEntityVVERController controller; + + public ContainerVVER(InventoryPlayer invPlayer, TileEntityVVERController controller) { + this.controller = controller; + + this.addSlotToContainer(new Slot(controller, 0, 53, 5)); + this.addSlotToContainer(new SlotCraftingOutput(invPlayer.player, controller, 1, 89, 32)); + this.addSlotToContainer(new Slot(controller, 2, 8, 59)); + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 9; j++) { + this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j * 18, 106 + i * 18)); + } + } + + for(int i = 0; i < 9; i++) { + this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 164)); + } + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if(var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if(par2 <= 2) { + if(!this.mergeItemStack(var5, 3, this.inventorySlots.size(), true)) { + return null; + } + } else { + + if(var3.getItem() instanceof IItemFluidIdentifier) { + if(!this.mergeItemStack(var5, 2, 3, false)) { + return null; + } + } else { + if(!this.mergeItemStack(var5, 0, 1, false)) { + return null; + } + } + } + + if(var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + } + + return var3; + } + + @Override + public boolean canInteractWith(EntityPlayer player) { + return controller.isUseableByPlayer(player); + } +} diff --git a/src/main/java/com/hbm/inventory/gui/GUINukeMk3.java b/src/main/java/com/hbm/inventory/gui/GUINukeMk3.java new file mode 100644 index 000000000..dc0a02e36 --- /dev/null +++ b/src/main/java/com/hbm/inventory/gui/GUINukeMk3.java @@ -0,0 +1,77 @@ +package com.hbm.inventory.gui; + +import org.lwjgl.opengl.GL11; + +import com.hbm.inventory.container.ContainerNukeMk3; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.bomb.TileEntityNukeMk3; +import com.hbm.util.I18nUtil; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.util.ResourceLocation; + +public class GUINukeMk3 extends GuiInfoContainer { + + private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/weapon/fatManSchematic.png"); + private TileEntityNukeMk3 testNuke; + + public GUINukeMk3(InventoryPlayer invPlayer, TileEntityNukeMk3 tedf) { + super(new ContainerNukeMk3(invPlayer, tedf)); + testNuke = tedf; + + this.xSize = 176; + this.ySize = 166; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float f) { + super.drawScreen(mouseX, mouseY, f); + + String[] descText = I18nUtil.resolveKeyArray("desc.gui.nukeMan.desc"); + this.drawCustomInfoStat(mouseX, mouseY, guiLeft - 16, guiTop + 16, 16, 16, guiLeft - 8, guiTop + 16 + 16, descText); + } + + @Override + protected void drawGuiContainerForegroundLayer( int i, int j) { + String name = this.testNuke.hasCustomInventoryName() ? this.testNuke.getInventoryName() : I18n.format(this.testNuke.getInventoryName()); + + this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752); + this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); + + if(testNuke.exp1()) + { + drawTexturedModalRect(guiLeft + 82, guiTop + 19, 176, 0, 24, 24); + } + + if(testNuke.exp2()) + { + drawTexturedModalRect(guiLeft + 106, guiTop + 19, 200, 0, 24, 24); + } + + if(testNuke.exp3()) + { + drawTexturedModalRect(guiLeft + 82, guiTop + 43, 176, 24, 24, 24); + } + + if(testNuke.exp4()) + { + drawTexturedModalRect(guiLeft + 106, guiTop + 43, 200, 24, 24, 24); + } + + if(testNuke.isReady()) + { + drawTexturedModalRect(guiLeft + 134, guiTop + 35, 176, 48, 16, 16); + } + + this.drawInfoPanel(guiLeft - 16, guiTop + 16, 16, 16, 2); + } +} diff --git a/src/main/java/com/hbm/inventory/gui/GUIVVER.java b/src/main/java/com/hbm/inventory/gui/GUIVVER.java new file mode 100644 index 000000000..75cb71911 --- /dev/null +++ b/src/main/java/com/hbm/inventory/gui/GUIVVER.java @@ -0,0 +1,199 @@ +package com.hbm.inventory.gui; + +import java.util.Locale; + +import org.apache.commons.lang3.math.NumberUtils; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +import com.hbm.inventory.container.ContainerVVER; +import com.hbm.items.ModItems; +import com.hbm.lib.RefStrings; +import com.hbm.packet.PacketDispatcher; +import com.hbm.packet.toserver.NBTControlPacket; +import com.hbm.render.util.GaugeUtil; +import com.hbm.tileentity.machine.TileEntityVVERController; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; + +public class GUIVVER extends GuiInfoContainer { + + protected TileEntityVVERController controller; + private final ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/reactors/gui_pwr.png"); + + private GuiTextField field; + + public GUIVVER(InventoryPlayer inventory, TileEntityVVERController controller) { + super(new ContainerVVER(inventory, controller)); + this.controller = controller; + + this.xSize = 176; + this.ySize = 188; + } + + @Override + public void initGui() { + super.initGui(); + + Keyboard.enableRepeatEvents(true); + + this.field = new GuiTextField(this.fontRendererObj, guiLeft + 57, guiTop + 63, 30, 8); + this.field.setTextColor(0x00ff00); + this.field.setDisabledTextColour(0x008000); + this.field.setEnableBackgroundDrawing(false); + this.field.setMaxStringLength(3); + + this.field.setText((100 - controller.rodTarget) + ""); + } + + @Override + public void drawScreen(int x, int y, float interp) { + super.drawScreen(x, y, interp); + + this.drawCustomInfoStat(x, y, guiLeft + 115, guiTop + 31, 18, 18, x, y, new String[] { "Core: " + String.format(Locale.US, "%,d", controller.coreHeat) + " / " + String.format(Locale.US, "%,d", controller.coreHeatCapacity) + " TU" }); + this.drawCustomInfoStat(x, y, guiLeft + 151, guiTop + 31, 18, 18, x, y, new String[] { "Hull: " + String.format(Locale.US, "%,d", controller.hullHeat) + " / " + String.format(Locale.US, "%,d", controller.hullHeatCapacityBase) + " TU" }); + + this.drawCustomInfoStat(x, y, guiLeft + 52, guiTop + 31, 36, 18, x, y, new String[] { ((int) (controller.progress * 100 / controller.processTime)) + "%" }); + this.drawCustomInfoStat(x, y, guiLeft + 52, guiTop + 53, 54, 4, x, y, "Control rod level: " + (100 - (Math.round(controller.rodLevel * 100)/100)) + "%"); + + if(controller.typeLoaded != -1 && controller.amountLoaded > 0) { + ItemStack display = new ItemStack(ModItems.vver_fuel, 1, controller.typeLoaded); + if(guiLeft + 88 <= x && guiLeft + 88 + 18 > x && guiTop + 4 < y && guiTop + 4 + 18 >= y) this.renderToolTip(display, x, y); + } + + controller.tanks[0].renderTankInfo(this, x, y, guiLeft + 8, guiTop + 5, 16, 52); + controller.tanks[1].renderTankInfo(this, x, y, guiLeft + 26, guiTop + 5, 16, 52); + } + + @Override + protected void drawItemStack(ItemStack stack, int x, int y, String label) { + GL11.glPushMatrix(); + GL11.glTranslatef(0.0F, 0.0F, 32.0F); + this.zLevel = 200.0F; + itemRender.zLevel = 200.0F; + FontRenderer font = null; + if(stack != null) font = stack.getItem().getFontRenderer(stack); + if(font == null) font = fontRendererObj; + itemRender.renderItemAndEffectIntoGUI(font, this.mc.getTextureManager(), stack, x, y); + GL11.glScaled(0.5, 0.5, 0.5); + itemRender.renderItemOverlayIntoGUI(font, this.mc.getTextureManager(), stack, (x + font.getStringWidth(label) / 4) * 2, (y + 15) * 2, label); + this.zLevel = 0.0F; + itemRender.zLevel = 0.0F; + GL11.glPopMatrix(); + } + + @Override + protected void drawGuiContainerForegroundLayer(int i, int j) { + this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + + double scale = 1.25; + String flux = String.format(Locale.US, "%,.1f", controller.flux); + GL11.glScaled(1 / scale, 1 / scale, 1); + this.fontRendererObj.drawString(flux, (int) (165 * scale - this.fontRendererObj.getStringWidth(flux)), (int)(64 * scale), 0x00ff00); + GL11.glScaled(scale, scale, 1); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); + + if(controller.hullHeat > controller.hullHeatCapacityBase * 0.8 || controller.coreHeat > controller.coreHeatCapacity * 0.8) + drawTexturedModalRect(guiLeft + 147, guiTop, 176, 14, 26, 26); + + int p = (int) (controller.progress * 33 / controller.processTime); + drawTexturedModalRect(guiLeft + 54, guiTop + 33, 176, 0, p, 14); + + int c = (int) (controller.rodLevel * 52 / 100); + drawTexturedModalRect(guiLeft + 53, guiTop + 54, 176, 40, c, 2); + + //GaugeUtil.renderGauge(Gauge.ROUND_SMALL, guiLeft + 115, guiTop + 31, this.zLevel, (double) controller.coreHeat / (double) controller.coreHeatCapacity); + //GaugeUtil.renderGauge(Gauge.ROUND_SMALL, guiLeft + 151, guiTop + 31, this.zLevel, (double) controller.hullHeat / (double) controller.hullHeatCapacity); + + GaugeUtil.drawSmoothGauge(guiLeft + 124, guiTop + 40, this.zLevel, (double) controller.coreHeat / (double) controller.coreHeatCapacity, 5, 2, 1, 0x7F0000); + GaugeUtil.drawSmoothGauge(guiLeft + 160, guiTop + 40, this.zLevel, (double) controller.hullHeat / (double) controller.hullHeatCapacityBase, 5, 2, 1, 0x7F0000); + + if(controller.typeLoaded != -1 && controller.amountLoaded > 0) { + ItemStack display = new ItemStack(ModItems.vver_fuel, 1, controller.typeLoaded); + this.drawItemStack(display, guiLeft + 89, guiTop + 5, EnumChatFormatting.YELLOW + "" + controller.amountLoaded + "/" + controller.rodCount); + RenderHelper.enableGUIStandardItemLighting(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + GL11.glDisable(GL11.GL_LIGHTING); + + controller.tanks[0].renderTank(guiLeft + 8, guiTop + 57, this.zLevel, 16, 52); + controller.tanks[1].renderTank(guiLeft + 26, guiTop + 57, this.zLevel, 16, 52); + + this.field.drawTextBox(); + } + + /*private void drawGauge(int x, int y, double d) { + GL11.glDisable(GL11.GL_TEXTURE_2D); + + d = MathHelper.clamp_double(d, 0, 1); + + float angle = (float) Math.toRadians(-d * 270 - 45); + Vec3 tip = Vec3.createVectorHelper(0, 5, 0); + Vec3 left = Vec3.createVectorHelper(1, -2, 0); + Vec3 right = Vec3.createVectorHelper(-1, -2, 0); + + tip.rotateAroundZ(angle); + left.rotateAroundZ(angle); + right.rotateAroundZ(angle); + + Tessellator tess = Tessellator.instance; + tess.startDrawing(GL11.GL_TRIANGLES); + tess.setColorOpaque_F(0F, 0F, 0F); + double mult = 1.5; + tess.addVertex(x + tip.xCoord * mult, y + tip.yCoord * mult, this.zLevel); + tess.addVertex(x + left.xCoord * mult, y + left.yCoord * mult, this.zLevel); + tess.addVertex(x + right.xCoord * mult, y + right.yCoord * mult, this.zLevel); + tess.setColorOpaque_F(0.75F, 0F, 0F); + tess.addVertex(x + tip.xCoord, y + tip.yCoord, this.zLevel); + tess.addVertex(x + left.xCoord, y + left.yCoord, this.zLevel); + tess.addVertex(x + right.xCoord, y + right.yCoord, this.zLevel); + tess.draw(); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(GL11.GL_TEXTURE_2D); + }*/ + + @Override + protected void mouseClicked(int mouseX, int mouseY, int i) { + super.mouseClicked(mouseX, mouseY, i); + this.field.mouseClicked(mouseX, mouseY, i); + + if(guiLeft + 88 <= mouseX && guiLeft + 88 + 18 > mouseX && guiTop + 58 < mouseY && guiTop + 58 + 18 >= mouseY) { + + if(NumberUtils.isNumber(field.getText())) { + int level = (int)MathHelper.clamp_double(Double.parseDouble(field.getText()), 0, 100); + field.setText(level + ""); + + NBTTagCompound control = new NBTTagCompound(); + control.setInteger("control", 100 - level); + PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(control, controller.xCoord, controller.yCoord, controller.zCoord)); + mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1F)); + + } + } + } + + @Override + protected void keyTyped(char c, int i) { + if(this.field.textboxKeyTyped(c, i)) return; + super.keyTyped(c, i); + } +} diff --git a/src/main/java/com/hbm/items/ModItems.java b/src/main/java/com/hbm/items/ModItems.java index a210bcb7b..1e00860b7 100644 --- a/src/main/java/com/hbm/items/ModItems.java +++ b/src/main/java/com/hbm/items/ModItems.java @@ -27,6 +27,7 @@ import com.hbm.items.machine.ItemRBMKRod.EnumBurnFunc; import com.hbm.items.machine.ItemRBMKRod.EnumDepleteFunc; import com.hbm.items.machine.ItemRTGPelletDepleted.DepletedRTGMaterial; import com.hbm.items.machine.ItemStamp.StampType; +import com.hbm.items.machine.ItemVVERFuel.EnumVVERFuel; import com.hbm.items.special.*; import com.hbm.items.special.ItemPlasticScrap.ScrapType; import com.hbm.items.tool.*; @@ -1048,6 +1049,10 @@ public class ModItems { public static Item pwr_fuel_hot; public static Item pwr_fuel_depleted; + public static Item vver_fuel; + public static Item vver_fuel_hot; + public static Item vver_fuel_depleted; + public static Item rbmk_lid; public static Item rbmk_lid_glass; public static Item rbmk_fuel_empty; @@ -3263,6 +3268,10 @@ public class ModItems { pwr_fuel_hot = new ItemEnumMulti(EnumPWRFuel.class, true, false).setUnlocalizedName("pwr_fuel_hot").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":pwr_fuel_hot"); pwr_fuel_depleted = new ItemEnumMulti(EnumPWRFuel.class, true, false).setUnlocalizedName("pwr_fuel_depleted").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":pwr_fuel_depleted"); + vver_fuel = new ItemVVERFuel().setUnlocalizedName("vver_fuel").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":pwr_fuel"); + vver_fuel_hot = new ItemEnumMulti(EnumVVERFuel.class, true, false).setUnlocalizedName("vver_fuel_hot").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":pwr_fuel_hot"); + vver_fuel_depleted = new ItemEnumMulti(EnumVVERFuel.class, true, false).setUnlocalizedName("vver_fuel_depleted").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":pwr_fuel_depleted"); + rbmk_lid = new ItemRBMKLid().setUnlocalizedName("rbmk_lid").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":rbmk_lid"); rbmk_lid_glass = new ItemRBMKLid().setUnlocalizedName("rbmk_lid_glass").setCreativeTab(MainRegistry.controlTab).setTextureName(RefStrings.MODID + ":rbmk_lid_glass"); @@ -6081,6 +6090,11 @@ public class ModItems { GameRegistry.registerItem(pwr_fuel_hot, pwr_fuel_hot.getUnlocalizedName()); GameRegistry.registerItem(pwr_fuel_depleted, pwr_fuel_depleted.getUnlocalizedName()); + //VVER Parts!!! + GameRegistry.registerItem(vver_fuel, vver_fuel.getUnlocalizedName()); + GameRegistry.registerItem(vver_fuel_hot, vver_fuel_hot.getUnlocalizedName()); + GameRegistry.registerItem(vver_fuel_depleted, vver_fuel_depleted.getUnlocalizedName()); + //RBMK parts GameRegistry.registerItem(rbmk_lid, rbmk_lid.getUnlocalizedName()); GameRegistry.registerItem(rbmk_lid_glass, rbmk_lid_glass.getUnlocalizedName()); diff --git a/src/main/java/com/hbm/items/machine/ItemVVERFuel.java b/src/main/java/com/hbm/items/machine/ItemVVERFuel.java new file mode 100644 index 000000000..7936713ca --- /dev/null +++ b/src/main/java/com/hbm/items/machine/ItemVVERFuel.java @@ -0,0 +1,64 @@ +package com.hbm.items.machine; + +import java.util.List; + +import com.hbm.items.ItemEnumMulti; +import com.hbm.util.EnumUtil; +import com.hbm.util.function.Function; +import com.hbm.util.function.Function.FunctionLogarithmic; +import com.hbm.util.function.Function.FunctionSqrt; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; + +public class ItemVVERFuel extends ItemEnumMulti { + + public ItemVVERFuel() { + super(EnumVVERFuel.class, true, true); + } + + public static enum EnumVVERFuel { + MEU( 05.0D, new FunctionLogarithmic(20 * 30).withDiv(2_500)), + HEU233( 07.5D, new FunctionSqrt(25)), + HEU235( 07.5D, new FunctionSqrt(22.5)), + MEN( 07.5D, new FunctionLogarithmic(22.5 * 30).withDiv(2_500)), + HEN237( 07.5D, new FunctionSqrt(27.5)), + MOX( 07.5D, new FunctionLogarithmic(20 * 30).withDiv(2_500)), + MEP( 07.5D, new FunctionLogarithmic(22.5 * 30).withDiv(2_500)), + HEP239( 10.0D, new FunctionSqrt(22.5)), + HEP241( 10.0D, new FunctionSqrt(25)), + MEA( 07.5D, new FunctionLogarithmic(25 * 30).withDiv(2_500)), + HEA242( 10.0D, new FunctionSqrt(25)), + HES326( 12.5D, new FunctionSqrt(27.5)), + HES327( 12.5D, new FunctionSqrt(30)), + BFB_AM_MIX( 2.5D, new FunctionSqrt(15), 250_000_000), + BFB_PU241( 2.5D, new FunctionSqrt(15), 250_000_000); + + public double yield = 1_000_000_000; + public double heatEmission; + public Function function; + + private EnumVVERFuel(double heatEmission, Function function, double yield) { + this.heatEmission = heatEmission; + this.function = function; + } + + private EnumVVERFuel(double heatEmission, Function function) { + this(heatEmission, function, 1_000_000_000); + } + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) { + + EnumVVERFuel num = EnumUtil.grabEnumSafely(EnumVVERFuel.class, stack.getItemDamage()); + + String color = EnumChatFormatting.GOLD + ""; + String reset = EnumChatFormatting.RESET + ""; + + list.add(color + "Heat per flux: " + reset + num.heatEmission + " TU"); + list.add(color + "Reaction function: " + reset + num.function.getLabelForFuel()); + list.add(color + "Fuel type: " + reset + num.function.getDangerFromFuel()); + } +} diff --git a/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java b/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java index 12bb77e7c..59312c43b 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java +++ b/src/main/java/com/hbm/items/weapon/sedna/ItemGunBaseNT.java @@ -124,8 +124,7 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IItemHUD { this.quality = quality; this.lastShot = new long[cfg.length]; for(int i = 0; i < cfg.length; i++) cfg[i].index = i; - if(quality == WeaponQuality.A_SIDE || quality == WeaponQuality.SPECIAL) this.setCreativeTab(MainRegistry.weaponTab); - if(quality == WeaponQuality.LEGENDARY || quality == WeaponQuality.SECRET) this.secrets.add(this); + this.setCreativeTab(MainRegistry.weaponTab); this.setTextureName(RefStrings.MODID + ":gun_darter"); } diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java b/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java index 09a925455..1ece832d9 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java @@ -26,9 +26,9 @@ public class GunFactory { public static void init() { /// AMMO ITEMS /// - ModItems.ammo_debug = new Item().setUnlocalizedName("ammo_debug").setTextureName(RefStrings.MODID + ":ammo_45"); + ModItems.ammo_debug = new Item().setUnlocalizedName("ammo_debug").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":ammo_45"); ModItems.ammo_standard = new ItemEnumMulti(EnumAmmo.class, true, true).setUnlocalizedName("ammo_standard").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":ammo_standard"); - ModItems.ammo_secret = new ItemEnumMulti(EnumAmmoSecret.class, true, true).setUnlocalizedName("ammo_secret").setCreativeTab(null).setTextureName(RefStrings.MODID + ":ammo_secret"); + ModItems.ammo_secret = new ItemEnumMulti(EnumAmmoSecret.class, true, true).setUnlocalizedName("ammo_secret").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":ammo_secret"); /// BULLLET CFGS /// ammo_debug = new BulletConfig().setItem(ModItems.ammo_debug).setSpread(0.01F).setRicochetAngle(45).setCasing(CASING44.clone().register("DEBUG0")); diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index f03f9289c..50ead0ce8 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -217,6 +217,7 @@ public class ClientProxy extends ServerProxy { ClientRegistry.bindTileEntitySpecialRenderer(TileEntityNukeSolinium.class, new RenderNukeSolinium()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityNukeN2.class, new RenderNukeN2()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityNukeMan.class, new RenderNukeMan()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityNukeMk3.class, new RenderNukeMk3()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityNukeBalefire.class, new RenderNukeFstbmb()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityBombMulti.class, new RenderBombMulti()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityNukeMike.class, new RenderNukeMike()); diff --git a/src/main/java/com/hbm/main/CraftingManager.java b/src/main/java/com/hbm/main/CraftingManager.java index b0b6b1405..cb1561fff 100644 --- a/src/main/java/com/hbm/main/CraftingManager.java +++ b/src/main/java/com/hbm/main/CraftingManager.java @@ -845,6 +845,17 @@ public class CraftingManager { addRecipeAuto(new ItemStack(ModBlocks.pwr_port, 1), new Object[] { "S", "C", "S", 'S', STEEL.plate(), 'C', ModBlocks.pwr_casing }); addRecipeAuto(new ItemStack(ModBlocks.pwr_neutron_source, 1), new Object[] { "LRL", "ZRZ", "LRL", 'L', PB.plate528(), 'R', ModItems.billet_ra226be, 'Z', ZR.plateCast() }); + addRecipeAuto(new ItemStack(ModBlocks.vver_fuel, 4), new Object[] { "LZL", "L L", "LZL", 'L', W.plate528(), 'Z', ZR.plateWelded() }); + addRecipeAuto(new ItemStack(ModBlocks.vver_control, 4), new Object[] { "SBS", "MBM", "SBS", 'S', STEEL.plate528(), 'B', CA.ingot(), 'M', ModItems.motor }); + addRecipeAuto(new ItemStack(ModBlocks.vver_channel, 4), new Object[] { "CPC", "BPB", "CPC", 'C', CU.ingot(), 'P', PB.pipe(), 'B', ANY_PLASTIC.ingot() }); + addRecipeAuto(new ItemStack(ModBlocks.vver_heatex, 4), new Object[] { "CSC", "SMS", "CSC", 'C', CU.plateCast(), 'S', PB.plate528(), 'M', ModItems.motor }); + addRecipeAuto(new ItemStack(ModBlocks.vver_heatsink, 4), new Object[] { "SCS", "CRC", "SCS", 'S', BIGMT.plateCast(), 'C', DURA.plate(), 'R', RUBBER.ingot() }); + addRecipeAuto(new ItemStack(ModBlocks.vver_reflector, 4), new Object[] { "RLR", "LSL", "RLR", 'R', OreDictManager.getReflector(), 'L', STEEL.plate528(), 'S', PB.plateCast() }); + addRecipeAuto(new ItemStack(ModBlocks.vver_casing, 4), new Object[] { "LCL", "CSC", "LCL", 'L', PB.plate528(), 'C', ANY_CONCRETE.any(), 'S', TI.plateCast() }); + addRecipeAuto(new ItemStack(ModBlocks.vver_controller, 1), new Object[] { "CPC", "PSP", "CPC", 'C', ModBlocks.vver_casing, 'P', ANY_PLASTIC.ingot(), 'S', !GeneralConfig.enableExpensiveMode ? DictFrame.fromOne(ModItems.circuit, EnumCircuitType.BASIC) : STEEL.heavyComp() }); + addRecipeAuto(new ItemStack(ModBlocks.vver_port, 1), new Object[] { "S", "C", "S", 'S', STEEL.plate(), 'C', ModBlocks.vver_casing }); + addRecipeAuto(new ItemStack(ModBlocks.vver_neutron_source, 1), new Object[] { "LRL", "ZRZ", "LRL", 'L', STEEL.plate528(), 'R', ModItems.billet_ra226be, 'Z', ZR.plateCast() }); + addRecipeAuto(new ItemStack(ModBlocks.deco_rbmk, 8), new Object[] { "R", 'R', ModBlocks.rbmk_blank }); addRecipeAuto(new ItemStack(ModBlocks.deco_rbmk_smooth, 1), new Object[] { "R", 'R', ModBlocks.deco_rbmk }); addRecipeAuto(new ItemStack(ModBlocks.rbmk_blank, 1), new Object[] { "RRR", "R R", "RRR", 'R', ModBlocks.deco_rbmk }); diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 4dff63e28..9bb287259 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -708,6 +708,7 @@ public class ResourceManager { public static final ResourceLocation bomb_gadget_tex = new ResourceLocation(RefStrings.MODID, "textures/models/bombs/gadget.png"); public static final ResourceLocation bomb_boy_tex = new ResourceLocation(RefStrings.MODID, "textures/models/lilboy.png"); public static final ResourceLocation bomb_man_tex = new ResourceLocation(RefStrings.MODID, "textures/models/FatMan.png"); + public static final ResourceLocation bomb_mk3_tex = new ResourceLocation(RefStrings.MODID, "textures/models/mk3.png"); public static final ResourceLocation bomb_mike_tex = new ResourceLocation(RefStrings.MODID, "textures/models/bombs/ivymike.png"); public static final ResourceLocation bomb_tsar_tex = new ResourceLocation(RefStrings.MODID, "textures/models/bombs/tsar.png"); public static final ResourceLocation bomb_prototype_tex = new ResourceLocation(RefStrings.MODID, "textures/models/Prototype.png"); diff --git a/src/main/java/com/hbm/render/tileentity/RenderNukeMk3.java b/src/main/java/com/hbm/render/tileentity/RenderNukeMk3.java new file mode 100644 index 000000000..d031ad71c --- /dev/null +++ b/src/main/java/com/hbm/render/tileentity/RenderNukeMk3.java @@ -0,0 +1,65 @@ +package com.hbm.render.tileentity; + +import org.lwjgl.opengl.GL11; + +import com.hbm.blocks.ModBlocks; +import com.hbm.main.ResourceManager; +import com.hbm.render.item.ItemRenderBase; + +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.item.Item; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.client.IItemRenderer; + +public class RenderNukeMk3 extends TileEntitySpecialRenderer implements IItemRendererProvider { + + @Override + public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f) { + GL11.glPushMatrix(); + GL11.glTranslated(x + 0.5D, y, z + 0.5D); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_CULL_FACE); + switch(tileEntity.getBlockMetadata()) { + case 3: GL11.glRotatef(90, 0F, 1F, 0F); break; + case 5: GL11.glRotatef(180, 0F, 1F, 0F); break; + case 2: GL11.glRotatef(270, 0F, 1F, 0F); break; + case 4: GL11.glRotatef(0, 0F, 1F, 0F); break; + } + + GL11.glShadeModel(GL11.GL_SMOOTH); + bindTexture(ResourceManager.bomb_mk3_tex); + ResourceManager.bomb_man.renderAll(); + GL11.glShadeModel(GL11.GL_FLAT); + + GL11.glEnable(GL11.GL_CULL_FACE); + + GL11.glPopMatrix(); + } + + @Override + public Item getItemForRenderer() { + return Item.getItemFromBlock(ModBlocks.nuke_mk3); + } + + @Override + public IItemRenderer getRenderer() { + return new ItemRenderBase() { + public void renderInventory() { + GL11.glTranslated(0, -2, 0); + GL11.glScaled(5, 5, 5); + } + + public void renderCommon() { + GL11.glRotated(180, 0, 1, 0); + GL11.glTranslated(-0.75, 0, 0); + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glDisable(GL11.GL_CULL_FACE); + bindTexture(ResourceManager.bomb_mk3_tex); + ResourceManager.bomb_man.renderAll(); + GL11.glEnable(GL11.GL_CULL_FACE); + 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 16b57c2ec..9cdabca1c 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -22,6 +22,7 @@ import com.hbm.blocks.generic.BlockWandLoot.TileEntityWandLoot; import com.hbm.blocks.generic.PartEmitter.TileEntityPartEmitter; import com.hbm.blocks.machine.BlockICF.TileEntityBlockICF; import com.hbm.blocks.machine.BlockPWR.TileEntityBlockPWR; +import com.hbm.blocks.machine.BlockVVER.TileEntityBlockVVER; import com.hbm.blocks.machine.Floodlight.TileEntityFloodlight; import com.hbm.blocks.machine.FloodlightBeam.TileEntityFloodlightBeam; import com.hbm.blocks.machine.MachineCapacitor.TileEntityCapacitor; @@ -237,6 +238,9 @@ public class TileMappings { put(TileEntityBlockPWR.class, "tileentity_block_pwr"); put(TileEntityPWRController.class, "tileentity_pwr_controller"); + put(TileEntityBlockVVER.class, "tileentity_block_vver"); + put(TileEntityVVERController.class, "tileentity_vver_controller"); + put(TileEntityData.class, "tileentity_data"); put(TileEntityWandLoot.class, "tileentity_wand_loot"); diff --git a/src/main/java/com/hbm/tileentity/bomb/TileEntityNukeMk3.java b/src/main/java/com/hbm/tileentity/bomb/TileEntityNukeMk3.java new file mode 100644 index 000000000..eb1c1dbc7 --- /dev/null +++ b/src/main/java/com/hbm/tileentity/bomb/TileEntityNukeMk3.java @@ -0,0 +1,254 @@ +package com.hbm.tileentity.bomb; + +import com.hbm.inventory.container.ContainerNukeMk3; +import com.hbm.inventory.gui.GUINukeMk3; +import com.hbm.items.ModItems; +import com.hbm.tileentity.IGUIProvider; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +public class TileEntityNukeMk3 extends TileEntity implements ISidedInventory, IGUIProvider { + + private ItemStack slots[]; + private String customName; + + public TileEntityNukeMk3() { + slots = new ItemStack[6]; + } + + @Override + public int getSizeInventory() { + return slots.length; + } + + @Override + public ItemStack getStackInSlot(int i) { + return slots[i]; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if(slots[i] != null) + { + if(slots[i].stackSize <= j) + { + ItemStack itemStack = slots[i]; + slots[i] = null; + return itemStack; + } + ItemStack itemStack1 = slots[i].splitStack(j); + if (slots[i].stackSize == 0) + { + slots[i] = null; + } + + return itemStack1; + } else { + return null; + } + } + + @Override + public ItemStack getStackInSlotOnClosing(int i) { + if(slots[i] != null) + { + ItemStack itemStack = slots[i]; + slots[i] = null; + return itemStack; + } else { + return null; + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemStack) { + slots[i] = itemStack; + if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) + { + itemStack.stackSize = getInventoryStackLimit(); + } + } + + @Override + public String getInventoryName() { + return this.hasCustomInventoryName() ? this.customName : "container.nukeMk3"; + } + + @Override + public boolean hasCustomInventoryName() { + return this.customName != null && this.customName.length() > 0; + } + + public void setCustomName(String name) { + this.customName = name; + } + + @Override + public int getInventoryStackLimit() { + return 1; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + if(worldObj.getTileEntity(xCoord, yCoord, zCoord) != this) + { + return false; + }else{ + return player.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <=64; + } + } + + @Override + public void openInventory() { + + } + + @Override + public void closeInventory() { + + } + + @Override + public boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_) { + return false; + } + + @Override + public int[] getAccessibleSlotsFromSide(int p_94128_1_) { + return new int[0]; + } + + @Override + public boolean canInsertItem(int i, ItemStack itemStack, int j) { + return this.isItemValidForSlot(i, itemStack); + } + + @Override + public boolean canExtractItem(int i, ItemStack itemStack, int j) { + return j != 0 || i != 1 || itemStack.getItem() == Items.bucket; + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + NBTTagList list = nbt.getTagList("items", 10); + slots = new ItemStack[getSizeInventory()]; + + for(int i = 0; i < list.tagCount(); i++) + { + NBTTagCompound nbt1 = list.getCompoundTagAt(i); + byte b0 = nbt1.getByte("slot"); + if(b0 >= 0 && b0 < slots.length) + { + slots[b0] = ItemStack.loadItemStackFromNBT(nbt1); + } + } + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + NBTTagList list = new NBTTagList(); + + for(int i = 0; i < slots.length; i++) + { + if(slots[i] != null) + { + NBTTagCompound nbt1 = new NBTTagCompound(); + nbt1.setByte("slot", (byte)i); + slots[i].writeToNBT(nbt1); + list.appendTag(nbt1); + } + } + nbt.setTag("items", list); + } + + public boolean exp1() { + if(this.slots[1] != null && this.slots[1].getItem() == ModItems.early_explosive_lenses) + { + return true; + } + + return false; + } + + public boolean exp2() { + if(this.slots[2] != null && this.slots[2].getItem() == ModItems.early_explosive_lenses) + { + return true; + } + + return false; + } + + public boolean exp3() { + if(this.slots[3] != null && this.slots[3].getItem() == ModItems.early_explosive_lenses) + { + return true; + } + + return false; + } + + public boolean exp4() { + if(this.slots[4] != null && this.slots[4].getItem() == ModItems.early_explosive_lenses) + { + return true; + } + + return false; + } + + public boolean isReady() { + if(this.exp1() == true && this.exp2() == true && this.exp3() == true && this.exp4() == true) + { + if(this.slots[0] != null && this.slots[5] != null && this.slots[0].getItem() == ModItems.man_igniter && slots[5].getItem() == ModItems.man_core) + { + return true; + } + } + + return false; + } + + public void clearSlots() { + for(int i = 0; i < slots.length; i++) + { + slots[i] = null; + } + } + + @Override + public AxisAlignedBB getRenderBoundingBox() { + return TileEntity.INFINITE_EXTENT_AABB; + } + + @Override + @SideOnly(Side.CLIENT) + public double getMaxRenderDistanceSquared() + { + return 65536.0D; + } + + @Override + public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new ContainerNukeMk3(player.inventory, this); + } + + @Override + @SideOnly(Side.CLIENT) + public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new GUINukeMk3(player.inventory, this); + } +} diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityVVERController.java b/src/main/java/com/hbm/tileentity/machine/TileEntityVVERController.java new file mode 100644 index 000000000..affb6d1f4 --- /dev/null +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityVVERController.java @@ -0,0 +1,631 @@ +package com.hbm.tileentity.machine; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import com.hbm.blocks.ModBlocks; +import com.hbm.handler.CompatHandler; +import com.hbm.interfaces.IControlReceiver; +import com.hbm.inventory.container.ContainerVVER; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.inventory.fluid.trait.FT_Heatable; +import com.hbm.inventory.fluid.trait.FT_PWRModerator; +import com.hbm.inventory.fluid.trait.FT_Heatable.HeatingStep; +import com.hbm.inventory.fluid.trait.FT_Heatable.HeatingType; +import com.hbm.inventory.gui.GUIVVER; +import com.hbm.items.ModItems; +import com.hbm.items.machine.ItemVVERFuel.EnumVVERFuel; +import com.hbm.main.MainRegistry; +import com.hbm.sound.AudioWrapper; +import com.hbm.tileentity.IGUIProvider; +import com.hbm.tileentity.TileEntityMachineBase; +import com.hbm.util.EnumUtil; +import com.hbm.util.fauxpointtwelve.BlockPos; + +import api.hbm.fluid.IFluidStandardTransceiver; +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import li.cil.oc.api.machine.Arguments; +import li.cil.oc.api.machine.Callback; +import li.cil.oc.api.machine.Context; +import li.cil.oc.api.network.SimpleComponent; +import net.minecraft.block.Block; +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.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")}) +public class TileEntityVVERController extends TileEntityMachineBase implements IGUIProvider, IControlReceiver, SimpleComponent, IFluidStandardTransceiver, CompatHandler.OCComponent { + + public FluidTank[] tanks; + public long coreHeat; + public static final long coreHeatCapacityBase = 10_000_000; + public long coreHeatCapacity = 10_000_000; + public long hullHeat; + public static final long hullHeatCapacityBase = 10_000_000; + public double flux; + + public double rodLevel = 100; + public double rodTarget = 100; + + public int typeLoaded; + public int amountLoaded; + public double progress; + public double processTime; + + public int rodCount; + public int connections; + public int connectionsControlled; + public int heatexCount; + public int heatsinkCount; + public int channelCount; + public int sourceCount; + + public int unloadDelay = 0; + public boolean assembled; + + private AudioWrapper audio; + + protected List ports = new ArrayList(); + protected List rods = new ArrayList(); + + public TileEntityVVERController() { + super(3); + + this.tanks = new FluidTank[2]; + this.tanks[0] = new FluidTank(Fluids.COOLANT, 128_000); + this.tanks[1] = new FluidTank(Fluids.COOLANT_HOT, 128_000); + } + + /** The initial creation of the reactor, does all the pre-calculation and whatnot */ + public void setup(HashMap partMap, HashMap rodMap) { + + rodCount = 0; + connections = 0; + connectionsControlled = 0; + heatexCount = 0; + channelCount = 0; + heatsinkCount = 0; + sourceCount = 0; + ports.clear(); + rods.clear(); + + int connectionsDouble = 0; + int connectionsControlledDouble = 0; + + for(Entry entry : partMap.entrySet()) { + Block block = entry.getValue(); + + if(block == ModBlocks.vver_fuel) rodCount++; + if(block == ModBlocks.vver_heatex) heatexCount++; + if(block == ModBlocks.vver_channel) channelCount++; + if(block == ModBlocks.vver_heatsink) heatsinkCount++; + if(block == ModBlocks.vver_neutron_source) sourceCount++; + if(block == ModBlocks.vver_port) ports.add(entry.getKey()); + } + + for(Entry entry : rodMap.entrySet()) { + BlockPos fuelPos = entry.getKey(); + + rods.add(fuelPos); + + for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { + + boolean controlled = false; + + for(int i = 1; i < 16; i++) { + BlockPos checkPos = fuelPos.offset(dir, i); + Block atPos = partMap.get(checkPos); + if(atPos == null || atPos == ModBlocks.vver_casing) break; + if(atPos == ModBlocks.vver_control) controlled = true; + if(atPos == ModBlocks.vver_fuel) { + if(controlled) { + connectionsControlledDouble++; + } else { + connectionsDouble++; + } + break; + } + if(atPos == ModBlocks.vver_reflector) { + if(controlled) { + connectionsControlledDouble += 2; + } else { + connectionsDouble += 2; + } + break; + } + } + } + } + + connections = connectionsDouble / 2; + connectionsControlled = connectionsControlledDouble / 2; + heatsinkCount = Math.min(heatsinkCount, 80); + + //switching this to int64 because after 2127 heatsinks the capacity exceeds the int32 which is well within the 4000+ threshold we are working with. oops! + this.coreHeatCapacity = this.coreHeatCapacityBase + this.heatsinkCount * (this.coreHeatCapacityBase / 20); + } + + @Override + public String getName() { + return "container.vverController"; + } + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + + this.tanks[0].setType(2, slots); + setupTanks(); + + if(unloadDelay > 0) unloadDelay--; + + int chunkX = xCoord >> 4; + int chunkZ = zCoord >> 4; + + //since fluid sources are often not within 1 chunk, we just do 2 chunks distance and call it a day + if(!worldObj.getChunkProvider().chunkExists(chunkX, chunkZ) || + !worldObj.getChunkProvider().chunkExists(chunkX + 2, chunkZ + 2) || + !worldObj.getChunkProvider().chunkExists(chunkX + 2, chunkZ - 2) || + !worldObj.getChunkProvider().chunkExists(chunkX - 2, chunkZ + 2) || + !worldObj.getChunkProvider().chunkExists(chunkX - 2, chunkZ - 2)) { + this.unloadDelay = 60; + } + + if(this.assembled) { + for(BlockPos pos : ports) { + for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { + BlockPos portPos = pos.offset(dir); + + if(tanks[1].getFill() > 0) this.sendFluid(tanks[1], worldObj, portPos.getX(), portPos.getY(), portPos.getZ(), dir); + if(worldObj.getTotalWorldTime() % 20 == 0) this.trySubscribe(tanks[0].getTankType(), worldObj, portPos.getX(), portPos.getY(), portPos.getZ(), dir); + } + } + + //only perform fission if the area has been loaded for 40 ticks or more + if(this.unloadDelay <= 0) { + + if((typeLoaded == -1 || amountLoaded <= 0) && slots[0] != null && slots[0].getItem() == ModItems.vver_fuel) { + typeLoaded = slots[0].getItemDamage(); + amountLoaded++; + this.decrStackSize(0, 1); + this.markChanged(); + } else if(slots[0] != null && slots[0].getItem() == ModItems.vver_fuel && slots[0].getItemDamage() == typeLoaded && amountLoaded < rodCount){ + amountLoaded++; + this.decrStackSize(0, 1); + this.markChanged(); + } + double diff = this.rodLevel - this.rodTarget; + if(diff < 1 && diff > -1) this.rodLevel = this.rodTarget; + if(this.rodTarget > this.rodLevel) this.rodLevel++; + if(this.rodTarget < this.rodLevel) this.rodLevel--; + + int newFlux = this.sourceCount * 20; + + if(typeLoaded != -1 && amountLoaded > 0) { + + EnumVVERFuel fuel = EnumUtil.grabEnumSafely(EnumVVERFuel.class, typeLoaded); + double usedRods = getTotalProcessMultiplier(); + double fluxPerRod = this.flux / this.rodCount; + double outputPerRod = fuel.function.effonix(fluxPerRod); + double totalOutput = outputPerRod * amountLoaded * usedRods; + double totalHeatOutput = totalOutput * fuel.heatEmission; + + this.coreHeat += totalHeatOutput; + newFlux += totalOutput; + + this.processTime = (int) fuel.yield; + this.progress += totalOutput; + + if(this.progress >= this.processTime) { + this.progress -= this.processTime; + + if(slots[1] == null) { + slots[1] = new ItemStack(ModItems.vver_fuel_hot, 1, typeLoaded); + } else if(slots[1].getItem() == ModItems.vver_fuel_hot && slots[1].getItemDamage() == typeLoaded && slots[1].stackSize < slots[1].getMaxStackSize()) { + slots[1].stackSize++; + } + + this.amountLoaded--; + this.markChanged(); + } + } + + if(this.amountLoaded <= 0) { + this.typeLoaded = -1; + } + + if(amountLoaded > rodCount) amountLoaded = rodCount; + + /* CORE COOLING */ + double coreCoolingApproachNum = getXOverE((double) this.heatexCount * 5 / (double) getRodCountForCoolant(), 2) / 2D; + long averageCoreHeat = (this.coreHeat + this.hullHeat) / 2; + this.coreHeat -= (coreHeat - averageCoreHeat) * coreCoolingApproachNum; + this.hullHeat -= (hullHeat - averageCoreHeat) * coreCoolingApproachNum; + + updateCoolant(); + + this.coreHeat *= 0.999D; + this.hullHeat *= 0.999D; + + this.flux = newFlux; + + if(tanks[0].getTankType().hasTrait(FT_PWRModerator.class) && tanks[0].getFill() > 0) { + this.flux *= tanks[0].getTankType().getTrait(FT_PWRModerator.class).getMultiplier(); + } + + if(this.coreHeat > this.coreHeatCapacity) { + meltDown(); + } + } else { + this.hullHeat = 0; + this.coreHeat = 0; + } + } + + this.networkPackNT(150); + } else { + + if(amountLoaded > 0) { + + if(audio == null) { + audio = createAudioLoop(); + audio.startSound(); + } else if(!audio.isPlaying()) { + audio = rebootAudio(audio); + } + + audio.updateVolume(getVolume(1F)); + audio.keepAlive(); + + } else { + + if(audio != null) { + audio.stopSound(); + audio = null; + } + } + } + } + + protected void meltDown() { + + worldObj.func_147480_a(xCoord, yCoord, zCoord, false); + + double x = 0; + double y = 0; + double z = 0; + + for(BlockPos pos : this.rods) { + Block b = worldObj.getBlock(pos.getX(), pos.getY(), pos.getZ()); + b.breakBlock(worldObj, pos.getX(), pos.getY(), pos.getZ(), b, worldObj.getBlockMetadata(pos.getX(), pos.getY(), pos.getZ())); + worldObj.setBlock(pos.getX(), pos.getY(), pos.getZ(), ModBlocks.corium_block, 5, 3); + + x += pos.getX() + 0.5; + y += pos.getY() + 0.5; + z += pos.getZ() + 0.5; + } + + x /= rods.size(); + y /= rods.size(); + z /= rods.size(); + + worldObj.newExplosion(null, x, y, z, 15F, true, true); + } + + @Override + public AudioWrapper createAudioLoop() { + return MainRegistry.proxy.getLoopedSound("hbm:block.reactorLoop", xCoord, yCoord, zCoord, 1F, 10F, 1.0F, 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; + } + } + + protected void updateCoolant() { + + FT_Heatable trait = tanks[0].getTankType().getTrait(FT_Heatable.class); + if(trait == null || trait.getEfficiency(HeatingType.PWR) <= 0) return; + + double coolingEff = (double) this.channelCount / (double) getRodCountForCoolant() * 0.1D; //10% cooling if numbers match + if(coolingEff > 1D) coolingEff = 1D; + + //no use in trying to convert everythin to long since the internal tanks would never even support operation like that, just cap the heat cycle count to prevent overflows in the math + int heatToUse = (int) Math.min(Math.min(this.hullHeat, (long) (this.hullHeat * coolingEff * trait.getEfficiency(HeatingType.PWR))), 2_000_000_000); + HeatingStep step = trait.getFirstStep(); + int coolCycles = tanks[0].getFill() / step.amountReq; + int hotCycles = (tanks[1].getMaxFill() - tanks[1].getFill()) / step.amountProduced; + int heatCycles = heatToUse / step.heatReq; + int cycles = Math.min(coolCycles, Math.min(hotCycles, heatCycles)); + + this.hullHeat -= step.heatReq * cycles; + this.tanks[0].setFill(tanks[0].getFill() - step.amountReq * cycles); + this.tanks[1].setFill(tanks[1].getFill() + step.amountProduced * cycles); + } + + protected int getRodCountForCoolant() { + return this.rodCount + (int) Math.ceil(this.heatsinkCount / 4D); + } + + @Override + public void serialize(ByteBuf buf) { + super.serialize(buf); + buf.writeInt(this.rodCount); + buf.writeLong(this.coreHeat); + buf.writeLong(this.hullHeat); + buf.writeDouble(this.flux); + buf.writeDouble(this.processTime); + buf.writeDouble(this.progress); + buf.writeInt(this.typeLoaded); + buf.writeInt(this.amountLoaded); + buf.writeDouble(this.rodLevel); + buf.writeDouble(this.rodTarget); + buf.writeLong(this.coreHeatCapacity); + tanks[0].serialize(buf); + tanks[1].serialize(buf); + } + + @Override + public void deserialize(ByteBuf buf) { + super.deserialize(buf); + this.rodCount = buf.readInt(); + this.coreHeat = buf.readLong(); + this.hullHeat = buf.readLong(); + this.flux = buf.readDouble(); + this.processTime = buf.readDouble(); + this.progress = buf.readDouble(); + this.typeLoaded = buf.readInt(); + this.amountLoaded = buf.readInt(); + this.rodLevel = buf.readDouble(); + this.rodTarget = buf.readDouble(); + this.coreHeatCapacity = buf.readLong(); + tanks[0].deserialize(buf); + tanks[1].deserialize(buf); + } + + protected void setupTanks() { + + FT_Heatable trait = tanks[0].getTankType().getTrait(FT_Heatable.class); + + if(trait == null || trait.getEfficiency(HeatingType.PWR) <= 0) { + tanks[0].setTankType(Fluids.NONE); + tanks[1].setTankType(Fluids.NONE); + return; + } + + tanks[1].setTankType(trait.getFirstStep().typeProduced); + } + + public double getTotalProcessMultiplier() { + double totalConnections = this.connections + this.connectionsControlled * (1D - (this.rodLevel / 100D)); + double connectionsEff = connectinFunc(totalConnections); + return connectionsEff; + } + + public double connectinFunc(double connections) { + return connections / 10D * (1D - getXOverE(connections, 300D)) + connections / 150D * getXOverE(connections, 300D); + } + + public double getXOverE(double x, double d) { + return 1 - Math.pow(Math.E, -x / d); + } + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + if(slot == 0) return stack.getItem() == ModItems.vver_fuel; + return false; + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + return new int[] {0, 1}; + } + + @Override + public boolean canExtractItem(int slot, ItemStack itemStack, int side) { + return slot == 1; + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + + tanks[0].readFromNBT(nbt, "t0"); + tanks[1].readFromNBT(nbt, "t1"); + + this.assembled = nbt.getBoolean("assembled"); + this.coreHeat = Math.max(nbt.getInteger("coreHeat"), nbt.getLong("coreHeatL")); + this.hullHeat = Math.max(nbt.getInteger("hullHeat"), nbt.getLong("hullHeatL")); + this.flux = nbt.getDouble("flux"); + this.rodLevel = nbt.getDouble("rodLevel"); + this.rodTarget = nbt.getDouble("rodTarget"); + this.typeLoaded = nbt.getInteger("typeLoaded"); + this.amountLoaded = nbt.getInteger("amountLoaded"); + this.progress = nbt.getDouble("progress"); + this.processTime = nbt.getDouble("processTime"); + this.coreHeatCapacity = Math.max(nbt.getInteger("coreHeatCapacity"), nbt.getLong("coreHeatCapacityL")); + if(this.coreHeatCapacity < this.coreHeatCapacityBase) this.coreHeatCapacity = this.coreHeatCapacityBase; + + this.rodCount = nbt.getInteger("rodCount"); + this.connections = nbt.getInteger("connections"); + this.connectionsControlled = nbt.getInteger("connectionsControlled"); + this.heatexCount = nbt.getInteger("heatexCount"); + this.channelCount = nbt.getInteger("channelCount"); + this.sourceCount = nbt.getInteger("sourceCount"); + this.heatsinkCount = nbt.getInteger("heatsinkCount"); + + ports.clear(); + int portCount = nbt.getInteger("portCount"); + for(int i = 0; i < portCount; i++) { + int[] port = nbt.getIntArray("p" + i); + ports.add(new BlockPos(port[0], port[1], port[2])); + } + + rods.clear(); + int rodCount = nbt.getInteger("rodCount"); + for(int i = 0; i < rodCount; i++) { + if(nbt.hasKey("r" + i)) { + int[] port = nbt.getIntArray("r" + i); + rods.add(new BlockPos(port[0], port[1], port[2])); + } + } + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + + tanks[0].writeToNBT(nbt, "t0"); + tanks[1].writeToNBT(nbt, "t1"); + + nbt.setBoolean("assembled", assembled); + nbt.setLong("coreHeatL", coreHeat); + nbt.setLong("hullHeatL", hullHeat); + nbt.setDouble("flux", flux); + nbt.setDouble("rodLevel", rodLevel); + nbt.setDouble("rodTarget", rodTarget); + nbt.setInteger("typeLoaded", typeLoaded); + nbt.setInteger("amountLoaded", amountLoaded); + nbt.setDouble("progress", progress); + nbt.setDouble("processTime", processTime); + nbt.setLong("coreHeatCapacityL", coreHeatCapacity); + + nbt.setInteger("rodCount", rodCount); + nbt.setInteger("connections", connections); + nbt.setInteger("connectionsControlled", connectionsControlled); + nbt.setInteger("heatexCount", heatexCount); + nbt.setInteger("channelCount", channelCount); + nbt.setInteger("sourceCount", sourceCount); + nbt.setInteger("heatsinkCount", heatsinkCount); + + nbt.setInteger("portCount", ports.size()); + for(int i = 0; i < ports.size(); i++) { + BlockPos pos = ports.get(i); + nbt.setIntArray("p" + i, new int[] { pos.getX(), pos.getY(), pos.getZ() }); + } + + nbt.setInteger("rodCount", rods.size()); + for(int i = 0; i < rods.size(); i++) { + BlockPos pos = rods.get(i); + nbt.setIntArray("r" + i, new int[] { pos.getX(), pos.getY(), pos.getZ() }); + } + } + + @Override + public boolean hasPermission(EntityPlayer player) { + return this.isUseableByPlayer(player); + } + + @Override + public void receiveControl(NBTTagCompound data) { + + if(data.hasKey("control")) { + this.rodTarget = MathHelper.clamp_int(data.getInteger("control"), 0, 100); + this.markChanged(); + } + } + + + // do some opencomputer stuff + @Override + @Optional.Method(modid = "OpenComputers") + public String getComponentName() { + return "ntm_vver_control"; + } + + @Callback(direct = true) + @Optional.Method(modid = "OpenComputers") + public Object[] getHeat(Context context, Arguments args) { + return new Object[] {coreHeat, hullHeat}; + } + + @Callback(direct = true) + @Optional.Method(modid = "OpenComputers") + public Object[] getFlux(Context context, Arguments args) { + return new Object[] {flux}; + } + + @Callback(direct = true) + @Optional.Method(modid = "OpenComputers") + public Object[] getLevel(Context context, Arguments args) { + return new Object[] {rodTarget, rodLevel}; + } + + @Callback(direct = true) + @Optional.Method(modid = "OpenComputers") + public Object[] getCoolantInfo(Context context, Arguments args) { + return new Object[] {tanks[0].getFill(), tanks[0].getMaxFill(), tanks[1].getFill(), tanks[1].getMaxFill()}; + } + + @Callback(direct = true) + @Optional.Method(modid = "OpenComputers") + public Object[] getFuelInfo(Context context, Arguments args) { + return new Object[] {amountLoaded, progress, processTime}; + } + + @Callback(direct = true) + @Optional.Method(modid = "OpenComputers") + public Object[] getInfo(Context context, Arguments args) { + return new Object[] {coreHeat, hullHeat, flux, rodTarget, rodLevel, amountLoaded, progress, processTime, tanks[0].getFill(), tanks[0].getMaxFill(), tanks[1].getFill(), tanks[1].getMaxFill()}; + } + + @Callback(direct = true, limit = 4) + @Optional.Method(modid = "OpenComputers") + public Object[] setLevel(Context context, Arguments args) { + rodTarget = MathHelper.clamp_double(args.checkDouble(0), 0, 100); + this.markChanged(); + return new Object[] {true}; + } + + @Override + public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new ContainerVVER(player.inventory, this); + } + + @Override + @SideOnly(Side.CLIENT) + public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new GUIVVER(player.inventory, this); + } + + @Override + public FluidTank[] getAllTanks() { + return tanks; + } + + @Override + public FluidTank[] getSendingTanks() { + return new FluidTank[] { tanks[1] }; + } + + @Override + public FluidTank[] getReceivingTanks() { + return new FluidTank[] { tanks[0] }; + } +} diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index def1974f6..ba2c1b94a 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -800,6 +800,7 @@ container.nukeFstbmb=Balefire Bomb container.nukeFurnace=Nuclear Powered Furnace container.nukeGadget=The Gadget container.nukeMan=Fat Man +container.nukeMk3=Mark 3 Nuclear Bomb container.nukeMike=Ivy Mike container.nukeN2=N² Mine container.nukeN45=N45 Naval Mine @@ -4091,6 +4092,51 @@ item.pwr_fuel_hot.men.name=Hot MEN PWR Fuel Rod item.pwr_fuel_hot.mep.name=Hot MEP PWR Fuel Rod item.pwr_fuel_hot.meu.name=Hot MEU PWR Fuel Rod item.pwr_fuel_hot.mox.name=Hot MOX PWR Fuel Rod +item.vver_fuel.bfb_am_mix.name=Fuel Grade Americium VVER BFB Rod +item.vver_fuel.bfb_pu241.name=Plutonium-241 VVER BFB Rod +item.vver_fuel.hea242.name=HEA-242 VVER Fuel Rod +item.vver_fuel.hen237.name=HEN-237 VVER Fuel Rod +item.vver_fuel.hep239.name=HEP-239 VVER Fuel Rod +item.vver_fuel.hep241.name=HEP-241 VVER Fuel Rod +item.vver_fuel.hes326.name=HES-326 VVER Fuel Rod +item.vver_fuel.hes327.name=HES-327 VVER Fuel Rod +item.vver_fuel.heu233.name=HEU-233 VVER Fuel Rod +item.vver_fuel.heu235.name=HEU-235 VVER Fuel Rod +item.vver_fuel.mea.name=MEA VVER Fuel Rod +item.vver_fuel.men.name=MEN VVER Fuel Rod +item.vver_fuel.mep.name=MEP VVER Fuel Rod +item.vver_fuel.meu.name=MEU VVER Fuel Rod +item.vver_fuel.mox.name=MOX VVER Fuel Rod +item.vver_fuel_depleted.bfb_am_mix.name=Depleted Fuel Grade Americium VVER BFB Rod +item.vver_fuel_depleted.bfb_pu241.name=Depleted Plutonium-241 VVER BFB Rod +item.vver_fuel_depleted.hea242.name=Depleted HEA-242 VVER Fuel Rod +item.vver_fuel_depleted.hen237.name=Depleted HEN-237 VVER Fuel Rod +item.vver_fuel_depleted.hep239.name=Depleted HEP-239 VVER Fuel Rod +item.vver_fuel_depleted.hep241.name=Depleted HEP-241 VVER Fuel Rod +item.vver_fuel_depleted.hes326.name=Depleted HES-326 VVER Fuel Rod +item.vver_fuel_depleted.hes327.name=Depleted HES-327 VVER Fuel Rod +item.vver_fuel_depleted.heu233.name=Depleted HEU-233 VVER Fuel Rod +item.vver_fuel_depleted.heu235.name=Depleted HEU-235 VVER Fuel Rod +item.vver_fuel_depleted.mea.name=Depleted MEA VVER Fuel Rod +item.vver_fuel_depleted.men.name=Depleted MEN VVER Fuel Rod +item.vver_fuel_depleted.mep.name=Depleted MEP VVER Fuel Rod +item.vver_fuel_depleted.meu.name=Depleted MEU VVER Fuel Rod +item.vver_fuel_depleted.mox.name=Depleted MOX VVER Fuel Rod +item.vver_fuel_hot.bfb_am_mix.name=Hot Fuel Grade Americium VVER BFB Rod +item.vver_fuel_hot.bfb_pu241.name=Hot Plutonium-241 VVER BFB Rod +item.vver_fuel_hot.hea242.name=Hot HEA-242 VVER Fuel Rod +item.vver_fuel_hot.hen237.name=Hot HEN-237 VVER Fuel Rod +item.vver_fuel_hot.hep239.name=Hot HEP-239 VVER Fuel Rod +item.vver_fuel_hot.hep241.name=Hot HEP-241 VVER Fuel Rod +item.vver_fuel_hot.hes326.name=Hot HES-326 VVER Fuel Rod +item.vver_fuel_hot.hes327.name=Hot HES-327 VVER Fuel Rod +item.vver_fuel_hot.heu233.name=Hot HEU-233 VVER Fuel Rod +item.vver_fuel_hot.heu235.name=Hot HEU-235 VVER Fuel Rod +item.vver_fuel_hot.mea.name=Hot MEA VVER Fuel Rod +item.vver_fuel_hot.men.name=Hot MEN VVER Fuel Rod +item.vver_fuel_hot.mep.name=Hot MEP VVER Fuel Rod +item.vver_fuel_hot.meu.name=Hot MEU VVER Fuel Rod +item.vver_fuel_hot.mox.name=Hot MOX VVER Fuel Rod item.quartz_plutonium.name=Plutonic Quartz item.radar_linker.name=Radar Linker item.radaway.name=RadAway @@ -5760,6 +5806,7 @@ tile.nuke_fleija.name=F.L.E.I.J.A. tile.nuke_fstbmb.name=Balefire Bomb tile.nuke_gadget.name=The Gadget tile.nuke_man.name=Fat Man +tile.nuke_mk3.name=Mark 3 Nuclear Bomb tile.nuke_mike.name=Ivy Mike tile.nuke_n2.name=N² Mine tile.nuke_n45.name=N45 Naval Mine @@ -5925,6 +5972,27 @@ tile.pwr_port.name=PWR Access Port tile.pwr_port.desc=Allows item and fluid IO$Placement: Casing tile.pwr_reflector.name=PWR Neutron Reflector tile.pwr_reflector.desc=Reflects neutrons back to fuel rods$Placement: Grid, for increased reactivity$Valid casing material +tile.vver_block.name=VVER +tile.vver_casing.name=VVER Pressure Vessel +tile.vver_casing.desc=Needs to cover all internal parts for the reactor to form$Placement: Casing +tile.vver_channel.name=VVER Coolant Channel +tile.vver_channel.desc=Uses hull heat to heat up coolant$Placement: Any +tile.vver_control.name=VVER Control Rod +tile.vver_control.desc=Allows connected fuel rods to be controlled$Placement: Grid, between fuel rods +tile.vver_controller.name=VVER Controller +tile.vver_controller.desc=Access terminal for the VVER$Placement: Casing, only one per reactor$Right-click to assemble the reactor +tile.vver_fuel.name=VVER Fuel Rod +tile.vver_fuel.desc=Increases VVER fuel capacity$Placement: Grid, for increased reactivity +tile.vver_heatex.name=VVER Heat Exchanger +tile.vver_heatex.desc=Moves core heat to the hull$Placement: Any +tile.vver_heatsink.name=VVER Heatsink +tile.vver_heatsink.desc=Increases core heat capacity by 5%%$Makes coolant channels and heat exchangers slightly less effective$Placement: Any +tile.vver_neutron_source.name=VVER Neutron Source +tile.vver_neutron_source.desc=Adds 20 flux to the core$Placement: Any$Flux only reaches fuel rods if connections are open +tile.vver_port.name=VVER Access Port +tile.vver_port.desc=Allows item and fluid IO$Placement: Casing +tile.vver_reflector.name=VVER Neutron Reflector +tile.vver_reflector.desc=Reflects neutrons back to fuel rods$Placement: Grid, for increased reactivity$Valid casing material tile.rad_lava_block.name=Volcanic Lava tile.radar_screen.name=Radar Screen tile.radio_telex.name=Telex Machine diff --git a/src/main/resources/assets/hbm/textures/blocks/mk3.png b/src/main/resources/assets/hbm/textures/blocks/mk3.png new file mode 100644 index 0000000000000000000000000000000000000000..f073668d5528086d89c58c51993427dd7e972a70 GIT binary patch literal 441 zcmV;q0Y?6bP)p{hT;f4O^r*z6%=S7r}6P(hL<3wgiaCn7lK z(0j+-S!*F8s460Yh_Ls@-D$01X6(ILYhk^207QiAx;W=xX0+Bg=P<^gwZ<5ui07Ql zIf)3`IR_EJ-D`^8JLeo!wMYTXjEJE3&KLt##Ug@;0N|WMMBwh28NGKRq67e1YeWQQ zc9SOXdEp7@z29Dc0eQdoe&>-OGph+ywUqbXj4=xE{eBUVBC%9_`gM0y6@b_4#afHp zR9Z_C8)N)gkE+sID-w5Sj8Vk-ug;&(2Y2V^=jUF_Z%An;*O^wIIhomQAxBRu2~gE4 zO+;{ASB024wM;u3H|MMkoO6o&x~{T!&S9;U0=L4G8K^#_r7;F`PDF&(8m%?<-q>2J z(!H*$N|o=x-K*vzQtQpBEj_1lDz3HaoZeNnyu16|$p1qF*n8Ky=A4*W0doATyQRP9 jqXNorepzKz{gc^0?PXhg!MtND00000NkvXXu0mjf8qLgR literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_block.png b/src/main/resources/assets/hbm/textures/blocks/vver_block.png new file mode 100644 index 0000000000000000000000000000000000000000..772c959e4a8baed0f50d99003c3f777f624abf27 GIT binary patch literal 344 zcmV-e0jK_nP)tVfK{|Pjo&rgE({PKP_ zLsdyB(Y6gSMpP9M0pR-f?ptJYPT;&l#2{kW?E+2HkaJ-e(nU8FffYej$+_UXBZL5e z_l_82MNmaJDmm}ihk!AH_nuM;R`quWN41g*UDu(i#26Wd#39u&Dgy5v+wB`h3|18* zV@tXKz8E2dK-)GPa^{c{B^Qj5aZ7Eusu(kVmleSnLrUqSzW;pCA00d_7F9!c(_ge+ q5%hgOX(lX8p928Z&5qkP6otQ#x)wplC~5~y(Js;!#T1jpWRpeu4t;^558OP% zEV^lt6tFEcNUfnnlj%Y~u`F3iDxZx7=^pa%@?P@z(J#OL_JJDS`_8Y3AR-K*iFt8% z$3Dx*vW(qshqZQ;|NQp06Q2M)-K>crVoXYmk+Sq?tw@a_hCqxFfU@*>Uws4kd!O}$ zefRA*qx^Fu07vgJ#!z}s;fnf`@a~^?q$cI)J&6cPD^i`(aGI5#;&8}E`GW!y5z5k| zv_eGCTA{TD;33aRQ}dBfzdsI44ovcU0=)OFLTL6@aIRpvw8R)X12*XmAr1~W#XpDg z-lLSJa0N&2NljW46o*5OwU!WKyMIcnP92a1iy@*^wXcZ?F~p0fBQVJy%z(8^Vu&;y(PTrZs^S~<4|&dF zQMK45O!0g1K%1uX)^e^OHPy)%V?abW9P+^vZ3sjBK>h-7gPM60AKG@2p`+zSl0zqMb!q^D_^Z1kJiBy{}c(po9%YAvPA^;*=S6IKmPn{ zl)w4vX;;9DySvFjKL;Xm(GQ$w?dMmoNcLI(PM?EM^#kkmnthg$WLFmODSqH|&SbaS zT~)x8ANc+C>rQ-Pt>x>@y6u3%741GQmlo$-J!sbtI9KpyyG2BL{4qc9NJL$4pqZhS z0y858r(ZK9w`eEfgT-` zA}Aq<#LVFo>0|gA!jyod2ohyv+odDry$6wkNJNZ++HO)a&e=J9Rs!$4lp3vu0kYeD z11UN=I@2&Q)}-e{%pES_GXhG{z)%tTKEOGLsv0KPVH!|0)KxP>qJU>oIoT3EBcPd4 zmK7ulLI|m`v{E1%I(}k*?;MI^IAYV9%;5q)TQ6f%0mzP(_Z^HKCZ9+IGh@GZY5iOY zmhc&Y?-xZ(Bqqm2F{E56LRpq6m7VXf-@DliEa5W(RaHX9sW#Q<5JGB9J4OH?MPAn% zF!SuWehU8Bbl(RQ#n7#t?@}3#8>TGFbWzpyCPmlx`Q}qbAH!z^etrFVHj1CMsgaoh zV@!Hij8pd5-oJYXeb=@ZCGb=|u-$HP*S65@g$X=G4;=5Qo2I!afh9fg_vg-Ar6 zZ{VCuP1E@f%#08Ms;Y$desp@O2c}_E*P9G~P7nO~=FJIywH{cDU#$n$;#cc|wfNO~ zAdX}AXYs4`z*_ujJ+KzPS`VzoU%kA>Ijeu!p8fvN{`vAHJx_X|^IdA#=T|RI)?f54 zxV^o_+dqECAx3DW#v3yvJupRnyywO50$`~9^ncSH&4Ob+FztJhyWr;LCOP~OJH?_?K&6OofCUf23m{$_33eb+q~1!s z5LlM4H$>$H&Lr+jsA0TA0~CUsXj_`CqI#J;2rTOTq(H#ltCOM3S&m zrJ4~QL^zWfV;Sj^Ai&MtX=yN-@!{hqCU;(5y};d3Ret15uS#u20N;*B%qq{GJjKiq z0FlJx3xbHC`vD};r$qkw3u(m*^@^D>xi2G_8P$w8uU|2FP{%@_f>MoP*dwaU4J5+3 zytn|MmI8pRV&t5O$>>!I}iRWu2NV^&E(62Yvpx=*Z`V+KkY$vLwd_Cz>2XUt=nxrIld zx+B8>Fi=%y52DTI9<2VbMwS$NPT;pTYc z_H^19ZF^fCmXcs*bRBdl;o+pFhXCGg;$dCys_^6UbB1BSXQ)<521$3Q?#On}zEc8t zbau9kF&1!Nj_LO9)Xwue{|i;+q1txBP_}=+0kz&$Hr#mQX#fBK07*qoM6N<$g7`QB Ay8r+H literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_casing_blank.png b/src/main/resources/assets/hbm/textures/blocks/vver_casing_blank.png new file mode 100644 index 0000000000000000000000000000000000000000..bd7470ae90cab069ac6eba5b2abd4b7b0cdf7f03 GIT binary patch literal 515 zcmV+e0{s1nP)428c)(Y@jBqJ{3J8z|jBl)?=3XMAldQu+`(OkvJT zjBH6qM<>hIZ{H6F-2K0=nPFypg!yI#`11J^8Ht$@8PwVk6>es9cQTU9V0Wk0#-f4% zKVDwX0=qk_8Ld@%YeWQQ#_v*C&FCWu;I`d~NWvX=M*u{WS{vtCu=@t0tg4hhf02_21+U9evX3372CEu?oMmpa(;q%)GaBe>)bd8oHvo$YISewB zj{{n*sOTl^qCzc&d~d3YnmZARs^IP{3oNQc20HW*Kvf8Lo@2c-6?X5a3daH6JH1vG z!0bk3APXdrncVK%^>3^IKVM#lMSt-T%#3IE%f?WzyMG}fNFwgZz6$^V002ovPDHLk FV1l0j*$Myv literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_casing_port.png b/src/main/resources/assets/hbm/textures/blocks/vver_casing_port.png new file mode 100644 index 0000000000000000000000000000000000000000..1e5b2d6feeb54370e717b85d34860a024c612aca GIT binary patch literal 300 zcmV+{0n`48P)ulZhAdVADJ7h9s4CW4thK0W&S9#>47~TV5bw%BMA#pWh)A~ldHF&_ y{suhlc1wm9l>t>%743w9@;v}Br}MeE7~lt{yh^VroB{p-0000ZL2lbd6ox;~@R0;-p@AqRg##pNQMhmx&L)fW4grELg8;pU zPT-^D0znSYO|vVyb%9nv3!{KU!dY0QIN~G=i8Luvq*LnONF?W*c{B6)=I7CiSFb;@ zl`*FBD0eBD&v6;p9J*>5)sX=Rn=lj?! z!&(bKni`DRJOlVQife&Q9-g%FyK(^5#^C!tsWGgQ)%KC_@%kg4@3A%pM+Bu6p7zL@ ze5PgH+$>x9#sC}<($t`|LPXG7p|u9!zvU9o^KXIe{dL3OKqp@dz!+0R2=L+Rs?r&N zF>!HyG9II~BFk)Jhh2Pl|3N(fr8KK#RqXB0KfMHCHk$!3nM?q9^Y$G|t4ba;sg19# z0D!d_gTXOrX<08WE{LKCfG`Z1PN#?nM}ShgasSKO$JYW75q#grT8rH->ufe7iXs+^ zMbR*yO_o`dR%p9_1={#s6}^;`aG%UJ^WAOGP3q!n0f-1mk^q|wH^wlTObEk}(P+eI zG$IVcVjn%epik$h9pTi9t?9_oA%2u8<@vT(^0tyZBlF07@%tX3<)4G9DM5=Xp_nMQ?7Fc)quH=3V@* zio4ck0BEgPXPf`7D@9;I5TKMsL|7%OQpv5Vi?0P>jKOA>EVD&5TyOINz%R`P3@V9>8`^S$fd~ZL{mp_Of=)?E+1AX~}`GNn-_x1yQ`QCn@FMssn)$32= zd-saY=GWIn{)PmdC3poeakw_aJ0sCr8pOYARyU(_Lavx_*noOKahWK`o701om7m-vCjV!>yLZ@+mR?sbI#0000pnbHNO?eQA|9Q$HrHt*7j7@k!Q)LnLmF1l(e`pQ=;zApW`1s zK6Ymd`q`78ruzT?kB`dCJg;B9GMaEGU52;$qJac2b6dZ>y%7ULU~Al$;vKnigP)Cpz3{^o@0r=WBaxUDF zuJZ|SZ_)*H_Gh%V^LSJu{6E0n&lcPR_dr_P5mENGbBsYQ`FbF{-y5}7++*q@DpLnl zLB<$FIP3Z(nUPd6Gu(q*GTXKRP)eq?#s?sxXLV7MnXxQJL=YZyKNZg<^R;c4rGV2>*r`mhlXB+98P_@?i(bn}j+4TntN;K2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_control_side.png b/src/main/resources/assets/hbm/textures/blocks/vver_control_side.png new file mode 100644 index 0000000000000000000000000000000000000000..b95c60c592419bd933fa68d34ad6a92f0fb5375b GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf-oZz4XZr#tK_`6W`{J1^KQa6BD0Q?f%>^-LTB=@-|Z)!D$||ye_SL zG+oA=VcXh`Z(EBxLsUFIT4xvSNlE8BsMzpT`0fkO)gTe~DWM4fV^dw< literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_control_top.png b/src/main/resources/assets/hbm/textures/blocks/vver_control_top.png new file mode 100644 index 0000000000000000000000000000000000000000..ee56ec77fbb35a749c39d061ffa409c70164e5b5 GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#VfmYuN*Ama&+l( zc+(tWbLaS@ikjKma^Ih`bYXdKtJKu7;mfam>1VflCmuIv64um8JC;}P5UN?Z^+9jv z!^d+CWH=Kae0@4|ijeC1J>MmBWeknKRL%7d^@{5}VRNl1^GMDaaW6ajgFL%^CHWD;SmG9*Z&u-uUw{zX= kt1^GS{FnLDDO1C|e5PbW;5(lzpcffDUHx3vIVCg!0BPlRDgXcg literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_controller.png b/src/main/resources/assets/hbm/textures/blocks/vver_controller.png new file mode 100644 index 0000000000000000000000000000000000000000..d010114a07e6fbc1bdad862fe7e678302092440e GIT binary patch literal 544 zcmV+*0^j|KP)+BRS#h=ynp z5`sk<{|~K2i=+`j(BR!EXI^&S+|0AMcNdh1_ic7zcRw>b^POUAd#9n5s{XNx2qMCD zTHNUX+`V%fH%CM;H&V)k80d;ntK#Ok8#7gM$`mmWfUl$R957R5G@hVZqd8+{hzK)P z3K3>G6GB)Ei%h@RaK~+ z-&p7I(`NvDKmSJWMxVi8z>mq8>Y`%iM&V8ffjVUt?(1l4j&9lG^Vuoxa}WHQj2QuD zj+o!AjlPF&XQES!(V?RftD iXWK4oU5+rM<=JoJUJar=kH>NV00000oneEP)JzM~KiC?g_-z(L@K+(S!s?Ond+a<3=1@`U<{6 zAA*6!-JQgRf#~9ZvbbvQRR*UElO3SY7vLoS>6d)d2?n>9OJfYGTDUCB*yR;t4AYl) z!l=&p`3(`_rr#rsBCfBxlzBx}nM~(+@A+N)0WcgrAtH1x&M9+IRYW95fUoZ#y!TjZ zDf2wAe(Qm4o(I~kW{!=xwh`Fo2lsdVhd8ctdUDL{JxT;Y5Jq2j&rIS`484k15fn4M$)bsYuy^nnf*`0ExU%f; zbaj1gFuP*n1XE$vqiMeHg{S$fdMOYhAmjqz{pFd5`#As?H&^_}H11;Y`38WB;}VuL zi?45D4D2m4#x#~QmJNAf-y2kr7q+Vn=1z)eZ{R?8*Z^_ITx$+=)=xK~s) z1USNk^Rv_HE=5dJK|CA~_Z;PUo*nn=IDnJSVFnM@YRE3_$27wM$yhBhXP6a(%|7in*q6w|0kKg3%r UwX_QtApigX07*qoM6N<$g1+{dWB>pF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_heatsink.png b/src/main/resources/assets/hbm/textures/blocks/vver_heatsink.png new file mode 100644 index 0000000000000000000000000000000000000000..7ef114b06a5f164c4372d539267f7de5211aea5e GIT binary patch literal 323 zcmV-J0lfZ+P)^=yXg`3P4aJRhBBXr)nkMxJG;Jf~2KC|dIL@c0|>!T{m<_(6aWF19nl z8mCzHh^A>URYmb*nhrnR literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_neutron_source.png b/src/main/resources/assets/hbm/textures/blocks/vver_neutron_source.png new file mode 100644 index 0000000000000000000000000000000000000000..46a280daaa31faea8127446b101eb7cff90329ef GIT binary patch literal 537 zcmV+!0_OdRP)}Uq4^XjLZZeB5-%iIv|lmWRlV1=C<4;f-WMsxxPdS%ng9P z?*WiRMiLXan-Nh_4cv@>&(Cy`i4X) zN9&qNM6f=(OCvRc`}@CqzFEUb8>Mr1+`B1B?Dsn)y*ov%i6pk$2d+0C;59Kfx|yE4 zli5Vu?RFH6R0W6OKxAcoet{&0u`HtiSW~kS5eti=k&ml$&Q>cnn+@yp3vO>eQ6!{- zq&I+B`B@xERK+{m&5Z`GBHX>@7h$ufz%s&NIJ_$^(~(A`!Z3`C5WnA zoQsg%FpR9u3XyF|w%Z4Wu{5GSdY|^)G_NhRiwbUS2RnfM2oA+6&da@Jub00000NkvXXu0mjfogwsf literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/vver_port.png b/src/main/resources/assets/hbm/textures/blocks/vver_port.png new file mode 100644 index 0000000000000000000000000000000000000000..2de75a8b874c2608cf80327da4753f4cfd925938 GIT binary patch literal 588 zcmV-S0<-;zP) z5q#eS@NKqHt|tfk`v7?7ZUF$ArXjZ$fY+~H0UO>9}`p1B9m!>ss|uDIzHKK&t{{(^Q)_|_-?d^SU)HVv~^_0^8NZcZ6ULU z&tJZx>Up%gmzers0l3y-jU~ju*?LWgft_mm*2Kh;5;pjdWsup_WQ|2cFhJ0YFu8ckb`+ad$!pU8CJ@M^IH#N}Nuou6wPO ze!owz*Tc;ID426*Fc@$=9%-5eeK^+7A5WQ1ro4Rqn#sorr|(a={cy{R;VY(-DZlp5 zxSQTF8jZ*~pC>dkVvM*upTEB2?VI;p-(2zK)3?9k5CQ=1j=DR&UXPU0Ka(C}GecF| zS5Z}f|8{OMK#Y-E>$yO!72u-ruWzmZ2q6$-L`8&@5-FvNIVh#jG|hR1Ruqrnpw`-n zO`E1Ue^f8#pjBs#@ytO80abkz2kq(A%(^pP%0aCa5uucVtk-K_E|(k*2gc(uP168$ zmuaKLt;y!|Ios`);O_MMeTKs!o6QD*loDpvnaIpK6NM0Hb84-G)oR6lzeiQcIpgkK mVq2&cTF#kTE2Wgq3%>#I;EKi%b_Lr20000C5s{{iZ9VXKfttS*+6&CEC;iiwLQRW zJulEJyWc>fNs5%Ouh8(WZNTzsY=f1vkfQXTul~p?+T|HB0HW&D$xFnaam&b4#TF6q z)?07&X`15eufJ{)5pTc!cAusxzWVB`77_98yYKeidwG5D-o4&?k1xOcvPDGPzkk2? z-s6iezF6Oni1qdT`}ccmEk66~vlbEY-h1!$-g|uh`RDfjy?gh1Yi)KvBG%Wgzs~R4 zN5pLY)>=G&{=7v*Jb3V+N5uO2;NYM~L|k8AukW|k;`;i!<=DOVP#KpI5v{fLjfjY8 znxeI~zSj47t)KPYH`LISQ}#&vTl%@Y;=8_ zzGN!mCD>K}#bR-5ezyTnMH!8!{1Wt}WyO?gNo#E;C^g6lqO@AAHZ*Xgp$>Qw!6m=c z$PqauVSipH9@&;-EL}%3=2nF53EW77Nh6S}`9~T}ew^zVSqR(fJ@!vo^ZK24-susq zT){4;Fk;FvO%2*cBcI4QM?Np&*K4SoufoRx+%~H1XbUu+L3MYnkMG_ zc?E`!!_Rd=D)-{XRXG&Ih}XM0(o(@x;j6)wiFDwq?d;=xp7znPT{|_+Y`0h}W?G{G z%Z-!rxU?xXS?5vSH7L7rD_YVlQkAJ4)dqpWP$Q`g1XLG=%#SjMB&TH+*s7u1a(9gn zs^v; zz%*BM6H_21r}gUBonZN=d8O;G8tKv`H?A%;-2pApSwjh|^PSW-`Zag${49mOZPqc; zl8nU8+MIvRdvrY-j45x9&vAx6*5zx?m+0!}>u3+{z+!s`mbZ?^hbB z7D!Mlw^q>_@=-?zNKU2GplAHj2(hqGuZgrl{_CUdU3AF*kk1UTEczHB!#D{iG3oK!e<2~{9f z3voV^@>JQ1)9zuql_p>LL}fCDW!nSiirKPT<6G|hs z(*Ty&@_lMH(>PbL(*D$HXLfE;G!s$ZsoLxgES)C0lu`ZrE;KpcK``js^m87KC@Co0 z{3QFhv9<~30@gNnRauU{cPSbBkR~iFIsw6r*xa%*fI9a? z3@orZ00(p+I8CBvXasllR|V36=>kT@lS>hu#?ysxF{%uLw5uyvs$h;eXLd@=6%*9# z!>YWF@0iX7(fWWpKhrUs7VCYw8^#mI2Qz??e|EG~%~3ayL5V&xg?7g=tcNnN#Nwf@FhrVX} z%2Js6Rdo^42_!t3O85h{dp5z2roW^mCeE6KKu;#$|Bu#Q+nQQn>QtIs9xiqBRbTbW9i{z-hPkC8!mUNp7BOlVj$SI?kn4u48ygt4y+aps&gIx^tqb zXrf)Mp3@HcG6#aTcVoJ7-Oi7$g=5lX)+;M(|iu zAU|7!muoPJfbQ7*Et7$9Ct$fjeEV(u z{hM#%@85hA|MurU^@xa%KKx+&es7PIfT(sQ|N7lAjS*V6jfmOz#(MAZ@ZrN-$&f#4 zmh(o)0~@J{j*gCwdZr=IpFeNke)nDf{)Zpp`xh@_{rciX{Ktp?`G2CNj$DLSFx|5V z%&|4yJ3Kt>&z?QoDo-jN)3N0)CUbdtIcxB{fBHlF_kaDDo`C+(k3Ys=Kl$7L3#i*3 z+Hjw1KPP*Bc64;qDZA3a!9mx>i;!ALM66ZcCD>|e+J?t6{2FHOeeJ6b4-flj0X1#Q zYt4%zHmg?=FMVNJQ{H0*&gHEd#9SK1pzAdE=;)|3xaHroXV2P35|@ngyRQkb4v>Ft z7e>=`DVV;xeAZp7k4(z>^=PLWi|NvU5n!e>+Ils1bV`zJQPY_uju5#09n$|$m#1q`KZnw}gAFG{}d7aGVp%jMq+*GZo6sO*gp)R)r?1S*p*aIWSvrF2k7++eB<0nI{kolsX2-rr>VxUlq2UqGWrW zn@9NivjiJwUd}DJ)l!DCjWZhxPl4$lo#iO$S4kaj$-fGz0kAsSAxMgat35auq_m;2 zI{2tcK8muHkJZ-^(K_fq-E&~tmp++pMzxU|NG*=od?+q0XJn=A`1rW%M5;BFrm;@z zgwfAjmXX&KLdR8L^}Q+pQ@hG4oLeElNwl0CkJT-nBE>5?=uXHN+vuylcZ)nxShp&qDo`j8WFpO{+B{Ukv{8r(@qtHB{}VvOfMFT;ZHXal@Qp)QJBQ(BN)99E;~zq#10 zwKzXNpP`o5^vyG12_8Y!70l-h)WpcN3c`auO;1!HW)u#Tyw)+@0x_T^Z!9Y5DRcHy zmy@pqHRJ++hHYBtUhT!T|j0DWKy-C=Bqn4j+^tklT{rfNkQ$sZv|Ds z)$8PcsjC(7`lpqt#WedQ)=e3-82t4A5m4)?v0PZU;rR5^Pj>=f8|6kRViT-wba8Rf zvR=CeRxcb;^PF$X#o<`a->LGP;cbBfLwQ zvVFE0`QUvL(=eWMRdjlK+FNTIXM}617-VS18u|6w`9>Gvna(i?@!V)+n&fXEq~j&X z+cfv|^t3bWOqy+Jm0_2fP+)?p&z6#y38+ABQ&Rb7&4c$zRVw%B(IY$2?Jw5FauQhcW*#|ZV1QTs##`$Gurp!DjjLx4z<+Xca zW#8mXTIXD?Rx?da-du2xkpGU9gFCQjp4_@RZ6wnaK#2><#dP5R7Fw&@TAh#QXXM%O zID24&1sB#}X@<;w-6CjTWg=3~G3PAe3r%#{mC5mwql+QLqZ2n^-@=U%W@K1bHfb69I9)<3}nMc0T zv@39QJo+r>0+>zglT;&JaMk(AF9DvNd5wYyg^Za0FDz~21a~fibGrFyYE|D~OHAqL z`p7?bYROMp+H$n_&y}E$)0J}p&Se%3G`CnIp%;sV4J7*_T9m$LaX#NOMy!1-8RQ;c zUm2*#L`3}`-Pk@E;=eUz+LnN(5XsBvf7kp{()i%Yp~?M?q{NY4Y>?Q`P8gHeX2{lB3>OPx*Itdi!MBF$-&)LQ$cq3$QWIS z_Td6V?Do&qcO@PzxgdIWcGjq&ijiveq}rtbDPZnwUhh>vDUn$RxK_EeANkSw_DQNd zba79fJZTXTPoF+*Zn3k!$g&9t!Q>>)9aN0ENf`*anAMoi)jBwOp{)>Sqd)@*uOdHv1N21kx>PNK%ywRgqNNRvUmE*X6fvJoeew zR<`18*VEtg^Yg~4SA;2atGPLskng#1;27+q_nccHA60<+Elv+|{FM8)N9ySoB1B2^ zTqi+NEvs@{=Aa2!^+1`9ukYQWa2_>LeQIT2&lCJs)FNVbXvX|h6JjRx*+$zZ2>CV1 zhYufi0!UKr*F~!;ZErfL5wBdq<>h6g;A(n~SgXxG(=^S#dwO+s)l}=;pDq*+7HLIy z0n~_B8k_X!(WA~Bj;FP53#!0WUqwGUI_hlC2iMMDzz)3u3~9jAn)(;qX`k?Q%(nV#Ov+kU80g< zefrMrp!CVV+x~{i>FMd(<#1olOyjO;YSLEIW$7>CHL%k(-TINoq3e0_>$CiG_eeUP z?zkfSla0D~Ri!K!@UDQ{PEJm`{s;O5N>4`VS0gs}@VuAT>N5E71M3lPJ{?cnzUish zlD}BN>Xu97=?klxtIHx>9YQmNYOy%}n@&qLH8pJ}?n(L?|6_9AuT0-PS;+DrgCpm> aEA+pFV%iI8EAEZ}0000