From 841852cc81d271292a15f52c4fa06294cdf31674 Mon Sep 17 00:00:00 2001 From: BallOfEnergy <66693744+BallOfEnergy1@users.noreply.github.com> Date: Sun, 25 Aug 2024 22:19:04 -0500 Subject: [PATCH] 99.999% there just some more optimization! (node culling) --- .../com/hbm/handler/rbmkmk2/RBMKHandler.java | 104 ++++++++++++------ .../tileentity/machine/rbmk/RBMKDials.java | 24 +++- .../machine/rbmk/TileEntityRBMKRod.java | 15 ++- .../machine/rbmk/TileEntityRBMKRodReaSim.java | 21 +++- 4 files changed, 123 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/hbm/handler/rbmkmk2/RBMKHandler.java b/src/main/java/com/hbm/handler/rbmkmk2/RBMKHandler.java index 1661cb216..a2bd18e5f 100644 --- a/src/main/java/com/hbm/handler/rbmkmk2/RBMKHandler.java +++ b/src/main/java/com/hbm/handler/rbmkmk2/RBMKHandler.java @@ -9,6 +9,7 @@ import java.util.HashMap; import java.util.Map.Entry; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Vec3; @@ -63,39 +64,72 @@ public class RBMKHandler { this.hasLid = false; } + public List getReaSimNodes(TileEntityRBMKRodReaSim rod) { + List list = new ArrayList<>(); + for (int x = rod.xCoord - fluxRange; x <= rod.xCoord + fluxRange; x++) + for (int z = rod.zCoord - fluxRange; z <= rod.zCoord + fluxRange; z++) + if ((x - rod.xCoord) * (x - rod.xCoord) + (z - rod.zCoord) * (z - rod.zCoord) <= fluxRange * fluxRange) + list.add(new BlockPos(rod)); + return list; + } + public List checkNode(BlockPos pos) { List list = new ArrayList<>(); - if (tile == null) { - list.add(pos); // what the fuck??? - return list; - } - - if (tile.isInvalid()) { + // Check if the tile no longer exists/is invalid. + if (tile == null || tile.isInvalid()) { list.add(pos); return list; } + List streams = new ArrayList<>(); + + // Simulate streams coming out of the RBMK rod. + for (ForgeDirection dir : TileEntityRBMKRod.fluxDirs) { + streams.add(new NeutronStream(this, Vec3.createVectorHelper(dir.offsetX, 0, dir.offsetZ))); + } + + // Check if the rod should uncache nodes. if (tile instanceof TileEntityRBMKRod && !(tile instanceof TileEntityRBMKRodReaSim)) { TileEntityRBMKRod rod = (TileEntityRBMKRod) tile; - if (!rod.hasRod) { + if (!rod.hasRod || rod.fluxQuantity == 0) { - // Simulate streams coming out of the RBMK rod find nodes to uncache. - - for (ForgeDirection dir : TileEntityRBMKRod.fluxDirs) { - NeutronStream stream = new NeutronStream(this, Vec3.createVectorHelper(dir.offsetX, 0, dir.offsetZ)); - - List nodes = stream.getNodes(false); - for (RBMKNode nodeToRemove : nodes) - list.add(new BlockPos(nodeToRemove.tile)); + for (NeutronStream stream : streams) { + stream.getNodes(false).forEach(node -> list.add(new BlockPos(node.tile))); } + return list; } } + if (tile instanceof TileEntityRBMKRodReaSim) { // fuckkkkkkk + TileEntityRBMKRodReaSim rod = (TileEntityRBMKRodReaSim) tile; + if (!rod.hasRod || rod.fluxQuantity == 0) { + list.addAll(getReaSimNodes(rod)); + } + } + + // TODO: implement ReaSim node culling on the non-rod side. + + // Check if non-rod nodes should be uncached due to no rod in range. + for (NeutronStream stream : streams) { + + List nodes = stream.getNodes(false); + + for (RBMKNode node : nodes) { + if (node.tile instanceof TileEntityRBMKRod) + return list; + } + + // If we get here, then no rods were found along this stream's path! + // This, most of the time, means we can just uncache all off the nodes inside the stream's path. + // That other part of the time, streams will be crossing paths. + // This is fine though, we can just uncache them anyway and the streams later on (next tick) will recache them. + nodes.forEach(node -> list.add(new BlockPos(node.tile))); + } + return list; - // TODO: Implement `hasRodInRange` for non-rod tile uncaching. } } @@ -160,6 +194,7 @@ public class RBMKHandler { } } + // USES THE CACHE!!! public List getBlocks() { List positions = new ArrayList<>(); @@ -173,10 +208,9 @@ public class RBMKHandler { return positions; } - // This, however, is used for actual RBMK flux calculations. // Does NOT include the origin node // USES THE CACHE!!! - public List getNodes(boolean cache) { + public List getNodes(boolean addNode) { List positions = new ArrayList<>(); for (int i = 1; i <= fluxRange; i++) { @@ -185,7 +219,7 @@ public class RBMKHandler { BlockPos pos = new BlockPos(origin.tile).add(x, 0, z); - if (nodeCache.containsKey(pos) && cache) + if (nodeCache.containsKey(pos)) positions.add(getNode(pos)); else if (this.origin.tile.getBlockType() instanceof RBMKBase) { @@ -194,7 +228,7 @@ public class RBMKHandler { TileEntityRBMKBase rbmkBase = (TileEntityRBMKBase)te; RBMKNode node = makeNode(rbmkBase); positions.add(node); - if (cache) + if (addNode) addNode(node); } } @@ -223,7 +257,6 @@ public class RBMKHandler { } int moderatedCount = 0; - double totalFluxMod = 1; for(BlockPos nodePos : getBlocks()) { @@ -262,23 +295,25 @@ public class RBMKHandler { if(!node.hasLid) ChunkRadiationManager.proxy.incrementRad(worldObj, nodePos.getX(), nodePos.getY(), nodePos.getZ(), (float) (this.fluxQuantity * 0.05F)); - if (node.type == RBMKHandler.RBMKType.MODERATOR) { + if (node.type == RBMKHandler.RBMKType.MODERATOR || nodeTE.isModerated()) { moderatedCount++; moderateStream(); } if (nodeTE instanceof IRBMKFluxReceiver) { IRBMKFluxReceiver column = (IRBMKFluxReceiver)nodeTE; + if (node.type == RBMKHandler.RBMKType.ROD) { TileEntityRBMKRod rod = (TileEntityRBMKRod)column; + if (rod.hasRod) { - if (rod.isModerated()) - moderateStream(); rod.receiveFlux(this); return; } + } else if(node.type == RBMKType.OUTGASSER) { TileEntityRBMKOutgasser outgasser = ((TileEntityRBMKOutgasser) column); + if(outgasser.canProcess()) { column.receiveFlux(this); return; @@ -286,33 +321,34 @@ public class RBMKHandler { } } else if (node.type == RBMKHandler.RBMKType.CONTROL_ROD) { - TileEntityRBMKControl rod = (TileEntityRBMKControl)nodeTE; + TileEntityRBMKControl rod = (TileEntityRBMKControl) nodeTE; + if (rod.level > 0.0D) { + this.fluxQuantity *= rod.getMult(); - totalFluxMod *= rod.getMult(); continue; } return; - } + } else if (node.type == RBMKHandler.RBMKType.REFLECTOR) { - if (node.type == RBMKHandler.RBMKType.REFLECTOR) { if (this.origin.tile.isModerated()) moderatedCount++; + if (this.fluxRatio > 0 && moderatedCount > 0) for (int i = 0; i < moderatedCount; i++) moderateStream(); - if (totalFluxMod < 1) - this.fluxQuantity *= totalFluxMod; + if (RBMKHandler.reflectorEfficiency != 1.0D) { this.fluxQuantity *= RBMKHandler.reflectorEfficiency; continue; } + ((TileEntityRBMKRod)originTE).receiveFlux(this); return; - } - if (node.type == RBMKHandler.RBMKType.ABSORBER) { + } else if (node.type == RBMKHandler.RBMKType.ABSORBER) { if (RBMKHandler.absorberEfficiency == 1) return; + this.fluxQuantity *= RBMKHandler.absorberEfficiency; } } @@ -398,8 +434,8 @@ public class RBMKHandler { // Gamerule caching because this apparently is kinda slow? // meh, good enough - reflectorEfficiency = 1; //RBMKDials.getReflectorEfficiency(world.worldObj); - absorberEfficiency = 1; //RBMKDials.getAbsorberEfficiency(world.worldObj); + reflectorEfficiency = RBMKDials.getReflectorEfficiency(world.getKey()); + absorberEfficiency = RBMKDials.getAbsorberEfficiency(world.getKey()); moderatorEfficiency = RBMKDials.getModeratorEfficiency(world.getKey()); // I hate this. diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java b/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java index 7f4874c50..c52555c23 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java @@ -32,6 +32,8 @@ public class RBMKDials { public static final String KEY_ENABLE_MELTDOWN_OVERPRESSURE = "dialEnableMeltdownOverpressure"; public static final String KEY_MODERATOR_EFFICIENCY = "dialModeratorEfficiency"; + public static final String KEY_ABSORBER_EFFICIENCY = "dialAbsorberEfficiency"; + public static final String KEY_REFLECTOR_EFFICIENCY = "dialReflectorEfficiency"; public static void createDials(World world) { GameRules rules = world.getGameRules(); @@ -58,6 +60,8 @@ public class RBMKDials { rules.setOrCreateGameRule(KEY_DISABLE_MELTDOWNS, "false"); rules.setOrCreateGameRule(KEY_ENABLE_MELTDOWN_OVERPRESSURE, "false"); rules.setOrCreateGameRule(KEY_MODERATOR_EFFICIENCY, "1.0"); + rules.setOrCreateGameRule(KEY_ABSORBER_EFFICIENCY, "1.0"); + rules.setOrCreateGameRule(KEY_REFLECTOR_EFFICIENCY, "1.0"); } } @@ -234,11 +238,29 @@ public class RBMKDials { } /** - * The percentage of neutron to moderate from fast to slow when they pass through a moderator. + * The percentage of neutrons to moderate from fast to slow when they pass through a moderator. * @param world * @return */ public static double getModeratorEfficiency(World world) { return MathHelper.clamp_double(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_MODERATOR_EFFICIENCY), 1D), 0.0D, 1.0D); } + + /** + * The percentage of neutrons to be absorbed when a stream hits an absorber column. + * @param world + * @return + */ + public static double getAbsorberEfficiency(World world) { + return MathHelper.clamp_double(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_MODERATOR_EFFICIENCY), 1D), 0.0D, 1.0D); + } + + /** + * The percentage of neutron to reflect when a stream hits a reflector column. + * @param world + * @return + */ + public static double getReflectorEfficiency(World world) { + return MathHelper.clamp_double(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_MODERATOR_EFFICIENCY), 1D), 0.0D, 1.0D); + } } 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 75388a8b7..97ad5a4d2 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java @@ -137,7 +137,9 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM this.lastFluxQuantity = this.fluxQuantity; //for spreading, we want the buffered flux to be 0 because we want to know exactly how much gets reflected back + this.fluxQuantity = 0; + spreadFlux(fluxQuantityOut, fluxRatioOut); hasRod = true; @@ -177,13 +179,18 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM BlockPos pos = new BlockPos(this); - RBMKHandler.RBMKNode node; + if (flux == 0) { + // simple way to remove the node from the cache when no flux is going into it! + removeNode(pos); + return; + } - if(getNode(pos) == null) { + RBMKHandler.RBMKNode node = getNode(pos); + + if(node == null) { node = RBMKHandler.makeNode(this); addNode(node); - } else - node = getNode(pos); + } for(ForgeDirection dir : fluxDirs) { 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 7114db0c7..74da00c39 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRodReaSim.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRodReaSim.java @@ -1,11 +1,13 @@ package com.hbm.tileentity.machine.rbmk; -import com.hbm.handler.rbmkmk2.RBMKHandler; +import com.hbm.handler.rbmkmk2.RBMKHandler.RBMKNode; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType; import com.hbm.util.fauxpointtwelve.BlockPos; import net.minecraft.util.Vec3; +import static com.hbm.handler.rbmkmk2.RBMKHandler.*; + public class TileEntityRBMKRodReaSim extends TileEntityRBMKRod { public TileEntityRBMKRodReaSim() { @@ -20,6 +22,21 @@ public class TileEntityRBMKRodReaSim extends TileEntityRBMKRod { @Override public void spreadFlux(double flux, double ratio) { + BlockPos pos = new BlockPos(this); + + if (flux == 0) { + // simple way to remove the node from the cache when no flux is going into it! + removeNode(pos); + return; + } + + RBMKNode node = getNode(pos); + + if(node == null) { + node = makeNode(this); + addNode(node); + } + int count = RBMKDials.getReaSimCount(worldObj); for (int i = 0; i < count; i++) { @@ -27,7 +44,7 @@ public class TileEntityRBMKRodReaSim extends TileEntityRBMKRod { neutronVector.rotateAroundY((float)(Math.PI * 2D * worldObj.rand.nextDouble())); - new RBMKHandler.NeutronStream(RBMKHandler.makeNode(this), neutronVector, flux, ratio); + new NeutronStream(makeNode(this), neutronVector, flux, ratio); // Create new neutron streams } }