now technically operational

This commit is contained in:
HbmMods 2026-07-22 15:05:31 +02:00
parent 4064efd028
commit 5ac837125c
5 changed files with 320 additions and 57 deletions

View File

@ -127,7 +127,7 @@ public class BlockPileBrick extends Block implements IToolable {
world.setBlock(iX, iY, iZ, ModBlocks.pile_block, BlockPile.META_CORE, 3); world.setBlock(iX, iY, iZ, ModBlocks.pile_block, BlockPile.META_CORE, 3);
TileEntityPileCore core = (TileEntityPileCore) world.getTileEntity(iX, iY, iZ); TileEntityPileCore core = (TileEntityPileCore) world.getTileEntity(iX, iY, iZ);
core.orientation = PileOrientation.getOrientation(dir); core.orientation = PileOrientation.getOrientation(dir);
core.setupSize(posHeight + negHeight + 1, left + right + 1, depth + 1); core.setupSize(posHeight + negHeight + 1, left, right, depth + 1);
} else { } else {
int edgeCount = 0; int edgeCount = 0;
if(h == -negHeight || h == posHeight) edgeCount++; if(h == -negHeight || h == posHeight) edgeCount++;

View File

@ -6,14 +6,17 @@ import java.util.List;
import com.hbm.blocks.IBlockMulti; import com.hbm.blocks.IBlockMulti;
import com.hbm.blocks.ILookOverlay; import com.hbm.blocks.ILookOverlay;
import com.hbm.blocks.ITooltipProvider; import com.hbm.blocks.ITooltipProvider;
import com.hbm.blocks.ModBlocks;
import com.hbm.main.NTMSounds; import com.hbm.main.NTMSounds;
import com.hbm.tileentity.machine.pile.TileEntityPileControl; import com.hbm.tileentity.machine.pile.TileEntityPileControl;
import com.hbm.tileentity.machine.pile.TileEntityPileLoader; import com.hbm.tileentity.machine.pile.TileEntityPileLoader;
import com.hbm.tileentity.machine.pile.TileEntityPileVent; import com.hbm.tileentity.machine.pile.TileEntityPileVent;
import com.hbm.util.i18n.I18nUtil; import com.hbm.util.i18n.I18nUtil;
import api.hbm.block.IToolable;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs; import net.minecraft.creativetab.CreativeTabs;
@ -28,7 +31,7 @@ import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre; import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
public class BlockPileDevice extends BlockContainer implements IBlockMulti, ILookOverlay, ITooltipProvider { public class BlockPileDevice extends BlockContainer implements IBlockMulti, ILookOverlay, ITooltipProvider, IToolable {
public static final int ITEM_META_LOADER = 0; public static final int ITEM_META_LOADER = 0;
public static final int ITEM_META_VENT = 1; public static final int ITEM_META_VENT = 1;
@ -79,6 +82,8 @@ public class BlockPileDevice extends BlockContainer implements IBlockMulti, ILoo
@Override @Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
if(player.isSneaking()) return false;
int meta = world.getBlockMetadata(x, y, z); int meta = world.getBlockMetadata(x, y, z);
meta -= meta % 4; meta -= meta % 4;
@ -184,4 +189,27 @@ public class BlockPileDevice extends BlockContainer implements IBlockMulti, ILoo
if(meta == ITEM_META_CONTROL) return this.getUnlocalizedName() + ".control"; if(meta == ITEM_META_CONTROL) return this.getUnlocalizedName() + ".control";
return this.getUnlocalizedName(); return this.getUnlocalizedName();
} }
@Override
public boolean onScrew(World world, EntityPlayer player, int x, int y, int z, int side, float fX, float fY, float fZ, ToolType tool) {
int meta = world.getBlockMetadata(x, y, z);
if(meta >= BLOCK_META_CONTROL) {
y -= 1;
side = 1;
} else {
ForgeDirection dir = ForgeDirection.getOrientation(meta % 4 + 2);
x -= dir.offsetX;
z -= dir.offsetZ;
side = dir.ordinal();
}
Block b = world.getBlock(x, y, z);
if(b == ModBlocks.pile_block) {
return ((BlockPile) b).onScrew(world, player, x, y, z, side, fX, fY, fZ, tool);
}
return false;
}
} }

