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,8 +174,8 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo
if(rbmk.hasLid() && rbmk.isLidRemovable()) { 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) if(node != null)
node.removeLid(); node.removeLid();
if(!world.isRemote) { if(!world.isRemote) {
@ -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.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 true;

View File

@ -1,13 +1,10 @@
package com.hbm.handler.neutron; package com.hbm.handler.neutron;
import com.hbm.tileentity.machine.rbmk.RBMKDials; 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.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.common.gameevent.TickEvent;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
@ -21,20 +18,16 @@ public class NeutronHandler {
if(event.phase != TickEvent.Phase.START) if(event.phase != TickEvent.Phase.START)
return; 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. // Remove `StreamWorld` objects if they have no streams.
{ // aflghdkljghlkbhfjkghgilurbhlkfjghkffdjgn NeutronNodeWorld.removeEmptyWorlds();
List<World> toRemove = new ArrayList<>();
NeutronNodeWorld.streamWorlds.forEach((world, streamWorld) -> {
if (streamWorld.streams.isEmpty())
toRemove.add(world);
});
for (World world : toRemove) { for(Map.Entry<World, NeutronNodeWorld.StreamWorld> world : NeutronNodeWorld.streamWorlds.entrySet()) {
NeutronNodeWorld.streamWorlds.remove(world);
}
}
for (Map.Entry<World, NeutronNodeWorld.StreamWorld> world : NeutronNodeWorld.streamWorlds.entrySet()) {
// Gamerule caching because this apparently is kinda slow? // Gamerule caching because this apparently is kinda slow?
// meh, good enough // meh, good enough
@ -48,33 +41,10 @@ public class NeutronHandler {
RBMKNeutronHandler.columnHeight = RBMKDials.getColumnHeight(world.getKey()) + 1; RBMKNeutronHandler.columnHeight = RBMKDials.getColumnHeight(world.getKey()) + 1;
RBMKNeutronHandler.fluxRange = RBMKDials.getFluxRange(world.getKey()); RBMKNeutronHandler.fluxRange = RBMKDials.getFluxRange(world.getKey());
for (NeutronStream stream : world.getValue().streams) { world.getValue().runStreamInteractions(world.getKey());
stream.runStreamInteraction(world.getKey());
}
world.getValue().removeAllStreams(); 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<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++;
} }
} }

View File

@ -8,55 +8,94 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
public class NeutronNodeWorld { 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. // List of all stream worlds.
public static HashMap<World, StreamWorld> streamWorlds = new HashMap<>(); public static HashMap<World, StreamWorld> 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<NeutronStream> streams; public static void addNode(World world, NeutronNode node) {
StreamWorld streamWorld = getOrAddWorld(world);
streamWorld.nodeCache.put(node.pos, node);
}
public StreamWorld() { public static void removeNode(World world, BlockPos pos) {
streams = new ArrayList<>(); StreamWorld streamWorld = streamWorlds.get(world);
} if(streamWorld == null) return;
streamWorld.removeNode(pos);
public void addStream(NeutronStream stream) { }
this.streams.add(stream);
} public static StreamWorld getOrAddWorld(World world) {
StreamWorld streamWorld = streamWorlds.get(world);
public void removeAllStreams() { if(streamWorld == null) {
this.streams.clear(); streamWorld = new StreamWorld();
} streamWorlds.put(world, streamWorld);
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));
} }
return streamWorld;
} }
public static void removeAllWorlds() { public static void removeAllWorlds() {
streamWorlds.clear(); 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 com.hbm.util.fauxpointtwelve.BlockPos;
import net.minecraft.util.Vec3; import net.minecraft.util.Vec3;
import net.minecraft.world.World; import net.minecraft.world.World;
import com.hbm.handler.neutron.NeutronNodeWorld.StreamWorld;
import java.util.Iterator; import java.util.Iterator;
@ -43,13 +42,8 @@ public abstract class NeutronStream {
this.fluxQuantity = flux; this.fluxQuantity = flux;
this.fluxRatio = ratio; this.fluxRatio = ratio;
this.type = type; this.type = type;
World worldObj = origin.tile.getWorldObj();
if (NeutronNodeWorld.streamWorlds.get(worldObj) == null) { NeutronNodeWorld.getOrAddWorld(origin.tile.getWorldObj()).addStream(this);
StreamWorld world = new StreamWorld();
world.addStream(this);
NeutronNodeWorld.streamWorlds.put(worldObj, world);
} else
NeutronNodeWorld.streamWorlds.get(worldObj).addStream(this);
} }
protected BlockPos posInstance; protected BlockPos posInstance;

View File

@ -28,9 +28,8 @@ public class PileNeutronHandler {
public static PileNeutronNode makeNode(TileEntityPileBase tile) { public static PileNeutronNode makeNode(TileEntityPileBase tile) {
BlockPos pos = new BlockPos(tile); BlockPos pos = new BlockPos(tile);
if (NeutronNodeWorld.nodeCache.containsKey(pos)) PileNeutronNode node = (PileNeutronNode) NeutronNodeWorld.getNode(tile.getWorldObj(), pos);
return (PileNeutronNode) NeutronNodeWorld.getNode(pos); return node != null ? node : new PileNeutronNode(tile);
return new PileNeutronNode(tile);
} }
private static TileEntity blockPosToTE(World worldObj, BlockPos pos) { private static TileEntity blockPosToTE(World worldObj, BlockPos pos) {
@ -43,6 +42,7 @@ public class PileNeutronHandler {
super(origin, vector, flux, 0D, NeutronType.PILE); super(origin, vector, flux, 0D, NeutronType.PILE);
} }
@SuppressWarnings("unchecked")
@Override @Override
public void runStreamInteraction(World worldObj) { public void runStreamInteraction(World worldObj) {
@ -51,27 +51,29 @@ public class PileNeutronHandler {
for(float i = 1; i <= range; i += 0.5F) { 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.getX() + 0.5 + vector.xCoord * i),
(int)Math.floor(pos.getY() + 0.5 + vector.yCoord * i), (int)Math.floor(pos.getY() + 0.5 + vector.yCoord * i),
(int)Math.floor(pos.getZ() + 0.5 + vector.zCoord * 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! continue; // don't interact with itself!
pos.mutate(node.getX(), node.getY(), node.getZ()); pos.mutate(nodePos.getX(), nodePos.getY(), nodePos.getZ());
TileEntity tile; TileEntity tile;
if (NeutronNodeWorld.nodeCache.containsKey(node)) NeutronNode node = NeutronNodeWorld.getNode(worldObj, nodePos);
tile = NeutronNodeWorld.nodeCache.get(node).tile; if(node != null) {
else { tile = node.tile;
tile = blockPosToTE(worldObj, node); } else {
if (tile == null) tile = blockPosToTE(worldObj, nodePos);
return; // Doesn't exist! if(tile == null) return;
if (tile instanceof TileEntityPileBase)
NeutronNodeWorld.addNode(new PileNeutronNode((TileEntityPileBase) tile)); if(tile instanceof TileEntityPileBase) {
NeutronNodeWorld.addNode(worldObj, new PileNeutronNode((TileEntityPileBase) tile));
}
} }
Block block = tile.getBlockType(); Block block = tile.getBlockType();
@ -79,17 +81,17 @@ public class PileNeutronHandler {
if(!(tile instanceof TileEntityPileBase)) { if(!(tile instanceof TileEntityPileBase)) {
// Return when a boron block is hit // Return when a boron block is hit
if (block == ModBlocks.block_boron) if(block == ModBlocks.block_boron)
return; return;
else if (block == ModBlocks.concrete || else if(block == ModBlocks.concrete ||
block == ModBlocks.concrete_smooth || block == ModBlocks.concrete_smooth ||
block == ModBlocks.concrete_asbestos || block == ModBlocks.concrete_asbestos ||
block == ModBlocks.concrete_colored || block == ModBlocks.concrete_colored ||
block == ModBlocks.brick_concrete) block == ModBlocks.brick_concrete)
fluxQuantity *= 0.25; fluxQuantity *= 0.25;
if (block == ModBlocks.block_graphite_rod && (meta & 8) == 0) if(block == ModBlocks.block_graphite_rod && (meta & 8) == 0)
return; return;
} }
@ -102,9 +104,9 @@ public class PileNeutronHandler {
return; return;
} }
int x = (int) (node.getX() + 0.5); int x = (int) (nodePos.getX() + 0.5);
int y = (int) (node.getY() + 0.5); int y = (int) (nodePos.getY() + 0.5);
int z = (int) (node.getZ() + 0.5); int z = (int) (nodePos.getZ() + 0.5);
List<EntityLivingBase> entities = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(x, y, z, x, y, z)); List<EntityLivingBase> entities = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(x, y, z, x, y, z));
if(entities != null) if(entities != null)

View File

@ -39,9 +39,8 @@ public class RBMKNeutronHandler {
public static RBMKNeutronNode makeNode(TileEntityRBMKBase tile) { public static RBMKNeutronNode makeNode(TileEntityRBMKBase tile) {
BlockPos pos = new BlockPos(tile); BlockPos pos = new BlockPos(tile);
if (NeutronNodeWorld.nodeCache.containsKey(pos)) RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(tile.getWorldObj(), pos);
return (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); return node != null ? node : new RBMKNeutronNode(tile, tile.getRBMKType(), tile.hasLid());
return new RBMKNeutronNode(tile, tile.getRBMKType(), tile.hasLid());
} }
public static class RBMKNeutronNode extends NeutronNode { public static class RBMKNeutronNode extends NeutronNode {
@ -79,16 +78,16 @@ public class RBMKNeutronHandler {
@Override @Override
public BlockPos next() { 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++; z++;
if (z > fluxRange) { if(z > fluxRange) {
z = -fluxRange; z = -fluxRange;
x++; x++;
} }
return posInstance.mutate(tile.xCoord + x, tile.yCoord, tile.zCoord + z); return posInstance.mutate(tile.xCoord + x, tile.yCoord, tile.zCoord + z);
} else { } else {
z++; z++;
if (z > fluxRange) { if(z > fluxRange) {
z = -fluxRange; z = -fluxRange;
x++; x++;
} }
@ -102,23 +101,24 @@ public class RBMKNeutronHandler {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> list = new ArrayList<>();
BlockPos pos = new BlockPos(this.tile); BlockPos pos = new BlockPos(this.tile);
World world = tile.getWorldObj();
RBMKNeutronStream[] streams = new RBMKNeutronStream[TileEntityRBMKRod.fluxDirs.length]; RBMKNeutronStream[] streams = new RBMKNeutronStream[TileEntityRBMKRod.fluxDirs.length];
// Simulate streams coming out of the RBMK rod. // Simulate streams coming out of the RBMK rod.
ForgeDirection[] fluxDirs = TileEntityRBMKRod.fluxDirs; 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))); streams[i] = (new RBMKNeutronStream(this, Vec3.createVectorHelper(fluxDirs[i].offsetX, 0, fluxDirs[i].offsetZ)));
} }
// Check if the rod should uncache nodes. // 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; TileEntityRBMKRod rod = (TileEntityRBMKRod) tile;
if (!rod.hasRod || rod.lastFluxQuantity == 0) { if(!rod.hasRod || rod.lastFluxQuantity == 0) {
for (RBMKNeutronStream stream : streams) { for(RBMKNeutronStream stream : streams) {
for(RBMKNeutronNode node : stream.getNodes(false)) for(NeutronNode node : stream.getNodes(false))
if (node != null) if(node != null)
list.add(new BlockPos(node.tile)); list.add(new BlockPos(node.tile));
} }
@ -130,11 +130,11 @@ public class RBMKNeutronHandler {
Iterator<BlockPos> reaSimNodes = getReaSimNodes(); Iterator<BlockPos> reaSimNodes = getReaSimNodes();
// Check if the ReaSim rod should be culled from the cache due to no rod or no flux. // 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; TileEntityRBMKRodReaSim rod = (TileEntityRBMKRodReaSim) tile;
if (!rod.hasRod || rod.lastFluxQuantity == 0) { if(!rod.hasRod || rod.lastFluxQuantity == 0) {
reaSimNodes.forEachRemaining((a) -> { 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: 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; return list;
@ -155,32 +155,32 @@ public class RBMKNeutronHandler {
if(nodePos == null) if(nodePos == null)
continue; 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; TileEntityRBMKRod rod = (TileEntityRBMKRod) node.tile;
if (rod.hasRod && rod.lastFluxQuantity > 0) { if(rod.hasRod && rod.lastFluxQuantity > 0) {
hasRod = true; hasRod = true;
break; break;
} }
} }
} }
if (!hasRod) { if(!hasRod) {
list.add(pos); list.add(pos);
return list; return list;
} }
} }
// Check if non-rod nodes should be uncached due to no rod in range. // 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) { for(NeutronNode node : nodes) {
if (!(node == null) && node.tile instanceof TileEntityRBMKRod) if(!(node == null) && node.tile instanceof TileEntityRBMKRod)
return list; return list;
} }
} }
@ -209,28 +209,28 @@ public class RBMKNeutronHandler {
// Does NOT include the origin node // Does NOT include the origin node
// USES THE CACHE!!! // USES THE CACHE!!!
public RBMKNeutronNode[] getNodes(boolean addNode) { public NeutronNode[] getNodes(boolean addNode) {
RBMKNeutronNode[] positions = new RBMKNeutronNode[fluxRange]; NeutronNode[] positions = new RBMKNeutronNode[fluxRange];
BlockPos pos = new BlockPos(origin.tile); 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 x = (int) Math.floor(0.5 + vector.xCoord * i);
int z = (int) Math.floor(0.5 + vector.zCoord * i); int z = (int) Math.floor(0.5 + vector.zCoord * i);
pos.mutate(origin.tile.xCoord + x, origin.tile.yCoord, origin.tile.zCoord + z); pos.mutate(origin.tile.xCoord + x, origin.tile.yCoord, origin.tile.zCoord + z);
if (NeutronNodeWorld.nodeCache.containsKey(pos)) NeutronNode node = NeutronNodeWorld.getNode(world, pos);
positions[i - 1] = (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); if(node != null) {
positions[i - 1] = node;
else if (this.origin.tile.getBlockType() instanceof RBMKBase) { } else if(this.origin.tile.getBlockType() instanceof RBMKBase) {
TileEntity te = blockPosToTE(this.origin.tile.getWorldObj(), pos); TileEntity te = blockPosToTE(world, pos);
if (te instanceof TileEntityRBMKBase) { if(te instanceof TileEntityRBMKBase) {
TileEntityRBMKBase rbmkBase = (TileEntityRBMKBase) te; TileEntityRBMKBase rbmkBase = (TileEntityRBMKBase) te;
RBMKNeutronNode node = makeNode(rbmkBase); node = makeNode(rbmkBase);
positions[i - 1] = node; positions[i - 1] = node;
if (addNode) if(addNode) NeutronNodeWorld.addNode(world, node);
NeutronNodeWorld.addNode(node);
} }
} }
} }
@ -241,20 +241,21 @@ public class RBMKNeutronHandler {
public void runStreamInteraction(World worldObj) { public void runStreamInteraction(World worldObj) {
// do nothing if there's nothing to do lmao // do nothing if there's nothing to do lmao
if (fluxQuantity == 0D) if(fluxQuantity == 0D)
return; return;
BlockPos pos = new BlockPos(origin.tile); BlockPos pos = new BlockPos(origin.tile);
TileEntityRBMKBase originTE; TileEntityRBMKBase originTE;
if (NeutronNodeWorld.nodeCache.containsKey(pos)) NeutronNode node = NeutronNodeWorld.getNode(worldObj, pos);
originTE = (TileEntityRBMKBase) NeutronNodeWorld.nodeCache.get(pos).tile; if(node != null) {
else { originTE = (TileEntityRBMKBase) node.tile;
} else {
originTE = (TileEntityRBMKBase) blockPosToTE(worldObj, pos); originTE = (TileEntityRBMKBase) blockPosToTE(worldObj, pos);
if (originTE == null) if(originTE == null) return; // Doesn't exist anymore!
return; // Doesn't exist anymore!
NeutronNodeWorld.addNode(new RBMKNeutronNode(originTE, originTE.getRBMKType(), originTE.hasLid())); NeutronNodeWorld.addNode(worldObj, new RBMKNeutronNode(originTE, originTE.getRBMKType(), originTE.hasLid()));
} }
int moderatedCount = 0; int moderatedCount = 0;
@ -263,23 +264,22 @@ public class RBMKNeutronHandler {
while(iterator.hasNext()) { 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; return;
RBMKNeutronNode node; NeutronNode targetNode = NeutronNodeWorld.getNode(worldObj, targetPos);
if(targetNode == null) {
if (!NeutronNodeWorld.nodeCache.containsKey(nodePos)) { TileEntity te = blockPosToTE(worldObj, targetPos); // ok, maybe it didn't get added to the list somehow??
TileEntity te = blockPosToTE(worldObj, nodePos); // ok, maybe it didn't get added to the list somehow?? if(te instanceof TileEntityRBMKBase) {
if (te instanceof TileEntityRBMKBase) { targetNode = makeNode((TileEntityRBMKBase) te);
node = makeNode((TileEntityRBMKBase) te); NeutronNodeWorld.addNode(worldObj, targetNode); // whoops!
NeutronNodeWorld.addNode(node); // whoops!
} else { } 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. if(hits == columnHeight) // If stream is fully blocked.
return; return;
else if (hits > 0) { // If stream is partially blocked. else if(hits > 0) { // If stream is partially blocked.
irradiateFromFlux(pos, hits); irradiateFromFlux(pos, hits);
fluxQuantity *= 1 - ((double) hits / columnHeight); // Inverse to get partial blocking by blocks. fluxQuantity *= 1 - ((double) hits / columnHeight); // Inverse to get partial blocking by blocks.
continue; 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; continue;
// we established earlier during `getNodes()` that they should all be RBMKBase TEs // we established earlier during `getNodes()` that they should all be RBMKBase TEs
// no issue with casting here! // no issue with casting here!
TileEntityRBMKBase nodeTE = (TileEntityRBMKBase) node.tile; TileEntityRBMKBase nodeTE = (TileEntityRBMKBase) targetNode.tile;
if (!(boolean) node.data.get("hasLid")) if(!(boolean) targetNode.data.get("hasLid"))
ChunkRadiationManager.proxy.incrementRad(worldObj, nodePos.getX(), nodePos.getY(), nodePos.getZ(), (float) (this.fluxQuantity * 0.05F)); 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++; moderatedCount++;
moderateStream(); moderateStream();
} }
if (nodeTE instanceof IRBMKFluxReceiver) { if(nodeTE instanceof IRBMKFluxReceiver) {
IRBMKFluxReceiver column = (IRBMKFluxReceiver) nodeTE; IRBMKFluxReceiver column = (IRBMKFluxReceiver) nodeTE;
if (type == RBMKType.ROD) { if(type == RBMKType.ROD) {
TileEntityRBMKRod rod = (TileEntityRBMKRod) column; TileEntityRBMKRod rod = (TileEntityRBMKRod) column;
if (rod.hasRod) { if(rod.hasRod) {
rod.receiveFlux(this); rod.receiveFlux(this);
return; return;
} }
} else if (type == RBMKType.OUTGASSER) { } else if(type == RBMKType.OUTGASSER) {
TileEntityRBMKOutgasser outgasser = ((TileEntityRBMKOutgasser) column); TileEntityRBMKOutgasser outgasser = ((TileEntityRBMKOutgasser) column);
if (outgasser.canProcess()) { if(outgasser.canProcess()) {
column.receiveFlux(this); column.receiveFlux(this);
return; return;
} }
} }
} else if (type == RBMKType.CONTROL_ROD) { } else if(type == RBMKType.CONTROL_ROD) {
TileEntityRBMKControl rod = (TileEntityRBMKControl) nodeTE; TileEntityRBMKControl rod = (TileEntityRBMKControl) nodeTE;
if (rod.level > 0.0D) { if(rod.level > 0.0D) {
this.fluxQuantity *= rod.getMult(); this.fluxQuantity *= rod.getMult();
continue; continue;
} }
return; return;
} else if (type == RBMKType.REFLECTOR) { } else if(type == RBMKType.REFLECTOR) {
if (((TileEntityRBMKBase) this.origin.tile).isModerated()) if(((TileEntityRBMKBase) this.origin.tile).isModerated())
moderatedCount++; moderatedCount++;
if (this.fluxRatio > 0 && moderatedCount > 0) if(this.fluxRatio > 0 && moderatedCount > 0)
for (int i = 0; i < moderatedCount; i++) for(int i = 0; i < moderatedCount; i++)
moderateStream(); moderateStream();
if (reflectorEfficiency != 1.0D) { if(reflectorEfficiency != 1.0D) {
this.fluxQuantity *= reflectorEfficiency; this.fluxQuantity *= reflectorEfficiency;
continue; continue;
} }
((TileEntityRBMKRod) originTE).receiveFlux(this); ((TileEntityRBMKRod) originTE).receiveFlux(this);
return; return;
} else if (type == RBMKType.ABSORBER) { } else if(type == RBMKType.ABSORBER) {
if (absorberEfficiency == 1) if(absorberEfficiency == 1)
return; return;
this.fluxQuantity *= absorberEfficiency; 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. 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. // 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"); RBMKType lastNodeType = (RBMKType) lastNode.data.get("type");
if (lastNodeType == RBMKType.CONTROL_ROD) { if(lastNodeType == RBMKType.CONTROL_ROD) {
TileEntityRBMKControl rod = (TileEntityRBMKControl) lastNode.tile; TileEntityRBMKControl rod = (TileEntityRBMKControl) lastNode.tile;
if (rod.getMult() > 0.0D) { if(rod.getMult() > 0.0D) {
this.fluxQuantity *= rod.getMult(); this.fluxQuantity *= rod.getMult();
irradiateFromFlux(new BlockPos(lastNode.tile.xCoord + this.vector.xCoord, lastNode.tile.yCoord, lastNode.tile.zCoord + this.vector.zCoord)); 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 // I FUCKING HATE THIS
// total count of bugs fixed attributed to this function: 13 // total count of bugs fixed attributed to this function: 13
Block block = origin.tile.getWorldObj().getBlock(pos.getX(), pos.getY() + h, pos.getZ()); Block block = origin.tile.getWorldObj().getBlock(pos.getX(), pos.getY() + h, pos.getZ());
if (block.isOpaqueCube()) if(block.isOpaqueCube())
hits += 1; hits += 1;
} }

View File

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

View File

@ -566,8 +566,7 @@ public class ModEventHandler {
@SubscribeEvent @SubscribeEvent
public void onUnload(WorldEvent.Unload event) { public void onUnload(WorldEvent.Unload event) {
NeutronNodeWorld.removeAllWorlds(); // Remove world from worlds when unloaded to avoid world issues. NeutronNodeWorld.streamWorlds.remove(event.world);
NeutronNodeWorld.removeAllNodes(); // Remove all nodes.
} }
public static boolean didSit = false; public static boolean didSit = false;

View File

@ -17,25 +17,30 @@ public abstract class TileEntityPileBase extends TileEntity {
@Override @Override
public void invalidate() { public void invalidate() {
super.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) { protected void castRay(int flux) {
BlockPos pos = new BlockPos(this); 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! // simple way to remove the node from the cache when no flux is going into it!
NeutronNodeWorld.removeNode(pos); NeutronNodeWorld.removeNode(worldObj, pos);
return; return;
} }
PileNeutronNode node = (PileNeutronNode) NeutronNodeWorld.getNode(pos); PileNeutronNode node = (PileNeutronNode) NeutronNodeWorld.getNode(worldObj, pos);
if(node == null) { if(node == null) {
node = PileNeutronHandler.makeNode(this); node = PileNeutronHandler.makeNode(this);
NeutronNodeWorld.addNode(node); NeutronNodeWorld.addNode(worldObj, node);
} }
Vec3 neutronVector = Vec3.createVectorHelper(1, 0, 0); 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.PacketDispatcher;
import com.hbm.packet.toclient.AuxParticlePacketNT; import com.hbm.packet.toclient.AuxParticlePacketNT;
import com.hbm.saveddata.TomSaveData; import com.hbm.saveddata.TomSaveData;
import com.hbm.tileentity.IBufPacketReceiver;
import com.hbm.tileentity.IOverpressurable; import com.hbm.tileentity.IOverpressurable;
import com.hbm.tileentity.TileEntityLoadedBase; import com.hbm.tileentity.TileEntityLoadedBase;
import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType;
@ -54,7 +53,7 @@ import java.util.Iterator;
* @author hbm * @author hbm
* *
*/ */
public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements IBufPacketReceiver { public abstract class TileEntityRBMKBase extends TileEntityLoadedBase {
public double heat; public double heat;
@ -133,7 +132,7 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements
double heatConsumption = RBMKDials.getBoilerHeatConsumption(worldObj); double heatConsumption = RBMKDials.getBoilerHeatConsumption(worldObj);
double availableHeat = (this.heat - 100) / heatConsumption; double availableHeat = (this.heat - 100) / heatConsumption;
double availableWater = this.water; 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)); 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)) if(heat == 20 && RBMKDials.getReasimBoilers(worldObj))
return; return;
List<TileEntityRBMKBase> rec = new ArrayList(); List<TileEntityRBMKBase> rec = new ArrayList<>();
rec.add(this); rec.add(this);
double heatTot = this.heat; double heatTot = this.heat;
int waterTot = this.water; int waterTot = this.water;
@ -227,8 +226,13 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements
@Override @Override
public void invalidate() { public void invalidate() {
super.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 @Override
@ -304,6 +308,7 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements
diag = false; diag = false;
} }
@SuppressWarnings("unchecked")
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static void diagnosticPrintHook(RenderGameOverlayEvent.Pre event, World world, int x, int y, int z) { 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 pX = resolution.getScaledWidth() / 2 + 8;
int pZ = resolution.getScaledHeight() / 2; int pZ = resolution.getScaledHeight() / 2;
List<String> exceptions = new ArrayList(); List<String> exceptions = new ArrayList<>();
exceptions.add("x"); exceptions.add("x");
exceptions.add("y"); exceptions.add("y");
exceptions.add("z"); exceptions.add("z");
@ -416,10 +421,11 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements
worldObj.spawnEntityInWorld(debris); worldObj.spawnEntityInWorld(debris);
} }
public static HashSet<TileEntityRBMKBase> columns = new HashSet(); public static HashSet<TileEntityRBMKBase> columns = new HashSet<>();
public static HashSet<IPipeNet> pipes = new HashSet(); public static HashSet<IPipeNet> pipes = new HashSet<>();
//assumes that !worldObj.isRemote //assumes that !worldObj.isRemote
@SuppressWarnings("unchecked")
public void meltdown() { public void meltdown() {
RBMKBase.dropLids = false; RBMKBase.dropLids = false;
@ -483,8 +489,8 @@ public abstract class TileEntityRBMKBase extends TileEntityLoadedBase implements
/* Hanlde overpressure event */ /* Hanlde overpressure event */
if(RBMKDials.getOverpressure(worldObj) && !pipes.isEmpty()) { if(RBMKDials.getOverpressure(worldObj) && !pipes.isEmpty()) {
HashSet<IFluidConductor> pipeBlocks = new HashSet(); HashSet<IFluidConductor> pipeBlocks = new HashSet<>();
HashSet<IFluidConnector> pipeReceivers = new HashSet(); HashSet<IFluidConnector> pipeReceivers = new HashSet<>();
//unify all parts into single sets to prevent redundancy //unify all parts into single sets to prevent redundancy
pipes.forEach(x -> { pipes.forEach(x -> {

View File

@ -15,6 +15,7 @@ import com.hbm.inventory.gui.GUIRBMKRod;
import com.hbm.items.ModItems; import com.hbm.items.ModItems;
import com.hbm.items.machine.ItemRBMKRod; import com.hbm.items.machine.ItemRBMKRod;
import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType; import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole.ColumnType;
import com.hbm.util.BufferUtil;
import com.hbm.util.CompatEnergyControl; import com.hbm.util.CompatEnergyControl;
import com.hbm.util.ParticleUtil; 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.Arguments;
import li.cil.oc.api.machine.Callback; import li.cil.oc.api.machine.Callback;
import li.cil.oc.api.machine.Context; import li.cil.oc.api.machine.Context;
import li.cil.oc.api.network.SimpleComponent;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container; import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -41,7 +41,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")}) @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!! // New system!!
// Used for receiving flux (calculating outbound flux/burning rods) // Used for receiving flux (calculating outbound flux/burning rods)
@ -52,6 +52,11 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
public boolean hasRod; public boolean hasRod;
// Fuel rod item data client sync
private String fuelYield;
private String fuelXenon;
private String fuelHeat;
public TileEntityRBMKRod() { public TileEntityRBMKRod() {
super(1); super(1);
} }
@ -94,7 +99,7 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
// Experimental flux ratio curve rods! // Experimental flux ratio curve rods!
// Again, nothing really uses this so its just idle code at the moment. // 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])); 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); fluxQuantityOut = rod.burn(worldObj, slots[0], fluxIn);
} else { } else {
NType rType = rod.rType; NType rType = rod.rType;
if (rType == NType.SLOW) if(rType == NType.SLOW)
fluxRatioOut = 0; fluxRatioOut = 0;
else else
fluxRatioOut = 1; fluxRatioOut = 1;
@ -192,17 +197,17 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
if(pos == null) if(pos == null)
pos = new BlockPos(this); 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! // simple way to remove the node from the cache when no flux is going into it!
NeutronNodeWorld.removeNode(pos); NeutronNodeWorld.removeNode(worldObj, pos);
return; return;
} }
RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(worldObj, pos);
if(node == null) { if(node == null) {
node = RBMKNeutronHandler.makeNode(this); node = RBMKNeutronHandler.makeNode(this);
NeutronNodeWorld.addNode(node); NeutronNodeWorld.addNode(worldObj, node);
} }
for(ForgeDirection dir : fluxDirs) { for(ForgeDirection dir : fluxDirs) {
@ -218,10 +223,10 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
public void readFromNBT(NBTTagCompound nbt) { public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(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 // recalculate new values to keep stable operations
this.fluxQuantity = nbt.getDouble("fluxFast") + nbt.getDouble("fluxSlow"); this.fluxQuantity = nbt.getDouble("fluxFast") + nbt.getDouble("fluxSlow");
if (this.fluxQuantity > 0) if(this.fluxQuantity > 0)
this.fluxFastRatio = nbt.getDouble("fluxFast") / fluxQuantity; this.fluxFastRatio = nbt.getDouble("fluxFast") / fluxQuantity;
else else
this.fluxFastRatio = 0; this.fluxFastRatio = 0;
@ -236,7 +241,7 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
public void writeToNBT(NBTTagCompound nbt) { public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt); super.writeToNBT(nbt);
if (!diag) { if(!diag) {
nbt.setDouble("fluxQuantity", this.lastFluxQuantity); nbt.setDouble("fluxQuantity", this.lastFluxQuantity);
nbt.setDouble("fluxMod", this.lastFluxRatio); nbt.setDouble("fluxMod", this.lastFluxRatio);
} else { } else {
@ -252,6 +257,12 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
buf.writeDouble(this.lastFluxQuantity); buf.writeDouble(this.lastFluxQuantity);
buf.writeDouble(this.lastFluxRatio); buf.writeDouble(this.lastFluxRatio);
buf.writeBoolean(this.hasRod); 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 @Override
@ -260,6 +271,13 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
this.fluxQuantity = buf.readDouble(); this.fluxQuantity = buf.readDouble();
this.fluxFastRatio = buf.readDouble(); this.fluxFastRatio = buf.readDouble();
this.hasRod = buf.readBoolean(); 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) { public void getDiagData(NBTTagCompound nbt) {
@ -267,13 +285,10 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
this.writeToNBT(nbt); this.writeToNBT(nbt);
diag = false; diag = false;
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) { if(fuelYield != null && fuelXenon != null && fuelHeat != null) {
nbt.setString("f_yield", fuelYield);
ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem()); nbt.setString("f_xenon", fuelXenon);
nbt.setString("f_heat", fuelHeat);
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);
} }
} }
@ -342,10 +357,10 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) { if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem()); ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem());
data.setDouble("enrichment", rod.getEnrichment(slots[0])); data.setDouble("enrichment", ItemRBMKRod.getEnrichment(slots[0]));
data.setDouble("xenon", rod.getPoison(slots[0])); data.setDouble("xenon", ItemRBMKRod.getPoison(slots[0]));
data.setDouble("c_heat", rod.getHullHeat(slots[0])); data.setDouble("c_heat", ItemRBMKRod.getHullHeat(slots[0]));
data.setDouble("c_coreHeat", rod.getCoreHeat(slots[0])); data.setDouble("c_coreHeat", ItemRBMKRod.getCoreHeat(slots[0]));
data.setDouble("c_maxHeat", rod.meltingPoint); 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.getEnrichment(slots[0]));
returnValues.add(ItemRBMKRod.getPoison(slots[0])); returnValues.add(ItemRBMKRod.getPoison(slots[0]));
returnValues.add(slots[0].getItem().getUnlocalizedName()); returnValues.add(slots[0].getItem().getUnlocalizedName());
} else } else {
for (int i = 0; i < 5; i++) for(int i = 0; i < 5; i++) returnValues.add("N/A");
returnValues.add("N/A"); }
return new Object[] { return new Object[] {
heat, returnValues.get(0), returnValues.get(1), heat, returnValues.get(0), returnValues.get(1),
fluxQuantity, fluxFastRatio, returnValues.get(2), returnValues.get(3), returnValues.get(4), 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) @Callback(direct = true)

View File

@ -28,22 +28,22 @@ public class TileEntityRBMKRodReaSim extends TileEntityRBMKRod {
if(pos == null) if(pos == null)
pos = new BlockPos(this); 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! // simple way to remove the node from the cache when no flux is going into it!
NeutronNodeWorld.removeNode(pos); NeutronNodeWorld.removeNode(worldObj, pos);
return; return;
} }
RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(pos); RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(worldObj, pos);
if(node == null) { if(node == null) {
node = makeNode(this); node = makeNode(this);
NeutronNodeWorld.addNode(node); NeutronNodeWorld.addNode(worldObj, node);
} }
int count = RBMKDials.getReaSimCount(worldObj); 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); Vec3 neutronVector = Vec3.createVectorHelper(1, 0, 0);
neutronVector.rotateAroundY((float)(Math.PI * 2D * worldObj.rand.nextDouble())); neutronVector.rotateAroundY((float)(Math.PI * 2D * worldObj.rand.nextDouble()));