aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/tectech/recipe
diff options
context:
space:
mode:
authorNotAPenguin <michiel.vandeginste@gmail.com>2024-09-02 23:17:17 +0200
committerGitHub <noreply@github.com>2024-09-02 23:17:17 +0200
commit1b820de08a05070909a267e17f033fcf58ac8710 (patch)
tree02831a025986a06b20f87e5bcc69d1e0c639a342 /src/main/java/tectech/recipe
parentafd3fd92b6a6ab9ab0d0dc3214e6bc8ff7a86c9b (diff)
downloadGT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.gz
GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.bz2
GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.zip
The Great Renaming (#3014)
* move kekztech to a single root dir * move detrav to a single root dir * move gtnh-lanthanides to a single root dir * move tectech and delete some gross reflection in gt++ * remove more reflection inside gt5u * delete more reflection in gt++ * fix imports * move bartworks and bwcrossmod * fix proxies * move galactigreg and ggfab * move gtneioreplugin * try to fix gt++ bee loader * apply the rename rules to BW * apply rename rules to bwcrossmod * apply rename rules to detrav scanner mod * apply rename rules to galacticgreg * apply rename rules to ggfab * apply rename rules to goodgenerator * apply rename rules to gtnh-lanthanides * apply rename rules to gt++ * apply rename rules to kekztech * apply rename rules to kubatech * apply rename rules to tectech * apply rename rules to gt apply the rename rules to gt * fix tt import * fix mui hopefully * fix coremod except intergalactic * rename assline recipe class * fix a class name i stumbled on * rename StructureUtility to GTStructureUtility to prevent conflict with structurelib * temporary rename of GTTooltipDataCache to old name * fix gt client/server proxy names
Diffstat (limited to 'src/main/java/tectech/recipe')
-rw-r--r--src/main/java/tectech/recipe/EyeOfHarmonyFrontend.java206
-rw-r--r--src/main/java/tectech/recipe/EyeOfHarmonyRecipe.java465
-rw-r--r--src/main/java/tectech/recipe/EyeOfHarmonyRecipeStorage.java186
-rw-r--r--src/main/java/tectech/recipe/GodforgeExoticFrontend.java82
-rw-r--r--src/main/java/tectech/recipe/GodforgePlasmaFrontend.java79
-rw-r--r--src/main/java/tectech/recipe/ResearchStationFrontend.java101
-rw-r--r--src/main/java/tectech/recipe/TTRecipeAdder.java251
-rw-r--r--src/main/java/tectech/recipe/TecTechRecipeMaps.java78
8 files changed, 1448 insertions, 0 deletions
diff --git a/src/main/java/tectech/recipe/EyeOfHarmonyFrontend.java b/src/main/java/tectech/recipe/EyeOfHarmonyFrontend.java
new file mode 100644
index 0000000000..4e1c40eb41
--- /dev/null
+++ b/src/main/java/tectech/recipe/EyeOfHarmonyFrontend.java
@@ -0,0 +1,206 @@
+package tectech.recipe;
+
+import static com.google.common.math.LongMath.pow;
+import static gregtech.api.util.GTUtility.formatNumbers;
+import static java.lang.Math.min;
+import static net.minecraft.util.EnumChatFormatting.BOLD;
+import static net.minecraft.util.EnumChatFormatting.DARK_RED;
+import static net.minecraft.util.EnumChatFormatting.RESET;
+import static net.minecraft.util.StatCollector.translateToLocal;
+import static net.minecraft.util.StatCollector.translateToLocalFormatted;
+import static tectech.util.CommonValues.EOH_TIER_FANCY_NAMES;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+
+import com.gtnewhorizons.modularui.api.math.Alignment;
+import com.gtnewhorizons.modularui.api.math.Pos2d;
+import com.gtnewhorizons.modularui.api.math.Size;
+
+import appeng.util.ReadableNumberConverter;
+import codechicken.nei.PositionedStack;
+import gregtech.api.recipe.BasicUIPropertiesBuilder;
+import gregtech.api.recipe.NEIRecipePropertiesBuilder;
+import gregtech.api.recipe.RecipeMapFrontend;
+import gregtech.api.util.GTLanguageManager;
+import gregtech.api.util.MethodsReturnNonnullByDefault;
+import gregtech.common.gui.modularui.UIHelper;
+import gregtech.nei.GTNEIDefaultHandler;
+import gregtech.nei.RecipeDisplayInfo;
+import gregtech.nei.formatter.INEISpecialInfoFormatter;
+
+@ParametersAreNonnullByDefault
+@MethodsReturnNonnullByDefault
+public class EyeOfHarmonyFrontend extends RecipeMapFrontend {
+
+ private static final int xDirMaxCount = 9;
+ private static final int itemRows = 9, fluidRows = 2;
+ public static final int maxItemInputs = 1, maxItemOutputs = xDirMaxCount * itemRows, maxFluidInputs = 0,
+ maxFluidOutputs = xDirMaxCount * fluidRows;
+ private static final int yOrigin = 8;
+ private static final long TRILLION = pow(10, 12);
+
+ public EyeOfHarmonyFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder,
+ NEIRecipePropertiesBuilder neiPropertiesBuilder) {
+ super(
+ uiPropertiesBuilder.logoPos(new Pos2d(8, yOrigin)),
+ neiPropertiesBuilder.recipeBackgroundSize(new Size(170, 117 + (itemRows + fluidRows - 4) * 18))
+ .neiSpecialInfoFormatter(new EyeOfHarmonySpecialValueFormatter()));
+ }
+
+ @Override
+ public List<Pos2d> getItemInputPositions(int itemInputCount) {
+ return UIHelper.getGridPositions(itemInputCount, 79, yOrigin, 1, 1);
+ }
+
+ public static final int maxItemsToRender = 80;
+
+ @Override
+ public List<Pos2d> getItemOutputPositions(int itemOutputCount) {
+ return UIHelper.getGridPositions(min(itemOutputCount, maxItemsToRender + 1), 7, yOrigin + 36, xDirMaxCount, 12);
+ }
+
+ @Override
+ public List<Pos2d> getFluidInputPositions(int fluidInputCount) {
+ return UIHelper.getGridPositions(fluidInputCount, 0, 0, 0, 0);
+ }
+
+ @Override
+ public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) {
+ return UIHelper.getGridPositions(fluidOutputCount, 7, yOrigin + 13 * 17 - 7 - 16, xDirMaxCount, 3);
+ }
+
+ @Override
+ public List<String> handleNEIItemTooltip(ItemStack stack, List<String> currentTip,
+ GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) {
+ super.handleNEIItemTooltip(stack, currentTip, neiCachedRecipe);
+ EyeOfHarmonyRecipe currentRecipe = (EyeOfHarmonyRecipe) neiCachedRecipe.mRecipe.mSpecialItems;
+
+ // Draw tooltip on planet item.
+ if (stack.isItemEqual(currentRecipe.getRecipeTriggerItem())) {
+ currentTip.add(
+ EnumChatFormatting.GRAY + translateToLocalFormatted(
+ "tt.nei.eoh.total_items",
+ formatNumbers(currentRecipe.getSumOfItems())));
+ return currentTip;
+ }
+
+ // Draw tooltip on other items.
+ double percentage = currentRecipe.getItemStackToProbabilityMap()
+ .getOrDefault(stack, -1.0);
+
+ if (percentage != -1.0) {
+ currentTip.add(EnumChatFormatting.GRAY + translateToLocalFormatted("tt.nei.eoh.solid_mass", percentage));
+ currentTip.add(
+ EnumChatFormatting.GRAY + translateToLocalFormatted(
+ "tt.nei.eoh.item_count",
+ formatNumbers(
+ currentRecipe.getItemStackToTrueStackSizeMap()
+ .get(stack))));
+ }
+
+ return currentTip;
+ }
+
+ @Override
+ public void drawNEIOverlays(GTNEIDefaultHandler.CachedDefaultRecipe neiCachedRecipe) {
+ EyeOfHarmonyRecipe EOHRecipe = (EyeOfHarmonyRecipe) neiCachedRecipe.mRecipe.mSpecialItems;
+ for (PositionedStack stack : neiCachedRecipe.mInputs) {
+ if (stack instanceof GTNEIDefaultHandler.FixedPositionedStack) {
+ if (stack.item.isItemEqual(EOHRecipe.getRecipeTriggerItem())) {
+ drawNEIOverlayText(translateToLocal("NC"), stack);
+ }
+ }
+ }
+ for (PositionedStack stack : neiCachedRecipe.mOutputs) {
+ if (stack instanceof GTNEIDefaultHandler.FixedPositionedStack) {
+ if (EOHRecipe.getItemStackToTrueStackSizeMap()
+ .containsKey(stack.item)) {
+ long stackSize = EOHRecipe.getItemStackToTrueStackSizeMap()
+ .get(stack.item);
+ String displayString;
+ if (stackSize > 9999) {
+ displayString = ReadableNumberConverter.INSTANCE.toWideReadableForm(stackSize);
+ } else {
+ displayString = String.valueOf(stackSize);
+ }
+
+ drawNEIOverlayText(displayString, stack, 0xffffff, 0.5f, true, Alignment.BottomRight);
+ }
+ }
+ }
+ }
+
+ private static class EyeOfHarmonySpecialValueFormatter implements INEISpecialInfoFormatter {
+
+ @Override
+ public List<String> format(RecipeDisplayInfo recipeInfo) {
+ EyeOfHarmonyRecipe recipe = (EyeOfHarmonyRecipe) recipeInfo.recipe.mSpecialItems;
+ List<String> result = new ArrayList<>();
+
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.Hydrogen.In", "Hydrogen") + ": "
+ + formatNumbers(recipe.getHydrogenRequirement())
+ + " L");
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.Helium.In", "Helium") + ": "
+ + formatNumbers(recipe.getHydrogenRequirement())
+ + " L");
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.SpacetimeTier", "Spacetime Tier") + ": "
+ + EOH_TIER_FANCY_NAMES[(int) recipe.getSpacetimeCasingTierRequired()]);
+
+ if (recipe.getEUOutput() < TRILLION) {
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.EU.Out", "EU Output") + ": "
+ + formatNumbers(recipe.getEUOutput())
+ + " EU");
+ } else {
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.EU.Out", "EU Output") + ": "
+ + ReadableNumberConverter.INSTANCE.toWideReadableForm(recipe.getEUOutput())
+ + " EU");
+ }
+
+ if (recipe.getEUOutput() < TRILLION) {
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.EU.In", "EU Input") + ": "
+ + formatNumbers(recipe.getEUStartCost())
+ + " EU");
+ } else {
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.EU.In", "EU Input") + ": "
+ + ReadableNumberConverter.INSTANCE.toWideReadableForm(recipe.getEUStartCost())
+ + " EU");
+ }
+
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.BaseRecipeChance", "Base Recipe Chance") + ": "
+ + formatNumbers(100 * recipe.getBaseRecipeSuccessChance())
+ + "%");
+ result.add(
+ GTLanguageManager.addStringLocalization("EOH.Recipe.RecipeEnergyEfficiency", "Recipe Energy Efficiency")
+ + ": "
+ + formatNumbers(100 * recipe.getRecipeEnergyEfficiency())
+ + "%");
+
+ if (recipe.getOutputItems()
+ .size() > maxItemsToRender) {
+ result.add(
+ "" + DARK_RED
+ + BOLD
+ + GTLanguageManager.addStringLocalization("EOH.Recipe.Warning.0", "Warning")
+ + RESET
+ + ": "
+ + GTLanguageManager.addStringLocalization("EOH.Recipe.Warning.1", "Not all items displayed."));
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/src/main/java/tectech/recipe/EyeOfHarmonyRecipe.java b/src/main/java/tectech/recipe/EyeOfHarmonyRecipe.java
new file mode 100644
index 0000000000..90acd63048
--- /dev/null
+++ b/src/main/java/tectech/recipe/EyeOfHarmonyRecipe.java
@@ -0,0 +1,465 @@
+package tectech.recipe;
+
+import static com.google.common.math.IntMath.pow;
+import static gregtech.api.GregTechAPI.getUnificatedOreDictStack;
+import static gregtech.api.enums.Mods.NewHorizonsCoreMod;
+import static gregtech.api.util.GTModHandler.getModItem;
+import static gregtech.api.util.GTUtility.getPlasmaFuelValueInEUPerLiterFromMaterial;
+import static java.lang.Math.min;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import gnu.trove.map.TMap;
+import gnu.trove.map.hash.TCustomHashMap;
+import gnu.trove.strategy.HashingStrategy;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.MaterialsUEVplus;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.util.GTOreDictUnificator;
+import gtneioreplugin.plugin.block.BlockDimensionDisplay;
+import gtneioreplugin.util.GT5OreLayerHelper;
+import gtneioreplugin.util.GT5OreSmallHelper;
+import tectech.util.FluidStackLong;
+import tectech.util.ItemStackLong;
+
+@SuppressWarnings("SpellCheckingInspection")
+public class EyeOfHarmonyRecipe {
+
+ static final FluidStackLong[] SPECIAL_FLUIDS = new FluidStackLong[] {
+ new FluidStackLong(MaterialsUEVplus.WhiteDwarfMatter.getMolten(1_152), 1_152),
+ new FluidStackLong(MaterialsUEVplus.WhiteDwarfMatter.getMolten(1_152), 1_152),
+ new FluidStackLong(MaterialsUEVplus.WhiteDwarfMatter.getMolten(4_608), 4_608),
+ new FluidStackLong(MaterialsUEVplus.WhiteDwarfMatter.getMolten(18_432), 18_432),
+ new FluidStackLong(MaterialsUEVplus.BlackDwarfMatter.getMolten(1_152), 1_152),
+ new FluidStackLong(MaterialsUEVplus.BlackDwarfMatter.getMolten(4_608), 4_608),
+ new FluidStackLong(MaterialsUEVplus.BlackDwarfMatter.getMolten(18_432), 18_432),
+ new FluidStackLong(MaterialsUEVplus.Universium.getMolten(1_152), 1_152),
+ new FluidStackLong(MaterialsUEVplus.Universium.getMolten(4_608), 4_608),
+ new FluidStackLong(MaterialsUEVplus.Universium.getMolten(18_432), 18_432) };
+
+ HashingStrategy<ItemStack> itemStackHashingStrategy = new HashingStrategy<>() {
+
+ private static final long serialVersionUID = -3966004160368229212L;
+
+ @Override
+ public int computeHashCode(ItemStack stack) {
+ // Not really sure how this works or if it is "unique enough".
+ int result = stack.getItem()
+ .hashCode();
+ result = 31 * result + stack.getItemDamage();
+ return result;
+ }
+
+ @Override
+ public boolean equals(ItemStack item1, ItemStack item2) {
+ return item1.getUnlocalizedName()
+ .equals(item2.getUnlocalizedName());
+ }
+ };
+
+ private final TMap<ItemStack, Double> itemStackToProbabilityMap = new TCustomHashMap<>(itemStackHashingStrategy);
+ private final TMap<ItemStack, Long> itemStackToTrueStackSizeMap = new TCustomHashMap<>(itemStackHashingStrategy);
+
+ private final ArrayList<ItemStackLong> outputItems;
+ private final ArrayList<FluidStackLong> outputFluids;
+
+ private final long hydrogenRequirement;
+ private final long heliumRequirement;
+
+ private final long euOutput;
+ private final long euStartCost;
+
+ private final double baseSuccessChance;
+
+ private final long spacetimeCasingTierRequired;
+
+ private final long miningTimeSeconds;
+
+ private final double recipeEnergyEfficiency;
+
+ private final ItemStack recipeTriggerItem;
+
+ private final long sumOfItems;
+ private final long rocketTier;
+
+ public TMap<ItemStack, Double> getItemStackToProbabilityMap() {
+ return itemStackToProbabilityMap;
+ }
+
+ public TMap<ItemStack, Long> getItemStackToTrueStackSizeMap() {
+ return itemStackToTrueStackSizeMap;
+ }
+
+ public double getRecipeEnergyEfficiency() {
+ return recipeEnergyEfficiency;
+ }
+
+ @SuppressWarnings("FieldCanBeLocal")
+ private final long standardRecipeEUOutPerTick = 100 * EyeOfHarmonyRecipeStorage.BILLION;
+
+ public long getSumOfItems() {
+ return sumOfItems;
+ }
+
+ public long getRocketTier() {
+ return rocketTier;
+ }
+
+ public EyeOfHarmonyRecipe(final ArrayList<Pair<Materials, Long>> materialList, final BlockDimensionDisplay block,
+ final double recipeEnergyEfficiency, final long hydrogenRequirement, final long heliumRequirement,
+ final long miningTimeSeconds, final long rocketTierOfRecipe, final double baseSuccessChance) {
+
+ this.rocketTier = rocketTierOfRecipe;
+ this.spacetimeCasingTierRequired = min(8, rocketTierOfRecipe);
+
+ this.recipeTriggerItem = new ItemStack(block);
+
+ this.outputItems = validDustGenerator(materialList);
+
+ this.sumOfItems = this.outputItems.stream()
+ .map(ItemStackLong::getStackSize)
+ .reduce(0L, Long::sum);
+
+ this.outputItems.add(new ItemStackLong(getStoneDustType(block.getDimension()), this.sumOfItems * 3L));
+ this.outputItems.sort(Comparator.comparingLong(ItemStackLong::getStackSize));
+ Collections.reverse(this.outputItems);
+
+ for (ItemStackLong itemStackLong : outputItems) {
+ double stackSize = (double) itemStackLong.getStackSize();
+ double probability = Math.round(100_000 * stackSize / sumOfItems) / 1000.0;
+
+ itemStackToProbabilityMap.put(itemStackLong.itemStack, probability);
+ itemStackToTrueStackSizeMap.put(itemStackLong.itemStack, itemStackLong.stackSize);
+ }
+ // End item processing.
+
+ // --- Fluid handling ---
+ ArrayList<FluidStackLong> fluidStackLongArrayList = new ArrayList<>();
+
+ int plasmaAmount = (int) ((this.spacetimeCasingTierRequired + 1) * 8_000_000L);
+
+ // If DeepDark then it should output all plasmas involved in making exotic catalyst.
+ if (rocketTier == 9) {
+ for (Materials material : VALID_PLASMAS) {
+ fluidStackLongArrayList.add(new FluidStackLong(material.getPlasma(plasmaAmount), plasmaAmount));
+ }
+ } else {
+ // --- Output and process fluids of the recipe.
+ ArrayList<FluidStack> fluidStackArrayList = new ArrayList<>(validPlasmaGenerator(materialList));
+ for (FluidStack fluidStack : fluidStackArrayList) {
+ fluidStack = new FluidStack(fluidStack, plasmaAmount);
+ fluidStackLongArrayList.add(new FluidStackLong(fluidStack, plasmaAmount));
+ }
+ }
+
+ // Add a bonus fluid of compressed star matter.
+ fluidStackLongArrayList.add(
+ new FluidStackLong(
+ MaterialsUEVplus.RawStarMatter.getFluid((this.spacetimeCasingTierRequired + 1) * 100_000),
+ (this.spacetimeCasingTierRequired + 1) * 100_000));
+
+ // Tier 0 & 1 - 576 White
+ // Tier 2 - 2304 White
+ // Tier 3 - 9216 White
+
+ // Tier 4 - 576 Black
+ // Tier 5 - 2304 Black
+ // Tier 6 - 9216 Black
+
+ // Tier 7 - 576 Universium
+ // Tier 8 - 2304 Universium
+ // Tier 9 - 9216 Universium
+ int spacetimeTier = (int) rocketTierOfRecipe;
+ if (spacetimeTier == 0 || spacetimeTier == 9) {
+ spacetimeTier -= 1;
+ }
+ fluidStackLongArrayList.add(SPECIAL_FLUIDS[spacetimeTier + 1]);
+
+ outputFluids = fluidStackLongArrayList;
+ // --- End fluid handling ---.
+
+ this.hydrogenRequirement = hydrogenRequirement;
+ this.heliumRequirement = heliumRequirement;
+
+ this.baseSuccessChance = baseSuccessChance;
+
+ this.miningTimeSeconds = miningTimeSeconds;
+ this.recipeEnergyEfficiency = recipeEnergyEfficiency;
+
+ long plasmaEU = plasmaCostCalculator(outputFluids);
+ long VM3EU = miningTimeSeconds * pow(2, 19) * 20;
+ this.euStartCost = (plasmaEU + VM3EU + standardRecipeEUOutPerTick * 20 * miningTimeSeconds);
+ this.euOutput = (long) (euStartCost * recipeEnergyEfficiency);
+ }
+
+ private ItemStack getStoneDustType(String key) {
+ ItemStack placeholder = GTOreDictUnificator.get(OrePrefixes.dust, Materials.Stone, 1);
+ return switch (key) {
+ case "Ne" -> GTOreDictUnificator.get(OrePrefixes.dust, Materials.Netherrack, 1);
+ case "ED", "VA", "EA" -> GTOreDictUnificator.get(OrePrefixes.dust, Materials.Endstone, 1);
+ case "Mo" -> getModItem(NewHorizonsCoreMod.ID, "item.MoonStoneDust", 1, placeholder);
+ case "De" -> getModItem(NewHorizonsCoreMod.ID, "item.DeimosStoneDust", 1, placeholder);
+ case "Ma" -> getModItem(NewHorizonsCoreMod.ID, "item.MarsStoneDust", 1, placeholder);
+ case "Ph" -> getModItem(NewHorizonsCoreMod.ID, "item.PhobosStoneDust", 1, placeholder);
+ case "As", "KB" -> getModItem(NewHorizonsCoreMod.ID, "item.AsteroidsStoneDust", 1, placeholder);
+ case "Ca" -> getModItem(NewHorizonsCoreMod.ID, "item.CallistoStoneDust", 1, placeholder);
+ case "Ce" -> getModItem(NewHorizonsCoreMod.ID, "item.CeresStoneDust", 1, placeholder);
+ case "Eu" -> getModItem(NewHorizonsCoreMod.ID, "item.EuropaStoneDust", 1, placeholder);
+ case "Ga" -> getModItem(NewHorizonsCoreMod.ID, "item.GanymedeStoneDust", 1, placeholder);
+ case "Io" -> getModItem(NewHorizonsCoreMod.ID, "item.IoStoneDust", 1, placeholder);
+ case "Me" -> getModItem(NewHorizonsCoreMod.ID, "item.MercuryStoneDust", 1, placeholder);
+ case "Ve" -> getModItem(NewHorizonsCoreMod.ID, "item.VenusStoneDust", 1, placeholder);
+ case "En" -> getModItem(NewHorizonsCoreMod.ID, "item.EnceladusStoneDust", 1, placeholder);
+ case "Mi" -> getModItem(NewHorizonsCoreMod.ID, "item.MirandaStoneDust", 1, placeholder);
+ case "Ob" -> getModItem(NewHorizonsCoreMod.ID, "item.OberonStoneDust", 1, placeholder);
+ case "Ti" -> getModItem(NewHorizonsCoreMod.ID, "item.TitanStoneDust", 1, placeholder);
+ case "Pr" -> getModItem(NewHorizonsCoreMod.ID, "item.ProteusStoneDust", 1, placeholder);
+ case "Tr" -> getModItem(NewHorizonsCoreMod.ID, "item.TritonStoneDust", 1, placeholder);
+ case "Ha" -> getModItem(NewHorizonsCoreMod.ID, "item.HaumeaStoneDust", 1, placeholder);
+ case "MM" -> getModItem(NewHorizonsCoreMod.ID, "item.MakeMakeStoneDust", 1, placeholder);
+ case "Pl" -> getModItem(NewHorizonsCoreMod.ID, "item.PlutoStoneDust", 1, placeholder);
+ case "BE" -> getModItem(NewHorizonsCoreMod.ID, "item.BarnardaEStoneDust", 1, placeholder);
+ case "BF" -> getModItem(NewHorizonsCoreMod.ID, "item.BarnardaFStoneDust", 1, placeholder);
+ case "CB" -> getModItem(NewHorizonsCoreMod.ID, "item.CentauriAStoneDust", 1, placeholder);
+ case "TE" -> getModItem(NewHorizonsCoreMod.ID, "item.TCetiEStoneDust", 1, placeholder);
+ case "VB" -> getModItem(NewHorizonsCoreMod.ID, "item.VegaBStoneDust", 1, placeholder);
+ default -> placeholder;
+ };
+ }
+
+ public EyeOfHarmonyRecipe(final GT5OreLayerHelper.NormalOreDimensionWrapper normalOreDimensionWrapper,
+ final GT5OreSmallHelper.SmallOreDimensionWrapper smallOreDimensionWrapper, final BlockDimensionDisplay block,
+ final double recipeEnergyEfficiency, final long hydrogenRequirement, final long heliumRequirement,
+ final long miningTimeSeconds, final long spacetimeCasingTierRequired, final double baseSuccessChance) {
+
+ // Process recipes output items.
+ // 6 * 64 = 6 stacks/second for VM tier 3 + Og gas.
+ this(
+ processDimension(normalOreDimensionWrapper, smallOreDimensionWrapper, miningTimeSeconds),
+ block,
+ recipeEnergyEfficiency,
+ hydrogenRequirement,
+ heliumRequirement,
+ miningTimeSeconds,
+ spacetimeCasingTierRequired,
+ baseSuccessChance);
+ }
+
+ // Return clone of list. Deep copy. Maybe a better way to do this?
+ public ArrayList<ItemStackLong> getOutputItems() {
+ ArrayList<ItemStackLong> copyOutputList = new ArrayList<>();
+ for (ItemStackLong itemStackLong : outputItems) {
+ copyOutputList.add(new ItemStackLong(itemStackLong));
+ }
+
+ return copyOutputList;
+ }
+
+ // Deep copy.
+ public ArrayList<FluidStackLong> getOutputFluids() {
+ ArrayList<FluidStackLong> copyOutputList = new ArrayList<>();
+
+ for (FluidStackLong fluidStackLong : outputFluids) {
+ copyOutputList.add(new FluidStackLong(fluidStackLong));
+ }
+
+ return copyOutputList;
+ }
+
+ public long getHydrogenRequirement() {
+ return hydrogenRequirement;
+ }
+
+ public long getHeliumRequirement() {
+ return heliumRequirement;
+ }
+
+ public long getEUOutput() {
+ return euOutput;
+ }
+
+ public long getEUStartCost() {
+ return euStartCost;
+ }
+
+ public long getRecipeTimeInTicks() {
+ return miningTimeSeconds * 20;
+ }
+
+ public double getBaseRecipeSuccessChance() {
+ return baseSuccessChance;
+ }
+
+ public long getSpacetimeCasingTierRequired() {
+ return spacetimeCasingTierRequired;
+ }
+
+ public ItemStack getRecipeTriggerItem() {
+ return recipeTriggerItem;
+ }
+
+ private static final double PRIMARY_MULTIPLIER = (0.1 + 1.0 / 9.0); // Byproduct from macerating/washing chance.
+ private static final double SECONDARY_MULTIPLIER = (1.0 / 9.0); // Thermal centrifuge byproduct chance.
+ private static final double TERTIARY_MULTIPLIER = (0.1); // Macerating thermal centrifuged byproduct chance.
+ private static final double QUATERNARY_MULTIPLIER = (0.7); // Mercury/chem bath processing chance.
+
+ private static final double[] ORE_MULTIPLIER = { PRIMARY_MULTIPLIER, SECONDARY_MULTIPLIER, TERTIARY_MULTIPLIER,
+ QUATERNARY_MULTIPLIER };
+
+ public static class HashMapHelper extends HashMap<Materials, Double> {
+
+ private static final long serialVersionUID = 2297018142561480614L;
+
+ void add(Materials material, double value) {
+
+ // If key already exists.
+ if (this.containsKey(material)) {
+ this.put(material, value + this.get(material));
+ return;
+ }
+
+ // Otherwise, add value to hashmap entry.
+ this.put(material, value);
+ }
+ }
+
+ public static void processHelper(HashMapHelper outputMap, Materials material, double mainMultiplier,
+ double probability) {
+ if (material == null) return;
+ outputMap.add(material.mDirectSmelting, (material.mOreMultiplier * 2) * mainMultiplier * probability);
+
+ int index = 0;
+ for (Materials byProductMaterial : material.mOreByProducts) {
+ outputMap
+ .add(byProductMaterial.mDirectSmelting, mainMultiplier * (ORE_MULTIPLIER[index++] * 2) * probability);
+ }
+ }
+
+ private static ArrayList<Pair<Materials, Long>> processDimension(
+ GT5OreLayerHelper.NormalOreDimensionWrapper normalOreDimWrapper,
+ GT5OreSmallHelper.SmallOreDimensionWrapper smallOreDimWrapper, long timeInSeconds) {
+ HashMapHelper outputMap = new HashMapHelper();
+
+ double mainMultiplier = timeInSeconds * 384.0;
+
+ if (normalOreDimWrapper != null) {
+ normalOreDimWrapper.oreVeinToProbabilityInDimension.forEach((veinInfo, probability) -> {
+ processHelper(outputMap, veinInfo.mPrimaryVeinMaterial, mainMultiplier, probability);
+ processHelper(outputMap, veinInfo.mSecondaryMaterial, mainMultiplier, probability);
+ // 8.0 to replicate void miner getDropsVanillaVeins method yields.
+ processHelper(outputMap, veinInfo.mBetweenMaterial, mainMultiplier / 8.0, probability);
+ processHelper(outputMap, veinInfo.mSporadicMaterial, mainMultiplier / 8.0, probability);
+ });
+ }
+
+ // Iterate over small ores in dimension and add them, kinda hacky but works and is close enough.
+ if (smallOreDimWrapper != null) {
+ smallOreDimWrapper.oreVeinToProbabilityInDimension.forEach(
+ (veinInfo,
+ probability) -> processHelper(outputMap, veinInfo.getOreMaterial(), mainMultiplier, probability));
+ }
+
+ ArrayList<Pair<Materials, Long>> outputList = new ArrayList<>();
+
+ outputMap.forEach((material, quantity) -> outputList.add(Pair.of(material, (long) Math.floor(quantity))));
+
+ return outputList;
+ }
+
+ private static ArrayList<FluidStack> validPlasmaGenerator(final List<Pair<Materials, Long>> planetList) {
+
+ ArrayList<FluidStack> plasmaList = new ArrayList<>();
+
+ for (Pair<Materials, Long> pair : planetList) {
+ if (VALID_PLASMAS.contains(pair.getLeft())) {
+ plasmaList.add(
+ pair.getLeft()
+ .getPlasma(1));
+ }
+ }
+
+ return plasmaList;
+ }
+
+ private static ArrayList<ItemStackLong> validDustGenerator(final ArrayList<Pair<Materials, Long>> planetList) {
+
+ ArrayList<ItemStackLong> dustList = new ArrayList<>();
+
+ for (Pair<Materials, Long> pair : planetList) {
+ ItemStack dust = getUnificatedOreDictStack(
+ pair.getLeft()
+ .getDust(1));
+ if (dust != null) {
+ dustList.add(new ItemStackLong(dust, pair.getRight()));
+ }
+ }
+ return dustList;
+ }
+
+ private static long plasmaCostCalculator(ArrayList<FluidStackLong> plasmas) {
+ long total = 0;
+
+ for (FluidStackLong plasma : plasmas) {
+ FluidStack plasmaFluid = plasma.getRegularFluidStack(plasma, 1);
+ try {
+ String plasmaName = plasmaFluid.getFluid()
+ .getUnlocalizedName();
+ total += plasmaEnergyMap.getOrDefault(plasmaName, 0L) * plasma.amount;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ return (long) (total * getMaxPlasmaTurbineEfficiency());
+ }
+
+ private static double getMaxPlasmaTurbineEfficiency() {
+ // I hate Shirabon.
+ return 3.85;
+ }
+
+ private static final List<Materials> VALID_PLASMAS = Stream
+ .of(
+ Materials.Helium,
+ Materials.Iron,
+ Materials.Calcium,
+ Materials.Niobium,
+ Materials.Nitrogen,
+ Materials.Zinc,
+ Materials.Silver,
+ Materials.Titanium,
+ Materials.Radon,
+ Materials.Nickel,
+ Materials.Boron,
+ Materials.Sulfur,
+ Materials.Americium,
+ Materials.Bismuth,
+ Materials.Oxygen,
+ Materials.Tin)
+ .collect(Collectors.toList());
+
+ private static final HashMap<String, Long> plasmaEnergyMap = new HashMap<>() {
+
+ private static final long serialVersionUID = 7933945171103801933L;
+
+ {
+ VALID_PLASMAS.forEach(
+ (material -> put(
+ material.getPlasma(1)
+ .getFluid()
+ .getUnlocalizedName(),
+ (long) (getPlasmaFuelValueInEUPerLiterFromMaterial(material) * getMaxPlasmaTurbineEfficiency()))));
+ }
+ };
+}
diff --git a/src/main/java/tectech/recipe/EyeOfHarmonyRecipeStorage.java b/src/main/java/tectech/recipe/EyeOfHarmonyRecipeStorage.java
new file mode 100644
index 0000000000..30671dc919
--- /dev/null
+++ b/src/main/java/tectech/recipe/EyeOfHarmonyRecipeStorage.java
@@ -0,0 +1,186 @@
+package tectech.recipe;
+
+import static java.lang.Math.pow;
+import static tectech.recipe.EyeOfHarmonyRecipe.processHelper;
+import static tectech.recipe.TecTechRecipeMaps.eyeOfHarmonyRecipes;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.FluidStack;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.google.common.math.LongMath;
+
+import gregtech.api.enums.GTValues;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.MaterialsUEVplus;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.util.GTOreDictUnificator;
+import gtneioreplugin.plugin.block.BlockDimensionDisplay;
+import gtneioreplugin.plugin.block.ModBlocks;
+import gtneioreplugin.util.DimensionHelper;
+import gtneioreplugin.util.GT5OreLayerHelper;
+import gtneioreplugin.util.GT5OreSmallHelper;
+import tectech.util.FluidStackLong;
+import tectech.util.ItemStackLong;
+
+public class EyeOfHarmonyRecipeStorage {
+
+ public static final long BILLION = LongMath.pow(10, 9);
+ private static final double CHANCE_DECREASE_PER_DIMENSION = 0.05;
+
+ // Map is unique so this is fine.
+ HashMap<Block, String> blocksMapInverted = new HashMap<>() {
+
+ private static final long serialVersionUID = -1634011860327553337L;
+
+ {
+ ModBlocks.blocks.forEach((dimString, dimBlock) -> { put(dimBlock, dimString); });
+ }
+ };
+
+ private final HashMap<String, EyeOfHarmonyRecipe> recipeHashMap = new HashMap<String, EyeOfHarmonyRecipe>() {
+
+ private static final long serialVersionUID = -3501819612517400500L;
+
+ {
+ for (String dimAbbreviation : DimensionHelper.DimNameDisplayed) {
+ BlockDimensionDisplay blockDimensionDisplay = (BlockDimensionDisplay) ModBlocks.blocks
+ .get(dimAbbreviation);
+
+ if (dimAbbreviation.equals("DD")) {
+ specialDeepDarkRecipe(this, blockDimensionDisplay);
+ } else {
+
+ GT5OreLayerHelper.NormalOreDimensionWrapper normalOre = GT5OreLayerHelper.dimToOreWrapper
+ .getOrDefault(dimAbbreviation, null);
+ GT5OreSmallHelper.SmallOreDimensionWrapper smallOre = GT5OreSmallHelper.dimToSmallOreWrapper
+ .getOrDefault(dimAbbreviation, null);
+ if (normalOre == null && smallOre == null) {
+ // No ores are generated in this dimension. Fail silently.
+ continue;
+ }
+
+ long spacetimeTier = blockDimensionDisplay.getDimensionRocketTier();
+ if (spacetimeTier == 0) {
+ spacetimeTier += 1;
+ }
+
+ put(
+ dimAbbreviation,
+ new EyeOfHarmonyRecipe(
+ normalOre,
+ smallOre,
+ blockDimensionDisplay,
+ 0.6 + blockDimensionDisplay.getDimensionRocketTier() / 10.0,
+ BILLION * (blockDimensionDisplay.getDimensionRocketTier() + 1),
+ BILLION * (blockDimensionDisplay.getDimensionRocketTier() + 1),
+ timeCalculator(blockDimensionDisplay.getDimensionRocketTier()),
+ spacetimeTier - 1,
+ 1.0 - CHANCE_DECREASE_PER_DIMENSION * blockDimensionDisplay.getDimensionRocketTier()));
+ }
+ }
+ }
+ };
+
+ public EyeOfHarmonyRecipe recipeLookUp(final ItemStack aStack) {
+ String dimAbbreviation = blocksMapInverted.get(Block.getBlockFromItem(aStack.getItem()));
+ return recipeHashMap.get(dimAbbreviation);
+ }
+
+ public EyeOfHarmonyRecipeStorage() {
+
+ for (EyeOfHarmonyRecipe recipe : recipeHashMap.values()) {
+
+ ArrayList<ItemStack> outputItems = new ArrayList<>();
+ for (ItemStackLong itemStackLong : recipe.getOutputItems()) {
+ outputItems.add(itemStackLong.itemStack);
+ }
+
+ ArrayList<FluidStack> outputFluids = new ArrayList<>();
+ for (FluidStackLong fluidStackLong : recipe.getOutputFluids()) {
+ outputFluids.add(fluidStackLong.fluidStack);
+ }
+
+ ItemStack planetItem = recipe.getRecipeTriggerItem()
+ .copy();
+ planetItem.stackSize = 0;
+
+ GTValues.RA.stdBuilder()
+ .itemInputs(planetItem)
+ .itemOutputs(outputItems.toArray(new ItemStack[0]))