View File

@ -29,18 +29,19 @@ public class ItemPileRodMK2 extends ItemEnumMulti {
} }
public static enum EnumPileRod { public static enum EnumPileRod {
RA226BE(1D), /* 0 */ RA226BE(1D),
PO210BE(1D), /* 1 */ PO210BE(1D),
ZR( 0D, 0D, 0D), /* 2 */ ZR( 0D, 0D, 0D, 2),
NU( 1D, 1_000D, 1D), /* 3 */ NU( 1D, 1_000D, 1D, 4),
RGP( 1D, 1_000D, 1D), /* 4 */ PU239( 1D, 1_000D, 1D, 5),
PU239( 1D, 1_000D, 1D), /* 5 */ RGP( 1D, 1_000D, 1D, 6),
WASTE( 1D, 1_000D, 1D); /* 6 */ WASTE( 1D, 0D, 1D, 6);
public double reactionMult = 1.0D; public double reactionMult = 1.0D;
public double life = 1_000D; public double life = 1_000D;
public double heatMult = 1.0D; public double heatMult = 0.0D;
public double neutronSource = 0D; public double neutronSource = 0D;
public int turnsInto;
private EnumPileRod(double neutronSource) { private EnumPileRod(double neutronSource) {
this.neutronSource = neutronSource; this.neutronSource = neutronSource;
@ -49,10 +50,11 @@ public class ItemPileRodMK2 extends ItemEnumMulti {
this.heatMult = 0; this.heatMult = 0;
} }
private EnumPileRod(double reaction, double life, double heat) { private EnumPileRod(double reaction, double life, double heat, int turnsInto) {
this.reactionMult = reaction; this.reactionMult = reaction;
this.life = life; this.life = life;
this.heatMult = heat; this.heatMult = heat;
this.turnsInto = turnsInto;
} }
} }
@ -87,4 +89,22 @@ public class ItemPileRodMK2 extends ItemEnumMulti {
} }
return outFlux; return outFlux;
} }
public static double getHeatPerNeutron(ItemStack stack) {
EnumPileRod rod = EnumUtil.grabEnumSafely(EnumPileRod.class, stack.getItemDamage());
return rod.heatMult;
}
public static ItemStack react(ItemStack stack, double inFlux) {
EnumPileRod rod = EnumUtil.grabEnumSafely(EnumPileRod.class, stack.getItemDamage());
if(rod.life <= 0) return stack;
double dep = getDepletion(stack) + inFlux;
if(dep < rod.life) {
setDepletion(stack, dep);
return stack;
} else {
return new ItemStack(stack.getItem(), 1, rod.turnsInto);
}
}
} }

View File

