RBMK: make that heat, move that heat

This commit is contained in:
Boblet 2021-04-07 13:02:30 +02:00
parent bd9a4cbf8e
commit 84f16755e6
3 changed files with 148 additions and 15 deletions

View File

@ -3,6 +3,7 @@ package com.hbm.inventory.gui;
import org.lwjgl.opengl.GL11;
import com.hbm.inventory.container.ContainerRBMKRod;
import com.hbm.items.machine.ItemRBMKRod;
import com.hbm.lib.RefStrings;
import com.hbm.tileentity.machine.rbmk.TileEntityRBMKRod;
@ -41,6 +42,14 @@ public class GUIRBMKRod extends GuiContainer {
if(rod.slots[0] != null) {
drawTexturedModalRect(guiLeft + 34, guiTop + 21, 176, 0, 18, 67);
double depletion = ItemRBMKRod.getEnrichment(rod.slots[0]);
int d = (int)(depletion * 67);
drawTexturedModalRect(guiLeft + 34, guiTop + 21, 194, 0, 18, d);
double xenon = ItemRBMKRod.getPoisonLevel(rod.slots[0]);
int x = (int)(xenon * 58);
drawTexturedModalRect(guiLeft + 126, guiTop + 82 - x, 212, 58 - x, 14, x);
}
}
}

View File

@ -13,13 +13,13 @@ import net.minecraft.util.EnumChatFormatting;
public class ItemRBMKRod extends ItemHazard {
String fullName = "";
double funcStart;
double funcEnd;
double xGen = 0.5D;;
double xBurn = 50D;
double heat = 1D;
double yield;
String fullName = ""; //full name of the fuel rod
double funcStart; //starting point of the linear reactivity function
double funcEnd; //endpoint of the function
double xGen = 0.5D;; //multiplier for xenon production
double xBurn = 50D; //divider for xenon burnup
double heat = 1D; //heat produced per outFlux
double yield; //total potential inFlux the rod can take in its lifetime
public ItemRBMKRod(String fullName) {
@ -41,8 +41,47 @@ public class ItemRBMKRod extends ItemHazard {
return this;
}
public double burn(ItemStack stack, double flux) {
return 0;
/**
* Adjusts the input flux using the poison level
* Generates, then burns poison
* Calculates the outflux based on influx, enrichment and poison
* Depletes the yield, then returns the outflux
* @param stack
* @param inFlux
* @return outFlux
*/
public double burn(ItemStack stack, double inFlux) {
inFlux *= getPoisonLevel(stack);
double xenon = getPoison(stack);
xenon += xenonGenFunc(inFlux);
xenon -= xenonBurnFunc(inFlux);
if(xenon < 0D) xenon = 0D;
if(xenon > 100D) xenon = 100D;
setPoison(stack, xenon);
double outFlux = reactivityFunc(inFlux * getEnrichment(stack));
double y = getYield(stack);
y -= inFlux;
if(y < 0D) y = 0D;
setYield(stack, y);
return outFlux;
}
/**
* Call this after 'burn' and supply its returned outFlux to get the appropriate heat
* @param flux
* @return heat generated from outFlux
*/
public double heatFromFlux(double flux) {
return flux * this.heat;
}
/**
@ -53,10 +92,20 @@ public class ItemRBMKRod extends ItemHazard {
return funcStart + (funcEnd - funcStart) * flux / 100D; //goodness gracious i guessed the right formula on the first try!
}
/**
* Xenon generated per tick, linear function
* @param flux
* @return
*/
public double xenonGenFunc(double flux) {
return flux * xGen;
}
/**
* Xenon burned away per tick, quadratic function
* @param flux
* @return
*/
public double xenonBurnFunc(double flux) {
return (flux * flux) / xBurn;
}
@ -65,10 +114,18 @@ public class ItemRBMKRod extends ItemHazard {
* @param stack
* @return enrichment [0;1]
*/
public double getEnrichment(ItemStack stack) {
public static double getEnrichment(ItemStack stack) {
return getYield(stack) / ((ItemRBMKRod) stack.getItem()).yield;
}
/**
* @param stack
* @return poison [0;1]
*/
public static double getPoisonLevel(ItemStack stack) {
return getPoison(stack) / 100D;
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) {
@ -131,10 +188,12 @@ public class ItemRBMKRod extends ItemHazard {
return 0;
}
@Override
public boolean showDurabilityBar(ItemStack stack) {
return getDurabilityForDisplay(stack) < 1D;
}
@Override
public double getDurabilityForDisplay(ItemStack stack) {
return getEnrichment(stack);
}

View File

@ -1,6 +1,10 @@
package com.hbm.tileentity.machine.rbmk;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Base class for all RBMK components, active or passive. Handles heat and the explosion sequence
@ -9,18 +13,27 @@ import net.minecraft.tileentity.TileEntity;
*/
public abstract class TileEntityRBMKBase extends TileEntity {
public float heat;
public double heat;
public boolean hasLid() {
return false;
}
public float maxHeat() {
return 1500;
/**
* Approx melting point of steel
* This metric won't be used because fuel tends to melt much earlier than that
* @return
*/
public double maxHeat() {
return 1500D;
}
public float passiveCooling() {
return 5;
/**
* Around the same for every component except boilers which do not have passive cooling
* @return
*/
public double passiveCooling() {
return 5D;
}
//necessary checks to figure out whether players are close enough to ensure that the reactor can be safely used
@ -31,9 +44,61 @@ public abstract class TileEntityRBMKBase extends TileEntity {
@Override
public void updateEntity() {
moveHeat();
coolPassively();
}
public static final ForgeDirection[] heatDirs = new ForgeDirection[] {
ForgeDirection.NORTH,
ForgeDirection.EAST,
ForgeDirection.SOUTH,
ForgeDirection.WEST
};
/**
* Moves heat to neighboring parts, if possible, in a relatively fair manner
*/
private void moveHeat() {
List<TileEntityRBMKBase> rec = new ArrayList();
double req = 0;
for(ForgeDirection dir : heatDirs) {
TileEntity te = worldObj.getTileEntity(xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ);
if(te instanceof TileEntityRBMKBase) {
TileEntityRBMKBase base = (TileEntityRBMKBase) te;
if(base.heat < this.heat) {
rec.add(base);
req += (this.heat - base.heat) / 2D;
}
}
}
if(rec.size() > 0) {
double max = req / rec.size();
for(TileEntityRBMKBase base : rec) {
double move = (this.heat - base.heat) / 2D;
if(move > max)
move = max;
base.heat += move;
this.heat -= move;
}
}
}
/**
* TODO: add faster passive cooling based on temperature (blackbody radiation has an exponent of 4!)
*/
private void coolPassively() {
this.heat -= this.passiveCooling();
}
}