mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
506 lines
14 KiB
Java
506 lines
14 KiB
Java
package com.hbm.tileentity.machine.rbmk;
|
|
|
|
import com.hbm.blocks.ModBlocks;
|
|
import com.hbm.blocks.machine.rbmk.RBMKBase;
|
|
import com.hbm.blocks.machine.rbmk.RBMKRod;
|
|
import com.hbm.entity.projectile.EntityRBMKDebris.DebrisType;
|
|
import com.hbm.handler.CompatHandler;
|
|
import com.hbm.handler.neutron.NeutronNodeWorld;
|
|
import com.hbm.handler.neutron.RBMKNeutronHandler;
|
|
import com.hbm.handler.radiation.ChunkRadiationManager;
|
|
import com.hbm.handler.neutron.RBMKNeutronHandler.RBMKNeutronNode;
|
|
import com.hbm.handler.neutron.NeutronStream;
|
|
import com.hbm.inventory.container.ContainerRBMKRod;
|
|
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.CompatEnergyControl;
|
|
import com.hbm.util.ParticleUtil;
|
|
|
|
import api.hbm.tile.IInfoProviderEC;
|
|
import com.hbm.util.fauxpointtwelve.BlockPos;
|
|
import cpw.mods.fml.common.Optional;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
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;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.Vec3;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
|
|
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 {
|
|
|
|
// New system!!
|
|
// Used for receiving flux (calculating outbound flux/burning rods)
|
|
public double fluxFastRatio;
|
|
public double fluxQuantity;
|
|
public double lastFluxQuantity;
|
|
public double lastFluxRatio;
|
|
|
|
public boolean hasRod;
|
|
|
|
public TileEntityRBMKRod() {
|
|
super(1);
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "container.rbmkRod";
|
|
}
|
|
|
|
@Override
|
|
public boolean isModerated() {
|
|
return ((RBMKRod)this.getBlockType()).moderated;
|
|
}
|
|
|
|
@Override
|
|
public int trackingRange() {
|
|
return 25;
|
|
}
|
|
|
|
@Override
|
|
public void receiveFlux(NeutronStream stream) {
|
|
double fastFlux = this.fluxQuantity * this.fluxFastRatio;
|
|
double fastFluxIn = stream.fluxQuantity * stream.fluxRatio;
|
|
|
|
this.fluxQuantity += stream.fluxQuantity;
|
|
fluxFastRatio = (fastFlux + fastFluxIn) / fluxQuantity;
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity() {
|
|
|
|
if(!worldObj.isRemote) {
|
|
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
|
|
ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem());
|
|
|
|
double fluxRatioOut;
|
|
double fluxQuantityOut;
|
|
|
|
// Experimental flux ratio curve rods!
|
|
// Again, nothing really uses this so its just idle code at the moment.
|
|
if (rod.specialFluxCurve) {
|
|
|
|
fluxRatioOut = rod.fluxRatioOut(this.fluxFastRatio, ItemRBMKRod.getEnrichment(slots[0]));
|
|
|
|
double fluxIn;
|
|
|
|
fluxIn = rod.fluxFromRatio(this.fluxQuantity, this.fluxFastRatio);
|
|
|
|
fluxQuantityOut = rod.burn(worldObj, slots[0], fluxIn);
|
|
} else {
|
|
NType rType = rod.rType;
|
|
if (rType == NType.SLOW)
|
|
fluxRatioOut = 0;
|
|
else
|
|
fluxRatioOut = 1;
|
|
|
|
double fluxIn = fluxFromType(rod.nType);
|
|
fluxQuantityOut = rod.burn(worldObj, slots[0], fluxIn);
|
|
}
|
|
|
|
rod.updateHeat(worldObj, slots[0], 1.0D);
|
|
this.heat += rod.provideHeat(worldObj, slots[0], heat, 1.0D);
|
|
|
|
if(!this.hasLid()) {
|
|
ChunkRadiationManager.proxy.incrementRad(worldObj, xCoord, yCoord, zCoord, (float) (this.fluxQuantity * 0.05F));
|
|
}
|
|
|
|
super.updateEntity();
|
|
|
|
if(this.heat > this.maxHeat()) {
|
|
|
|
if(RBMKDials.getMeltdownsDisabled(worldObj)) {
|
|
ParticleUtil.spawnGasFlame(worldObj, xCoord + 0.5, yCoord + RBMKDials.getColumnHeight(worldObj) + 0.5, zCoord + 0.5, 0, 0.2, 0);
|
|
} else {
|
|
this.meltdown();
|
|
}
|
|
this.lastFluxRatio = 0;
|
|
this.lastFluxQuantity = 0;
|
|
this.fluxQuantity = 0;
|
|
return;
|
|
}
|
|
|
|
if(this.heat > 10_000) this.heat = 10_000;
|
|
|
|
//for spreading, we want the buffered flux to be 0 because we want to know exactly how much gets reflected back
|
|
|
|
this.lastFluxQuantity = this.fluxQuantity;
|
|
this.lastFluxRatio = this.fluxFastRatio;
|
|
|
|
this.fluxQuantity = 0;
|
|
this.fluxFastRatio = 0;
|
|
|
|
spreadFlux(fluxQuantityOut, fluxRatioOut);
|
|
|
|
hasRod = true;
|
|
|
|
} else {
|
|
|
|
this.lastFluxRatio = 0;
|
|
this.lastFluxQuantity = 0;
|
|
this.fluxQuantity = 0;
|
|
this.fluxFastRatio = 0;
|
|
|
|
hasRod = false;
|
|
|
|
super.updateEntity();
|
|
}
|
|
}
|
|
}
|
|
|
|
private double fluxFromType(NType type) {
|
|
|
|
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;
|
|
case ANY: return this.fluxQuantity;
|
|
}
|
|
|
|
return 0.0D;
|
|
}
|
|
|
|
public static final ForgeDirection[] fluxDirs = new ForgeDirection[] {
|
|
ForgeDirection.NORTH,
|
|
ForgeDirection.EAST,
|
|
ForgeDirection.SOUTH,
|
|
ForgeDirection.WEST
|
|
};
|
|
|
|
private BlockPos pos;
|
|
|
|
public void spreadFlux(double flux, double ratio) {
|
|
|
|
if(pos == null)
|
|
pos = new BlockPos(this);
|
|
|
|
if (flux == 0) {
|
|
// simple way to remove the node from the cache when no flux is going into it!
|
|
NeutronNodeWorld.removeNode(pos);
|
|
return;
|
|
}
|
|
|
|
RBMKNeutronNode node = (RBMKNeutronNode) NeutronNodeWorld.getNode(pos);
|
|
|
|
if(node == null) {
|
|
node = RBMKNeutronHandler.makeNode(this);
|
|
NeutronNodeWorld.addNode(node);
|
|
}
|
|
|
|
for(ForgeDirection dir : fluxDirs) {
|
|
|
|
Vec3 neutronVector = Vec3.createVectorHelper(dir.offsetX, dir.offsetY, dir.offsetZ);
|
|
|
|
// Create new neutron streams
|
|
new RBMKNeutronHandler.RBMKNeutronStream(node, neutronVector, flux, ratio);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound nbt) {
|
|
super.readFromNBT(nbt);
|
|
|
|
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)
|
|
this.fluxFastRatio = nbt.getDouble("fluxFast") / fluxQuantity;
|
|
else
|
|
this.fluxFastRatio = 0;
|
|
} else {
|
|
this.fluxQuantity = nbt.getDouble("fluxQuantity");
|
|
this.fluxFastRatio = nbt.getDouble("fluxMod");
|
|
}
|
|
this.hasRod = nbt.getBoolean("hasRod");
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound nbt) {
|
|
super.writeToNBT(nbt);
|
|
|
|
if (!diag) {
|
|
nbt.setDouble("fluxQuantity", this.lastFluxQuantity);
|
|
nbt.setDouble("fluxMod", this.lastFluxRatio);
|
|
} else {
|
|
nbt.setDouble("fluxSlow", this.fluxQuantity * (1 - fluxFastRatio));
|
|
nbt.setDouble("fluxFast", this.fluxQuantity * fluxFastRatio);
|
|
}
|
|
nbt.setBoolean("hasRod", this.hasRod);
|
|
}
|
|
|
|
@Override
|
|
public void serialize(ByteBuf buf) {
|
|
super.serialize(buf);
|
|
buf.writeDouble(this.lastFluxQuantity);
|
|
buf.writeDouble(this.lastFluxRatio);
|
|
buf.writeBoolean(this.hasRod);
|
|
}
|
|
|
|
@Override
|
|
public void deserialize(ByteBuf buf) {
|
|
super.deserialize(buf);
|
|
this.fluxQuantity = buf.readDouble();
|
|
this.fluxFastRatio = buf.readDouble();
|
|
this.hasRod = buf.readBoolean();
|
|
}
|
|
|
|
public void getDiagData(NBTTagCompound nbt) {
|
|
diag = true;
|
|
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);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onMelt(int reduce) {
|
|
|
|
boolean moderated = this.isModerated();
|
|
int h = RBMKDials.getColumnHeight(worldObj);
|
|
reduce = MathHelper.clamp_int(reduce, 1, h);
|
|
|
|
if(worldObj.rand.nextInt(3) == 0)
|
|
reduce++;
|
|
|
|
boolean corium = slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod;
|
|
|
|
if(corium && slots[0].getItem() == ModItems.rbmk_fuel_drx)
|
|
RBMKBase.digamma = true;
|
|
|
|
slots[0] = null;
|
|
|
|
if(corium) {
|
|
|
|
for(int i = h; i >= 0; i--) {
|
|
worldObj.setBlock(xCoord, yCoord + i, zCoord, ModBlocks.corium_block, 5, 3);
|
|
worldObj.markBlockForUpdate(xCoord, yCoord + i, zCoord);
|
|
}
|
|
|
|
int count = 1 + worldObj.rand.nextInt(RBMKDials.getColumnHeight(worldObj));
|
|
|
|
for(int i = 0; i < count; i++) {
|
|
spawnDebris(DebrisType.FUEL);
|
|
}
|
|
} else {
|
|
this.standardMelt(reduce);
|
|
}
|
|
|
|
if(moderated) {
|
|
|
|
int count = 2 + worldObj.rand.nextInt(2);
|
|
|
|
for(int i = 0; i < count; i++) {
|
|
spawnDebris(DebrisType.GRAPHITE);
|
|
}
|
|
}
|
|
|
|
spawnDebris(DebrisType.ELEMENT);
|
|
|
|
if(this.getBlockMetadata() == RBMKBase.DIR_NORMAL_LID.ordinal() + RBMKBase.offset)
|
|
spawnDebris(DebrisType.LID);
|
|
}
|
|
|
|
@Override
|
|
public RBMKNeutronHandler.RBMKType getRBMKType() {
|
|
return RBMKNeutronHandler.RBMKType.ROD;
|
|
}
|
|
|
|
@Override
|
|
public ColumnType getConsoleType() {
|
|
return ColumnType.FUEL;
|
|
}
|
|
|
|
@Override
|
|
public NBTTagCompound getNBTForConsole() {
|
|
NBTTagCompound data = new NBTTagCompound();
|
|
|
|
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("c_maxHeat", rod.meltingPoint);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
@Override
|
|
public boolean canLoad(ItemStack toLoad) {
|
|
return toLoad != null && slots[0] == null;
|
|
}
|
|
|
|
@Override
|
|
public void load(ItemStack toLoad) {
|
|
slots[0] = toLoad.copy();
|
|
this.markDirty();
|
|
}
|
|
|
|
@Override
|
|
public boolean canUnload() {
|
|
return slots[0] != null;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack provideNext() {
|
|
return slots[0];
|
|
}
|
|
|
|
@Override
|
|
public void unload() {
|
|
slots[0] = null;
|
|
this.markDirty();
|
|
}
|
|
|
|
// do some opencomputer stuff
|
|
@Override
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public String getComponentName() {
|
|
return "rbmk_fuel_rod";
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getHeat(Context context, Arguments args) {
|
|
return new Object[] {heat};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getFluxQuantity(Context context, Arguments args) {
|
|
return new Object[] {fluxQuantity};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getFluxRatio(Context context, Arguments args) {
|
|
return new Object[] {fluxFastRatio};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getDepletion(Context context, Arguments args) {
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
return new Object[] {ItemRBMKRod.getEnrichment(slots[0])};
|
|
}
|
|
return new Object[] {"N/A"};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getXenonPoison(Context context, Arguments args) {
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
return new Object[] {ItemRBMKRod.getPoison(slots[0])};
|
|
}
|
|
return new Object[] {"N/A"};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getCoreHeat(Context context, Arguments args) {
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
return new Object[] {ItemRBMKRod.getCoreHeat(slots[0])};
|
|
}
|
|
return new Object[] {"N/A"};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getSkinHeat(Context context, Arguments args) {
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
return new Object[] {ItemRBMKRod.getHullHeat(slots[0])};
|
|
}
|
|
return new Object[] {"N/A"};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getType(Context context, Arguments args) {
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
return new Object[] {slots[0].getItem().getUnlocalizedName()};
|
|
}
|
|
return new Object[] {"N/A"};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getInfo(Context context, Arguments args) {
|
|
List<Object> returnValues = new ArrayList<>();
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
returnValues.add(ItemRBMKRod.getHullHeat(slots[0]));
|
|
returnValues.add(ItemRBMKRod.getCoreHeat(slots[0]));
|
|
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");
|
|
|
|
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};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getModerated(Context context, Arguments args) {
|
|
return new Object[] {((RBMKRod)this.getBlockType()).moderated};
|
|
}
|
|
|
|
@Callback(direct = true)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getCoordinates(Context context, Arguments args) {
|
|
return new Object[] {xCoord, yCoord, zCoord};
|
|
}
|
|
|
|
@Override
|
|
public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
|
return new ContainerRBMKRod(player.inventory, this);
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
|
return new GUIRBMKRod(player.inventory, this);
|
|
}
|
|
|
|
@Override
|
|
public void provideExtraInfo(NBTTagCompound data) {
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
data.setDouble(CompatEnergyControl.D_DEPLETION_PERCENT, ((1.0D - ItemRBMKRod.getEnrichment(slots[0])) * 100_000.0D) / 1_000.0D);
|
|
data.setDouble(CompatEnergyControl.D_XENON_PERCENT, ItemRBMKRod.getPoison(slots[0]));
|
|
data.setDouble(CompatEnergyControl.D_SKIN_C, ItemRBMKRod.getHullHeat(slots[0]));
|
|
data.setDouble(CompatEnergyControl.D_CORE_C, ItemRBMKRod.getCoreHeat(slots[0]));
|
|
data.setDouble(CompatEnergyControl.D_MELT_C, ((ItemRBMKRod) slots[0].getItem()).meltingPoint);
|
|
}
|
|
}
|
|
}
|