@ -8,18 +8,25 @@ import com.hbm.blocks.ModBlocks;
import com.hbm.blocks.machine.MachinePWRController; import com.hbm.blocks.machine.MachinePWRController;
import com.hbm.blocks.machine.pile.BlockPile; import com.hbm.blocks.machine.pile.BlockPile;
import com.hbm.interfaces.NotableComments; import com.hbm.interfaces.NotableComments;
import com.hbm.items.machine.ItemPileRodMK2;
import com.hbm.items.machine.ItemPileRodMK2.EnumPileRod;
import com.hbm.main.NTMSounds; import com.hbm.main.NTMSounds;
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.packet.toclient.PlayerInformPacket;
import com.hbm.tileentity.TileEntityTickingBase; import com.hbm.tileentity.TileEntityTickingBase;
import com.hbm.util.EnumUtil;
import com.hbm.util.fauxpointtwelve.BlockPos;
import com.hbm.util.fauxpointtwelve.DirPos; import com.hbm.util.fauxpointtwelve.DirPos;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.MathHelper;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
@NotableComments @NotableComments
@ -56,12 +63,23 @@ public class TileEntityPileCore extends TileEntityTickingBase {
public List<PileChannel> ventilationChannels = new ArrayList(); public List<PileChannel> ventilationChannels = new ArrayList();
public List<PileChannel> controlChannels = new ArrayList(); public List<PileChannel> controlChannels = new ArrayList();
public int left;
public int right;
/**
* Segments are fuel and control channels grouped by vertical slices viewed from the front, this makes the simulation part easier.
*/
public PileSegment[] segments = new PileSegment[0];
@Override @Override
public void readFromNBT(NBTTagCompound nbt) { public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt); super.readFromNBT(nbt);
height = nbt.getInteger("height"); height = nbt.getInteger("height");
width = nbt.getInteger("width"); width = nbt.getInteger("width");
depth = nbt.getInteger("depth"); depth = nbt.getInteger("depth");
left = nbt.getInteger("left");
right = nbt.getInteger("right");
segments = new PileSegment[width];
int fuelCount = nbt.getByte("fc"); int fuelCount = nbt.getByte("fc");
int ventCount = nbt.getByte("vc"); int ventCount = nbt.getByte("vc");
@ -74,6 +92,30 @@ public class TileEntityPileCore extends TileEntityTickingBase {
for(int i = 0; i < fuelCount; i++) fuelChannels.add(readChannelFromNBT(nbt, "f" + i)); for(int i = 0; i < fuelCount; i++) fuelChannels.add(readChannelFromNBT(nbt, "f" + i));
for(int i = 0; i < ventCount; i++) ventilationChannels.add(readChannelFromNBT(nbt, "v" + i)); for(int i = 0; i < ventCount; i++) ventilationChannels.add(readChannelFromNBT(nbt, "v" + i));
for(int i = 0; i < contCount; i++) controlChannels.add(readChannelFromNBT(nbt, "c" + i)); for(int i = 0; i < contCount; i++) controlChannels.add(readChannelFromNBT(nbt, "c" + i));
this.recalculateSegments();
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setInteger("height", height);
nbt.setInteger("width", width);
nbt.setInteger("depth", depth);
nbt.setInteger("left", left);
nbt.setInteger("right", right);
int fuelCount = fuelChannels.size();
int ventCount = ventilationChannels.size();
int contCount = controlChannels.size();
nbt.setByte("fc", (byte) fuelCount);
nbt.setByte("vc", (byte) ventCount);
nbt.setByte("cc", (byte) contCount);
for(int i = 0; i < fuelCount; i++) fuelChannels.get(i).writeChannelToNBT(nbt, "f" + i);
for(int i = 0; i < ventCount; i++) ventilationChannels.get(i).writeChannelToNBT(nbt, "v" + i);
for(int i = 0; i < contCount; i++) controlChannels.get(i).writeChannelToNBT(nbt, "c" + i);
} }
public PileChannel getFuelChannel(int x, int y, int z) { return getChannel(x, y, z, fuelChannels); } public PileChannel getFuelChannel(int x, int y, int z) { return getChannel(x, y, z, fuelChannels); }
@ -93,30 +135,13 @@ public class TileEntityPileCore extends TileEntityTickingBase {
return list.indexOf(chan); // more reliable when channels change and not that big of a deal because we have lists in single digit length return list.indexOf(chan); // more reliable when channels change and not that big of a deal because we have lists in single digit length
} }
@Override public TileEntityPileCore setupSize(int h, int l, int r, int d) {
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setInteger("height", height);
nbt.setInteger("width", width);
nbt.setInteger("depth", depth);
int fuelCount = fuelChannels.size();
int ventCount = ventilationChannels.size();
int contCount = controlChannels.size();
nbt.setByte("fc", (byte) fuelCount);
nbt.setByte("vc", (byte) ventCount);
nbt.setByte("cc", (byte) contCount);
for(int i = 0; i < fuelCount; i++) fuelChannels.get(i).writeChannelToNBT(nbt, "f" + i);
for(int i = 0; i < ventCount; i++) ventilationChannels.get(i).writeChannelToNBT(nbt, "v" + i);
for(int i = 0; i < contCount; i++) controlChannels.get(i).writeChannelToNBT(nbt, "c" + i);
}
public TileEntityPileCore setupSize(int h, int w, int d) {
this.height = h; this.height = h;
this.width = w; this.width = l + 1 + r;
this.depth = d; this.depth = d;
this.left = l;
this.right = r;
this.segments = new PileSegment[width];
return this; return this;
} }
@ -148,6 +173,7 @@ public class TileEntityPileCore extends TileEntityTickingBase {
worldObj.setBlockMetadataWithNotify(iX, iY, iZ, BlockPile.META_DUMMY, 3); worldObj.setBlockMetadataWithNotify(iX, iY, iZ, BlockPile.META_DUMMY, 3);
} }
worldObj.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, NTMSounds.VANILLA_PLINK, 1F, 0.75F); worldObj.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, NTMSounds.VANILLA_PLINK, 1F, 0.75F);
recalculateSegments();
return true; return true;
} }
} }
@ -190,6 +216,8 @@ public class TileEntityPileCore extends TileEntityTickingBase {
worldObj.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, NTMSounds.VANILLA_PLINK, 1F, 1.25F); worldObj.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, NTMSounds.VANILLA_PLINK, 1F, 1.25F);
this.markChanged(); this.markChanged();
recalculateSegments();
return true; return true;
} }
@ -198,37 +226,168 @@ public class TileEntityPileCore extends TileEntityTickingBase {
if(!worldObj.isRemote) { if(!worldObj.isRemote) {
for(PileChannel chan : this.ventilationChannels) { this.runSimulation();
if(chan.air <= 0) continue; this.handleVentilation();
}
int toUse = (int) Math.ceil(chan.air * 5D / 1_000); }
chan.air -= toUse;
protected void runSimulation() {
if(worldObj.getTotalWorldTime() % 3 != 0) continue;
// reaction
double x = chan.entry.getX() + 0.5 + chan.entry.getDir().offsetX * (this.width - 0.375); for(PileChannel chan : this.fuelChannels) {
double y = chan.entry.getY() + 0.5; if(chan.length <= 0) continue;
double z = chan.entry.getZ() + 0.5 + chan.entry.getDir().offsetZ * (this.width - 0.375); double producedNeutrons = 0;
Random rand = worldObj.rand; double latestDepletion = 0D;
NBTTagCompound data = new NBTTagCompound(); for(int i = 0; i < chan.rods.length; i++) {
data.setString("type", "tower"); ItemStack stack = chan.rods[i];
data.setFloat("lift", 1F); if(stack != null && stack.getItem() instanceof ItemPileRodMK2) {
data.setFloat("base", 0.125F + rand.nextFloat() * 0.125F); double neut = ItemPileRodMK2.getReactivity(stack, chan.incomingNeutrons / chan.length);
data.setFloat("max", 1F); producedNeutrons += neut;
data.setFloat("strafe", 0.0025F); chan.heat += neut * ItemPileRodMK2.getHeatPerNeutron(stack);
data.setBoolean("noWind", true); chan.rods[i] = ItemPileRodMK2.react(stack, neut);
data.setInteger("life", 20 + worldObj.rand.nextInt(30)); EnumPileRod rod = EnumUtil.grabEnumSafely(EnumPileRod.class, stack.getItemDamage());
data.setInteger("color", 0xa0a0a0); double life = rod.life < 1 ? 1 : rod.life;
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, x, y, z), new TargetPoint(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 150)); latestDepletion = ItemPileRodMK2.getDepletion(chan.rods[i]) / life;
}
}
chan.outgoingNeutrons = producedNeutrons;
chan.incomingNeutrons = 0;
/// DEBUG ///
int hash = BlockPos.getIdentity(xCoord, yCoord, zCoord);
for(Object o : worldObj.playerEntities) {
if(o instanceof EntityPlayerMP) {
EntityPlayerMP player = (EntityPlayerMP) o;
int index = this.getFuelChannelNum(chan);
PacketDispatcher.wrapper.sendTo(new PlayerInformPacket("#" + index + " " + Math.round(chan.heat) + "TU " + Math.round(chan.outgoingNeutrons) + "n " + Math.round(latestDepletion * 100) + "%", hash + index), player);
}
}
/// DEBUG ///
}
// intra-segment propagation
for(PileSegment seg : this.segments) {
if(seg == null || seg.segType != seg.segType.FUEL) continue;
double outgoing = 0D;
for(PileChannel chan : seg.channels) outgoing += chan.outgoingNeutrons;
for(PileChannel chan : seg.channels) chan.incomingNeutrons += outgoing;
}
// inter-segment propagation
for(int i = 1; i < this.segments.length - 1; i++) { // bound chosen because edges can't have channels
PileSegment seg = this.segments[i];
if(seg == null || seg.segType != seg.segType.FUEL) continue;
double outgoing = 0D;
for(PileChannel chan : seg.channels) outgoing += chan.outgoingNeutrons;
double mult = 1D;
for(int j = i - 1; j >= 1; j--) { // center to left
PileSegment neighbor = this.segments[j];
if(neighbor == null) continue;
mult *= neighbor.getNeutronMult(this);
if(neighbor.segType == neighbor.segType.FUEL) {
for(PileChannel chan : neighbor.channels) chan.incomingNeutrons += outgoing * mult;
}
}
mult = 1D;
for(int j = i + 1; j < this.segments.length - 1; j++) { // center to right
PileSegment neighbor = this.segments[j];
if(neighbor == null) continue;
mult *= neighbor.getNeutronMult(this);
if(neighbor.segType == neighbor.segType.FUEL) {
for(PileChannel chan : neighbor.channels) chan.incomingNeutrons += outgoing * mult;
}
} }
} }
} }
protected void handleVentilation() {
for(PileChannel chan : this.ventilationChannels) {
if(chan.air <= 0) continue;
double airCap = (double) chan.air / (double) chan.MAX_AIR;
for(PileChannel fuel : this.fuelChannels) {
if(Math.abs(fuel.entry.getY() - chan.entry.getY()) <= 1) {
fuel.heat *= (1D - airCap * 0.5D); // channel can hold up to 1000mB, turning into a 0.5 heat mult for connected fuel channels
}
}
int toUse = (int) Math.ceil(airCap * 5D);
chan.air -= toUse;
if(worldObj.getTotalWorldTime() % 3 != 0) continue;
double x = chan.entry.getX() + 0.5 + chan.entry.getDir().offsetX * (this.width - 0.375);
double y = chan.entry.getY() + 0.5;
double z = chan.entry.getZ() + 0.5 + chan.entry.getDir().offsetZ * (this.width - 0.375);
Random rand = worldObj.rand;
NBTTagCompound data = new NBTTagCompound();
data.setString("type", "tower");
data.setFloat("lift", 1F);
data.setFloat("base", (0.125F + rand.nextFloat() * 0.125F) * (float) airCap);
data.setFloat("max", 1F * (float) airCap);
data.setFloat("strafe", 0.0025F);
data.setBoolean("noWind", true);
data.setInteger("life", 20 + worldObj.rand.nextInt(30));
data.setInteger("color", 0xa0a0a0);
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, x, y, z), new TargetPoint(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 150));
}
}
protected void recalculateSegments() {
this.segments = new PileSegment[width];
for(PileChannel chan : fuelChannels) {
int index = getChannelVerticalIndex(chan);
if(index < 0 || index >= this.segments.length) continue;
if(this.segments[index] == null) {
this.segments[index] = new PileSegment(PileChannelType.FUEL).addChan(chan);
} else {
if(this.segments[index].segType == PileChannelType.FUEL) this.segments[index].addChan(chan);
}
}
for(PileChannel chan : controlChannels) {
int index = getChannelVerticalIndex(chan);
if(index < 0 || index >= this.segments.length) continue;
if(this.segments[index] == null) {
this.segments[index] = new PileSegment(PileChannelType.CONTROL).addChan(chan);
} else {
if(this.segments[index].segType == PileChannelType.CONTROL) this.segments[index].addChan(chan);
}
}
}
/**
* Splits the entire pile into vertical slices, left to right, and returns the index of which slice a channel belongs to.
* Since this left-to-right approach assumes the front of the pile, this only is used for fuel channels and control rods.
*/
protected int getChannelVerticalIndex(PileChannel chan) {
DirPos pos = chan.entry;
ForgeDirection right = pos.getDir().getRotation(ForgeDirection.UP);
int deltaX = (pos.getX() - xCoord) * right.offsetX;
int deltaZ = (pos.getZ() - zCoord) * right.offsetZ;
int abs = deltaX == 0 ? deltaZ : deltaX;
int index = abs + this.left;
return index;
}
public void destroy() { public void destroy() {
worldObj.setBlock(xCoord, yCoord, zCoord, ModBlocks.pile_brick); worldObj.setBlock(xCoord, yCoord, zCoord, ModBlocks.pile_brick);
} }
/**
* The orientation of the pile, based on the direction the core is pointing in.
* Channels that follow the orientation are fuel, perpendicular ones are for ventilation.
*/
public static enum PileOrientation { public static enum PileOrientation {
NORTH_SOUTH, NORTH_SOUTH,
EAST_WEST, EAST_WEST,
@ -241,6 +400,10 @@ public class TileEntityPileCore extends TileEntityTickingBase {
} }
} }
/**
* A channel, represents any type, therefore has the data of all three types.
* Could have been an abstract class + three child classes but then we'd just be overcomplicating it.
*/
public class PileChannel { // originally called "PileHole", however i didn't want it sounding too sexual public class PileChannel { // originally called "PileHole", however i didn't want it sounding too sexual
public final DirPos entry; // first channel block plus direction it faces inward public final DirPos entry; // first channel block plus direction it faces inward
@ -249,6 +412,9 @@ public class TileEntityPileCore extends TileEntityTickingBase {
public final ItemStack[] rods; public final ItemStack[] rods;
public double heat = 0D; public double heat = 0D;
public double outgoingNeutrons = 0D;
public double incomingNeutrons = 0D;
public static final int MAX_AIR = 1_000;
public int air; public int air;
public double control = 1D; // pulled out by default, unlike me who never pulls out public double control = 1D; // pulled out by default, unlike me who never pulls out
@ -286,6 +452,17 @@ public class TileEntityPileCore extends TileEntityTickingBase {
} }
} }
nbt.setTag("items", list); nbt.setTag("items", list);
nbt.setDouble("heat", heat);
nbt.setDouble("neutrons", incomingNeutrons);
}
if(type == type.VENTILATION) {
nbt.setInteger("air", air);
}
if(type == type.CONTROL) {
nbt.setDouble("control", control);
} }
} }
@ -335,6 +512,17 @@ public class TileEntityPileCore extends TileEntityTickingBase {
chan.rods[b0] = ItemStack.loadItemStackFromNBT(nbt1); chan.rods[b0] = ItemStack.loadItemStackFromNBT(nbt1);
} }
} }
chan.heat = nbt.getDouble("heat");
chan.incomingNeutrons = nbt.getDouble("neutrons");
}
if(chan.type == chan.type.VENTILATION) {
chan.air = nbt.getInteger("air");
}
if(chan.type == chan.type.CONTROL) {
chan.control = nbt.getDouble("control");
} }
return chan; return chan;
@ -354,4 +542,31 @@ public class TileEntityPileCore extends TileEntityTickingBase {
} }
} }
} }
/** A vertical "slice" of the front of the reactor, can include multiple channels per slice,
* due to reactor geometry constraints, all channels are of the same type. */
public static class PileSegment {
public List<PileChannel> channels = new ArrayList();
public final PileChannelType segType;
public PileSegment(PileChannelType segType) {
this.segType = segType;
}
public PileSegment addChan(PileChannel chan) {
this.channels.add(chan);
return this;
}
public double getNeutronMult(TileEntityPileCore core) {
if(this.segType != this.segType.CONTROL) return 1D;
int size = core.depth - 1; // minus one to make the calculation easier, a xixix pattern becomes xixi which means the rods cover 50%
if(size < 3) return 0D; // reactors this small can't exist, nor can they have control rods
double total = 0D;
for(PileChannel chan : channels) total += chan.control;
return MathHelper.clamp_double(total / size, 0D, 0.5D);
}
}
} }

View File

@ -62,7 +62,7 @@ public class TileEntityPileVent extends TileEntityPileDeviceBase implements IFlu
if(ventChan != null) { if(ventChan != null) {
this.chanNum = core.getVentilationChannelNum(ventChan); this.chanNum = core.getVentilationChannelNum(ventChan);
int toFill = BobMathUtil.min(compair.getFill(), 1_000 - ventChan.air); int toFill = BobMathUtil.min(compair.getFill(), ventChan.MAX_AIR - ventChan.air);
ventChan.air += toFill; ventChan.air += toFill;
this.compair.setFill(this.compair.getFill() - toFill); this.compair.setFill(this.compair.getFill() - toFill);
this.isActive = toFill > 0; this.isActive = toFill > 0;