From bb84ebe2092cf16fa080bfffb73ce18b09c19bb6 Mon Sep 17 00:00:00 2001 From: George Paton Date: Wed, 26 Feb 2025 15:38:31 +1100 Subject: [PATCH 1/3] Fix #1918 - make sure node caching is per world, remove nodes from cache correctly, and prevent unloading dimensions immediately ceasing all reactivity. Also fixes rod information not updating unless the GUI is open --- .../com/hbm/blocks/machine/rbmk/RBMKBase.java | 74 ++++---- .../hbm/handler/neutron/NeutronHandler.java | 52 ++---- .../hbm/handler/neutron/NeutronNodeWorld.java | 117 ++++++++----- .../hbm/handler/neutron/NeutronStream.java | 10 +- .../handler/neutron/PileNeutronHandler.java | 42 ++--- .../handler/neutron/RBMKNeutronHandler.java | 160 +++++++++--------- .../com/hbm/items/machine/ItemRBMKLid.java | 28 +-- .../java/com/hbm/main/ModEventHandler.java | 3 +- .../machine/pile/TileEntityPileBase.java | 15 +- .../machine/rbmk/TileEntityRBMKBase.java | 28 +-- .../machine/rbmk/TileEntityRBMKRod.java | 74 ++++---- .../machine/rbmk/TileEntityRBMKRodReaSim.java | 10 +- 12 files changed, 321 insertions(+), 292 deletions(-) diff --git a/src/main/java/com/hbm/blocks/machine/rbmk/RBMKBase.java b/src/main/java/com/hbm/blocks/machine/rbmk/RBMKBase.java index 234a2a4b9..6dba321ce 100644 --- a/src/main/java/com/hbm/blocks/machine/rbmk/RBMKBase.java +++ b/src/main/java/com/hbm/blocks/machine/rbmk/RBMKBase.java @@ -58,31 +58,31 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo public int getOffset() { return 0; } - + public boolean openInv(World world, int x, int y, int z, EntityPlayer player) { - + if(world.isRemote) { return true; } - + int[] pos = this.findCore(world, x, y, z); - + if(pos == null) return false; - + TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]); - + if(!(te instanceof TileEntityRBMKBase)) return false; - + TileEntityRBMKBase rbmk = (TileEntityRBMKBase) te; - + if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemRBMKLid) { - + if(!rbmk.hasLid()) return false; } - + if(!player.isSneaking()) { FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, pos[0], pos[1], pos[2]); return true; @@ -93,27 +93,27 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo @Override public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { - + float height = 0.0F; - + int[] pos = this.findCore(world, x, y, z); - + if(pos != null) { TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]); - + if(te instanceof TileEntityRBMKBase) { - + TileEntityRBMKBase rbmk = (TileEntityRBMKBase) te; - + if(rbmk.hasLid()) { height += 0.25F; } } } - + return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY + height, z + this.maxZ); } - + /* * NORTH: no cover * EAST: concrete cover @@ -130,21 +130,21 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo MultiblockHandlerXR.fillSpace(world, x + dir.offsetX * o, y + dir.offsetY * o, z + dir.offsetZ * o, getDimensions(world), this, dir); this.makeExtra(world, x, y + RBMKDials.getColumnHeight(world), z); } - + @Override protected ForgeDirection getDirModified(ForgeDirection dir) { return DIR_NO_LID; } - + public int[] getDimensions(World world) { return new int[] {RBMKDials.getColumnHeight(world), 0, 0, 0, 0, 0}; } @Override public void breakBlock(World world, int x, int y, int z, Block b, int i) { - + if(!world.isRemote && dropLids) { - + if(i == DIR_NORMAL_LID.ordinal() + offset) { world.spawnEntityInWorld(new EntityItem(world, x + 0.5, y + 0.5 + RBMKDials.getColumnHeight(world), z + 0.5, new ItemStack(ModItems.rbmk_lid))); } @@ -152,32 +152,32 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo world.spawnEntityInWorld(new EntityItem(world, x + 0.5, y + 0.5 + RBMKDials.getColumnHeight(world), z + 0.5, new ItemStack(ModItems.rbmk_lid_glass))); } } - + super.breakBlock(world, x, y, z, b, i); } - + @Override public boolean onScrew(World world, EntityPlayer player, int x, int y, int z, int side, float fX, float fY, float fZ, ToolType tool) { - + if(tool != ToolType.SCREWDRIVER) return false; - + int[] pos = this.findCore(world, x, y, z); - + if(pos != null) { TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]); - + if(te instanceof TileEntityRBMKBase) { - + TileEntityRBMKBase rbmk = (TileEntityRBMKBase) te; int i = rbmk.getBlockMetadata(); - + if(rbmk.hasLid() && rbmk.isLidRemovable()) { - RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(new BlockPos(te)); - if (node != null) + RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(world, new BlockPos(te)); + if(node != null) node.removeLid(); - + if(!world.isRemote) { if(i == DIR_NORMAL_LID.ordinal() + offset) { world.spawnEntityInWorld(new EntityItem(world, pos[0] + 0.5, pos[1] + 0.5 + RBMKDials.getColumnHeight(world), pos[2] + 0.5, new ItemStack(ModItems.rbmk_lid))); @@ -185,15 +185,15 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo if(i == DIR_GLASS_LID.ordinal() + offset) { world.spawnEntityInWorld(new EntityItem(world, pos[0] + 0.5, pos[1] + 0.5 + RBMKDials.getColumnHeight(world), pos[2] + 0.5, new ItemStack(ModItems.rbmk_lid_glass))); } - - world.setBlockMetadataWithNotify(pos[0], pos[1], pos[2], DIR_NO_LID.ordinal() + this.offset, 3); + + world.setBlockMetadataWithNotify(pos[0], pos[1], pos[2], DIR_NO_LID.ordinal() + offset, 3); } - + return true; } } } - + return false; } diff --git a/src/main/java/com/hbm/handler/neutron/NeutronHandler.java b/src/main/java/com/hbm/handler/neutron/NeutronHandler.java index efc536f2e..d05472427 100644 --- a/src/main/java/com/hbm/handler/neutron/NeutronHandler.java +++ b/src/main/java/com/hbm/handler/neutron/NeutronHandler.java @@ -1,13 +1,10 @@ package com.hbm.handler.neutron; import com.hbm.tileentity.machine.rbmk.RBMKDials; -import com.hbm.util.fauxpointtwelve.BlockPos; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.TickEvent; import net.minecraft.world.World; -import java.util.ArrayList; -import java.util.List; import java.util.Map; @@ -21,20 +18,16 @@ public class NeutronHandler { if(event.phase != TickEvent.Phase.START) return; + // Freshen the node cache every `cacheTime` ticks to prevent huge RAM usage from idle nodes. + int cacheTime = 20; + boolean cacheClear = ticks >= cacheTime; + if(cacheClear) ticks = 0; + ticks++; + // Remove `StreamWorld` objects if they have no streams. - { // aflghdkljghlkbhfjkghgilurbhlkfjghkffdjgn - List toRemove = new ArrayList<>(); - NeutronNodeWorld.streamWorlds.forEach((world, streamWorld) -> { - if (streamWorld.streams.isEmpty()) - toRemove.add(world); - }); + NeutronNodeWorld.removeEmptyWorlds(); - for (World world : toRemove) { - NeutronNodeWorld.streamWorlds.remove(world); - } - } - - for (Map.Entry world : NeutronNodeWorld.streamWorlds.entrySet()) { + for(Map.Entry world : NeutronNodeWorld.streamWorlds.entrySet()) { // Gamerule caching because this apparently is kinda slow? // meh, good enough @@ -48,33 +41,10 @@ public class NeutronHandler { RBMKNeutronHandler.columnHeight = RBMKDials.getColumnHeight(world.getKey()) + 1; RBMKNeutronHandler.fluxRange = RBMKDials.getFluxRange(world.getKey()); - for (NeutronStream stream : world.getValue().streams) { - stream.runStreamInteraction(world.getKey()); - } + world.getValue().runStreamInteractions(world.getKey()); world.getValue().removeAllStreams(); + + if(cacheClear) world.getValue().cleanNodes(); } - - // Freshen the node cache every `cacheTime` ticks to prevent huge RAM usage from idle nodes. - int cacheTime = 20; - if (ticks >= cacheTime) { - ticks = 0; - List toRemove = new ArrayList<>(); - for (NeutronNode cachedNode : NeutronNodeWorld.nodeCache.values()) { - if (cachedNode.type == NeutronStream.NeutronType.RBMK) { - RBMKNeutronHandler.RBMKNeutronNode node = (RBMKNeutronHandler.RBMKNeutronNode) cachedNode; - toRemove.addAll(node.checkNode()); - } - /* TODO: actually do this and uncache pile nodes - if (cachedNode.type == NeutronStream.NeutronType.PILE) { - PileNeutronNode node = (PileNeutronNode) cachedNode; - toRemove.addAll(node.checkNode()); - } - */ - } - - toRemove.forEach(NeutronNodeWorld::removeNode); - - } - ticks++; } } diff --git a/src/main/java/com/hbm/handler/neutron/NeutronNodeWorld.java b/src/main/java/com/hbm/handler/neutron/NeutronNodeWorld.java index 1f544ae7f..6dcbb4684 100644 --- a/src/main/java/com/hbm/handler/neutron/NeutronNodeWorld.java +++ b/src/main/java/com/hbm/handler/neutron/NeutronNodeWorld.java @@ -8,55 +8,94 @@ import java.util.HashMap; import java.util.List; public class NeutronNodeWorld { - // HashMap of all neutron nodes and their positions. - protected static HashMap nodeCache = new HashMap<>(); - - public static void addNode(NeutronNode node) { - nodeCache.put(node.pos, node); - } - - public static void removeNode(BlockPos position) { - nodeCache.remove(position); - } - - public static NeutronNode getNode(BlockPos position) { - return nodeCache.get(position); - } - - public static void removeAllNodes() { - nodeCache.clear(); - } // List of all stream worlds. public static HashMap streamWorlds = new HashMap<>(); - public static class StreamWorld { + public static NeutronNode getNode(World world, BlockPos pos) { + StreamWorld streamWorld = streamWorlds.get(world); + return streamWorld != null ? streamWorld.nodeCache.get(pos) : null; + } - List streams; + public static void addNode(World world, NeutronNode node) { + StreamWorld streamWorld = getOrAddWorld(world); + streamWorld.nodeCache.put(node.pos, node); + } - public StreamWorld() { - streams = new ArrayList<>(); - } - - public void addStream(NeutronStream stream) { - this.streams.add(stream); - } - - public void removeAllStreams() { - this.streams.clear(); - } - - public void removeAllStreamsOfType(NeutronStream.NeutronType type) { - List toRemove = new ArrayList<>(); - for (NeutronStream stream : streams) { - if (stream.type == type) - toRemove.add(stream); - } - toRemove.forEach((stream) -> streams.remove(stream)); + public static void removeNode(World world, BlockPos pos) { + StreamWorld streamWorld = streamWorlds.get(world); + if(streamWorld == null) return; + streamWorld.removeNode(pos); + } + + public static StreamWorld getOrAddWorld(World world) { + StreamWorld streamWorld = streamWorlds.get(world); + if(streamWorld == null) { + streamWorld = new StreamWorld(); + streamWorlds.put(world, streamWorld); } + return streamWorld; } public static void removeAllWorlds() { streamWorlds.clear(); } + + public static void removeEmptyWorlds() { + streamWorlds.values().removeIf((streamWorld) -> { + return streamWorld.streams.isEmpty(); + }); + } + + public static class StreamWorld { + + private List streams; + private HashMap nodeCache = new HashMap<>(); + + public StreamWorld() { + streams = new ArrayList<>(); + } + + public void runStreamInteractions(World world) { + for(NeutronStream stream : streams) { + stream.runStreamInteraction(world); + } + } + + public void addStream(NeutronStream stream) { + streams.add(stream); + } + + public void removeAllStreams() { + streams.clear(); + } + + public void cleanNodes() { + List toRemove = new ArrayList<>(); + for(NeutronNode cachedNode : nodeCache.values()) { + if(cachedNode.type == NeutronStream.NeutronType.RBMK) { + RBMKNeutronHandler.RBMKNeutronNode node = (RBMKNeutronHandler.RBMKNeutronNode) cachedNode; + toRemove.addAll(node.checkNode()); + } + /* TODO: actually do this and uncache pile nodes + if(cachedNode.type == NeutronStream.NeutronType.PILE) { + PileNeutronNode node = (PileNeutronNode) cachedNode; + toRemove.addAll(node.checkNode()); + } + */ + } + + for(BlockPos pos : toRemove) { + nodeCache.remove(pos); + } + } + + public void removeNode(BlockPos pos) { + nodeCache.remove(pos); + } + + public void removeAllStreamsOfType(NeutronStream.NeutronType type) { + streams.removeIf(stream -> stream.type == type); + } + } } diff --git a/src/main/java/com/hbm/handler/neutron/NeutronStream.java b/src/main/java/com/hbm/handler/neutron/NeutronStream.java index 7de1cc4aa..6ef167910 100644 --- a/src/main/java/com/hbm/handler/neutron/NeutronStream.java +++ b/src/main/java/com/hbm/handler/neutron/NeutronStream.java @@ -3,7 +3,6 @@ package com.hbm.handler.neutron; import com.hbm.util.fauxpointtwelve.BlockPos; import net.minecraft.util.Vec3; import net.minecraft.world.World; -import com.hbm.handler.neutron.NeutronNodeWorld.StreamWorld; import java.util.Iterator; @@ -43,13 +42,8 @@ public abstract class NeutronStream { this.fluxQuantity = flux; this.fluxRatio = ratio; this.type = type; - World worldObj = origin.tile.getWorldObj(); - if (NeutronNodeWorld.streamWorlds.get(worldObj) == null) { - StreamWorld world = new StreamWorld(); - world.addStream(this); - NeutronNodeWorld.streamWorlds.put(worldObj, world); - } else - NeutronNodeWorld.streamWorlds.get(worldObj).addStream(this); + + NeutronNodeWorld.getOrAddWorld(origin.tile.getWorldObj()).addStream(this); } protected BlockPos posInstance; diff --git a/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java b/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java index 56913bc91..843b878a2 100644 --- a/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java +++ b/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java @@ -28,9 +28,8 @@ public class PileNeutronHandler { public static PileNeutronNode makeNode(TileEntityPileBase tile) { BlockPos pos = new BlockPos(tile); - if (NeutronNodeWorld.nodeCache.containsKey(pos)) - return (PileNeutronNode) NeutronNodeWorld.getNode(pos); - return new PileNeutronNode(tile); + PileNeutronNode node = (PileNeutronNode) NeutronNodeWorld.getNode(tile.getWorldObj(), pos); + return node != null ? node : new PileNeutronNode(tile); } private static TileEntity blockPosToTE(World worldObj, BlockPos pos) { @@ -43,6 +42,7 @@ public class PileNeutronHandler { super(origin, vector, flux, 0D, NeutronType.PILE); } + @SuppressWarnings("unchecked") @Override public void runStreamInteraction(World worldObj) { @@ -51,27 +51,29 @@ public class PileNeutronHandler { for(float i = 1; i <= range; i += 0.5F) { - BlockPos node = new BlockPos( + BlockPos nodePos = new BlockPos( (int)Math.floor(pos.getX() + 0.5 + vector.xCoord * i), (int)Math.floor(pos.getY() + 0.5 + vector.yCoord * i), (int)Math.floor(pos.getZ() + 0.5 + vector.zCoord * i) ); - if(node.equals(pos)) + if(nodePos.equals(pos)) continue; // don't interact with itself! - pos.mutate(node.getX(), node.getY(), node.getZ()); + pos.mutate(nodePos.getX(), nodePos.getY(), nodePos.getZ()); TileEntity tile; - if (NeutronNodeWorld.nodeCache.containsKey(node)) - tile = NeutronNodeWorld.nodeCache.get(node).tile; - else { - tile = blockPosToTE(worldObj, node); - if (tile == null) - return; // Doesn't exist! - if (tile instanceof TileEntityPileBase) - NeutronNodeWorld.addNode(new PileNeutronNode((TileEntityPileBase) tile)); + NeutronNode node = NeutronNodeWorld.getNode(worldObj, nodePos); + if(node != null) { + tile = node.tile; + } else { + tile = blockPosToTE(worldObj, nodePos); + if(tile == null) return; + + if(tile instanceof TileEntityPileBase) { + NeutronNodeWorld.addNode(worldObj, new PileNeutronNode((TileEntityPileBase) tile)); + } } Block block = tile.getBlockType(); @@ -79,17 +81,17 @@ public class PileNeutronHandler { if(!(tile instanceof TileEntityPileBase)) { // Return when a boron block is hit - if (block == ModBlocks.block_boron) + if(block == ModBlocks.block_boron) return; - else if (block == ModBlocks.concrete || + else if(block == ModBlocks.concrete || block == ModBlocks.concrete_smooth || block == ModBlocks.concrete_asbestos || block == ModBlocks.concrete_colored || block == ModBlocks.brick_concrete) fluxQuantity *= 0.25; - if (block == ModBlocks.block_graphite_rod && (meta & 8) == 0) + if(block == ModBlocks.block_graphite_rod && (meta & 8) == 0) return; } @@ -102,9 +104,9 @@ public class PileNeutronHandler { return; } - int x = (int) (node.getX() + 0.5); - int y = (int) (node.getY() + 0.5); - int z = (int) (node.getZ() + 0.5); + int x = (int) (nodePos.getX() + 0.5); + int y = (int) (nodePos.getY() + 0.5); + int z = (int) (nodePos.getZ() + 0.5); List entities = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(x, y, z, x, y, z)); if(entities != null) diff --git a/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java b/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java index d3f883589..aa3574361 100644 --- a/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java +++ b/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java @@ -39,9 +39,8 @@ public class RBMKNeutronHandler { public static RBMKNeutronNode makeNode(TileEntityRBMKBase tile) { BlockPos pos = new BlockPos(tile); - if (NeutronNodeWorld.nodeCache.containsKey(pos)) - return (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); - return new RBMKNeutronNode(tile, tile.getRBMKType(), tile.hasLid()); + RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(tile.getWorldObj(), pos); + return node != null ? node : new RBMKNeutronNode(tile, tile.getRBMKType(), tile.hasLid()); } public static class RBMKNeutronNode extends NeutronNode { @@ -79,16 +78,16 @@ public class RBMKNeutronHandler { @Override public BlockPos next() { - if (Math.pow(x, 2) + Math.pow(z, 2) <= fluxRange * fluxRange) { + if(Math.pow(x, 2) + Math.pow(z, 2) <= fluxRange * fluxRange) { z++; - if (z > fluxRange) { + if(z > fluxRange) { z = -fluxRange; x++; } return posInstance.mutate(tile.xCoord + x, tile.yCoord, tile.zCoord + z); } else { z++; - if (z > fluxRange) { + if(z > fluxRange) { z = -fluxRange; x++; } @@ -102,23 +101,24 @@ public class RBMKNeutronHandler { List list = new ArrayList<>(); BlockPos pos = new BlockPos(this.tile); + World world = tile.getWorldObj(); RBMKNeutronStream[] streams = new RBMKNeutronStream[TileEntityRBMKRod.fluxDirs.length]; // Simulate streams coming out of the RBMK rod. ForgeDirection[] fluxDirs = TileEntityRBMKRod.fluxDirs; - for (int i = 0; i < fluxDirs.length; i++) { + for(int i = 0; i < fluxDirs.length; i++) { streams[i] = (new RBMKNeutronStream(this, Vec3.createVectorHelper(fluxDirs[i].offsetX, 0, fluxDirs[i].offsetZ))); } // Check if the rod should uncache nodes. - if (tile instanceof TileEntityRBMKRod && !(tile instanceof TileEntityRBMKRodReaSim)) { + if(tile instanceof TileEntityRBMKRod && !(tile instanceof TileEntityRBMKRodReaSim)) { TileEntityRBMKRod rod = (TileEntityRBMKRod) tile; - if (!rod.hasRod || rod.lastFluxQuantity == 0) { + if(!rod.hasRod || rod.lastFluxQuantity == 0) { - for (RBMKNeutronStream stream : streams) { - for(RBMKNeutronNode node : stream.getNodes(false)) - if (node != null) + for(RBMKNeutronStream stream : streams) { + for(NeutronNode node : stream.getNodes(false)) + if(node != null) list.add(new BlockPos(node.tile)); } @@ -130,11 +130,11 @@ public class RBMKNeutronHandler { Iterator reaSimNodes = getReaSimNodes(); // Check if the ReaSim rod should be culled from the cache due to no rod or no flux. - if (tile instanceof TileEntityRBMKRodReaSim) { // fuckkkkkkk + if(tile instanceof TileEntityRBMKRodReaSim) { // fuckkkkkkk TileEntityRBMKRodReaSim rod = (TileEntityRBMKRodReaSim) tile; - if (!rod.hasRod || rod.lastFluxQuantity == 0) { + if(!rod.hasRod || rod.lastFluxQuantity == 0) { reaSimNodes.forEachRemaining((a) -> { - if (a != null) + if(a != null) list.add(a.clone()); // ae The RAM usage will be really high here but hopefully the GC can take care of it :pray: }); return list; @@ -155,32 +155,32 @@ public class RBMKNeutronHandler { if(nodePos == null) continue; - NeutronNode node = NeutronNodeWorld.nodeCache.get(nodePos); + NeutronNode node = NeutronNodeWorld.getNode(world, nodePos); - if (node != null && node.tile instanceof TileEntityRBMKRod) { + if(node != null && node.tile instanceof TileEntityRBMKRod) { TileEntityRBMKRod rod = (TileEntityRBMKRod) node.tile; - if (rod.hasRod && rod.lastFluxQuantity > 0) { + if(rod.hasRod && rod.lastFluxQuantity > 0) { hasRod = true; break; } } } - if (!hasRod) { + if(!hasRod) { list.add(pos); return list; } } // Check if non-rod nodes should be uncached due to no rod in range. - for (RBMKNeutronStream stream : streams) { + for(RBMKNeutronStream stream : streams) { - RBMKNeutronNode[] nodes = stream.getNodes(false); + NeutronNode[] nodes = stream.getNodes(false); - for (RBMKNeutronNode node : nodes) { - if (!(node == null) && node.tile instanceof TileEntityRBMKRod) + for(NeutronNode node : nodes) { + if(!(node == null) && node.tile instanceof TileEntityRBMKRod) return list; } } @@ -209,28 +209,28 @@ public class RBMKNeutronHandler { // Does NOT include the origin node // USES THE CACHE!!! - public RBMKNeutronNode[] getNodes(boolean addNode) { - RBMKNeutronNode[] positions = new RBMKNeutronNode[fluxRange]; + public NeutronNode[] getNodes(boolean addNode) { + NeutronNode[] positions = new RBMKNeutronNode[fluxRange]; BlockPos pos = new BlockPos(origin.tile); + World world = origin.tile.getWorldObj(); - for (int i = 1; i <= fluxRange; i++) { + for(int i = 1; i <= fluxRange; i++) { int x = (int) Math.floor(0.5 + vector.xCoord * i); int z = (int) Math.floor(0.5 + vector.zCoord * i); pos.mutate(origin.tile.xCoord + x, origin.tile.yCoord, origin.tile.zCoord + z); - if (NeutronNodeWorld.nodeCache.containsKey(pos)) - positions[i - 1] = (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); - - else if (this.origin.tile.getBlockType() instanceof RBMKBase) { - TileEntity te = blockPosToTE(this.origin.tile.getWorldObj(), pos); - if (te instanceof TileEntityRBMKBase) { + NeutronNode node = NeutronNodeWorld.getNode(world, pos); + if(node != null) { + positions[i - 1] = node; + } else if(this.origin.tile.getBlockType() instanceof RBMKBase) { + TileEntity te = blockPosToTE(world, pos); + if(te instanceof TileEntityRBMKBase) { TileEntityRBMKBase rbmkBase = (TileEntityRBMKBase) te; - RBMKNeutronNode node = makeNode(rbmkBase); + node = makeNode(rbmkBase); positions[i - 1] = node; - if (addNode) - NeutronNodeWorld.addNode(node); + if(addNode) NeutronNodeWorld.addNode(world, node); } } } @@ -241,20 +241,21 @@ public class RBMKNeutronHandler { public void runStreamInteraction(World worldObj) { // do nothing if there's nothing to do lmao - if (fluxQuantity == 0D) + if(fluxQuantity == 0D) return; BlockPos pos = new BlockPos(origin.tile); TileEntityRBMKBase originTE; - if (NeutronNodeWorld.nodeCache.containsKey(pos)) - originTE = (TileEntityRBMKBase) NeutronNodeWorld.nodeCache.get(pos).tile; - else { + NeutronNode node = NeutronNodeWorld.getNode(worldObj, pos); + if(node != null) { + originTE = (TileEntityRBMKBase) node.tile; + } else { originTE = (TileEntityRBMKBase) blockPosToTE(worldObj, pos); - if (originTE == null) - return; // Doesn't exist anymore! - NeutronNodeWorld.addNode(new RBMKNeutronNode(originTE, originTE.getRBMKType(), originTE.hasLid())); + if(originTE == null) return; // Doesn't exist anymore! + + NeutronNodeWorld.addNode(worldObj, new RBMKNeutronNode(originTE, originTE.getRBMKType(), originTE.hasLid())); } int moderatedCount = 0; @@ -263,23 +264,22 @@ public class RBMKNeutronHandler { while(iterator.hasNext()) { - BlockPos nodePos = iterator.next(); + BlockPos targetPos = iterator.next(); - if (fluxQuantity == 0D) // Whoops, used it all up! + if(fluxQuantity == 0D) // Whoops, used it all up! return; - RBMKNeutronNode node; - - if (!NeutronNodeWorld.nodeCache.containsKey(nodePos)) { - TileEntity te = blockPosToTE(worldObj, nodePos); // ok, maybe it didn't get added to the list somehow?? - if (te instanceof TileEntityRBMKBase) { - node = makeNode((TileEntityRBMKBase) te); - NeutronNodeWorld.addNode(node); // whoops! + NeutronNode targetNode = NeutronNodeWorld.getNode(worldObj, targetPos); + if(targetNode == null) { + TileEntity te = blockPosToTE(worldObj, targetPos); // ok, maybe it didn't get added to the list somehow?? + if(te instanceof TileEntityRBMKBase) { + targetNode = makeNode((TileEntityRBMKBase) te); + NeutronNodeWorld.addNode(worldObj, targetNode); // whoops! } else { - int hits = getHits(nodePos); // Get the amount of hits on blocks. - if (hits == columnHeight) // If stream is fully blocked. + int hits = getHits(targetPos); // Get the amount of hits on blocks. + if(hits == columnHeight) // If stream is fully blocked. return; - else if (hits > 0) { // If stream is partially blocked. + else if(hits > 0) { // If stream is partially blocked. irradiateFromFlux(pos, hits); fluxQuantity *= 1 - ((double) hits / columnHeight); // Inverse to get partial blocking by blocks. continue; @@ -290,81 +290,79 @@ public class RBMKNeutronHandler { } } - node = (RBMKNeutronNode) NeutronNodeWorld.nodeCache.get(nodePos); + RBMKType type = (RBMKType) targetNode.data.get("type"); - RBMKType type = (RBMKType) node.data.get("type"); - - if (type == RBMKType.OTHER) // pass right on by! + if(type == RBMKType.OTHER) // pass right on by! continue; // we established earlier during `getNodes()` that they should all be RBMKBase TEs // no issue with casting here! - TileEntityRBMKBase nodeTE = (TileEntityRBMKBase) node.tile; + TileEntityRBMKBase nodeTE = (TileEntityRBMKBase) targetNode.tile; - if (!(boolean) node.data.get("hasLid")) - ChunkRadiationManager.proxy.incrementRad(worldObj, nodePos.getX(), nodePos.getY(), nodePos.getZ(), (float) (this.fluxQuantity * 0.05F)); + if(!(boolean) targetNode.data.get("hasLid")) + ChunkRadiationManager.proxy.incrementRad(worldObj, targetPos.getX(), targetPos.getY(), targetPos.getZ(), (float) (this.fluxQuantity * 0.05F)); - if (type == RBMKType.MODERATOR || nodeTE.isModerated()) { + if(type == RBMKType.MODERATOR || nodeTE.isModerated()) { moderatedCount++; moderateStream(); } - if (nodeTE instanceof IRBMKFluxReceiver) { + if(nodeTE instanceof IRBMKFluxReceiver) { IRBMKFluxReceiver column = (IRBMKFluxReceiver) nodeTE; - if (type == RBMKType.ROD) { + if(type == RBMKType.ROD) { TileEntityRBMKRod rod = (TileEntityRBMKRod) column; - if (rod.hasRod) { + if(rod.hasRod) { rod.receiveFlux(this); return; } - } else if (type == RBMKType.OUTGASSER) { + } else if(type == RBMKType.OUTGASSER) { TileEntityRBMKOutgasser outgasser = ((TileEntityRBMKOutgasser) column); - if (outgasser.canProcess()) { + if(outgasser.canProcess()) { column.receiveFlux(this); return; } } - } else if (type == RBMKType.CONTROL_ROD) { + } else if(type == RBMKType.CONTROL_ROD) { TileEntityRBMKControl rod = (TileEntityRBMKControl) nodeTE; - if (rod.level > 0.0D) { + if(rod.level > 0.0D) { this.fluxQuantity *= rod.getMult(); continue; } return; - } else if (type == RBMKType.REFLECTOR) { + } else if(type == RBMKType.REFLECTOR) { - if (((TileEntityRBMKBase) this.origin.tile).isModerated()) + if(((TileEntityRBMKBase) this.origin.tile).isModerated()) moderatedCount++; - if (this.fluxRatio > 0 && moderatedCount > 0) - for (int i = 0; i < moderatedCount; i++) + if(this.fluxRatio > 0 && moderatedCount > 0) + for(int i = 0; i < moderatedCount; i++) moderateStream(); - if (reflectorEfficiency != 1.0D) { + if(reflectorEfficiency != 1.0D) { this.fluxQuantity *= reflectorEfficiency; continue; } ((TileEntityRBMKRod) originTE).receiveFlux(this); return; - } else if (type == RBMKType.ABSORBER) { - if (absorberEfficiency == 1) + } else if(type == RBMKType.ABSORBER) { + if(absorberEfficiency == 1) return; this.fluxQuantity *= absorberEfficiency; } } - RBMKNeutronNode[] nodes = getNodes(true); + NeutronNode[] nodes = getNodes(true); - RBMKNeutronNode lastNode = nodes[(nodes.length - 1)]; + NeutronNode lastNode = nodes[(nodes.length - 1)]; if(lastNode == null) { // This implies that there was *no* last node, meaning either way it was never caught. // There is really no good way to figure out where exactly it should irradiate, so just irradiate at the origin tile. @@ -374,9 +372,9 @@ public class RBMKNeutronHandler { RBMKType lastNodeType = (RBMKType) lastNode.data.get("type"); - if (lastNodeType == RBMKType.CONTROL_ROD) { + if(lastNodeType == RBMKType.CONTROL_ROD) { TileEntityRBMKControl rod = (TileEntityRBMKControl) lastNode.tile; - if (rod.getMult() > 0.0D) { + if(rod.getMult() > 0.0D) { this.fluxQuantity *= rod.getMult(); irradiateFromFlux(new BlockPos(lastNode.tile.xCoord + this.vector.xCoord, lastNode.tile.yCoord, lastNode.tile.zCoord + this.vector.zCoord)); } @@ -392,7 +390,7 @@ public class RBMKNeutronHandler { // I FUCKING HATE THIS // total count of bugs fixed attributed to this function: 13 Block block = origin.tile.getWorldObj().getBlock(pos.getX(), pos.getY() + h, pos.getZ()); - if (block.isOpaqueCube()) + if(block.isOpaqueCube()) hits += 1; } diff --git a/src/main/java/com/hbm/items/machine/ItemRBMKLid.java b/src/main/java/com/hbm/items/machine/ItemRBMKLid.java index 853fe918f..87e59ca73 100644 --- a/src/main/java/com/hbm/items/machine/ItemRBMKLid.java +++ b/src/main/java/com/hbm/items/machine/ItemRBMKLid.java @@ -20,46 +20,46 @@ public class ItemRBMKLid extends Item { @Override public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float fx, float fy, float fz) { - + Block b = world.getBlock(x, y, z); - + if(b instanceof RBMKBase) { RBMKBase rbmk = (RBMKBase) b; - + int[] pos = rbmk.findCore(world, x, y, z); - + if(pos == null) return false; - + TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]); - + if(!(te instanceof TileEntityRBMKBase)) return false; - + TileEntityRBMKBase tile = (TileEntityRBMKBase) te; - + if(tile.hasLid()) return false; - RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(new BlockPos(te)); - if (node != null) + RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(world, new BlockPos(te)); + if(node != null) node.addLid(); int meta = RBMKBase.DIR_NORMAL_LID.ordinal(); - + if(this == ModItems.rbmk_lid_glass) { meta = RBMKBase.DIR_GLASS_LID.ordinal(); world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, Blocks.glass.stepSound.func_150496_b(), (Blocks.glass.stepSound.getVolume() + 1.0F) / 2.0F, Blocks.glass.stepSound.getPitch() * 0.8F); } else { world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, ModBlocks.concrete_smooth.stepSound.func_150496_b(), (ModBlocks.concrete_smooth.stepSound.getVolume() + 1.0F) / 2.0F, ModBlocks.concrete_smooth.stepSound.getPitch() * 0.8F); } - + world.setBlockMetadataWithNotify(pos[0], pos[1], pos[2], meta + RBMKBase.offset, 3); stack.stackSize--; - + return true; } - + return false; } } diff --git a/src/main/java/com/hbm/main/ModEventHandler.java b/src/main/java/com/hbm/main/ModEventHandler.java index 567ca1edc..292c2a435 100644 --- a/src/main/java/com/hbm/main/ModEventHandler.java +++ b/src/main/java/com/hbm/main/ModEventHandler.java @@ -566,8 +566,7 @@ public class ModEventHandler { @SubscribeEvent public void onUnload(WorldEvent.Unload event) { - NeutronNodeWorld.removeAllWorlds(); // Remove world from worlds when unloaded to avoid world issues. - NeutronNodeWorld.removeAllNodes(); // Remove all nodes. + NeutronNodeWorld.streamWorlds.remove(event.world); } public static boolean didSit = false; diff --git a/src/main/java/com/hbm/tileentity/machine/pile/TileEntityPileBase.java b/src/main/java/com/hbm/tileentity/machine/pile/TileEntityPileBase.java index 0463be416..261c91a0a 100644 --- a/src/main/java/com/hbm/tileentity/machine/pile/TileEntityPileBase.java +++ b/src/main/java/com/hbm/tileentity/machine/pile/TileEntityPileBase.java @@ -17,25 +17,30 @@ public abstract class TileEntityPileBase extends TileEntity { @Override public void invalidate() { super.invalidate(); + NeutronNodeWorld.removeNode(worldObj, new BlockPos(this)); + } - NeutronNodeWorld.removeNode(new BlockPos(this)); + @Override + public void onChunkUnload() { + super.onChunkUnload(); + NeutronNodeWorld.removeNode(worldObj, new BlockPos(this)); } protected void castRay(int flux) { BlockPos pos = new BlockPos(this); - if (flux == 0) { + if(flux == 0) { // simple way to remove the node from the cache when no flux is going into it! - NeutronNodeWorld.removeNode(pos); + NeutronNodeWorld.removeNode(worldObj, pos); return; } - PileNeutronNode node = (PileNeutronNode) NeutronNodeWorld.getNode(pos); + PileNeutronNode node = (PileNeutronNode) NeutronNodeWorld.getNode(worldObj, pos); if(node == null) { node = PileNeutronHandler.makeNode(this); - NeutronNodeWorld.addNode(node); + NeutronNodeWorld.addNode(worldObj, node); } Vec3 neutronVector = Vec3.createVectorHelper(1, 0, 0); diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java index f345b29b5..f196cd5bd 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKBase.java @@ -14,7 +14,6 @@ import com.hbm.main.MainRegistry; import com.hbm.packet.PacketDispatcher; import com.hbm.packet.toclient.AuxParticlePacketNT; import com.hbm.saveddata.TomSaveData; -import com.hbm.tileentity.IBufPacketReceiver; import com.hbm.tileentity.IOverpressurable; import com.hbm.tileentity.TileEntityLoadedBase; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType; @@ -54,7 +53,7 @@ import java.util.Iterator; * @author hbm * */ -public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements IBufPacketReceiver { +public abstract class TileEntityRBMKBase extends TileEntityLoadedBase { public double heat; @@ -133,12 +132,12 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements double heatConsumption = RBMKDials.getBoilerHeatConsumption(worldObj); double availableHeat = (this.heat - 100) / heatConsumption; double availableWater = this.water; - double availableSpace = this.maxSteam - this.steam; + double availableSpace = maxSteam - this.steam; int processedWater = (int) Math.floor(BobMathUtil.min(availableHeat, availableWater, availableSpace) * MathHelper.clamp_double(RBMKDials.getReaSimBoilerSpeed(worldObj), 0D, 1D)); if(processedWater <= 0) return; - + this.water -= processedWater; this.steam += processedWater; this.heat -= processedWater * heatConsumption; @@ -161,7 +160,7 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements if(heat == 20 && RBMKDials.getReasimBoilers(worldObj)) return; - List rec = new ArrayList(); + List rec = new ArrayList<>(); rec.add(this); double heatTot = this.heat; int waterTot = this.water; @@ -227,8 +226,13 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements @Override public void invalidate() { super.invalidate(); + NeutronNodeWorld.removeNode(worldObj, new BlockPos(this)); // woo-fucking-hoo!!! + } - NeutronNodeWorld.removeNode(new BlockPos(this)); // woo-fucking-hoo!!! + @Override + public void onChunkUnload() { + super.onChunkUnload(); + NeutronNodeWorld.removeNode(worldObj, new BlockPos(this)); // woo-fucking-hoo!!! } @Override @@ -304,6 +308,7 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements diag = false; } + @SuppressWarnings("unchecked") @SideOnly(Side.CLIENT) public static void diagnosticPrintHook(RenderGameOverlayEvent.Pre event, World world, int x, int y, int z) { @@ -326,7 +331,7 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements int pX = resolution.getScaledWidth() / 2 + 8; int pZ = resolution.getScaledHeight() / 2; - List exceptions = new ArrayList(); + List exceptions = new ArrayList<>(); exceptions.add("x"); exceptions.add("y"); exceptions.add("z"); @@ -416,10 +421,11 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements worldObj.spawnEntityInWorld(debris); } - public static HashSet columns = new HashSet(); - public static HashSet pipes = new HashSet(); + public static HashSet columns = new HashSet<>(); + public static HashSet pipes = new HashSet<>(); //assumes that !worldObj.isRemote + @SuppressWarnings("unchecked") public void meltdown() { RBMKBase.dropLids = false; @@ -483,8 +489,8 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements /* Hanlde overpressure event */ if(RBMKDials.getOverpressure(worldObj) && !pipes.isEmpty()) { - HashSet pipeBlocks = new HashSet(); - HashSet pipeReceivers = new HashSet(); + HashSet pipeBlocks = new HashSet<>(); + HashSet pipeReceivers = new HashSet<>(); //unify all parts into single sets to prevent redundancy pipes.forEach(x -> { 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 b32166fcf..52ab2a91e 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java @@ -15,6 +15,7 @@ import com.hbm.inventory.gui.GUIRBMKRod; import com.hbm.items.ModItems; import com.hbm.items.machine.ItemRBMKRod; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType; +import com.hbm.util.BufferUtil; import com.hbm.util.CompatEnergyControl; import com.hbm.util.ParticleUtil; @@ -27,7 +28,6 @@ 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.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; @@ -41,7 +41,7 @@ import java.util.ArrayList; import java.util.List; @Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")}) -public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBMKFluxReceiver, IRBMKLoadable, SimpleComponent, IInfoProviderEC, CompatHandler.OCComponent { +public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBMKFluxReceiver, IRBMKLoadable, IInfoProviderEC, CompatHandler.OCComponent { // New system!! // Used for receiving flux (calculating outbound flux/burning rods) @@ -52,6 +52,11 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM public boolean hasRod; + // Fuel rod item data client sync + private String fuelYield; + private String fuelXenon; + private String fuelHeat; + public TileEntityRBMKRod() { super(1); } @@ -94,7 +99,7 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM // Experimental flux ratio curve rods! // Again, nothing really uses this so its just idle code at the moment. - if (rod.specialFluxCurve) { + if(rod.specialFluxCurve) { fluxRatioOut = rod.fluxRatioOut(this.fluxFastRatio, ItemRBMKRod.getEnrichment(slots[0])); @@ -105,7 +110,7 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM fluxQuantityOut = rod.burn(worldObj, slots[0], fluxIn); } else { NType rType = rod.rType; - if (rType == NType.SLOW) + if(rType == NType.SLOW) fluxRatioOut = 0; else fluxRatioOut = 1; @@ -168,7 +173,7 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM double fastFlux = this.fluxQuantity * this.fluxFastRatio; double slowFlux = this.fluxQuantity * (1 - this.fluxFastRatio); - + switch(type) { case SLOW: return slowFlux + fastFlux * 0.5; case FAST: return fastFlux + slowFlux * 0.3; @@ -192,17 +197,17 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM if(pos == null) pos = new BlockPos(this); - if (flux == 0) { + if(flux == 0) { // simple way to remove the node from the cache when no flux is going into it! - NeutronNodeWorld.removeNode(pos); + NeutronNodeWorld.removeNode(worldObj, pos); return; } - RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); + RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(worldObj, pos); if(node == null) { node = RBMKNeutronHandler.makeNode(this); - NeutronNodeWorld.addNode(node); + NeutronNodeWorld.addNode(worldObj, node); } for(ForgeDirection dir : fluxDirs) { @@ -218,10 +223,10 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); - if (nbt.hasKey("fluxFast") || nbt.hasKey("fluxSlow")) { + if(nbt.hasKey("fluxFast") || nbt.hasKey("fluxSlow")) { // recalculate new values to keep stable operations this.fluxQuantity = nbt.getDouble("fluxFast") + nbt.getDouble("fluxSlow"); - if (this.fluxQuantity > 0) + if(this.fluxQuantity > 0) this.fluxFastRatio = nbt.getDouble("fluxFast") / fluxQuantity; else this.fluxFastRatio = 0; @@ -236,7 +241,7 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); - if (!diag) { + if(!diag) { nbt.setDouble("fluxQuantity", this.lastFluxQuantity); nbt.setDouble("fluxMod", this.lastFluxRatio); } else { @@ -252,6 +257,12 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM buf.writeDouble(this.lastFluxQuantity); buf.writeDouble(this.lastFluxRatio); buf.writeBoolean(this.hasRod); + if(this.hasRod) { + ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem()); + BufferUtil.writeString(buf, ItemRBMKRod.getYield(slots[0]) + " / " + rod.yield + " (" + (ItemRBMKRod.getEnrichment(slots[0]) * 100) + "%)"); + BufferUtil.writeString(buf, ItemRBMKRod.getPoison(slots[0]) + "%"); + BufferUtil.writeString(buf, ItemRBMKRod.getCoreHeat(slots[0]) + " / " + ItemRBMKRod.getHullHeat(slots[0]) + " / " + rod.meltingPoint); + } } @Override @@ -260,6 +271,13 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM this.fluxQuantity = buf.readDouble(); this.fluxFastRatio = buf.readDouble(); this.hasRod = buf.readBoolean(); + if(this.hasRod) { + fuelYield = BufferUtil.readString(buf); + fuelXenon = BufferUtil.readString(buf); + fuelHeat = BufferUtil.readString(buf); + } else { + fuelYield = fuelXenon = fuelHeat = null; + } } public void getDiagData(NBTTagCompound nbt) { @@ -267,13 +285,10 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM this.writeToNBT(nbt); diag = false; - if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) { - - ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem()); - - nbt.setString("f_yield", rod.getYield(slots[0]) + " / " + rod.yield + " (" + (rod.getEnrichment(slots[0]) * 100) + "%)"); - nbt.setString("f_xenon", rod.getPoison(slots[0]) + "%"); - nbt.setString("f_heat", rod.getCoreHeat(slots[0]) + " / " + rod.getHullHeat(slots[0]) + " / " + rod.meltingPoint); + if(fuelYield != null && fuelXenon != null && fuelHeat != null) { + nbt.setString("f_yield", fuelYield); + nbt.setString("f_xenon", fuelXenon); + nbt.setString("f_heat", fuelHeat); } } @@ -342,10 +357,10 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) { ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem()); - data.setDouble("enrichment", rod.getEnrichment(slots[0])); - data.setDouble("xenon", rod.getPoison(slots[0])); - data.setDouble("c_heat", rod.getHullHeat(slots[0])); - data.setDouble("c_coreHeat", rod.getCoreHeat(slots[0])); + data.setDouble("enrichment", ItemRBMKRod.getEnrichment(slots[0])); + data.setDouble("xenon", ItemRBMKRod.getPoison(slots[0])); + data.setDouble("c_heat", ItemRBMKRod.getHullHeat(slots[0])); + data.setDouble("c_coreHeat", ItemRBMKRod.getCoreHeat(slots[0])); data.setDouble("c_maxHeat", rod.meltingPoint); } @@ -459,14 +474,15 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM returnValues.add(ItemRBMKRod.getEnrichment(slots[0])); returnValues.add(ItemRBMKRod.getPoison(slots[0])); returnValues.add(slots[0].getItem().getUnlocalizedName()); - } else - for (int i = 0; i < 5; i++) - returnValues.add("N/A"); + } else { + for(int i = 0; i < 5; i++) returnValues.add("N/A"); + } return new Object[] { - heat, returnValues.get(0), returnValues.get(1), - fluxQuantity, fluxFastRatio, returnValues.get(2), returnValues.get(3), returnValues.get(4), - ((RBMKRod)this.getBlockType()).moderated, xCoord, yCoord, zCoord}; + heat, returnValues.get(0), returnValues.get(1), + fluxQuantity, fluxFastRatio, returnValues.get(2), returnValues.get(3), returnValues.get(4), + ((RBMKRod)this.getBlockType()).moderated, xCoord, yCoord, zCoord + }; } @Callback(direct = true) diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRodReaSim.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRodReaSim.java index a23c5f2e3..c6b85e9c3 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRodReaSim.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRodReaSim.java @@ -28,22 +28,22 @@ public class TileEntityRBMKRodReaSim extends TileEntityRBMKRod { if(pos == null) pos = new BlockPos(this); - if (flux == 0) { + if(flux == 0) { // simple way to remove the node from the cache when no flux is going into it! - NeutronNodeWorld.removeNode(pos); + NeutronNodeWorld.removeNode(worldObj, pos); return; } - RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); + RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(worldObj, pos); if(node == null) { node = makeNode(this); - NeutronNodeWorld.addNode(node); + NeutronNodeWorld.addNode(worldObj, node); } int count = RBMKDials.getReaSimCount(worldObj); - for (int i = 0; i < count; i++) { + for(int i = 0; i < count; i++) { Vec3 neutronVector = Vec3.createVectorHelper(1, 0, 0); neutronVector.rotateAroundY((float)(Math.PI * 2D * worldObj.rand.nextDouble())); From a6b1a9068bde1aa161c873b744438e2a47f5649d Mon Sep 17 00:00:00 2001 From: George Paton Date: Wed, 26 Feb 2025 16:33:04 +1100 Subject: [PATCH 2/3] fix crash caused by placing piles immediately adjacent to RBMKs --- src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java | 2 +- src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java b/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java index 843b878a2..548d6d75b 100644 --- a/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java +++ b/src/main/java/com/hbm/handler/neutron/PileNeutronHandler.java @@ -65,7 +65,7 @@ public class PileNeutronHandler { TileEntity tile; NeutronNode node = NeutronNodeWorld.getNode(worldObj, nodePos); - if(node != null) { + if(node != null && node instanceof PileNeutronNode) { tile = node.tile; } else { tile = blockPosToTE(worldObj, nodePos); diff --git a/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java b/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java index aa3574361..c22ffcddc 100644 --- a/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java +++ b/src/main/java/com/hbm/handler/neutron/RBMKNeutronHandler.java @@ -222,7 +222,7 @@ public class RBMKNeutronHandler { pos.mutate(origin.tile.xCoord + x, origin.tile.yCoord, origin.tile.zCoord + z); NeutronNode node = NeutronNodeWorld.getNode(world, pos); - if(node != null) { + if(node != null && node instanceof RBMKNeutronNode) { positions[i - 1] = node; } else if(this.origin.tile.getBlockType() instanceof RBMKBase) { TileEntity te = blockPosToTE(world, pos); @@ -292,7 +292,7 @@ public class RBMKNeutronHandler { RBMKType type = (RBMKType) targetNode.data.get("type"); - if(type == RBMKType.OTHER) // pass right on by! + if(type == RBMKType.OTHER || type == null) // pass right on by! continue; // we established earlier during `getNodes()` that they should all be RBMKBase TEs From 9da32595ff20b6a2fd47e0da5ef894d4d4405d3c Mon Sep 17 00:00:00 2001 From: George Paton Date: Wed, 26 Feb 2025 19:36:47 +1100 Subject: [PATCH 3/3] 4x rarer meteor dungeons --- src/main/java/com/hbm/world/gen/NTMWorldGenerator.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java index e56c3e0eb..d0ba4ad63 100644 --- a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java +++ b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java @@ -40,25 +40,25 @@ public class NTMWorldGenerator implements IWorldGenerator { NBTStructure.registerStructure(0, new SpawnCondition() {{ canSpawn = biome -> !invalidBiomes.contains(biome); start = d -> new MapGenNTMFeatures.Start(d.getW(), d.getX(), d.getY(), d.getZ()); - spawnWeight = 14; + spawnWeight = 14 * 4; }}); NBTStructure.registerStructure(0, new SpawnCondition() {{ canSpawn = biome -> !invalidBiomes.contains(biome); start = d -> new BunkerStart(d.getW(), d.getX(), d.getY(), d.getZ()); - spawnWeight = 1; + spawnWeight = 1 * 4; }}); NBTStructure.registerStructure(0, new SpawnCondition() {{ canSpawn = biome -> !biome.canSpawnLightningBolt() && biome.temperature >= 2F; structure = new JigsawPiece("vertibird", StructureManager.vertibird); - spawnWeight = 3; + spawnWeight = 3 * 4; }}); NBTStructure.registerStructure(0, new SpawnCondition() {{ canSpawn = biome -> !biome.canSpawnLightningBolt() && biome.temperature >= 2F; structure = new JigsawPiece("crashed_vertibird", StructureManager.crashed_vertibird); - spawnWeight = 3; + spawnWeight = 3 * 4; }}); Map bricks = new HashMap() {{