diff --git a/dependencies.gradle b/dependencies.gradle index 60e303570..07f32d2af 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -67,6 +67,7 @@ dependencies { implementation rfg.deobf("curse.maven:athenaeum-284350:4633750") implementation rfg.deobf("curse.maven:dropt-284973:5405050") + compileOnly rfg.deobf("curse.maven:opencomputers-223008:5274236") compileOnly rfg.deobf("curse.maven:yungs-better-mineshafts-forge-389665:3247154") api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.700") diff --git a/src/main/java/supersymmetry/api/capability/ICoolantHandler.java b/src/main/java/supersymmetry/api/capability/ICoolantHandler.java new file mode 100644 index 000000000..a37522eab --- /dev/null +++ b/src/main/java/supersymmetry/api/capability/ICoolantHandler.java @@ -0,0 +1,24 @@ +package supersymmetry.api.capability; + + +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fluids.Fluid; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import supersymmetry.api.capability.impl.LockableFluidTank; +import supersymmetry.api.nuclear.fission.ICoolantStats; + +public interface ICoolantHandler extends ILockableHandler { + + @Nullable + ICoolantStats getCoolant(); + + void setCoolant(@Nullable ICoolantStats prop); + + @NotNull + LockableFluidTank getFluidTank(); + + @NotNull + EnumFacing getFrontFacing(); +} diff --git a/src/main/java/supersymmetry/api/capability/IFuelRodHandler.java b/src/main/java/supersymmetry/api/capability/IFuelRodHandler.java new file mode 100644 index 000000000..69db7f1fc --- /dev/null +++ b/src/main/java/supersymmetry/api/capability/IFuelRodHandler.java @@ -0,0 +1,28 @@ +package supersymmetry.api.capability; + + +import net.minecraft.item.ItemStack; +import supersymmetry.api.items.itemhandlers.LockableItemStackHandler; +import supersymmetry.api.nuclear.fission.IFissionFuelStats; +import supersymmetry.api.nuclear.fission.components.FuelRod; + +public interface IFuelRodHandler extends ILockableHandler { + + IFissionFuelStats getFuel(); + + void setFuel(IFissionFuelStats prop); + + IFissionFuelStats getPartialFuel(); + + /** + * Set the fuel type that's currently being processed by this specific handler. + * + * @param prop The new fuel type. + * @return true if the partial fuel changed. + */ + boolean setPartialFuel(IFissionFuelStats prop); + + void setInternalFuelRod(FuelRod rod); + + LockableItemStackHandler getStackHandler(); +} diff --git a/src/main/java/supersymmetry/api/capability/ILockableHandler.java b/src/main/java/supersymmetry/api/capability/ILockableHandler.java new file mode 100644 index 000000000..bc679800c --- /dev/null +++ b/src/main/java/supersymmetry/api/capability/ILockableHandler.java @@ -0,0 +1,13 @@ +package supersymmetry.api.capability; + +import org.jetbrains.annotations.Nullable; + +public interface ILockableHandler { + + void setLock(boolean isLocked); + + boolean isLocked(); + + @Nullable + T getLockedObject(); +} diff --git a/src/main/java/supersymmetry/api/capability/impl/LockableFluidTank.java b/src/main/java/supersymmetry/api/capability/impl/LockableFluidTank.java new file mode 100644 index 000000000..20cb154e4 --- /dev/null +++ b/src/main/java/supersymmetry/api/capability/impl/LockableFluidTank.java @@ -0,0 +1,81 @@ +package supersymmetry.api.capability.impl; + +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import supersymmetry.api.capability.ILockableHandler; + +public class LockableFluidTank extends NotifiableFluidTank implements ILockableHandler { + + private boolean locked; + private Fluid lockedFluid; + + public LockableFluidTank(int capacity, MetaTileEntity entityToNotify, boolean isExport) { + super(capacity, entityToNotify, isExport); + } + + @Override + public Fluid getLockedObject() { + return lockedFluid; + } + + @Override + public void setLock(boolean isLocked) { + locked = isLocked; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + int filled = super.fill(resource, doFill); + if (doFill && this.fluid != null && this.fluid.amount != 0) { + this.lockedFluid = this.fluid.getFluid(); + } + return filled; + } + + @Override + public void setFluid(FluidStack fluid) { + super.setFluid(fluid); + if (this.fluid != null && this.fluid.amount != 0) { + this.lockedFluid = this.fluid.getFluid(); + } + } + + @Override + public boolean isLocked() { + return locked; + } + + @Override + public boolean canFillFluidType(FluidStack fluid) { + if (locked && fluid.getFluid() != lockedFluid) { + return false; + } + return super.canFillFluidType(fluid); + } + + @Override + public FluidTank readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + if (nbt.hasKey("LockedFluid")) { + this.lockedFluid = FluidRegistry.getFluid(nbt.getString("LockedFluid")); + } else if (this.fluid != null && this.fluid.amount != 0) { + this.lockedFluid = this.fluid.getFluid(); + } + return this; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + if (lockedFluid != null) { + nbt.setString("LockedFluid", lockedFluid.getName()); + } + return nbt; + } +} diff --git a/src/main/java/supersymmetry/api/cover/ICustomEnergyCover.java b/src/main/java/supersymmetry/api/cover/ICustomEnergyCover.java new file mode 100644 index 000000000..3b12e405a --- /dev/null +++ b/src/main/java/supersymmetry/api/cover/ICustomEnergyCover.java @@ -0,0 +1,18 @@ +package supersymmetry.api.cover; + +/** + * Simple interface specifying that an attached energy detector(advanced or not) cover reads custom EU values from the + * MTE + */ +public interface ICustomEnergyCover { + + /** + * @return The total EU capacity + */ + long getCoverCapacity(); + + /** + * @return The stored EU capacity + */ + long getCoverStored(); +} diff --git a/src/main/java/supersymmetry/api/gui/SusyGuiTextures.java b/src/main/java/supersymmetry/api/gui/SusyGuiTextures.java index bbe38754e..5f073093d 100644 --- a/src/main/java/supersymmetry/api/gui/SusyGuiTextures.java +++ b/src/main/java/supersymmetry/api/gui/SusyGuiTextures.java @@ -28,4 +28,13 @@ public class SusyGuiTextures { public static final TextureArea BUTTON_INT_CIRCUIT_PLUS_PRIMITIVE = TextureArea.fullImage("textures/gui/widget/button_circuit_plus_primitive.png"); public static final TextureArea BUTTON_INT_CIRCUIT_MINUS_PRIMITIVE = TextureArea.fullImage("textures/gui/widget/button_circuit_minus_primitive.png"); public static final TextureArea FLUID_SLOT_PRIMITIVE = TextureArea.fullImage("textures/gui/base/fluid_slot_primitive.png"); + + // Nuclear GuiTextures + public static final TextureArea BUTTON_CONTROL_ROD_HELPER = TextureArea.fullImage("textures/gui/widget/button_control_rod_helper.png"); + public static final TextureArea DARK_SLIDER_BACKGROUND = TextureArea.fullImage("textures/gui/widget/dark_slider_background.png"); + public static final TextureArea DARK_SLIDER_BACKGROUND_VERTICAL = TextureArea.fullImage("textures/gui/widget/dark_slider_background_vertical.png"); + public static final TextureArea DARK_SLIDER_ICON = TextureArea.fullImage("textures/gui/widget/dark_slider.png"); + public static final TextureArea PROGRESS_BAR_FISSION_HEAT = TextureArea.fullImage("textures/gui/progress_bar/progress_bar_fission_heat.png"); + public static final TextureArea PROGRESS_BAR_FISSION_PRESSURE = TextureArea.fullImage("textures/gui/progress_bar/progress_bar_fission_pressure.png"); + public static final TextureArea PROGRESS_BAR_FISSION_ENERGY = TextureArea.fullImage("textures/gui/progress_bar/progress_bar_fission_energy.png"); } diff --git a/src/main/java/supersymmetry/api/gui/widgets/UpdatedSliderWidget.java b/src/main/java/supersymmetry/api/gui/widgets/UpdatedSliderWidget.java new file mode 100644 index 000000000..b6a7bccde --- /dev/null +++ b/src/main/java/supersymmetry/api/gui/widgets/UpdatedSliderWidget.java @@ -0,0 +1,42 @@ +package supersymmetry.api.gui.widgets; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.widgets.SliderWidget; +import gregtech.api.util.Position; +import gregtech.api.util.Size; +import gregtech.api.util.function.FloatConsumer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import supersymmetry.api.util.function.FloatSupplier; +import supersymmetry.mixins.gregtech.SliderWidgetAccessor; + +public class UpdatedSliderWidget extends SliderWidget { + + private FloatSupplier detector; + private final SliderWidgetAccessor self; + + public UpdatedSliderWidget(String name, int xPosition, int yPosition, int width, int height, float min, float max, + float currentValue, FloatConsumer responder, FloatSupplier detector) { + super(name, xPosition, yPosition, width, height, min, max, currentValue, responder); + this.detector = detector; + this.self = (SliderWidgetAccessor) this; + } + + @Override + public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { + Position pos = getPosition(); + Size size = getSize(); + if (self.getBackgroundArea() != null) { + self.getBackgroundArea().draw(pos.x, pos.y, size.width, size.height); + } + self.setSliderPosition((detector.get() - self.getMin()) / (self.getMax() - self.getMin())); + self.setDisplayString2(getDisplayString()); + + self.getSliderIcon().draw(pos.x + (int) (self.getSliderPosition() * (float) (size.width - 8)), pos.y, self.getSliderWidth(), + size.height); + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; + fontRenderer.drawString(self.getDisplayString2(), + pos.x + size.width / 2 - fontRenderer.getStringWidth(self.getDisplayString2()) / 2, + pos.y + size.height / 2 - fontRenderer.FONT_HEIGHT / 2, self.getTextColor()); + } +} diff --git a/src/main/java/supersymmetry/api/items/itemhandlers/LockableItemStackHandler.java b/src/main/java/supersymmetry/api/items/itemhandlers/LockableItemStackHandler.java new file mode 100644 index 000000000..865a8d69e --- /dev/null +++ b/src/main/java/supersymmetry/api/items/itemhandlers/LockableItemStackHandler.java @@ -0,0 +1,45 @@ +package supersymmetry.api.items.itemhandlers; + +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraft.item.ItemStack; + +import org.jetbrains.annotations.NotNull; +import supersymmetry.api.capability.ILockableHandler; + +public class LockableItemStackHandler extends NotifiableItemStackHandler implements ILockableHandler { + + protected boolean locked; + protected ItemStack lockedItemStack; + + public LockableItemStackHandler(MetaTileEntity entityToNotify, boolean isExport) { + super(entityToNotify, 1, entityToNotify, isExport); + } + + @Override + public void setLock(boolean isLocked) { + this.locked = isLocked; + if (isLocked && !this.getStackInSlot(0).isEmpty()) { + lockedItemStack = this.getStackInSlot(0).copy(); + } + } + + public boolean isLocked() { + return this.locked; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + if (this.locked && !this.lockedItemStack.isItemEqual(stack)) { + return stack; + } + return super.insertItem(slot, stack, simulate); + } + + @Override + public ItemStack getLockedObject() { + return lockedItemStack; + } +} diff --git a/src/main/java/supersymmetry/api/metatileentity/multiblock/IFissionReactorHatch.java b/src/main/java/supersymmetry/api/metatileentity/multiblock/IFissionReactorHatch.java new file mode 100644 index 000000000..967eed49c --- /dev/null +++ b/src/main/java/supersymmetry/api/metatileentity/multiblock/IFissionReactorHatch.java @@ -0,0 +1,17 @@ +package supersymmetry.api.metatileentity.multiblock; + +import net.minecraft.util.math.BlockPos; + +import org.jetbrains.annotations.Nullable; + +public interface IFissionReactorHatch { + + /** + * @param depth The depth of the reactor that needs checking + * @return If the channel directly below the hatch is valid or not + */ + boolean checkValidity(int depth); + + @Nullable + BlockPos getPos(); +} diff --git a/src/main/java/supersymmetry/api/metatileentity/multiblock/SuSyMultiblockAbilities.java b/src/main/java/supersymmetry/api/metatileentity/multiblock/SuSyMultiblockAbilities.java index f1d942b7b..10b4b9ee6 100644 --- a/src/main/java/supersymmetry/api/metatileentity/multiblock/SuSyMultiblockAbilities.java +++ b/src/main/java/supersymmetry/api/metatileentity/multiblock/SuSyMultiblockAbilities.java @@ -2,8 +2,19 @@ import gregtech.api.metatileentity.multiblock.MultiblockAbility; import net.minecraftforge.items.IItemHandlerModifiable; +import supersymmetry.api.capability.ICoolantHandler; +import supersymmetry.api.capability.IFuelRodHandler; +import supersymmetry.common.metatileentities.multi.multiblockpart.MetaTileEntityControlRodPort; +@SuppressWarnings("InstantiationOfUtilityClass") public class SuSyMultiblockAbilities { + public static final MultiblockAbility PRIMITIVE_IMPORT_ITEMS = new MultiblockAbility<>("primitive_import_items"); public static final MultiblockAbility PRIMITIVE_EXPORT_ITEMS = new MultiblockAbility<>("primitive_export_items"); + + public static final MultiblockAbility IMPORT_FUEL_ROD = new MultiblockAbility<>("import_fuel_rod"); + public static final MultiblockAbility EXPORT_FUEL_ROD = new MultiblockAbility<>("export_fuel_rod"); + public static final MultiblockAbility IMPORT_COOLANT = new MultiblockAbility<>("import_coolant"); + public static final MultiblockAbility EXPORT_COOLANT = new MultiblockAbility<>("export_coolant"); + public static final MultiblockAbility CONTROL_ROD_PORT = new MultiblockAbility<>("control_rod_port"); } diff --git a/src/main/java/supersymmetry/api/nuclear/fission/CoolantRegistry.java b/src/main/java/supersymmetry/api/nuclear/fission/CoolantRegistry.java new file mode 100644 index 000000000..470bec3a5 --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/CoolantRegistry.java @@ -0,0 +1,36 @@ +package supersymmetry.api.nuclear.fission; + +import net.minecraftforge.fluids.Fluid; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Map; + +public class CoolantRegistry { + + private static final Map COOLANTS = new Object2ObjectOpenHashMap<>(); + private static final Map COOLANTS_INVERSE = new Object2ObjectOpenHashMap<>(); + + public static void registerCoolant(@NotNull Fluid fluid, @NotNull ICoolantStats coolant) { + COOLANTS.put(fluid, coolant); + COOLANTS_INVERSE.put(coolant, fluid); + } + + @Nullable + public static ICoolantStats getCoolant(Fluid fluid) { + return COOLANTS.get(fluid); + } + + @NotNull + public static Collection getAllCoolants() { + return COOLANTS.keySet(); + } + + @Nullable + public static Fluid originalFluid(ICoolantStats stats) { + return COOLANTS_INVERSE.get(stats); + } +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/FissionFuelRegistry.java b/src/main/java/supersymmetry/api/nuclear/fission/FissionFuelRegistry.java new file mode 100644 index 000000000..0e810e83e --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/FissionFuelRegistry.java @@ -0,0 +1,47 @@ +package supersymmetry.api.nuclear.fission; + +import gregtech.api.util.ItemStackHashStrategy; + +import net.minecraft.item.ItemStack; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Map; + +public class FissionFuelRegistry { + + private static final Map IDENTIFIED_FUELS = new Object2ObjectOpenHashMap<>(); + private static final Map FUELS = new Object2ObjectOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount()); + private static final Map DEPLETED_FUELS = new Object2ObjectOpenHashMap<>(); + + public static void registerFuel(@NotNull ItemStack item, @NotNull IFissionFuelStats fuel, + @NotNull ItemStack depletedFuel) { + IDENTIFIED_FUELS.put(fuel.getID(), fuel); + FUELS.put(item, fuel); + DEPLETED_FUELS.put(fuel, depletedFuel); + } + + @Nullable + public static IFissionFuelStats getFissionFuel(ItemStack stack) { + return FUELS.get(stack); + } + + @NotNull + public static Collection getAllFissionableRods() { + return FUELS.keySet(); + } + + @Nullable + public static IFissionFuelStats getFissionFuel(String name) { + return IDENTIFIED_FUELS.get(name); + } + + public static @NotNull ItemStack getDepletedFuel(IFissionFuelStats stats) { + return DEPLETED_FUELS.get(stats).copy(); + } +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/FissionReactor.java b/src/main/java/supersymmetry/api/nuclear/fission/FissionReactor.java new file mode 100644 index 000000000..b97dd322f --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/FissionReactor.java @@ -0,0 +1,724 @@ +package supersymmetry.api.nuclear.fission; + +import gregtech.common.ConfigHolder; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import supersymmetry.api.nuclear.fission.components.ControlRod; +import supersymmetry.api.nuclear.fission.components.CoolantChannel; +import supersymmetry.api.nuclear.fission.components.FuelRod; +import supersymmetry.api.nuclear.fission.components.ReactorComponent; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class FissionReactor { + + /** + * The gas constant in J * K^-1 * mol^-1 if you want to use a different set of units prepare thy life to become the + * worst of nightmares + */ + public static final double R = 8.31446261815324; + /** + * Standard pressure in Pascal, corresponds to one standard atmosphere + */ + public static final double standardPressure = 101325; + + /** + * The starting temperature of the reactor in Kelvin + */ + public static final double roomTemperature = 273; + + /** + * Boiling point of air at standard pressure in Kelvin + */ + public static final double airBoilingPoint = 78.8; + + private ReactorComponent[][] reactorLayout; + private final List fuelRods; + private final List controlRods; + private final List coolantChannels; + private final List effectiveControlRods; + private final List effectiveCoolantChannels; + + private double k; + + private double controlRodFactor; + + public double kEff; // criticality value, based on k + + /** + * Integers used on variables with direct player control for easier adjustments (normalize this to 0,1) + */ + public double controlRodInsertion; + private int reactorDepth; + private double reactorRadius; + + private boolean moderatorTipped; // set by the type of control rod in the reactor(prepInitialConditions) + + /** + * Megawatts + */ + public double power; + + /** + * Temperature of the reactor + */ + public double temperature = roomTemperature; + public double pressure = standardPressure; + private double exteriorPressure = standardPressure; + /** + * Temperature of boiling point in kelvin at standard pressure Determined by a weighted sum of the individual + * coolant boiling points in {@link FissionReactor#prepareInitialConditions()} + */ + private double coolantBoilingPointStandardPressure; + + /** + * Average temperature of the coolant in kelvin as coolant exits the reactor. + */ + private double coolantExitTemperature; + + private double prevTemperature; + + /** + * Latent heat of vaporization in J/mol Determined by a weighted sum of the individual heats of vaporization in + * {@link FissionReactor#prepareInitialConditions()} + */ + private double coolantHeatOfVaporization; + /** + * Equilibrium temperature in kelvin Determined by a weighted sum of the individual coolant temperatures in + * {@link FissionReactor#prepareInitialConditions()} + */ + private double coolantBaseTemperature; + public double maxFuelDepletion = 1; + public double fuelDepletion = -1; + private double neutronPoisonAmount; // can kill reactor if power is lowered and this value is high + private double decayProductsAmount; + private double envTemperature = roomTemperature; // maybe gotten from config per dim + public double accumulatedHydrogen; + private double weightedGenerationTime = 2; // The mean generation time in seconds, accounting for delayed neutrons + + public double maxTemperature = 2000; + // Pascals + public double maxPressure = 15000000; + // In MW apparently + public double maxPower = 3; // determined by the amount of fuel in reactor and neutron matricies + public static double zircaloyHydrogenReactionTemperature = 1500; + + private double surfaceArea; + public static double thermalConductivity = 45; // 45 W/(m K), for steel + public static double wallThickness = 0.1; + public static double coolantWallThickness = 0.06; // Ideal for a 1-m diameter steel pipe with the given maximum + // pressure + public static double specificHeatCapacity = 420; // 420 J/(kg K), for steel + public static double convectiveHeatTransferCoefficient = 10; // 10 W/(m^2 K), for slow-moving air + + public static double powerDefectCoefficient = 0.016; // In units of reactivity + public static double decayProductRate = 0.997; // Based on the half-life of xenon-135, using real-life days as + // Minecraft days, and yes, I am using this for plutonium too + public static double poisonFraction = 0.063; // Xenon-135 yield from fission + public static double crossSectionRatio = 4; // The ratio between the cross section for typical fuels and xenon-135; + + // very much changed here for balance purposes + + private double coolantMass; + public double fuelMass; + private double structuralMass; + public boolean needsOutput; + public boolean controlRodRegulationOn = true; + protected boolean isOn = false; + + protected static double responseFunction(double target, double current, double criticalRate) { + if (current < 0) { + if (criticalRate < 1) { + return 0; + } else { + current = 0.1; + } + } + double expDecay = Math.exp(-criticalRate); + return current * expDecay + target * (1 - expDecay); + } + + protected double responseFunctionTemperature(double envTemperature, double currentTemperature, double heatAdded, + double heatAbsorbed) { + currentTemperature = Math.max(0.1, currentTemperature); + heatAbsorbed = Math.max(0, heatAbsorbed); + /* + * Simplifies what is the following: + * heatTransferCoefficient = 1 / (1 / convectiveHeatTransferCoefficient + wallThickness / thermalConductivity); + * (https://en.wikipedia.org/wiki/Newton%27s_law_of_cooling#First-order_transient_response_of_lumped- + * capacitance_objects) + * This assumes that we're extracting heat from the reactor through the wall into slowly moving air, removing + * the second convective heat. + * timeConstant = heatTransferCoefficient * this.surfaceArea / specificHeatCapacity; + */ + // Technically the inverse. + double timeConstant = specificHeatCapacity * + (1 / convectiveHeatTransferCoefficient + wallThickness / thermalConductivity) / this.surfaceArea; + + // Solves the following differential equation: + // dT/dt = h_added_tot / m_tot - k(T - T_env) at t = 1s with T(0) = T_0 + double expDecay = Math.exp(-timeConstant); + + double effectiveEnvTemperature = envTemperature + + (heatAdded - heatAbsorbed) / (timeConstant * (this.coolantMass + this.structuralMass + this.fuelMass)); + return currentTemperature * expDecay + effectiveEnvTemperature * (1 - expDecay); + } + + public FissionReactor(int size, int depth, double controlRodInsertion) { + reactorLayout = new ReactorComponent[size][size]; + reactorDepth = depth; + reactorRadius = (double) size / 2 + 1.5; // Includes the extra block plus the distance from the center of a + // block to its edge + // Maps (0, 15) -> (0.01, 1) + this.controlRodInsertion = Math.max(0.001, controlRodInsertion); + fuelRods = new ArrayList<>(); + controlRods = new ArrayList<>(); + coolantChannels = new ArrayList<>(); + effectiveControlRods = new ArrayList<>(); + effectiveCoolantChannels = new ArrayList<>(); + // 2pi * r^2 + 2pi * r * l + surfaceArea = (reactorRadius * reactorRadius) * Math.PI * 2 + reactorDepth * reactorRadius * Math.PI * 2; + structuralMass = reactorDepth * reactorRadius * reactorRadius * Math.PI * + 300; // Assuming 300 kg/m^3 when it's basically empty, does not have to be precise + } + + public void prepareThermalProperties() { + int idRod = 0, idControl = 0, idChannel = 0; + + for (int i = 0; i < reactorLayout.length; i++) { + for (int j = 0; j < reactorLayout[i].length; j++) { + /* + * Check for null because the layout + * is in general not a square + */ + ReactorComponent comp = reactorLayout[i][j]; + if (comp != null && comp.isValid()) { + comp.setPos(i, j); + maxTemperature = Double.min(maxTemperature, comp.getMaxTemperature()); + structuralMass += comp.getMass(); + if (comp instanceof FuelRod fuelRod) { + comp.setIndex(idRod); + fuelRods.add(fuelRod); + idRod++; + } + + if (comp instanceof ControlRod controlRod) { + comp.setIndex(idControl); + controlRods.add(controlRod); + idControl++; + } + + if (comp instanceof CoolantChannel coolantChannel) { + comp.setIndex(idChannel); + coolantChannels.add(coolantChannel); + idChannel++; + } + } + } + } + } + + public void computeGeometry() { + effectiveControlRods.clear(); + effectiveCoolantChannels.clear(); + moderatorTipped = false; + double[][] geometricMatrixSlowNeutrons = new double[fuelRods.size()][fuelRods.size()]; + double[][] geometricMatrixFastNeutrons = new double[fuelRods.size()][fuelRods.size()]; + + /* + * We calculate geometric factor matrices to determine how many neutrons go from the i-th to the j-th fuel rod + * This factor is different for slow and fast neutrons because they interact differently with the materials and + * fuel + */ + for (int i = 0; i < fuelRods.size(); i++) { + for (int j = 0; j < i; j++) { + boolean pathIsClear = true; + double mij = 0; + FuelRod rodOne = fuelRods.get(i); + FuelRod rodTwo = fuelRods.get(j); + + /* + * Geometric factor calculation is done by (rough) numerical integration along a straight path between + * the two cells + */ + int prevX = fuelRods.get(i).getX(); + int prevY = fuelRods.get(i).getY(); + double resolution = FissionValues.fissionReactorResolution; + for (int t = 0; t < resolution; t++) { + int x = (int) Math.round((rodTwo.getX() - rodOne.getX()) * + ((float) t / resolution) + fuelRods.get(i).getX()); + int y = (int) Math.round((rodTwo.getY() - rodOne.getY()) * + ((float) t / resolution) + fuelRods.get(i).getY()); + if (x < 0 || x > reactorLayout.length - 1 || y < 0 || y > reactorLayout.length - 1) { + continue; + } + ReactorComponent component = reactorLayout[x][y]; + + if (component == null) { + continue; + } + + mij += component.getModerationFactor(); + + if (x == prevX && y == prevY) { + continue; + } + prevX = x; + prevY = y; + + /* + * For simplicity, we pretend that fuel rods are completely opaque to neutrons, paths that hit fuel + * rods are ignored as obstructed + */ + if (component instanceof FuelRod && !component.samePositionAs(fuelRods.get(i)) && + !component.samePositionAs(fuelRods.get(j))) { + pathIsClear = false; + break; + } + + /* + * We keep track of which active elements we hit, so we can determine how important they are + * relative to the others later + */ + if (component instanceof ControlRod rod) { + rod.addFuelRodPair(); + } else if (component instanceof CoolantChannel channel) { + channel.addFuelRodPair(); + } + } + + /* + * The actual calculation of the geometric factors, fast neutrons are randomly converted into slow + * neutrons along the path, we pretend that fuel rods are infinitely tall and thin for simplicity + * This means the fraction of slow neutrons will go as (1-exp(-m * x))/x where x is the distance between + * the cells + * The fraction of fast neutrons is simply one minus the fraction of slow neutrons + */ + if (pathIsClear) { + mij /= resolution; + geometricMatrixSlowNeutrons[i][j] = (1.0 - + Math.exp(-mij * rodOne.getDistance(rodTwo))) / + rodOne.getDistance(rodTwo); + geometricMatrixSlowNeutrons[j][i] = geometricMatrixSlowNeutrons[i][j]; + geometricMatrixFastNeutrons[i][j] = 1.0 / + rodOne.getDistance(rodTwo) - geometricMatrixSlowNeutrons[i][j]; + geometricMatrixFastNeutrons[j][i] = geometricMatrixFastNeutrons[i][j]; + } + } + } + + /* + * We now use the data we have on the geometry to calculate the reactor's stats + */ + double avgGeometricFactorSlowNeutrons = 0; + double avgGeometricFactorFastNeutrons = 0; + + double avgHighEnergyFissionFactor = 0; + double avgLowEnergyFissionFactor = 0; + double avgHighEnergyCaptureFactor = 0; + double avgLowEnergyCaptureFactor = 0; + + double avgFuelRodDistance = 0; + + for (int iIdx = 0; iIdx < fuelRods.size(); iIdx++) { + FuelRod i = fuelRods.get(iIdx); + for (int jIdx = 0; jIdx < iIdx; jIdx++) { + FuelRod j = fuelRods.get(jIdx); + avgGeometricFactorSlowNeutrons += geometricMatrixSlowNeutrons[i.getIndex()][j.getIndex()]; + avgGeometricFactorFastNeutrons += geometricMatrixFastNeutrons[i.getIndex()][j.getIndex()]; + + avgFuelRodDistance += i.getDistance(j); + } + avgHighEnergyFissionFactor += i.getHEFissionFactor(); + avgLowEnergyFissionFactor += i.getLEFissionFactor(); + avgHighEnergyCaptureFactor += i.getHECaptureFactor(); + avgLowEnergyCaptureFactor += i.getLECaptureFactor(); + } + + if (fuelRods.size() > 1) { + avgGeometricFactorSlowNeutrons *= 0.25 / fuelRods.size(); + avgGeometricFactorFastNeutrons *= 0.25 / fuelRods.size(); + + avgHighEnergyFissionFactor /= fuelRods.size(); + avgLowEnergyFissionFactor /= fuelRods.size(); + avgHighEnergyCaptureFactor /= fuelRods.size(); + avgLowEnergyCaptureFactor /= fuelRods.size(); + + avgFuelRodDistance /= (fuelRods.size() * fuelRods.size() - fuelRods.size()); + avgFuelRodDistance *= 2; + + double kSlow = avgLowEnergyFissionFactor / avgLowEnergyCaptureFactor * avgGeometricFactorSlowNeutrons; + double kFast = avgHighEnergyFissionFactor / avgHighEnergyCaptureFactor * avgGeometricFactorFastNeutrons; + k = (kSlow + kFast) * reactorDepth / (1. + reactorDepth); + + double depthDiameterDifference = 0.5 * (reactorDepth - reactorRadius * 2) / reactorRadius; + double sigmoid = 1 / (1 + Math.exp(-depthDiameterDifference)); + double fuelRodFactor = sigmoid * Math.pow(avgFuelRodDistance, -2) + + (1 - sigmoid) * Math.pow(avgFuelRodDistance, -1); + + maxPower = fuelRods.size() * (avgHighEnergyFissionFactor + avgLowEnergyFissionFactor) * fuelRodFactor * + FissionValues.nuclearPowerMultiplier; + } else { + // The calculations break down for the geometry, so we just do this instead. + k = 0.00001; + maxPower = 0.1 * FissionValues.nuclearPowerMultiplier; + } + /* + * We give each control rod and coolant channel a weight depending on how many fuel rods they affect + */ + this.computeControlRodWeights(); + this.computeCoolantChannelWeights(); + + controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods, this.controlRodInsertion); + + this.prepareInitialConditions(); + } + + /** + * Loops over all the control rods, determines which ones actually affect reactivity, and gives them a weight + * depending on how many fuel rods they affect + */ + protected void computeControlRodWeights() { + for (ControlRod rod : controlRods) { + rod.computeWeightFromFuelRodMap(); + if (rod.getWeight() > 0) { + effectiveControlRods.add(rod); + } + } + ControlRod.normalizeWeights(effectiveControlRods, fuelRods.size()); + } + + /** + * Loops over all the coolant channels, determines which ones actually affect reactivity, and gives them a weight + * depending on how many fuel rods they affect + */ + protected void computeCoolantChannelWeights() { + for (CoolantChannel channel : coolantChannels) { + channel.computeWeightFromFuelRodMap(); + if (channel.getWeight() > 0) { + effectiveCoolantChannels.add(channel); + } + } + CoolantChannel.normalizeWeights(effectiveCoolantChannels); + } + + public boolean isDepleted() { + return fuelDepletion >= maxFuelDepletion || fuelDepletion < 0; + } + + public void resetFuelDepletion() { + this.fuelDepletion = 0; + } + + public void prepareInitialConditions() { + coolantBaseTemperature = 0; + coolantBoilingPointStandardPressure = 0; + coolantExitTemperature = 0; + coolantHeatOfVaporization = 0; + maxFuelDepletion = 0; + weightedGenerationTime = 0; + + for (FuelRod rod : fuelRods) { + maxFuelDepletion += rod.getDuration(); + weightedGenerationTime += rod.getNeutronGenerationTime(); + } + if (fuelDepletion < 0) { + fuelDepletion = maxFuelDepletion; + } + weightedGenerationTime /= fuelRods.size(); + + for (CoolantChannel channel : coolantChannels) { + ICoolantStats prop = channel.getCoolant(); + Fluid fluid = CoolantRegistry.originalFluid(prop); + + if (fluid != null) { + coolantBaseTemperature += fluid.getTemperature(); + } + coolantBoilingPointStandardPressure += prop.getBoilingPoint(); + coolantExitTemperature += prop.getHotCoolant().getTemperature(); + coolantHeatOfVaporization += prop.getHeatOfVaporization(); + } + + if (!coolantChannels.isEmpty()) { + coolantBaseTemperature /= coolantChannels.size(); + coolantBoilingPointStandardPressure /= coolantChannels.size(); + coolantExitTemperature /= coolantChannels.size(); + coolantHeatOfVaporization /= coolantChannels.size(); + + if (coolantBaseTemperature == 0) { + coolantBaseTemperature = envTemperature; + } + if (coolantBoilingPointStandardPressure == 0) { + coolantBoilingPointStandardPressure = airBoilingPoint; + } + } + isOn = true; + } + + /** + * Consumes the coolant. Calculates the heat removed by the coolant based on an amalgamation of different equations. + * It is not particularly realistic, but allows for some fine-tuning to happen. Heat removed is proportional to the + * surface area of the coolant channel (which is equivalent to the reactor's depth), as well as the flow rate of + * coolant and the difference in temperature between the reactor and the coolant + */ + public double makeCoolantFlow(int flowRate) { + double heatRemoved = 0; + coolantMass = 0; + for (CoolantChannel channel : coolantChannels) { + FluidStack tryFluidDrain = channel.getInputHandler().getFluidTank().drain(flowRate, false); + if (tryFluidDrain != null) { + int drained = tryFluidDrain.amount; + + ICoolantStats prop = channel.getCoolant(); + int coolantTemp = CoolantRegistry.originalFluid(prop).getTemperature(); + + double cooledTemperature = prop.getHotCoolant().getTemperature(); + if (cooledTemperature > this.temperature) { + continue; + } + + double heatRemovedPerLiter = prop.getSpecificHeatCapacity() / + FissionValues.fissionCoolantDivisor * + (cooledTemperature - coolantTemp); + // Explained by: + // https://physics.stackexchange.com/questions/153434/heat-transfer-between-the-bulk-of-the-fluid-inside-the-pipe-and-the-pipe-externa + double heatFluxPerAreaAndTemp = 1 / + (1 / prop.getCoolingFactor() + coolantWallThickness / thermalConductivity); + double idealHeatFlux = heatFluxPerAreaAndTemp * 4 * reactorDepth * + (temperature - cooledTemperature); + + // Don't cut off cooling when it turns off + if (realMaxPower() != this.getDecayHeat() && realMaxPower() != 0) { + idealHeatFlux = Math.min(idealHeatFlux, realMaxPower() * 1e6 / coolantChannels.size()); + } + + double idealFluidUsed = idealHeatFlux / heatRemovedPerLiter; + double cappedFluidUsed = Math.min(drained, idealFluidUsed); + + int remainingSpace = channel.getOutputHandler().getFluidTank().getCapacity() - + channel.getOutputHandler().getFluidTank().getFluidAmount(); + int actualFlowRate = Math.min(remainingSpace, + (int) (cappedFluidUsed + channel.partialCoolant)); + // Should occasionally decrease when coolant is actually consumed. + channel.partialCoolant += cappedFluidUsed - actualFlowRate; + + FluidStack HPCoolant = new FluidStack( + prop.getHotCoolant(), actualFlowRate); + + channel.getInputHandler().getFluidTank().drain(actualFlowRate, true); + channel.getOutputHandler().getFluidTank().fill(HPCoolant, true); + if (prop.accumulatesHydrogen() && + this.temperature > zircaloyHydrogenReactionTemperature) { + double boilingPoint = coolantBoilingPoint(prop); + if (this.temperature > boilingPoint) { + this.accumulatedHydrogen += (this.temperature - boilingPoint) / boilingPoint; + } else if (actualFlowRate < Math.min(remainingSpace, idealFluidUsed)) { + this.accumulatedHydrogen += (this.temperature - zircaloyHydrogenReactionTemperature) / + zircaloyHydrogenReactionTemperature; + } + } + + this.coolantMass += cappedFluidUsed * prop.getMass(); + heatRemoved += cappedFluidUsed * heatRemovedPerLiter; + } + } + this.coolantMass /= 1000; + this.accumulatedHydrogen *= 0.98; + return heatRemoved; + } + + /** + * The thermodynamics is not completely realistic, but it's close enough for simple things like this, the boiling + * point depends on pressure + */ + protected double coolantBoilingPoint() { + return 1. / (1. / this.coolantBoilingPointStandardPressure - + R * Math.log(this.pressure / standardPressure) / this.coolantHeatOfVaporization); + } + + protected double coolantBoilingPoint(ICoolantStats coolant) { + if (coolant.getBoilingPoint() == 0) { + return coolantBoilingPoint(); + } + return 1. / (1. / coolant.getBoilingPoint() - + R * Math.log(this.pressure / standardPressure) / + coolant.getHeatOfVaporization()); + } + + public void updateTemperature(int flowRate) { + this.prevTemperature = this.temperature; + // simulate heat based only on the reactor power + this.temperature = responseFunctionTemperature(envTemperature, this.temperature, this.power * 1e6, 0); + // prevent temperature from going above meltdown temp, to stop coolant from absorbing more heat than it should + this.temperature = Math.min(maxTemperature, temperature); + double heatRemoved = this.makeCoolantFlow(flowRate); + // calculate the actual temperature based on the reactor power and the heat removed + this.temperature = responseFunctionTemperature(envTemperature, prevTemperature, this.power * 1e6, heatRemoved); + this.temperature = Math.max(this.temperature, this.coolantBaseTemperature); + } + + public void updatePressure() { + this.pressure = responseFunction( + !(this.temperature <= this.coolantBoilingPoint()) && this.isOn ? 1000. * R * this.temperature : + this.exteriorPressure, + this.pressure, 0.2); + } + + public void updateNeutronPoisoning() { + this.neutronPoisonAmount += this.decayProductsAmount * (1 - decayProductRate) * poisonFraction; + this.neutronPoisonAmount *= decayProductRate * Math.exp(-crossSectionRatio * power / surfaceArea); + } + + public double getDecayHeat() { + return this.neutronPoisonAmount * 0.05 + this.decayProductsAmount * 0.1 + 0.0001; // The extra constant is to + // kickstart the reactor. + } + + public void updatePower() { + if (this.isOn) { + this.kEff = this.k; + // Since the power defect is a change in the reactivity rho (1 - 1 / kEff), we have to do this thing. + // (1 - 1 / k) = rho(k) => rho^-1(rho) = 1 / (1 - rho) + // rho^-1(rho(k) - defect) is thus 1 / (1 - (1 - 1/k - defect)) = 1 / (1/k + defect) + this.kEff = 1 / ((1 / this.kEff) + powerDefectCoefficient * (this.power / this.maxPower) + + neutronPoisonAmount * crossSectionRatio / surfaceArea + controlRodFactor); + this.kEff = Math.max(0, this.kEff); + + double inverseReactorPeriod = (this.kEff - 1) / weightedGenerationTime; + + this.power += 0.001; // Let it kickstart itself + this.power *= Math.exp(inverseReactorPeriod); + + this.fuelDepletion += this.power; + + this.decayProductsAmount += Math.max(power, 0.) / 1000; + } else { + this.power *= 0.5; + } + this.decayProductsAmount *= decayProductRate; + } + + public double realMaxPower() { + if (this.moderatorTipped && (this.controlRodInsertion <= 9. / 16 && this.controlRodInsertion >= 7. / 16)) { + return this.maxPower * 1.1; + } else if (!this.isOn) { + return this.getDecayHeat(); + } else { + return this.maxPower; + } + } + + public boolean checkForMeltdown() { + return this.temperature > this.maxTemperature; + } + + public boolean checkForExplosion() { + return this.pressure > this.maxPressure; + } + + public void addComponent(ReactorComponent component, int x, int y) { + reactorLayout[x][y] = component; + } + + public NBTTagCompound serializeNBT() { + NBTTagCompound tagCompound = new NBTTagCompound(); + tagCompound.setDouble("Temperature", this.temperature); + tagCompound.setDouble("PrevTemperature", this.prevTemperature); + tagCompound.setDouble("Pressure", this.pressure); + tagCompound.setDouble("Power", this.power); + tagCompound.setDouble("FuelDepletion", this.fuelDepletion); + tagCompound.setDouble("AccumulatedHydrogen", this.accumulatedHydrogen); + tagCompound.setDouble("NeutronPoisonAmount", this.neutronPoisonAmount); + tagCompound.setDouble("DecayProductsAmount", this.decayProductsAmount); + tagCompound.setBoolean("NeedsOutput", this.needsOutput); + tagCompound.setDouble("ControlRodInsertion", this.controlRodInsertion); + tagCompound.setBoolean("IsOn", this.isOn); + tagCompound.setBoolean("ControlRodRegulationOn", this.controlRodRegulationOn); + + return tagCompound; + } + + public void deserializeNBT(NBTTagCompound tagCompound) { + this.temperature = tagCompound.getDouble("Temperature"); + this.prevTemperature = tagCompound.getDouble("PrevTemperature"); + this.pressure = tagCompound.getDouble("Pressure"); + this.power = tagCompound.getDouble("Power"); + this.fuelDepletion = tagCompound.getDouble("FuelDepletion"); + this.accumulatedHydrogen = tagCompound.getDouble("AccumulatedHydrogen"); + this.neutronPoisonAmount = tagCompound.getDouble("NeutronPoisonAmount"); + this.decayProductsAmount = tagCompound.getDouble("DecayProductsAmount"); + this.needsOutput = tagCompound.getBoolean("NeedsOutput"); + this.controlRodInsertion = tagCompound.getDouble("ControlRodInsertion"); + this.isOn = tagCompound.getBoolean("IsOn"); + this.controlRodRegulationOn = tagCompound.getBoolean("ControlRodRegulationOn"); + } + + public void updateControlRodInsertion(double controlRodInsertion) { + this.controlRodInsertion = Math.max(0.001, controlRodInsertion); + this.controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods, this.controlRodInsertion); + } + + public void regulateControlRods() { + if (!this.isOn || !this.controlRodRegulationOn) + return; + + boolean adjustFactor = false; + if (pressure > maxPressure * 0.8 || temperature > (coolantExitTemperature + maxTemperature) / 2 || + temperature > maxTemperature - 150 || temperature - prevTemperature > 30) { + if (kEff > 1) { + this.controlRodInsertion += 0.004; + adjustFactor = true; + } + } else if (temperature > coolantExitTemperature * 0.3 + coolantBaseTemperature * 0.7) { + if (kEff > 1.01) { + this.controlRodInsertion += 0.008; + adjustFactor = true; + } else if (kEff < 1.005) { + this.controlRodInsertion -= 0.001; + adjustFactor = true; + } + } else if (temperature > coolantExitTemperature * 0.1 + coolantBaseTemperature * 0.9) { + if (kEff > 1.025) { + this.controlRodInsertion += 0.012; + adjustFactor = true; + } else if (kEff < 1.015) { + this.controlRodInsertion -= 0.004; + adjustFactor = true; + } + } else { + if (kEff > 1.1) { + this.controlRodInsertion += 0.02; + adjustFactor = true; + } else if (kEff < 1.05) { + this.controlRodInsertion -= 0.006; + adjustFactor = true; + } + } + + if (adjustFactor) { + this.controlRodInsertion = Math.max(0, Math.min(1, this.controlRodInsertion)); + this.controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods, this.controlRodInsertion); + } + } + + public void turnOff() { + this.isOn = false; + this.maxPower = 0; + this.k = 0; + this.kEff = 0; + this.coolantMass = 0; + this.fuelMass = 0; + for (ReactorComponent[] components : reactorLayout) { + Arrays.fill(components, null); + } + fuelRods.clear(); + controlRods.clear(); + coolantChannels.clear(); + effectiveControlRods.clear(); + effectiveCoolantChannels.clear(); + } +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/FissionValues.java b/src/main/java/supersymmetry/api/nuclear/fission/FissionValues.java new file mode 100644 index 000000000..8d9b7a87d --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/FissionValues.java @@ -0,0 +1,16 @@ +package supersymmetry.api.nuclear.fission; + +public class FissionValues { + + // Fission Hatches + public static final int FISSION_LOCK_UPDATE = 212228; + + // Fission Reactor + public static final int SYNC_REACTOR_STATS = 212229; + public static final int SYNC_LOCKING_STATE = 212230; + + public static final double nuclearPowerMultiplier = 0.1; + public static final double fissionCoolantDivisor = 14; + public static final double fissionReactorResolution = 100; + public static final double heatExchangerEfficiencyMultiplier = 0.25; +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/ICoolantStats.java b/src/main/java/supersymmetry/api/nuclear/fission/ICoolantStats.java new file mode 100644 index 000000000..b60a9761d --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/ICoolantStats.java @@ -0,0 +1,48 @@ +package supersymmetry.api.nuclear.fission; + +import net.minecraftforge.fluids.Fluid; + +public interface ICoolantStats { + + /** + * @return The heated coolant fluid. + */ + Fluid getHotCoolant(); + + /** + * @return The specific heat capacity of the fluid in J/(kg*K). + */ + double getSpecificHeatCapacity(); + + /** + * @return A factor relating to the neutron moderation properties; the higher the factor, the fewer neutrons pass + * through. + */ + double getModeratorFactor(); + + /** + * @return A rough heat transfer coefficient for the fluid. + */ + double getCoolingFactor(); + + /** + * @return The boiling point of the fluid in Kelvin. + */ + double getBoilingPoint(); + + /** + * @return The heat of vaporization of the fluid in J/(kg*K). + */ + double getHeatOfVaporization(); + + /** + * @return If the coolant reacts with zirconium cladding at high temperatures. This is true for mostly water-based + * coolants. + */ + boolean accumulatesHydrogen(); + + /** + * @return The mass of the coolant per liter in kg + */ + double getMass(); +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/IFissionFuelStats.java b/src/main/java/supersymmetry/api/nuclear/fission/IFissionFuelStats.java new file mode 100644 index 000000000..82a6844c7 --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/IFissionFuelStats.java @@ -0,0 +1,62 @@ +package supersymmetry.api.nuclear.fission; + +public interface IFissionFuelStats { + + /** + * @return The maximum temperature the fuel can handle before the reactor melts down. + */ + int getMaxTemperature(); + + /** + * @return How long the fuel lasts in the reactor, in terms of the megajoules it makes. + */ + int getDuration(); + + /** + * @return The cross section of slow neutrons that can be captured by this fuel to breed it. + */ + double getSlowNeutronCaptureCrossSection(); + + /** + * @return The cross section of fast neutrons that can be captured by this fuel to breed it. + */ + double getFastNeutronCaptureCrossSection(); + + /** + * @return The cross section of slow neutrons that can cause fission in this fuel. + */ + double getSlowNeutronFissionCrossSection(); + + /** + * @return The cross section of fast neutrons that can cause fission in this fuel. + */ + double getFastNeutronFissionCrossSection(); + + /** + * @return The average time for a neutron to be emitted during a fission event. Do not make this accurate. + */ + double getNeutronGenerationTime(); + + /** + * Helper method for the tooltip + * + * @return An integer corresponding to the stability of the fuel. 0 corresponds to stable, 1 to somewhat stable, 2 + * to dangerous, 3 to very dangerous + */ + default int getNeutronGenerationTimeCategory() { + if (this.getNeutronGenerationTime() > 2) { + return 0; + } else if (this.getNeutronGenerationTime() > 1.25) { + return 1; + } else if (this.getNeutronGenerationTime() > 0.9) { + return 2; + } else { + return 3; + } + } + + /** + * @return A unique ID for this fuel. + */ + String getID(); +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/components/ControlRod.java b/src/main/java/supersymmetry/api/nuclear/fission/components/ControlRod.java new file mode 100644 index 000000000..18c6af172 --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/components/ControlRod.java @@ -0,0 +1,88 @@ +package supersymmetry.api.nuclear.fission.components; + +import java.util.List; + +public class ControlRod extends ReactorComponent { + + private double weight; + private final boolean tipModeration; + private int relatedFuelRodPairs; + + public ControlRod(double maxTemperature, boolean tipModeration, double thermalConductivity, double mass) { + super(0, maxTemperature, thermalConductivity, mass, true); + this.tipModeration = tipModeration; + this.weight = 0; + } + + /** + * Normalizes the weights of a list of control rods based on the true number of fuel rod pairs. + * + * @param effectiveControlRods The control rods to normalize. + * @param fuelRodNum The number of fuel rods in the reactor. + */ + public static void normalizeWeights(List effectiveControlRods, int fuelRodNum) { + for (ControlRod control_rod : effectiveControlRods) { + if (fuelRodNum != 1) + control_rod.weight /= (fuelRodNum * fuelRodNum) - fuelRodNum; + } + } + + /** + * Determines the effect of a list of control rods based on how far they are inserted into a reactor. + * + * @param effectiveControlRods The list of control rods to be analyzed. + * @param insertion How far the control rods are inserted into the reactor, from 0 to 1. + * @return A number representing the reactivity change of the reactor from the control rods. + */ + public static double controlRodFactor(List effectiveControlRods, double insertion) { + double crf = 0; + for (ControlRod control_rod : effectiveControlRods) { + if (control_rod.hasModeratorTip()) { + if (insertion <= 0.3) { + crf -= insertion / 3 * control_rod.weight; + } else { + crf -= (-11F / 7 * (insertion - 0.3) + 0.1) * control_rod.weight; + } + } else { + crf += insertion * control_rod.weight; + } + } + return crf; + } + + /** + * @return How much the control rod affects reactivity. + */ + public double getWeight() { + return weight; + } + + /** + * @param weight How much the control rod should affect reactivity. + */ + public void setWeight(double weight) { + this.weight = weight; + } + + /** + * Notify the control rod of a pair of fuel rods that it is in the way of, to help increase its weight later. + */ + public void addFuelRodPair() { + relatedFuelRodPairs++; + } + + /** + * @return Whether the control rod increases reactivity at low insertion levels (due to having a moderating tip). + */ + public boolean hasModeratorTip() { + return tipModeration; + } + + /** + * Automatically calculates the control rod weight (its effect on reactivity) based on the number of fuel rod pairs + * that it is in the way of. + */ + public void computeWeightFromFuelRodMap() { + this.weight = relatedFuelRodPairs * 4; // 4 being a constant to help balance this out + } +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/components/CoolantChannel.java b/src/main/java/supersymmetry/api/nuclear/fission/components/CoolantChannel.java new file mode 100644 index 000000000..ba86fd9ba --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/components/CoolantChannel.java @@ -0,0 +1,67 @@ +package supersymmetry.api.nuclear.fission.components; + +import supersymmetry.api.capability.ICoolantHandler; +import supersymmetry.api.nuclear.fission.ICoolantStats; + +import java.util.List; + +public class CoolantChannel extends ReactorComponent { + + private final ICoolantStats coolant; + private double weight; + private int relatedFuelRodPairs; + + private ICoolantHandler inputHandler; + private ICoolantHandler outputHandler; + + // Allows fission reactors to heat up less than a full liter of coolant. + public double partialCoolant; + + public CoolantChannel(double maxTemperature, double thermalConductivity, ICoolantStats coolant, double mass, + ICoolantHandler inputHandler, ICoolantHandler outputHandler) { + super(coolant.getModeratorFactor(), maxTemperature, thermalConductivity, mass, + true); + this.coolant = coolant; + this.weight = 0; + this.inputHandler = inputHandler; + this.outputHandler = outputHandler; + } + + public static void normalizeWeights(List effectiveCoolantChannels) { + double sum = 0; + for (CoolantChannel channel : effectiveCoolantChannels) { + sum += channel.weight; + } + for (CoolantChannel channel : effectiveCoolantChannels) { + channel.weight /= sum; + } + } + + public void addFuelRodPair() { + relatedFuelRodPairs++; + } + + public double getWeight() { + return weight; + } + + public void setWeight(double weight) { + this.weight = weight; + } + + public ICoolantStats getCoolant() { + return coolant; + } + + public void computeWeightFromFuelRodMap() { + this.weight = relatedFuelRodPairs * 2; + } + + public ICoolantHandler getInputHandler() { + return inputHandler; + } + + public ICoolantHandler getOutputHandler() { + return outputHandler; + } +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/components/FuelRod.java b/src/main/java/supersymmetry/api/nuclear/fission/components/FuelRod.java new file mode 100644 index 000000000..9442e9f86 --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/components/FuelRod.java @@ -0,0 +1,47 @@ +package supersymmetry.api.nuclear.fission.components; + + +import supersymmetry.api.nuclear.fission.IFissionFuelStats; + +public class FuelRod extends ReactorComponent { + + private IFissionFuelStats fuel; + + public FuelRod(double maxTemperature, double thermalConductivity, IFissionFuelStats fuel, double mass) { + super(0, maxTemperature, thermalConductivity, mass, true); + this.fuel = fuel; + } + + public double getDuration() { + return fuel.getDuration(); + } + + public double getHEFissionFactor() { + return fuel.getFastNeutronFissionCrossSection(); + } + + public double getLEFissionFactor() { + return fuel.getSlowNeutronFissionCrossSection(); + } + + public double getHECaptureFactor() { + return fuel.getFastNeutronCaptureCrossSection(); + } + + public double getLECaptureFactor() { + return fuel.getSlowNeutronCaptureCrossSection(); + } + + public double getNeutronGenerationTime() { + return fuel.getNeutronGenerationTime(); + } + + public IFissionFuelStats getFuel() { + return fuel; + } + + public void setFuel(IFissionFuelStats property) { + this.fuel = property; + this.maxTemperature = property.getMaxTemperature(); + } +} diff --git a/src/main/java/supersymmetry/api/nuclear/fission/components/ReactorComponent.java b/src/main/java/supersymmetry/api/nuclear/fission/components/ReactorComponent.java new file mode 100644 index 000000000..4add00fd4 --- /dev/null +++ b/src/main/java/supersymmetry/api/nuclear/fission/components/ReactorComponent.java @@ -0,0 +1,78 @@ +package supersymmetry.api.nuclear.fission.components; + +public class ReactorComponent { + + private final double moderationFactor; + protected double maxTemperature; + private final double thermalConductivity; + private final double mass; + + private int x; + private int y; + + private final boolean isValid; + + private int index = -1; + + public ReactorComponent(double moderationFactor, double maxTemperature, double thermalConductivity, double mass, + boolean isValid) { + this.moderationFactor = moderationFactor; + this.maxTemperature = maxTemperature; + this.thermalConductivity = thermalConductivity; + this.mass = mass; + this.isValid = isValid; + } + + public void setPos(int x, int y) { + this.x = x; + this.y = y; + } + + public void setIndex(int index) { + this.index = index; + } + + public double getModerationFactor() { + return moderationFactor; + } + + public double getMaxTemperature() { + return maxTemperature; + } + + public double getThermalConductivity() { + return thermalConductivity; + } + + public boolean isValid() { + return isValid; + } + + /** + * @return The index of the reactor component, which is -1 if unset + */ + public int getIndex() { + return index; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public boolean samePositionAs(ReactorComponent component) { + return this.getX() == component.getX() && this.getY() == component.getY(); + } + + public double getDistance(ReactorComponent component) { + return Math.sqrt(Math.pow(this.getX() - component.getX(), 2) + + Math.pow(this.getY() - component.getY(), 2)); + } + + public double getMass() { + return mass; + } +} diff --git a/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java b/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java index 1a71a9d45..9d1db8675 100644 --- a/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java +++ b/src/main/java/supersymmetry/api/recipes/SuSyRecipeMaps.java @@ -331,6 +331,12 @@ public class SuSyRecipeMaps { .setSlotOverlay(true, false, GuiTextures.FURNACE_OVERLAY_2) .setSound(GTSoundEvents.FURNACE); + public static final RecipeMap SPENT_FUEL_POOL_RECIPES = new RecipeMap<>("spent_fuel_pool", 1, 1, 1, 1, new SimpleRecipeBuilder(), false) + .setProgressBar(GuiTextures.PROGRESS_BAR_BATH, ProgressWidget.MoveType.HORIZONTAL); + + public static final RecipeMap GAS_CENTRIFUGE_RECIPES = new RecipeMap<>("gas_centrifuge", 0, 0, 1, 2, new SimpleRecipeBuilder(), false) + .setProgressBar(GuiTextures.PROGRESS_BAR_MIXER, ProgressWidget.MoveType.CIRCULAR) + .setSound(GTSoundEvents.CENTRIFUGE); public static final RecipeMap JET_WINGPACK_FUELS = new RecipeMap<>("jet_wingpack_fuels", 0, 0, 1, 0, new NoEnergyRecipeBuilder(), false) .setSlotOverlay(false, false, GuiTextures.DARK_CANISTER_OVERLAY) diff --git a/src/main/java/supersymmetry/api/unification/material/info/SuSyMaterialIconType.java b/src/main/java/supersymmetry/api/unification/material/info/SuSyMaterialIconType.java index b75200093..41e4783eb 100644 --- a/src/main/java/supersymmetry/api/unification/material/info/SuSyMaterialIconType.java +++ b/src/main/java/supersymmetry/api/unification/material/info/SuSyMaterialIconType.java @@ -15,4 +15,15 @@ public class SuSyMaterialIconType { public static MaterialIconType slurry = new MaterialIconType("slurry"); public static MaterialIconType supercritical = new MaterialIconType("supercritical"); public static MaterialIconType dustWet = new MaterialIconType("dustWet"); + + // Nuclear MaterialIcontypes + public static final MaterialIconType fuelRod = new MaterialIconType("fuelRod"); + public static final MaterialIconType fuelRodDepleted = new MaterialIconType("fuelRodDepleted"); + public static final MaterialIconType fuelRodHotDepleted = new MaterialIconType("fuelRodHotDepleted"); + public static final MaterialIconType fuelPellet = new MaterialIconType("fuelPellet"); + public static final MaterialIconType fuelPelletDepleted = new MaterialIconType("fuelPelletDepleted"); + + public static final MaterialIconType dustSpentFuel = new MaterialIconType("dustSpentFuel"); + public static final MaterialIconType dustBredFuel = new MaterialIconType("dustBredFuel"); + public static final MaterialIconType dustFissionByproduct = new MaterialIconType("dustFissionByproduct"); } diff --git a/src/main/java/supersymmetry/api/unification/material/properties/CoolantProperty.java b/src/main/java/supersymmetry/api/unification/material/properties/CoolantProperty.java new file mode 100644 index 000000000..16c0ac5a3 --- /dev/null +++ b/src/main/java/supersymmetry/api/unification/material/properties/CoolantProperty.java @@ -0,0 +1,120 @@ +package supersymmetry.api.unification.material.properties; + +import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.unification.material.Material; + +import gregtech.api.unification.material.properties.IMaterialProperty; +import gregtech.api.unification.material.properties.MaterialProperties; +import gregtech.api.unification.material.properties.PropertyKey; +import net.minecraftforge.fluids.Fluid; +import supersymmetry.api.nuclear.fission.ICoolantStats; + +public class CoolantProperty implements IMaterialProperty, ICoolantStats { + + private Material hotHPCoolant; + private double moderatorFactor; + /** + * Roughly the heat transfer coefficient Do not put too much thought into this + */ + private double coolingFactor; + // in kelvin at standard conditions + private double boilingPoint; + // neutron absorption rate + // in J/L + private double heatOfVaporization; + // in J/(kg*K) + private double specificHeatCapacity; + private boolean accumulatesHydrogen = false; + // To store the specific key + private FluidStorageKey key; + + private double mass; + + public CoolantProperty(Material mat, Material hotHPCoolant, FluidStorageKey key, double moderatorFactor, + double coolingFactor, + double boilingPoint, double heatOfVaporization, + double specificHeatCapacity) { + this.hotHPCoolant = hotHPCoolant; + this.moderatorFactor = moderatorFactor; + this.coolingFactor = coolingFactor; + this.boilingPoint = boilingPoint; + this.heatOfVaporization = heatOfVaporization; + this.specificHeatCapacity = specificHeatCapacity; + this.key = key; + this.mass = mat.getMass(); + } + + @Override + public void verifyProperty(MaterialProperties properties) { + properties.ensureSet(PropertyKey.FLUID, true); + } + + public void setHotHPCoolant(Material hotHPCoolant) { + this.hotHPCoolant = hotHPCoolant; + } + + public Material getHotHPCoolant() { + return this.hotHPCoolant; + } + + public void setModeratorFactor(double moderatorFactor) { + this.moderatorFactor = moderatorFactor; + } + + public double getModeratorFactor() { + return this.moderatorFactor; + } + + public void setCoolingFactor(double coolingFactor) { + this.coolingFactor = coolingFactor; + } + + public double getCoolingFactor() { + return this.coolingFactor; + } + + public void setBoilingPoint(double boilingPoint) { + this.boilingPoint = boilingPoint; + } + + public double getBoilingPoint() { + return this.boilingPoint; + } + + public double getHeatOfVaporization() { + return heatOfVaporization; + } + + public void setHeatOfVaporization(double heatOfVaporization) { + this.heatOfVaporization = heatOfVaporization; + } + + public double getSpecificHeatCapacity() { + return specificHeatCapacity; + } + + public void setSpecificHeatCapacity(double specificHeatCapacity) { + this.specificHeatCapacity = specificHeatCapacity; + } + + public boolean accumulatesHydrogen() { + return accumulatesHydrogen; + } + + public CoolantProperty setAccumulatesHydrogen(boolean accumulatesHydrogen) { + this.accumulatesHydrogen = accumulatesHydrogen; + return this; + } + + public Fluid getHotCoolant() { + return hotHPCoolant.getFluid(); + } + + public FluidStorageKey getCoolantKey() { + return key; + } + + public double getMass() { + return mass; + } +} diff --git a/src/main/java/supersymmetry/api/unification/material/properties/FissionFuelProperty.java b/src/main/java/supersymmetry/api/unification/material/properties/FissionFuelProperty.java new file mode 100644 index 000000000..0bdae6e1d --- /dev/null +++ b/src/main/java/supersymmetry/api/unification/material/properties/FissionFuelProperty.java @@ -0,0 +1,114 @@ +package supersymmetry.api.unification.material.properties; + + +import gregtech.api.unification.material.properties.IMaterialProperty; +import gregtech.api.unification.material.properties.MaterialProperties; +import gregtech.api.unification.material.properties.PropertyKey; +import supersymmetry.api.nuclear.fission.IFissionFuelStats; + +public class FissionFuelProperty implements IMaterialProperty, IFissionFuelStats { + + // The max temperature the fuel can handle before it liquefies. + private int maxTemperature; + // Scales how long the fuel rod lasts in the reactor. + private int duration; + // How likely it is to absorb a neutron that had touched a moderator. + private double slowNeutronCaptureCrossSection; + // How likely it is to absorb a neutron that has not yet touched a moderator. + private double fastNeutronCaptureCrossSection; + // How likely it is for a moderated neutron to cause fission in this fuel. + private double slowNeutronFissionCrossSection; + // How likely it is for a not-yet-moderated neutron to cause fission in this fuel. + private double fastNeutronFissionCrossSection; + // The average time for a neutron to be emitted during a fission event. Do not make this accurate. + private double neutronGenerationTime; + private String id; + + @Override + public void verifyProperty(MaterialProperties properties) { + properties.ensureSet(PropertyKey.DUST, true); + } + + public FissionFuelProperty(int maxTemperature, int duration, double slowNeutronCaptureCrossSection, + double fastNeutronCaptureCrossSection, double slowNeutronFissionCrossSection, + double fastNeutronFissionCrossSection, double neutronGenerationTime, String id) { + this.maxTemperature = maxTemperature; + this.duration = duration; + this.slowNeutronCaptureCrossSection = slowNeutronCaptureCrossSection; + this.fastNeutronCaptureCrossSection = fastNeutronCaptureCrossSection; + this.slowNeutronFissionCrossSection = slowNeutronFissionCrossSection; + this.fastNeutronFissionCrossSection = fastNeutronFissionCrossSection; + this.neutronGenerationTime = neutronGenerationTime; + this.id = id; + } + + @Override + public int getMaxTemperature() { + return maxTemperature; + } + + public void setMaxTemperature(int maxTemperature) { + if (maxTemperature <= 0) throw new IllegalArgumentException("Max temperature must be greater than zero!"); + this.maxTemperature = maxTemperature; + } + + @Override + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + if (duration <= 0) throw new IllegalArgumentException("Fuel duration must be greater than zero!"); + this.duration = duration; + } + + @Override + public double getSlowNeutronCaptureCrossSection() { + return slowNeutronCaptureCrossSection; + } + + public void setSlowNeutronCaptureCrossSection(double slowNeutronCaptureCrossSection) { + this.slowNeutronCaptureCrossSection = slowNeutronCaptureCrossSection; + } + + @Override + public double getFastNeutronCaptureCrossSection() { + return fastNeutronCaptureCrossSection; + } + + public void setFastNeutronCaptureCrossSection(double fastNeutronCaptureCrossSection) { + this.fastNeutronCaptureCrossSection = fastNeutronCaptureCrossSection; + } + + @Override + public double getSlowNeutronFissionCrossSection() { + return slowNeutronFissionCrossSection; + } + + public void setSlowNeutronFissionCrossSection(double slowNeutronFissionCrossSection) { + this.slowNeutronFissionCrossSection = slowNeutronFissionCrossSection; + } + + @Override + public double getFastNeutronFissionCrossSection() { + return fastNeutronFissionCrossSection; + } + + public void setFastNeutronFissionCrossSection(double fastNeutronFissionCrossSection) { + this.fastNeutronFissionCrossSection = fastNeutronFissionCrossSection; + } + + @Override + public double getNeutronGenerationTime() { + return neutronGenerationTime; + } + + @Override + public String getID() { + return this.id; + } + + public void setNeutronGenerationTime(double neutronGenerationTime) { + this.neutronGenerationTime = neutronGenerationTime; + } +} diff --git a/src/main/java/supersymmetry/api/unification/material/properties/RadioactiveProperty.java b/src/main/java/supersymmetry/api/unification/material/properties/RadioactiveProperty.java new file mode 100644 index 000000000..9f476cee9 --- /dev/null +++ b/src/main/java/supersymmetry/api/unification/material/properties/RadioactiveProperty.java @@ -0,0 +1,13 @@ +package supersymmetry.api.unification.material.properties; + +import gregtech.api.unification.material.properties.IMaterialProperty; +import gregtech.api.unification.material.properties.MaterialProperties; +import gregtech.api.unification.material.properties.PropertyKey; + +public class RadioactiveProperty implements IMaterialProperty { + + @Override + public void verifyProperty(MaterialProperties properties) { + properties.ensureSet(PropertyKey.DUST, true); + } +} diff --git a/src/main/java/supersymmetry/api/unification/material/properties/SuSyMaterialProperties.java b/src/main/java/supersymmetry/api/unification/material/properties/SuSyMaterialProperties.java deleted file mode 100644 index 11cf38697..000000000 --- a/src/main/java/supersymmetry/api/unification/material/properties/SuSyMaterialProperties.java +++ /dev/null @@ -1,11 +0,0 @@ -package gregtech.api.unification.material.properties; - -import supersymmetry.api.unification.material.properties.SuSyPropertyKey; - -import java.util.*; - -public class SuSyMaterialProperties { - private static final Set> baseTypes = new HashSet<>(Arrays.asList( - SuSyPropertyKey.FIBER - )); -} diff --git a/src/main/java/supersymmetry/api/unification/material/properties/SuSyPropertyKey.java b/src/main/java/supersymmetry/api/unification/material/properties/SuSyPropertyKey.java index 88e68b53d..33808dddb 100644 --- a/src/main/java/supersymmetry/api/unification/material/properties/SuSyPropertyKey.java +++ b/src/main/java/supersymmetry/api/unification/material/properties/SuSyPropertyKey.java @@ -1,8 +1,9 @@ package supersymmetry.api.unification.material.properties; import gregtech.api.unification.material.properties.PropertyKey; -import gregtech.api.unification.material.properties.IMaterialProperty; -public class SuSyPropertyKey { +public class SuSyPropertyKey { public static final PropertyKey FIBER = new PropertyKey<>("fiber", FiberProperty.class); + public static final PropertyKey COOLANT = new PropertyKey<>("coolant", CoolantProperty.class); + public static final PropertyKey FISSION_FUEL = new PropertyKey<>("fission_fuel", FissionFuelProperty.class); } diff --git a/src/main/java/supersymmetry/api/unification/ore/SusyOrePrefix.java b/src/main/java/supersymmetry/api/unification/ore/SusyOrePrefix.java index ad56e26f1..e882bd39c 100644 --- a/src/main/java/supersymmetry/api/unification/ore/SusyOrePrefix.java +++ b/src/main/java/supersymmetry/api/unification/ore/SusyOrePrefix.java @@ -4,8 +4,12 @@ import gregtech.api.unification.material.info.MaterialFlags; import gregtech.api.unification.material.info.MaterialIconType; import gregtech.api.unification.ore.OrePrefix; +import net.minecraft.client.resources.I18n; import supersymmetry.api.unification.material.info.SuSyMaterialFlags; import supersymmetry.api.unification.material.info.SuSyMaterialIconType; +import supersymmetry.api.unification.material.properties.SuSyPropertyKey; + +import java.util.Collections; import static gregtech.api.unification.ore.OrePrefix.Flags.ENABLE_UNIFICATION; @@ -54,4 +58,28 @@ public class SusyOrePrefix { // Wet dust public static final OrePrefix dustWet = new OrePrefix("dustWet", -1, null, SuSyMaterialIconType.dustWet, OrePrefix.Flags.ENABLE_UNIFICATION, mat -> mat.hasFlag(SuSyMaterialFlags.GENERATE_WET_DUST)); + + // Nuclear stuff, introduced by Zalgo and Bruberu + public static final OrePrefix fuelRod = new OrePrefix("fuelRod", -1, null, SuSyMaterialIconType.fuelRod, 0, + material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL), + mat -> Collections.singletonList(I18n.format("metaitem.nuclear.tooltip.radioactive"))); + public static final OrePrefix fuelRodDepleted = new OrePrefix("fuelRodDepleted", -1, null, + SuSyMaterialIconType.fuelRodDepleted, 0, material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL), + mat -> Collections.singletonList(I18n.format("metaitem.nuclear.tooltip.radioactive"))); + public static final OrePrefix fuelRodHotDepleted = new OrePrefix("fuelRodHotDepleted", -1, null, + SuSyMaterialIconType.fuelRodHotDepleted, 0, material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL), + mat -> Collections.singletonList(I18n.format("metaitem.nuclear.tooltip.radioactive"))); + public static final OrePrefix fuelPellet = new OrePrefix("fuelPellet", -1, null, + SuSyMaterialIconType.fuelPellet, 0, material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL), + mat -> Collections.singletonList(I18n.format("metaitem.nuclear.tooltip.radioactive"))); + public static final OrePrefix fuelPelletDepleted = new OrePrefix("fuelPelletDepleted", -1, null, + SuSyMaterialIconType.fuelPelletDepleted, 0, material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL), + mat -> Collections.singletonList(I18n.format("metaitem.nuclear.tooltip.radioactive"))); + + public static final OrePrefix dustSpentFuel = new OrePrefix("dustSpentFuel", -1, null, + SuSyMaterialIconType.dustSpentFuel, 0, material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL)); + public static final OrePrefix dustBredFuel = new OrePrefix("dustBredFuel", -1, null, + SuSyMaterialIconType.dustBredFuel, 0, material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL)); + public static final OrePrefix dustFissionByproduct = new OrePrefix("dustFissionByproduct", -1, null, + SuSyMaterialIconType.dustFissionByproduct, 0, material -> material.hasProperty(SuSyPropertyKey.FISSION_FUEL)); } diff --git a/src/main/java/supersymmetry/api/util/SuSyUtility.java b/src/main/java/supersymmetry/api/util/SuSyUtility.java index 84cd0040b..401830ba5 100644 --- a/src/main/java/supersymmetry/api/util/SuSyUtility.java +++ b/src/main/java/supersymmetry/api/util/SuSyUtility.java @@ -1,11 +1,21 @@ package supersymmetry.api.util; import gregtech.api.GTValues; +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.pattern.MultiblockShapeInfo; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.registry.MaterialRegistry; +import gregtech.api.util.RelativeDirection; +import gregtech.core.unification.material.internal.MaterialRegistryManager; import net.minecraft.util.ResourceLocation; import supersymmetry.Supersymmetry; import java.util.function.Function; +import static gregtech.api.unification.material.info.MaterialFlags.*; +import static gregtech.api.unification.material.info.MaterialIconSet.DULL; +import static gregtech.api.util.GTUtility.gregtechId; + public class SuSyUtility { /* @@ -56,4 +66,37 @@ public class SuSyUtility { public static ResourceLocation susyId(String path) { return new ResourceLocation(Supersymmetry.MODID, path); } + + /** + * Returns a new String with the character at the given index replaced with the given character + * + * @param str The original string whose character is to be replaced + * @param index The index of the character to be replaced + * @param replace The character to replace the character at the given index + * @return The new string with the character at the given index replaced with the given character + */ + public static String replace(String str, int index, char replace) { + if (str == null) { + return str; + } else if (index < 0 || index >= str.length()) { + return str; + } + char[] chars = str.toCharArray(); + chars[index] = replace; + return String.valueOf(chars); + } + + // Work-around for not having Corium in susycore + public static Material Corium() { + Material corium = MaterialRegistryManager.getInstance().getMaterial("corium"); + if (corium == null) { + corium = new Material.Builder(1560, gregtechId("corium")) + .liquid(new FluidBuilder().temperature(2500).block().density(8.0D).viscosity(10000)) + .color(0x7A6B50) + .iconSet(DULL) + .flags(NO_UNIFICATION, STICKY, GLOWING) + .build(); + } + return corium; + } } diff --git a/src/main/java/supersymmetry/api/util/function/FloatSupplier.java b/src/main/java/supersymmetry/api/util/function/FloatSupplier.java new file mode 100644 index 000000000..72aa25b31 --- /dev/null +++ b/src/main/java/supersymmetry/api/util/function/FloatSupplier.java @@ -0,0 +1,7 @@ +package supersymmetry.api.util.function; + +@FunctionalInterface +public interface FloatSupplier { + + float get(); +} diff --git a/src/main/java/supersymmetry/client/renderer/textures/SusyTextures.java b/src/main/java/supersymmetry/client/renderer/textures/SusyTextures.java index fa465778c..73b41fa6a 100644 --- a/src/main/java/supersymmetry/client/renderer/textures/SusyTextures.java +++ b/src/main/java/supersymmetry/client/renderer/textures/SusyTextures.java @@ -80,10 +80,16 @@ public SusyTextures(){ public static final OrientedOverlayRenderer SINTERING_OVERLAY = new OrientedOverlayRenderer("machines/multiblocks/sintering"); public static final OrientedOverlayRenderer SMOKE_STACK_OVERLAY = new OrientedOverlayRenderer("machines/multiblocks/smoke_stack"); public static final OrientedOverlayRenderer PRIMITIVE_SMELTER_OVERLAY = new OrientedOverlayRenderer("machines/multiblocks/primitive_smelter"); + public static final OrientedOverlayRenderer FISSION_REACTOR_OVERLAY = new OrientedOverlayRenderer("multiblock/fission_reactor"); + public static final OrientedOverlayRenderer SPENT_FUEL_POOL_OVERLAY = new OrientedOverlayRenderer("multiblock/spent_fuel_pool"); + public static final OrientedOverlayRenderer GAS_CENTRIFUGE_OVERLAY = new OrientedOverlayRenderer("multiblock/gas_centrifuge"); public static final SimpleOverlayRenderer SILICON_CARBIDE_CASING = new SimpleOverlayRenderer("multiblock_casing/silicon_carbide_casing"); public static final SimpleOverlayRenderer ULV_STRUCTURAL_CASING = new SimpleOverlayRenderer("multiblock_casing/ulv_structural_casing"); public static final SimpleOverlayRenderer SLAG_HOT = new SimpleOverlayRenderer("resource/slag_hot"); + public static final SimpleOverlayRenderer FISSION_REACTOR_TEXTURE = new SimpleOverlayRenderer("casings/fission/reactor_vessel"); + public static final SimpleOverlayRenderer CONTROL_ROD = new SimpleOverlayRenderer("overlay/machine/overlay_control_rod"); + public static final SimpleOverlayRenderer CONTROL_ROD_MODERATED = new SimpleOverlayRenderer("overlay/machine/overlay_control_rod_moderated"); public static final SimpleCubeRenderer MASONRY_BRICK = new SimpleCubeRenderer("gregtech:blocks/multiblock_casing/masonry_brick"); diff --git a/src/main/java/supersymmetry/common/CommonProxy.java b/src/main/java/supersymmetry/common/CommonProxy.java index d594aab6d..50864268c 100644 --- a/src/main/java/supersymmetry/common/CommonProxy.java +++ b/src/main/java/supersymmetry/common/CommonProxy.java @@ -1,7 +1,10 @@ package supersymmetry.common; +import gregtech.api.GregTechAPI; import gregtech.api.block.VariantItemBlock; import gregtech.api.modules.ModuleContainerRegistryEvent; +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.unification.material.Material; import gregtech.api.unification.material.event.MaterialEvent; import gregtech.api.unification.material.event.PostMaterialEvent; import gregtech.client.utils.TooltipHelper; @@ -28,7 +31,12 @@ import software.bernie.geckolib3.GeckoLib; import supersymmetry.Supersymmetry; import supersymmetry.api.event.MobHordeEvent; +import supersymmetry.api.nuclear.fission.CoolantRegistry; +import supersymmetry.api.nuclear.fission.FissionFuelRegistry; import supersymmetry.api.recipes.SuSyRecipeMaps; +import supersymmetry.api.unification.material.properties.CoolantProperty; +import supersymmetry.api.unification.material.properties.FissionFuelProperty; +import supersymmetry.api.unification.material.properties.SuSyPropertyKey; import supersymmetry.api.unification.ore.SusyOrePrefix; import supersymmetry.api.unification.ore.SusyStoneTypes; import supersymmetry.common.blocks.SheetedFrameItemBlock; @@ -86,6 +94,10 @@ public static void registerBlocks(@NotNull RegistryEvent.Register event) registry.register(SuSyBlocks.ELECTRODE_ASSEMBLY); registry.register(SuSyBlocks.MULTIBLOCK_CASING); registry.register(SuSyBlocks.SERPENTINE); + registry.register(SuSyBlocks.FISSION_CASING); + registry.register(SuSyBlocks.NUCLEAR_CASING); + registry.register(SuSyBlocks.GAS_CENTRIFUGE_CASING); + registry.register(SuSyBlocks.PANELLING); SHEETED_FRAMES.values().stream().distinct().forEach(registry::register); } @@ -115,12 +127,16 @@ public static void registerItems(@NotNull RegistryEvent.Register event) { registry.register(createItemBlock(SuSyBlocks.ELECTRODE_ASSEMBLY, VariantItemBlock::new)); registry.register(createItemBlock(SuSyBlocks.MULTIBLOCK_CASING, VariantItemBlock::new)); registry.register(createItemBlock(SuSyBlocks.SERPENTINE, VariantItemBlock::new)); - + registry.register(createItemBlock(SuSyBlocks.FISSION_CASING, VariantItemBlock::new)); + registry.register(createItemBlock(SuSyBlocks.NUCLEAR_CASING, VariantItemBlock::new)); + registry.register(createItemBlock(SuSyBlocks.GAS_CENTRIFUGE_CASING, VariantItemBlock::new)); + registry.register(createItemBlock(SuSyBlocks.PANELLING, VariantItemBlock::new)); SHEETED_FRAMES.values() .stream().distinct() .map(block -> createItemBlock(block, SheetedFrameItemBlock::new)) .forEach(registry::register); + } @SubscribeEvent(priority = EventPriority.HIGH) @@ -141,6 +157,18 @@ public static void postRegisterMaterials(@NotNull PostMaterialEvent event) { MetaItems.addOrePrefix(SusyOrePrefix.dustWet); //SusyMaterials.removeFlags(); + + for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { + if (material.hasProperty(SuSyPropertyKey.FISSION_FUEL)) { + FissionFuelProperty prop = material.getProperty(SuSyPropertyKey.FISSION_FUEL); + FissionFuelRegistry.registerFuel(OreDictUnifier.get(SusyOrePrefix.fuelRod, material), prop, + OreDictUnifier.get(SusyOrePrefix.fuelRodHotDepleted, material)); + } + if (material.hasProperty(SuSyPropertyKey.COOLANT)) { + CoolantProperty prop = material.getProperty(SuSyPropertyKey.COOLANT); + CoolantRegistry.registerCoolant(material.getFluid(prop.getCoolantKey()), prop); + } + } } @SubscribeEvent diff --git a/src/main/java/supersymmetry/common/blocks/BlockFissionCasing.java b/src/main/java/supersymmetry/common/blocks/BlockFissionCasing.java new file mode 100644 index 000000000..aea2d2445 --- /dev/null +++ b/src/main/java/supersymmetry/common/blocks/BlockFissionCasing.java @@ -0,0 +1,56 @@ +package supersymmetry.common.blocks; + +import gregtech.api.block.IStateHarvestLevel; +import gregtech.api.block.VariantBlock; +import gregtech.api.items.toolitem.ToolClasses; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.IStringSerializable; + +import org.jetbrains.annotations.NotNull; + +public class BlockFissionCasing extends VariantBlock { + + public BlockFissionCasing() { + super(Material.IRON); + setTranslationKey("fission_casing"); + setHardness(10.0f); + setResistance(10.0f); + setSoundType(SoundType.METAL); + setDefaultState(getState(FissionCasingType.REACTOR_VESSEL)); + } + + public enum FissionCasingType implements IStringSerializable, IStateHarvestLevel { + + REACTOR_VESSEL("reactor_vessel", 2), + FUEL_CHANNEL("fuel_channel", 2), + CONTROL_ROD_CHANNEL("control_rod_channel", 2), + COOLANT_CHANNEL("coolant_channel", 2); + + private final String name; + private final int harvestLevel; + + FissionCasingType(String name, int harvestLevel) { + this.name = name; + this.harvestLevel = harvestLevel; + } + + @NotNull + @Override + public String getName() { + return this.name; + } + + @Override + public int getHarvestLevel(IBlockState state) { + return harvestLevel; + } + + @Override + public String getHarvestTool(IBlockState state) { + return ToolClasses.WRENCH; + } + } +} diff --git a/src/main/java/supersymmetry/common/blocks/BlockGasCentrifugeCasing.java b/src/main/java/supersymmetry/common/blocks/BlockGasCentrifugeCasing.java new file mode 100644 index 000000000..708addbbc --- /dev/null +++ b/src/main/java/supersymmetry/common/blocks/BlockGasCentrifugeCasing.java @@ -0,0 +1,49 @@ +package supersymmetry.common.blocks; + +import gregtech.api.block.IStateHarvestLevel; +import gregtech.api.block.VariantBlock; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.IStringSerializable; + +public class BlockGasCentrifugeCasing extends VariantBlock { + + public BlockGasCentrifugeCasing() { + super(Material.IRON); + setTranslationKey("gas_centrifuge_casing"); + setHardness(5.0f); + setResistance(10.0f); + setSoundType(SoundType.METAL); + setDefaultState(getState(GasCentrifugeCasingType.GAS_CENTRIFUGE_COLUMN)); + } + + @Override + public boolean isOpaqueCube(IBlockState state) { + return state != getState(GasCentrifugeCasingType.GAS_CENTRIFUGE_COLUMN); + } + + public enum GasCentrifugeCasingType implements IStringSerializable, IStateHarvestLevel { + + GAS_CENTRIFUGE_COLUMN("gas_centrifuge_column", 2); + + private String name; + private int harvestLevel; + + GasCentrifugeCasingType(String name, int harvestLevel) { + this.name = name; + this.harvestLevel = harvestLevel; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getHarvestLevel(IBlockState state) { + return harvestLevel; + } + } +} diff --git a/src/main/java/supersymmetry/common/blocks/BlockNuclearCasing.java b/src/main/java/supersymmetry/common/blocks/BlockNuclearCasing.java new file mode 100644 index 000000000..4f0e983de --- /dev/null +++ b/src/main/java/supersymmetry/common/blocks/BlockNuclearCasing.java @@ -0,0 +1,48 @@ +package supersymmetry.common.blocks; + +import gregtech.api.block.IStateHarvestLevel; +import gregtech.api.block.VariantActiveBlock; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.IStringSerializable; + +import org.jetbrains.annotations.NotNull; + +public class BlockNuclearCasing extends VariantActiveBlock { + + public BlockNuclearCasing() { + super(Material.IRON); + setTranslationKey("nuclear_casing"); + setHardness(5.0f); + setResistance(10.0f); + setSoundType(SoundType.METAL); + setDefaultState(getState(NuclearCasingType.SPENT_FUEL_CASING)); + } + + public enum NuclearCasingType implements IStringSerializable, IStateHarvestLevel { + + SPENT_FUEL_CASING("spent_fuel_casing", 2), + GAS_CENTRIFUGE_HEATER("gas_centrifuge_heater", 1); + + NuclearCasingType(String name, int harvestLevel) { + this.name = name; + this.harvestLevel = harvestLevel; + } + + private final String name; + private final int harvestLevel; + + @NotNull + @Override + public String getName() { + return this.name; + } + + @Override + public int getHarvestLevel(IBlockState state) { + return this.harvestLevel; + } + } +} diff --git a/src/main/java/supersymmetry/common/blocks/BlockPanelling.java b/src/main/java/supersymmetry/common/blocks/BlockPanelling.java new file mode 100644 index 000000000..c98973f01 --- /dev/null +++ b/src/main/java/supersymmetry/common/blocks/BlockPanelling.java @@ -0,0 +1,50 @@ +package supersymmetry.common.blocks; + +import gregtech.api.block.VariantBlock; + +import net.minecraft.block.SoundType; +import net.minecraft.util.IStringSerializable; + +public class BlockPanelling extends VariantBlock { + + public BlockPanelling() { + super(net.minecraft.block.material.Material.IRON); + setTranslationKey("panelling"); + setHardness(2.0f); + setResistance(5.0f); + setSoundType(SoundType.METAL); + setHarvestLevel("wrench", 2); + setDefaultState(getState(PanellingType.WHITE)); + } + + public enum PanellingType implements IStringSerializable { + + WHITE("white"), + ORANGE("orange"), + MAGENTA("magenta"), + LIGHT_BLUE("light_blue"), + YELLOW("yellow"), + LIME("lime"), + PINK("pink"), + GRAY("gray"), + LIGHT_GRAY("light_gray"), + CYAN("cyan"), + PURPLE("purple"), + BLUE("blue"), + BROWN("brown"), + GREEN("green"), + RED("red"), + BLACK("black"); + + private final String name; + + PanellingType(String name) { + this.name = name; + } + + @Override + public String getName() { + return this.name; + } + } +} diff --git a/src/main/java/supersymmetry/common/blocks/SuSyBlocks.java b/src/main/java/supersymmetry/common/blocks/SuSyBlocks.java index a4f07a677..9e1fbff73 100644 --- a/src/main/java/supersymmetry/common/blocks/SuSyBlocks.java +++ b/src/main/java/supersymmetry/common/blocks/SuSyBlocks.java @@ -41,6 +41,12 @@ public class SuSyBlocks { public static BlockSuSyMultiblockCasing MULTIBLOCK_CASING; public static BlockSerpentine SERPENTINE; + // Nuclear Blocks + public static BlockFissionCasing FISSION_CASING; + public static BlockNuclearCasing NUCLEAR_CASING; + public static BlockGasCentrifugeCasing GAS_CENTRIFUGE_CASING; + public static BlockPanelling PANELLING; + public static void init() { COOLING_COIL = new BlockCoolingCoil(); COOLING_COIL.setRegistryName("cooling_coil"); @@ -101,6 +107,16 @@ public static void init() { SERPENTINE = new BlockSerpentine(); SERPENTINE.setRegistryName("serpentine"); + FISSION_CASING = new BlockFissionCasing(); + FISSION_CASING.setRegistryName("fission_casing"); + NUCLEAR_CASING = new BlockNuclearCasing(); + NUCLEAR_CASING.setRegistryName("nuclear_casing"); + GAS_CENTRIFUGE_CASING = new BlockGasCentrifugeCasing(); + GAS_CENTRIFUGE_CASING.setRegistryName("gas_centrifuge_casing"); + + PANELLING = new BlockPanelling(); + PANELLING.setRegistryName("panelling"); + } @SideOnly(Side.CLIENT) @@ -120,11 +136,15 @@ public static void registerItemModels() { registerItemModel(RESOURCE_BLOCK); registerItemModel(RESOURCE_BLOCK_1); registerItemModel(HOME); + registerItemModel(FISSION_CASING); + registerItemModel(GAS_CENTRIFUGE_CASING); + registerItemModel(PANELLING); EVAPORATION_BED.onModelRegister(); MULTIBLOCK_TANK.onModelRegister(); ELECTRODE_ASSEMBLY.onModelRegister(); registerItemModel(MULTIBLOCK_CASING); SERPENTINE.onModelRegister(); + NUCLEAR_CASING.onModelRegister(); } @SideOnly(Side.CLIENT) diff --git a/src/main/java/supersymmetry/common/item/SuSyMetaItems.java b/src/main/java/supersymmetry/common/item/SuSyMetaItems.java index 8a34c3ba3..730862d09 100644 --- a/src/main/java/supersymmetry/common/item/SuSyMetaItems.java +++ b/src/main/java/supersymmetry/common/item/SuSyMetaItems.java @@ -8,9 +8,11 @@ import gregtech.api.items.metaitem.StandardMetaItem; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.items.MetaItems; import gregtech.common.items.behaviors.TooltipBehavior; import net.minecraft.client.resources.I18n; import supersymmetry.SuSyValues; +import supersymmetry.api.unification.ore.SusyOrePrefix; import supersymmetry.common.item.armor.SuSyMetaArmor; public class SuSyMetaItems { @@ -22,6 +24,10 @@ public class SuSyMetaItems { public static MetaValueItem PUMP_STEAM; public static MetaValueItem AIR_VENT; public static MetaValueItem TRACK_SEGMENT; + // Nuclear + public static MetaValueItem ANODE_BASKET; + public static MetaValueItem FUEL_CLADDING; + public static ArmorMetaItem.ArmorMetaValueItem JET_WINGPACK; public static void initMetaItems() { @@ -58,13 +64,28 @@ private static void initMetaItem() { TRACK_SEGMENT = metaItem.addItem(5, "track_segment").addComponents(new TooltipBehavior((lines) -> { lines.add(I18n.format("metaitem.track_segment.length_info")); })); + ANODE_BASKET = metaItem.addItem(6, "basket.anode"); + FUEL_CLADDING = metaItem.addItem(7, "cladding.fuel"); } - private static void addTieredOredictItem (OreDictValueItem[] items, int id, int RGB, OrePrefix prefix) { + private static void addTieredOredictItem(OreDictValueItem[] items, int id, int RGB, OrePrefix prefix) { for (int i = 0; i < items.length; i++) { items[i] = oreDictItem.addOreDictItem(id + i, SuSyValues.TierMaterials[i + 1].toString(), RGB, MaterialIconSet.DULL, prefix, I18n.format("gregtech.universal.catalysts.tooltip.tier", GTValues.V[i], GTValues.VN[i])); } } + + static { + MetaItems.addOrePrefix( + SusyOrePrefix.fuelRod, + SusyOrePrefix.fuelRodDepleted, + SusyOrePrefix.fuelRodHotDepleted, + SusyOrePrefix.fuelPellet, + SusyOrePrefix.fuelPelletDepleted, + SusyOrePrefix.dustSpentFuel, + SusyOrePrefix.dustBredFuel, + SusyOrePrefix.dustFissionByproduct + ); + } } diff --git a/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java b/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java index 8d33f82ce..27e380aa6 100644 --- a/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java +++ b/src/main/java/supersymmetry/common/metatileentities/SuSyMetaTileEntities.java @@ -30,9 +30,12 @@ import supersymmetry.api.recipes.SuSyRecipeMaps; import supersymmetry.api.util.SuSyUtility; import supersymmetry.client.renderer.textures.SusyTextures; +import supersymmetry.common.metatileentities.multi.MetaTileEntityFissionReactor; +import supersymmetry.common.metatileentities.multi.MetaTileEntitySpentFuelPool; import supersymmetry.common.metatileentities.logistics.MetaTileEntityBridge; import supersymmetry.common.metatileentities.logistics.MetaTileEntityExtender; import supersymmetry.common.metatileentities.multi.electric.*; +import supersymmetry.common.metatileentities.multi.multiblockpart.*; import supersymmetry.common.metatileentities.multi.primitive.MetaTileEntityCoagulationTank; import supersymmetry.common.metatileentities.multi.primitive.MetaTileEntityPrimitiveMudPump; import supersymmetry.common.metatileentities.multi.primitive.MetaTileEntityPrimitiveSmelter; @@ -187,6 +190,18 @@ public class SuSyMetaTileEntities { public static final MetaTileEntityMultiFluidHatch[] SUSY_QUADRUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[3]; // LV-HV public static final MetaTileEntityMultiFluidHatch[] SUSY_NONUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[3]; // LV-HV + + // Nuclear MTEs + public static MetaTileEntityFissionReactor FISSION_REACTOR; + public static MetaTileEntityFuelRodImportBus FUEL_ROD_INPUT; + public static MetaTileEntityFuelRodExportBus FUEL_ROD_OUTPUT; + public static MetaTileEntityCoolantImportHatch COOLANT_INPUT; + public static MetaTileEntityCoolantExportHatch COOLANT_OUTPUT; + public static MetaTileEntityControlRodPort CONTROL_ROD; + public static MetaTileEntityControlRodPort CONTROL_ROD_MODERATED; + public static MetaTileEntitySpentFuelPool SPENT_FUEL_POOL; + public static MetaTileEntityGasCentrifuge GAS_CENTRIFUGE; + public static void init() { MAGNETIC_REFRIGERATOR = registerMetaTileEntity(14500, new MetaTileEntityMagneticRefrigerator(susyId("magnetic_refrigerator"))); COAGULATION_TANK = registerMetaTileEntity(14501, new MetaTileEntityCoagulationTank(susyId("coagulation_tank"))); @@ -351,6 +366,17 @@ public static void init() { registerSimpleMTE(ELECTROSTATIC_SEPARATOR, 12, 17035, "electrostatic_separator", SuSyRecipeMaps.ELECTROSTATIC_SEPARATOR, SusyTextures.ELECTROSTATIC_SEPARATOR_OVERLAY, true, GTUtility.defaultTankSizeFunction); registerSimpleMTE(POLISHING_MACHINE, 12, 17048, "polishing_machine", SuSyRecipeMaps.POLISHING_MACHINE, SusyTextures.POLISHING_MACHINE_OVERLAY, true, GTUtility.defaultTankSizeFunction); registerSimpleMTE(TEXTILE_SPINNER, 12, 17061, "textile_spinner", SuSyRecipeMaps.SPINNING_RECIPES, SusyTextures.TEXTILE_SPINNER_OVERLAY, true); + + FISSION_REACTOR = registerMetaTileEntity(1043, new MetaTileEntityFissionReactor(gregtechId("fission_reactor"))); + SPENT_FUEL_POOL = registerMetaTileEntity(1044, new MetaTileEntitySpentFuelPool(gregtechId("spent_fuel_pool"))); + GAS_CENTRIFUGE = registerMetaTileEntity(1046, new MetaTileEntityGasCentrifuge(gregtechId("gas_centrifuge"))); + + FUEL_ROD_INPUT = registerMetaTileEntity(1800, new MetaTileEntityFuelRodImportBus(gregtechId("fuel_rod_input"))); + FUEL_ROD_OUTPUT = registerMetaTileEntity(1801, new MetaTileEntityFuelRodExportBus(gregtechId("fuel_rod_output"))); + COOLANT_INPUT = registerMetaTileEntity(1802, new MetaTileEntityCoolantImportHatch(gregtechId("coolant_input"))); + COOLANT_OUTPUT = registerMetaTileEntity(1803, new MetaTileEntityCoolantExportHatch(gregtechId("coolant_output"))); + CONTROL_ROD = registerMetaTileEntity(1804, new MetaTileEntityControlRodPort(gregtechId("control_rod"), false)); + CONTROL_ROD_MODERATED = registerMetaTileEntity(1805, new MetaTileEntityControlRodPort(gregtechId("control_rod_moderated"), true)); } private static void registerSimpleSteamMTE(SuSySimpleSteamMetaTileEntity[] machines, int startId, String name, RecipeMap recipeMap, SuSySteamProgressIndicator progressIndicator, ICubeRenderer texture, boolean isBricked) { diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/MetaTileEntityFissionReactor.java b/src/main/java/supersymmetry/common/metatileentities/multi/MetaTileEntityFissionReactor.java new file mode 100644 index 000000000..8862066b8 --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/MetaTileEntityFissionReactor.java @@ -0,0 +1,1114 @@ +package supersymmetry.common.metatileentities.multi; + +import gregtech.api.capability.IMaintenanceHatch; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.widgets.AdvancedTextWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.ProgressWidget; +import gregtech.api.gui.widgets.SliderWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; +import gregtech.api.metatileentity.IDataInfoProvider; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.IProgressBarMultiblock; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.MultiblockShapeInfo; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.api.pattern.PatternStringError; +import gregtech.api.pattern.TraceabilityPredicate; +import gregtech.api.util.BlockInfo; +import gregtech.api.util.GTUtility; +import gregtech.api.util.RelativeDirection; +import gregtech.api.util.TextComponentUtil; +import gregtech.api.util.TextFormattingUtil; +import gregtech.client.renderer.ICubeRenderer; +import gregtech.common.ConfigHolder; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.metatileentities.MetaTileEntities; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.*; +import net.minecraft.world.World; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import supersymmetry.api.capability.ICoolantHandler; +import supersymmetry.api.capability.IFuelRodHandler; +import supersymmetry.api.cover.ICustomEnergyCover; +import supersymmetry.api.gui.SusyGuiTextures; +import supersymmetry.api.gui.widgets.UpdatedSliderWidget; +import supersymmetry.api.metatileentity.multiblock.IFissionReactorHatch; +import supersymmetry.api.metatileentity.multiblock.SuSyMultiblockAbilities; +import supersymmetry.api.nuclear.fission.*; +import supersymmetry.api.nuclear.fission.components.ControlRod; +import supersymmetry.api.nuclear.fission.components.CoolantChannel; +import supersymmetry.api.nuclear.fission.components.FuelRod; +import supersymmetry.api.util.SuSyUtility; +import supersymmetry.client.renderer.textures.SusyTextures; +import supersymmetry.common.blocks.BlockFissionCasing; +import supersymmetry.common.blocks.SuSyBlocks; +import supersymmetry.common.metatileentities.SuSyMetaTileEntities; +import supersymmetry.common.metatileentities.multi.multiblockpart.MetaTileEntityControlRodPort; +import supersymmetry.common.metatileentities.multi.multiblockpart.MetaTileEntityCoolantExportHatch; +import supersymmetry.common.metatileentities.multi.multiblockpart.MetaTileEntityFuelRodImportBus; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static supersymmetry.api.nuclear.fission.FissionValues.SYNC_LOCKING_STATE; +import static supersymmetry.api.nuclear.fission.FissionValues.SYNC_REACTOR_STATS; + +public class MetaTileEntityFissionReactor extends MultiblockWithDisplayBase + implements IDataInfoProvider, IProgressBarMultiblock, ICustomEnergyCover { + + private FissionReactor fissionReactor; + private int diameter; + private int heightTop; + private int heightBottom; + private int height; + private int flowRate = 1; + // Used for maintenance mechanics + private boolean isFlowingCorrectly = true; + private double controlRodInsertionValue; + private LockingState lockingState = LockingState.UNLOCKED; + + private double temperature; + private double maxTemperature; + private double pressure; + private double maxPressure; + private double power; + private double maxPower; + private double kEff; + private double fuelDepletionPercent; + + private NBTTagCompound transientData; + + public MetaTileEntityFissionReactor(ResourceLocation metaTileEntityId) { + super(metaTileEntityId); + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityFissionReactor(metaTileEntityId); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer entityPlayer) { + ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 240, 208); + + // Display + builder.image(4, 4, 232, 109, GuiTextures.DISPLAY); + + // triple bar + ProgressWidget progressBar = new ProgressWidget( + () -> this.getFillPercentage(0), + 4, 115, 76, 7, + SusyGuiTextures.PROGRESS_BAR_FISSION_HEAT, ProgressWidget.MoveType.HORIZONTAL) + .setHoverTextConsumer(list -> this.addBarHoverText(list, 0)); + builder.widget(progressBar); + + progressBar = new ProgressWidget( + () -> this.getFillPercentage(1), + 82, 115, 76, 7, + SusyGuiTextures.PROGRESS_BAR_FISSION_PRESSURE, ProgressWidget.MoveType.HORIZONTAL) + .setHoverTextConsumer(list -> this.addBarHoverText(list, 1)); + builder.widget(progressBar); + + progressBar = new ProgressWidget( + () -> this.getFillPercentage(2), + 160, 115, 76, 7, + SusyGuiTextures.PROGRESS_BAR_FISSION_ENERGY, ProgressWidget.MoveType.HORIZONTAL) + .setHoverTextConsumer(list -> this.addBarHoverText(list, 2)); + builder.widget(progressBar); + + builder.label(9, 9, getMetaFullName(), 0xFFFFFF); + + builder.widget(new UpdatedSliderWidget("gregtech.gui.fission.control_rod_insertion", 10, 60, 220, + 18, 0.0f, 1.0f, + (float) controlRodInsertionValue, this::setControlRodInsertionValue, + () -> (float) this.controlRodInsertionValue) { + + @Override + protected String getDisplayString() { + return I18n.format("gregtech.gui.fission.control_rod_insertion", + String.format("%.2f%%", this.getSliderValue() * 100)); + } + }.setBackground(SusyGuiTextures.DARK_SLIDER_BACKGROUND).setSliderIcon(SusyGuiTextures.DARK_SLIDER_ICON)); + builder.widget(new SliderWidget("gregtech.gui.fission.coolant_flow", 10, 80, 220, 18, 0.0f, 16000.f, flowRate, + this::setFlowRate).setBackground(SusyGuiTextures.DARK_SLIDER_BACKGROUND) + .setSliderIcon(SusyGuiTextures.DARK_SLIDER_ICON)); + + builder.widget(new AdvancedTextWidget(9, 20, this::addDisplayText, 0xFFFFFF) + .setMaxWidthLimit(220) + .setClickHandler(this::handleDisplayClick)); + + // Power Button + + builder.widget(new ToggleButtonWidget(215, 183, 18, 18, GuiTextures.BUTTON_LOCK, + this::isLocked, this::tryLocking).shouldUseBaseBackground() + .setTooltipText("gregtech.gui.fission.lock")); + builder.widget(new ImageWidget(215, 201, 18, 6, GuiTextures.BUTTON_POWER_DETAIL)); + + // Voiding Mode Button + builder.widget(new ImageWidget(215, 161, 18, 18, GuiTextures.BUTTON_VOID_NONE) + .setTooltip("gregtech.gui.multiblock_voiding_not_supported")); + + builder.widget(new ImageWidget(215, 143, 18, 18, GuiTextures.BUTTON_NO_DISTINCT_BUSES) + .setTooltip("gregtech.multiblock.universal.distinct_not_supported")); + + // Flex Button + builder.widget(getFlexButton(215, 125, 18, 18)); + + builder.bindPlayerInventory(entityPlayer.inventory, 125); + return builder; + } + + @Override + public double getFillPercentage(int index) { + if (index == 0) { + return this.temperature / this.maxTemperature; + } else if (index == 1) { + return this.pressure / this.maxPressure; + } else { + if (this.maxPower / this.power > Math.exp(12)) { + return 0; + } + return (Math.log(this.power / this.maxPower) + 12) / 12; + } + } + + @Override + protected @NotNull Widget getFlexButton(int x, int y, int width, int height) { + return new ToggleButtonWidget(x, y, width, height, this::areControlRodsRegulated, + this::toggleControlRodRegulation).setButtonTexture(SusyGuiTextures.BUTTON_CONTROL_ROD_HELPER) + .setTooltipText("gregtech.gui.fission.helper"); + } + + /** + * Public for OC integration, use it if you want ig + */ + public void toggleControlRodRegulation(boolean b) { + if (fissionReactor != null) { + this.fissionReactor.controlRodRegulationOn = b; + } + } + + public boolean areControlRodsRegulated() { + return fissionReactor != null && this.fissionReactor.controlRodRegulationOn; + } + + @Override + public void addBarHoverText(List list, int index) { + if (index == 0) { + list.add(new TextComponentTranslation("gregtech.gui.fission.temperature", + String.format("%.1f", this.temperature) + " / " + String.format("%.1f", this.maxTemperature))); + } else if (index == 1) { + list.add(new TextComponentTranslation("gregtech.gui.fission.pressure", + String.format("%.0f", this.pressure) + " / " + String.format("%.0f", this.maxPressure))); + } else { + list.add(new TextComponentTranslation("gregtech.gui.fission.power", String.format("%.1f", this.power), + String.format("%.1f", this.maxPower))); + } + } + + private void setFlowRate(float flowrate) { + this.flowRate = (int) flowrate; + if (flowRate < 1) flowRate = 1; + } + + public void setControlRodInsertionValue(float value) { + this.controlRodInsertionValue = value; + if (fissionReactor != null) + fissionReactor.updateControlRodInsertion(controlRodInsertionValue); + } + + private boolean isLocked() { + return lockingState == LockingState.LOCKED; + } + + private TextFormatting getLockedTextColor() { + switch (lockingState) { + case LOCKED: + return TextFormatting.GREEN; + case UNLOCKED: + return TextFormatting.DARK_AQUA; + case INVALID_COMPONENT: + return TextFormatting.RED; + case SHOULD_LOCK: + return TextFormatting.BLACK; + default: + return getWorld().getWorldTime() % 4 >= 2 ? TextFormatting.RED : TextFormatting.YELLOW; + } + } + + private void tryLocking(boolean lock) { + if (!isStructureFormed()) + return; + + if (lock) + lockAndPrepareReactor(); + else + unlockAll(); + } + + @Override + protected void addErrorText(List list) { + if (lockingState != LockingState.LOCKED && lockingState != LockingState.UNLOCKED) { + list.add( + new TextComponentTranslation("gregtech.gui.fission.lock." + lockingState.toString().toLowerCase())); + } + } + + @Override + protected void addDisplayText(List list) { + super.addDisplayText(list); + list.add( + TextComponentUtil.setColor(new TextComponentTranslation( + "gregtech.gui.fission.lock." + lockingState.toString().toLowerCase()), getLockedTextColor())); + list.add(new TextComponentTranslation("gregtech.gui.fission.k_eff", String.format("%.4f", this.kEff))); + list.add(new TextComponentTranslation("gregtech.gui.fission.depletion", + String.format("%.2f", this.fuelDepletionPercent * 100))); + } + + protected boolean isBlockEdge(@NotNull World world, @NotNull BlockPos.MutableBlockPos pos, + @NotNull EnumFacing direction, + int steps) { + pos.move(direction, steps); + + if (world.getBlockState(pos).getBlock() == SuSyBlocks.FISSION_CASING) { + pos.move(direction.getOpposite(), steps); + return false; + } + + MetaTileEntity potentialTile = GTUtility.getMetaTileEntity(world, pos); + pos.move(direction.getOpposite(), steps); + if (potentialTile == null) { + return true; + } + + return !(potentialTile instanceof IFissionReactorHatch || potentialTile instanceof IMaintenanceHatch); + } + + protected EnumFacing getUp() { + return RelativeDirection.UP.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + } + + protected EnumFacing getRight() { + return RelativeDirection.RIGHT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + } + + /** + * Uses the upper layer to determine the diameter of the structure + */ + protected int findDiameter(int heightTop) { + int i = 1; + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + pos.move(getUp(), heightTop); + while (i <= 15) { + if (this.isBlockEdge(this.getWorld(), pos, + this.getFrontFacing().getOpposite(), + i)) + break; + i++; + } + return i; + } + + /** + * Checks for casings on top or bottom of the controller to determine the height of the reactor + */ + protected int findHeight(boolean top) { + int i = 1; + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + while (i <= 15) { + if (this.isBlockEdge(this.getWorld(), pos, top ? getUp() : getUp().getOpposite(), i)) + break; + i++; + } + return i - 1; + } + + @Override + public void updateFormedValid() { + // Take in coolant, take in fuel, update reactor, output steam + + if (!this.getWorld().isRemote && this.getOffsetTimer() % 20 == 0) { + if (this.lockingState == LockingState.LOCKED) { + // Coolant handling + if (this.getOffsetTimer() % 100 == 0) { + if (isFlowingCorrectly) { + if (getWorld().rand.nextDouble() > (1 - 0.01 * this.getNumMaintenanceProblems())) { + isFlowingCorrectly = false; + } + } else { + if (getWorld().rand.nextDouble() > 0.12 * this.getNumMaintenanceProblems()) { + isFlowingCorrectly = true; + } + } + } + + // Fuel handling + if (this.fissionReactor.isDepleted()) { + boolean canWork = true; + boolean needsReset = false; + for (IFuelRodHandler fuelImport : this.getAbilities(SuSyMultiblockAbilities.IMPORT_FUEL_ROD)) { + if (fuelImport.getStackHandler().extractItem(0, 1, true).isEmpty()) { + canWork = false; + this.lockingState = LockingState.MISSING_FUEL; + break; + } else if (!((MetaTileEntityFuelRodImportBus) fuelImport).getExportHatch(this.height - + 1) + .getExportItems().insertItem(0, + FissionFuelRegistry.getDepletedFuel(fuelImport.getFuel()), true) + .isEmpty()) { + // We still need to know if the output is blocked, even if the recipe doesn't start + // yet + canWork = false; + this.lockingState = LockingState.FUEL_CLOGGED; + break; + } + + } + + for (IFuelRodHandler fuelImport : this.getAbilities(SuSyMultiblockAbilities.IMPORT_FUEL_ROD)) { + if (fissionReactor.needsOutput) { + ((MetaTileEntityFuelRodImportBus) fuelImport).getExportHatch(this.height - 1) + .getExportItems().insertItem(0, + FissionFuelRegistry.getDepletedFuel(fuelImport.getPartialFuel()), + false); + this.fissionReactor.fuelMass -= 60; + } + if (canWork) { + fuelImport.getStackHandler().extractItem(0, 1, false); + needsReset |= fuelImport.setPartialFuel(fuelImport.getFuel()); + this.fissionReactor.fuelMass += 60; + } + } + if (canWork) { + fissionReactor.needsOutput = true; + this.fissionReactor.resetFuelDepletion(); + + if (needsReset) { + fissionReactor.computeGeometry(); + } + } else { + this.unlockAll(); + } + + } + } + this.updateReactorState(isFlowingCorrectly ? flowRate : 0); + + this.syncReactorStats(); + + boolean melts = this.fissionReactor.checkForMeltdown(); + boolean explodes = this.fissionReactor.checkForExplosion(); + double hydrogen = this.fissionReactor.accumulatedHydrogen; + if (melts) { + this.performMeltdownEffects(); + } + if (explodes) { + this.performPrimaryExplosion(); + if (hydrogen > 1) { + this.performSecondaryExplosion(hydrogen); + } + } + } + } + + protected void performMeltdownEffects() { + this.unlockAll(); + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + pos = pos.move(this.getFrontFacing().getOpposite(), diameter / 2); + placeCorium(pos, EnumFacing.UP); + for (int i = 0; i <= this.heightBottom; i++) { + this.getWorld().setBlockState(pos, SuSyUtility.Corium().getFluid().getBlock().getDefaultState()); + for (EnumFacing facing : EnumFacing.HORIZONTALS) { + placeCorium(pos, facing); + } + pos.move(EnumFacing.DOWN); + } + this.getWorld().setBlockState(pos.add(0, 1, 0), SuSyUtility.Corium().getFluid().getBlock().getDefaultState()); + } + + private void placeCorium(BlockPos.MutableBlockPos pos, EnumFacing facing) { + this.getWorld().setBlockState(pos.move(facing), SuSyUtility.Corium().getFluid().getBlock().getDefaultState()); + pos.move(facing.getOpposite()); + } + + protected void performPrimaryExplosion() { + this.unlockAll(); + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + pos = pos.move(this.getFrontFacing().getOpposite(), diameter / 2); + this.getWorld().createExplosion(null, pos.getX(), pos.getY() + heightTop, pos.getZ(), 4.f, true); + } + + protected void performSecondaryExplosion(double accumulatedHydrogen) { + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + pos = pos.move(this.getFrontFacing().getOpposite(), diameter / 2); + this.getWorld().newExplosion(null, pos.getX(), pos.getY() + heightTop + 3, pos.getZ(), + 4.f + (float) Math.log(accumulatedHydrogen), true, true); + } + + @NotNull + @Override + protected BlockPattern createStructurePattern() { + this.heightTop = Math.max(Math.min(this.getWorld() != null ? this.findHeight(true) : 1, 7), 1); + this.heightBottom = Math.max(Math.min(this.getWorld() != null ? this.findHeight(false) : 1, 7), 1); + + this.height = heightTop + heightBottom + 1; + + this.diameter = this.getWorld() != null ? Math.max(Math.min(this.findDiameter(heightTop), 15), 5) : 5; + + int radius = this.diameter % 2 == 0 ? (int) Math.floor(this.diameter / 2.f) : + Math.round((this.diameter - 1) / 2.f); + + StringBuilder interiorBuilder = new StringBuilder(); + + String[] interiorSlice = new String[this.diameter]; + String[] controllerSlice; + String[] topSlice; + String[] bottomSlice; + + // First loop over the matrix + for (int i = 0; i < this.diameter; i++) { + for (int j = 0; j < this.diameter; j++) { + + if (Math.pow(i - Math.floor(this.diameter / 2.), 2) + Math.pow(j - Math.floor(this.diameter / 2.), 2) < + Math.pow(radius + 0.5f, 2)) { + interiorBuilder.append('A'); + } else { + interiorBuilder.append(' '); + } + } + + interiorSlice[i] = interiorBuilder.toString(); + interiorBuilder.setLength(0); + } + + // Second loop is to detect where to put walls, the controller and I/O, two fewer iterations are needed because + // two strings always represent two walls on opposite sides + interiorSlice[this.diameter - 1] = interiorSlice[0] = interiorSlice[0].replace('A', 'B'); + for (int i = 1; i < this.diameter - 1; i++) { + for (int j = 0; j < this.diameter; j++) { + if (interiorSlice[i].charAt(j) != 'A') { + continue; + } + + // The integer division is fine here, since we want an odd diameter (say, 5) to go to the middle value + // (2 in this case) + int outerI = i + (int) Math.signum(i - (diameter / 2)); + + if (Math.pow(outerI - Math.floor(this.diameter / 2.), 2) + + Math.pow(j - Math.floor(this.diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = SuSyUtility.replace(interiorSlice[i], j, 'B'); + } + + int outerJ = j + (int) Math.signum(j - (diameter / 2)); + if (Math.pow(i - Math.floor(this.diameter / 2.), 2) + + Math.pow(outerJ - Math.floor(this.diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = SuSyUtility.replace(interiorSlice[i], j, 'B'); + } + } + } + + controllerSlice = interiorSlice.clone(); + topSlice = interiorSlice.clone(); + bottomSlice = interiorSlice.clone(); + controllerSlice[0] = controllerSlice[0].substring(0, (int) Math.floor(this.diameter / 2.)) + 'S' + + controllerSlice[0].substring((int) Math.floor(this.diameter / 2.) + 1); + for (int i = 0; i < this.diameter; i++) { + topSlice[i] = topSlice[i].replace('A', 'I'); + bottomSlice[i] = bottomSlice[i].replace('A', 'O'); + } + + return FactoryBlockPattern.start(RelativeDirection.RIGHT, RelativeDirection.FRONT, RelativeDirection.UP) + .aisle(bottomSlice) + .aisle(interiorSlice).setRepeatable(heightBottom - 1) + .aisle(controllerSlice) + .aisle(interiorSlice).setRepeatable(heightTop - 1) + .aisle(topSlice) + .where('S', selfPredicate()) + // A for interior components + .where('A', + states(getFuelChannelState(), getControlRodChannelState(), getCoolantChannelState()).or(air())) + // I for the inputs on the top + .where('I', + states(getVesselState()).or(getImportPredicate())) + // O for the outputs on the bottom + .where('O', + states(getVesselState()) + .or(abilities(SuSyMultiblockAbilities.EXPORT_COOLANT, SuSyMultiblockAbilities.EXPORT_FUEL_ROD))) + // B for the vessel blocks on the walls + .where('B', + states(getVesselState()) + .or(abilities(MultiblockAbility.MAINTENANCE_HATCH).setMinGlobalLimited(1) + .setMaxGlobalLimited(1))) + .where(' ', any()) + .build(); + } + + public TraceabilityPredicate getImportPredicate() { + MultiblockAbility[] allowedAbilities = { SuSyMultiblockAbilities.IMPORT_COOLANT, SuSyMultiblockAbilities.IMPORT_FUEL_ROD, + SuSyMultiblockAbilities.CONTROL_ROD_PORT }; + return tilePredicate((state, tile) -> { + if (!(tile instanceof IMultiblockAbilityPart && + ArrayUtils.contains(allowedAbilities, ((IMultiblockAbilityPart) tile).getAbility()))) { + return false; + } + if (tile instanceof IFissionReactorHatch hatchPart) { + if (!hatchPart.checkValidity(height - 1)) { + state.setError(new PatternStringError("gregtech.multiblock.pattern.error.hatch_invalid")); + return false; + } + return true; + } + return false; + }, + () -> Arrays.stream(allowedAbilities) + .flatMap(ability -> MultiblockAbility.REGISTRY.get(ability).stream()) + .filter(Objects::nonNull).map(tile -> { + MetaTileEntityHolder holder = new MetaTileEntityHolder(); + holder.setMetaTileEntity(tile); + holder.getMetaTileEntity().onPlacement(); + holder.getMetaTileEntity().setFrontFacing(EnumFacing.SOUTH); + return new BlockInfo(MetaBlocks.MACHINE.getDefaultState(), holder); + }).toArray(BlockInfo[]::new)); + } + + @NotNull + @Override + public List getDataInfo() { + List list = new ArrayList<>(); + list.add(new TextComponentTranslation("gregtech.multiblock.fission_reactor.diameter", + new TextComponentTranslation(TextFormattingUtil.formatNumbers(this.diameter) + "m") + .setStyle(new Style().setColor(TextFormatting.YELLOW)))); + list.add(new TextComponentTranslation("gregtech.multiblock.fission_reactor.height", + new TextComponentTranslation(TextFormattingUtil.formatNumbers(this.height) + "m") + .setStyle(new Style().setColor(TextFormatting.YELLOW)))); + return list; + } + + @NotNull + protected IBlockState getVesselState() { + return SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.REACTOR_VESSEL); + } + + @NotNull + protected IBlockState getFuelChannelState() { + return SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.FUEL_CHANNEL); + } + + @NotNull + protected IBlockState getControlRodChannelState() { + return SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.CONTROL_ROD_CHANNEL); + } + + @NotNull + IBlockState getCoolantChannelState() { + return SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.COOLANT_CHANNEL); + } + + @Override + public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) { + return SusyTextures.FISSION_REACTOR_TEXTURE; + } + + @SideOnly(Side.CLIENT) + @NotNull + @Override + protected ICubeRenderer getFrontOverlay() { + return SusyTextures.FISSION_REACTOR_OVERLAY; + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + + this.getFrontOverlay().renderOrientedState(renderState, translation, pipeline, getFrontFacing(), isActive(), + true); + } + + @Override + public boolean isActive() { + return isStructureFormed() && lockingState == LockingState.LOCKED; + } + + @Override + public void checkStructurePattern() { + if (!this.isStructureFormed()) { + reinitializeStructurePattern(); + } + super.checkStructurePattern(); + } + + @Override + public void invalidateStructure() { + this.unlockAll(); + this.fissionReactor = null; + this.temperature = 273; + this.maxTemperature = 273; + this.power = 0; + this.kEff = 0; + this.pressure = 0; + this.maxPressure = 0; + this.maxPower = 0; + super.invalidateStructure(); + } + + @Override + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + if (fissionReactor == null) { + fissionReactor = new FissionReactor(this.diameter - 2, this.height - 2, controlRodInsertionValue); + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + data.setInteger("diameter", this.diameter); + data.setInteger("heightTop", this.heightTop); + data.setInteger("heightBottom", this.heightBottom); + data.setInteger("flowRate", this.flowRate); + data.setDouble("controlRodInsertion", this.controlRodInsertionValue); + data.setBoolean("locked", this.lockingState == LockingState.LOCKED); + data.setDouble("kEff", this.kEff); + if (fissionReactor != null) { + data.setTag("transientData", this.fissionReactor.serializeNBT()); + } + + return super.writeToNBT(data); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.diameter = data.getInteger("diameter"); + this.heightTop = data.getInteger("heightTop"); + this.heightBottom = data.getInteger("heightBottom"); + this.flowRate = data.getInteger("flowRate"); + this.controlRodInsertionValue = data.getDouble("controlRodInsertion"); + this.height = this.heightTop + this.heightBottom + 1; + this.kEff = data.getDouble("kEff"); + if (data.getBoolean("locked")) { + this.lockingState = LockingState.SHOULD_LOCK; + } + if (data.hasKey("transientData")) { + transientData = data.getCompoundTag("transientData"); + } + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeInt(this.diameter); + buf.writeInt(this.heightTop); + buf.writeInt(this.heightBottom); + buf.writeInt(this.flowRate); + buf.writeDouble(this.controlRodInsertionValue); + if (this.lockingState == LockingState.SHOULD_LOCK) { + if (fissionReactor == null) { + this.fissionReactor = new FissionReactor(this.diameter - 2, this.height - 2, controlRodInsertionValue); + } + this.lockAndPrepareReactor(); + this.fissionReactor.deserializeNBT(transientData); + } + buf.writeBoolean(this.lockingState == LockingState.LOCKED); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.diameter = buf.readInt(); + this.heightTop = buf.readInt(); + this.heightBottom = buf.readInt(); + this.flowRate = buf.readInt(); + this.controlRodInsertionValue = buf.readDouble(); + if (buf.readBoolean()) { + this.lockingState = LockingState.LOCKED; + } + } + + public void syncReactorStats() { + this.temperature = this.fissionReactor.temperature; + this.maxTemperature = this.fissionReactor.maxTemperature; + this.pressure = this.fissionReactor.pressure; + this.maxPressure = this.fissionReactor.maxPressure; + this.power = this.fissionReactor.power; + this.maxPower = this.fissionReactor.maxPower; + this.kEff = this.fissionReactor.kEff; + this.controlRodInsertionValue = this.fissionReactor.controlRodInsertion; + this.fuelDepletionPercent = Math.max(0, this.fissionReactor.fuelDepletion) / + this.fissionReactor.maxFuelDepletion; + writeCustomData(SYNC_REACTOR_STATS, (packetBuffer -> { + packetBuffer.writeDouble(this.temperature); + packetBuffer.writeDouble(this.maxTemperature); + packetBuffer.writeDouble(this.pressure); + packetBuffer.writeDouble(this.maxPressure); + packetBuffer.writeDouble(this.power); + packetBuffer.writeDouble(this.maxPower); + packetBuffer.writeDouble(this.kEff); + packetBuffer.writeDouble(this.controlRodInsertionValue); + packetBuffer.writeDouble(this.fuelDepletionPercent); + })); + this.markDirty(); + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + + if (dataId == SYNC_REACTOR_STATS) { + this.temperature = buf.readDouble(); + this.maxTemperature = buf.readDouble(); + this.pressure = buf.readDouble(); + this.maxPressure = buf.readDouble(); + this.power = buf.readDouble(); + this.maxPower = buf.readDouble(); + this.kEff = buf.readDouble(); + this.controlRodInsertionValue = buf.readDouble(); + this.fuelDepletionPercent = buf.readDouble(); + } else if (dataId == SYNC_LOCKING_STATE) { + this.lockingState = buf.readEnumValue(LockingState.class); + this.scheduleRenderUpdate(); + } + } + + protected void lockAll() { + for (ICoolantHandler handler : this.getAbilities(SuSyMultiblockAbilities.IMPORT_COOLANT)) { + handler.setLock(true); + } + for (IFuelRodHandler handler : this.getAbilities(SuSyMultiblockAbilities.IMPORT_FUEL_ROD)) { + handler.setLock(true); + } + } + + protected void unlockAll() { + for (ICoolantHandler handler : this.getAbilities(SuSyMultiblockAbilities.IMPORT_COOLANT)) { + handler.setLock(false); + } + for (IFuelRodHandler handler : this.getAbilities(SuSyMultiblockAbilities.IMPORT_FUEL_ROD)) { + handler.setLock(false); + } + if (this.fissionReactor != null) { + this.fissionReactor.turnOff(); + } + if (this.lockingState == LockingState.LOCKED) { // Don't remove warnings + this.setLockingState(LockingState.UNLOCKED); + } + } + + private void lockAndPrepareReactor() { + this.lockAll(); + int radius = this.diameter / 2; // This is the floor of the radius, the actual radius is 0.5 blocks + // larger + BlockPos.MutableBlockPos reactorOrigin = new BlockPos.MutableBlockPos(this.getPos()); + reactorOrigin.move(this.frontFacing.getOpposite(), radius); + boolean foundFuel = false; + for (int i = -radius; i <= radius; i++) { + for (int j = -radius; j <= radius; j++) { + if (Math.pow(i, 2) + Math.pow(j, 2) > Math.pow(radius, 2) + radius) // (radius + .5)^2 = + // radius^2 + radius + .25 + continue; + BlockPos currentPos = reactorOrigin.offset(this.getRight(), i) + .offset(this.frontFacing.getOpposite(), j).offset(getUp(), heightTop); + if (getWorld().getTileEntity(currentPos) instanceof IGregTechTileEntity gtTe) { + MetaTileEntity mte = gtTe.getMetaTileEntity(); + if (mte instanceof ICoolantHandler coolantIn) { + Fluid lockedFluid = coolantIn.getLockedObject(); + if (lockedFluid != null) { + ICoolantStats stats = CoolantRegistry.getCoolant(lockedFluid); + if (stats != null) { + coolantIn.setCoolant(stats); + BlockPos exportHatchPos = currentPos.offset(coolantIn.getFrontFacing().getOpposite(), + height - 1); + if (getWorld().getTileEntity( + exportHatchPos) instanceof IGregTechTileEntity coolantOutCandidate) { + MetaTileEntity coolantOutMTE = coolantOutCandidate.getMetaTileEntity(); + if (coolantOutMTE instanceof MetaTileEntityCoolantExportHatch coolantOut) { + coolantOut.setCoolant(stats); + CoolantChannel component = new CoolantChannel(100050, 0, stats, 1000, coolantIn, + coolantOut); + fissionReactor.addComponent(component, i + radius - 1, j + radius - 1); + continue; + } + } + } + } + this.unlockAll(); + setLockingState(LockingState.MISSING_COOLANT); + return; + } else if (mte instanceof IFuelRodHandler fuelIn) { + ItemStack lockedFuel = fuelIn.getStackHandler().getStackInSlot(0); + if (!lockedFuel.isEmpty()) { + IFissionFuelStats stats = FissionFuelRegistry.getFissionFuel(lockedFuel); + if (stats != null) { + FuelRod component; + fuelIn.setFuel(stats); + foundFuel = true; + if (fissionReactor.fuelDepletion == 0 || fuelIn.getPartialFuel() == null) { + fuelIn.setPartialFuel(stats); + component = new FuelRod(stats.getMaxTemperature(), 1, stats, 650); + fuelIn.setInternalFuelRod(component); + } else { + // It's guaranteed to have this property (if the implementation is correct). + IFissionFuelStats partialProp = fuelIn.getPartialFuel(); + component = new FuelRod(partialProp.getMaxTemperature(), 1, partialProp, 650); + fuelIn.setInternalFuelRod(component); + } + fuelIn.setInternalFuelRod(component); + fissionReactor.addComponent(component, i + radius - 1, j + radius - 1); + continue; + } + } + this.unlockAll(); + setLockingState(LockingState.MISSING_FUEL); + return; + } else if (mte instanceof MetaTileEntityControlRodPort controlIn) { + ControlRod component = new ControlRod(100000, controlIn.hasModeratorTip(), 1, 800); + fissionReactor.addComponent(component, i + radius - 1, j + radius - 1); + } + } + } + } + if (!foundFuel) { + this.unlockAll(); + setLockingState(LockingState.NO_FUEL_CHANNELS); + return; + } + fissionReactor.prepareThermalProperties(); + fissionReactor.computeGeometry(); + setLockingState(LockingState.LOCKED); + } + + private void updateReactorState(int flowRate) { + this.fissionReactor.updatePower(); + this.fissionReactor.updateTemperature(flowRate); + this.fissionReactor.updatePressure(); + this.fissionReactor.updateNeutronPoisoning(); + this.fissionReactor.regulateControlRods(); + } + + protected void setLockingState(LockingState lockingState) { + if (this.lockingState != lockingState) { + writeCustomData(SYNC_LOCKING_STATE, (buf) -> buf.writeEnumValue(lockingState)); + } + this.lockingState = lockingState; + } + + @Override + public long getCoverCapacity() { + // power is in MW + return (long) (this.maxPower * 1e6); + } + + @Override + public long getCoverStored() { + // power is in MW + return (long) (this.power * 1e6); + } + + private enum LockingState { + // The reactor is locked + LOCKED, + // The reactor is unlocked + UNLOCKED, + // The reactor is supposed to be locked, but the locking logic is yet to run + SHOULD_LOCK, + // The reactor can't lock because it is missing fuel in a fuel channel + MISSING_FUEL, + // The reactor can't lock because it is missing coolant in a coolant channel + MISSING_COOLANT, + // The reactor can't lock because a fuel output is clogged + FUEL_CLOGGED, + // There are no fuel channels at all! + NO_FUEL_CHANNELS, + // The reactor can't lock because components are flagged as invalid + INVALID_COMPONENT + } + + @Override + public List getMatchingShapes() { + List shapes = new ArrayList<>(); + + for (int diameter = 5; diameter <= 15; diameter += 2) { + int radius = diameter % 2 == 0 ? (int) Math.floor(diameter / 2.f) : + Math.round((diameter - 1) / 2.f); + StringBuilder interiorBuilder = new StringBuilder(); + + String[] interiorSlice = new String[diameter]; + String[] controllerSlice; + String[] topSlice; + String[] bottomSlice; + + // First loop over the matrix + for (int i = 0; i < diameter; i++) { + for (int j = 0; j < diameter; j++) { + if (Math.pow(i - Math.floor(diameter / 2.), 2) + + Math.pow(j - Math.floor(diameter / 2.), 2) < + Math.pow(radius + 0.5f, 2)) { + interiorBuilder.append('A'); + } else { + interiorBuilder.append(' '); + } + } + + interiorSlice[i] = interiorBuilder.toString(); + interiorBuilder.setLength(0); + } + + // Second loop is to detect where to put walls, the controller and I/O + for (int i = 0; i < diameter; i++) { + for (int j = 0; j < diameter; j++) { + if (interiorSlice[i].charAt(j) != 'A') { + continue; + } + + int outerI = i + (int) Math.signum(i - (diameter / 2)); + + if (Math.pow(outerI - Math.floor(diameter / 2.), 2) + + Math.pow(j - Math.floor(diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = SuSyUtility.replace(interiorSlice[i], j, 'V'); + } + + int outerJ = j + (int) Math.signum(j - (diameter / 2)); + if (Math.pow(i - Math.floor(diameter / 2.), 2) + + Math.pow(outerJ - Math.floor(diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = SuSyUtility.replace(interiorSlice[i], j, 'V'); + } + } + } + + controllerSlice = interiorSlice.clone(); + topSlice = interiorSlice.clone(); + bottomSlice = interiorSlice.clone(); + controllerSlice[0] = controllerSlice[0].substring(0, (int) Math.floor(diameter / 2.)) + "SM" + + controllerSlice[0].substring((int) Math.floor(diameter / 2.) + 2); + + // Example hatches + controllerSlice[1] = controllerSlice[1].substring(0, (int) Math.floor(diameter / 2.) - 1) + "fff" + + controllerSlice[1].substring((int) Math.floor(diameter / 2.) + 2); + controllerSlice[2] = controllerSlice[2].substring(0, (int) Math.floor(diameter / 2.) - 1) + "fcf" + + controllerSlice[2].substring((int) Math.floor(diameter / 2.) + 2); + controllerSlice[3] = controllerSlice[3].substring(0, (int) Math.floor(diameter / 2.) - 1) + "frf" + + controllerSlice[3].substring((int) Math.floor(diameter / 2.) + 2); + + topSlice[1] = topSlice[1].substring(0, (int) Math.floor(diameter / 2.) - 1) + "eee" + + topSlice[1].substring((int) Math.floor(diameter / 2.) + 2); + topSlice[2] = topSlice[2].substring(0, (int) Math.floor(diameter / 2.) - 1) + "ebe" + + topSlice[2].substring((int) Math.floor(diameter / 2.) + 2); + topSlice[3] = topSlice[3].substring(0, (int) Math.floor(diameter / 2.) - 1) + "eqe" + + topSlice[3].substring((int) Math.floor(diameter / 2.) + 2); + + bottomSlice[1] = bottomSlice[1].substring(0, (int) Math.floor(diameter / 2.) - 1) + "ggg" + + bottomSlice[1].substring((int) Math.floor(diameter / 2.) + 2); + bottomSlice[2] = bottomSlice[2].substring(0, (int) Math.floor(diameter / 2.) - 1) + "gdg" + + bottomSlice[2].substring((int) Math.floor(diameter / 2.) + 2); + bottomSlice[3] = bottomSlice[3].substring(0, (int) Math.floor(diameter / 2.) - 1) + "gVg" + + bottomSlice[3].substring((int) Math.floor(diameter / 2.) + 2); + + for (int i = 0; i < diameter; i++) { + topSlice[i] = topSlice[i].replace('A', 'V'); + bottomSlice[i] = bottomSlice[i].replace('A', 'V'); + } + MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(/*TODO*/); + builder.aisle(topSlice); + for (int i = 0; i < heightBottom - 1; i++) { + builder.aisle(interiorSlice); + } + builder.aisle(controllerSlice); + for (int i = 0; i < heightTop - 1; i++) { + builder.aisle(interiorSlice); + } + builder.aisle(bottomSlice); + shapes.add(builder.where('S', SuSyMetaTileEntities.FISSION_REACTOR, EnumFacing.NORTH) + // A for interior components, which are air here + .where('A', Blocks.AIR.getDefaultState()) + // Technically a duplicate, but this just makes things easier + .where(' ', Blocks.AIR.getDefaultState()) + // I for the inputs on the top + .where('V', this.getVesselState()) + .where('f', this.getFuelChannelState()) + .where('c', this.getCoolantChannelState()) + .where('r', this.getControlRodChannelState()) + .where('e', SuSyMetaTileEntities.FUEL_ROD_INPUT, EnumFacing.UP) + .where('g', SuSyMetaTileEntities.FUEL_ROD_OUTPUT, EnumFacing.DOWN) + .where('b', SuSyMetaTileEntities.COOLANT_INPUT, EnumFacing.UP) + .where('d', SuSyMetaTileEntities.COOLANT_OUTPUT, EnumFacing.DOWN) + .where('q', SuSyMetaTileEntities.CONTROL_ROD, EnumFacing.UP) + .where('m', SuSyMetaTileEntities.CONTROL_ROD_MODERATED, EnumFacing.UP) + + // B for the vessel blocks on the walls + .where('M', () -> ConfigHolder.machines.enableMaintenance ? MetaTileEntities.MAINTENANCE_HATCH : + this.getVesselState(), EnumFacing.NORTH) + .build()); + } + return shapes; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.machine.fission_reactor.tooltip.1")); + tooltip.add(I18n.format("gregtech.machine.fission_reactor.tooltip.2")); + tooltip.add(I18n.format("gregtech.machine.fission_reactor.tooltip.3")); + } + + public double getMaxPower() { + return maxPower; + } + + public double getPower() { + return power; + } + + public double getMaxPressure() { + return maxPressure; + } + + public double getPressure() { + return pressure; + } + + public double getMaxTemperature() { + return maxTemperature; + } + + public double getTemperature() { + return temperature; + } + + public double getControlRodInsertion() { + return controlRodInsertionValue; + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/MetaTileEntitySpentFuelPool.java b/src/main/java/supersymmetry/common/metatileentities/multi/MetaTileEntitySpentFuelPool.java new file mode 100644 index 000000000..fbfd44202 --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/MetaTileEntitySpentFuelPool.java @@ -0,0 +1,101 @@ +package supersymmetry.common.metatileentities.multi; + +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.api.recipes.RecipeMaps; +import gregtech.client.renderer.ICubeRenderer; +import gregtech.client.renderer.texture.Textures; +import gregtech.common.blocks.BlockMetalCasing; +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import supersymmetry.api.recipes.SuSyRecipeMaps; +import supersymmetry.client.renderer.textures.SusyTextures; +import supersymmetry.common.blocks.BlockNuclearCasing; +import supersymmetry.common.blocks.SuSyBlocks; + +import java.util.List; + +import static gregtech.api.util.RelativeDirection.*; + +public class MetaTileEntitySpentFuelPool extends RecipeMapMultiblockController { + + public MetaTileEntitySpentFuelPool(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, SuSyRecipeMaps.SPENT_FUEL_POOL_RECIPES); + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntitySpentFuelPool(metaTileEntityId); + } + + @Override + public boolean hasMaintenanceMechanics() { + return false; + } + + @NotNull + @Override + protected BlockPattern createStructurePattern() { + return FactoryBlockPattern.start(FRONT, UP, RIGHT) + // spotless:off + .aisle("CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "TTTTTTTTTT") + .aisle("CCCCCCCCCC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CUUUUUUUUC", "S........T") + .aisle("CCCCCCCCCC", "CWRRRRRRWC", "CWRRRRRRWC", "CWRRRRRRWC", "CWRRRRRRWC", "CWRRRRRRWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CUUUUUUUUC", "T........T") + .setRepeatable(1, 10) + .aisle("CCCCCCCCCC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CWWWWWWWWC", "CUUUUUUUUC", "T........T") + .aisle("CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "CCCCCCCCCC", "TTTTTTTTTT") + //spotless:on + .where('S', selfPredicate()) + .where('.', any()) + .where('C', blocks(SuSyBlocks.PANELLING)) + .where('W', blocks(Blocks.WATER).or(blocks(Blocks.FLOWING_WATER))) + .where('U', blocks(Blocks.WATER)) + .where('R', states(getRodState())) + .where('T', states(getMetalCasingState()).or(autoAbilities(true, false, true, true, false, true, false))) + .build(); + } + + @Override + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + this.recipeMapWorkable.setParallelLimit(structurePattern.formedRepetitionCount[0] * 32); + } + + @Override + public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) { + return Textures.CLEAN_STAINLESS_STEEL_CASING; + } + + @NotNull + @Override + protected ICubeRenderer getFrontOverlay() { + return SusyTextures.SPENT_FUEL_POOL_OVERLAY; + } + + private IBlockState getRodState() { + return SuSyBlocks.NUCLEAR_CASING.getState(BlockNuclearCasing.NuclearCasingType.SPENT_FUEL_CASING); + } + + private IBlockState getMetalCasingState() { + return MetaBlocks.METAL_CASING.getState(BlockMetalCasing.MetalCasingType.STAINLESS_CLEAN); + } + + public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.tooltip.parallel", "32 per block of pool length")); + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/electric/MetaTileEntityGasCentrifuge.java b/src/main/java/supersymmetry/common/metatileentities/multi/electric/MetaTileEntityGasCentrifuge.java new file mode 100644 index 000000000..ca2cc024f --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/electric/MetaTileEntityGasCentrifuge.java @@ -0,0 +1,96 @@ +package supersymmetry.common.metatileentities.multi.electric; + +import gregtech.api.capability.impl.MultiblockRecipeLogic; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.client.renderer.ICubeRenderer; +import gregtech.client.renderer.texture.Textures; +import gregtech.common.blocks.BlockBoilerCasing; +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import supersymmetry.api.recipes.SuSyRecipeMaps; +import supersymmetry.client.renderer.textures.SusyTextures; +import supersymmetry.common.blocks.BlockGasCentrifugeCasing; +import supersymmetry.common.blocks.BlockNuclearCasing; +import supersymmetry.common.blocks.SuSyBlocks; + +import java.util.List; + +import static gregtech.api.util.RelativeDirection.*; + +public class MetaTileEntityGasCentrifuge extends RecipeMapMultiblockController { + + public MetaTileEntityGasCentrifuge(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, SuSyRecipeMaps.GAS_CENTRIFUGE_RECIPES); + this.recipeMapWorkable = new MultiblockRecipeLogic(this); + } + + @NotNull + @Override + protected BlockPattern createStructurePattern() { + return FactoryBlockPattern.start(FRONT, UP, RIGHT) + .aisle("SI", "HH", "CC", "CC", "CC", "CC", "CC") + .aisle("EE", "HH", "CC", "CC", "CC", "CC", "CC").setRepeatable(1, 14) + .aisle("OO", "HH", "CC", "CC", "CC", "CC", "CC") + .where('S', selfPredicate()) + .where('P', states(getPipeState())) + .where('H', states(getHeaterState())) + .where('C', states(getCentrifugeState())) + .where('I', states(getPipeState()).or(autoAbilities(false, false, false, false, true, false, false))) + .where('E', states(getPipeState()).or(autoAbilities(true, true, false, false, false, false, false))) + .where('O', states(getPipeState()).or(autoAbilities(false, false, false, false, false, true, false))) + .build(); + } + + @Override + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + this.recipeMapWorkable.setParallelLimit(structurePattern.formedRepetitionCount[0]); + } + + public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.tooltip.parallel", "1 + number of added columns")); + } + + @Override + public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) { + return Textures.INERT_PTFE_CASING; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityGasCentrifuge(metaTileEntityId); + } + + private IBlockState getPipeState() { + return MetaBlocks.BOILER_CASING.getState(BlockBoilerCasing.BoilerCasingType.POLYTETRAFLUOROETHYLENE_PIPE); + } + + private IBlockState getHeaterState() { + return SuSyBlocks.NUCLEAR_CASING.getState( + BlockNuclearCasing.NuclearCasingType.GAS_CENTRIFUGE_HEATER); + } + + private IBlockState getCentrifugeState() { + return SuSyBlocks.GAS_CENTRIFUGE_CASING + .getState(BlockGasCentrifugeCasing.GasCentrifugeCasingType.GAS_CENTRIFUGE_COLUMN); + } + + protected ICubeRenderer getFrontOverlay() { + return SusyTextures.GAS_CENTRIFUGE_OVERLAY; + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityControlRodPort.java b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityControlRodPort.java new file mode 100644 index 000000000..e30d9474c --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityControlRodPort.java @@ -0,0 +1,99 @@ +package supersymmetry.common.metatileentities.multi.multiblockpart; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import gregtech.api.gui.ModularUI; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.client.renderer.texture.Textures; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import supersymmetry.api.metatileentity.multiblock.IFissionReactorHatch; +import supersymmetry.api.metatileentity.multiblock.SuSyMultiblockAbilities; +import supersymmetry.client.renderer.textures.SusyTextures; +import supersymmetry.common.blocks.BlockFissionCasing; +import supersymmetry.common.blocks.SuSyBlocks; + +import java.util.List; + +public class MetaTileEntityControlRodPort extends MetaTileEntityMultiblockNotifiablePart + implements IFissionReactorHatch, + IMultiblockAbilityPart { + + private boolean hasModeratorTip; + + public MetaTileEntityControlRodPort(ResourceLocation metaTileEntityId, boolean hasModeratorTip) { + super(metaTileEntityId, 4, false); + this.hasModeratorTip = hasModeratorTip; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityControlRodPort(metaTileEntityId, hasModeratorTip); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return null; + } + + @Override + protected boolean openGUIOnRightClick() { + return false; + } + + @Override + public boolean checkValidity(int depth) { + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + for (int i = 1; i < depth; i++) { + if (getWorld().getBlockState(pos.move(this.frontFacing.getOpposite())) != + SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.CONTROL_ROD_CHANNEL)) { + return false; + } + } + return getWorld().getBlockState(pos.move(this.frontFacing.getOpposite())) == + SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.REACTOR_VESSEL); + } + + @Override + public MultiblockAbility getAbility() { + return SuSyMultiblockAbilities.CONTROL_ROD_PORT; + } + + @Override + public void registerAbilities(List abilityList) { + abilityList.add(this); + } + + public boolean hasModeratorTip() { + return hasModeratorTip; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format(this.getMetaName() + ".tooltip.1")); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + if (!this.hasModeratorTip) { + SusyTextures.CONTROL_ROD.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + SusyTextures.CONTROL_ROD_MODERATED.renderSided(getFrontFacing(), renderState, translation, pipeline); + } + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantExportHatch.java b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantExportHatch.java new file mode 100644 index 000000000..5c43c8ac9 --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantExportHatch.java @@ -0,0 +1,182 @@ +package supersymmetry.common.metatileentities.multi.multiblockpart; + +import gregtech.api.capability.IControllable; +import gregtech.api.capability.impl.FilteredItemHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.FluidContainerSlotWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.client.renderer.texture.Textures; + +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.NotNull; +import supersymmetry.api.capability.ICoolantHandler; +import supersymmetry.api.capability.impl.LockableFluidTank; +import supersymmetry.api.metatileentity.multiblock.IFissionReactorHatch; +import supersymmetry.api.metatileentity.multiblock.SuSyMultiblockAbilities; +import supersymmetry.api.nuclear.fission.ICoolantStats; + +import java.util.List; + +import static supersymmetry.api.nuclear.fission.FissionValues.FISSION_LOCK_UPDATE; + + +public class MetaTileEntityCoolantExportHatch extends MetaTileEntityMultiblockNotifiablePart + implements IMultiblockAbilityPart, ICoolantHandler, + IControllable, IFissionReactorHatch { + + private boolean workingEnabled; + private LockableFluidTank fluidTank; + private ICoolantStats coolant; + + public MetaTileEntityCoolantExportHatch(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, 4, true); + } + + @Override + public boolean isWorkingEnabled() { + return workingEnabled; + } + + @Override + public void setWorkingEnabled(boolean isWorkingAllowed) { + this.workingEnabled = isWorkingAllowed; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityCoolantExportHatch(metaTileEntityId); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return createTankUI(fluidTank, getMetaFullName(), entityPlayer).build(getHolder(), entityPlayer); + } + + public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, EntityPlayer entityPlayer) { + ModularUI.Builder builder = ModularUI.defaultBuilder(); + builder.image(7, 16, 81, 55, GuiTextures.DISPLAY); + TankWidget tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) + .setHideTooltip(true).setAlwaysShowFull(true); + builder.widget(tankWidget); + builder.label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF); + builder.dynamicLabel(11, 30, tankWidget::getFormattedFluidAmount, 0xFFFFFF); + builder.dynamicLabel(11, 40, tankWidget::getFluidLocalizedName, 0xFFFFFF); + return builder.label(6, 6, title) + .widget(new FluidContainerSlotWidget(importItems, 0, 90, 16, false) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.IN_SLOT_OVERLAY)) + .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) + .widget(new SlotWidget(exportItems, 0, 90, 53, true, false) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)) + .bindPlayerInventory(entityPlayer.inventory); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + if (shouldRenderOverlay()) { + Textures.PIPE_OUT_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + Textures.FLUID_HATCH_OUTPUT_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + } + } + + @Override + public boolean checkValidity(int depth) { + // Export ports are always considered valid + return true; + } + + @Override + public void setLock(boolean isLocked) { + fluidTank.setLock(isLocked); + writeCustomData(FISSION_LOCK_UPDATE, (packetBuffer -> packetBuffer.writeBoolean(isLocked))); + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == FISSION_LOCK_UPDATE) { + this.fluidTank.setLock(buf.readBoolean()); + } + } + + @Override + public boolean isLocked() { + return fluidTank.isLocked(); + } + + @Override + public Fluid getLockedObject() { + return fluidTank.getLockedObject(); + } + + @Override + public ICoolantStats getCoolant() { + return this.coolant; + } + + @Override + public void setCoolant(ICoolantStats prop) { + this.coolant = prop; + } + + @Override + public @NotNull LockableFluidTank getFluidTank() { + return this.fluidTank; + } + + @Override + public MultiblockAbility getAbility() { + return SuSyMultiblockAbilities.EXPORT_COOLANT; + } + + @Override + public void registerAbilities(List abilityList) { + abilityList.add(this); + } + + @Override + protected IItemHandlerModifiable createImportItemHandler() { + return new FilteredItemHandler(this).setFillPredicate( + FilteredItemHandler.getCapabilityFilter(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY)); + } + + @Override + protected IItemHandlerModifiable createExportItemHandler() { + return new ItemStackHandler(1); + } + + @Override + protected FluidTankList createExportFluidHandler() { + this.fluidTank = new LockableFluidTank(16000, this, true); + return new FluidTankList(false, fluidTank); + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote) { + fillContainerFromInternalTank(fluidTank); + pushFluidsIntoNearbyHandlers(getFrontFacing()); + } + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantImportHatch.java b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantImportHatch.java new file mode 100644 index 000000000..a8e65d73a --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantImportHatch.java @@ -0,0 +1,220 @@ +package supersymmetry.common.metatileentities.multi.multiblockpart; + +import gregtech.api.capability.IControllable; +import gregtech.api.capability.impl.FilteredItemHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.FluidContainerSlotWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.client.renderer.texture.Textures; + +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import supersymmetry.api.capability.ICoolantHandler; +import supersymmetry.api.capability.impl.LockableFluidTank; +import supersymmetry.api.metatileentity.multiblock.IFissionReactorHatch; +import supersymmetry.api.metatileentity.multiblock.SuSyMultiblockAbilities; +import supersymmetry.api.nuclear.fission.ICoolantStats; +import supersymmetry.common.blocks.BlockFissionCasing; +import supersymmetry.common.blocks.SuSyBlocks; +import supersymmetry.common.metatileentities.SuSyMetaTileEntities; + +import java.util.List; + +import static supersymmetry.api.nuclear.fission.FissionValues.FISSION_LOCK_UPDATE; + + +public class MetaTileEntityCoolantImportHatch extends MetaTileEntityMultiblockNotifiablePart + implements IMultiblockAbilityPart, ICoolantHandler, + IControllable, IFissionReactorHatch { + + private boolean workingEnabled; + private LockableFluidTank fluidTank; + private ICoolantStats coolant; + + public MetaTileEntityCoolantImportHatch(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, 4, false); + } + + @Override + protected FluidTankList createImportFluidHandler() { + this.fluidTank = new LockableFluidTank(16000, this, false); + return new FluidTankList(false, fluidTank); + } + + @Override + public boolean isWorkingEnabled() { + return workingEnabled; + } + + @Override + public void setWorkingEnabled(boolean isWorkingAllowed) { + this.workingEnabled = isWorkingAllowed; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityCoolantImportHatch(metaTileEntityId); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return createTankUI(fluidTank, getMetaFullName(), entityPlayer).build(getHolder(), entityPlayer); + } + + public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, EntityPlayer entityPlayer) { + ModularUI.Builder builder = ModularUI.defaultBuilder(); + builder.image(7, 16, 131, 55, GuiTextures.DISPLAY); + TankWidget tankWidget = new TankWidget(fluidTank, 119, 52, 18, 18) + .setHideTooltip(true).setAlwaysShowFull(true); + builder.widget(tankWidget); + builder.label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF); + builder.dynamicLabel(11, 30, tankWidget::getFormattedFluidAmount, 0xFFFFFF); + builder.dynamicLabel(11, 40, () -> { + if (isLocked()) { + return tankWidget.getFluidLocalizedName() + " " + I18n.format("gregtech.gui.locked"); + } else { + return tankWidget.getFluidLocalizedName(); + } + }, 0xFFFFFF); + return builder.label(6, 6, title) + .widget(new FluidContainerSlotWidget(importItems, 0, 140, 16, false) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.IN_SLOT_OVERLAY)) + .widget(new ImageWidget(141, 36, 14, 15, GuiTextures.TANK_ICON)) + .widget(new SlotWidget(exportItems, 0, 140, 53, true, false) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)) + .bindPlayerInventory(entityPlayer.inventory); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + if (shouldRenderOverlay()) { + Textures.PIPE_IN_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + Textures.FLUID_HATCH_INPUT_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + } + } + + @Override + public boolean checkValidity(int depth) { + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + for (int i = 1; i < depth; i++) { + if (getWorld().getBlockState(pos.move(this.frontFacing.getOpposite())) != + SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.COOLANT_CHANNEL)) { + return false; + } + } + if (getWorld() + .getTileEntity(pos.move(this.frontFacing.getOpposite())) instanceof IGregTechTileEntity gtTe) { + return gtTe.getMetaTileEntity().metaTileEntityId.equals(SuSyMetaTileEntities.COOLANT_OUTPUT.metaTileEntityId); + } + return false; + } + + @Override + public MultiblockAbility getAbility() { + return SuSyMultiblockAbilities.IMPORT_COOLANT; + } + + @Override + public void registerAbilities(List abilityList) { + abilityList.add(this); + } + + @Override + protected IItemHandlerModifiable createImportItemHandler() { + return new FilteredItemHandler(this).setFillPredicate( + FilteredItemHandler.getCapabilityFilter(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY)); + } + + @Override + protected IItemHandlerModifiable createExportItemHandler() { + return new ItemStackHandler(1); + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote) { + fillContainerFromInternalTank(fluidTank); + fillInternalTankFromFluidContainer(fluidTank); + pullFluidsFromNearbyHandlers(getFrontFacing()); + } + } + + @Override + public void setLock(boolean isLocked) { + fluidTank.setLock(isLocked); + writeCustomData(FISSION_LOCK_UPDATE, (packetBuffer -> packetBuffer.writeBoolean(isLocked))); + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == FISSION_LOCK_UPDATE) { + fluidTank.setLock(buf.readBoolean()); + } + } + + @Override + public boolean isLocked() { + return fluidTank.isLocked(); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + } + + @Override + public ICoolantStats getCoolant() { + return this.coolant; + } + + @Override + public void setCoolant(ICoolantStats prop) { + this.coolant = prop; + } + + @Override + public @NotNull LockableFluidTank getFluidTank() { + return this.fluidTank; + } + + @Override + public Fluid getLockedObject() { + return fluidTank.getLockedObject(); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.machine.nuclear.locking.fluid")); + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodExportBus.java b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodExportBus.java new file mode 100644 index 000000000..8128a4a67 --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodExportBus.java @@ -0,0 +1,108 @@ +package supersymmetry.common.metatileentities.multi.multiblockpart; + +import gregtech.api.capability.IControllable; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.client.renderer.texture.Textures; + +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import supersymmetry.api.metatileentity.multiblock.IFissionReactorHatch; +import supersymmetry.api.metatileentity.multiblock.SuSyMultiblockAbilities; + +import java.util.List; + +public class MetaTileEntityFuelRodExportBus extends MetaTileEntityMultiblockNotifiablePart + implements IMultiblockAbilityPart, IControllable, + IFissionReactorHatch { + + private boolean workingEnabled; + + public MetaTileEntityFuelRodExportBus(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, 4, true); + } + + @Override + public boolean isWorkingEnabled() { + return workingEnabled; + } + + @Override + public void setWorkingEnabled(boolean isWorkingAllowed) { + this.workingEnabled = isWorkingAllowed; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityFuelRodExportBus(metaTileEntityId); + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && getOffsetTimer() % 5 == 0) { + pushItemsIntoNearbyHandlers(getFrontFacing()); + } + } + + @Override + protected IItemHandlerModifiable createExportItemHandler() { + return new ItemStackHandler(1); + } + + @Override + protected IItemHandlerModifiable createImportItemHandler() { + return new ItemStackHandler(1); + } + + private ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 143) + .label(10, 5, getMetaFullName()); + + builder.widget(new SlotWidget(exportItems, 0, 79, 18, true, false) + .setBackgroundTexture(GuiTextures.SLOT)); + + return builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 60); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return createUITemplate(entityPlayer).build(getHolder(), entityPlayer); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + if (shouldRenderOverlay()) { + Textures.PIPE_OUT_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + Textures.ITEM_HATCH_OUTPUT_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + } + } + + @Override + public MultiblockAbility getAbility() { + return SuSyMultiblockAbilities.EXPORT_FUEL_ROD; + } + + @Override + public void registerAbilities(List abilityList) { + abilityList.add(this.exportItems); + } + + @Override + public boolean checkValidity(int depth) { + return true; + } +} diff --git a/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodImportBus.java b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodImportBus.java new file mode 100644 index 000000000..c5f7a5dd7 --- /dev/null +++ b/src/main/java/supersymmetry/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodImportBus.java @@ -0,0 +1,255 @@ +package supersymmetry.common.metatileentities.multi.multiblockpart; + +import gregtech.api.capability.IControllable; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.BlockableSlotWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.client.renderer.texture.Textures; + +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import supersymmetry.api.capability.IFuelRodHandler; +import supersymmetry.api.items.itemhandlers.LockableItemStackHandler; +import supersymmetry.api.metatileentity.multiblock.IFissionReactorHatch; +import supersymmetry.api.metatileentity.multiblock.SuSyMultiblockAbilities; +import supersymmetry.api.nuclear.fission.FissionFuelRegistry; +import supersymmetry.api.nuclear.fission.IFissionFuelStats; +import supersymmetry.api.nuclear.fission.components.FuelRod; +import supersymmetry.common.blocks.BlockFissionCasing; +import supersymmetry.common.blocks.SuSyBlocks; + +import java.io.IOException; +import java.util.List; + +import static supersymmetry.api.nuclear.fission.FissionValues.FISSION_LOCK_UPDATE; + + +public class MetaTileEntityFuelRodImportBus extends MetaTileEntityMultiblockNotifiablePart + implements IMultiblockAbilityPart, IFuelRodHandler, + IControllable, IFissionReactorHatch { + + private boolean workingEnabled; + private IFissionFuelStats fuelProperty; + public MetaTileEntityFuelRodExportBus pairedHatch; + private IFissionFuelStats partialFuel; + private FuelRod internalFuelRod; + + public MetaTileEntityFuelRodImportBus(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, 4, false); + } + + @Override + public boolean isWorkingEnabled() { + return workingEnabled; + } + + @Override + public void setWorkingEnabled(boolean isWorkingAllowed) { + this.workingEnabled = isWorkingAllowed; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityFuelRodImportBus(metaTileEntityId); + } + + @Override + protected IItemHandlerModifiable createExportItemHandler() { + return new ItemStackHandler(1); + } + + @Override + protected IItemHandlerModifiable createImportItemHandler() { + return new LockableItemStackHandler(this, false); + } + + private ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 143).label(10, 5, getMetaFullName()); + + builder.widget(new BlockableSlotWidget(importItems, 0, 79, 18, true, true) + .setIsBlocked(this::isLocked).setBackgroundTexture(GuiTextures.SLOT)); + + return builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 60); + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && getOffsetTimer() % 5 == 0) { + pullItemsFromNearbyHandlers(getFrontFacing()); + } + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return createUITemplate(entityPlayer).build(getHolder(), entityPlayer); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + if (shouldRenderOverlay()) { + Textures.PIPE_IN_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + Textures.ITEM_HATCH_INPUT_OVERLAY.renderSided(getFrontFacing(), renderState, translation, pipeline); + } + } + + @Override + public MultiblockAbility getAbility() { + return SuSyMultiblockAbilities.IMPORT_FUEL_ROD; + } + + @Override + public void registerAbilities(List abilityList) { + abilityList.add(this); + } + + @Override + public boolean checkValidity(int depth) { + this.pairedHatch = getExportHatch(depth); + return pairedHatch != null; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + getLockedImport().setLock(data.getBoolean("locked")); + if (data.hasKey("partialFuel")) { + this.partialFuel = FissionFuelRegistry.getFissionFuel(data.getString("partialFuel")); + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + data.setBoolean("locked", getLockedImport().isLocked()); + if (partialFuel != null) data.setString("partialFuel", this.partialFuel.getID()); + return super.writeToNBT(data); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeItemStack(getLockedImport().getStackInSlot(0)); + buf.writeBoolean(getLockedImport().isLocked()); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + try { + getLockedImport().setStackInSlot(0, buf.readItemStack()); + } catch (IOException e) { // ignored + } + getLockedImport().setLock(buf.readBoolean()); + } + + private LockableItemStackHandler getLockedImport() { + return (LockableItemStackHandler) importItems; + } + + @Override + public void setLock(boolean isLocked) { + getLockedImport().setLock(isLocked); + writeCustomData(FISSION_LOCK_UPDATE, (packetBuffer -> { + packetBuffer.writeBoolean(isLocked); + })); + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == FISSION_LOCK_UPDATE) { + getLockedImport().setLock(buf.readBoolean()); + } + } + + @Override + public boolean isLocked() { + return getLockedImport().isLocked(); + } + + @Override + public ItemStack getLockedObject() { + return getLockedImport().getLockedObject(); + } + + @Override + public IFissionFuelStats getFuel() { + return this.fuelProperty; + } + + @Override + public void setFuel(IFissionFuelStats prop) { + this.fuelProperty = prop; + } + + @Override + public IFissionFuelStats getPartialFuel() { + return this.partialFuel; + } + + @Override + public boolean setPartialFuel(IFissionFuelStats prop) { + if (prop == this.partialFuel) { + return false; + } + this.partialFuel = prop; + if (this.internalFuelRod != null) { + this.internalFuelRod.setFuel(prop); + } + return true; + } + + @Override + public void setInternalFuelRod(FuelRod rod) { + this.internalFuelRod = rod; + } + + @Override + public LockableItemStackHandler getStackHandler() { + return this.getLockedImport(); + } + + public MetaTileEntityFuelRodExportBus getExportHatch(int depth) { + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); + for (int i = 1; i < depth; i++) { + if (getWorld().getBlockState(pos.move(this.frontFacing.getOpposite())) != + SuSyBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.FUEL_CHANNEL)) { + return null; + } + } + if (getWorld().getTileEntity(pos.move(this.frontFacing.getOpposite())) instanceof IGregTechTileEntity gtTe) { + MetaTileEntity mte = gtTe.getMetaTileEntity(); + if (mte instanceof MetaTileEntityFuelRodExportBus) { + return (MetaTileEntityFuelRodExportBus) mte; + } + } + return null; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.machine.nuclear.locking.item")); + } +} diff --git a/src/main/java/supersymmetry/integration/jei/basic/CoolantCategory.java b/src/main/java/supersymmetry/integration/jei/basic/CoolantCategory.java new file mode 100644 index 000000000..9da0d292a --- /dev/null +++ b/src/main/java/supersymmetry/integration/jei/basic/CoolantCategory.java @@ -0,0 +1,61 @@ +package supersymmetry.integration.jei.basic; + +import gregtech.api.gui.GuiTextures; +import gregtech.common.metatileentities.MetaTileEntities; + +import gregtech.integration.jei.basic.BasicRecipeCategory; +import net.minecraft.client.Minecraft; + +import mezz.jei.api.IGuiHelper; +import mezz.jei.api.gui.IDrawable; +import mezz.jei.api.gui.IGuiFluidStackGroup; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.recipe.IRecipeWrapper; +import org.jetbrains.annotations.Nullable; +import supersymmetry.common.metatileentities.SuSyMetaTileEntities; + +public class CoolantCategory extends BasicRecipeCategory { + + private final IDrawable icon; + protected final IDrawable slot; + private final IDrawable arrow; + + public CoolantCategory(IGuiHelper guiHelper) { + super("coolant", "fission.coolant.name", guiHelper.createBlankDrawable(176, 90), guiHelper); + + this.icon = guiHelper.createDrawableIngredient(SuSyMetaTileEntities.FISSION_REACTOR.getStackForm()); + this.slot = guiHelper.drawableBuilder(GuiTextures.SLOT.imageLocation, 0, 0, 18, 18).setTextureSize(18, 18) + .build(); + this.arrow = guiHelper.drawableBuilder(GuiTextures.PROGRESS_BAR_ARROW.imageLocation, 0, 20, 20, 20) + .setTextureSize(20, 40).build(); + } + + @Nullable + @Override + public IDrawable getIcon() { + return this.icon; + } + + @Override + public void setRecipe(IRecipeLayout recipeLayout, CoolantInfo recipeWrapper, IIngredients ingredients) { + IGuiFluidStackGroup fluidStackGroup = recipeLayout.getFluidStacks(); + + fluidStackGroup.init(0, true, 55, 9); + fluidStackGroup.set(0, recipeWrapper.coolant); + fluidStackGroup.init(1, true, 105, 9); + fluidStackGroup.set(1, recipeWrapper.hotCoolant); + } + + @Override + public void drawExtras(Minecraft minecraft) { + slot.draw(minecraft, 54, 8); + slot.draw(minecraft, 104, 8); + arrow.draw(minecraft, 77, 6); + } + + @Override + public IRecipeWrapper getRecipeWrapper(CoolantInfo recipe) { + return recipe; + } +} diff --git a/src/main/java/supersymmetry/integration/jei/basic/CoolantInfo.java b/src/main/java/supersymmetry/integration/jei/basic/CoolantInfo.java new file mode 100644 index 000000000..e88b093cf --- /dev/null +++ b/src/main/java/supersymmetry/integration/jei/basic/CoolantInfo.java @@ -0,0 +1,70 @@ +package supersymmetry.integration.jei.basic; + + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.ingredients.VanillaTypes; +import mezz.jei.api.recipe.IRecipeWrapper; +import supersymmetry.api.nuclear.fission.CoolantRegistry; +import supersymmetry.api.nuclear.fission.ICoolantStats; + +public class CoolantInfo implements IRecipeWrapper { + + public FluidStack coolant; + public FluidStack hotCoolant; + + private String temps; + private String heatCapacity; + private String heatTransfer; + private String moderation; + private String hydrogen; + + public CoolantInfo(Fluid coolant, Fluid hotCoolant) { + this.coolant = new FluidStack(coolant, 1000); + this.hotCoolant = new FluidStack(hotCoolant, 1000); + + ICoolantStats stats = CoolantRegistry.getCoolant(this.coolant.getFluid()); + + temps = I18n.format("gregtech.coolant.exit_temp", + stats.getHotCoolant().getTemperature()); + heatCapacity = I18n.format("gregtech.coolant.heat_capacity", + stats.getSpecificHeatCapacity()); + heatTransfer = I18n.format(I18n.format("gregtech.coolant.cooling_factor", + stats.getCoolingFactor())); + moderation = I18n.format("gregtech.coolant.moderation_factor", + stats.getModeratorFactor()); + if (stats.accumulatesHydrogen()) { + hydrogen = I18n.format("gregtech.coolant.accumulates_hydrogen"); + } + } + + @Override + public void getIngredients(IIngredients ingredients) { + ingredients.setInput(VanillaTypes.FLUID, coolant); + ingredients.setOutput(VanillaTypes.FLUID, hotCoolant); + } + + @Override + public void drawInfo(Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY) { + int fontHeight = Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT; + + int start = 40; + int linesDrawn = 0; + minecraft.fontRenderer.drawString(temps, 0, fontHeight * linesDrawn + start, 0x111111); + linesDrawn++; + minecraft.fontRenderer.drawString(heatCapacity, 0, fontHeight * linesDrawn + start, 0x111111); + linesDrawn++; + minecraft.fontRenderer.drawString(heatTransfer, 0, fontHeight * linesDrawn + start, 0x111111); + linesDrawn++; + minecraft.fontRenderer.drawString(moderation, 0, fontHeight * linesDrawn + start, 0x111111); + linesDrawn++; + + if (hydrogen != null) { + minecraft.fontRenderer.drawString(hydrogen, 0, fontHeight * linesDrawn + start, 0x111111); + } + } +} diff --git a/src/main/java/supersymmetry/integration/jei/basic/FissionFuelCategory.java b/src/main/java/supersymmetry/integration/jei/basic/FissionFuelCategory.java new file mode 100644 index 000000000..307596836 --- /dev/null +++ b/src/main/java/supersymmetry/integration/jei/basic/FissionFuelCategory.java @@ -0,0 +1,61 @@ +package supersymmetry.integration.jei.basic; + +import gregtech.api.gui.GuiTextures; +import gregtech.common.metatileentities.MetaTileEntities; + +import gregtech.integration.jei.basic.BasicRecipeCategory; +import net.minecraft.client.Minecraft; + +import mezz.jei.api.IGuiHelper; +import mezz.jei.api.gui.IDrawable; +import mezz.jei.api.gui.IGuiItemStackGroup; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.recipe.IRecipeWrapper; +import org.jetbrains.annotations.Nullable; +import supersymmetry.common.metatileentities.SuSyMetaTileEntities; + +public class FissionFuelCategory extends BasicRecipeCategory { + + private final IDrawable icon; + protected final IDrawable slot; + private final IDrawable arrow; + + public FissionFuelCategory(IGuiHelper guiHelper) { + super("fission_fuel", "fission.fuel.name", guiHelper.createBlankDrawable(176, 90), guiHelper); + + this.icon = guiHelper.createDrawableIngredient(SuSyMetaTileEntities.FISSION_REACTOR.getStackForm()); + this.slot = guiHelper.drawableBuilder(GuiTextures.SLOT.imageLocation, 0, 0, 18, 18).setTextureSize(18, 18) + .build(); + this.arrow = guiHelper.drawableBuilder(GuiTextures.PROGRESS_BAR_ARROW.imageLocation, 0, 20, 20, 20) + .setTextureSize(20, 40).build(); + } + + @Nullable + @Override + public IDrawable getIcon() { + return this.icon; + } + + @Override + public void setRecipe(IRecipeLayout recipeLayout, FissionFuelInfo recipeWrapper, IIngredients ingredients) { + IGuiItemStackGroup itemStackGroup = recipeLayout.getItemStacks(); + + itemStackGroup.init(0, true, 54, 8); + itemStackGroup.set(0, recipeWrapper.rod); + itemStackGroup.init(1, true, 104, 8); + itemStackGroup.set(1, recipeWrapper.depletedRod); + } + + @Override + public void drawExtras(Minecraft minecraft) { + slot.draw(minecraft, 54, 8); + slot.draw(minecraft, 104, 8); + arrow.draw(minecraft, 77, 6); + } + + @Override + public IRecipeWrapper getRecipeWrapper(FissionFuelInfo recipe) { + return recipe; + } +} diff --git a/src/main/java/supersymmetry/integration/jei/basic/FissionFuelInfo.java b/src/main/java/supersymmetry/integration/jei/basic/FissionFuelInfo.java new file mode 100644 index 000000000..6731245fa --- /dev/null +++ b/src/main/java/supersymmetry/integration/jei/basic/FissionFuelInfo.java @@ -0,0 +1,64 @@ +package supersymmetry.integration.jei.basic; + + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; + +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.ingredients.VanillaTypes; +import mezz.jei.api.recipe.IRecipeWrapper; +import supersymmetry.api.nuclear.fission.FissionFuelRegistry; +import supersymmetry.api.nuclear.fission.IFissionFuelStats; + +public class FissionFuelInfo implements IRecipeWrapper { + + public ItemStack rod; + public ItemStack depletedRod; + + private String duration; + private String maxTemp; + private String crossSectionFast; + private String crossSectionSlow; + private String neutronGenerationTime; + + public FissionFuelInfo(ItemStack rod, ItemStack depletedRod) { + this.rod = rod; + this.depletedRod = depletedRod; + + IFissionFuelStats prop = FissionFuelRegistry.getFissionFuel(rod); + + duration = I18n.format("metaitem.nuclear.tooltip.duration", prop.getDuration()); + maxTemp = I18n.format("metaitem.nuclear.tooltip.temperature", prop.getMaxTemperature()); + crossSectionFast = I18n.format("metaitem.nuclear.tooltip.cross_section_fast", + prop.getFastNeutronFissionCrossSection()); + crossSectionSlow = I18n.format("metaitem.nuclear.tooltip.cross_section_slow", + prop.getSlowNeutronFissionCrossSection()); + neutronGenerationTime = I18n.format( + "metaitem.nuclear.tooltip.neutron_time." + prop.getNeutronGenerationTimeCategory(), + prop.getNeutronGenerationTime()); + } + + @Override + public void getIngredients(IIngredients ingredients) { + ingredients.setInput(VanillaTypes.ITEM, rod); + ingredients.setOutput(VanillaTypes.ITEM, depletedRod); + } + + @Override + public void drawInfo(Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY) { + int fontHeight = Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT; + + int start = 40; + int linesDrawn = 0; + minecraft.fontRenderer.drawString(duration, 0, start, 0x111111); + linesDrawn++; + minecraft.fontRenderer.drawString(maxTemp, 0, fontHeight * linesDrawn + start, 0x111111); + linesDrawn++; + minecraft.fontRenderer.drawString(crossSectionFast, 0, fontHeight * linesDrawn + start, 0x111111); + linesDrawn++; + minecraft.fontRenderer.drawString(crossSectionSlow, 0, fontHeight * linesDrawn + start, 0x111111); + linesDrawn++; + minecraft.fontRenderer.drawString(neutronGenerationTime, 0, fontHeight * linesDrawn + start, 0x111111); + } +} diff --git a/src/main/java/supersymmetry/integration/opencomputers/drivers/specific/DriverFissionReactor.java b/src/main/java/supersymmetry/integration/opencomputers/drivers/specific/DriverFissionReactor.java new file mode 100644 index 000000000..339fd0a37 --- /dev/null +++ b/src/main/java/supersymmetry/integration/opencomputers/drivers/specific/DriverFissionReactor.java @@ -0,0 +1,103 @@ +package supersymmetry.integration.opencomputers.drivers.specific; + +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; + +import gregtech.integration.opencomputers.drivers.EnvironmentMetaTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +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.ManagedEnvironment; +import li.cil.oc.api.prefab.DriverSidedTileEntity; +import supersymmetry.common.metatileentities.multi.MetaTileEntityFissionReactor; + +public class DriverFissionReactor extends DriverSidedTileEntity { + + @Override + public Class getTileEntityClass() { + return MetaTileEntityFissionReactor.class; + } + + @Override + public boolean worksWith(World world, BlockPos pos, EnumFacing side) { + TileEntity tileEntity = world.getTileEntity(pos); + if (tileEntity instanceof IGregTechTileEntity) { + return ((IGregTechTileEntity) tileEntity).getMetaTileEntity() instanceof MetaTileEntityFissionReactor; + } + return false; + } + + @Override + public ManagedEnvironment createEnvironment(World world, BlockPos pos, EnumFacing side) { + TileEntity tileEntity = world.getTileEntity(pos); + if (tileEntity instanceof IGregTechTileEntity) { + return new EnvironmentFissionReactor((IGregTechTileEntity) tileEntity, + (MetaTileEntityFissionReactor) ((IGregTechTileEntity) tileEntity).getMetaTileEntity()); + } + return null; + } + + public final static class EnvironmentFissionReactor extends + EnvironmentMetaTileEntity { + + public EnvironmentFissionReactor(IGregTechTileEntity holder, MetaTileEntityFissionReactor tileEntity) { + super(holder, tileEntity, "gt_fissionReactor"); + } + + @Callback(doc = "function():number -- Returns the max power of the reactor, in MW.") + public Object[] getMaxPower(final Context context, final Arguments args) { + return new Object[] { tileEntity.getMaxPower() }; + } + + @Callback(doc = "function():number -- Returns the power of the reactor, in MW.") + public Object[] getPower(final Context context, final Arguments args) { + return new Object[] { tileEntity.getPower() }; + } + + @Callback(doc = "function():number -- Returns the max temperature of the reactor.") + public Object[] getMaxTemperature(final Context context, final Arguments args) { + return new Object[] { tileEntity.getMaxTemperature() }; + } + + @Callback(doc = "function():number -- Returns the temperature of the reactor.") + public Object[] getTemperature(final Context context, final Arguments args) { + return new Object[] { tileEntity.getTemperature() }; + } + + @Callback(doc = "function():number -- Returns the max pressure of the reactor, in pascals.") + public Object[] getMaxPressure(final Context context, final Arguments args) { + return new Object[] { tileEntity.getMaxPressure() }; + } + + @Callback(doc = "function():number -- Returns the pressure of the reactor, in pascals.") + public Object[] getPressure(final Context context, final Arguments args) { + return new Object[] { tileEntity.getPressure() }; + } + + @Callback(doc = "function():number -- Returns how much control rods are inserted, in [0, 1]") + public Object[] getControlRodInsertion(final Context context, final Arguments args) { + return new Object[] { tileEntity.getControlRodInsertion() }; + } + + @Callback(doc = "function(insertion:boolean) -- Sets how much control rods are inserted, in [0, 1]") + public Object[] setControlRodInsertion(final Context context, final Arguments args) { + tileEntity.setControlRodInsertionValue((float) args.checkDouble(0)); + return new Object[] {}; + } + + @Callback(doc = "function():boolean -- Returns whether smiley is regulating control rods.") + public Object[] getSmiley(final Context context, final Arguments args) { + return new Object[] { tileEntity.areControlRodsRegulated() }; + } + + @Callback(doc = "function(smiley:boolean) -- Pass in true to revive smiley, pass in false to kill smiley.") + public Object[] setSmiley(final Context context, final Arguments args) { + tileEntity.toggleControlRodRegulation(args.checkBoolean(0)); + return new Object[] {}; + } + } +} diff --git a/src/main/java/supersymmetry/loaders/recipe/handlers/FluidRecipeHandler.java b/src/main/java/supersymmetry/loaders/recipe/handlers/FluidRecipeHandler.java new file mode 100644 index 000000000..8d381ef1f --- /dev/null +++ b/src/main/java/supersymmetry/loaders/recipe/handlers/FluidRecipeHandler.java @@ -0,0 +1,55 @@ +package supersymmetry.loaders.recipe.handlers; + +import gregtech.api.GregTechAPI; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.Materials; +import supersymmetry.api.nuclear.fission.FissionValues; +import supersymmetry.api.recipes.SuSyRecipeMaps; +import supersymmetry.api.unification.material.properties.CoolantProperty; +import supersymmetry.api.unification.material.properties.SuSyPropertyKey; + +public class FluidRecipeHandler { + + public static void runRecipeGeneration() { + for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { + if (material.hasProperty(SuSyPropertyKey.COOLANT)) + processCoolant(material, material.getProperty(SuSyPropertyKey.COOLANT)); + } + } + + public static void processCoolant(Material mat, CoolantProperty coolant) { + int waterAmt = 6; + double multiplier = FissionValues.heatExchangerEfficiencyMultiplier; + + // water temp difference * water heat capacity * amount / coolantHeatCapacity * (hotHpTemp - coolantTemp) + int coolantAmt = (int) Math.ceil(100 * 4168 * waterAmt * multiplier / (coolant.getSpecificHeatCapacity() * + (coolant.getHotHPCoolant().getFluid().getTemperature() - mat.getFluid().getTemperature()))); + + SuSyRecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(1) + .fluidInputs(coolant.getHotHPCoolant().getFluid(coolantAmt), Materials.Water.getFluid(waterAmt)) + .fluidOutputs(mat.getFluid(coolantAmt), Materials.Steam.getFluid(waterAmt * 160)).buildAndRegister(); + + SuSyRecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(1) + .fluidInputs(coolant.getHotHPCoolant().getFluid(coolantAmt), + Materials.DistilledWater.getFluid(waterAmt)) + .fluidOutputs(mat.getFluid(coolantAmt), Materials.Steam.getFluid(waterAmt * 160)).buildAndRegister(); + waterAmt = 600; + // Slightly more efficient + coolantAmt = (int) Math.ceil(100 * 4168 * waterAmt * multiplier / (coolant.getSpecificHeatCapacity() * + (coolant.getHotHPCoolant().getFluid().getTemperature() - mat.getFluid().getTemperature())));; + + SuSyRecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(2) + .fluidInputs(coolant.getHotHPCoolant().getFluid(coolantAmt), Materials.Water.getFluid(waterAmt)) + .fluidOutputs(mat.getFluid(coolantAmt), Materials.Steam.getFluid(waterAmt * 160)).buildAndRegister(); + + SuSyRecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(2) + .fluidInputs(coolant.getHotHPCoolant().getFluid(coolantAmt), + Materials.DistilledWater.getFluid(waterAmt)) + .fluidOutputs(mat.getFluid(coolantAmt), Materials.Steam.getFluid(waterAmt * 160)).buildAndRegister(); + + // Radiator + SuSyRecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(10).circuitMeta(3) + .fluidInputs(coolant.getHotHPCoolant().getFluid(8000)).fluidOutputs(mat.getFluid(8000)) + .buildAndRegister(); + } +} diff --git a/src/main/java/supersymmetry/loaders/recipe/handlers/NuclearRecipeHandler.java b/src/main/java/supersymmetry/loaders/recipe/handlers/NuclearRecipeHandler.java new file mode 100644 index 000000000..7379a4b53 --- /dev/null +++ b/src/main/java/supersymmetry/loaders/recipe/handlers/NuclearRecipeHandler.java @@ -0,0 +1,48 @@ +package supersymmetry.loaders.recipe.handlers; + +import gregtech.api.unification.material.Material; +import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.items.MetaItems; +import supersymmetry.api.unification.material.properties.FissionFuelProperty; +import supersymmetry.api.unification.material.properties.SuSyPropertyKey; +import supersymmetry.api.unification.ore.SusyOrePrefix; +import supersymmetry.common.item.SuSyMetaItems; + +import static gregtech.api.GTValues.*; +import static gregtech.api.recipes.RecipeMaps.*; +import static gregtech.api.unification.ore.OrePrefix.*; +import static supersymmetry.api.recipes.SuSyRecipeMaps.SPENT_FUEL_POOL_RECIPES; +import static supersymmetry.api.unification.ore.SusyOrePrefix.*; + +public class NuclearRecipeHandler { + + public static void register() { + SusyOrePrefix.fuelRod.addProcessingHandler(SuSyPropertyKey.FISSION_FUEL, NuclearRecipeHandler::processFuelRod); + } + + private static void processFuelRod(OrePrefix orePrefix, Material material, FissionFuelProperty oreProperty) { + // This is fine, since it goes up to 320x parallel + SPENT_FUEL_POOL_RECIPES.recipeBuilder().duration(10000).EUt(20) + .input(fuelRodHotDepleted, material) + .output(fuelRodDepleted, material) + .buildAndRegister(); + + CANNER_RECIPES.recipeBuilder().duration(200).EUt(VA[HV]) + .input(fuelRodDepleted, material) + .output(SuSyMetaItems.FUEL_CLADDING) + .output(fuelPelletDepleted, material, 16) + .buildAndRegister(); + + FORMING_PRESS_RECIPES.recipeBuilder().duration(25).EUt(VA[EV]) + .input(dust, material, 1) + .notConsumable(MetaItems.SHAPE_MOLD_CYLINDER) + .output(fuelPellet, material) + .buildAndRegister(); + + CANNER_RECIPES.recipeBuilder().duration(300).EUt(VA[HV]) + .input(fuelPellet, material, 16) + .input(SuSyMetaItems.FUEL_CLADDING) + .output(fuelRod, material) + .buildAndRegister(); + } +} diff --git a/src/main/java/supersymmetry/mixins/gregtech/SliderWidgetAccessor.java b/src/main/java/supersymmetry/mixins/gregtech/SliderWidgetAccessor.java new file mode 100644 index 000000000..26c4f7181 --- /dev/null +++ b/src/main/java/supersymmetry/mixins/gregtech/SliderWidgetAccessor.java @@ -0,0 +1,40 @@ +package supersymmetry.mixins.gregtech; + +import gregtech.api.gui.resources.TextureArea; +import gregtech.api.gui.widgets.SliderWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(value = SliderWidget.class, remap = false) +public interface SliderWidgetAccessor { + + @Accessor("backgroundArea") + TextureArea getBackgroundArea(); + + @Accessor("sliderIcon") + TextureArea getSliderIcon(); + + @Accessor("sliderPosition") + float getSliderPosition(); + + @Accessor("sliderPosition") + void setSliderPosition(float sliderPosition); + + @Accessor("min") + float getMin(); + + @Accessor("max") + float getMax(); + + @Accessor("displayString") + String getDisplayString2(); + + @Accessor("displayString") + void setDisplayString2(String displayString); + + @Accessor("textColor") + int getTextColor(); + + @Accessor("sliderWidth") + int getSliderWidth(); +} diff --git a/src/main/resources/assets/gregtech/models/block/gas_centrifuge.json b/src/main/resources/assets/gregtech/models/block/gas_centrifuge.json new file mode 100644 index 000000000..39d000cbd --- /dev/null +++ b/src/main/resources/assets/gregtech/models/block/gas_centrifuge.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "credit": "Made with Blockbench", + "elements": [ + { + "from": [3, 0, 3], + "to": [13, 16, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 10, 16], "texture": "#0"}, + "east": {"uv": [0, 0, 10, 16], "texture": "#0"}, + "south": {"uv": [0, 0, 10, 16], "texture": "#0"}, + "west": {"uv": [0, 0, 10, 16], "texture": "#0"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#1"} + } + } + ] +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_bred_fuel.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_bred_fuel.json new file mode 100644 index 000000000..bddd04683 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_bred_fuel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/dust_bred_fuel" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_fission_byproduct.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_fission_byproduct.json new file mode 100644 index 000000000..795e4ca25 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_fission_byproduct.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/dust_fission_byproduct" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_spent_fuel.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_spent_fuel.json new file mode 100644 index 000000000..ad6dfae00 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_spent_fuel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/dust_spent_fuel" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet.json new file mode 100644 index 000000000..671278d88 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/fuel_pellet" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet_depleted.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet_depleted.json new file mode 100644 index 000000000..b0443d9a1 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet_depleted.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/fuel_pellet_depleted" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod.json new file mode 100644 index 000000000..bcc67cf2b --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/fuel_rod" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod_depleted.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod_depleted.json new file mode 100644 index 000000000..89eddf20f --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod_depleted.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/fuel_rod_depleted" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod_hot_depleted.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod_hot_depleted.json new file mode 100644 index 000000000..673ffcfdb --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_rod_hot_depleted.json @@ -0,0 +1,7 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/fuel_rod_hot_depleted", + "layer1": "gregtech:items/material_sets/dull/fuel_rod_hot_depleted_overlay" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/basket.anode.json b/src/main/resources/assets/gregtech/models/item/metaitems/basket.anode.json new file mode 100644 index 000000000..e62090d36 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/basket.anode.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/basket.anode" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/cladding.fuel.json b/src/main/resources/assets/gregtech/models/item/metaitems/cladding.fuel.json new file mode 100644 index 000000000..4365c94dc --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/cladding.fuel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/cladding.fuel" + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/fission/control_rod_channel_top.png b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/control_rod_channel_top.png new file mode 100644 index 000000000..60082d12d Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/control_rod_channel_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/fission/coolant_channel_top.png b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/coolant_channel_top.png new file mode 100644 index 000000000..2a06c4f1a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/coolant_channel_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/fission/fuel_channel_side.png b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/fuel_channel_side.png new file mode 100644 index 000000000..73a3ba6be Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/fuel_channel_side.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/fission/fuel_channel_top.png b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/fuel_channel_top.png new file mode 100644 index 000000000..3f11bf709 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/fuel_channel_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/fission/reactor_vessel.png b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/reactor_vessel.png new file mode 100644 index 000000000..9292cb867 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/fission/reactor_vessel.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_end.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_end.png new file mode 100644 index 000000000..abbd8bfbc Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_end.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_side.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_side.png new file mode 100644 index 000000000..b5bf39ba6 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_side.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_side_bloom.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_side_bloom.png new file mode 100644 index 000000000..9bbab3414 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_side_bloom.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_top.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_top.png new file mode 100644 index 000000000..6330cdea6 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_top_bloom.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_top_bloom.png new file mode 100644 index 000000000..36e65e7bd Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_heater_top_bloom.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_side.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_side.png new file mode 100644 index 000000000..e0e687c0a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/gas_centrifuge_side.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_empty_side.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_empty_side.png new file mode 100644 index 000000000..344dda81d Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_empty_side.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_empty_top.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_empty_top.png new file mode 100644 index 000000000..7cd9c07af Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_empty_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_side.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_side.png new file mode 100644 index 000000000..10b7d26f8 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_side.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_side_bloom.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_side_bloom.png new file mode 100644 index 000000000..7bed8529d Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_side_bloom.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_top.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_top.png new file mode 100644 index 000000000..a9d9df047 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_top_bloom.png b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_top_bloom.png new file mode 100644 index 000000000..d21358d75 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/nuclear/spent_fuel_casing_top_bloom.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/fluids/fluid.high_pressure_steam.png b/src/main/resources/assets/gregtech/textures/blocks/fluids/fluid.high_pressure_steam.png new file mode 100644 index 000000000..4ef78c9f0 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/fluids/fluid.high_pressure_steam.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/fluids/fluid.high_pressure_steam.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/fluids/fluid.high_pressure_steam.png.mcmeta new file mode 100644 index 000000000..dd1601946 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/fluids/fluid.high_pressure_steam.png.mcmeta @@ -0,0 +1,45 @@ +{ + "animation":{ + "frametime":1, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1 + ] + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front.png new file mode 100644 index 000000000..72bbef85a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active.png new file mode 100644 index 000000000..94a4416b1 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active_emissive.png new file mode 100644 index 000000000..822fa52e1 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_emissive.png new file mode 100644 index 000000000..00bcc3b51 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused.png new file mode 100644 index 000000000..8f139ba6a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused_emissive.png new file mode 100644 index 000000000..577f0815c Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front.png new file mode 100644 index 000000000..72bbef85a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_active.png new file mode 100644 index 000000000..94a4416b1 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_active_emissive.png new file mode 100644 index 000000000..822fa52e1 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_emissive.png new file mode 100644 index 000000000..00bcc3b51 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_paused.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_paused.png new file mode 100644 index 000000000..8f139ba6a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_paused.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_paused_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_paused_emissive.png new file mode 100644 index 000000000..577f0815c Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/gas_centrifuge/overlay_front_paused_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front.png new file mode 100644 index 000000000..72bbef85a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_active.png new file mode 100644 index 000000000..94a4416b1 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_active_emissive.png new file mode 100644 index 000000000..822fa52e1 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_emissive.png new file mode 100644 index 000000000..00bcc3b51 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_paused.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_paused.png new file mode 100644 index 000000000..8f139ba6a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_paused.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_paused_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_paused_emissive.png new file mode 100644 index 000000000..577f0815c Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/heat_exchanger/overlay_front_paused_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back.png new file mode 100644 index 000000000..a265b3bba Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_active.png new file mode 100644 index 000000000..cba59fa39 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_active_emissive.png new file mode 100644 index 000000000..19114daf4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_emissive.png new file mode 100644 index 000000000..19114daf4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_back_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front.png new file mode 100644 index 000000000..a265b3bba Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_active.png new file mode 100644 index 000000000..cba59fa39 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_active_emissive.png new file mode 100644 index 000000000..19114daf4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_emissive.png new file mode 100644 index 000000000..19114daf4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_front_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side.png new file mode 100644 index 000000000..c4d67c201 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_active.png new file mode 100644 index 000000000..6eb0165c3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_active_emissive.png new file mode 100644 index 000000000..19114daf4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_emissive.png new file mode 100644 index 000000000..19114daf4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_side_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top.png new file mode 100644 index 000000000..a00ea6ee4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_active.png new file mode 100644 index 000000000..8cace5651 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_active_emissive.png new file mode 100644 index 000000000..48b5a3c36 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_emissive.png new file mode 100644 index 000000000..4f2753163 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_paused.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_paused.png new file mode 100644 index 000000000..e8ab4a755 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_paused.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_paused_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_paused_emissive.png new file mode 100644 index 000000000..d1df3858b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/spent_fuel_pool/overlay_top_paused_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_control_rod.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_control_rod.png new file mode 100644 index 000000000..b4e043100 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_control_rod.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_control_rod_moderated.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_control_rod_moderated.png new file mode 100644 index 000000000..82f896544 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/machine/overlay_control_rod_moderated.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_black.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_black.png new file mode 100644 index 000000000..0ab0e5ca3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_black.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_black.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_black.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_black.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_blue.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_blue.png new file mode 100644 index 000000000..732a4a4a0 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_blue.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_blue.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_blue.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_blue.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_brown.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_brown.png new file mode 100644 index 000000000..e960139fe Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_brown.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_brown.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_brown.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_brown.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_cyan.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_cyan.png new file mode 100644 index 000000000..a843391ae Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_cyan.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_cyan.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_cyan.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_cyan.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_gray.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_gray.png new file mode 100644 index 000000000..1dda46682 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_gray.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_gray.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_gray.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_gray.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_green.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_green.png new file mode 100644 index 000000000..8024c3860 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_green.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_green.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_green.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_green.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_blue.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_blue.png new file mode 100644 index 000000000..11a7a0bea Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_blue.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_blue.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_blue.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_blue.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_gray.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_gray.png new file mode 100644 index 000000000..168556ba0 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_gray.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_gray.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_gray.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_light_gray.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_lime.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_lime.png new file mode 100644 index 000000000..c32fd7306 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_lime.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_lime.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_lime.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_lime.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_magenta.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_magenta.png new file mode 100644 index 000000000..304db0a6a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_magenta.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_magenta.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_magenta.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_magenta.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_orange.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_orange.png new file mode 100644 index 000000000..716fa6a7f Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_orange.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_orange.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_orange.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_orange.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_pink.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_pink.png new file mode 100644 index 000000000..c4f959b6a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_pink.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_pink.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_pink.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_pink.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_purple.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_purple.png new file mode 100644 index 000000000..8ef9ea56b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_purple.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_purple.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_purple.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_purple.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_red.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_red.png new file mode 100644 index 000000000..52af19d4b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_red.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_red.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_red.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_red.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_white.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_white.png new file mode 100644 index 000000000..a9edf8421 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_white.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_white.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_white.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_white.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_yellow.png b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_yellow.png new file mode 100644 index 000000000..36a6fbc8a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_yellow.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_yellow.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_yellow.png.mcmeta new file mode 100644 index 000000000..9be26b2b4 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/panelling/panelling_yellow.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "size": 2 + } + } +} diff --git a/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_energy.png b/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_energy.png new file mode 100644 index 000000000..c3304cb7b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_energy.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_heat.png b/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_heat.png new file mode 100644 index 000000000..711bd00b0 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_heat.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_pressure.png b/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_pressure.png new file mode 100644 index 000000000..a24b37061 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/progress_bar/progress_bar_fission_pressure.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_control_rod_helper.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_control_rod_helper.png new file mode 100644 index 000000000..5b3c39d41 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_control_rod_helper.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider.png b/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider.png new file mode 100644 index 000000000..48e8d79dc Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider_background.png b/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider_background.png new file mode 100644 index 000000000..7bd2b81bd Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider_background.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider_background_vertical.png b/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider_background_vertical.png new file mode 100644 index 000000000..634eb6bc8 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/dark_slider_background_vertical.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_bred_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_bred_fuel.png new file mode 100644 index 000000000..be7073222 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_bred_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_fission_byproduct.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_fission_byproduct.png new file mode 100644 index 000000000..be7073222 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_fission_byproduct.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_spent_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_spent_fuel.png new file mode 100644 index 000000000..be0cd30a2 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_spent_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet.png new file mode 100644 index 000000000..4873ba601 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet_depleted.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet_depleted.png new file mode 100644 index 000000000..0caa59886 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet_depleted.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod.png new file mode 100644 index 000000000..9a5a98b80 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_depleted.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_depleted.png new file mode 100644 index 000000000..d71b7ff20 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_depleted.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_hot_depleted.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_hot_depleted.png new file mode 100644 index 000000000..1f0a666eb Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_hot_depleted.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_hot_depleted_overlay.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_hot_depleted_overlay.png new file mode 100644 index 000000000..04b23d0aa Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_rod_hot_depleted_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_bred_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_bred_fuel.png new file mode 100644 index 000000000..8f597c61e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_bred_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_fission_byproduct.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_fission_byproduct.png new file mode 100644 index 000000000..8f597c61e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_fission_byproduct.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_spent_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_spent_fuel.png new file mode 100644 index 000000000..4c8e6485e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_spent_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/basket.anode.png b/src/main/resources/assets/gregtech/textures/items/metaitems/basket.anode.png new file mode 100644 index 000000000..dce6b7a4f Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/basket.anode.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/cladding.fuel.png b/src/main/resources/assets/gregtech/textures/items/metaitems/cladding.fuel.png new file mode 100644 index 000000000..44525dbbd Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/cladding.fuel.png differ diff --git a/src/main/resources/assets/susy/blockstates/fission_casing.json b/src/main/resources/assets/susy/blockstates/fission_casing.json new file mode 100644 index 000000000..13f608d2f --- /dev/null +++ b/src/main/resources/assets/susy/blockstates/fission_casing.json @@ -0,0 +1,41 @@ +{ + "forge_marker" : 1, + "defaults": { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/casings/solid/machine_casing_solid_steel" + } + }, + "variants" : { + "variant=reactor_vessel" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/casings/fission/reactor_vessel" + } + }, + "variant=fuel_channel" : { + "model" : "minecraft:cube_bottom_top", + "textures" : { + "top" : "gregtech:blocks/casings/fission/fuel_channel_top", + "bottom" : "gregtech:blocks/casings/fission/fuel_channel_top", + "side" : "gregtech:blocks/casings/fission/fuel_channel_side" + } + }, + "variant=control_rod_channel" : { + "model" : "minecraft:cube_bottom_top", + "textures" : { + "top" : "gregtech:blocks/casings/fission/control_rod_channel_top", + "bottom" : "gregtech:blocks/casings/fission/control_rod_channel_top", + "side" : "gregtech:blocks/casings/fission/fuel_channel_side" + } + }, + "variant=coolant_channel" : { + "model" : "minecraft:cube_bottom_top", + "textures" : { + "top" : "gregtech:blocks/casings/fission/coolant_channel_top", + "bottom" : "gregtech:blocks/casings/fission/coolant_channel_top", + "side" : "gregtech:blocks/casings/fission/fuel_channel_side" + } + } + } +} diff --git a/src/main/resources/assets/susy/blockstates/gas_centrifuge_casing.json b/src/main/resources/assets/susy/blockstates/gas_centrifuge_casing.json new file mode 100644 index 000000000..67f4dd5d3 --- /dev/null +++ b/src/main/resources/assets/susy/blockstates/gas_centrifuge_casing.json @@ -0,0 +1,21 @@ +{ + "forge_marker" : 1, + "defaults": { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/casings/solid/machine_casing_solid_steel" + } + }, + "variants" : { + "variant" : { + "gas_centrifuge_column" : { + "model" : "gregtech:gas_centrifuge", + "textures" : { + "0" : "gregtech:blocks/casings/nuclear/gas_centrifuge_side", + "1" : "gregtech:blocks/casings/nuclear/gas_centrifuge_end", + "particle" : "gregtech:blocks/casings/nuclear/gas_centrifuge_side" + } + } + } + } +} diff --git a/src/main/resources/assets/susy/blockstates/nuclear_casing.json b/src/main/resources/assets/susy/blockstates/nuclear_casing.json new file mode 100644 index 000000000..c894ad185 --- /dev/null +++ b/src/main/resources/assets/susy/blockstates/nuclear_casing.json @@ -0,0 +1,41 @@ +{ + "forge_marker" : 1, + "variants" : { + "active=false,variant=spent_fuel_casing" : { + "model": "minecraft:cube_column", + "textures": { + "end": "gregtech:blocks/casings/nuclear/spent_fuel_casing_empty_top", + "side": "gregtech:blocks/casings/nuclear/spent_fuel_casing_empty_side" + } + }, + "active=true,variant=spent_fuel_casing" : { + "model" : "gregtech:cube_2_layer_bottom_top", + "textures" : { + "bot_side" : "gregtech:blocks/casings/nuclear/spent_fuel_casing_side", + "bot_bottom" : "gregtech:blocks/casings/nuclear/spent_fuel_casing_top", + "bot_top" : "gregtech:blocks/casings/nuclear/spent_fuel_casing_top", + "top_side" : "gregtech:blocks/casings/nuclear/spent_fuel_casing_side_bloom", + "top_bottom" : "gregtech:blocks/casings/nuclear/spent_fuel_casing_top_bloom", + "top_top" : "gregtech:blocks/casings/nuclear/spent_fuel_casing_top_bloom" + } + }, + "active=false,variant=gas_centrifuge_heater" : { + "model" : "minecraft:cube_column", + "textures" : { + "end" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_top", + "side" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_side" + } + }, + "active=true,variant=gas_centrifuge_heater" : { + "model" : "gregtech:cube_2_layer_bottom_top", + "textures" : { + "bot_side" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_side", + "bot_bottom" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_top", + "bot_top" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_top", + "top_side" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_side_bloom", + "top_bottom" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_top_bloom", + "top_top" : "gregtech:blocks/casings/nuclear/gas_centrifuge_heater_top_bloom" + } + } + } +} diff --git a/src/main/resources/assets/susy/blockstates/panelling.json b/src/main/resources/assets/susy/blockstates/panelling.json new file mode 100644 index 000000000..e9e2170f7 --- /dev/null +++ b/src/main/resources/assets/susy/blockstates/panelling.json @@ -0,0 +1,109 @@ +{ + "forge_marker" : 1, + "defaults": { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_white" + } + }, + "variants" : { + "variant" : { + "white" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_white" + } + }, + "orange" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_orange" + } + }, + "magenta" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_magenta" + } + }, + "light_blue" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_light_blue" + } + }, + "yellow" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_yellow" + } + }, + "lime" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_lime" + } + }, + "pink" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_pink" + } + }, + "gray" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_gray" + } + }, + "light_gray" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_light_gray" + } + }, + "cyan" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_cyan" + } + }, + "purple" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_purple" + } + }, + "blue" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_blue" + } + }, + "brown" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_brown" + } + }, + "green" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_green" + } + }, + "red" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_red" + } + }, + "black" : { + "model" : "minecraft:cube_all", + "textures" : { + "all" : "gregtech:blocks/panelling/panelling_black" + } + } + } + } +} diff --git a/src/main/resources/assets/susy/lang/en_us.lang b/src/main/resources/assets/susy/lang/en_us.lang index b3a8e6546..4cc671c01 100644 --- a/src/main/resources/assets/susy/lang/en_us.lang +++ b/src/main/resources/assets/susy/lang/en_us.lang @@ -901,3 +901,131 @@ susy.command.horde.status.no_active_invasion=Player %s has no active invasion. susy.fluid.voiding.liquid=Voidable with Dumper susy.fluid.voiding.gas=Voidable with Smoke Stack susy.fluid.voiding.flammable=Voidable with Flare Stack + +# Nuclear +tile.fission_casing.reactor_vessel.name=Reactor Vessel +tile.fission_casing.fuel_channel.name=Fuel Channel +tile.fission_casing.control_rod_channel.name=Control Rod Channel +tile.fission_casing.coolant_channel.name=Coolant Channel +gregtech.machine.fuel_rod_input.name=Fuel Rod Input Port +gregtech.machine.fuel_rod_input.tooltip=Requires §fFuel Channels§7 below itself to function and form. +gregtech.machine.fuel_rod_output.name=Fuel Rod Output Port +gregtech.machine.fuel_rod_output.tooltip=Requires §fFuel Channels§7 above itself to function and form. +gregtech.machine.coolant_input.name=Coolant Input Port +gregtech.machine.coolant_input.tooltip=Requires §fCoolant Channels§7 below itself to function and form. +gregtech.machine.coolant_output.name=Coolant Output Port +gregtech.machine.coolant_output.tooltip=Requires §fCoolant Channels§7 above itself to function and form. +gregtech.machine.control_rod.name=Control Rod Port +gregtech.machine.control_rod.tooltip=Requires §fControl Rod Channels§7 below itself to function and form. +gregtech.machine.control_rod.tooltip.1=Lowers neutron multiplication as it is inserted when placed between fuel rods! +gregtech.machine.control_rod_moderated.name=Graphite-Tipped Control Rod Port +gregtech.machine.control_rod_moderated.tooltip=Requires §fControl Rod Channels§7 below itself to function and form. +gregtech.machine.control_rod_moderated.tooltip.1=Increases neutron multiplication when placed between fuel rods when inserted around 30%! +gregtech.machine.nuclear.locking.item=Locks when the reactor is turned on; the held item cannot change type when locked. +gregtech.machine.nuclear.locking.fluid=Locks when the reactor is turned on; the held fluid cannot change type when locked. + +gregtech.multiblock.fission_reactor.description=Fission Reactors use fuel rods placed together to create a sustained chain of fission reactions. These reactions generate heat (power) that may be soaked up by coolants, which can then be used inside turbines. For example, using distilled water as a coolant, each channel soaks up about 2 EU/t of heat per degree Kelvin and block of internal reactor depth. The reactor can take on a variety of shapes. Its cross sections can be seen in JEI, and the reactor may extend 7 blocks up and down from the controller. Reactors can import and export fuel rods/coolants through special pairs of hatches on the top and bottom layers, respectively. Control rod hatches may also be placed on the top layer, and they give the user more control over the reactor. Inserting them more decreases the neutron multiplication rate "effective K" (shown as k_eff), a factor by which the power is continually multiplied by until it reaches the approximate max power. If k_eff is over 1, the reactor's power will eventually increase; if it's below 1, it will eventually decrease; and if it's around 1, it will stay stable. In fact, the reactor automatically shifts this over time, attempting to reach a stable equilibrium. This may be overridden manually, which you may want to do if the k_eff is over 1.05 to avoid it spiralling out of control and melting down. K_eff is also affected by neutron poisons inside the reactor, which will increase in concentration over time as the reactor runs (and still remain in a fairly high concentration for a while after). The rate at which k_eff "acts" is dependent on the mean generation time, which is how long it takes for the next generation of neutrons to be produced. This depends on the fuel rod (and can be seen in their tooltips), and it is mostly affected by delayed neutrons produced from decaying fission products. The power may then be modeled using an exponential function with a time constant of the mean generation time divided by (k_eff - 1). Control rods, fuel hatches, and coolant hatches all require special tubing beneath them to form correctly; check their tooltips to see which blocks to use. Once a reactor's hatches are filled, the reactor can be locked to begin operation, meaning that the types of items/fluids in the hatches can not be changed while the reactor operates. The placement of the fuel rods and coolant channels within the reactor is quite important. Neutrons produced by decaying atoms in the fuel rods can cause fissions in other fuel rods; therefore, reactors work far more effectively with more than one fuel rod channel. The chance that a neutron interacts with a fuel rod is increased if it is slowed down by a moderator, such as distilled water inside a coolant channel. As such, it can be helpful to put coolant channels between fuel rods to increase k_eff (and control rods do much the opposite). Fuel rods also decay at a rate proportional to the power; a 600 MJ fuel rod will deplete after 600 seconds of 1 MW, or alternatively 1 second of 600 MW. Note: if this multiblock receives maintenance problems, the coolant systems will occasionally seize up and stop working. However, coolant channels only operate when the hot coolant fluid is actually hotter than the reactor itself, and they can also only altogether export as much heat as the max power. +gregtech.multiblock.gas_centrifuge.description=The Gas Centrifuge can help in the purification process of isotopes, especially those of uranium. By repeatedly putting uranium hexafluoride into a gas centrifuge, one can obtain highly enriched uranium hexafluoride, which has a purity high enough to make nuclear fuels. Each block of length makes it perform one more recipe in parallel. +gregtech.multiblock.heat_exchanger.description=The Heat Exchanger can be used to take heat out from one fluid by either radiating it out into its surrounding environment or by transferring it into another fluid. This can be used with hot coolant from fission reactors to help generate steam for steam turbines. +gregtech.multiblock.spent_fuel_pool.description=The Spent Fuel Pool takes hot depleted fuel rods fresh from a fission reactor and cools them down to be processed later. It only forms when full blocks of water are placed on top; what did you expect? Each block of length makes it perform 32 more recipes in parallel. + +metaitem.nuclear.tooltip.radioactive=§cEmits dangerous radiation +metaitem.nuclear.tooltip.duration=Total heat energy: %d MJ +metaitem.nuclear.tooltip.temperature=Melting point: %d K +metaitem.nuclear.tooltip.cross_section_fast=Fast neutron prob: %d barn +metaitem.nuclear.tooltip.cross_section_slow=Slow neutron prob: %d barn +metaitem.nuclear.tooltip.neutron_time.0=Avg. neutron: %ds (§1Safe§r) +metaitem.nuclear.tooltip.neutron_time.1=Avg. neutron: %ds (§2Safer§r) +metaitem.nuclear.tooltip.neutron_time.2=Avg. neutron: %ds (§cUnsafe§r) +metaitem.nuclear.tooltip.neutron_time.3=Avg. neutron: %ds (§4Very unsafe§r) + +item.material.oreprefix.fuelRod=%s Fuel Rod +item.material.oreprefix.fuelRodDepleted=%s Depleted Fuel Rod +item.material.oreprefix.fuelRodHotDepleted=%s Hot Depleted Fuel Rod +item.material.oreprefix.fuelPellet=%s Fuel Pellet +item.material.oreprefix.fuelPelletDepleted=%s Depleted Fuel Pellet +item.material.oreprefix.dustSpentFuel=%s Spent Fuel Dust +item.material.oreprefix.dustBredFuel=%s Bred Fuel Dust +item.material.oreprefix.dustFissionByproduct=%s Fission Byproduct Dust + +recipemap.gas_centrifuge.name=Gas Centrifuge +recipemap.spent_fuel_pool.name=Spent Fuel Pool + +fission.coolant.name=Coolant Heating +fission.fuel.name=Fission Reactor + +metaitem.basket.anode.name=Anode Basket +metaitem.cladding.fuel.name=Fuel Cladding + +tile.panelling.white.name=White Panelling +tile.panelling.orange.name=Orange Panelling +tile.panelling.magenta.name=Magenta Panelling +tile.panelling.light_blue.name=Light Blue Panelling +tile.panelling.yellow.name=Yellow Panelling +tile.panelling.lime.name=Lime Panelling +tile.panelling.pink.name=Pink Panelling +tile.panelling.gray.name=Gray Panelling +tile.panelling.light_gray.name=Light Gray Panelling +tile.panelling.cyan.name=Cyan Panelling +tile.panelling.purple.name=Purple Panelling +tile.panelling.blue.name=Blue Panelling +tile.panelling.brown.name=Brown Panelling +tile.panelling.green.name=Green Panelling +tile.panelling.red.name=Red Panelling +tile.panelling.black.name=Black Panelling + +# Nuclear Blocks +tile.nuclear_casing.spent_fuel_casing.name=Spent Fuel Casing +tile.nuclear_casing.gas_centrifuge_heater.name=Gas Centrifuge Heater +tile.gas_centrifuge_casing.gas_centrifuge_column.name=Gas Centrifuge Column + +gregtech.machine.fission_reactor.name=Fission Reactor +gregtech.machine.fission_reactor.tooltip.1=Check preview for allowed shapes. +gregtech.machine.fission_reactor.tooltip.2=§cMay meltdown/explode if the temperature/pressure gets too high! +gregtech.machine.fission_reactor.tooltip.3=§cPlease read the JEI info page! It is very important! + +gregtech.machine.spent_fuel_pool.name=Spent Fuel Pool +gregtech.machine.gas_centrifuge.name=Gas Centrifuge + +gregtech.machine.fission_reactor.tooltip=Blowy-uppy yumyum generator +gregtech.machine.heat_exchanger.tooltip=Molecular hot potato player + +gregtech.coolant.general=§9Can be used as a coolant§7 +gregtech.coolant.exit_temp=Hot coolant temperature: %d K +gregtech.coolant.heat_capacity=Heat capacity: %d J/kgK +gregtech.coolant.cooling_factor=Heat transfer: %d W/(m^2K) +gregtech.coolant.moderation_factor=Moderation cross section: %d barn +gregtech.coolant.accumulates_hydrogen=§cAccumulates hydrogen at 1500K + +gregtech.gui.fission.control_rod_insertion=Control rod insertion: %d +gregtech.gui.fission.coolant_flow=Coolant flow rate: %d L/t per channel +gregtech.gui.fission.temperature=Temperature: %.3f K +gregtech.gui.fission.pressure=Pressure: %.3f Pa +gregtech.gui.fission.power=Power: %.3f MW / %.3f MW +gregtech.gui.fission.k_eff=Neutron multiplication factor: %f +gregtech.gui.fission.depletion=Current fuel rod depletion: %f%% + +gregtech.gui.fission.lock.locked=Reactor locked and active! +gregtech.gui.fission.lock.unlocked=Reactor not active +gregtech.gui.fission.lock.should_lock=Activating... +gregtech.gui.fission.lock.missing_fuel=A bus is missing fuel! +gregtech.gui.fission.lock.missing_coolant=A hatch is missing coolant! +gregtech.gui.fission.lock.fuel_clogged=An output fuel bus is full! +gregtech.gui.fission.lock.no_fuel_channels=There isn't a fuel channel! +gregtech.gui.fission.lock.invalid_component=Erm, what the flip? Check your log file +gregtech.gui.fission.lock.disabled=Lock Fuel and Coolant types and start the Reactor +gregtech.gui.fission.lock.enabled=Unlock Fuel and Coolant types and stop the Reactor + +gregtech.gui.fission.helper.disabled=When I'm smiling, I regulate your control rods for you! - Smiley, the Control Rod Specialist +gregtech.gui.fission.helper.enabled=When I'm smiling, I regulate your control rods for you! - Smiley, the Control Rod Specialist + +gregtech.gui.locked=(Locked) + +gregtech.multiblock.fission_reactor.diameter=Diameter: %s +gregtech.multiblock.fission_reactor.height=Height: %s + +gregtech.multiblock.fission_reactor.turn_on=Turn on the reactor? (Locks all hatches) +gregtech.multiblock.fission_reactor.turn_off=Turn off the reactor? +gregtech.multiblock.fission_reactor.structure_incomplete=Cannot toggle the reactor. The structure is incomplete. +gregtech.multiblock.fission_reactor.invalid_components=Reactor startup failed. Some of the inputs ports are invalid. Please check that channels are aligned with their respective ports. +gregtech.multiblock.fission_reactor.missing_inputs=Reactor startup failed. Some of the inputs ports are empty or have inappropriate contents. Please check the ports. diff --git a/src/main/resources/mixins.susy.gregtech.json b/src/main/resources/mixins.susy.gregtech.json index 3a0d0c00c..353dd6776 100644 --- a/src/main/resources/mixins.susy.gregtech.json +++ b/src/main/resources/mixins.susy.gregtech.json @@ -1,15 +1,16 @@ { - "package" : "supersymmetry.mixins.gregtech", - "refmap" : "mixins.susy.refmap.json", - "target" : "@env(DEFAULT)", - "minVersion" : "0.8", - "compatibilityLevel" : "JAVA_8", - "mixins" : [ + "package": "supersymmetry.mixins.gregtech", + "refmap": "mixins.susy.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ "BlockMachineMixin", "MetaTileEntityDrumAccessor", "MetaTileEntityFluidDrillMixin", "MetaTileEntityLargeMinerMixin", "MetaTileEntityMinerMixin", - "MultiblockControllerBaseMixin" + "MultiblockControllerBaseMixin", + "SliderWidgetAccessor" ] }