From b1e6936e08af10bc022842baba3a17e905d876a6 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 4 Aug 2022 18:58:13 +0200 Subject: [PATCH] fixes, RBMK console screen functionality, schmalz --- .../hbm/blocks/machine/MachineStirling.java | 8 +- .../hbm/entity/effect/EntityFalloutRain.java | 6 +- .../com/hbm/handler/EntityEffectHandler.java | 3 + .../hbm/handler/nei/AnvilRecipeHandler.java | 8 - .../java/com/hbm/hazard/HazardRegistry.java | 4 +- .../com/hbm/inventory/OreDictManager.java | 11 + .../com/hbm/inventory/gui/GUIRBMKConsole.java | 57 +++++- .../inventory/recipes/anvil/AnvilRecipes.java | 2 +- .../render/tileentity/RenderRBMKConsole.java | 48 ++++- .../render/tileentity/RendererObjTester.java | 80 ++++++-- .../hbm/tileentity/TileEntityProxyCombo.java | 4 +- .../machine/TileEntityStirling.java | 4 +- .../machine/rbmk/TileEntityRBMKConsole.java | 190 ++++++++++++++++-- .../machine/rbmk/TileEntityRBMKOutgasser.java | 2 +- .../machine/rbmk/TileEntityRBMKRod.java | 9 + src/main/resources/assets/hbm/lang/en_US.lang | 12 ++ .../gui/reactors/gui_rbmk_console.png | Bin 6111 -> 6569 bytes .../hbm/textures/models/machines/mixer.png | Bin 0 -> 1931 bytes .../textures/models/machines/rbmk_control.png | Bin 4371 -> 4317 bytes .../models/projectiles/himars_single.png | Bin 0 -> 924 bytes .../models/projectiles/himars_standard.png | Bin 0 -> 543 bytes .../hbm/textures/models/turrets/himars.png | Bin 0 -> 3158 bytes 22 files changed, 398 insertions(+), 50 deletions(-) create mode 100644 src/main/resources/assets/hbm/textures/models/machines/mixer.png create mode 100644 src/main/resources/assets/hbm/textures/models/projectiles/himars_single.png create mode 100644 src/main/resources/assets/hbm/textures/models/projectiles/himars_standard.png create mode 100644 src/main/resources/assets/hbm/textures/models/turrets/himars.png diff --git a/src/main/java/com/hbm/blocks/machine/MachineStirling.java b/src/main/java/com/hbm/blocks/machine/MachineStirling.java index de2731c53..aaab916fa 100644 --- a/src/main/java/com/hbm/blocks/machine/MachineStirling.java +++ b/src/main/java/com/hbm/blocks/machine/MachineStirling.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import com.hbm.blocks.BlockDummyable; +import com.hbm.blocks.IBlockMulti; import com.hbm.blocks.ILookOverlay; import com.hbm.blocks.ITooltipProvider; import com.hbm.items.ModItems; @@ -23,7 +24,7 @@ import net.minecraft.world.World; import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre; import net.minecraftforge.common.util.ForgeDirection; -public class MachineStirling extends BlockDummyable implements ILookOverlay, ITooltipProvider { +public class MachineStirling extends BlockDummyable implements ILookOverlay, ITooltipProvider, IBlockMulti { public MachineStirling() { super(Material.iron); @@ -182,4 +183,9 @@ public class MachineStirling extends BlockDummyable implements ILookOverlay, ITo public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { this.addStandardInfo(stack, player, list, ext); } + + @Override + public int getSubCount() { + return 0; + } } diff --git a/src/main/java/com/hbm/entity/effect/EntityFalloutRain.java b/src/main/java/com/hbm/entity/effect/EntityFalloutRain.java index 92b21609a..de26d22ce 100644 --- a/src/main/java/com/hbm/entity/effect/EntityFalloutRain.java +++ b/src/main/java/com/hbm/entity/effect/EntityFalloutRain.java @@ -170,12 +170,14 @@ public class EntityFalloutRain extends Entity { } } - if(dist < 65 && b.getBlockHardness(worldObj, x, y, z) <= Blocks.stonebrick.getExplosionResistance(null)) { + float hardness = b.getBlockHardness(worldObj, x, y, z); + if(dist < 65 && hardness <= Blocks.stonebrick.getExplosionResistance(null) && hardness >= 0) { Block bl = worldObj.getBlock(x, y - 1, z); if(bl == Blocks.air) { for(int i = 0; i <= depth; i++) { - if(worldObj.getBlock(x, y + i, z).getBlockHardness(worldObj, x, y + i, z) <= Blocks.stonebrick.getExplosionResistance(null)) { + hardness = worldObj.getBlock(x, y + i, z).getBlockHardness(worldObj, x, y + i, z); + if(hardness <= Blocks.stonebrick.getExplosionResistance(null) && hardness >= 0) { EntityFallingBlock entityfallingblock = new EntityFallingBlock(worldObj, x + 0.5D, y + 0.5D + i, z + 0.5D, worldObj.getBlock(x, y + i, z), worldObj.getBlockMetadata(x, y + i, z)); worldObj.spawnEntityInWorld(entityfallingblock); } diff --git a/src/main/java/com/hbm/handler/EntityEffectHandler.java b/src/main/java/com/hbm/handler/EntityEffectHandler.java index 9194f6b0d..78c037158 100644 --- a/src/main/java/com/hbm/handler/EntityEffectHandler.java +++ b/src/main/java/com/hbm/handler/EntityEffectHandler.java @@ -67,6 +67,9 @@ public class EntityEffectHandler { pprps.shield += Math.min(pprps.maxShield - pprps.shield, 0.005F * tsd); } + if(pprps.shield > pprps.maxShield) + pprps.shield = pprps.maxShield; + props.saveNBTData(data); pprps.saveNBTData(data); PacketDispatcher.wrapper.sendTo(new ExtPropPacket(data), (EntityPlayerMP) entity); diff --git a/src/main/java/com/hbm/handler/nei/AnvilRecipeHandler.java b/src/main/java/com/hbm/handler/nei/AnvilRecipeHandler.java index b1c9e4712..4df799a33 100644 --- a/src/main/java/com/hbm/handler/nei/AnvilRecipeHandler.java +++ b/src/main/java/com/hbm/handler/nei/AnvilRecipeHandler.java @@ -86,14 +86,6 @@ public class AnvilRecipeHandler extends TemplateRecipeHandler { } for(int i = 0; i < in.size(); i++) { - - if(in.get(i) instanceof List) { - List array = (List) in.get(i); - - for(ItemStack stack : array) - System.out.println(stack); - } - this.input.add(new PositionedStack(in.get(i), inOX + 18 * (i % inLine), inOY + 18 * (i / inLine))); } diff --git a/src/main/java/com/hbm/hazard/HazardRegistry.java b/src/main/java/com/hbm/hazard/HazardRegistry.java index ff496604f..9bca608eb 100644 --- a/src/main/java/com/hbm/hazard/HazardRegistry.java +++ b/src/main/java/com/hbm/hazard/HazardRegistry.java @@ -467,8 +467,8 @@ public class HazardRegistry { /* * Blacklist */ - HazardSystem.blacklist(TH232.ore()); - HazardSystem.blacklist(U.ore()); + for(String ore : TH232.ores()) HazardSystem.blacklist(ore); + for(String ore : U.ores()) HazardSystem.blacklist(ore); /* diff --git a/src/main/java/com/hbm/inventory/OreDictManager.java b/src/main/java/com/hbm/inventory/OreDictManager.java index 06bf60ac5..67858355b 100644 --- a/src/main/java/com/hbm/inventory/OreDictManager.java +++ b/src/main/java/com/hbm/inventory/OreDictManager.java @@ -685,6 +685,7 @@ public class OreDictManager { public void registerStack(String tag, ItemStack stack) { for(String mat : mats) { + OreDictionary.registerOre(tag + mat, stack); if(!hazards.isEmpty() && hazMult > 0F) { @@ -697,6 +698,16 @@ public class OreDictManager { HazardSystem.register(tag + mat, data); } } + + /* + * Fix for a small oddity in nuclearcraft: many radioactive elements do not have an ore prefix and the sizes + * seem generally inconsistent (TH and U are 20 "tiny"s per ingot while boron is 12), so we assume those to be ingots. + * Therefore we register all ingots a second time but without prefix. TODO: add a config option to disable this compat. + * I'd imagine greg's OD system might not like things without prefixes. + */ + if("ingot".equals(tag)) { + registerStack("", stack); + } } } diff --git a/src/main/java/com/hbm/inventory/gui/GUIRBMKConsole.java b/src/main/java/com/hbm/inventory/gui/GUIRBMKConsole.java index d4947437c..bd2599747 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIRBMKConsole.java +++ b/src/main/java/com/hbm/inventory/gui/GUIRBMKConsole.java @@ -15,6 +15,7 @@ import com.hbm.packet.PacketDispatcher; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.RBMKColumn; +import com.hbm.util.I18nUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.audio.PositionedSoundRecord; @@ -22,6 +23,7 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; @@ -90,7 +92,14 @@ public class GUIRBMKConsole extends GuiScreen { this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 61, guiTop + 70, 10, 10, mouseX, mouseY, new String[]{ "Select all control rods" } ); this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 72, guiTop + 70, 10, 10, mouseX, mouseY, new String[]{ "Deselect all" } ); - this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 6, guiTop + 8, 76, 60, mouseX, mouseY, new String[]{ "ignore all this for now" } ); + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 2; j++) { + int id = i * 2 + j + 1; + this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 6 + 40 * j, guiTop + 8 + 21 * i, 18, 18, mouseX, mouseY, new String[]{ EnumChatFormatting.YELLOW + I18nUtil.resolveKey("rbmk.console." + console.screens[id - 1].type.name().toLowerCase(), id) } ); + this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 24 + 40 * j, guiTop + 8 + 21 * i, 18, 18, mouseX, mouseY, new String[]{ I18nUtil.resolveKey("rbmk.console.assign", id) } ); + } + } this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 6, guiTop + 70, 10, 10, mouseX, mouseY, new String[]{ "Select red group" } ); this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 17, guiTop + 70, 10, 10, mouseX, mouseY, new String[]{ "Select yellow group" } ); @@ -114,6 +123,7 @@ public class GUIRBMKConsole extends GuiScreen { int bY = 11; int size = 10; + //toggle column selection if(guiLeft + 86 <= mouseX && guiLeft + 86 + 150 > mouseX && guiTop + 11 < mouseY && guiTop + 11 + 150 >= mouseY) { int index = ((mouseX - bX - guiLeft) / size + (mouseY - bY - guiTop) / size * 15); @@ -126,12 +136,14 @@ public class GUIRBMKConsole extends GuiScreen { } } + //clear selection if(guiLeft + 72 <= mouseX && guiLeft + 72 + 10 > mouseX && guiTop + 70 < mouseY && guiTop + 70 + 10 >= mouseY) { this.selection = new boolean[15 * 15]; mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 0.5F)); return; } + //select all control rods if(guiLeft + 61 <= mouseX && guiLeft + 61 + 10 > mouseX && guiTop + 70 < mouseY && guiTop + 70 + 10 >= mouseY) { this.selection = new boolean[15 * 15]; @@ -145,6 +157,7 @@ public class GUIRBMKConsole extends GuiScreen { return; } + //select color groups for(int k = 0; k < 5; k++) { if(guiLeft + 6 + k * 11 <= mouseX && guiLeft + 6 + k * 11 + 10 > mouseX && guiTop + 70 < mouseY && guiTop + 70 + 10 >= mouseY) { @@ -162,6 +175,7 @@ public class GUIRBMKConsole extends GuiScreen { } } + //AZ-5 if(guiLeft + 30 <= mouseX && guiLeft + 30 + 28 > mouseX && guiTop + 138 < mouseY && guiTop + 138 + 28 >= mouseY) { if(az5Lid) { @@ -185,6 +199,7 @@ public class GUIRBMKConsole extends GuiScreen { return; } + //save control rod setting if(guiLeft + 48 <= mouseX && guiLeft + 48 + 12 > mouseX && guiTop + 82 < mouseY && guiTop + 82 + 12 >= mouseY) { double level; @@ -208,6 +223,39 @@ public class GUIRBMKConsole extends GuiScreen { PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(control, console.xCoord, console.yCoord, console.zCoord)); mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1F)); } + + //submit selection for status screen + + for(int j = 0; j < 3; j++) { + for(int k = 0; k < 2; k++) { + + int id = j * 2 + k; + + if(guiLeft + 6 + 40 * k <= mouseX && guiLeft + 6 + 40 * k + 18 > mouseX && guiTop + 8 + 21 * j < mouseY && guiTop + 8 + 21 * j + 18 >= mouseY) { + NBTTagCompound control = new NBTTagCompound(); + control.setByte("toggle", (byte) id); + PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(control, console.xCoord, console.yCoord, console.zCoord)); + mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 0.5F)); + return; + } + + if(guiLeft + 24 + 40 * k <= mouseX && guiLeft + 24 + 40 * k + 18 > mouseX && guiTop + 8 + 21 * j < mouseY && guiTop + 8 + 21 * j + 18 >= mouseY) { + + NBTTagCompound control = new NBTTagCompound(); + control.setByte("id", (byte) id); + + for(int s = 0; s < selection.length; s++) { + if(selection[s]) { + control.setBoolean("s" + s, true); + } + } + + PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(control, console.xCoord, console.yCoord, console.zCoord)); + mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 0.75F)); + return; + } + } + } } @SuppressWarnings("incomplete-switch") //shut up @@ -220,6 +268,13 @@ public class GUIRBMKConsole extends GuiScreen { drawTexturedModalRect(guiLeft + 30, guiTop + 138, 228, 172, 28, 28); } + for(int j = 0; j < 3; j++) { + for(int k = 0; k < 2; k++) { + int id = j * 2 + k; + drawTexturedModalRect(guiLeft + 6 + 40 * k, guiTop + 8 + 21 * j, this.console.screens[id].type.offset, 238, 18, 18); + } + } + int bX = 86; int bY = 11; int size = 10; diff --git a/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java b/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java index 8c9599857..2d7f13c6f 100644 --- a/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java @@ -65,7 +65,7 @@ public class AnvilRecipes { smithingRecipes.add(new AnvilSmithingHotRecipe(3, new ItemStack(ModItems.meteorite_sword_reforged, 1), new ComparableStack(ModItems.meteorite_sword_seared), new ComparableStack(ModItems.ingot_meteorite_forged))); smithingRecipes.add(new AnvilSmithingRecipe(1, new ItemStack(ModItems.gun_ar15, 1), new ComparableStack(ModItems.gun_thompson), new ComparableStack(ModItems.pipe_lead))); smithingRecipes.add(new AnvilSmithingRecipe(1916169, new ItemStack(ModItems.wings_murk, 1), new ComparableStack(ModItems.wings_limp), new ComparableStack(ModItems.particle_tachyon))); - smithingRecipes.add(new AnvilSmithingRecipe(4, new ItemStack(ModItems.flask_infusion, EnumInfusion.SHIELD.ordinal()), new ComparableStack(ModItems.gem_alexandrite), new ComparableStack(ModItems.bottle_nuka))); + smithingRecipes.add(new AnvilSmithingRecipe(4, new ItemStack(ModItems.flask_infusion, 1, EnumInfusion.SHIELD.ordinal()), new ComparableStack(ModItems.gem_alexandrite), new ComparableStack(ModItems.bottle_nuka))); smithingRecipes.add(new AnvilSmithingCyanideRecipe()); smithingRecipes.add(new AnvilSmithingRenameRecipe()); diff --git a/src/main/java/com/hbm/render/tileentity/RenderRBMKConsole.java b/src/main/java/com/hbm/render/tileentity/RenderRBMKConsole.java index 65650bde2..c149f2089 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderRBMKConsole.java +++ b/src/main/java/com/hbm/render/tileentity/RenderRBMKConsole.java @@ -1,14 +1,17 @@ package com.hbm.render.tileentity; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; import com.hbm.blocks.BlockDummyable; import com.hbm.main.ResourceManager; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.RBMKColumn; -import com.hbm.tileentity.machine.storage.TileEntityMachineFENSU; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.RBMKScreen; +import com.hbm.util.I18nUtil; -import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; @@ -72,6 +75,47 @@ public class RenderRBMKConsole extends TileEntitySpecialRenderer { tess.draw(); GL11.glEnable(GL11.GL_TEXTURE_2D); + FontRenderer font = Minecraft.getMinecraft().fontRenderer; + GL11.glTranslatef(-0.42F, 3.5F, 1.75F); + GL11.glDepthMask(false); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + + for(int i = 0; i < console.screens.length; i++) { + + GL11.glPushMatrix(); + + if(i % 2 == 1) + GL11.glTranslatef(0, 0, 1.75F * -2); + + GL11.glTranslatef(0, -0.75F * (i / 2), 0); + + RBMKScreen screen = console.screens[i]; + String text = screen.display; + + if(text != null && ! text.isEmpty()) { + + String[] parts = text.split("="); + + if(parts.length == 2) { + text = I18nUtil.resolveKey(parts[0], parts[1]); + } + + int width = font.getStringWidth(text); + int height = font.FONT_HEIGHT; + + float f3 = Math.min(0.03F, 0.8F / Math.max(width, 1)); + GL11.glScalef(f3, -f3, f3); + GL11.glNormal3f(0.0F, 0.0F, -1.0F); + GL11.glRotatef(90, 0, 1, 0); + + font.drawString(text, - width / 2, - height / 2, 0x00ff00); + } + GL11.glPopMatrix(); + } + + GL11.glDepthMask(true); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); } diff --git a/src/main/java/com/hbm/render/tileentity/RendererObjTester.java b/src/main/java/com/hbm/render/tileentity/RendererObjTester.java index aa1ba0f02..53dcfb817 100644 --- a/src/main/java/com/hbm/render/tileentity/RendererObjTester.java +++ b/src/main/java/com/hbm/render/tileentity/RendererObjTester.java @@ -1,6 +1,11 @@ package com.hbm.render.tileentity; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; import com.hbm.lib.RefStrings; import com.hbm.main.ResourceManager; @@ -11,6 +16,7 @@ import com.hbm.render.util.BeamPronter.EnumWaveType; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; @@ -168,23 +174,64 @@ public class RendererObjTester extends TileEntitySpecialRenderer { GL11.glDepthMask(true); GL11.glShadeModel(GL11.GL_FLAT);*/ - - GL11.glShadeModel(GL11.GL_SMOOTH); - - GL11.glEnable(GL11.GL_CULL_FACE); - GL11.glEnable(GL11.GL_LIGHTING); - - bindTexture(ResourceManager.soyuz_module_dome_tex); - ResourceManager.soyuz_module.renderPart("Dome"); - bindTexture(ResourceManager.soyuz_module_lander_tex); - ResourceManager.soyuz_module.renderPart("Capsule"); - bindTexture(ResourceManager.soyuz_module_propulsion_tex); - ResourceManager.soyuz_module.renderPart("Propulsion"); - bindTexture(ResourceManager.soyuz_module_solar_tex); - ResourceManager.soyuz_module.renderPart("Solar"); - - GL11.glShadeModel(GL11.GL_FLAT); + GL11.glTranslated(0D, 4D, 0D); + GL11.glRotated(System.currentTimeMillis() % 3600 / 10D, 0, 0, 1); + GL11.glTranslated(0D, -4D, 0D); + GL11.glRotated(System.currentTimeMillis() % 3600 / 10D, 0, 1, 0); + + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_LIGHTING); + + //GL11.glDisable(GL11.GL_TEXTURE_2D); + RenderHelper.disableStandardItemLighting(); + RenderHelper.enableStandardItemLighting(); + GL11.glColor4d(1, 1, 1, 1); + GL11.glClearColor(0, 0, 0, 0); + + float amb = 2F; + float dif = 2F; + float spe = 2F; + float shi = 1F; + FloatBuffer iamb = (FloatBuffer) BufferUtils.createFloatBuffer(8).put(new float[] { amb, amb, amb, 1F }).flip(); + FloatBuffer idif = (FloatBuffer) BufferUtils.createFloatBuffer(8).put(new float[] { dif, dif, dif, 1F }).flip(); + FloatBuffer ispe = (FloatBuffer) BufferUtils.createFloatBuffer(8).put(new float[] { spe, spe, spe, 1F }).flip(); + FloatBuffer mamb = (FloatBuffer) BufferUtils.createFloatBuffer(8).put(new float[] { amb, amb, amb, 1F }).flip(); + FloatBuffer mdif = (FloatBuffer) BufferUtils.createFloatBuffer(8).put(new float[] { dif, dif, dif, 1F }).flip(); + FloatBuffer mspe = (FloatBuffer) BufferUtils.createFloatBuffer(8).put(new float[] { spe, spe, spe, 1F }).flip(); + float msh = 128F * shi; + FloatBuffer mem = (FloatBuffer) BufferUtils.createFloatBuffer(8).put(new float[] { 1F, 1F, 1F, 1F }).flip(); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, iamb); + GL11.glLight(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, idif); + GL11.glLight(GL11.GL_LIGHT0, GL11.GL_SPECULAR, ispe); + GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, iamb); + GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, idif); + GL11.glLight(GL11.GL_LIGHT1, GL11.GL_SPECULAR, ispe); + GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT, mamb); + GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE, mdif); + GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SPECULAR, mspe); + GL11.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS, msh); + GL11.glMaterial(GL11.GL_FRONT, GL11.GL_EMISSION, mem); + GL11.glLightModeli(GL12.GL_LIGHT_MODEL_COLOR_CONTROL, GL12.GL_SEPARATE_SPECULAR_COLOR); + + + bindTexture(ResourceManager.soyuz_module_dome_tex); + ResourceManager.soyuz_module.renderPart("Dome"); + bindTexture(ResourceManager.soyuz_module_lander_tex); + ResourceManager.soyuz_module.renderPart("Capsule"); + bindTexture(ResourceManager.soyuz_module_propulsion_tex); + ResourceManager.soyuz_module.renderPart("Propulsion"); + bindTexture(ResourceManager.soyuz_module_solar_tex); + ResourceManager.soyuz_module.renderPart("Solar"); + + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glColor3f(1F, 1F, 1F); + /*GL11.glDisable(GL11.GL_CULL_FACE); GL11.glShadeModel(GL11.GL_SMOOTH); @@ -282,6 +329,7 @@ public class RendererObjTester extends TileEntitySpecialRenderer { }*/ GL11.glPopMatrix(); + RenderHelper.enableStandardItemLighting(); } } \ No newline at end of file diff --git a/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java b/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java index df0ebaf0f..e64e5c12f 100644 --- a/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java +++ b/src/main/java/com/hbm/tileentity/TileEntityProxyCombo.java @@ -198,13 +198,13 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy public long transferPower(long power) { if(!this.power) - return 0; + return power; if(getTile() instanceof IEnergyConnector) { return ((IEnergyConnector)getTile()).transferPower(power); } - return 0; + return power; } @Override diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityStirling.java b/src/main/java/com/hbm/tileentity/machine/TileEntityStirling.java index dd30f6e98..29578af85 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityStirling.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityStirling.java @@ -160,7 +160,9 @@ public class TileEntityStirling extends TileEntityLoadedBase implements INBTPack } @Override - public void setPower(long power) { } + public void setPower(long power) { + this.powerBuffer = power; + } @Override public long getPower() { diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKConsole.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKConsole.java index 8e87230c0..ac442c39a 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKConsole.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKConsole.java @@ -1,6 +1,7 @@ package com.hbm.tileentity.machine.rbmk; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; @@ -9,6 +10,7 @@ import com.hbm.inventory.fluid.Fluids; import com.hbm.tileentity.TileEntityMachineBase; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKControlManual.RBMKColor; import com.hbm.util.I18nUtil; +import com.hbm.util.Tuple.Triplet; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -30,9 +32,15 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon //made this one-dimensional because it's a lot easier to serialize public RBMKColumn[] columns = new RBMKColumn[15 * 15]; + + public RBMKScreen[] screens = new RBMKScreen[6]; public TileEntityRBMKConsole() { super(0); + + for(int i = 0; i < screens.length; i++) { + screens[i] = new RBMKScreen(); + } } @Override @@ -50,9 +58,10 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon this.worldObj.theProfiler.startSection("rbmkConsole_rescan"); rescan(); this.worldObj.theProfiler.endSection(); - - prepareNetworkPack(); + prepareScreenInfo(); } + + prepareNetworkPack(); } } @@ -93,19 +102,103 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon this.fluxBuffer[19] = (int) flux; } + private void prepareScreenInfo() { + + for(RBMKScreen screen : this.screens) { + + if(screen.type == ScreenType.NONE) { + screen.display = null; + continue; + } + + double value = 0; + int count = 0; + + for(Integer i : screen.columns) { + + RBMKColumn col = this.columns[i]; + + if(col == null) + continue; + + switch(screen.type) { + case COL_TEMP: + count++; + value += col.data.getDouble("heat"); + break; + case FUEL_DEPLETION: + if(col.data.hasKey("enrichment")) { + count++; + value += (100D - (col.data.getDouble("enrichment") * 100D)); + } + break; + case FUEL_POISON: + if(col.data.hasKey("xenon")) { + count++; + value += col.data.getDouble("xenon") * 100D; + } + break; + case FUEL_TEMP: + if(col.data.hasKey("c_heat")) { + count++; + value += col.data.getDouble("c_heat"); + } + break; + case ROD_EXTRACTION: + if(col.data.hasKey("level")) { + count++; + value += col.data.getDouble("level") * 100; + } + break; + } + } + + double result = value / (double) count; + String text = ((int)(result * 10)) / 10D + ""; + + switch(screen.type) { + case COL_TEMP: text = "rbmk.screen.temp=" + text + "°C"; break; + case FUEL_DEPLETION: text = "rbmk.screen.depletion=" + text + "%"; break; + case FUEL_POISON: text = "rbmk.screen.xenon=" + text + "%"; break; + case FUEL_TEMP: text = "rbmk.screen.core=" + text + "°C"; break; + case ROD_EXTRACTION: text = "rbmk.screen.rod=" + text + "%"; break; + } + + screen.display = text; + } + } + private void prepareNetworkPack() { NBTTagCompound data = new NBTTagCompound(); + - for(int i = 0; i < columns.length; i++) { + if(this.worldObj.getTotalWorldTime() % 10 == 0) { - if(this.columns[i] != null) { - data.setTag("column_" + i, this.columns[i].data); - data.setShort("type_" + i, (short)this.columns[i].type.ordinal()); + data.setBoolean("full", true); + + for(int i = 0; i < columns.length; i++) { + + if(this.columns[i] != null) { + data.setTag("column_" + i, this.columns[i].data); + data.setShort("type_" + i, (short)this.columns[i].type.ordinal()); + } + } + + data.setIntArray("flux", this.fluxBuffer); + + for(int i = 0; i < this.screens.length; i++) { + RBMKScreen screen = screens[i]; + if(screen.display != null) { + data.setString("t" + i, screen.display); + } } } - data.setIntArray("flux", this.fluxBuffer); + for(int i = 0; i < this.screens.length; i++) { + RBMKScreen screen = screens[i]; + data.setByte("s" + i, (byte) screen.type.ordinal()); + } this.networkPack(data, 50); } @@ -113,16 +206,28 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon @Override public void networkUnpack(NBTTagCompound data) { - this.columns = new RBMKColumn[15 * 15]; - - for(int i = 0; i < columns.length; i++) { + if(data.getBoolean("full")) { + this.columns = new RBMKColumn[15 * 15]; - if(data.hasKey("type_" + i)) { - this.columns[i] = new RBMKColumn(ColumnType.values()[data.getShort("type_" + i)], (NBTTagCompound)data.getTag("column_" + i)); + for(int i = 0; i < columns.length; i++) { + + if(data.hasKey("type_" + i)) { + this.columns[i] = new RBMKColumn(ColumnType.values()[data.getShort("type_" + i)], (NBTTagCompound)data.getTag("column_" + i)); + } + } + + this.fluxBuffer = data.getIntArray("flux"); + + for(int i = 0; i < this.screens.length; i++) { + RBMKScreen screen = screens[i]; + screen.display = data.getString("t" + i); } } - this.fluxBuffer = data.getIntArray("flux"); + for(int i = 0; i < this.screens.length; i++) { + RBMKScreen screen = screens[i]; + screen.type = ScreenType.values()[data.getByte("s" + i)]; + } } @Override @@ -155,6 +260,27 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon } } } + + if(data.hasKey("toggle")) { + int slot = data.getByte("toggle"); + int next = this.screens[slot].type.ordinal() + 1; + ScreenType type = ScreenType.values()[next % ScreenType.values().length]; + this.screens[slot].type = type; + } + + if(data.hasKey("id")) { + int slot = data.getByte("id"); + List list = new ArrayList(); + + for(int i = 0; i < 15 * 15; i++) { + if(data.getBoolean("s" + i)) { + list.add(i); + } + } + + Integer[] cols = list.toArray(new Integer[0]); + this.screens[slot].columns = cols; + } } @Override @@ -182,6 +308,11 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon this.targetX = nbt.getInteger("tX"); this.targetY = nbt.getInteger("tY"); this.targetZ = nbt.getInteger("tZ"); + + for(int i = 0; i < this.screens.length; i++) { + this.screens[i].type = ScreenType.values()[nbt.getByte("t" + i)]; + this.screens[i].columns = Arrays.stream(nbt.getIntArray("s" + i)).boxed().toArray(Integer[]::new); + } } @Override @@ -191,6 +322,11 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon nbt.setInteger("tX", this.targetX); nbt.setInteger("tY", this.targetY); nbt.setInteger("tZ", this.targetZ); + + for(int i = 0; i < this.screens.length; i++) { + nbt.setByte("t" + i, (byte) this.screens[i].type.ordinal()); + nbt.setIntArray("s" + i, Arrays.stream(this.screens[i].columns).mapToInt(Integer::intValue).toArray()); + } } public static class RBMKColumn { @@ -292,4 +428,32 @@ public class TileEntityRBMKConsole extends TileEntityMachineBase implements ICon this.offset = offset; } } + + public class RBMKScreen { + public ScreenType type = ScreenType.NONE; + public Integer[] columns = new Integer[0]; + public String display = null; + + public RBMKScreen() { } + public RBMKScreen(ScreenType type, Integer[] columns, String display) { + this.type = type; + this.columns = columns; + this.display = display; + } + } + + public static enum ScreenType { + NONE(0 * 18), + COL_TEMP(1 * 18), + ROD_EXTRACTION(2 * 18), + FUEL_DEPLETION(3 * 18), + FUEL_POISON(4 * 18), + FUEL_TEMP(5 * 18); + + public int offset; + + private ScreenType(int offset) { + this.offset = offset; + } + } } diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutgasser.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutgasser.java index 780abe209..44d309f01 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutgasser.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKOutgasser.java @@ -91,7 +91,7 @@ public class TileEntityRBMKOutgasser extends TileEntityRBMKSlottedBase implement recipes.put(new ComparableStack(Items.mushroom_stew), new ItemStack(ModItems.glowing_stew)); } - private boolean canProcess() { + public boolean canProcess() { if(slots[0] == null) return false; diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java index 5e46da82d..ed3c69a31 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java @@ -175,6 +175,15 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM return 0; } } + + if(te instanceof TileEntityRBMKOutgasser) { + TileEntityRBMKOutgasser rod = (TileEntityRBMKOutgasser)te; + + if(!rod.canProcess()) { + return flux; + } + } + if(te instanceof IRBMKFluxReceiver) { IRBMKFluxReceiver rod = (IRBMKFluxReceiver)te; rod.receiveFlux(stream, flux); diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index 9ba6c7c94..1dfb75ba8 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -3349,6 +3349,13 @@ rbmk.heat=Column temperature: %s rbmk.boiler.water=Feedwater: %s / %s rbmk.boiler.steam=Steam: %s / %s rbmk.boiler.type=Compressor: %s +rbmk.console.assign=Assign selected columns to screen #%s +rbmk.console.none=Off +rbmk.console.col_temp=Monitor average column temperature +rbmk.console.rod_extraction=Monitor average control rod extraction +rbmk.console.fuel_depletion=Monitor average fuel depletion +rbmk.console.fuel_poison=Monitor average xenon poisoning +rbmk.console.fuel_temp=Monitor average fuel temperature rbmk.control.level=%s rbmk.control.red=§cRed Group rbmk.control.yellow=§eYellow Group @@ -3360,6 +3367,11 @@ rbmk.rod.depletion=Depletion: %s rbmk.rod.xenon=Xenon poison: %s rbmk.rod.coreTemp=Core temperature: %s rbmk.rod.skinTemp=Skin temperature: %s / %s +rbmk.screen.core=Core: %s +rbmk.screen.depletion=Depl: %s +rbmk.screen.rod=Control: %s +rbmk.screen.temp=Temp: %s +rbmk.screen.xenon=Xenon: %s soundCategory.ntmMachines=NTM Machines diff --git a/src/main/resources/assets/hbm/textures/gui/reactors/gui_rbmk_console.png b/src/main/resources/assets/hbm/textures/gui/reactors/gui_rbmk_console.png index 352ca62f508c408925e1cf52ff3259bc60ea8c22..8771329375e75fd9e63ccd3ce38691e5f6f7106f 100644 GIT binary patch literal 6569 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 O1<=(r(kNAPi25(&%t8JD literal 6111 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 W>VGgo9SEJ+1A~($x@FqV;r|6tl_oL( diff --git a/src/main/resources/assets/hbm/textures/models/machines/mixer.png b/src/main/resources/assets/hbm/textures/models/machines/mixer.png new file mode 100644 index 0000000000000000000000000000000000000000..39101a8da27307692b7bdcb7d3b8c32cb3197787 GIT binary patch literal 1931 zcmd6ni8tG67soTTbuhGwGcTjGl-e4kYH#x+k)$CZvRNy!1W7ct#}-Q~h@lwU#M&}r zYDp7}T8EC-5a}q!Qlnlkwazd~tFJQNbpDF>o^$U#&$-`oKhJZ|Jx`7Y2JwZWmLdoQ z`T~W7;iQ=%b(_;N()fD!mROoTi^d_GL9H*o+K?V(X@ENb0tpM0jwo`{+Jc809-fg= z7#K*mv2kLtl2cQ^=5X@aY;JUP8iTIypJ1suIM<-;0Xk&}h+AD%0PeMj}yhI6oJcn@&z}TiY8D zh~1Sdkg~EyFxcAK+QHr)fI<;)xH}r{<>BE&BnJBVg;FRC8ZC;!NQjNiC@Om3?;l1c zQ@yHGAS%9hCm3QQX~ER zq;v`jN9O_kHIxaWCUgzl7iD_q*1C zHE(j!Z^xMR`C1Rtu8+qeU!{94=lg7yQAjy+_E5N+H7zto8X58SdH zWjIf<(F!aZvtL(2~&w^G1GZ4(C&#BxYgBAc++^JEU?L0e>m*=P_W}*pzQ*e zFv@gpMHtScU{(rz+p%V^GCVuIz}+M(2@AeiMtK>BoJqy>kgTL*XU3vFtwl`?4&x=A z^Z&7d-lpz+y7A{Mq<1t3q%!cyKZ}^o`CPiUc_p(sHyqoTIlX^Y8@dtUG)r5k3XxV*n;0>bDH+}RXy|dJzdPn9ixi5dB$pd zTU$lt3=BxtkC+}gb^Zs6O!eB9dU6GJY3IXs>1(wj0Ra6gZD>}hT366bf487>puXKF zXroJx=|R38e7Lf5!s!f9xacchh#ik?Gjx8P{rI5n$v}LUEPuhN0QrcgXLm{7*i%e2 zl-f|a3rNR1h=Eg@N zJtG}G8>DTUa_=UqSTbiqCepC%rL_Ank-_gZLpvbF-&&v4ps0zV>emvVu7-HW zL4AH>ggr?Lo?KrwuX6J3WG)IJ%JJK?{Y*M`tyJ=m@7m4f5)tZ<{OWeLm754Kr)zF& z&G*rE`j6l3=Ex{;xw+5kmNFF#pKpCU_;aBxi9!0HPJRAz@|vnrk&3fRlEk*ngY_C~#lKk1*Z{Wda5b%GxAUlYJXvs>hdt)tl&e05MpY5kL zqM=OyZvDt6*T$YP?V^Tg>}yE1D1}0_eiv2ns8;YvsPd1H4;vp`kL4SQ!xV;YwvvtH z8ub6pl8CMPGRY$vNyQg&v)vN0s6F$ShC)AK=VgP8SB_@m)j;z~ZcAaU^nt{cv|e{$ z11pN$6OHBg2|IAw{IU?tO74Hv)d1%CX$=L-tPFmiS@hGSwS@yr|HQp$WvKQtZVzmz?9M!!g0dxV@*( z=FpvF#`fmXX!fzZaNf&CQ}4Y4@Av|BhPLx~cI@~4qYejC{r77lKSg4X`&gSbc*fEn uU7TMRk5s99lhF_e>ASVt9bnDj6PYaQhPb<}%^A|q3WS1VV6D!98UF*Psmgc& literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/models/machines/rbmk_control.png b/src/main/resources/assets/hbm/textures/models/machines/rbmk_control.png index ad6377034c15c86da674b9e780903e58a5a6ad9f..203602b6b9ddef67f580fa22f91f4236589b2aa7 100644 GIT binary patch literal 4317 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 delta 4231 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 R1(@9!JYD@<);T3K0RYu^ltBOh literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/models/projectiles/himars_standard.png b/src/main/resources/assets/hbm/textures/models/projectiles/himars_standard.png new file mode 100644 index 0000000000000000000000000000000000000000..79604841b1ddc34f0073ade29ba6080ce6d110d1 GIT binary patch literal 543 zcmeAS@N?(olHy`uVBq!ia0vp^0YDtW!3HEn8#e3)QY^(zo*^7SP{WbZ!N9h_D%H7eD>A+-duap01>(SpK zfm>ep*!dcj%`wUKs*T#v@Op8s|GL~=>vopx*?s8xb%(xFtO13OzfQl=7yx22UZ4I> zeiQRTnW@|h9vyqFe=^+e-lIRyLY~f%3D;aaui^D?=iAGt1Qq|^uJD)V&lk~@mCOD= z4_A6=uun+yrJMDKj!AiE3O5@q6D+B{zVP~Xh(S#2^zYiIusbcz+}r=T;}jt zD5Z(7%TGMP096Ilf6_ns(Z}15rz@Y|fBfU~V6VU1i%$d}pZUvX)6Kl?-TzXZa`&|Y zRe!46zdrWxqMMBq7@aEj#$8{Rc<~L;dd1}iK$o#`ShgyHt=HrMtME%a!3T6k5tnnB zLQ2Dh7iwRE!d%6y=f@3{u6{1- HoD!M<^ri95 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/models/turrets/himars.png b/src/main/resources/assets/hbm/textures/models/turrets/himars.png new file mode 100644 index 0000000000000000000000000000000000000000..1d468f35540a38e9a393e5ff2ff55587f5993adc GIT binary patch literal 3158 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 LT