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

This commit is contained in:
George Paton 2025-02-26 15:38:31 +11:00
parent fd500f8a98
commit bb84ebe209
12 changed files with 321 additions and 292 deletions

View File

@ -174,7 +174,7 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo
if(rbmk.hasLid() && rbmk.isLidRemovable()) {
RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(new BlockPos(te));
RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(world, new BlockPos(te));
if(node != null)
node.removeLid();
@ -186,7 +186,7 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo
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;

View File

@ -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,18 +18,14 @@ public class NeutronHandler {
if(event.phase != TickEvent.Phase.START)
return;
// Remove `StreamWorld` objects if they have no streams.
{ // aflghdkljghlkbhfjkghgilurbhlkfjghkffdjgn
List<World> toRemove = new ArrayList<>();
NeutronNodeWorld.streamWorlds.forEach((world, streamWorld) -> {
if (streamWorld.streams.isEmpty())
toRemove.add(world);
});
// 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++;
for (World world : toRemove) {
NeutronNodeWorld.streamWorlds.remove(world);
}
}
// Remove `StreamWorld` objects if they have no streams.
NeutronNodeWorld.removeEmptyWorlds();
for(Map.Entry<World, NeutronNodeWorld.StreamWorld> world : NeutronNodeWorld.streamWorlds.entrySet()) {
@ -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();
}
// Freshen the node cache every `cacheTime` ticks to prevent huge RAM usage from idle nodes.
int cacheTime = 20;
if (ticks >= cacheTime) {
ticks = 0;
List<BlockPos> 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++;
if(cacheClear) world.getValue().cleanNodes();
}
}
}

View File

@ -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<BlockPos, NeutronNode> 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<World, StreamWorld> streamWorlds = new HashMap<>();
public static class StreamWorld {
List<NeutronStream> streams;
public StreamWorld() {
streams = new ArrayList<>();
public static NeutronNode getNode(World world, BlockPos pos) {
StreamWorld streamWorld = streamWorlds.get(world);
return streamWorld != null ? streamWorld.nodeCache.get(pos) : null;
}
public void addStream(NeutronStream stream) {
this.streams.add(stream);
public static void addNode(World world, NeutronNode node) {
StreamWorld streamWorld = getOrAddWorld(world);
streamWorld.nodeCache.put(node.pos, node);
}
public void removeAllStreams() {
this.streams.clear();
public static void removeNode(World world, BlockPos pos) {
StreamWorld streamWorld = streamWorlds.get(world);
if(streamWorld == null) return;
streamWorld.removeNode(pos);
}
public void removeAllStreamsOfType(NeutronStream.NeutronType type) {
List<NeutronStream> toRemove = new ArrayList<>();
for (NeutronStream stream : streams) {
if (stream.type == type)
toRemove.add(stream);
}
toRemove.forEach((stream) -> streams.remove(stream));
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<NeutronStream> streams;
private HashMap<BlockPos, NeutronNode> 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<BlockPos> 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);
}
}
}

View File

@ -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;

View File

@ -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();
@ -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<EntityLivingBase> entities = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(x, y, z, x, y, z));
if(entities != null)

View File

@ -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 {
@ -102,6 +101,7 @@ public class RBMKNeutronHandler {
List<BlockPos> list = new ArrayList<>();
BlockPos pos = new BlockPos(this.tile);
World world = tile.getWorldObj();
RBMKNeutronStream[] streams = new RBMKNeutronStream[TileEntityRBMKRod.fluxDirs.length];
@ -117,7 +117,7 @@ public class RBMKNeutronHandler {
if(!rod.hasRod || rod.lastFluxQuantity == 0) {
for(RBMKNeutronStream stream : streams) {
for(RBMKNeutronNode node : stream.getNodes(false))
for(NeutronNode node : stream.getNodes(false))
if(node != null)
list.add(new BlockPos(node.tile));
}
@ -155,7 +155,7 @@ 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) {
@ -177,9 +177,9 @@ public class RBMKNeutronHandler {
// Check if non-rod nodes should be uncached due to no rod in range.
for(RBMKNeutronStream stream : streams) {
RBMKNeutronNode[] nodes = stream.getNodes(false);
NeutronNode[] nodes = stream.getNodes(false);
for (RBMKNeutronNode node : nodes) {
for(NeutronNode node : nodes) {
if(!(node == null) && node.tile instanceof TileEntityRBMKRod)
return list;
}
@ -209,10 +209,11 @@ 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++) {
int x = (int) Math.floor(0.5 + vector.xCoord * i);
@ -220,17 +221,16 @@ public class RBMKNeutronHandler {
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);
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);
}
}
}
@ -248,13 +248,14 @@ public class RBMKNeutronHandler {
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,20 +264,19 @@ public class RBMKNeutronHandler {
while(iterator.hasNext()) {
BlockPos nodePos = iterator.next();
BlockPos targetPos = iterator.next();
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??
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) {
node = makeNode((TileEntityRBMKBase) te);
NeutronNodeWorld.addNode(node); // whoops!
targetNode = makeNode((TileEntityRBMKBase) te);
NeutronNodeWorld.addNode(worldObj, targetNode); // whoops!
} else {
int hits = getHits(nodePos); // Get the amount of hits on blocks.
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.
@ -290,19 +290,17 @@ public class RBMKNeutronHandler {
}
}
node = (RBMKNeutronNode) NeutronNodeWorld.nodeCache.get(nodePos);
RBMKType type = (RBMKType) node.data.get("type");
RBMKType type = (RBMKType) targetNode.data.get("type");
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()) {
moderatedCount++;
@ -362,9 +360,9 @@ public class RBMKNeutronHandler {
}
}
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.

View File

@ -41,7 +41,7 @@ public class ItemRBMKLid extends Item {
if(tile.hasLid())
return false;
RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(new BlockPos(te));
RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(world, new BlockPos(te));
if(node != null)
node.addLid();

View File

@ -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;

View File

@ -17,8 +17,13 @@ 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) {
@ -27,15 +32,15 @@ public abstract class TileEntityPileBase extends TileEntity {
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);

View File

@ -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,7 +132,7 @@ 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));
@ -161,7 +160,7 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements
if(heat == 20 && RBMKDials.getReasimBoilers(worldObj))
return;
List<TileEntityRBMKBase> rec = new ArrayList();
List<TileEntityRBMKBase> 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<String> exceptions = new ArrayList();
List<String> 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<TileEntityRBMKBase> columns = new HashSet();
public static HashSet<IPipeNet> pipes = new HashSet();
public static HashSet<TileEntityRBMKBase> columns = new HashSet<>();
public static HashSet<IPipeNet> 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<IFluidConductor> pipeBlocks = new HashSet();
HashSet<IFluidConnector> pipeReceivers = new HashSet();
HashSet<IFluidConductor> pipeBlocks = new HashSet<>();
HashSet<IFluidConnector> pipeReceivers = new HashSet<>();
//unify all parts into single sets to prevent redundancy
pipes.forEach(x -> {

View File

@ -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);
}
@ -194,15 +199,15 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
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) {
@ -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};
((RBMKRod)this.getBlockType()).moderated, xCoord, yCoord, zCoord
};
}
@Callback(direct = true)

View File

@ -30,15 +30,15 @@ public class TileEntityRBMKRodReaSim extends TileEntityRBMKRod {
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);