mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
488 lines
13 KiB
Java
488 lines
13 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.radiation.ChunkRadiationManager;
|
|
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.Compat;
|
|
import com.hbm.util.ParticleUtil;
|
|
|
|
import cpw.mods.fml.common.Optional;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
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.client.gui.GuiScreen;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.inventory.Container;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
|
|
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")})
|
|
public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBMKFluxReceiver, IRBMKLoadable, SimpleComponent {
|
|
|
|
//amount of "neutron energy" buffered for the next tick to use for the reaction
|
|
public double fluxFast;
|
|
public double fluxSlow;
|
|
public boolean hasRod;
|
|
|
|
public TileEntityRBMKRod() {
|
|
super(1);
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "container.rbmkRod";
|
|
}
|
|
|
|
@Override
|
|
public boolean isModerated() {
|
|
return ((RBMKRod)this.getBlockType()).moderated;
|
|
}
|
|
|
|
@SuppressWarnings("incomplete-switch") //shut the fuck up
|
|
@Override
|
|
public void receiveFlux(NType type, double flux) {
|
|
|
|
switch(type) {
|
|
case FAST: this.fluxFast += flux; break;
|
|
case SLOW: this.fluxSlow += flux; break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity() {
|
|
|
|
if(!worldObj.isRemote) {
|
|
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
|
|
ItemRBMKRod rod = ((ItemRBMKRod)slots[0].getItem());
|
|
|
|
double fluxIn = fluxFromType(rod.nType);
|
|
double fluxOut = rod.burn(worldObj, slots[0], fluxIn);
|
|
NType rType = rod.rType;
|
|
|
|
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.fluxFast + this.fluxSlow) * 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();
|
|
}
|
|
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.fluxFast = 0;
|
|
this.fluxSlow = 0;
|
|
|
|
this.worldObj.theProfiler.startSection("rbmkRod_flux_spread");
|
|
spreadFlux(rType, fluxOut);
|
|
this.worldObj.theProfiler.endSection();
|
|
|
|
hasRod = true;
|
|
|
|
} else {
|
|
|
|
this.fluxFast = 0;
|
|
this.fluxSlow = 0;
|
|
|
|
hasRod = false;
|
|
|
|
super.updateEntity();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* SLOW: full efficiency for slow neutrons, fast neutrons have half efficiency
|
|
* FAST: fast neutrons have 100% efficiency, slow only 30%
|
|
* ANY: just add together whatever we have because who cares
|
|
* @param type
|
|
* @return
|
|
*/
|
|
|
|
private double fluxFromType(NType type) {
|
|
|
|
switch(type) {
|
|
case SLOW: return this.fluxFast * 0.5D + this.fluxSlow;
|
|
case FAST: return this.fluxFast + this.fluxSlow * 0.3D;
|
|
case ANY: return this.fluxFast + this.fluxSlow;
|
|
}
|
|
|
|
return 0.0D;
|
|
}
|
|
|
|
public static final ForgeDirection[] fluxDirs = new ForgeDirection[] {
|
|
ForgeDirection.NORTH,
|
|
ForgeDirection.EAST,
|
|
ForgeDirection.SOUTH,
|
|
ForgeDirection.WEST
|
|
};
|
|
|
|
protected static NType stream;
|
|
|
|
protected void spreadFlux(NType type, double fluxOut) {
|
|
|
|
int range = RBMKDials.getFluxRange(worldObj);
|
|
|
|
for(ForgeDirection dir : fluxDirs) {
|
|
|
|
stream = type;
|
|
double flux = fluxOut;
|
|
|
|
for(int i = 1; i <= range; i++) {
|
|
|
|
flux = runInteraction(xCoord + dir.offsetX * i, yCoord, zCoord + dir.offsetZ * i, flux);
|
|
|
|
if(flux <= 0)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected double runInteraction(int x, int y, int z, double flux) {
|
|
|
|
TileEntity te = Compat.getTileStandard(worldObj, x, y, z);
|
|
|
|
if(te instanceof TileEntityRBMKBase) {
|
|
TileEntityRBMKBase base = (TileEntityRBMKBase) te;
|
|
|
|
if(!base.hasLid())
|
|
ChunkRadiationManager.proxy.incrementRad(worldObj, xCoord, yCoord, zCoord, (float) (flux * 0.05F));
|
|
|
|
if(base.isModerated()) {
|
|
this.stream = NType.SLOW;
|
|
}
|
|
}
|
|
|
|
//burn baby burn
|
|
if(te instanceof TileEntityRBMKRod) {
|
|
TileEntityRBMKRod rod = (TileEntityRBMKRod)te;
|
|
|
|
if(rod.getStackInSlot(0) != null && rod.getStackInSlot(0).getItem() instanceof ItemRBMKRod) {
|
|
rod.receiveFlux(stream, flux);
|
|
return 0;
|
|
} else {
|
|
return flux;
|
|
}
|
|
}
|
|
|
|
if(te instanceof TileEntityRBMKOutgasser) {
|
|
TileEntityRBMKOutgasser rod = (TileEntityRBMKOutgasser)te;
|
|
|
|
if(!rod.canProcess()) {
|
|
return flux;
|
|
}
|
|
}
|
|
|
|
if(te instanceof IRBMKFluxReceiver) {
|
|
IRBMKFluxReceiver rod = (IRBMKFluxReceiver)te;
|
|
rod.receiveFlux(stream, flux);
|
|
return 0;
|
|
}
|
|
|
|
//multiply neutron count with rod setting
|
|
if(te instanceof TileEntityRBMKControl) {
|
|
TileEntityRBMKControl control = (TileEntityRBMKControl)te;
|
|
|
|
if(control.getMult() == 0.0D)
|
|
return 0;
|
|
|
|
flux *= control.getMult();
|
|
|
|
return flux;
|
|
}
|
|
|
|
//set neutrons to slow
|
|
if(te instanceof TileEntityRBMKModerator) {
|
|
stream = NType.SLOW;
|
|
return flux;
|
|
}
|
|
|
|
//return the neutrons back to this with no further action required
|
|
if(te instanceof TileEntityRBMKReflector) {
|
|
this.receiveFlux(this.isModerated() ? NType.SLOW : stream, flux);
|
|
return 0;
|
|
}
|
|
|
|
//break the neutron flow and nothign else
|
|
if(te instanceof TileEntityRBMKAbsorber) {
|
|
return 0;
|
|
}
|
|
|
|
if(te instanceof TileEntityRBMKBase) {
|
|
return flux;
|
|
}
|
|
|
|
int limit = RBMKDials.getColumnHeight(worldObj);
|
|
int hits = 0;
|
|
for(int h = 0; h <= limit; h++) {
|
|
|
|
if(!worldObj.getBlock(x, y + h, z).isOpaqueCube())
|
|
hits++;
|
|
}
|
|
|
|
if(hits > 0)
|
|
ChunkRadiationManager.proxy.incrementRad(worldObj, xCoord, yCoord, zCoord, (float) (flux * 0.05F * hits / (float)limit));
|
|
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound nbt) {
|
|
super.readFromNBT(nbt);
|
|
|
|
this.fluxFast = nbt.getDouble("fluxFast");
|
|
this.fluxSlow = nbt.getDouble("fluxSlow");
|
|
this.hasRod = nbt.getBoolean("hasRod");
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound nbt) {
|
|
super.writeToNBT(nbt);
|
|
|
|
nbt.setDouble("fluxFast", this.fluxFast);
|
|
nbt.setDouble("fluxSlow", this.fluxSlow);
|
|
nbt.setBoolean("hasRod", this.hasRod);
|
|
}
|
|
|
|
public void getDiagData(NBTTagCompound nbt) {
|
|
this.writeToNBT(nbt);
|
|
|
|
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 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
|
|
public String getComponentName() {
|
|
return "rbmk_fuel_rod";
|
|
}
|
|
|
|
@Callback(direct = true, limit = 16)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getHeat(Context context, Arguments args) {
|
|
return new Object[] {heat};
|
|
}
|
|
|
|
@Callback(direct = true, limit = 16)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getFluxSlow(Context context, Arguments args) {
|
|
return new Object[] {fluxSlow};
|
|
}
|
|
|
|
@Callback(direct = true, limit = 16)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getFluxFast(Context context, Arguments args) {
|
|
return new Object[] {fluxFast};
|
|
}
|
|
|
|
@Callback(direct = true, limit = 16)
|
|
@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, limit = 16)
|
|
@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, limit = 16)
|
|
@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, limit = 16)
|
|
@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, limit = 16)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getInfo(Context context, Arguments args) {
|
|
Object OC_enrich_buf;
|
|
Object OC_poison_buf;
|
|
Object OC_hull_buf;
|
|
Object OC_core_buf;
|
|
if(slots[0] != null && slots[0].getItem() instanceof ItemRBMKRod) {
|
|
OC_enrich_buf = ItemRBMKRod.getEnrichment(slots[0]);
|
|
OC_poison_buf = ItemRBMKRod.getPoison(slots[0]);
|
|
OC_hull_buf = ItemRBMKRod.getHullHeat(slots[0]);
|
|
OC_core_buf = ItemRBMKRod.getCoreHeat(slots[0]);
|
|
} else {
|
|
OC_enrich_buf = "N/A";
|
|
OC_poison_buf = "N/A";
|
|
OC_hull_buf = "N/A";
|
|
OC_core_buf = "N/A";
|
|
}
|
|
return new Object[] {heat, OC_hull_buf, OC_core_buf, fluxSlow, fluxFast, OC_enrich_buf, OC_poison_buf, ((RBMKRod)this.getBlockType()).moderated, xCoord, yCoord, zCoord};
|
|
}
|
|
|
|
@Callback(direct = true, limit = 16)
|
|
@Optional.Method(modid = "OpenComputers")
|
|
public Object[] getModerated(Context context, Arguments args) {
|
|
return new Object[] {((RBMKRod)this.getBlockType()).moderated};
|
|
}
|
|
|
|
@Callback(direct = true, limit = 16)
|
|
@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 GuiScreen provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
|
return new GUIRBMKRod(player.inventory, this);
|
|
}
|
|
}
|