Merge pull request #1958 from MellowArpeggiation/master

Fix #1918 - RBMKs turning off when chunks unload, a world is quit, or a dimension unloads
This commit is contained in:
HbmMods 2025-02-27 10:27:15 +01:00 committed by GitHub
commit fa93b944b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 325 additions and 296 deletions

View File

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

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,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<World> 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.StreamWorld> world : NeutronNodeWorld.streamWorlds.entrySet()) {
for(Map.Entry<World, NeutronNodeWorld.StreamWorld> 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<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;
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 {
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() {
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<NeutronStream> 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<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 && node instanceof PileNeutronNode) {
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<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 {
@ -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<BlockPos> 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<BlockPos> 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 && node instanceof RBMKNeutronNode) {
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 || type == null) // 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;
}

View File

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

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,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);

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,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<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);
}
@ -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)

View File

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

View File

@ -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<Block, BlockSelector> bricks = new HashMap<Block, BlockSelector>() {{