From ac1ba8ed306647799bbe164582ddf177bb72908e Mon Sep 17 00:00:00 2001 From: yGlobalista <35036442+globalista-dev@users.noreply.github.com> Date: Sun, 17 Dec 2023 07:15:25 -0300 Subject: [PATCH] KubeJS support for fuel rods, control rods and fluid-neutron interactions (#605) Co-authored-by: Technici4n <13494793+Technici4n@users.noreply.github.com> --- docs/ADDING_NUCLEAR_COMPONENTS.md | 139 +++++++++++++++++ .../usage/NeutronInteractionCategory.java | 5 +- .../usage/ThermalInteractionCategory.java | 6 +- .../ModernIndustrialization.java | 2 + .../compat/kubejs/KubeJSProxy.java | 3 + .../compat/kubejs/LoadedKubeJSProxy.java | 15 +- .../material/MaterialBuilderJSWrapper.java | 31 ++++ .../kubejs/material/PartJsonCreator.java | 13 +- .../MIRegistrationKubeJSEvents.java | 2 + ...gisterFluidNeutronInteractionsEventJS.java | 98 ++++++++++++ .../materials/MIMaterials.java | 62 ++++---- .../materials/MaterialRegistry.java | 5 +- .../materials/part/ControlRodPart.java | 65 ++++++++ .../materials/part/MIParts.java | 2 + .../materials/part/NuclearFuelPart.java | 34 ++-- .../materials/property/MaterialProperty.java | 6 + .../nuclear/FluidNuclearComponent.java | 147 ++++++++++++++++++ .../nuclear/FluidNuclearComponents.java | 99 ------------ .../nuclear/INeutronBehaviour.java | 2 +- .../nuclear/INuclearTileData.java | 2 +- .../nuclear/IsotopeFuelParams.java | 87 +++++++++++ .../nuclear/IsotopeParams.java | 38 +++++ .../nuclear/NuclearConstant.java | 81 ---------- 23 files changed, 704 insertions(+), 240 deletions(-) create mode 100644 docs/ADDING_NUCLEAR_COMPONENTS.md create mode 100644 src/main/java/aztech/modern_industrialization/compat/kubejs/registration/RegisterFluidNeutronInteractionsEventJS.java create mode 100644 src/main/java/aztech/modern_industrialization/materials/part/ControlRodPart.java create mode 100644 src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponent.java delete mode 100644 src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponents.java create mode 100644 src/main/java/aztech/modern_industrialization/nuclear/IsotopeFuelParams.java create mode 100644 src/main/java/aztech/modern_industrialization/nuclear/IsotopeParams.java diff --git a/docs/ADDING_NUCLEAR_COMPONENTS.md b/docs/ADDING_NUCLEAR_COMPONENTS.md new file mode 100644 index 000000000..20f7a0a7b --- /dev/null +++ b/docs/ADDING_NUCLEAR_COMPONENTS.md @@ -0,0 +1,139 @@ +# Adding nuclear reactor components +MI allows you to add new nuclear reactor components using KubeJS. +Currently, fuel rods, control rods and fluid-neutron interactions can be registered. + +To add fission fuel rods and control rods, you will need to use a startup script and the events in `MIMaterialEvents` +Fuel rods and control rods are parts that can be added to a new or preexisting material. + +Isotopes are used in the registration of rods. +They can be added using the `MIRegistrationEvents.registerNuclearIsotopes` event. + +## Add a fuel rod +Read the [material system documentation](`ADDING_MATERIALS.md`) first for an explanation of the material system. + +To register fuel rods for a material, you must first register the material as a fission fuel. +This can be done using `.nuclearFuel(...)` on the material builder with a number of parameters: +```js +MIMaterialEvents.addMaterials(event => { + event.createMaterial('LE Americium MOX', 'le_americium_mox', 0x83867B, + builder => { + builder + .nuclearFuel( + 0.6, // Thermal absorption probabilty + 0.35, // Thermal scattering + 2400, // Max temperature + 900, // Low temperature limit (neutron production starts to decrease) + 2300, // High temperature limit (neutron production completely stops) + 8, // Neutron multiplication + 0.5) // Direct energy factor + }); +}); +``` + +You can also combine the parameters of two existing materials using the `.nuclearFuelMix(materialA, materialB, mix)` method. +This can be used to simulate MOX and MOX-type fuels. +The resulting parameters will be `(1 - r) * a + r * b`, where `r` is the factor, `a` is the first set of parameters and `b` is the second. +The example below illustrates how a fuel rod can be created from the uranium 238 and plutonium parameters. +This generates the same parameters as LE MOX fuel. +```js +MIMaterialEvents.addMaterials(event => { + event.createMaterial('LE Americium MOX', 'le_americium_mox', 0x83867B, + builder => { + builder + .nuclearFuelMix("uranium_238", "plutonium", 1/9) + }); +}); +``` + +You then need to call the `.fuelRods()` method on the material builder to register the rods. +Here is a complete example: +```js +MIMaterialEvents.addMaterials(event => { + event.createMaterial('LE Americium MOX', 'le_americium_mox', 0x83867B, + builder => { + builder + .nuclearFuelMix("uranium_238", "plutonium", 1/9) + // Every material with a fuel rod needs at least the ingot and rod parts + .addParts('ingot', 'rod') + .fuelRods() + }); +}); +``` + +## Add a control rod +To add a control rod, use the `.controlRod(...)` material builder method. + +Here is an example script that adds a new `Boron` material that has a control rod: +```js +MIMaterialEvents.addMaterials(event => { + event.createMaterial('Boron', 'boron', 0x493D35, + builder => { + // Every material that has a control rod needs at least the ingot and rod parts + builder.addParts('ingot', 'rod') + .controlRod( + 1900, // Max temperature + 0.5, // Heat conduction + 0.95, // Thermal absorption probability + 0.9, // Fast absorption probability + 0.05, // Thermal scattering probability + 0.1, // Fast scattering probability + 'HEAVY', // Scattering type, can be ULTRA_LIGHT (0.05), LIGHT (0.2), MEDIUM (0.5) or HEAVY (0.85) + 1) // Size + .defaultRecipes(); + }); +}); +``` + +## Add a fluid-neutron interaction +These types of fluids are the ones that can absorb neutrons inside a Nuclear Reactor (think water producing deuterium). +You can add your own using a startup script and the `MIRegistrationEvents.registerFluidNeutronInteractions` event. + +To create the fluid in the first place, refer to the [fluid creation tutorial](`ADDING_FLUIDS.md`). + +Here's an example script that adds tritium turning into hydrogen-4: + +```js +MIRegistrationEvents.registerFluidNeutronInteractions(event => { + event.register( + 'modern_industrialization:tritium', // The fluid being added as a nuclear component + 5, // Heat conduction factor (later multiplied by the base heat conduction, 0.01) + 1, // Density + 'ultra_light', // Scattering type + 0.02, // Thermal absorption probability + 0.01, // Fast absorption probability + 0.15, // Thermal scattering probability + 0.65, // Fast scattering probability + 'modern_industrialization:hydrogen_4', // The fluid product + 1, // Amount of converted product fluid per consumed input fluid + 1.0); // Probability of converting 1 of input fluid per received neutron +}); +``` +For a high-pressure fluid (with 8x the density), the last two parameters would be `8, 0.125`. + +### Removing and modifying a fluid nuclear component +You can remove a fluid nuclear component: + +```js +MIRegistrationEvents.registerFluidNeutronInteractions(event => { + event.remove('minecraft:water'); // Remove water as a fluid nuclear component +}); +``` + +If, instead of removing the fluid nuclear component, you'd rather modify it, you can: +```js +MIRegistrationEvents.registerFluidNeutronInteractions(event => { + // Same parameters as `register(...)`, see above. + event.modify( + 'minecraft:water', + 5, + 1, + 'ultra_light', + 0.02, + 0.01, + 0.15, + 0.65, + 'modern_industrialization:heavy_water', + 1, + 1.0); +}); +``` diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/usage/NeutronInteractionCategory.java b/src/client/java/aztech/modern_industrialization/compat/viewer/usage/NeutronInteractionCategory.java index fc2b69504..d273ee46f 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/usage/NeutronInteractionCategory.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/usage/NeutronInteractionCategory.java @@ -27,7 +27,7 @@ import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.ModernIndustrialization; import aztech.modern_industrialization.compat.viewer.abstraction.ViewerCategory; -import aztech.modern_industrialization.nuclear.FluidNuclearComponents; +import aztech.modern_industrialization.nuclear.FluidNuclearComponent; import aztech.modern_industrialization.nuclear.INeutronBehaviour; import aztech.modern_industrialization.nuclear.INuclearComponent; import aztech.modern_industrialization.nuclear.NeutronInteraction; @@ -92,8 +92,7 @@ public void buildRecipes(RecipeManager recipeManager, Consumer consumer) for (Fluid fluid : Registry.FLUID) { if (fluid.isSource(fluid.defaultFluidState()) && fluid != Fluids.EMPTY) { - FluidVariant variant = FluidVariant.of(fluid); - INuclearComponent component = FluidNuclearComponents.of(variant); + INuclearComponent component = FluidNuclearComponent.get(fluid); if (component != null) { consumer.accept(new Recipe(component, CategoryType.FAST_NEUTRON_INTERACTION)); consumer.accept(new Recipe(component, CategoryType.THERMAL_NEUTRON_INTERACTION)); diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/usage/ThermalInteractionCategory.java b/src/client/java/aztech/modern_industrialization/compat/viewer/usage/ThermalInteractionCategory.java index 85585c8c2..76ee74565 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/usage/ThermalInteractionCategory.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/usage/ThermalInteractionCategory.java @@ -27,7 +27,7 @@ import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.compat.viewer.abstraction.ViewerCategory; import aztech.modern_industrialization.machines.gui.MachineScreen; -import aztech.modern_industrialization.nuclear.FluidNuclearComponents; +import aztech.modern_industrialization.nuclear.FluidNuclearComponent; import aztech.modern_industrialization.nuclear.INeutronBehaviour; import aztech.modern_industrialization.nuclear.INuclearComponent; import aztech.modern_industrialization.nuclear.NuclearComponentItem; @@ -37,7 +37,6 @@ import aztech.modern_industrialization.util.TextHelper; import com.mojang.blaze3d.systems.RenderSystem; import java.util.function.Consumer; -import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; import net.minecraft.client.Minecraft; import net.minecraft.core.Registry; @@ -77,8 +76,7 @@ public void buildRecipes(RecipeManager recipeManager, Consumer consumer) for (Fluid fluid : Registry.FLUID) { if (fluid.isSource(fluid.defaultFluidState()) && fluid != Fluids.EMPTY) { - FluidVariant variant = FluidVariant.of(fluid); - INuclearComponent component = FluidNuclearComponents.of(variant); + INuclearComponent component = FluidNuclearComponent.get(fluid); if (component != null) { consumer.accept(new Recipe(component, CategoryType.THERMAL_PROPERTIES)); diff --git a/src/main/java/aztech/modern_industrialization/ModernIndustrialization.java b/src/main/java/aztech/modern_industrialization/ModernIndustrialization.java index c71cdc17e..5227a8b46 100644 --- a/src/main/java/aztech/modern_industrialization/ModernIndustrialization.java +++ b/src/main/java/aztech/modern_industrialization/ModernIndustrialization.java @@ -44,6 +44,7 @@ import aztech.modern_industrialization.materials.MIMaterials; import aztech.modern_industrialization.misc.autotest.MIAutoTesting; import aztech.modern_industrialization.misc.guidebook.GuidebookEvents; +import aztech.modern_industrialization.nuclear.FluidNuclearComponent; import aztech.modern_industrialization.pipes.MIPipes; import aztech.modern_industrialization.proxy.CommonProxy; import aztech.modern_industrialization.stats.PlayerStatisticsData; @@ -103,6 +104,7 @@ public static void initialize() { setupBlocks(); MIBlockEntityTypes.init(); MIVillager.init(); + FluidNuclearComponent.init(); // fields. setupPackets(); diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/KubeJSProxy.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/KubeJSProxy.java index 98c4691d5..b3ddeb3e3 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/KubeJSProxy.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/KubeJSProxy.java @@ -64,4 +64,7 @@ public void fireAddEbfTiersEvent(Consumer public void fireCustomConditionEvent() { } + + public void fireRegisterFluidNeutronInteractionsEvent() { + } } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/LoadedKubeJSProxy.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/LoadedKubeJSProxy.java index 324b64e8a..18125878d 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/LoadedKubeJSProxy.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/LoadedKubeJSProxy.java @@ -23,13 +23,7 @@ */ package aztech.modern_industrialization.compat.kubejs; -import aztech.modern_industrialization.compat.kubejs.machine.AddEbfTiersEventJS; -import aztech.modern_industrialization.compat.kubejs.machine.AddMultiblockSlotsEventJS; -import aztech.modern_industrialization.compat.kubejs.machine.MIMachineKubeJSEvents; -import aztech.modern_industrialization.compat.kubejs.machine.RegisterCasingsEventJS; -import aztech.modern_industrialization.compat.kubejs.machine.RegisterMachinesEventJS; -import aztech.modern_industrialization.compat.kubejs.machine.RegisterRecipeTypesEventJS; -import aztech.modern_industrialization.compat.kubejs.machine.RegisterUpgradesEventJS; +import aztech.modern_industrialization.compat.kubejs.machine.*; import aztech.modern_industrialization.compat.kubejs.material.AddMaterialsEventJS; import aztech.modern_industrialization.compat.kubejs.material.MIMaterialKubeJSEvents; import aztech.modern_industrialization.compat.kubejs.material.ModifyMaterialEventJS; @@ -37,6 +31,7 @@ import aztech.modern_industrialization.compat.kubejs.recipe.MIRecipeKubeJSEvents; import aztech.modern_industrialization.compat.kubejs.registration.MIRegistrationKubeJSEvents; import aztech.modern_industrialization.compat.kubejs.registration.RegisterFluidFuelsEventJS; +import aztech.modern_industrialization.compat.kubejs.registration.RegisterFluidNeutronInteractionsEventJS; import aztech.modern_industrialization.compat.kubejs.registration.RegisterFluidsEventJS; import aztech.modern_industrialization.inventory.SlotPositions; import aztech.modern_industrialization.machines.blockentities.multiblocks.ElectricBlastFurnaceBlockEntity; @@ -100,4 +95,10 @@ public void fireAddEbfTiersEvent(Consumer public void fireCustomConditionEvent() { MIRecipeKubeJSEvents.CUSTOM_CONDITION.post(new CustomConditionEventJS()); } + + @Override + public void fireRegisterFluidNeutronInteractionsEvent() { + MIRegistrationKubeJSEvents.REGISTER_FLUID_NEUTRON_INTERACTIONS.post(new RegisterFluidNeutronInteractionsEventJS()); + } + } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/material/MaterialBuilderJSWrapper.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/material/MaterialBuilderJSWrapper.java index 3f0454560..a504336fa 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/material/MaterialBuilderJSWrapper.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/material/MaterialBuilderJSWrapper.java @@ -24,7 +24,9 @@ package aztech.modern_industrialization.compat.kubejs.material; import aztech.modern_industrialization.materials.MaterialBuilder; +import aztech.modern_industrialization.materials.MaterialRegistry; import aztech.modern_industrialization.materials.part.MaterialItemPart; +import aztech.modern_industrialization.materials.part.NuclearFuelPart; import aztech.modern_industrialization.materials.part.PartKey; import aztech.modern_industrialization.materials.property.MaterialHardness; import aztech.modern_industrialization.materials.property.MaterialProperty; @@ -32,6 +34,8 @@ import aztech.modern_industrialization.materials.recipe.SmeltingRecipes; import aztech.modern_industrialization.materials.recipe.StandardRecipes; import aztech.modern_industrialization.materials.set.MaterialSet; +import aztech.modern_industrialization.nuclear.IsotopeFuelParams; +import aztech.modern_industrialization.nuclear.NuclearConstant; import com.google.gson.JsonObject; class MaterialBuilderJSWrapper { @@ -186,4 +190,31 @@ public MaterialBuilderJSWrapper forgeHammerRecipes() { materialBuilder.addRecipes(ForgeHammerRecipes::apply); return this; } + + public MaterialBuilderJSWrapper nuclearFuel(double thermalAbsorbProba, double thermalScatterings, int maxTemp, int tempLimitLow, + int tempLimitHigh, double neutronsMultiplication, double directEnergyFactor) { + materialBuilder.set(MaterialProperty.ISOTOPE, new IsotopeFuelParams(thermalAbsorbProba, thermalScatterings, maxTemp, tempLimitLow, + tempLimitHigh, neutronsMultiplication, directEnergyFactor)); + return this; + } + + public MaterialBuilderJSWrapper nuclearFuelMix(String a, String b, double factor) { + materialBuilder.set(MaterialProperty.ISOTOPE, IsotopeFuelParams.mix( + IsotopeFuelParams.of(MaterialRegistry.getMaterial(a)), + IsotopeFuelParams.of(MaterialRegistry.getMaterial(b)), + factor)); + return this; + } + + public MaterialBuilderJSWrapper fuelRods() { + materialBuilder.addParts(NuclearFuelPart.ofAll()); + return this; + } + + public MaterialBuilderJSWrapper controlRod(int maxTemperature, double heatConduction, double thermalAbsorbProba, double fastAbsorbProba, + double thermalScatteringProba, double fastScatteringProba, NuclearConstant.ScatteringType scatteringType, double size) { + materialBuilder.addParts(creator.controlRodPart(maxTemperature, heatConduction, thermalAbsorbProba, fastAbsorbProba, thermalScatteringProba, + fastScatteringProba, scatteringType, size)); + return this; + } } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/material/PartJsonCreator.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/material/PartJsonCreator.java index bcc29b732..b62bd90fb 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/material/PartJsonCreator.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/material/PartJsonCreator.java @@ -24,10 +24,14 @@ package aztech.modern_industrialization.compat.kubejs.material; import aztech.modern_industrialization.api.energy.CableTier; -import aztech.modern_industrialization.materials.part.*; +import aztech.modern_industrialization.materials.part.MIParts; +import aztech.modern_industrialization.materials.part.OrePart; +import aztech.modern_industrialization.materials.part.PartTemplate; +import aztech.modern_industrialization.materials.part.RawMetalPart; import aztech.modern_industrialization.materials.set.MaterialBlockSet; import aztech.modern_industrialization.materials.set.MaterialOreSet; import aztech.modern_industrialization.materials.set.MaterialRawSet; +import aztech.modern_industrialization.nuclear.NuclearConstant; import com.google.gson.JsonObject; import net.minecraft.util.valueproviders.UniformInt; @@ -150,4 +154,11 @@ public PartTemplate tankPart(int bucketCapacity) { public PartTemplate tankPart(String englishName, String path, int bucketCapacity) { return MIParts.TANK.of(englishName, path, bucketCapacity); } + + public PartTemplate controlRodPart(int maxTemperature, double heatConduction, double thermalAbsorbProba, double fastAbsorbProba, + double thermalScatteringProba, double fastScatteringProba, NuclearConstant.ScatteringType scatteringType, double size) { + return MIParts.CONTROL_ROD.of(maxTemperature, heatConduction, thermalAbsorbProba, fastAbsorbProba, thermalScatteringProba, + fastScatteringProba, scatteringType, size); + + } } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/registration/MIRegistrationKubeJSEvents.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/registration/MIRegistrationKubeJSEvents.java index b46aedfea..80c992301 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/registration/MIRegistrationKubeJSEvents.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/registration/MIRegistrationKubeJSEvents.java @@ -31,4 +31,6 @@ public interface MIRegistrationKubeJSEvents { EventHandler REGISTER_FLUIDS = EVENT_GROUP.startup("registerFluids", () -> RegisterFluidsEventJS.class); EventHandler REGISTER_FLUID_FUELS = EVENT_GROUP.startup("registerFluidFuels", () -> RegisterFluidFuelsEventJS.class); + EventHandler REGISTER_FLUID_NEUTRON_INTERACTIONS = EVENT_GROUP.startup("registerFluidNeutronInteractions", + () -> RegisterFluidNeutronInteractionsEventJS.class); } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/registration/RegisterFluidNeutronInteractionsEventJS.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/registration/RegisterFluidNeutronInteractionsEventJS.java new file mode 100644 index 000000000..75df0bf19 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/registration/RegisterFluidNeutronInteractionsEventJS.java @@ -0,0 +1,98 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.compat.kubejs.registration; + +import aztech.modern_industrialization.nuclear.FluidNuclearComponent; +import aztech.modern_industrialization.nuclear.IsotopeParams; +import aztech.modern_industrialization.nuclear.NuclearConstant; +import dev.latvian.mods.kubejs.event.EventJS; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.core.Registry; +import net.minecraft.world.level.material.Fluid; + +public class RegisterFluidNeutronInteractionsEventJS extends EventJS { + + public void register( + Fluid fluid, + double heatConduction, + double density, + String scatteringString, + // Isotope params + double thermalAbsorption, + double fastAbsorption, + double thermalScattering, + double fastScattering, + // Products + Fluid productFluid, + long productPerNeutron, + double productProbability) { + + var scatteringType = switch (scatteringString) { + case "ultra_light" -> NuclearConstant.ScatteringType.ULTRA_LIGHT; + case "light" -> NuclearConstant.ScatteringType.LIGHT; + case "medium" -> NuclearConstant.ScatteringType.MEDIUM; + case "heavy" -> NuclearConstant.ScatteringType.HEAVY; + default -> throw new IllegalArgumentException("Invalid ScatteringType: " + scatteringString); + }; + + FluidNuclearComponent.register( + new FluidNuclearComponent( + fluid, + heatConduction, + density, + scatteringType, + new IsotopeParams(thermalAbsorption, fastAbsorption, thermalScattering, fastScattering), + FluidVariant.of(productFluid), + productPerNeutron, + productProbability)); + } + + public void remove(Fluid fluid) { + if (FluidNuclearComponent.get(fluid) == null) { + throw new IllegalArgumentException("Fluid " + Registry.FLUID.getKey(fluid) + " is not a nuclear component!"); + } + + FluidNuclearComponent.remove(fluid); + } + + public void modify( + Fluid fluid, + double heatConduction, + double density, + String scatteringString, + // Isotope params + double thermalAbsorption, + double fastAbsorption, + double thermalScattering, + double fastScattering, + // Products + Fluid productFluid, + long productPerNeutron, + double productProbability) { + + remove(fluid); + register(fluid, heatConduction, density, scatteringString, thermalAbsorption, fastAbsorption, thermalScattering, fastScattering, productFluid, + productPerNeutron, productProbability); + } +} diff --git a/src/main/java/aztech/modern_industrialization/materials/MIMaterials.java b/src/main/java/aztech/modern_industrialization/materials/MIMaterials.java index 9254cebac..9ed035518 100644 --- a/src/main/java/aztech/modern_industrialization/materials/MIMaterials.java +++ b/src/main/java/aztech/modern_industrialization/materials/MIMaterials.java @@ -41,6 +41,7 @@ import aztech.modern_industrialization.materials.set.MaterialOreSet; import aztech.modern_industrialization.materials.set.MaterialRawSet; import aztech.modern_industrialization.nuclear.INeutronBehaviour; +import aztech.modern_industrialization.nuclear.IsotopeFuelParams; import aztech.modern_industrialization.nuclear.NuclearAbsorbable; import aztech.modern_industrialization.nuclear.NuclearConstant; import net.minecraft.util.valueproviders.UniformInt; @@ -536,21 +537,12 @@ public static MaterialBuilder addVanillaGem(boolean compressor, String gemPath, .addParts(BLOCK.of(MaterialBlockSet.COPPER)).addParts(PLATE, WIRE, DOUBLE_INGOT, HOT_INGOT).addParts(CABLE.of(CableTier.EV)) .addRecipes(StandardRecipes::apply).addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, false, 64))); - URANIUM = MaterialRegistry.addMaterial(new MaterialBuilder("Uranium", "uranium") - .set(MaterialProperty.SET, DULL) - .set(MaterialProperty.MEAN_RGB, 0x39e600) - .addParts(FUEL_ROD.ofAll(NuclearConstant.U)) - .addParts(ITEM_PURE_METAL).addParts(ROD).addParts(BLOCK.of(MaterialBlockSet.GOLD)).addParts(ORE.ofAll(8, 5, 16, MaterialOreSet.COPPER)) - .addParts(RAW_METAL.of(MaterialRawSet.URANIUM)) - .addParts(RAW_METAL_BLOCK.of(MaterialRawSet.COPPER)) - .addRecipes(StandardRecipes::apply) - .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); - URANIUM_235 = MaterialRegistry.addMaterial( new MaterialBuilder("Uranium 235", "uranium_235") .set(MaterialProperty.SET, SHINY) .set(MaterialProperty.MEAN_RGB, 0xe60045) .set(MaterialProperty.HARDNESS, VERY_HARD) + .set(MaterialProperty.ISOTOPE, new IsotopeFuelParams(0.6, 0.35, 2400, 900, 2300, 8, 0.5)) .addParts(BLOCK.of(MaterialBlockSet.GOLD)).addParts(ITEM_PURE_METAL) .addRecipes(StandardRecipes::apply).addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); @@ -559,13 +551,27 @@ public static MaterialBuilder addVanillaGem(boolean compressor, String gemPath, .set(MaterialProperty.SET, DULL) .set(MaterialProperty.MEAN_RGB, 0x55bd33) .set(MaterialProperty.HARDNESS, SOFT) + .set(MaterialProperty.ISOTOPE, new IsotopeFuelParams(0.6, 0.30, 3200, 1000, 3000, 6, 0.3)) .addParts(BLOCK.of(MaterialBlockSet.GOLD)).addParts(ITEM_PURE_METAL) .addRecipes(StandardRecipes::apply).addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); + URANIUM = MaterialRegistry.addMaterial(new MaterialBuilder("Uranium", "uranium") + .set(MaterialProperty.SET, DULL) + .set(MaterialProperty.MEAN_RGB, 0x39e600) + .set(MaterialProperty.ISOTOPE, IsotopeFuelParams.mix(URANIUM_238, URANIUM_235, 1.0 / 81)) + .addParts(NuclearFuelPart.ofAll()) + .addParts(ITEM_PURE_METAL).addParts(ROD).addParts(BLOCK.of(MaterialBlockSet.GOLD)).addParts(ORE.ofAll(8, 5, 16, MaterialOreSet.COPPER)) + .addParts(RAW_METAL.of(MaterialRawSet.URANIUM)) + .addParts(RAW_METAL_BLOCK.of(MaterialRawSet.COPPER)) + .addRecipes(StandardRecipes::apply) + .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); + LE_URANIUM = MaterialRegistry.addMaterial(new MaterialBuilder("LE Uranium", "le_uranium") .set(MaterialProperty.SET, DULL) .set(MaterialProperty.MEAN_RGB, 0x70a33c) - .set(MaterialProperty.HARDNESS, VERY_HARD).addParts(FUEL_ROD.ofAll(NuclearConstant.LEU)) + .set(MaterialProperty.HARDNESS, VERY_HARD) + .set(MaterialProperty.ISOTOPE, IsotopeFuelParams.mix(URANIUM_238, URANIUM_235, 1.0 / 9)) + .addParts(NuclearFuelPart.ofAll()) .addParts(BLOCK.of(MaterialBlockSet.GOLD)).addParts(ITEM_PURE_METAL).addParts(ROD).addRecipes(StandardRecipes::apply) .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); @@ -573,31 +579,36 @@ public static MaterialBuilder addVanillaGem(boolean compressor, String gemPath, .set(MaterialProperty.SET, DULL) .set(MaterialProperty.MEAN_RGB, 0xaae838) .set(MaterialProperty.HARDNESS, VERY_HARD) - .addParts(FUEL_ROD.ofAll(NuclearConstant.HEU)) + .set(MaterialProperty.ISOTOPE, IsotopeFuelParams.mix(URANIUM_238, URANIUM_235, 1.0 / 3)) + .addParts(NuclearFuelPart.ofAll()) .addParts(BLOCK.of(MaterialBlockSet.GOLD)).addParts(ITEM_PURE_METAL).addParts(ROD).addRecipes(StandardRecipes::apply) .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); + PLUTONIUM = MaterialRegistry.addMaterial(new MaterialBuilder("Plutonium", "plutonium") + .set(MaterialProperty.SET, SHINY) + .set(MaterialProperty.MEAN_RGB, 0xd701e7) + .set(MaterialProperty.HARDNESS, VERY_HARD) + .set(MaterialProperty.ISOTOPE, new IsotopeFuelParams(0.9, 0.25, 2100, 600, 2000, 9, 0.25)) + .addParts(BLOCK.of(MaterialBlockSet.GOLD)) + .addParts(ITEM_PURE_METAL).addParts(BATTERY.of(CableTier.SUPERCONDUCTOR)).addRecipes(StandardRecipes::apply) + .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); + LE_MOX = MaterialRegistry.addMaterial(new MaterialBuilder("LE Mox", "le_mox") .set(MaterialProperty.SET, SHINY) .set(MaterialProperty.MEAN_RGB, 0x00e7e5) .set(MaterialProperty.HARDNESS, VERY_HARD) + .set(MaterialProperty.ISOTOPE, IsotopeFuelParams.mix(URANIUM_238, PLUTONIUM, 1.0 / 9)) .addParts(BLOCK.of(MaterialBlockSet.GOLD)) - .addParts(FUEL_ROD.ofAll(NuclearConstant.LE_MOX)).addParts(ITEM_PURE_METAL).addParts(ROD).addRecipes(StandardRecipes::apply) + .addParts(NuclearFuelPart.ofAll()).addParts(ITEM_PURE_METAL).addParts(ROD).addRecipes(StandardRecipes::apply) .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); HE_MOX = MaterialRegistry.addMaterial(new MaterialBuilder("HE Mox", "he_mox") .set(MaterialProperty.SET, SHINY) .set(MaterialProperty.MEAN_RGB, 0xcc87fa) .set(MaterialProperty.HARDNESS, VERY_HARD) + .set(MaterialProperty.ISOTOPE, IsotopeFuelParams.mix(URANIUM_238, PLUTONIUM, 1.0 / 3)) .addParts(BLOCK.of(MaterialBlockSet.GOLD)) - .addParts(FUEL_ROD.ofAll(NuclearConstant.HE_MOX)).addParts(ITEM_PURE_METAL).addParts(ROD).addRecipes(StandardRecipes::apply) - .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); - - PLUTONIUM = MaterialRegistry.addMaterial(new MaterialBuilder("Plutonium", "plutonium") - .set(MaterialProperty.SET, SHINY) - .set(MaterialProperty.MEAN_RGB, 0xd701e7) - .set(MaterialProperty.HARDNESS, VERY_HARD).addParts(BLOCK.of(MaterialBlockSet.GOLD)) - .addParts(ITEM_PURE_METAL).addParts(BATTERY.of(CableTier.SUPERCONDUCTOR)).addRecipes(StandardRecipes::apply) + .addParts(NuclearFuelPart.ofAll()).addParts(ITEM_PURE_METAL).addParts(ROD).addRecipes(StandardRecipes::apply) .addRecipes((ctx) -> SmeltingRecipes.applyBlastFurnace(ctx, 128))); PLATINUM = MaterialRegistry.addMaterial( @@ -659,14 +670,7 @@ public static MaterialBuilder addVanillaGem(boolean compressor, String gemPath, .set(MaterialProperty.MEAN_RGB, 0x967224) .set(MaterialProperty.HARDNESS, SOFT) .addParts(DUST, TINY_DUST, INGOT, PLATE, ROD, DOUBLE_INGOT, BATTERY.of(CableTier.EV)) - .addParts( - new PartTemplate("Control Rod", FUEL_ROD.key) - .withRegister((partContext, part, itemPath1, itemId, itemTag, englishName) -> NuclearAbsorbable - .of("Cadmium Control Rod", itemPath1, 1900, 0.5 * NuclearConstant.BASE_HEAT_CONDUCTION, - INeutronBehaviour.of(NuclearConstant.ScatteringType.HEAVY, NuclearConstant.CADMIUM, - 1), - NuclearConstant.DESINTEGRATION_BY_ROD)) - .withCustomPath("%s_control_rod")) + .addParts(CONTROL_ROD.of(1900, 0.5, NuclearConstant.ScatteringType.HEAVY, NuclearConstant.CADMIUM, 1)) .addRecipes(StandardRecipes::apply, SmeltingRecipes::apply)); NEODYMIUM = MaterialRegistry.addMaterial(new MaterialBuilder("Neodymium", "neodymium") diff --git a/src/main/java/aztech/modern_industrialization/materials/MaterialRegistry.java b/src/main/java/aztech/modern_industrialization/materials/MaterialRegistry.java index 1dab55593..1f0f37684 100644 --- a/src/main/java/aztech/modern_industrialization/materials/MaterialRegistry.java +++ b/src/main/java/aztech/modern_industrialization/materials/MaterialRegistry.java @@ -26,7 +26,6 @@ import aztech.modern_industrialization.compat.kubejs.KubeJSProxy; import java.util.Collections; import java.util.Map; -import java.util.Objects; import java.util.TreeMap; public class MaterialRegistry { @@ -44,7 +43,9 @@ public static Material addMaterial(MaterialBuilder materialBuilder) { public static Material getMaterial(String name) { Material material = MATERIALS.get(name); - Objects.requireNonNull(material); + if (material == null) { + throw new IllegalArgumentException("No such material: " + name); + } return material; } diff --git a/src/main/java/aztech/modern_industrialization/materials/part/ControlRodPart.java b/src/main/java/aztech/modern_industrialization/materials/part/ControlRodPart.java new file mode 100644 index 000000000..9e165b971 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/materials/part/ControlRodPart.java @@ -0,0 +1,65 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.materials.part; + +import static aztech.modern_industrialization.materials.part.MIParts.FUEL_ROD; + +import aztech.modern_industrialization.nuclear.INeutronBehaviour; +import aztech.modern_industrialization.nuclear.IsotopeParams; +import aztech.modern_industrialization.nuclear.NuclearAbsorbable; +import aztech.modern_industrialization.nuclear.NuclearConstant; + +public class ControlRodPart implements PartKeyProvider { + + @Override + public PartKey key() { + return FUEL_ROD.key; + } + + public PartTemplate of(int maxTemperature, double heatConduction, double thermalAbsorbProba, double fastAbsorbProba, + double thermalScatteringProba, double fastScatteringProba, NuclearConstant.ScatteringType scatteringType, double size) { + return new PartTemplate("Control Rod", key()) + .withRegister((partContext, part, itemPath1, itemId, itemTag, itemEnglishName) -> NuclearAbsorbable + .of(partContext.getMaterialEnglishName() + " Control Rod", itemPath1, maxTemperature, + heatConduction * NuclearConstant.BASE_HEAT_CONDUCTION, + INeutronBehaviour.of(scatteringType, + new IsotopeParams(thermalAbsorbProba, fastAbsorbProba, thermalScatteringProba, + fastScatteringProba), + size), + NuclearConstant.DESINTEGRATION_BY_ROD)) + .withCustomPath("%s_control_rod"); + } + + public PartTemplate of(int maxTemperature, double heatConduction, NuclearConstant.ScatteringType scatteringType, + IsotopeParams params, double size) { + return new PartTemplate("Control Rod", key()) + .withRegister((partContext, part, itemPath1, itemId, itemTag, itemEnglishName) -> NuclearAbsorbable + .of(partContext.getMaterialEnglishName() + " Control Rod", itemPath1, maxTemperature, + heatConduction * NuclearConstant.BASE_HEAT_CONDUCTION, + INeutronBehaviour.of(scatteringType, params, size), + NuclearConstant.DESINTEGRATION_BY_ROD)) + .withCustomPath("%s_control_rod"); + } + +} diff --git a/src/main/java/aztech/modern_industrialization/materials/part/MIParts.java b/src/main/java/aztech/modern_industrialization/materials/part/MIParts.java index 3eaf2fa89..f4eccd079 100644 --- a/src/main/java/aztech/modern_industrialization/materials/part/MIParts.java +++ b/src/main/java/aztech/modern_industrialization/materials/part/MIParts.java @@ -89,6 +89,8 @@ public class MIParts { public static final NuclearFuelPart FUEL_ROD_DOUBLE = new NuclearFuelPart(DOUBLE); public static final NuclearFuelPart FUEL_ROD_QUAD = new NuclearFuelPart(QUAD); + public static final ControlRodPart CONTROL_ROD = new ControlRodPart(); + public static final PartTemplate N_DOPED_PLATE = new PartTemplate("N-Doped %s Plate", "n_doped_plate").withOverlay(PLATE, "n_doped"); public static final PartTemplate P_DOPED_PLATE = new PartTemplate("P-Doped %s Plate", "p_doped_plate").withOverlay(PLATE, "p_doped"); diff --git a/src/main/java/aztech/modern_industrialization/materials/part/NuclearFuelPart.java b/src/main/java/aztech/modern_industrialization/materials/part/NuclearFuelPart.java index e95e02a44..4855d616d 100644 --- a/src/main/java/aztech/modern_industrialization/materials/part/NuclearFuelPart.java +++ b/src/main/java/aztech/modern_industrialization/materials/part/NuclearFuelPart.java @@ -25,7 +25,9 @@ import aztech.modern_industrialization.MIItem; import aztech.modern_industrialization.items.SortOrder; +import aztech.modern_industrialization.materials.property.MaterialProperty; import aztech.modern_industrialization.nuclear.INeutronBehaviour; +import aztech.modern_industrialization.nuclear.IsotopeFuelParams; import aztech.modern_industrialization.nuclear.NuclearConstant; import aztech.modern_industrialization.nuclear.NuclearFuel; import aztech.modern_industrialization.nuclear.NuclearFuel.NuclearFuelParams; @@ -61,13 +63,7 @@ public PartKey key() { return key; } - public PartTemplate of(NuclearConstant.IsotopeFuelParams params) { - - NuclearFuelParams fuelParams = new NuclearFuelParams(NuclearConstant.DESINTEGRATION_BY_ROD * type.size, params.maxTemp, params.tempLimitLow, - params.tempLimitHigh, params.neutronsMultiplication, params.directEnergyFactor, type.size); - - INeutronBehaviour neutronBehaviour = INeutronBehaviour.of(NuclearConstant.ScatteringType.HEAVY, params, type.size); - + private PartTemplate of() { String englishNameFormatter = switch (type) { case SIMPLE -> "Fuel Rod"; case DOUBLE -> "Double Fuel Rod"; @@ -75,11 +71,22 @@ public PartTemplate of(NuclearConstant.IsotopeFuelParams params) { case DEPLETED -> "Depleted %s Fuel Rod"; }; - var out = new PartTemplate(englishNameFormatter, - key).withRegister((partContext, part, itemPath, itemId, itemTag, englishName) -> { + var out = new PartTemplate(englishNameFormatter, key) + .withRegister((partContext, part, itemPath, itemId, itemTag, englishName) -> { if (Type.DEPLETED == type) { MIItem.item(englishName, itemPath, SortOrder.ITEMS_OTHER); } else { + IsotopeFuelParams params = partContext.get(MaterialProperty.ISOTOPE); + if (params == null) { + throw new IllegalArgumentException("Material %s must be a fuel isotope".formatted(partContext.getMaterialName())); + } + + NuclearFuelParams fuelParams = new NuclearFuelParams(NuclearConstant.DESINTEGRATION_BY_ROD * type.size, params.maxTemp, + params.tempLimitLow, + params.tempLimitHigh, params.neutronsMultiplication, params.directEnergyFactor, type.size); + + INeutronBehaviour neutronBehaviour = INeutronBehaviour.of(NuclearConstant.ScatteringType.HEAVY, params, type.size); + NuclearFuel.of(englishName, itemPath, fuelParams, neutronBehaviour, partContext.getMaterialName() + "_fuel_rod_depleted"); } @@ -90,8 +97,11 @@ public PartTemplate of(NuclearConstant.IsotopeFuelParams params) { return out; } - public List ofAll(NuclearConstant.IsotopeFuelParams params) { - return List.of(MIParts.FUEL_ROD.of(params), MIParts.FUEL_ROD_DOUBLE.of(params), MIParts.FUEL_ROD_QUAD.of(params), - MIParts.FUEL_ROD_DEPLETED.of(params)); + public static List ofAll() { + return List.of( + MIParts.FUEL_ROD.of(), + MIParts.FUEL_ROD_DOUBLE.of(), + MIParts.FUEL_ROD_QUAD.of(), + MIParts.FUEL_ROD_DEPLETED.of()); } } diff --git a/src/main/java/aztech/modern_industrialization/materials/property/MaterialProperty.java b/src/main/java/aztech/modern_industrialization/materials/property/MaterialProperty.java index bf0800d8f..210411455 100644 --- a/src/main/java/aztech/modern_industrialization/materials/property/MaterialProperty.java +++ b/src/main/java/aztech/modern_industrialization/materials/property/MaterialProperty.java @@ -26,10 +26,12 @@ import aztech.modern_industrialization.materials.part.MIParts; import aztech.modern_industrialization.materials.part.PartKeyProvider; import aztech.modern_industrialization.materials.set.MaterialSet; +import aztech.modern_industrialization.nuclear.IsotopeFuelParams; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.jetbrains.annotations.Nullable; /** * Some extra property for a material @@ -64,4 +66,8 @@ public MaterialProperty(String id, T defaultValue) { * Which template set to use for the textures. */ public static final MaterialProperty SET = new MaterialProperty<>("material_set", MaterialSet.DULL); + /** + * Isotope parameters for nuclear fission fuels. + */ + public static final MaterialProperty<@Nullable IsotopeFuelParams> ISOTOPE = new MaterialProperty<>("isotope", null); } diff --git a/src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponent.java b/src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponent.java new file mode 100644 index 000000000..6317de7e9 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponent.java @@ -0,0 +1,147 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.nuclear; + +import aztech.modern_industrialization.MIFluids; +import aztech.modern_industrialization.compat.kubejs.KubeJSProxy; +import java.util.IdentityHashMap; +import java.util.Map; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.Fluids; +import org.jetbrains.annotations.Nullable; + +public record FluidNuclearComponent( + FluidVariant variant, + double heatConduction, + INeutronBehaviour neutronBehaviour, + FluidVariant neutronProduct, + long neutronProductAmount, + double neutronProductProbability) implements INuclearComponent { + + public FluidNuclearComponent( + Fluid fluid, + double heatConduction, + double density, + NuclearConstant.ScatteringType type, + IsotopeParams params, + FluidVariant neutronProduct, + long neutronProductAmount, + double neutronProductProbability) { + this( + FluidVariant.of(fluid), + heatConduction * density, + INeutronBehaviour.of(type, params, density), + neutronProduct, + neutronProductAmount, + neutronProductProbability); + } + + @Override + public FluidVariant getVariant() { + return variant; + } + + @Override + public double getHeatConduction() { + return heatConduction; + } + + @Override + public INeutronBehaviour getNeutronBehaviour() { + return neutronBehaviour; + } + + @Override + public FluidVariant getNeutronProduct() { + return neutronProduct; + } + + @Override + public long getNeutronProductAmount() { + return neutronProductAmount; + } + + @Override + public double getNeutronProductProbability() { + return neutronProductProbability; + } + + private static final Map registry = new IdentityHashMap<>(); + + public static void register(FluidNuclearComponent component) { + Fluid fluid = component.getVariant().getFluid(); + if (registry.containsKey(fluid)) { + throw new IllegalArgumentException("Already registered fluid-neutron interaction for " + fluid); + } + + registry.put(fluid, component); + } + + public static void remove(Fluid fluid) { + registry.remove(fluid); + } + + @Nullable + public static FluidNuclearComponent get(Fluid fluid) { + return registry.get(fluid); + } + + public static void init() { + register(new FluidNuclearComponent(Fluids.WATER, + NuclearConstant.BASE_HEAT_CONDUCTION * 5, + 1, + NuclearConstant.ScatteringType.ULTRA_LIGHT, + NuclearConstant.HYDROGEN, + MIFluids.DEUTERIUM.variant(), + 1, + 1)); + register(new FluidNuclearComponent(MIFluids.HEAVY_WATER.asFluid(), + NuclearConstant.BASE_HEAT_CONDUCTION * 6, + 1, + NuclearConstant.ScatteringType.LIGHT, + NuclearConstant.DEUTERIUM, + MIFluids.TRITIUM.variant(), + 1, + 1)); + register(new FluidNuclearComponent(MIFluids.HIGH_PRESSURE_WATER.asFluid(), + NuclearConstant.BASE_HEAT_CONDUCTION * 5, + 4, + NuclearConstant.ScatteringType.ULTRA_LIGHT, + NuclearConstant.HYDROGEN, + MIFluids.DEUTERIUM.variant(), + 8, + 0.125)); + register(new FluidNuclearComponent(MIFluids.HIGH_PRESSURE_HEAVY_WATER.asFluid(), + NuclearConstant.BASE_HEAT_CONDUCTION * 6, + 4, + NuclearConstant.ScatteringType.LIGHT, + NuclearConstant.DEUTERIUM, + MIFluids.TRITIUM.variant(), + 8, + 0.125)); + + KubeJSProxy.instance.fireRegisterFluidNeutronInteractionsEvent(); + } +} diff --git a/src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponents.java b/src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponents.java deleted file mode 100644 index 8271658b0..000000000 --- a/src/main/java/aztech/modern_industrialization/nuclear/FluidNuclearComponents.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 Azercoco & Technici4n - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package aztech.modern_industrialization.nuclear; - -import aztech.modern_industrialization.MIFluids; -import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; -import org.jetbrains.annotations.Nullable; - -public class FluidNuclearComponents { - private static final INuclearComponent WATER = create(Fluids.WATER, - NuclearConstant.BASE_HEAT_CONDUCTION * 5, 1, - NuclearConstant.ScatteringType.ULTRA_LIGHT, NuclearConstant.HYDROGEN, - MIFluids.DEUTERIUM.variant(), false); - private static final INuclearComponent HEAVY_WATER = create(MIFluids.HEAVY_WATER.asFluid(), - NuclearConstant.BASE_HEAT_CONDUCTION * 6, 1, - NuclearConstant.ScatteringType.LIGHT, NuclearConstant.DEUTERIUM, - MIFluids.TRITIUM.variant(), false); - private static final INuclearComponent HIGH_PRESSURE_WATER = create(MIFluids.HIGH_PRESSURE_WATER.asFluid(), - NuclearConstant.BASE_HEAT_CONDUCTION * 5, 4, - NuclearConstant.ScatteringType.ULTRA_LIGHT, NuclearConstant.HYDROGEN, - MIFluids.DEUTERIUM.variant(), true); - private static final INuclearComponent HIGH_PRESSURE_HEAVY_WATER = create(MIFluids.HIGH_PRESSURE_HEAVY_WATER.asFluid(), - NuclearConstant.BASE_HEAT_CONDUCTION * 6, 4, - NuclearConstant.ScatteringType.LIGHT, NuclearConstant.DEUTERIUM, - MIFluids.TRITIUM.variant(), true); - - @Nullable - public static INuclearComponent of(FluidVariant variant) { - Fluid fluid = variant.getFluid(); - - if (fluid == Fluids.WATER) { - return WATER; - } else if (fluid == MIFluids.HEAVY_WATER.asFluid()) { - return HEAVY_WATER; - } else if (fluid == MIFluids.HIGH_PRESSURE_WATER.asFluid()) { - return HIGH_PRESSURE_WATER; - } else if (fluid == MIFluids.HIGH_PRESSURE_HEAVY_WATER.asFluid()) { - return HIGH_PRESSURE_HEAVY_WATER; - } - - return null; - } - - private static INuclearComponent create(Fluid fluid, double heatConduction, double density, NuclearConstant.ScatteringType type, - NuclearConstant.IsotopeParams params, FluidVariant neutronProduct, boolean highPressure) { - FluidVariant variant = FluidVariant.of(fluid); - - return new INuclearComponent<>() { - @Override - public double getHeatConduction() { - return heatConduction * density; - } - - @Override - public INeutronBehaviour getNeutronBehaviour() { - return INeutronBehaviour.of(type, params, density); - } - - public FluidVariant getVariant() { - return variant; - } - - public FluidVariant getNeutronProduct() { - return neutronProduct; - } - - public long getNeutronProductAmount() { - return highPressure ? 8 : 1; - } - - public double getNeutronProductProbability() { - return highPressure ? 0.125 : 1; - } - }; - } -} diff --git a/src/main/java/aztech/modern_industrialization/nuclear/INeutronBehaviour.java b/src/main/java/aztech/modern_industrialization/nuclear/INeutronBehaviour.java index 1d27965f5..a5313d425 100644 --- a/src/main/java/aztech/modern_industrialization/nuclear/INeutronBehaviour.java +++ b/src/main/java/aztech/modern_industrialization/nuclear/INeutronBehaviour.java @@ -86,7 +86,7 @@ static double probaFromCrossSection(double crossSection) { return 1 - Math.exp(-crossSection); } - static INeutronBehaviour of(NuclearConstant.ScatteringType scatteringType, NuclearConstant.IsotopeParams params, double size) { + static INeutronBehaviour of(NuclearConstant.ScatteringType scatteringType, IsotopeParams params, double size) { return of(scatteringType, params.thermalAbsorption, params.fastAbsorption, params.thermalScattering, params.fastScattering, size); } diff --git a/src/main/java/aztech/modern_industrialization/nuclear/INuclearTileData.java b/src/main/java/aztech/modern_industrialization/nuclear/INuclearTileData.java index 511347f96..0f8654a3c 100644 --- a/src/main/java/aztech/modern_industrialization/nuclear/INuclearTileData.java +++ b/src/main/java/aztech/modern_industrialization/nuclear/INuclearTileData.java @@ -61,7 +61,7 @@ default INuclearComponent getComponent() { } else if (variant instanceof FluidVariant resource) { if (!resource.isBlank() && getVariantAmount() > 0) { - return FluidNuclearComponents.of(resource); + return FluidNuclearComponent.get(resource.getFluid()); } } diff --git a/src/main/java/aztech/modern_industrialization/nuclear/IsotopeFuelParams.java b/src/main/java/aztech/modern_industrialization/nuclear/IsotopeFuelParams.java new file mode 100644 index 000000000..4460ee482 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/nuclear/IsotopeFuelParams.java @@ -0,0 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.nuclear; + +import aztech.modern_industrialization.materials.Material; +import aztech.modern_industrialization.materials.property.MaterialProperty; + +public class IsotopeFuelParams extends IsotopeParams { + + public final int maxTemp; + public final double neutronsMultiplication; + public final double directEnergyFactor; + public final int tempLimitLow; + public final int tempLimitHigh; + + public IsotopeFuelParams(double thermalAbsorbProba, double thermalScatterings, int maxTemp, int tempLimitLow, int tempLimitHigh, + double neutronsMultiplication, double directEnergyFactor) { + + super(thermalAbsorbProba, INeutronBehaviour.reduceCrossProba(thermalAbsorbProba, 0.1), thermalScatterings, + INeutronBehaviour.reduceCrossProba(thermalScatterings, 0.5)); + + this.maxTemp = maxTemp; + this.neutronsMultiplication = neutronsMultiplication; + this.directEnergyFactor = directEnergyFactor; + this.tempLimitLow = tempLimitLow; + this.tempLimitHigh = tempLimitHigh; + + } + + public static IsotopeFuelParams of(Material material) { + var params = material.get(MaterialProperty.ISOTOPE); + if (params == null) { + throw new IllegalArgumentException("Material %s must be a fuel isotope".formatted(material.name)); + } + return params; + } + + public static IsotopeFuelParams mix(Material a, Material b, double factor) { + return mix(of(a), of(b), factor); + } + + public static IsotopeFuelParams mix(IsotopeFuelParams a, IsotopeFuelParams b, double factor) { + factor = 1 - factor; + + double newThermalAbsorptionProba = INeutronBehaviour.probaFromCrossSection(mix(a.thermalAbsorption, b.thermalAbsorption, factor)); + double newScatteringProba = INeutronBehaviour.probaFromCrossSection(mix(a.thermalScattering, b.thermalScattering, factor)); + double newNeutronMultiplicationFactor = mix(a.neutronsMultiplication, b.neutronsMultiplication, factor); + + double totalEnergy = mix(a.neutronsMultiplication * (1 + a.directEnergyFactor), b.neutronsMultiplication * (1 + b.directEnergyFactor), + factor); + + int newMaxTemp = (int) mix(a.maxTemp, b.maxTemp, factor); + int newTempLimitLow = (int) mix(a.tempLimitLow, b.tempLimitLow, factor); + int newTempLimitHigh = (int) mix(a.tempLimitHigh, b.tempLimitHigh, factor); + + double newDirectEnergyFactor = totalEnergy / (newNeutronMultiplicationFactor) - 1; + + return new IsotopeFuelParams(newThermalAbsorptionProba, newScatteringProba, newMaxTemp, newTempLimitLow, newTempLimitHigh, + newNeutronMultiplicationFactor, newDirectEnergyFactor); + + } + + private static double mix(double a, double b, double r) { + return r * a + (1 - r) * b; + } +} diff --git a/src/main/java/aztech/modern_industrialization/nuclear/IsotopeParams.java b/src/main/java/aztech/modern_industrialization/nuclear/IsotopeParams.java new file mode 100644 index 000000000..bec0d6b50 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/nuclear/IsotopeParams.java @@ -0,0 +1,38 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.nuclear; + +public class IsotopeParams { + public final double thermalAbsorption; + public final double fastAbsorption; + public final double fastScattering; + public final double thermalScattering; + + public IsotopeParams(double thermalAbsorbProba, double fastAbsorptionProba, double thermalScatteringProba, double fastScatteringProba) { + this.thermalAbsorption = INeutronBehaviour.crossSectionFromProba(thermalAbsorbProba); + this.fastAbsorption = INeutronBehaviour.crossSectionFromProba(fastAbsorptionProba); + this.thermalScattering = INeutronBehaviour.crossSectionFromProba(thermalScatteringProba); + this.fastScattering = INeutronBehaviour.crossSectionFromProba(fastScatteringProba); + } +} diff --git a/src/main/java/aztech/modern_industrialization/nuclear/NuclearConstant.java b/src/main/java/aztech/modern_industrialization/nuclear/NuclearConstant.java index 6883dd367..6db912dfe 100644 --- a/src/main/java/aztech/modern_industrialization/nuclear/NuclearConstant.java +++ b/src/main/java/aztech/modern_industrialization/nuclear/NuclearConstant.java @@ -24,7 +24,6 @@ package aztech.modern_industrialization.nuclear; public class NuclearConstant { - public static final int EU_FOR_FAST_NEUTRON = 8; public static final int DESINTEGRATION_BY_ROD = 10240000; public static final double BASE_HEAT_CONDUCTION = 0.01; @@ -48,86 +47,6 @@ public enum ScatteringType { public final double slowFraction; } - public static class IsotopeParams { - public final double thermalAbsorption; - public final double fastAbsorption; - public final double fastScattering; - public final double thermalScattering; - - public IsotopeParams(double thermalAbsorbProba, double fastAbsorptionProba, double thermalScatteringProba, double fastScatteringProba) { - this.thermalAbsorption = INeutronBehaviour.crossSectionFromProba(thermalAbsorbProba); - this.fastAbsorption = INeutronBehaviour.crossSectionFromProba(fastAbsorptionProba); - this.thermalScattering = INeutronBehaviour.crossSectionFromProba(thermalScatteringProba); - this.fastScattering = INeutronBehaviour.crossSectionFromProba(fastScatteringProba); - } - } - - public static class IsotopeFuelParams extends IsotopeParams { - - public final int maxTemp; - public final double neutronsMultiplication; - public final double directEnergyFactor; - public final int tempLimitLow; - public final int tempLimitHigh; - - public IsotopeFuelParams(double thermalAbsorbProba, double thermalScatterings, int maxTemp, int tempLimitLow, int tempLimitHigh, - double neutronsMultiplication, double directEnergyFactor) { - - super(thermalAbsorbProba, INeutronBehaviour.reduceCrossProba(thermalAbsorbProba, 0.1), thermalScatterings, - INeutronBehaviour.reduceCrossProba(thermalScatterings, 0.5)); - - this.maxTemp = maxTemp; - this.neutronsMultiplication = neutronsMultiplication; - this.directEnergyFactor = directEnergyFactor; - this.tempLimitLow = tempLimitLow; - this.tempLimitHigh = tempLimitHigh; - - } - - public static IsotopeFuelParams mix(IsotopeFuelParams a, IsotopeFuelParams b, double factor) { - - factor = 1 - factor; - - double newThermalAbsorptionProba = INeutronBehaviour.probaFromCrossSection(mix(a.thermalAbsorption, b.thermalAbsorption, factor)); - double newScatteringProba = INeutronBehaviour.probaFromCrossSection(mix(a.thermalScattering, b.thermalScattering, factor)); - double newNeutronMultiplicationFactor = mix(a.neutronsMultiplication, b.neutronsMultiplication, factor); - - double totalEnergy = mix(a.neutronsMultiplication * (1 + a.directEnergyFactor), b.neutronsMultiplication * (1 + b.directEnergyFactor), - factor); - - int newMaxTemp = (int) mix(a.maxTemp, b.maxTemp, factor); - int newTempLimitLow = (int) mix(a.tempLimitLow, b.tempLimitLow, factor); - int newTempLimitHigh = (int) mix(a.tempLimitHigh, b.tempLimitHigh, factor); - - double newDirectEnergyFactor = totalEnergy / (newNeutronMultiplicationFactor) - 1; - - return new IsotopeFuelParams(newThermalAbsorptionProba, newScatteringProba, newMaxTemp, newTempLimitLow, newTempLimitHigh, - newNeutronMultiplicationFactor, newDirectEnergyFactor); - - } - - private static double mix(double a, double b, double r) { - return r * a + (1 - r) * b; - } - - public IsotopeFuelParams mix(IsotopeFuelParams b, double factor) { - return IsotopeFuelParams.mix(this, b, factor); - } - - } - - public static final IsotopeFuelParams U235 = new IsotopeFuelParams(0.6, 0.35, 2400, 900, 2300, 8, 0.5); - public static final IsotopeFuelParams U238 = new IsotopeFuelParams(0.6, 0.30, 3200, 1000, 3000, 6, 0.3); - public static final IsotopeFuelParams Pu239 = new IsotopeFuelParams(0.9, 0.25, 2100, 600, 2000, 9, 0.25); - - public static final IsotopeFuelParams U = U238.mix(U235, 1.0 / 81); - - public static final IsotopeFuelParams LEU = U238.mix(U235, 1.0 / 9); - public static final IsotopeFuelParams HEU = U238.mix(U235, 1.0 / 3); - - public static final IsotopeFuelParams LE_MOX = U238.mix(Pu239, 1.0 / 9); - public static final IsotopeFuelParams HE_MOX = U238.mix(Pu239, 1.0 / 3); - public static final IsotopeParams HYDROGEN = new IsotopeParams(0.1, 0.05, 0.25, 0.75); public static final IsotopeParams DEUTERIUM = new IsotopeParams(0.02, 0.01, 0.15, 0.65);